diff options
Diffstat (limited to 'src')
1523 files changed, 82761 insertions, 51089 deletions
diff --git a/src/devices/bus/a2bus/a2bus.h b/src/devices/bus/a2bus/a2bus.h index f76a5e1166c..9afff242bdf 100644 --- a/src/devices/bus/a2bus/a2bus.h +++ b/src/devices/bus/a2bus/a2bus.h @@ -51,6 +51,9 @@ MCFG_DEVICE_INPUT_DEFAULTS(_def_inp) \ device_a2bus_card_interface::static_set_a2bus_tag(*device, _nbtag, _tag); +// 7M = XTAL_14_31818MHz / 2 or XTAL_28_63636MHz / 4 (for IIgs) +static constexpr uint32_t A2BUS_7M_CLOCK = 7159090; + //************************************************************************** // TYPE DEFINITIONS //************************************************************************** diff --git a/src/devices/bus/a2bus/a2midi.cpp b/src/devices/bus/a2bus/a2midi.cpp index 5d746f1beb3..dc2f41457fe 100644 --- a/src/devices/bus/a2bus/a2midi.cpp +++ b/src/devices/bus/a2bus/a2midi.cpp @@ -95,14 +95,9 @@ uint8_t a2bus_midi_device::read_c0nx(address_space &space, uint8_t offset) { return m_ptm->read(space, offset & 7); } - else if (offset == 8) + else if (offset == 8 || offset == 9) { - return m_acia->status_r(space, 0); - } - else if (offset == 9) - { - uint8_t ret = m_acia->data_r(space, 0); - return ret; + return m_acia->read(space, offset & 1); } return 0; @@ -118,13 +113,9 @@ void a2bus_midi_device::write_c0nx(address_space &space, uint8_t offset, uint8_t { m_ptm->write(space, offset & 7, data); } - else if (offset == 8) - { - m_acia->control_w(space, 0, data); - } - else if (offset == 9) + else if (offset == 8 || offset == 9) { - m_acia->data_w(space, 0, data); + m_acia->write(space, offset & 1, data); } } diff --git a/src/devices/bus/a2bus/a2videoterm.cpp b/src/devices/bus/a2bus/a2videoterm.cpp index c71b9fb9e1a..db6ca59f3c7 100644 --- a/src/devices/bus/a2bus/a2videoterm.cpp +++ b/src/devices/bus/a2bus/a2videoterm.cpp @@ -39,8 +39,8 @@ DEFINE_DEVICE_TYPE(A2BUS_VIDEOTERM, a2bus_videoterm_device, "a2vidtrm", "Videx VideoTerm") DEFINE_DEVICE_TYPE(A2BUS_IBSAP16, a2bus_ap16_device, "a2ap16", "IBS AP-16 80 column card") DEFINE_DEVICE_TYPE(A2BUS_IBSAP16ALT, a2bus_ap16alt_device, "a2ap16a", "IBS AP-16 80 column card (alt. version)") -DEFINE_DEVICE_TYPE(A2BUS_VTC1, a2bus_vtc1_device, "a2vtc1", "Unknown VideoTerm clone #1") -DEFINE_DEVICE_TYPE(A2BUS_VTC2, a2bus_vtc2_device, "a2vtc2", "Unknown VideoTerm clone #2") +DEFINE_DEVICE_TYPE(A2BUS_VTC1, a2bus_vtc1_device, "a2vtc1", "unknown VideoTerm clone #1") +DEFINE_DEVICE_TYPE(A2BUS_VTC2, a2bus_vtc2_device, "a2vtc2", "unknown VideoTerm clone #2") DEFINE_DEVICE_TYPE(A2BUS_AEVIEWMASTER80, a2bus_aevm80_device, "a2aevm80", "Applied Engineering Viewmaster 80") #define VIDEOTERM_ROM_REGION "vterm_rom" diff --git a/src/devices/bus/a2bus/ezcgi.cpp b/src/devices/bus/a2bus/ezcgi.cpp index e7e3a693fd6..f1d782a80bc 100644 --- a/src/devices/bus/a2bus/ezcgi.cpp +++ b/src/devices/bus/a2bus/ezcgi.cpp @@ -59,7 +59,6 @@ MACHINE_CONFIG_MEMBER( a2bus_ezcgi_9938_device::device_add_mconfig ) MCFG_SCREEN_UPDATE_DEVICE(TMS_TAG, v9938_device, screen_update) MCFG_SCREEN_SIZE(MSX2_TOTAL_XRES_PIXELS, 262*2) MCFG_SCREEN_VISIBLE_AREA(MSX2_XBORDER_PIXELS - MSX2_VISIBLE_XBORDER_PIXELS, MSX2_TOTAL_XRES_PIXELS - MSX2_XBORDER_PIXELS + MSX2_VISIBLE_XBORDER_PIXELS - 1, MSX2_YBORDER_PIXELS - MSX2_VISIBLE_YBORDER_PIXELS, MSX2_TOTAL_YRES_PIXELS - MSX2_YBORDER_PIXELS + MSX2_VISIBLE_YBORDER_PIXELS - 1) - MCFG_SCREEN_PALETTE(TMS_TAG) MACHINE_CONFIG_END MACHINE_CONFIG_MEMBER( a2bus_ezcgi_9958_device::device_add_mconfig ) @@ -73,7 +72,6 @@ MACHINE_CONFIG_MEMBER( a2bus_ezcgi_9958_device::device_add_mconfig ) MCFG_SCREEN_UPDATE_DEVICE(TMS_TAG, v9938_device, screen_update) MCFG_SCREEN_SIZE(MSX2_TOTAL_XRES_PIXELS, 262*2) MCFG_SCREEN_VISIBLE_AREA(MSX2_XBORDER_PIXELS - MSX2_VISIBLE_XBORDER_PIXELS, MSX2_TOTAL_XRES_PIXELS - MSX2_XBORDER_PIXELS + MSX2_VISIBLE_XBORDER_PIXELS - 1, MSX2_YBORDER_PIXELS - MSX2_VISIBLE_YBORDER_PIXELS, MSX2_TOTAL_YRES_PIXELS - MSX2_YBORDER_PIXELS + MSX2_VISIBLE_YBORDER_PIXELS - 1) - MCFG_SCREEN_PALETTE(TMS_TAG) MACHINE_CONFIG_END //************************************************************************** diff --git a/src/devices/bus/a2bus/pc_xporter.cpp b/src/devices/bus/a2bus/pc_xporter.cpp index 3583781a871..9b3b4c726f3 100644 --- a/src/devices/bus/a2bus/pc_xporter.cpp +++ b/src/devices/bus/a2bus/pc_xporter.cpp @@ -114,21 +114,21 @@ ADDRESS_MAP_END //------------------------------------------------- MACHINE_CONFIG_MEMBER( a2bus_pcxporter_device::device_add_mconfig ) - MCFG_CPU_ADD("v30", V30, XTAL_14_31818MHz/2) // 7.16 MHz as per manual + MCFG_CPU_ADD("v30", V30, A2BUS_7M_CLOCK) // 7.16 MHz as per manual MCFG_CPU_PROGRAM_MAP(pc_map) MCFG_CPU_IO_MAP(pc_io) MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259", pic8259_device, inta_cb) MCFG_DEVICE_DISABLE() MCFG_DEVICE_ADD("pit8253", PIT8253, 0) - MCFG_PIT8253_CLK0(XTAL_14_31818MHz/12.0) // heartbeat IRQ + MCFG_PIT8253_CLK0(A2BUS_7M_CLOCK / 6.0) // heartbeat IRQ MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pic8259", pic8259_device, ir0_w)) - MCFG_PIT8253_CLK1(XTAL_14_31818MHz/12.0) // dram refresh + MCFG_PIT8253_CLK1(A2BUS_7M_CLOCK / 6.0) // dram refresh MCFG_PIT8253_OUT1_HANDLER(WRITELINE(a2bus_pcxporter_device, pc_pit8253_out1_changed)) - MCFG_PIT8253_CLK2(XTAL_14_31818MHz/12.0) // pio port c pin 4, and speaker polling enough + MCFG_PIT8253_CLK2(A2BUS_7M_CLOCK / 6.0) // pio port c pin 4, and speaker polling enough MCFG_PIT8253_OUT2_HANDLER(WRITELINE(a2bus_pcxporter_device, pc_pit8253_out2_changed)) - MCFG_DEVICE_ADD( "dma8237", PCXPORT_DMAC, XTAL_14_31818MHz/2 ) + MCFG_DEVICE_ADD("dma8237", PCXPORT_DMAC, A2BUS_7M_CLOCK / 2) MCFG_I8237_OUT_HREQ_CB(WRITELINE(a2bus_pcxporter_device, pc_dma_hrq_changed)) MCFG_I8237_OUT_EOP_CB(WRITELINE(a2bus_pcxporter_device, pc_dma8237_out_eop)) MCFG_I8237_IN_MEMR_CB(READ8(a2bus_pcxporter_device, pc_dma_read_byte)) diff --git a/src/devices/bus/a2bus/ssbapple.cpp b/src/devices/bus/a2bus/ssbapple.cpp new file mode 100644 index 00000000000..cf432236e1a --- /dev/null +++ b/src/devices/bus/a2bus/ssbapple.cpp @@ -0,0 +1,91 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + ssbapple.c + + Implementation of the SSB Apple speech card + Must be in slot 2 for the provided software to work! + +*********************************************************************/ + +#include "emu.h" +#include "ssbapple.h" +#include "sound/tms5220.h" +#include "speaker.h" + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(A2BUS_SSBAPPLE, a2bus_ssb_device, "a2ssbapl", "Multitech Industrial SSB Apple speech card") + +#define TMS_TAG "tms5220" + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER( a2bus_ssb_device::device_add_mconfig ) + MCFG_SPEAKER_STANDARD_MONO("ssbapple") + MCFG_SOUND_ADD(TMS_TAG, TMS5220, 640000) // guess - this gives 8 kHz output according to the datasheet + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "ssbapple", 1.0) +MACHINE_CONFIG_END + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +a2bus_ssb_device::a2bus_ssb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + device_a2bus_card_interface(mconfig, *this), + m_tms(*this, TMS_TAG) +{ +} + +a2bus_ssb_device::a2bus_ssb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + a2bus_ssb_device(mconfig, A2BUS_SSBAPPLE, tag, owner, clock) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a2bus_ssb_device::device_start() +{ + // set_a2bus_device makes m_slot valid + set_a2bus_device(); + + if (m_slot != 2) + { + popmessage("SSB Card should be in slot 2!\n"); + } +} + +void a2bus_ssb_device::device_reset() +{ +} + +bool a2bus_ssb_device::take_c800() +{ + return false; +} + +uint8_t a2bus_ssb_device::read_cnxx(address_space &space, uint8_t offset) +{ + return 0x1f | m_tms->status_r(space, 0); +} + +void a2bus_ssb_device::write_cnxx(address_space &space, uint8_t offset, uint8_t data) +{ + m_tms->data_w(space, 0, data); +} diff --git a/src/devices/bus/a2bus/ssbapple.h b/src/devices/bus/a2bus/ssbapple.h new file mode 100644 index 00000000000..fa03048d53a --- /dev/null +++ b/src/devices/bus/a2bus/ssbapple.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + ssbapple.h + + Implementation of the SSB Apple speech card + +*********************************************************************/ + +#ifndef MAME_BUS_A2BUS_SSBAPPLE_H +#define MAME_BUS_A2BUS_SSBAPPLE_H + +#pragma once + +#include "a2bus.h" +#include "sound/tms5220.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class a2bus_ssb_device: + public device_t, + public device_a2bus_card_interface +{ +public: + // construction/destruction + a2bus_ssb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + static constexpr feature_type imperfect_features() { return feature::SOUND; } + + required_device<tms5220_device> m_tms; + +protected: + a2bus_ssb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + + // overrides of standard a2bus slot functions + virtual uint8_t read_cnxx(address_space &space, uint8_t offset) override; + virtual void write_cnxx(address_space &space, uint8_t offset, uint8_t data) override; + virtual bool take_c800() override; +}; + +// device type definition +DECLARE_DEVICE_TYPE(A2BUS_SSBAPPLE, a2bus_ssb_device) + +#endif // MAME_BUS_A2BUS_A2SSBAPPLE_H diff --git a/src/devices/bus/a2bus/transwarp.cpp b/src/devices/bus/a2bus/transwarp.cpp new file mode 100644 index 00000000000..9288ecc0b17 --- /dev/null +++ b/src/devices/bus/a2bus/transwarp.cpp @@ -0,0 +1,248 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + transwarp.cpp + + Implementation of the Applied Engineering TransWarp accelerator + + TODO: + - needs built-in language card, it's advertised to work w/o one. + - C074 speed control + - Doesn't work with Swyft but advertised to; how does h/w get + around the Fxxx ROM not checksumming right? + +*********************************************************************/ + +#include "emu.h" +#include "transwarp.h" +#include "cpu/m6502/m6502.h" +#include "cpu/m6502/m65c02.h" + +/*************************************************************************** + PARAMETERS +***************************************************************************/ + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(A2BUS_TRANSWARP, a2bus_transwarp_device, "a2twarp", "Applied Engineering TransWarp") + +#define CPU_TAG "tw65c02" + +static ADDRESS_MAP_START( m65c02_mem, AS_PROGRAM, 8, a2bus_transwarp_device ) + AM_RANGE(0x0000, 0xffff) AM_READWRITE(dma_r, dma_w) +ADDRESS_MAP_END + +ROM_START( warprom ) + ROM_REGION(0x1000, "twrom", 0) + ROM_LOAD( "ae transwarp rom v1.4.bin", 0x000000, 0x001000, CRC(afe37f55) SHA1(7b75534e7895e04859a0b1337801c6eeb0cef52a) ) +ROM_END + +static INPUT_PORTS_START( warp ) + PORT_START("DSW1") + PORT_DIPNAME( 0x01, 0x01, "Slot 1" ) + PORT_DIPSETTING( 0x00, "Language Card" ) + PORT_DIPSETTING( 0x01, "Non-LC" ) + PORT_DIPNAME( 0x02, 0x02, "Slot 2" ) + PORT_DIPSETTING( 0x00, "Language Card" ) + PORT_DIPSETTING( 0x02, "Non-LC" ) + PORT_DIPNAME( 0x04, 0x04, "Slot 3" ) + PORT_DIPSETTING( 0x00, "Language Card" ) + PORT_DIPSETTING( 0x04, "Non-LC" ) + PORT_DIPNAME( 0x08, 0x08, "Slot 4" ) + PORT_DIPSETTING( 0x00, "Language Card" ) + PORT_DIPSETTING( 0x08, "Non-LC" ) + PORT_DIPNAME( 0x10, 0x10, "Slot 5" ) + PORT_DIPSETTING( 0x00, "Language Card" ) + PORT_DIPSETTING( 0x10, "Non-LC" ) + PORT_DIPNAME( 0x20, 0x20, "Slot 6" ) + PORT_DIPSETTING( 0x00, "Language Card" ) + PORT_DIPSETTING( 0x20, "Non-LC" ) + PORT_DIPNAME( 0x40, 0x40, "Slot 7" ) + PORT_DIPSETTING( 0x00, "Language Card" ) + PORT_DIPSETTING( 0x40, "Non-LC" ) + PORT_DIPNAME( 0x80, 0x00, "Speed" ) + PORT_DIPSETTING( 0x00, "Full acceleration" ) + PORT_DIPSETTING( 0x80, "Half acceleration" ) + + PORT_START("DSW2") + PORT_DIPNAME( 0x01, 0x01, "Slot 1" ) + PORT_DIPSETTING( 0x00, "Stock speed" ) + PORT_DIPSETTING( 0x01, "Accelerated" ) + PORT_DIPNAME( 0x02, 0x02, "Slot 2" ) + PORT_DIPSETTING( 0x00, "Stock speed" ) + PORT_DIPSETTING( 0x02, "Accelerated" ) + PORT_DIPNAME( 0x04, 0x04, "Slot 3" ) + PORT_DIPSETTING( 0x00, "Stock speed" ) + PORT_DIPSETTING( 0x04, "Accelerated" ) + PORT_DIPNAME( 0x08, 0x08, "Slot 4" ) + PORT_DIPSETTING( 0x00, "Stock speed" ) + PORT_DIPSETTING( 0x08, "Accelerated" ) + PORT_DIPNAME( 0x10, 0x10, "Slot 5" ) + PORT_DIPSETTING( 0x00, "Stock speed" ) + PORT_DIPSETTING( 0x10, "Accelerated" ) + PORT_DIPNAME( 0x20, 0x00, "Slot 6" ) + PORT_DIPSETTING( 0x00, "Stock speed" ) + PORT_DIPSETTING( 0x20, "Accelerated" ) + PORT_DIPNAME( 0x40, 0x40, "Slot 7" ) + PORT_DIPSETTING( 0x00, "Stock speed" ) + PORT_DIPSETTING( 0x40, "Accelerated" ) + PORT_DIPNAME( 0x80, 0x00, "Transwarp Enable" ) + PORT_DIPSETTING( 0x00, "Acceleration enabled" ) + PORT_DIPSETTING( 0x80, "Acceleration disabled" ) +INPUT_PORTS_END + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +/*------------------------------------------------- + rom_region - device-specific ROM region +-------------------------------------------------*/ + +const tiny_rom_entry *a2bus_transwarp_device::device_rom_region() const +{ + return ROM_NAME(warprom); +} + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor a2bus_transwarp_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( warp ); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER( a2bus_transwarp_device::device_add_mconfig ) + MCFG_CPU_ADD(CPU_TAG, M65C02, A2BUS_7M_CLOCK / 2) + MCFG_CPU_PROGRAM_MAP(m65c02_mem) +MACHINE_CONFIG_END + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +a2bus_transwarp_device::a2bus_transwarp_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + device_a2bus_card_interface(mconfig, *this), + m_bEnabled(false), + m_ourcpu(*this, CPU_TAG), + m_rom(*this, "twrom"), + m_dsw1(*this, "DSW1"), + m_dsw2(*this, "DSW2") +{ +} + +a2bus_transwarp_device::a2bus_transwarp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + a2bus_transwarp_device(mconfig, A2BUS_TRANSWARP, tag, owner, clock) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void a2bus_transwarp_device::device_start() +{ + // set_a2bus_device makes m_slot valid + set_a2bus_device(); + + m_timer = timer_alloc(0); + + save_item(NAME(m_bEnabled)); +} + +void a2bus_transwarp_device::device_reset() +{ + m_bEnabled = true; + m_bReadA2ROM = false; + set_maincpu_halt(ASSERT_LINE); + + if (!(m_dsw2->read() & 0x80)) + { + if (m_dsw1->read() & 0x80) + m_ourcpu->set_unscaled_clock(A2BUS_7M_CLOCK / 4); + else + m_ourcpu->set_unscaled_clock(A2BUS_7M_CLOCK / 2); + } + else + { + m_ourcpu->set_unscaled_clock(1021800); + } +} + +void a2bus_transwarp_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (!(m_dsw2->read() & 0x80)) + { + if (m_dsw1->read() & 0x80) + m_ourcpu->set_unscaled_clock(A2BUS_7M_CLOCK / 4); + else + m_ourcpu->set_unscaled_clock(A2BUS_7M_CLOCK / 2); + } + m_timer->adjust(attotime::never); +} + +READ8_MEMBER( a2bus_transwarp_device::dma_r ) +{ + if ((offset >= 0xc090) && (offset <= 0xc0ff)) + { + hit_slot(((offset >> 4) & 0xf) - 8); + } + + if ((offset >= 0xf000) && (!m_bReadA2ROM)) + { + return m_rom[offset & 0xfff]; + } + + return slot_dma_read(space, offset); +} + + +//------------------------------------------------- +// dma_w - +//------------------------------------------------- + +WRITE8_MEMBER( a2bus_transwarp_device::dma_w ) +{ + //if ((offset >= 0xc070) && (offset <= 0xc07f)) printf("%02x to %04x\n", data, offset); + + if (offset == 0xc072) + { + m_bReadA2ROM = true; + } + + if ((offset >= 0xc090) && (offset <= 0xc0ff)) + { + hit_slot(((offset >> 4) & 0xf) - 8); + } + + slot_dma_write(space, offset, data); +} + +bool a2bus_transwarp_device::take_c800() +{ + return false; +} + +void a2bus_transwarp_device::hit_slot(int slot) +{ + // only do slot slowdown if acceleration is enabled + if (!(m_dsw2->read() & 0x80)) + { + // accleration's on, check the specific slot + if (m_dsw2->read() & (1<<(slot-1))) + { + m_ourcpu->set_unscaled_clock(1021800); + // slow down for around 20 cycles, should be more than enough + m_timer->adjust(attotime::from_usec(20)); + } + } +} diff --git a/src/devices/bus/a2bus/transwarp.h b/src/devices/bus/a2bus/transwarp.h new file mode 100644 index 00000000000..be327e56c6e --- /dev/null +++ b/src/devices/bus/a2bus/transwarp.h @@ -0,0 +1,61 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont +/********************************************************************* + + transwarp.h + + Implementation of the Applied Engineering TransWarp accelerator + +*********************************************************************/ + +#ifndef MAME_BUS_A2BUS_A2TRANSWARP_H +#define MAME_BUS_A2BUS_A2TRANSWARP_H + +#include "a2bus.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class a2bus_transwarp_device: + public device_t, + public device_a2bus_card_interface +{ +public: + // construction/destruction + a2bus_transwarp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual const tiny_rom_entry *device_rom_region() const override; + + DECLARE_READ8_MEMBER( dma_r ); + DECLARE_WRITE8_MEMBER( dma_w ); + +protected: + a2bus_transwarp_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // overrides of device_t functions + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + + // overrides of standard a2bus slot functions + virtual bool take_c800() override; + +private: + bool m_bEnabled; + bool m_bReadA2ROM; + emu_timer *m_timer; + + required_device<cpu_device> m_ourcpu; + required_region_ptr<uint8_t> m_rom; + required_ioport m_dsw1, m_dsw2; + + void hit_slot(int slot); +}; + +// device type definition +DECLARE_DEVICE_TYPE(A2BUS_TRANSWARP, a2bus_transwarp_device) + +#endif // MAME_BUS_A2BUS_TRANSWARP_H diff --git a/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp b/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp index 023412f7e7c..12feac575f8 100644 --- a/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp +++ b/src/devices/bus/bbc/1mhzbus/1mhzbus.cpp @@ -96,6 +96,11 @@ void bbc_1mhzbus_slot_device::device_reset() } } +WRITE_LINE_MEMBER(bbc_1mhzbus_slot_device::rst_w) +{ + if (m_card) + m_card->rst_w(state); +} //------------------------------------------------- // SLOT_INTERFACE( bbc_1mhzbus_devices ) @@ -105,29 +110,28 @@ void bbc_1mhzbus_slot_device::device_reset() // slot devices //#include "teletext.h" //#include "ieee488.h" -//#include "music500.h" -//#include "music5000.h" +//#include "m5000.h" //#include "multiform.h" #include "opus3.h" //#include "ramdisc.h" -//#include "torchg400.h" -//#include "torchg800.h" +//#include "graduate.h" #include "beebsid.h" //#include "prisma3.h" +#include "cfa3000opt.h" SLOT_INTERFACE_START(bbc_1mhzbus_devices) -// SLOT_INTERFACE("teletext", BBC_TELETEXT) /* Acorn ANE01 Teletext Adapter */ -// SLOT_INTERFACE("ieee488", BBC_IEEE488) /* Acorn ANK01 IEEE488 Interface */ -// SLOT_INTERFACE("music500", BBC_MUSIC500) /* Acorn ANV02 Music500 */ -// SLOT_INTERFACE("music2000", BBC_MUSIC2000) /* Hybrid Music 2000 MIDI Interface */ -// SLOT_INTERFACE("music3000", BBC_MUSIC3000) /* Hybrid Music 3000 Expander */ -// SLOT_INTERFACE("music5000", BBC_MUSIC5000) /* Hybrid Music 5000 Synthesiser */ -// SLOT_INTERFACE("multiform", BBC_MULTIFORM) /* Technomatic Multiform Z80 */ - SLOT_INTERFACE("opus3", BBC_OPUS3) /* Opus Challenger 3 */ -// SLOT_INTERFACE("ramdisc", BBC_RAMDISC) /* Morley Electronics RAM Disc */ -// SLOT_INTERFACE("torchg400", BBC_TORCHG400) /* Torch Graduate G400 */ -// SLOT_INTERFACE("torchg800", BBC_TORCHG800) /* Torch Graduate G800 */ - SLOT_INTERFACE("beebsid", BBC_BEEBSID) /* BeebSID */ -// SLOT_INTERFACE("prisma3", BBC_PRISMA3) /* Prisma 3 - Millipede 1989 */ +// SLOT_INTERFACE("teletext", BBC_TELETEXT) /* Acorn ANE01 Teletext Adapter */ +// SLOT_INTERFACE("ieee488", BBC_IEEE488) /* Acorn ANK01 IEEE488 Interface */ +// SLOT_INTERFACE("m500", BBC_M500) /* Acorn ANV02 Music 500 */ +// SLOT_INTERFACE("m2000", BBC_M2000) /* Hybrid Music 2000 MIDI Interface */ +// SLOT_INTERFACE("m3000", BBC_M3000) /* Hybrid Music 3000 Expander */ +// SLOT_INTERFACE("m5000", BBC_M5000) /* Hybrid Music 5000 Synthesiser */ +// SLOT_INTERFACE("multiform", BBC_MULTIFORM) /* Technomatic Multiform Z80 */ + SLOT_INTERFACE("opus3", BBC_OPUS3) /* Opus Challenger 3 */ +// SLOT_INTERFACE("ramdisc", BBC_RAMDISC) /* Morley Electronics RAM Disc */ +// SLOT_INTERFACE("graduate", BBC_GRADUATE) /* The Torch Graduate G400/G800 */ + SLOT_INTERFACE("beebsid", BBC_BEEBSID) /* BeebSID */ +// SLOT_INTERFACE("prisma3", BBC_PRISMA3) /* PRISMA-3 - Millipede 1989 */ + SLOT_INTERFACE("cfa3000opt", CFA3000_OPT) /* Henson CFA 3000 Option Board */ SLOT_INTERFACE_END diff --git a/src/devices/bus/bbc/1mhzbus/1mhzbus.h b/src/devices/bus/bbc/1mhzbus/1mhzbus.h index a05d3d7eb12..3c6527a0adc 100644 --- a/src/devices/bus/bbc/1mhzbus/1mhzbus.h +++ b/src/devices/bus/bbc/1mhzbus/1mhzbus.h @@ -14,7 +14,7 @@ 0V 7 8 NIRQ 0V 9 10 NPGFC 0V 11 12 NPGFD - 0V 13 14 RST + 0V 13 14 NRST 0V 15 16 Analog In 0V 17 18 D0 D1 19 20 D2 @@ -128,6 +128,7 @@ public: template <class Object> static devcb_base &set_nmi_handler(device_t &device, Object &&cb) { return downcast<bbc_1mhzbus_slot_device &>(device).m_nmi_handler.set_callback(std::forward<Object>(cb)); } + DECLARE_WRITE_LINE_MEMBER( rst_w ); DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_irq_handler(state); } DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); } @@ -152,6 +153,8 @@ public: // construction/destruction virtual ~device_bbc_1mhzbus_interface(); + virtual DECLARE_WRITE_LINE_MEMBER(rst_w) { } + protected: device_bbc_1mhzbus_interface(const machine_config &mconfig, device_t &device); diff --git a/src/devices/bus/bbc/1mhzbus/cfa3000opt.cpp b/src/devices/bus/bbc/1mhzbus/cfa3000opt.cpp new file mode 100644 index 00000000000..63f2229b27a --- /dev/null +++ b/src/devices/bus/bbc/1mhzbus/cfa3000opt.cpp @@ -0,0 +1,116 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Henson CFA 3000 Option Board + +**********************************************************************/ + + +#include "emu.h" +#include "cfa3000opt.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(CFA3000_OPT, cfa3000_opt_device, "cfa3000opt", "Henson CFA 3000 Option Board") + + +//------------------------------------------------- +// INPUT_PORTS( cfa3000opt ) +//------------------------------------------------- + +static INPUT_PORTS_START( cfa3000opt ) + PORT_START("OPT") + PORT_DIPNAME(0x80, 0x00, "Switch 1") PORT_DIPLOCATION("Option:1") + PORT_DIPSETTING(0x80, "not used") + PORT_DIPSETTING(0x00, "not used") + + PORT_DIPNAME(0x40, 0x00, "Switch 2") PORT_DIPLOCATION("Option:2") + PORT_DIPSETTING(0x40, "not used") + PORT_DIPSETTING(0x00, "not used") + + PORT_DIPNAME(0x20, 0x00, "Switch 3") PORT_DIPLOCATION("Option:3") + PORT_DIPSETTING(0x20, "Auto Send") + PORT_DIPSETTING(0x00, "Request Send") + + PORT_DIPNAME(0x10, 0x00, "Switch 4") PORT_DIPLOCATION("Option:4") + PORT_DIPSETTING(0x10, "repeat >4db") + PORT_DIPSETTING(0x00, "do not repeat >4db") + + PORT_DIPNAME(0x08, 0x00, "Switch 5") PORT_DIPLOCATION("Option:5") + PORT_DIPSETTING(0x08, "est. fluct.") + PORT_DIPSETTING(0x00, "do not est. fluct.") + + PORT_DIPNAME(0x04, 0x00, "Switch 6") PORT_DIPLOCATION("Option:6") + PORT_DIPSETTING(0x04, "Full Threshold") + PORT_DIPSETTING(0x00, "Supra Threshold") + + PORT_DIPNAME(0x02, 0x00, "Switch 7") PORT_DIPLOCATION("Option:7") + PORT_DIPSETTING(0x02, "db") + PORT_DIPSETTING(0x00, "log units") + + PORT_DIPNAME(0x01, 0x00, "Switch 8") PORT_DIPLOCATION("Option:8") + PORT_DIPSETTING(0x01, "2nd level") + PORT_DIPSETTING(0x00, "1st level") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor cfa3000_opt_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( cfa3000opt ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// cfa3000_opt_device - constructor +//------------------------------------------------- + +cfa3000_opt_device::cfa3000_opt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, CFA3000_OPT, tag, owner, clock), + device_bbc_1mhzbus_interface(mconfig, *this), + m_opt(*this, "OPT") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void cfa3000_opt_device::device_start() +{ + address_space& space = machine().device("maincpu")->memory().space(AS_PROGRAM); + m_slot = dynamic_cast<bbc_1mhzbus_slot_device *>(owner()); + + space.install_read_handler(0xfcc2, 0xfcc2, read8_delegate(FUNC(cfa3000_opt_device::option_r), this)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void cfa3000_opt_device::device_reset() +{ +} + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ8_MEMBER(cfa3000_opt_device::option_r) +{ + return m_opt->read(); +} diff --git a/src/devices/bus/bbc/1mhzbus/cfa3000opt.h b/src/devices/bus/bbc/1mhzbus/cfa3000opt.h new file mode 100644 index 00000000000..e372a14b51b --- /dev/null +++ b/src/devices/bus/bbc/1mhzbus/cfa3000opt.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Henson CFA 3000 Option Board + +**********************************************************************/ + +#ifndef MAME_BUS_BBC_1MHZBUS_CFA3000OPT_H +#define MAME_BUS_BBC_1MHZBUS_CFA3000OPT_H + +#pragma once + +#include "1mhzbus.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> cfa3000_opt_device + +class cfa3000_opt_device : + public device_t, + public device_bbc_1mhzbus_interface +{ +public: + // construction/destruction + cfa3000_opt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ8_MEMBER(option_r); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + +private: + required_ioport m_opt; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(CFA3000_OPT, cfa3000_opt_device) + + +#endif // MAME_BUS_BBC_1MHZBUS_CFA3000OPT_H diff --git a/src/devices/bus/bbc/analogue/analogue.cpp b/src/devices/bus/bbc/analogue/analogue.cpp index 5d7f4497d67..24f2707e8f5 100644 --- a/src/devices/bus/bbc/analogue/analogue.cpp +++ b/src/devices/bus/bbc/analogue/analogue.cpp @@ -103,10 +103,12 @@ void bbc_analogue_slot_device::device_reset() // slot devices #include "joystick.h" //#include "quinkey.h" +#include "cfa3000a.h" SLOT_INTERFACE_START( bbc_analogue_devices ) SLOT_INTERFACE("acornjoy", BBC_ACORNJOY) /* Acorn ANH01 Joysticks */ SLOT_INTERFACE("voltmace3b", BBC_VOLTMACE3B) /* Voltmace Delta 3b "Twin" Joysticks */ // SLOT_INTERFACE("quinkey", BBC_QUINKEY) /* Microwriter Quinkey */ + SLOT_INTERFACE("cfa3000a", CFA3000_ANLG) /* Hanson CFA 3000 Analogue */ SLOT_INTERFACE_END diff --git a/src/devices/bus/bbc/analogue/cfa3000a.cpp b/src/devices/bus/bbc/analogue/cfa3000a.cpp new file mode 100644 index 00000000000..da163200c2c --- /dev/null +++ b/src/devices/bus/bbc/analogue/cfa3000a.cpp @@ -0,0 +1,100 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Henson CFA 3000 Analogue + +**********************************************************************/ + + +#include "emu.h" +#include "cfa3000a.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(CFA3000_ANLG, cfa3000_anlg_device, "cfa3000a", "Henson CFA 3000 Analogue") + + +//------------------------------------------------- +// INPUT_PORTS( cfa3000a ) +//------------------------------------------------- + +static INPUT_PORTS_START( cfa3000a ) + PORT_START("CHANNEL0") + PORT_BIT(0xff, 0x80, IPT_PADDLE) PORT_NAME("Background Intensity") PORT_SENSITIVITY(25) PORT_KEYDELTA(5) PORT_CENTERDELTA(0) PORT_REVERSE + + PORT_START("CHANNEL1") + PORT_BIT(0xff, 0x00, IPT_UNKNOWN) + + PORT_START("CHANNEL2") + PORT_BIT(0xff, 0x80, IPT_PADDLE) PORT_NAME("Age") PORT_SENSITIVITY(25) PORT_KEYDELTA(5) PORT_CENTERDELTA(0) PORT_REVERSE + + PORT_START("CHANNEL3") + PORT_BIT(0xff, 0x00, IPT_UNKNOWN) + + PORT_START("BUTTONS") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor cfa3000_anlg_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( cfa3000a ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// cfa3000_anlg_device - constructor +//------------------------------------------------- + +cfa3000_anlg_device::cfa3000_anlg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, CFA3000_ANLG, tag, owner, clock), + device_bbc_analogue_interface(mconfig, *this), + m_channel(*this, "CHANNEL%u", 0), + m_buttons(*this, "BUTTONS") +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void cfa3000_anlg_device::device_start() +{ +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void cfa3000_anlg_device::device_reset() +{ +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +uint8_t cfa3000_anlg_device::ch_r(int channel) +{ + return m_channel[channel]->read(); +} + +uint8_t cfa3000_anlg_device::pb_r() +{ + return m_buttons->read(); +} diff --git a/src/devices/bus/bbc/analogue/cfa3000a.h b/src/devices/bus/bbc/analogue/cfa3000a.h new file mode 100644 index 00000000000..8948ca586be --- /dev/null +++ b/src/devices/bus/bbc/analogue/cfa3000a.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Henson CFA3000 Analogue + +**********************************************************************/ + + +#ifndef MAME_BUS_BBC_ANALOGUE_CFA3000A_H +#define MAME_BUS_BBC_ANALOGUE_CFA3000A_H + +#pragma once + +#include "analogue.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> cfa3000_anlg_device + +class cfa3000_anlg_device : + public device_t, + public device_bbc_analogue_interface +{ +public: + // construction/destruction + cfa3000_anlg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + + virtual uint8_t ch_r(int channel) override; + virtual uint8_t pb_r() override; + +private: + required_ioport_array<4> m_channel; + required_ioport m_buttons; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(CFA3000_ANLG, cfa3000_anlg_device) + + +#endif // MAME_BUS_BBC_ANALOGUE_CFA3000A_H diff --git a/src/devices/bus/bbc/fdc/cv1797.cpp b/src/devices/bus/bbc/fdc/cv1797.cpp new file mode 100644 index 00000000000..17f0d9130c8 --- /dev/null +++ b/src/devices/bus/bbc/fdc/cv1797.cpp @@ -0,0 +1,160 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Computer Village 1797 FDC + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/ComputerVillage_FDC.html + +**********************************************************************/ + + +#include "emu.h" +#include "cv1797.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_CV1797, bbc_cv1797_device, "bbc_cv1797", "Computer Village 1797 FDC") + + +//------------------------------------------------- +// MACHINE_DRIVER( cv1797 ) +//------------------------------------------------- + +FLOPPY_FORMATS_MEMBER( bbc_cv1797_device::floppy_formats ) + FLOPPY_ACORN_SSD_FORMAT, + FLOPPY_ACORN_DSD_FORMAT, + FLOPPY_FSD_FORMAT +FLOPPY_FORMATS_END0 + +static SLOT_INTERFACE_START( bbc_floppies_525 ) + SLOT_INTERFACE("525sssd", FLOPPY_525_SSSD) + SLOT_INTERFACE("525sd", FLOPPY_525_SD) + SLOT_INTERFACE("525ssdd", FLOPPY_525_SSDD) + SLOT_INTERFACE("525dd", FLOPPY_525_DD) + SLOT_INTERFACE("525qd", FLOPPY_525_QD) +SLOT_INTERFACE_END + +ROM_START( cv1797 ) + ROM_REGION(0x4000, "dfs_rom", 0) + ROM_DEFAULT_BIOS("lvldos") + ROM_SYSTEM_BIOS(0, "lvldos", "LVL Dos 0.91") + ROMX_LOAD("lvldos91.rom", 0x0000, 0x2000, CRC(69d7653a) SHA1(9cd39d011290b97d5ba05b6c745689a8553be5fc), ROM_BIOS(1)) + ROM_RELOAD(0x2000, 0x2000) +ROM_END + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER( bbc_cv1797_device::device_add_mconfig ) + MCFG_FD1797_ADD("fd1797", XTAL_8MHz / 8) + MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(bbc_cv1797_device, fdc_intrq_w)) + MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(bbc_cv1797_device, fdc_drq_w)) + MCFG_WD_FDC_HLD_CALLBACK(WRITELINE(bbc_cv1797_device, motor_w)) + MCFG_FLOPPY_DRIVE_ADD("fd1797:0", bbc_floppies_525, "525qd", floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) + MCFG_FLOPPY_DRIVE_ADD("fd1797:1", bbc_floppies_525, "525qd", floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) +MACHINE_CONFIG_END + +const tiny_rom_entry *bbc_cv1797_device::device_rom_region() const +{ + return ROM_NAME( cv1797 ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_cv1797_device - constructor +//------------------------------------------------- + +bbc_cv1797_device::bbc_cv1797_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_CV1797, tag, owner, clock), + device_bbc_fdc_interface(mconfig, *this), + m_dfs_rom(*this, "dfs_rom"), + m_fdc(*this, "fd1797"), + m_floppy0(*this, "fd1797:0"), + m_floppy1(*this, "fd1797:1") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_cv1797_device::device_start() +{ + device_t* cpu = machine().device("maincpu"); + address_space& space = cpu->memory().space(AS_PROGRAM); + m_slot = dynamic_cast<bbc_fdc_slot_device *>(owner()); + + space.install_readwrite_handler(0xfe80, 0xfe80, read8_delegate(FUNC(fd1797_device::read), (fd1797_device *)m_fdc), write8_delegate(FUNC(fd1797_device::write), (fd1797_device *)m_fdc)); + space.install_readwrite_handler(0xfe84, 0xfe9f, read8_delegate(FUNC(bbc_cv1797_device::fd1797l_read), this), write8_delegate(FUNC(bbc_cv1797_device::fd1797l_write), this)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void bbc_cv1797_device::device_reset() +{ + machine().root_device().membank("bank4")->configure_entry(12, memregion("dfs_rom")->base()); + + m_fdc->soft_reset(); +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ8_MEMBER(bbc_cv1797_device::fd1797l_read) +{ + return m_drive_control; +} + +WRITE8_MEMBER(bbc_cv1797_device::fd1797l_write) +{ + floppy_image_device *floppy = nullptr; + + m_drive_control = data; + logerror("fdc: Drive control %02x\n", data); + // bit 0: drive select + floppy_image_device *floppy0 = m_floppy0->get_device(); + floppy_image_device *floppy1 = m_floppy1->get_device(); + floppy = (BIT(data, 0) ? floppy1 : floppy0); + m_fdc->set_floppy(floppy); + + // bit 1: side select + if (floppy) + floppy->ss_w(BIT(data, 1)); + + // bit 2: density + m_fdc->dden_w(BIT(data, 2)); + + // bit 6: reset + //if (BIT(data, 6)) m_fdc->soft_reset(); +} + +WRITE_LINE_MEMBER(bbc_cv1797_device::fdc_intrq_w) +{ + m_slot->intrq_w(state); +} + +WRITE_LINE_MEMBER(bbc_cv1797_device::fdc_drq_w) +{ + m_slot->drq_w(state); +} + +WRITE_LINE_MEMBER(bbc_cv1797_device::motor_w) +{ + if (m_floppy0->get_device()) m_floppy0->get_device()->mon_w(!state); + if (m_floppy1->get_device()) m_floppy1->get_device()->mon_w(!state); +} diff --git a/src/devices/bus/bbc/fdc/cv1797.h b/src/devices/bus/bbc/fdc/cv1797.h new file mode 100644 index 00000000000..b03385810f2 --- /dev/null +++ b/src/devices/bus/bbc/fdc/cv1797.h @@ -0,0 +1,66 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Computer Village 1797 FDC + +**********************************************************************/ + + +#ifndef MAME_BUS_BBC_FDC_CV1797_H +#define MAME_BUS_BBC_FDC_CV1797_H + +#pragma once + +#include "fdc.h" +#include "machine/wd_fdc.h" +#include "formats/acorn_dsk.h" +#include "formats/fsd_dsk.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class bbc_cv1797_device : + public device_t, + public device_bbc_fdc_interface + +{ +public: + static constexpr feature_type imperfect_features() { return feature::DISK; } + + // construction/destruction + bbc_cv1797_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + +private: + DECLARE_FLOPPY_FORMATS(floppy_formats); + + DECLARE_READ8_MEMBER(fd1797l_read); + DECLARE_WRITE8_MEMBER(fd1797l_write); + DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w); + DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); + DECLARE_WRITE_LINE_MEMBER(motor_w); + + required_memory_region m_dfs_rom; + required_device<fd1797_device> m_fdc; + required_device<floppy_connector> m_floppy0; + optional_device<floppy_connector> m_floppy1; + + int m_drive_control; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_CV1797, bbc_cv1797_device) + + +#endif /* MAME_BUS_BBC_FDC_CV1797_H */ diff --git a/src/devices/bus/bbc/fdc/fdc.cpp b/src/devices/bus/bbc/fdc/fdc.cpp index 89158ac6cea..35bbdacdebe 100644 --- a/src/devices/bus/bbc/fdc/fdc.cpp +++ b/src/devices/bus/bbc/fdc/fdc.cpp @@ -102,7 +102,7 @@ void bbc_fdc_slot_device::device_reset() // slot devices #include "acorn.h" #include "cumana.h" -//#include "cv1797.h" +#include "cv1797.h" //#include "microware.h" #include "opus.h" //#include "solidisk.h" @@ -115,7 +115,7 @@ SLOT_INTERFACE_START( bbc_fdc_devices ) SLOT_INTERFACE("acorn1770", BBC_ACORN1770) SLOT_INTERFACE("cumana1", BBC_CUMANA1) SLOT_INTERFACE("cumana2", BBC_CUMANA2) - //SLOT_INTERFACE("cv1797", BBC_CV1797) + SLOT_INTERFACE("cv1797", BBC_CV1797) //SLOT_INTERFACE("microware", BBC_MICROWARE) SLOT_INTERFACE("opus8272", BBC_OPUS8272) SLOT_INTERFACE("opus2791", BBC_OPUS2791) diff --git a/src/devices/bus/bbc/tube/tube.cpp b/src/devices/bus/bbc/tube/tube.cpp index 13bb4430230..ab232a6ce04 100644 --- a/src/devices/bus/bbc/tube/tube.cpp +++ b/src/devices/bus/bbc/tube/tube.cpp @@ -124,7 +124,7 @@ WRITE8_MEMBER(bbc_tube_slot_device::host_w) #include "tube_65c102.h" #include "tube_80186.h" #include "tube_80286.h" -//#include "tube_arm.h" +#include "tube_arm.h" #include "tube_casper.h" //#include "tube_x25.h" #include "tube_z80.h" @@ -140,7 +140,7 @@ SLOT_INTERFACE_START( bbc_extube_devices ) SLOT_INTERFACE("z80", BBC_TUBE_Z80) /* Acorn ANC04 Z80 2nd processor */ // SLOT_INTERFACE("32016", BBC_TUBE_32016) /* Acorn ANC05 32016 2nd processor */ // SLOT_INTERFACE("camb", BBC_TUBE_CAMB) /* Acorn ANC06 Cambridge Co-Processor */ -// SLOT_INTERFACE("arm", BBC_TUBE_ARM) /* Acorn ANC13 ARM Evaluation System */ + SLOT_INTERFACE("arm", BBC_TUBE_ARM) /* Acorn ANC13 ARM Evaluation System */ SLOT_INTERFACE("80286", BBC_TUBE_80286) /* Acorn 80286 2nd Processor */ // SLOT_INTERFACE("a500", BBC_TUBE_A500) /* Acorn A500 2nd Processor */ SLOT_INTERFACE("casper", BBC_TUBE_CASPER) /* Casper 68000 2nd Processor */ diff --git a/src/devices/bus/bbc/tube/tube_arm.cpp b/src/devices/bus/bbc/tube/tube_arm.cpp new file mode 100644 index 00000000000..7243f2989c7 --- /dev/null +++ b/src/devices/bus/bbc/tube/tube_arm.cpp @@ -0,0 +1,151 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Acorn ANC13 ARM Evaluation System + +**********************************************************************/ + + +#include "emu.h" +#include "tube_arm.h" +#include "softlist_dev.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_TUBE_ARM, bbc_tube_arm_device, "bbc_tube_arm", "ARM Evaluation System") + + +//------------------------------------------------- +// ADDRESS_MAP( tube_arm_mem ) +//------------------------------------------------- + +static ADDRESS_MAP_START(tube_arm_mem, AS_PROGRAM, 32, bbc_tube_arm_device) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x0000000, 0x03fffff) AM_READWRITE8(ram_r, ram_w, 0xffffffff) + AM_RANGE(0x1000000, 0x100001f) AM_DEVREADWRITE8("ula", tube_device, parasite_r, parasite_w, 0x000000ff) + AM_RANGE(0x3000000, 0x3003fff) AM_ROM AM_REGION("bootstrap", 0) AM_MIRROR(0xc000) +ADDRESS_MAP_END + +//------------------------------------------------- +// ROM( tube_arm ) +//------------------------------------------------- + +ROM_START( tube_arm ) + ROM_REGION(0x4000, "bootstrap", 0) + ROM_DEFAULT_BIOS("101") + ROM_SYSTEM_BIOS(0, "101", "Executive v1.00 (14th August 1986)") + ROMX_LOAD("ARMeval_101.rom", 0x0000, 0x4000, CRC(cab85473) SHA1(f86bbc4894e62725b8ef22d44e7f44d37c98ac14), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(1, "100", "Executive v1.00 (6th June 1986)") + ROMX_LOAD("ARMeval_100.rom", 0x0000, 0x4000, CRC(ed80462a) SHA1(ba33eaf1a23cfef6fc1b88aa516ca2b3693e69d9), ROM_BIOS(2)) + ROM_SYSTEM_BIOS(2, "005", "Brazil v-.005 (8th August 1986)") + ROMX_LOAD("Brazil_005.rom", 0x0000, 0x4000, CRC(7c27c098) SHA1(abcc71cbc43489e89a87aac64e67b17daef5895a), ROM_BIOS(3)) +ROM_END + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER(bbc_tube_arm_device::device_add_mconfig) + MCFG_CPU_ADD("arm", ARM, XTAL_20MHz / 3) + MCFG_CPU_PROGRAM_MAP(tube_arm_mem) + + MCFG_TUBE_ADD("ula") + MCFG_TUBE_HIRQ_HANDLER(DEVWRITELINE(DEVICE_SELF_OWNER, bbc_tube_slot_device, irq_w)) + MCFG_TUBE_PNMI_HANDLER(INPUTLINE("arm", ARM_FIRQ_LINE)) + MCFG_TUBE_PIRQ_HANDLER(INPUTLINE("arm", ARM_IRQ_LINE)) + + /* internal ram */ + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("4M") + MCFG_RAM_DEFAULT_VALUE(0x00) + + /* software lists */ + MCFG_SOFTWARE_LIST_ADD("flop_ls_arm", "bbc_flop_arm") +MACHINE_CONFIG_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *bbc_tube_arm_device::device_rom_region() const +{ + return ROM_NAME( tube_arm ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_tube_arm_device - constructor +//------------------------------------------------- + +bbc_tube_arm_device::bbc_tube_arm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_TUBE_ARM, tag, owner, clock), + device_bbc_tube_interface(mconfig, *this), + m_arm(*this, "arm"), + m_ula(*this, "ula"), + m_ram(*this, "ram"), + m_bootstrap(*this, "bootstrap"), + m_rom_select(true) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_tube_arm_device::device_start() +{ + m_slot = dynamic_cast<bbc_tube_slot_device *>(owner()); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void bbc_tube_arm_device::device_reset() +{ + /* enable the reset vector to be fetched from ROM */ + m_rom_select = true; +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ8_MEMBER(bbc_tube_arm_device::host_r) +{ + return m_ula->host_r(space, offset); +} + +WRITE8_MEMBER(bbc_tube_arm_device::host_w) +{ + m_ula->host_w(space, offset, data); +} + + +READ8_MEMBER(bbc_tube_arm_device::ram_r) +{ + uint8_t data; + + if (m_rom_select) + data = m_bootstrap->base()[offset & 0x3fff]; + else + data = m_ram->pointer()[offset]; + + return data; +} + +WRITE8_MEMBER(bbc_tube_arm_device::ram_w) +{ + /* clear ROM select on first write */ + if (!machine().side_effect_disabled()) m_rom_select = false; + + m_ram->pointer()[offset] = data; +} diff --git a/src/devices/bus/bbc/tube/tube_arm.h b/src/devices/bus/bbc/tube/tube_arm.h new file mode 100644 index 00000000000..6f2e43ef43d --- /dev/null +++ b/src/devices/bus/bbc/tube/tube_arm.h @@ -0,0 +1,61 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Acorn ANC13 ARM Evaluation System + +**********************************************************************/ + + +#ifndef MAME_BUS_BBC_TUBE_ARM_H +#define MAME_BUS_BBC_TUBE_ARM_H + +#include "tube.h" +#include "cpu/arm/arm.h" +#include "machine/ram.h" +#include "machine/tube.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> bbc_tube_arm_device + +class bbc_tube_arm_device : + public device_t, + public device_bbc_tube_interface +{ +public: + // construction/destruction + bbc_tube_arm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ8_MEMBER( ram_r ); + DECLARE_WRITE8_MEMBER( ram_w ); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + + virtual DECLARE_READ8_MEMBER( host_r ) override; + virtual DECLARE_WRITE8_MEMBER( host_w ) override; + +private: + required_device<arm_cpu_device> m_arm; + required_device<tube_device> m_ula; + required_device<ram_device> m_ram; + required_memory_region m_bootstrap; + + bool m_rom_select; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_TUBE_ARM, bbc_tube_arm_device) + + +#endif /* MAME_BUS_BBC_TUBE_ARM_H */ diff --git a/src/devices/bus/bbc/userport/cfa3000kbd.cpp b/src/devices/bus/bbc/userport/cfa3000kbd.cpp new file mode 100644 index 00000000000..d07d7b6dd2f --- /dev/null +++ b/src/devices/bus/bbc/userport/cfa3000kbd.cpp @@ -0,0 +1,141 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Henson CFA 3000 Keyboard + + 240 Pattern Right 0000 + 241 Pattern Left 0001 + 242 Patient Response 0010 + 243 Present Stimuli 0011 + + 244 Up 0100 + 245 Down 0101 + 246 Left 0110 + 247 Right 0111 + + 248 D 1000 + 249 C 1001 + 250 B 1010 + 251 A 1011 + + 252 Mode 1100 + 253 Erase 1101 + 254 Restart 1110 + 255 Print 1111 + +**********************************************************************/ + + +#include "emu.h" +#include "cfa3000kbd.h" + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(CFA3000_KBD, cfa3000_kbd_device, "cfa3000kbd", "Henson CFA 3000 Keyboard") + + +//------------------------------------------------- +// INPUT_PORTS( cfa3000kbd ) +//------------------------------------------------- + +static INPUT_PORTS_START( cfa3000kbd ) + PORT_START("KBD.0") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Pattern ->") PORT_CODE(KEYCODE_STOP) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Pattern <-") PORT_CODE(KEYCODE_COMMA) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Patient Response") PORT_CODE(KEYCODE_SPACE) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Present Stimuli") PORT_CODE(KEYCODE_S) + PORT_START("KBD.1") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Up") PORT_CODE(KEYCODE_UP) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Left/Menu") PORT_CODE(KEYCODE_LEFT) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Right/Extend") PORT_CODE(KEYCODE_RIGHT) + PORT_START("KBD.2") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) + PORT_START("KBD.3") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Mode") PORT_CODE(KEYCODE_M) + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Erase") PORT_CODE(KEYCODE_E) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Restart") PORT_CODE(KEYCODE_R) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Print") PORT_CODE(KEYCODE_P) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor cfa3000_kbd_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( cfa3000kbd ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// cfa3000_kbd_device - constructor +//------------------------------------------------- + +cfa3000_kbd_device::cfa3000_kbd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, CFA3000_KBD, tag, owner, clock), + device_bbc_userport_interface(mconfig, *this), + m_kbd(*this, "KBD.%u", 0) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void cfa3000_kbd_device::device_start() +{ +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void cfa3000_kbd_device::device_reset() +{ +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ8_MEMBER(cfa3000_kbd_device::pb_r) +{ + uint8_t data = 0x00; + + if (m_kbd[0]->read()) + { + data = m_kbd[0]->read() >> 1; + data = 0xf0 | (BIT(data, 2) ? 0x03 : data); + } + if (m_kbd[1]->read()) + { + data = m_kbd[1]->read() >> 1; + data = 0xf4 | (BIT(data, 2) ? 0x03 : data); + } + if (m_kbd[2]->read()) + { + data = m_kbd[2]->read() >> 1; + data = 0xf8 | (BIT(data, 2) ? 0x03 : data); + } + if (m_kbd[3]->read()) + { + data = m_kbd[3]->read() >> 1; + data = 0xfc | (BIT(data, 2) ? 0x03 : data); + } + return data; +} diff --git a/src/devices/bus/bbc/userport/cfa3000kbd.h b/src/devices/bus/bbc/userport/cfa3000kbd.h new file mode 100644 index 00000000000..2ece3cbf380 --- /dev/null +++ b/src/devices/bus/bbc/userport/cfa3000kbd.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Henson CFA 3000 Keyboard + +**********************************************************************/ + + +#ifndef MAME_BUS_BBC_USERPORT_CFA3000KBD_H +#define MAME_BUS_BBC_USERPORT_CFA3000KBD_H + +#pragma once + +#include "userport.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> cfa3000_kbd_device + +class cfa3000_kbd_device : + public device_t, + public device_bbc_userport_interface +{ +public: + // construction/destruction + cfa3000_kbd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + + virtual DECLARE_READ8_MEMBER(pb_r) override; + +private: + required_ioport_array<4> m_kbd; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(CFA3000_KBD, cfa3000_kbd_device) + + +#endif // MAME_BUS_BBC_USERPORT_CFA3000KBD_H diff --git a/src/devices/bus/bbc/userport/userport.cpp b/src/devices/bus/bbc/userport/userport.cpp index 51591bbe85e..7df5c0e7f66 100644 --- a/src/devices/bus/bbc/userport/userport.cpp +++ b/src/devices/bus/bbc/userport/userport.cpp @@ -14,7 +14,7 @@ // GLOBAL VARIABLES //************************************************************************** -DEFINE_DEVICE_TYPE(BBC_USERPORT_SLOT, bbc_userport_device, "bbc_userport_slot", "BBC Micro User port") +DEFINE_DEVICE_TYPE(BBC_USERPORT_SLOT, bbc_userport_slot_device, "bbc_userport_slot", "BBC Micro User port") @@ -29,7 +29,7 @@ DEFINE_DEVICE_TYPE(BBC_USERPORT_SLOT, bbc_userport_device, "bbc_userport_slot", device_bbc_userport_interface::device_bbc_userport_interface(const machine_config &mconfig, device_t &device) : device_slot_card_interface(mconfig, device) { - m_slot = dynamic_cast<bbc_userport_device *>(device.owner()); + m_slot = dynamic_cast<bbc_userport_slot_device *>(device.owner()); } @@ -51,38 +51,61 @@ device_bbc_userport_interface::~device_bbc_userport_interface() // bbc_userport_slot_device - constructor //------------------------------------------------- -bbc_userport_device::bbc_userport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +bbc_userport_slot_device::bbc_userport_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, BBC_USERPORT_SLOT, tag, owner, clock), - device_slot_interface(mconfig, *this), m_device(nullptr) + device_slot_interface(mconfig, *this), + m_device(nullptr), + m_cb1_handler(*this), + m_cb2_handler(*this) { } + //------------------------------------------------- -// ~bbc_userport_slot_device - destructor +// device_start - device-specific startup //------------------------------------------------- -//bbc_userport_device::~bbc_userport_device() -//{ -//} +void bbc_userport_slot_device::device_start() +{ + m_device = dynamic_cast<device_bbc_userport_interface *>(get_card_device()); + + // resolve callbacks + m_cb1_handler.resolve_safe(); + m_cb2_handler.resolve_safe(); +} //------------------------------------------------- -// device_start - device-specific startup +// device_reset - device-specific reset //------------------------------------------------- -void bbc_userport_device::device_start() +void bbc_userport_slot_device::device_reset() { - m_device = dynamic_cast<device_bbc_userport_interface *>(get_card_device()); } -uint8_t bbc_userport_device::read_portb() +//------------------------------------------------- +// pb_r +//------------------------------------------------- + +READ8_MEMBER(bbc_userport_slot_device::pb_r) +{ + if (m_device) + return m_device->pb_r(space, 0); + else + return 0xff; +} + + +//------------------------------------------------- +// pb_w +//------------------------------------------------- + +WRITE8_MEMBER(bbc_userport_slot_device::pb_w) { - uint8_t data = 0xff; if (m_device) - data |= m_device->read_portb(); - return data; + m_device->pb_w(space, 0, data); } @@ -92,12 +115,14 @@ uint8_t bbc_userport_device::read_portb() // slot devices -//#include "amxmouse.h" -//#include "tracker.h" +//#include "mouse.h" +#include "cfa3000kbd.h" SLOT_INTERFACE_START( bbc_userport_devices ) -// SLOT_INTERFACE("amxmouse", BBC_AMXMOUSE) /* AMX Mouse */ -// SLOT_INTERFACE("tracker", BBC_TRACKER) /* Acorn Tracker Ball */ +// SLOT_INTERFACE("amxmouse", BBC_AMXMOUSE) /* AMX Mouse */ +// SLOT_INTERFACE("m512mouse", BBC_M512MOUSE) /* Acorn Mouse (provided with Master 512) */ +// SLOT_INTERFACE("tracker", BBC_TRACKER) /* Marconi RB2 Tracker Ball / Acorn Tracker Ball */ // SLOT_INTERFACE("music4000", BBC_MUSIC4000) /* Hybrid Music 4000 Keyboard */ + SLOT_INTERFACE("cfa3000kbd", CFA3000_KBD) /* Henson CFA 3000 Keyboard */ SLOT_INTERFACE_END diff --git a/src/devices/bus/bbc/userport/userport.h b/src/devices/bus/bbc/userport/userport.h index 0db9464af32..632ad412f63 100644 --- a/src/devices/bus/bbc/userport/userport.h +++ b/src/devices/bus/bbc/userport/userport.h @@ -31,70 +31,81 @@ #pragma once + //************************************************************************** -// TYPE DEFINITIONS +// INTERFACE CONFIGURATION MACROS //************************************************************************** -class bbc_userport_device; +#define MCFG_BBC_USERPORT_SLOT_ADD(_tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, BBC_USERPORT_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) -// ======================> device_bbc_userport_interface +#define MCFG_BBC_USERPORT_CB1_HANDLER(_devcb) \ + devcb = &bbc_userport_slot_device::set_cb1_handler(*device, DEVCB_##_devcb); -class device_bbc_userport_interface : public device_slot_card_interface -{ -public: - // construction/destruction - virtual ~device_bbc_userport_interface(); +#define MCFG_BBC_USERPORT_CB2_HANDLER(_devcb) \ + devcb = &bbc_userport_slot_device::set_cb2_handler(*device, DEVCB_##_devcb); - virtual uint8_t read_portb() { return 0xff; }; - virtual uint8_t read_cb1() { return 0xff; }; - virtual uint8_t read_cb2() { return 0xff; }; +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** -protected: - device_bbc_userport_interface(const machine_config &mconfig, device_t &device); - bbc_userport_device *m_slot; -}; +// ======================> bbc_userport_slot_device -// ======================> bbc_userport_device +class device_bbc_userport_interface; -class bbc_userport_device : public device_t, - public device_slot_interface +class bbc_userport_slot_device : public device_t, public device_slot_interface { public: // construction/destruction - bbc_userport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + bbc_userport_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // callbacks + template <class Object> static devcb_base &set_cb1_handler(device_t &device, Object &&cb) + { return downcast<bbc_userport_slot_device &>(device).m_cb1_handler.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_cb2_handler(device_t &device, Object &&cb) + { return downcast<bbc_userport_slot_device &>(device).m_cb2_handler.set_callback(std::forward<Object>(cb)); } - uint8_t read_portb(); - uint8_t read_cb1(); - uint8_t read_cb2(); + DECLARE_WRITE_LINE_MEMBER(cb1_w) { m_cb1_handler(state); } + DECLARE_WRITE_LINE_MEMBER(cb2_w) { m_cb2_handler(state); } + DECLARE_READ8_MEMBER(pb_r); + DECLARE_WRITE8_MEMBER(pb_w); + +protected: // device-level overrides virtual void device_start() override; + virtual void device_reset() override; -protected: device_bbc_userport_interface *m_device; + +private: + devcb_write_line m_cb1_handler; + devcb_write_line m_cb2_handler; }; -// device type definition -DECLARE_DEVICE_TYPE(BBC_USERPORT_SLOT, bbc_userport_device) +// ======================> device_bbc_userport_interface -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** +class device_bbc_userport_interface : public device_slot_card_interface +{ +public: + // construction/destruction + virtual ~device_bbc_userport_interface(); -#define MCFG_BBC_USERPORT_SLOT_ADD(_tag, _slot_intf, _def_slot) \ - MCFG_DEVICE_ADD(_tag, BBC_USERPORT_SLOT, 0) \ - MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + virtual DECLARE_READ8_MEMBER(pb_r) { return 0xff; } + virtual DECLARE_WRITE8_MEMBER(pb_w) { } -#define MCFG_BBC_USERPORT_PB_HANDLER(_devcb) \ - devcb = &bbc_userport_device::set_pb_handler(*device, DEVCB_##_devcb); +protected: + device_bbc_userport_interface(const machine_config &mconfig, device_t &device); -#define MCFG_BBC_USERPORT_CB1_HANDLER(_devcb) \ - devcb = &bbc_userport_device::set_cb1_handler(*device, DEVCB_##_devcb); + bbc_userport_slot_device *m_slot; +}; -#define MCFG_BBC_USERPORT_CB2_HANDLER(_devcb) \ - devcb = &bbc_userport_device::set_cb2_handler(*device, DEVCB_##_devcb); + +// device type definition +DECLARE_DEVICE_TYPE(BBC_USERPORT_SLOT, bbc_userport_slot_device) SLOT_INTERFACE_EXTERN( bbc_userport_devices ); diff --git a/src/devices/bus/c64/midi_maplin.cpp b/src/devices/bus/c64/midi_maplin.cpp index 1550d761055..5e5b751ecc6 100644 --- a/src/devices/bus/c64/midi_maplin.cpp +++ b/src/devices/bus/c64/midi_maplin.cpp @@ -107,11 +107,8 @@ uint8_t c64_maplin_midi_cartridge_device::c64_cd_r(address_space &space, offs_t switch (offset & 0xff) { case 0: - data = m_acia->status_r(space, 0); - break; - case 1: - data = m_acia->data_r(space, 0); + data = m_acia->read(space, offset & 1); break; } } @@ -131,11 +128,8 @@ void c64_maplin_midi_cartridge_device::c64_cd_w(address_space &space, offs_t off switch (offset & 0xff) { case 0: - m_acia->control_w(space, 0, data); - break; - case 1: - m_acia->data_w(space, 0, data); + m_acia->write(space, offset & 1, data); break; } } diff --git a/src/devices/bus/c64/midi_namesoft.cpp b/src/devices/bus/c64/midi_namesoft.cpp index 6f9a1f855db..db32a283189 100644 --- a/src/devices/bus/c64/midi_namesoft.cpp +++ b/src/devices/bus/c64/midi_namesoft.cpp @@ -105,11 +105,8 @@ uint8_t c64_namesoft_midi_cartridge_device::c64_cd_r(address_space &space, offs_ switch (offset & 0xff) { case 2: - data = m_acia->status_r(space, 0); - break; - case 3: - data = m_acia->data_r(space, 0); + data = m_acia->read(space, offset & 1); break; } } @@ -129,11 +126,8 @@ void c64_namesoft_midi_cartridge_device::c64_cd_w(address_space &space, offs_t o switch (offset & 0xff) { case 0: - m_acia->control_w(space, 0, data); - break; - case 1: - m_acia->data_w(space, 0, data); + m_acia->write(space, offset & 1, data); break; } } diff --git a/src/devices/bus/c64/midi_passport.cpp b/src/devices/bus/c64/midi_passport.cpp index cc7761906bb..34c77eeef28 100644 --- a/src/devices/bus/c64/midi_passport.cpp +++ b/src/devices/bus/c64/midi_passport.cpp @@ -135,12 +135,8 @@ uint8_t c64_passport_midi_cartridge_device::c64_cd_r(address_space &space, offs_ data = m_ptm->read(space, offset & 0x07); break; - case 8: - data = m_acia->status_r(space, 0); - break; - - case 9: - data = m_acia->data_r(space, 0); + case 8: case 9: + data = m_acia->read(space, offset & 0x01); break; } } @@ -164,12 +160,8 @@ void c64_passport_midi_cartridge_device::c64_cd_w(address_space &space, offs_t o m_ptm->write(space, offset & 0x07, data); break; - case 8: - m_acia->control_w(space, 0, data); - break; - - case 9: - m_acia->data_w(space, 0, data); + case 8: case 9: + m_acia->write(space, offset & 0x01, data); break; case 0x30: diff --git a/src/devices/bus/c64/midi_sci.cpp b/src/devices/bus/c64/midi_sci.cpp index efdea06b435..ef4e79e0f53 100644 --- a/src/devices/bus/c64/midi_sci.cpp +++ b/src/devices/bus/c64/midi_sci.cpp @@ -106,11 +106,8 @@ uint8_t c64_sequential_midi_cartridge_device::c64_cd_r(address_space &space, off switch (offset & 0xff) { case 2: - data = m_acia->status_r(space, 0); - break; - case 3: - data = m_acia->data_r(space, 0); + data = m_acia->read(space, offset & 1); break; } } @@ -130,11 +127,8 @@ void c64_sequential_midi_cartridge_device::c64_cd_w(address_space &space, offs_t switch (offset & 0xff) { case 0: - m_acia->control_w(space, 0, data); - break; - case 1: - m_acia->data_w(space, 0, data); + m_acia->write(space, offset & 1, data); break; } } diff --git a/src/devices/bus/c64/midi_siel.cpp b/src/devices/bus/c64/midi_siel.cpp index 3b6feec98fc..d4b56e90535 100644 --- a/src/devices/bus/c64/midi_siel.cpp +++ b/src/devices/bus/c64/midi_siel.cpp @@ -107,11 +107,8 @@ uint8_t c64_siel_midi_cartridge_device::c64_cd_r(address_space &space, offs_t of switch (offset & 0xff) { case 6: - data = m_acia->status_r(space, 0); - break; - case 7: - data = m_acia->data_r(space, 0); + data = m_acia->read(space, offset & 1); break; } } @@ -131,11 +128,8 @@ void c64_siel_midi_cartridge_device::c64_cd_w(address_space &space, offs_t offse switch (offset & 0xff) { case 4: - m_acia->control_w(space, 0, data); - break; - case 5: - m_acia->data_w(space, 0, data); + m_acia->write(space, offset & 1, data); break; } } diff --git a/src/devices/bus/cbmiec/c1571.cpp b/src/devices/bus/cbmiec/c1571.cpp index adf1f3ab043..686b2028b39 100644 --- a/src/devices/bus/cbmiec/c1571.cpp +++ b/src/devices/bus/cbmiec/c1571.cpp @@ -737,7 +737,7 @@ MACHINE_CONFIG_MEMBER( mini_chief_device::device_add_mconfig ) MCFG_FLOPPY_DRIVE_ADD_FIXED(C64H156_TAG":0", c1571_floppies, "525qd", c1571_device::floppy_formats) MCFG_DEVICE_ADD(ISA_BUS_TAG, ISA8, 0) - MCFG_ISA8_CPU(M6502_TAG) + MCFG_ISA8_CPU("^" M6502_TAG) MCFG_ISA8_SLOT_ADD(ISA_BUS_TAG, "isa1", mini_chief_isa8_cards, "wd1002a_wx1", false) MACHINE_CONFIG_END diff --git a/src/devices/bus/cbmiec/interpod.cpp b/src/devices/bus/cbmiec/interpod.cpp index d645e065513..7cceb9ed970 100644 --- a/src/devices/bus/cbmiec/interpod.cpp +++ b/src/devices/bus/cbmiec/interpod.cpp @@ -112,8 +112,7 @@ const tiny_rom_entry *interpod_device::device_rom_region() const static ADDRESS_MAP_START( interpod_mem, AS_PROGRAM, 8, interpod_device ) AM_RANGE(0x0000, 0x007f) AM_MIRROR(0x3b80) AM_DEVICE(R6532_TAG, mos6532_new_device, ram_map) AM_RANGE(0x0400, 0x041f) AM_MIRROR(0x3be0) AM_DEVICE(R6532_TAG, mos6532_new_device, io_map) - AM_RANGE(0x2000, 0x2000) AM_MIRROR(0x9ffe) AM_DEVREADWRITE(MC6850_TAG, acia6850_device, status_r, control_w) - AM_RANGE(0x2001, 0x2001) AM_MIRROR(0x9ffe) AM_DEVREADWRITE(MC6850_TAG, acia6850_device, data_r, data_w) + AM_RANGE(0x2000, 0x2001) AM_MIRROR(0x9ffe) AM_DEVREADWRITE(MC6850_TAG, acia6850_device, read, write) AM_RANGE(0x4000, 0x47ff) AM_MIRROR(0xb800) AM_ROM AM_REGION(R6502_TAG, 0) AM_RANGE(0x8000, 0x800f) AM_MIRROR(0x5ff0) AM_DEVREADWRITE(R6522_TAG, via6522_device, read, write) ADDRESS_MAP_END diff --git a/src/devices/bus/cbus/pc9801_118.cpp b/src/devices/bus/cbus/pc9801_118.cpp index d28ab186c2c..57d99ff4d29 100644 --- a/src/devices/bus/cbus/pc9801_118.cpp +++ b/src/devices/bus/cbus/pc9801_118.cpp @@ -137,7 +137,7 @@ void pc9801_118_device::device_validity_check(validity_checker &valid) const void pc9801_118_device::install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler) { - int buswidth = machine().firstcpu->space_config(AS_IO)->m_databus_width; + int buswidth = machine().firstcpu->space_config(AS_IO)->m_data_width; switch(buswidth) { case 8: diff --git a/src/devices/bus/cbus/pc9801_26.cpp b/src/devices/bus/cbus/pc9801_26.cpp index 7b16eea2d65..b9e2d84eb3d 100644 --- a/src/devices/bus/cbus/pc9801_26.cpp +++ b/src/devices/bus/cbus/pc9801_26.cpp @@ -130,7 +130,7 @@ void pc9801_26_device::device_validity_check(validity_checker &valid) const void pc9801_26_device::install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler) { - int buswidth = machine().firstcpu->space_config(AS_IO)->m_databus_width; + int buswidth = machine().firstcpu->space_config(AS_IO)->m_data_width; switch(buswidth) { case 8: diff --git a/src/devices/bus/cbus/pc9801_86.cpp b/src/devices/bus/cbus/pc9801_86.cpp index 547ddb634a6..7736bf93d95 100644 --- a/src/devices/bus/cbus/pc9801_86.cpp +++ b/src/devices/bus/cbus/pc9801_86.cpp @@ -148,7 +148,7 @@ void pc9801_86_device::device_validity_check(validity_checker &valid) const void pc9801_86_device::install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler) { - int buswidth = machine().firstcpu->space_config(AS_IO)->m_databus_width; + int buswidth = machine().firstcpu->space_config(AS_IO)->m_data_width; switch(buswidth) { case 8: diff --git a/src/devices/bus/cbus/pc9801_amd98.cpp b/src/devices/bus/cbus/pc9801_amd98.cpp index 11e92d8e292..ecb8b9343d8 100644 --- a/src/devices/bus/cbus/pc9801_amd98.cpp +++ b/src/devices/bus/cbus/pc9801_amd98.cpp @@ -125,7 +125,7 @@ void pc9801_amd98_device::device_validity_check(validity_checker &valid) const void pc9801_amd98_device::install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler) { - int buswidth = machine().firstcpu->space_config(AS_IO)->m_databus_width; + int buswidth = machine().firstcpu->space_config(AS_IO)->m_data_width; switch(buswidth) { case 8: diff --git a/src/devices/bus/coco/coco_dcmodem.cpp b/src/devices/bus/coco/coco_dcmodem.cpp index 67c6707e53e..77206445bb0 100644 --- a/src/devices/bus/coco/coco_dcmodem.cpp +++ b/src/devices/bus/coco/coco_dcmodem.cpp @@ -12,6 +12,8 @@ ***************************************************************************/ #include "emu.h" +#include "coco_dcmodem.h" + #include "cococart.h" #include "machine/mos6551.h" diff --git a/src/devices/bus/coco/coco_dcmodem.h b/src/devices/bus/coco/coco_dcmodem.h new file mode 100644 index 00000000000..e80f33be656 --- /dev/null +++ b/src/devices/bus/coco/coco_dcmodem.h @@ -0,0 +1,12 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods + +#ifndef MAME_BUS_COCO_COCO_DCMODEM_H +#define MAME_BUS_COCO_COCO_DCMODEM_H + +#pragma once + +// device type definition +extern const device_type COCO_DCMODEM; + +#endif // MAME_BUS_COCO_COCO_DCMODEM_H diff --git a/src/devices/bus/coco/coco_fdc.cpp b/src/devices/bus/coco/coco_fdc.cpp index 89a9d8bd548..01f91976db2 100644 --- a/src/devices/bus/coco/coco_fdc.cpp +++ b/src/devices/bus/coco/coco_fdc.cpp @@ -494,22 +494,27 @@ namespace DEFINE_DEVICE_TYPE(COCO3_HDB1, coco3_hdb1_device, "coco3_hdb1", "CoCo3 HDB-DOS") //************************************************************************** -// CP400 FDC +// Prológica CP-450 BASIC Disco V. 1.0 (1984) +// +// There is a photo of the CP-450 disk controller unit at: +// https://datassette.org/softwares/tandy-trs-color/cp-450-basic-disco-v-10 +// http://files.datassette.org/softwares/img/wp_20141212_22_08_26_pro.jpg +// //************************************************************************** -ROM_START(cp400_fdc) +ROM_START(cp450_fdc) ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) - ROM_LOAD("cp400dsk.rom", 0x0000, 0x2000, CRC(e9ad60a0) SHA1(827697fa5b755f5dc1efb054cdbbeb04e405405b)) + ROM_LOAD("cp450_basic_disco_v1.0.rom", 0x0000, 0x2000, CRC(e9ad60a0) SHA1(827697fa5b755f5dc1efb054cdbbeb04e405405b)) ROM_END namespace { - class cp400_fdc_device : public coco_fdc_device_base + class cp450_fdc_device : public coco_fdc_device_base { public: // construction/destruction - cp400_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : coco_fdc_device_base(mconfig, CP400_FDC, tag, owner, clock) + cp450_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : coco_fdc_device_base(mconfig, CP450_FDC, tag, owner, clock) { } @@ -517,9 +522,43 @@ namespace // optional information overrides virtual const tiny_rom_entry *device_rom_region() const override { - return ROM_NAME(cp400_fdc); + return ROM_NAME(cp450_fdc); } }; } -DEFINE_DEVICE_TYPE(CP400_FDC, cp400_fdc_device, "cp400_fdc", "CP400 FDC") +DEFINE_DEVICE_TYPE(CP450_FDC, cp450_fdc_device, "cp450_fdc", "Prológica CP-450 BASIC Disco V. 1.0 (1984)") + +//************************************************************************** +// Codimex CD-6809 FDC (1986) +// +// Seems to be a clone of the JFD-COCO originally manufactured by J&M +// More ifo at: http://amxproject.com/?p=2747 +//************************************************************************** + +ROM_START(cd6809_fdc) + ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) + ROM_LOAD("cd6809dsk.u16", 0x0000, 0x2000, CRC(3c35bda8) SHA1(9b2eec25188bed4326b84739a666435884e4ddf4)) +ROM_END + +namespace +{ + class cd6809_fdc_device : public coco_fdc_device_base + { + public: + // construction/destruction + cd6809_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : coco_fdc_device_base(mconfig, CD6809_FDC, tag, owner, clock) + { + } + + protected: + // optional information overrides + virtual const tiny_rom_entry *device_rom_region() const override + { + return ROM_NAME(cd6809_fdc); + } + }; +} + +DEFINE_DEVICE_TYPE(CD6809_FDC, cd6809_fdc_device, "cd6809_fdc", "Codimex CD-6809 Disk BASIC (1986)") diff --git a/src/devices/bus/coco/coco_fdc.h b/src/devices/bus/coco/coco_fdc.h index 4cfc2e5a886..7ca2ca9e6fe 100644 --- a/src/devices/bus/coco/coco_fdc.h +++ b/src/devices/bus/coco/coco_fdc.h @@ -60,4 +60,11 @@ private: bool m_drq; }; +// device type definitions - CoCo FDC +extern const device_type COCO_FDC; +extern const device_type COCO_FDC_V11; +extern const device_type COCO3_HDB1; +extern const device_type CP450_FDC; +extern const device_type CD6809_FDC; + #endif // MAME_BUS_COCO_COCO_FDC_H diff --git a/src/devices/bus/coco/coco_gmc.cpp b/src/devices/bus/coco/coco_gmc.cpp index 8e9ac52d4a9..3c257e2b3ef 100644 --- a/src/devices/bus/coco/coco_gmc.cpp +++ b/src/devices/bus/coco/coco_gmc.cpp @@ -17,6 +17,8 @@ ***************************************************************************/ #include "emu.h" +#include "coco_gmc.h" + #include "coco_pak.h" #include "sound/sn76496.h" #include "speaker.h" diff --git a/src/devices/bus/coco/coco_gmc.h b/src/devices/bus/coco/coco_gmc.h new file mode 100644 index 00000000000..1f1ec6654c8 --- /dev/null +++ b/src/devices/bus/coco/coco_gmc.h @@ -0,0 +1,11 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods +#ifndef MAME_BUS_COCO_COCO_GMC_H +#define MAME_BUS_COCO_COCO_GMC_H + +#pragma once + +// device type definition +extern const device_type COCO_PAK_GMC; + +#endif // MAME_BUS_COCO_COCO_GMC_H diff --git a/src/devices/bus/coco/coco_multi.cpp b/src/devices/bus/coco/coco_multi.cpp index 98c1cb96765..8ac57f25f48 100644 --- a/src/devices/bus/coco/coco_multi.cpp +++ b/src/devices/bus/coco/coco_multi.cpp @@ -54,7 +54,16 @@ ***************************************************************************/ #include "emu.h" +#include "coco_multi.h" + #include "cococart.h" +#include "coco_dcmodem.h" +#include "coco_fdc.h" +#include "coco_gmc.h" +#include "coco_orch90.h" +#include "coco_pak.h" +#include "coco_rs232.h" +#include "coco_ssc.h" #define SLOT1_TAG "slot1" #define SLOT2_TAG "slot2" diff --git a/src/devices/bus/coco/coco_multi.h b/src/devices/bus/coco/coco_multi.h new file mode 100644 index 00000000000..5672c42c8e1 --- /dev/null +++ b/src/devices/bus/coco/coco_multi.h @@ -0,0 +1,12 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods + +#ifndef MAME_BUS_COCO_COCO_MULTIPAK_H +#define MAME_BUS_COCO_COCO_MULTIPAK_H + +#pragma once + +// device type definition +extern const device_type COCO_MULTIPAK; + +#endif // MAME_BUS_COCO_COCO_MULTIPAK_H diff --git a/src/devices/bus/coco/coco_orch90.cpp b/src/devices/bus/coco/coco_orch90.cpp index 0b9342c4a71..1263ea8f8d5 100644 --- a/src/devices/bus/coco/coco_orch90.cpp +++ b/src/devices/bus/coco/coco_orch90.cpp @@ -26,6 +26,7 @@ ***************************************************************************/ #include "emu.h" +#include "coco_orch90.h" #include "cococart.h" #include "sound/dac.h" diff --git a/src/devices/bus/coco/coco_orch90.h b/src/devices/bus/coco/coco_orch90.h new file mode 100644 index 00000000000..97cf476d35d --- /dev/null +++ b/src/devices/bus/coco/coco_orch90.h @@ -0,0 +1,12 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods + +#ifndef MAME_BUS_COCO_COCO_ORCH90_H +#define MAME_BUS_COCO_COCO_ORCH90_H + +#pragma once + +// device type definition +extern const device_type COCO_ORCH90; + +#endif // MAME_BUS_COCO_COCO_ORCH90_H diff --git a/src/devices/bus/coco/coco_pak.h b/src/devices/bus/coco/coco_pak.h index a9b46957ca3..6ddfbc6b97e 100644 --- a/src/devices/bus/coco/coco_pak.h +++ b/src/devices/bus/coco/coco_pak.h @@ -64,4 +64,10 @@ private: uint8_t m_pos; }; + +// device type definitions +extern const device_type COCO_PAK; +extern const device_type COCO_PAK_BANKED; +extern const device_type COCO_PAK_GMC; + #endif // MAME_BUS_COCO_COCO_PAK_H diff --git a/src/devices/bus/coco/coco_rs232.cpp b/src/devices/bus/coco/coco_rs232.cpp index bee862b3a5f..fa6344f05b9 100644 --- a/src/devices/bus/coco/coco_rs232.cpp +++ b/src/devices/bus/coco/coco_rs232.cpp @@ -9,6 +9,8 @@ ***************************************************************************/ #include "emu.h" +#include "coco_rs232.h" + #include "cococart.h" #include "machine/mos6551.h" diff --git a/src/devices/bus/coco/coco_rs232.h b/src/devices/bus/coco/coco_rs232.h new file mode 100644 index 00000000000..2076a2c8a4c --- /dev/null +++ b/src/devices/bus/coco/coco_rs232.h @@ -0,0 +1,12 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods + +#ifndef MAME_BUS_COCO_COCO_RS232_H +#define MAME_BUS_COCO_COCO_RS232_H + +#pragma once + +// device type definition +extern const device_type COCO_RS232; + +#endif // MAME_BUS_COCO_COCO_RS232_H diff --git a/src/devices/bus/coco/coco_ssc.cpp b/src/devices/bus/coco/coco_ssc.cpp index 61ae0470540..16adf923aeb 100644 --- a/src/devices/bus/coco/coco_ssc.cpp +++ b/src/devices/bus/coco/coco_ssc.cpp @@ -31,6 +31,8 @@ ***************************************************************************/ #include "emu.h" +#include "coco_ssc.h" + #include "sound/ay8910.h" #include "sound/sp0256.h" #include "machine/netlist.h" @@ -150,16 +152,14 @@ DEFINE_DEVICE_TYPE(COCOSSC_SAC, cocossc_sac_device, "cocossc_sac", "CoCo SSC Sou // MACHINE FRAGMENTS AND ADDRESS MAPS //************************************************************************** -static ADDRESS_MAP_START(ssc_io_map, AS_IO, 8, coco_ssc_device) - AM_RANGE(TMS7000_PORTA, TMS7000_PORTA) AM_READ(ssc_port_a_r) - AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_WRITE(ssc_port_b_w) - AM_RANGE(TMS7000_PORTC, TMS7000_PORTC) AM_READWRITE(ssc_port_c_r, ssc_port_c_w) - AM_RANGE(TMS7000_PORTD, TMS7000_PORTD) AM_READWRITE(ssc_port_d_r, ssc_port_d_w) -ADDRESS_MAP_END - MACHINE_CONFIG_MEMBER(coco_ssc_device::device_add_mconfig) MCFG_CPU_ADD(PIC_TAG, TMS7040, DERIVED_CLOCK(1, 2)) - MCFG_CPU_IO_MAP(ssc_io_map) + MCFG_TMS7000_IN_PORTA_CB(READ8(coco_ssc_device, ssc_port_a_r)) + MCFG_TMS7000_OUT_PORTB_CB(WRITE8(coco_ssc_device, ssc_port_b_w)) + MCFG_TMS7000_IN_PORTC_CB(READ8(coco_ssc_device, ssc_port_c_r)) + MCFG_TMS7000_OUT_PORTC_CB(WRITE8(coco_ssc_device, ssc_port_c_w)) + MCFG_TMS7000_IN_PORTD_CB(READ8(coco_ssc_device, ssc_port_d_r)) + MCFG_TMS7000_OUT_PORTD_CB(WRITE8(coco_ssc_device, ssc_port_d_w)) MCFG_RAM_ADD("staticram") MCFG_RAM_DEFAULT_SIZE("2K") diff --git a/src/devices/bus/coco/coco_ssc.h b/src/devices/bus/coco/coco_ssc.h new file mode 100644 index 00000000000..ce9b3d5e26c --- /dev/null +++ b/src/devices/bus/coco/coco_ssc.h @@ -0,0 +1,12 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods + +#ifndef MAME_BUS_COCO_COCO_SSC_H +#define MAME_BUS_COCO_COCO_SSC_H + +#pragma once + +// device type definition +extern const device_type COCO_SSC; + +#endif // MAME_BUS_COCO_COCO_SSC_H diff --git a/src/devices/bus/coco/coco_t4426.cpp b/src/devices/bus/coco/coco_t4426.cpp index 895df9a5515..5adc451d18a 100644 --- a/src/devices/bus/coco/coco_t4426.cpp +++ b/src/devices/bus/coco/coco_t4426.cpp @@ -43,6 +43,8 @@ ***************************************************************************/ #include "emu.h" +#include "coco_t4426.h" + #include "cococart.h" #include "machine/6850acia.h" #include "bus/rs232/rs232.h" diff --git a/src/devices/bus/coco/coco_t4426.h b/src/devices/bus/coco/coco_t4426.h new file mode 100644 index 00000000000..415b16f50de --- /dev/null +++ b/src/devices/bus/coco/coco_t4426.h @@ -0,0 +1,12 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods + +#ifndef MAME_BUS_COCO_COCO_T4426_H +#define MAME_BUS_COCO_COCO_T4426_H + +#pragma once + +// device type definition +extern const device_type COCO_T4426; + +#endif // MAME_BUS_COCO_COCO_T4426_H diff --git a/src/devices/bus/coco/cococart.h b/src/devices/bus/coco/cococart.h index 0c03446699d..e22e4c55e99 100644 --- a/src/devices/bus/coco/cococart.h +++ b/src/devices/bus/coco/cococart.h @@ -15,24 +15,6 @@ #include "softlist_dev.h" -// The following are modules included by the various CoCo cartridge -// devices. For some reason, the build system will not necessarily -// identify them as dependencies. Adding these #include's here seems -// to rectify the problem -#include "cpu/tms7000/tms7000.h" -#include "machine/mos6551.h" -#include "machine/6850acia.h" -#include "machine/msm6242.h" -#include "machine/ds1315.h" -#include "machine/wd_fdc.h" -#include "sound/ay8910.h" -#include "sound/sp0256.h" -#include "sound/sn76496.h" -#include "formats/dmk_dsk.h" -#include "formats/sdf_dsk.h" -#include "formats/jvc_dsk.h" -#include "formats/vdk_dsk.h" - /*************************************************************************** TYPE DEFINITIONS @@ -233,31 +215,4 @@ private: #define MCFG_COCO_CARTRIDGE_REMOVE(_tag) \ MCFG_DEVICE_REMOVE(_tag) - -/*************************************************************************** - COCO CARTRIDGE DEVICES -***************************************************************************/ - -// device type definitions - CoCo FDC -extern const device_type COCO_FDC; -extern const device_type COCO_FDC_V11; -extern const device_type COCO3_HDB1; -extern const device_type CP400_FDC; - -// device type definitions - Dragon FDC -extern const device_type DRAGON_FDC; -extern const device_type SDTANDY_FDC; - -// device type definitions - other -extern const device_type COCO_ORCH90; -extern const device_type COCO_MULTIPAK; -extern const device_type COCO_RS232; -extern const device_type COCO_DCMODEM; -extern const device_type COCO_SSC; -extern const device_type COCO_PAK; -extern const device_type COCO_PAK_BANKED; -extern const device_type COCO_PAK_GMC; -extern const device_type COCO_T4426; -extern const device_type DRAGON_JCBSND; - #endif // MAME_BUS_COCO_COCOCART_H diff --git a/src/devices/bus/coco/dragon_fdc.cpp b/src/devices/bus/coco/dragon_fdc.cpp index 42e1ee7a13b..97f4cb325ac 100644 --- a/src/devices/bus/coco/dragon_fdc.cpp +++ b/src/devices/bus/coco/dragon_fdc.cpp @@ -66,6 +66,8 @@ *********************************************************************/ #include "emu.h" +#include "dragon_fdc.h" + #include "cococart.h" #include "coco_fdc.h" #include "imagedev/flopdrv.h" diff --git a/src/devices/bus/coco/dragon_fdc.h b/src/devices/bus/coco/dragon_fdc.h new file mode 100644 index 00000000000..6377e867003 --- /dev/null +++ b/src/devices/bus/coco/dragon_fdc.h @@ -0,0 +1,13 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods + +#ifndef MAME_BUS_COCO_DRAGON_FDC_H +#define MAME_BUS_COCO_DRAGON_FDC_H + +#pragma once + +// device type definitions - Dragon FDC +extern const device_type DRAGON_FDC; +extern const device_type SDTANDY_FDC; + +#endif // MAME_BUS_COCO_DRAGON_FDC_H diff --git a/src/devices/bus/einstein/pipe.cpp b/src/devices/bus/einstein/pipe/pipe.cpp index 9a44d86dcdf..51169544ba7 100644 --- a/src/devices/bus/einstein/pipe.cpp +++ b/src/devices/bus/einstein/pipe/pipe.cpp @@ -10,6 +10,8 @@ #include "pipe.h" // supported devices +#include "silicon_disc.h" +#include "speculator.h" #include "tk02.h" @@ -54,6 +56,9 @@ tatung_pipe_device::~tatung_pipe_device() void tatung_pipe_device::device_start() { + // get inserted module + m_card = dynamic_cast<device_tatung_pipe_interface *>(get_card_device()); + // resolve callbacks m_int_handler.resolve_safe(); m_nmi_handler.resolve_safe(); @@ -69,6 +74,16 @@ void tatung_pipe_device::device_reset() } //------------------------------------------------- +// host to module interface +//------------------------------------------------- + +WRITE_LINE_MEMBER( tatung_pipe_device::host_int_w ) +{ + if (m_card) + m_card->int_w(state); +} + +//------------------------------------------------- // set_program_space - set address space we are attached to //------------------------------------------------- @@ -115,5 +130,7 @@ device_tatung_pipe_interface::~device_tatung_pipe_interface() //************************************************************************** SLOT_INTERFACE_START( tatung_pipe_cards ) + SLOT_INTERFACE("silicon_disc", EINSTEIN_SILICON_DISC) + SLOT_INTERFACE("speculator", EINSTEIN_SPECULATOR) SLOT_INTERFACE("tk02", TK02_80COL) SLOT_INTERFACE_END diff --git a/src/devices/bus/einstein/pipe.h b/src/devices/bus/einstein/pipe/pipe.h index d9911ff94d7..02be494cb2e 100644 --- a/src/devices/bus/einstein/pipe.h +++ b/src/devices/bus/einstein/pipe/pipe.h @@ -39,8 +39,8 @@ ***************************************************************************/ -#ifndef MAME_BUS_EINSTEIN_PIPE_H -#define MAME_BUS_EINSTEIN_PIPE_H +#ifndef MAME_BUS_EINSTEIN_PIPE_PIPE_H +#define MAME_BUS_EINSTEIN_PIPE_PIPE_H #pragma once @@ -90,6 +90,9 @@ public: template <class Object> static devcb_base &set_reset_handler(device_t &device, Object &&cb) { return downcast<tatung_pipe_device &>(device).m_reset_handler.set_callback(std::forward<Object>(cb)); } + // called from host + DECLARE_WRITE_LINE_MEMBER( host_int_w ); + // called from card device DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int_handler(state); } DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); } @@ -119,6 +122,9 @@ public: device_tatung_pipe_interface(const machine_config &mconfig, device_t &device); virtual ~device_tatung_pipe_interface(); + // host to card + virtual void int_w(int state) { } + protected: address_space &program_space() { return *m_slot->m_program; } address_space &io_space() { return *m_slot->m_io; } @@ -132,4 +138,4 @@ DECLARE_DEVICE_TYPE(TATUNG_PIPE, tatung_pipe_device) // supported devices SLOT_INTERFACE_EXTERN(tatung_pipe_cards); -#endif // MAME_BUS_EINSTEIN_PIPE_H +#endif // MAME_BUS_EINSTEIN_PIPE_PIPE_H diff --git a/src/devices/bus/einstein/pipe/silicon_disc.cpp b/src/devices/bus/einstein/pipe/silicon_disc.cpp new file mode 100644 index 00000000000..354ada1c594 --- /dev/null +++ b/src/devices/bus/einstein/pipe/silicon_disc.cpp @@ -0,0 +1,119 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Silicon Disc + +***************************************************************************/ + +#include "emu.h" +#include "silicon_disc.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(EINSTEIN_SILICON_DISC, einstein_silicon_disc_device, "einstein_sd", "Einstein Silicon Disc") + +//------------------------------------------------- +// device_address_map +//------------------------------------------------- + +DEVICE_ADDRESS_MAP_START(map, 8, einstein_silicon_disc_device) + AM_RANGE(0x08, 0x08) AM_MIRROR(0xff00) AM_WRITE(sector_low_w) + AM_RANGE(0x09, 0x09) AM_MIRROR(0xff00) AM_WRITE(sector_high_w) +ADDRESS_MAP_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +ROM_START( silicon_disc ) + ROM_REGION(0x2000, "rom", 0) + ROM_LOAD("sd11.bin", 0x0000, 0x2000, CRC(0e4f5e6d) SHA1(d0bc01e533d8963c596154435c5b2d156a96d470)) +ROM_END + +const tiny_rom_entry *einstein_silicon_disc_device::device_rom_region() const +{ + return ROM_NAME( silicon_disc ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// einstein_silicon_disc_device - constructor +//------------------------------------------------- + +einstein_silicon_disc_device::einstein_silicon_disc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, EINSTEIN_SILICON_DISC, tag, owner, clock), + device_tatung_pipe_interface(mconfig, *this), + m_rom(*this, "rom"), + m_bios(*this, ":bios"), + m_sector(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void einstein_silicon_disc_device::device_start() +{ + // setup ram + m_ram = std::make_unique<uint8_t[]>(0x40000); + memset(m_ram.get(), 0xff, 0x40000); + + // register for save states + save_pointer(NAME(m_ram.get()), 0x40000); + save_item(NAME(m_sector)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void einstein_silicon_disc_device::device_reset() +{ + // copy our rom into the main bios region so it will get picked up by the bank switching + // not really part of the pipe interface cartridge but here for convenience, in reality + // the rom gets put directly onto the main motherboard into the second empty socket + memcpy(m_bios->base() + 0x4000, m_rom->base(), 0x2000); + + // install i/o ports + io_space().install_device(0xf0, 0xff, *this, &einstein_silicon_disc_device::map); + io_space().install_readwrite_handler(0xfa, 0xfa, 0, 0, 0xff00, + read8_delegate(FUNC(einstein_silicon_disc_device::ram_r), this), + write8_delegate(FUNC(einstein_silicon_disc_device::ram_w), this)); +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +WRITE8_MEMBER( einstein_silicon_disc_device::sector_low_w ) +{ + m_sector &= 0xff00; + m_sector |= data; +} + +WRITE8_MEMBER( einstein_silicon_disc_device::sector_high_w ) +{ + m_sector &= 0x00ff; + m_sector |= ((data & 0x07) << 8); +} + +// a8 to a14 are used to specify the byte in a 128-byte sector +READ8_MEMBER( einstein_silicon_disc_device::ram_r ) +{ + return m_ram[(m_sector * 0x80) | ((offset >> 8) & 0x7f)]; +} + +WRITE8_MEMBER( einstein_silicon_disc_device::ram_w ) +{ + m_ram[(m_sector * 0x80) | ((offset >> 8) & 0x7f)] = data; +} diff --git a/src/devices/bus/einstein/pipe/silicon_disc.h b/src/devices/bus/einstein/pipe/silicon_disc.h new file mode 100644 index 00000000000..9a4a8caf85d --- /dev/null +++ b/src/devices/bus/einstein/pipe/silicon_disc.h @@ -0,0 +1,54 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Silicon Disc + + A 256k RAM drive that gets accessed as drive 3. + +***************************************************************************/ + +#ifndef MAME_BUS_EINSTEIN_SILICON_DISC_H +#define MAME_BUS_EINSTEIN_SILICON_DISC_H + +#pragma once + +#include "pipe.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> einstein_silicon_disc_device + +class einstein_silicon_disc_device : public device_t, public device_tatung_pipe_interface +{ +public: + // construction/destruction + einstein_silicon_disc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_WRITE8_MEMBER(sector_low_w); + DECLARE_WRITE8_MEMBER(sector_high_w); + DECLARE_READ8_MEMBER(ram_r); + DECLARE_WRITE8_MEMBER(ram_w); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + DECLARE_ADDRESS_MAP(map, 8); + + required_memory_region m_rom; + required_memory_region m_bios; + + std::unique_ptr<uint8_t[]> m_ram; + uint16_t m_sector; +}; + +// device type definition +DECLARE_DEVICE_TYPE(EINSTEIN_SILICON_DISC, einstein_silicon_disc_device) + +#endif // MAME_BUS_EINSTEIN_SILICON_DISC_H diff --git a/src/devices/bus/einstein/pipe/speculator.cpp b/src/devices/bus/einstein/pipe/speculator.cpp new file mode 100644 index 00000000000..51918b018ca --- /dev/null +++ b/src/devices/bus/einstein/pipe/speculator.cpp @@ -0,0 +1,206 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Speculator + + TODO: Not working, based on the schematics of the Memotech MTX version + +***************************************************************************/ + +#include "emu.h" +#include "speculator.h" +#include "machine/rescap.h" +#include "sound/wave.h" +#include "formats/tzx_cas.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(EINSTEIN_SPECULATOR, einstein_speculator_device, "einstein_speculator", "Einstein Speculator") + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER( einstein_speculator_device::device_add_mconfig ) + MCFG_DEVICE_ADD("ic5a", TTL74123, 0) + MCFG_TTL74123_CONNECTION_TYPE(TTL74123_NOT_GROUNDED_NO_DIODE) + MCFG_TTL74123_RESISTOR_VALUE(RES_K(47)) + MCFG_TTL74123_CAPACITOR_VALUE(CAP_P(560)) + MCFG_TTL74123_A_PIN_VALUE(1) + MCFG_TTL74123_B_PIN_VALUE(1) + MCFG_TTL74123_CLEAR_PIN_VALUE(0) + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(einstein_speculator_device, ic5a_q_w)) + + MCFG_DEVICE_ADD("ic5b", TTL74123, 0) + MCFG_TTL74123_CONNECTION_TYPE(TTL74123_NOT_GROUNDED_NO_DIODE) + MCFG_TTL74123_RESISTOR_VALUE(RES_K(47)) + MCFG_TTL74123_CAPACITOR_VALUE(CAP_P(560)) + MCFG_TTL74123_A_PIN_VALUE(1) + MCFG_TTL74123_B_PIN_VALUE(1) + MCFG_TTL74123_CLEAR_PIN_VALUE(0) + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(einstein_speculator_device, ic5b_q_w)) + + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_WAVE_ADD(WAVE_TAG, "cassette") + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) + MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + + MCFG_CASSETTE_ADD("cassette") + MCFG_CASSETTE_FORMATS(tzx_cassette_formats) + MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED) + MCFG_CASSETTE_INTERFACE("spectrum_cass") +MACHINE_CONFIG_END + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// einstein_speculator_device - constructor +//------------------------------------------------- + +einstein_speculator_device::einstein_speculator_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, EINSTEIN_SPECULATOR, tag, owner, clock), + device_tatung_pipe_interface(mconfig, *this), + m_ic5a(*this, "ic5a"), m_ic5b(*this, "ic5b"), + m_cassette(*this, "cassette"), + m_speaker(*this, "speaker"), + m_nmisel(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void einstein_speculator_device::device_start() +{ + // setup ram + m_ram = std::make_unique<uint8_t[]>(0x800); + memset(m_ram.get(), 0xff, 0x800); + + // register for save states + save_pointer(NAME(m_ram.get()), 0x800); + save_item(NAME(m_nmisel)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void einstein_speculator_device::device_reset() +{ + // ram: range 0x1f, 0x3f, 0x5f, 0x7f, 0x9f, 0xbf, 0xdf, 0xff + io_space().install_readwrite_handler(0x1f, 0x1f, 0, 0, 0xffe0, + read8_delegate(FUNC(einstein_speculator_device::ram_r), this), + write8_delegate(FUNC(einstein_speculator_device::ram_w), this)); + + // ram: range 0x60 - 0xff + io_space().install_readwrite_handler(0x60, 0x60, 0, 0, 0xff9f, + read8_delegate(FUNC(einstein_speculator_device::ram_r), this), + write8_delegate(FUNC(einstein_speculator_device::ram_w), this)); + + // tape read/nmi write register: range 0xff + io_space().install_readwrite_handler(0xff, 0xff, 0, 0, 0xff00, + read8_delegate(FUNC(einstein_speculator_device::tape_r), this), + write8_delegate(FUNC(einstein_speculator_device::nmi_w), this)); +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +WRITE_LINE_MEMBER( einstein_speculator_device::ic5a_q_w ) +{ + m_ic5b->a_w(state); + + if (m_nmisel == 1) + { + logerror("imm nmi: %d\n", state); + m_slot->nmi_w(state); + } +} + +WRITE_LINE_MEMBER( einstein_speculator_device::ic5b_q_w ) +{ + if (m_nmisel == 0) + { + logerror("del nmi: %d\n", state); + m_slot->nmi_w(state); + } +} + +void einstein_speculator_device::int_w(int state) +{ + logerror("int_w: %d\n", state); + m_ic5a->a_w(!state); +} + +// pal ic4 +offs_t einstein_speculator_device::address_translate(offs_t offset) +{ + int ra3, ra2, ra1, ra0; + + ra3 = !BIT(offset, 7) && BIT(offset, 0); + + ra2 = BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 13) && BIT(offset, 12) && !BIT(offset, 11); + ra2 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 13) && BIT(offset, 12) && !BIT(offset, 10); + ra2 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 13) && BIT(offset, 12) && !BIT(offset, 9); + ra2 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 13) && BIT(offset, 12) && !BIT(offset, 8); + + ra1 = BIT(offset, 15) && BIT(offset, 14) && !BIT(offset, 13); + ra1 |= BIT(offset, 15) && BIT(offset, 14) && !BIT(offset, 12); + ra1 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 11) && BIT(offset, 10) && !BIT(offset, 9); + ra1 |= BIT(offset, 15) && BIT(offset, 14) && BIT(offset, 11) && BIT(offset, 10) && !BIT(offset, 8); + + ra0 = BIT(offset, 15) && !BIT(offset, 14); + ra0 |= BIT(offset, 15) && BIT(offset, 13) && !BIT(offset, 12); + ra0 |= BIT(offset, 15) && BIT(offset, 13) && BIT(offset, 11) && !BIT(offset, 10); + ra0 |= BIT(offset, 15) && BIT(offset, 13) && BIT(offset, 11) && BIT(offset, 9) && !BIT(offset, 8); + + return (ra3 << 3) | (ra2 << 2) | (ra1 << 1) | (ra0 << 0); +} + +READ8_MEMBER( einstein_speculator_device::ram_r ) +{ + offs_t addr = ((offset << 4) & 0x7f) | address_translate(offset); + return m_ram[addr]; +} + +WRITE8_MEMBER( einstein_speculator_device::ram_w ) +{ + offs_t addr = ((offset << 4) & 0x7f) | address_translate(offset); + m_ram[addr] = data; +} + +READ8_MEMBER( einstein_speculator_device::tape_r ) +{ + // 7654321- unknown + // -------0 cassette input + + return m_cassette->input() > 0.0038 ? 1 : 0; +} + +WRITE8_MEMBER( einstein_speculator_device::nmi_w ) +{ + logerror("nmi_w offset %04x data %02x\n", offset, data); + + // 76543--- unknown + // -----2-- nmi enable? + // ------1- nmi select? + // -------0 speaker? + + m_ic5a->clear_w(BIT(data, 2)); + m_ic5b->clear_w(BIT(data, 2)); + + m_nmisel = BIT(data, 1); + + m_speaker->level_w(BIT(data, 0)); +} diff --git a/src/devices/bus/einstein/pipe/speculator.h b/src/devices/bus/einstein/pipe/speculator.h new file mode 100644 index 00000000000..bdbb4476e3e --- /dev/null +++ b/src/devices/bus/einstein/pipe/speculator.h @@ -0,0 +1,66 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Speculator + + A Spectrum emulator + +***************************************************************************/ + +#ifndef MAME_BUS_EINSTEIN_PIPE_SPECULATOR_H +#define MAME_BUS_EINSTEIN_PIPE_SPECULATOR_H + +#pragma once + +#include "pipe.h" +#include "machine/74123.h" +#include "imagedev/cassette.h" +#include "sound/spkrdev.h" +#include "speaker.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> einstein_speculator_device + +class einstein_speculator_device : public device_t, public device_tatung_pipe_interface +{ +public: + // construction/destruction + einstein_speculator_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual void int_w(int state) override; + + DECLARE_READ8_MEMBER(ram_r); + DECLARE_WRITE8_MEMBER(ram_w); + DECLARE_READ8_MEMBER(tape_r); + DECLARE_WRITE8_MEMBER(nmi_w); + + DECLARE_WRITE_LINE_MEMBER(ic5a_q_w); + DECLARE_WRITE_LINE_MEMBER(ic5b_q_w); + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + offs_t address_translate(offs_t offset); + + required_device<ttl74123_device> m_ic5a; + required_device<ttl74123_device> m_ic5b; + required_device<cassette_image_device> m_cassette; + required_device<speaker_sound_device> m_speaker; + + std::unique_ptr<uint8_t[]> m_ram; + + int m_nmisel; +}; + +// device type definition +DECLARE_DEVICE_TYPE(EINSTEIN_SPECULATOR, einstein_speculator_device) + +#endif // MAME_BUS_EINSTEIN_PIPE_SPECULATOR_H diff --git a/src/devices/bus/einstein/tk02.cpp b/src/devices/bus/einstein/pipe/tk02.cpp index 02bea85e43f..9af704c2f2b 100644 --- a/src/devices/bus/einstein/tk02.cpp +++ b/src/devices/bus/einstein/pipe/tk02.cpp @@ -22,7 +22,7 @@ DEFINE_DEVICE_TYPE(TK02_80COL, tk02_device, "tk02", "TK02 80 Column Monochrome U //------------------------------------------------- DEVICE_ADDRESS_MAP_START(map, 8, tk02_device) -// AM_RANGE(0x00, 0x07) AM_SELECT(0xff00) AM_READWRITE(ram_r, ram_w) // no AM_SELECT (or AM_MASK) support here +// AM_RANGE(0x00, 0x07) AM_SELECT(0xff00) AM_READWRITE(ram_r, ram_w) // no AM_SELECT (or AM_MASK) support here AM_RANGE(0x08, 0x08) AM_MIRROR(0xff00) AM_DEVWRITE("crtc", mc6845_device, address_w) AM_RANGE(0x09, 0x09) AM_MIRROR(0xff00) AM_DEVWRITE("crtc", mc6845_device, register_w) AM_RANGE(0x0c, 0x0c) AM_MIRROR(0xff00) AM_READ(status_r) diff --git a/src/devices/bus/einstein/tk02.h b/src/devices/bus/einstein/pipe/tk02.h index 8a7d2231de3..8a7d2231de3 100644 --- a/src/devices/bus/einstein/tk02.h +++ b/src/devices/bus/einstein/pipe/tk02.h diff --git a/src/devices/bus/einstein/userport/mouse.cpp b/src/devices/bus/einstein/userport/mouse.cpp new file mode 100644 index 00000000000..945bff5d37c --- /dev/null +++ b/src/devices/bus/einstein/userport/mouse.cpp @@ -0,0 +1,106 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Einstein Mouse + + TODO: Verify implementation (mouse directions are digital only?) + +***************************************************************************/ + +#include "emu.h" +#include "mouse.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(EINSTEIN_MOUSE, einstein_mouse_device, "einstein_mouse", "Einstein Mouse") + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +static INPUT_PORTS_START( mouse ) + PORT_START("mouse_b") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) PORT_NAME("Mouse Left Button") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(1) PORT_NAME("Mouse Right Button") + + PORT_START("mouse_x") + PORT_BIT(0xff, 0x00, IPT_MOUSE_X) PORT_PLAYER(1) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) + + PORT_START("mouse_y") + PORT_BIT(0xff, 0x00, IPT_MOUSE_Y) PORT_PLAYER(1) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) +INPUT_PORTS_END + +ioport_constructor einstein_mouse_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( mouse ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// einstein_speech_device - constructor +//------------------------------------------------- + +einstein_mouse_device::einstein_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, EINSTEIN_MOUSE, tag, owner, clock), + device_einstein_userport_interface(mconfig, *this), + m_mouse_b(*this, "mouse_b"), + m_mouse_x(*this, "mouse_x"), + m_mouse_y(*this, "mouse_y"), + m_x(0), m_y(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void einstein_mouse_device::device_start() +{ + // register for save states + save_item(NAME(m_x)); + save_item(NAME(m_y)); +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +// 7------- not used +// -6------ not used +// --5----- right button +// ---4---- left button +// ----3--- right +// -----2-- left +// ------1- down +// -------0 up + +uint8_t einstein_mouse_device::read() +{ + uint8_t data = 0; + + uint8_t x = m_mouse_x->read(); + uint8_t y = m_mouse_y->read(); + + int dx = m_x - x; + int dy = m_y - y; + + data |= m_mouse_b->read() << 4; + data |= (dx < 0) ? 0 : 1 << 3; + data |= (dx > 0) ? 0 : 1 << 2; + data |= (dy < 0) ? 0 : 1 << 1; + data |= (dy > 0) ? 0 : 1 << 0; + + m_x = x; + m_y = y; + + return data; +} diff --git a/src/devices/bus/einstein/userport/mouse.h b/src/devices/bus/einstein/userport/mouse.h new file mode 100644 index 00000000000..dad8200d06b --- /dev/null +++ b/src/devices/bus/einstein/userport/mouse.h @@ -0,0 +1,47 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Einstein Mouse + +***************************************************************************/ + +#ifndef MAME_BUS_EINSTEIN_USERPORT_MOUSE_H +#define MAME_BUS_EINSTEIN_USERPORT_MOUSE_H + +#pragma once + +#include "userport.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> einstein_mouse_device + +class einstein_mouse_device : public device_t, public device_einstein_userport_interface +{ +public: + // construction/destruction + einstein_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual ioport_constructor device_input_ports() const override; + virtual void device_start() override; + + virtual uint8_t read() override; + +private: + required_ioport m_mouse_b; + required_ioport m_mouse_x; + required_ioport m_mouse_y; + + int m_x; + int m_y; +}; + +// device type definition +DECLARE_DEVICE_TYPE(EINSTEIN_MOUSE, einstein_mouse_device) + +#endif // MAME_BUS_EINSTEIN_USERPORT_MOUSE_H diff --git a/src/devices/bus/einstein/userport/speech.cpp b/src/devices/bus/einstein/userport/speech.cpp new file mode 100644 index 00000000000..b98e5d5513e --- /dev/null +++ b/src/devices/bus/einstein/userport/speech.cpp @@ -0,0 +1,88 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Einstein Speech Synthesiser (J&K Software) + + TODO: Verify implementation + +***************************************************************************/ + +#include "emu.h" +#include "speech.h" +#include "speaker.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(EINSTEIN_SPEECH, einstein_speech_device, "einstein_speech", "Einstein Speech Synthesiser") + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +ROM_START( sp0256 ) + ROM_REGION(0x10000, "sp0256", 0) + ROM_LOAD("sp0256a-al2.bin", 0x1000, 0x0800, CRC(b504ac15) SHA1(e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc)) +ROM_END + +const tiny_rom_entry *einstein_speech_device::device_rom_region() const +{ + return ROM_NAME( sp0256 ); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER( einstein_speech_device::device_add_mconfig ) + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("sp0256", SP0256, 3120000) // ??? + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) +MACHINE_CONFIG_END + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// einstein_speech_device - constructor +//------------------------------------------------- + +einstein_speech_device::einstein_speech_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, EINSTEIN_SPEECH, tag, owner, clock), + device_einstein_userport_interface(mconfig, *this), + m_sp0256(*this, "sp0256") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void einstein_speech_device::device_start() +{ +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +// 7------- reset? +// -6------ sp0256 lrq +// --543210 sp0256 ald + +uint8_t einstein_speech_device::read() +{ + return m_sp0256->lrq_r() ? 0x00 : 0x40; +} + +void einstein_speech_device::write(uint8_t data) +{ + if (BIT(data, 7) == 0) + m_sp0256->ald_w(machine().dummy_space(), 0, data & 0x3f); +} diff --git a/src/devices/bus/einstein/userport/speech.h b/src/devices/bus/einstein/userport/speech.h new file mode 100644 index 00000000000..4c62b24e842 --- /dev/null +++ b/src/devices/bus/einstein/userport/speech.h @@ -0,0 +1,45 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Einstein Speech Synthesiser (J&K Software) + +***************************************************************************/ + +#ifndef MAME_BUS_EINSTEIN_USERPORT_SPEECH_H +#define MAME_BUS_EINSTEIN_USERPORT_SPEECH_H + +#pragma once + +#include "userport.h" +#include "sound/sp0256.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> einstein_speech_device + +class einstein_speech_device : public device_t, public device_einstein_userport_interface +{ +public: + // construction/destruction + einstein_speech_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual const tiny_rom_entry *device_rom_region() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + + virtual uint8_t read() override; + virtual void write(uint8_t data) override; + +private: + required_device<sp0256_device> m_sp0256; +}; + +// device type definition +DECLARE_DEVICE_TYPE(EINSTEIN_SPEECH, einstein_speech_device) + +#endif // MAME_BUS_EINSTEIN_USERPORT_SPEECH_H diff --git a/src/devices/bus/einstein/userport/userport.cpp b/src/devices/bus/einstein/userport/userport.cpp new file mode 100644 index 00000000000..d38dba12af9 --- /dev/null +++ b/src/devices/bus/einstein/userport/userport.cpp @@ -0,0 +1,124 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Einstein User Port + +***************************************************************************/ + +#include "emu.h" +#include "userport.h" + +// supported devices +#include "mouse.h" +#include "speech.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(EINSTEIN_USERPORT, einstein_userport_device, "einstein_userport", "Einstein User Port") + + +//************************************************************************** +// SLOT DEVICE +//************************************************************************** + +//------------------------------------------------- +// einstein_userport_device - constructor +//------------------------------------------------- + +einstein_userport_device::einstein_userport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, EINSTEIN_USERPORT, tag, owner, clock), + device_slot_interface(mconfig, *this), + m_card(nullptr), + m_bstb_handler(*this) +{ +} + +//------------------------------------------------- +// einstein_userport_device - destructor +//------------------------------------------------- + +einstein_userport_device::~einstein_userport_device() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void einstein_userport_device::device_start() +{ + // resolve callbacks + m_bstb_handler.resolve_safe(); + + m_card = dynamic_cast<device_einstein_userport_interface *>(get_card_device()); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void einstein_userport_device::device_reset() +{ +} + + +//************************************************************************** +// I/O PORTS +//************************************************************************** + +READ8_MEMBER( einstein_userport_device::read ) +{ + if (m_card) + return m_card->read(); + else + return 0xff; +} + +WRITE8_MEMBER( einstein_userport_device::write ) +{ + if (m_card) + m_card->write(data); +} + +WRITE_LINE_MEMBER( einstein_userport_device::brdy_w ) +{ + if (m_card) + m_card->brdy_w(state); +} + + +//************************************************************************** +// CARTRIDGE INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_einstein_userport_interface - constructor +//------------------------------------------------- + +device_einstein_userport_interface::device_einstein_userport_interface(const machine_config &mconfig, device_t &device) : + device_slot_card_interface(mconfig, device) +{ + m_slot = dynamic_cast<einstein_userport_device *>(device.owner()); +} + +//------------------------------------------------- +// ~device_einstein_userport_interface - destructor +//------------------------------------------------- + +device_einstein_userport_interface::~device_einstein_userport_interface() +{ +} + + +//************************************************************************** +// SLOT INTERFACE +//************************************************************************** + +SLOT_INTERFACE_START( einstein_userport_cards ) + SLOT_INTERFACE("mouse", EINSTEIN_MOUSE) + SLOT_INTERFACE("speech", EINSTEIN_SPEECH) +SLOT_INTERFACE_END diff --git a/src/devices/bus/einstein/userport/userport.h b/src/devices/bus/einstein/userport/userport.h new file mode 100644 index 00000000000..59301644aa3 --- /dev/null +++ b/src/devices/bus/einstein/userport/userport.h @@ -0,0 +1,96 @@ +// license: GPL-2.0+ +// copyright-holders: Dirk Best +/*************************************************************************** + + Einstein User Port + + 16-pin slot + + +5V 1 2 D0 + GND 3 4 D1 + BRDY 5 6 D2 + GND 7 8 D3 + GND 9 10 D4 + /BSTB 11 12 D5 + GND 13 14 D6 + +5V 15 16 D7 + +***************************************************************************/ + +#ifndef MAME_BUS_EINSTEIN_USERPORT_USERPORT_H +#define MAME_BUS_EINSTEIN_USERPORT_USERPORT_H + +#pragma once + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_EINSTEIN_USERPORT_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, EINSTEIN_USERPORT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(einstein_userport_cards, nullptr, false) + +#define MCFG_EINSTEIN_USERPORT_BSTB_HANDLER(_devcb) \ + devcb = &einstein_userport_device::set_bstb_handler(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class device_einstein_userport_interface; + +class einstein_userport_device : public device_t, public device_slot_interface +{ +public: + // construction/destruction + einstein_userport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual ~einstein_userport_device(); + + // callbacks + template <class Object> static devcb_base &set_bstb_handler(device_t &device, Object &&cb) + { return downcast<einstein_userport_device &>(device).m_bstb_handler.set_callback(std::forward<Object>(cb)); } + + // called from card device + DECLARE_WRITE_LINE_MEMBER( bstb_w ) { m_bstb_handler(state); } + + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER (write ); + DECLARE_WRITE_LINE_MEMBER( brdy_w ); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + device_einstein_userport_interface *m_card; + +private: + devcb_write_line m_bstb_handler; +}; + +// class representing interface-specific live userport device +class device_einstein_userport_interface : public device_slot_card_interface +{ +public: + // construction/destruction + virtual ~device_einstein_userport_interface(); + + virtual uint8_t read() { return 0xff; } + virtual void write(uint8_t data) { } + virtual void brdy_w(int state) { } + +protected: + device_einstein_userport_interface(const machine_config &mconfig, device_t &device); + + einstein_userport_device *m_slot; +}; + +// device type definition +DECLARE_DEVICE_TYPE(EINSTEIN_USERPORT, einstein_userport_device) + +// supported devices +SLOT_INTERFACE_EXTERN(einstein_userport_cards); + +#endif // MAME_BUS_EINSTEIN_USERPORT_USERPORT_H diff --git a/src/devices/bus/electron/exp.cpp b/src/devices/bus/electron/exp.cpp index 3bcc1377e19..105a8f44c18 100644 --- a/src/devices/bus/electron/exp.cpp +++ b/src/devices/bus/electron/exp.cpp @@ -103,11 +103,11 @@ void electron_expansion_slot_device::device_reset() #include "fbjoy.h" //#include "fbprint.h" //#include "jafamode7.h" -//#include "plus1.h" +#include "plus1.h" #include "plus3.h" #include "pwrjoy.h" //#include "rombox.h" -//#include "romboxplus.h" +//#include "romboxp.h" #include "m2105.h" //#include "voxbox.h" @@ -117,11 +117,11 @@ SLOT_INTERFACE_START( electron_expansion_devices ) SLOT_INTERFACE("fbjoy", ELECTRON_FBJOY) //SLOT_INTERFACE("fbprint", ELECTRON_FBPRINT) //SLOT_INTERFACE("jafamode7", ELECTRON_JAFAMODE7) - //SLOT_INTERFACE("plus1", ELECTRON_PLUS1) + SLOT_INTERFACE("plus1", ELECTRON_PLUS1) SLOT_INTERFACE("plus3", ELECTRON_PLUS3) SLOT_INTERFACE("pwrjoy", ELECTRON_PWRJOY) //SLOT_INTERFACE("rombox", ELECTRON_ROMBOX) - //SLOT_INTERFACE("romboxplus", ELECTRON_ROMBOXPLUS) + //SLOT_INTERFACE("romboxp", ELECTRON_ROMBOXP) SLOT_INTERFACE("m2105", ELECTRON_M2105) //SLOT_INTERFACE("voxbox", ELECTRON_VOXBOX) SLOT_INTERFACE_END diff --git a/src/devices/bus/electron/m2105.cpp b/src/devices/bus/electron/m2105.cpp index 228c0e006a6..2c5921c8d3a 100644 --- a/src/devices/bus/electron/m2105.cpp +++ b/src/devices/bus/electron/m2105.cpp @@ -78,13 +78,13 @@ MACHINE_CONFIG_MEMBER( electron_m2105_device::device_add_mconfig ) MCFG_VIA6522_IRQ_HANDLER(DEVWRITELINE("irqs", input_merger_device, in_w<1>)) /* duart */ - MCFG_MC68681_ADD("sc2681", XTAL_3_6864MHz) + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) MCFG_MC68681_IRQ_CALLBACK(DEVWRITELINE("irqs", input_merger_device, in_w<2>)) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("rs232", rs232_port_device, write_txd)) //MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(electron_m2105_device, sio_out_w)) MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sc2681", mc68681_device, rx_a_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_a_w)) /* printer */ MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") @@ -117,7 +117,7 @@ electron_m2105_device::electron_m2105_device(const machine_config &mconfig, cons , m_exp_rom(*this, "exp_rom") , m_via6522_0(*this, "via6522_0") , m_via6522_1(*this, "via6522_1") - , m_duart(*this, "sc2681") + , m_duart(*this, "duart") , m_tms(*this, "tms5220") , m_centronics(*this, "centronics") , m_irqs(*this, "irqs") @@ -134,7 +134,7 @@ void electron_m2105_device::device_start() m_slot = dynamic_cast<electron_expansion_slot_device *>(owner()); space.install_readwrite_handler(0xfc40, 0xfc5f, READ8_DEVICE_DELEGATE(m_via6522_1, via6522_device, read), WRITE8_DEVICE_DELEGATE(m_via6522_1, via6522_device, write)); - space.install_readwrite_handler(0xfc60, 0xfc6f, READ8_DEVICE_DELEGATE(m_duart, mc68681_device, read), WRITE8_DEVICE_DELEGATE(m_duart, mc68681_device, write)); + space.install_readwrite_handler(0xfc60, 0xfc6f, READ8_DEVICE_DELEGATE(m_duart, scn2681_device, read), WRITE8_DEVICE_DELEGATE(m_duart, scn2681_device, write)); space.install_readwrite_handler(0xfc70, 0xfc8f, READ8_DEVICE_DELEGATE(m_via6522_0, via6522_device, read), WRITE8_DEVICE_DELEGATE(m_via6522_0, via6522_device, write)); } diff --git a/src/devices/bus/electron/m2105.h b/src/devices/bus/electron/m2105.h index 387b96f918d..2411913008c 100644 --- a/src/devices/bus/electron/m2105.h +++ b/src/devices/bus/electron/m2105.h @@ -46,7 +46,7 @@ private: required_memory_region m_exp_rom; required_device<via6522_device> m_via6522_0; required_device<via6522_device> m_via6522_1; - required_device<mc68681_device> m_duart; + required_device<scn2681_device> m_duart; required_device<tms5220_device> m_tms; required_device<centronics_device> m_centronics; required_device<input_merger_device> m_irqs; diff --git a/src/devices/bus/electron/plus1.cpp b/src/devices/bus/electron/plus1.cpp new file mode 100644 index 00000000000..cc9067fe6c2 --- /dev/null +++ b/src/devices/bus/electron/plus1.cpp @@ -0,0 +1,246 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + ALA11 - Acorn Plus 1 + + The Acorn Plus 1 added two ROM cartridge slots, an analogue interface + (supporting two channels) and a Centronics parallel port. The + analogue interface was normally used for joysticks, the parallel for + a printer. The ROM slots could be booted from via the "Shift+BREAK" + key-combination. (The slot at the front of the interface took priority + if both were populated). + +**********************************************************************/ + + +#include "emu.h" +#include "plus1.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(ELECTRON_PLUS1, electron_plus1_device, "electron_plus1", "Acorn Plus 1 Expansion") + + +//------------------------------------------------- +// ROM( plus1 ) +//------------------------------------------------- + +ROM_START( plus1 ) + // Bank 12 Expansion module operating system + ROM_REGION( 0x2000, "exp_rom", 0 ) + ROM_DEFAULT_BIOS("plus1") + ROM_SYSTEM_BIOS(0, "plus1", "Expansion 1.00") + ROMX_LOAD("plus1.rom", 0x0000, 0x1000, CRC(ac30b0ed) SHA1(2de04ab7c81414d6c9c967f965c53fc276392463), ROM_BIOS(1)) + ROM_RELOAD( 0x1000, 0x1000) + + ROM_SYSTEM_BIOS(1, "presap1", "PRES Expansion 1.1") + ROMX_LOAD("presplus1.rom", 0x0000, 0x1000, CRC(8ef1e0e5) SHA1(080e1b788b3fe4fa272cd2cc792293eb7b874e82), ROM_BIOS(2)) + ROM_RELOAD( 0x1000, 0x1000) + + ROM_SYSTEM_BIOS(2, "presap2", "PRES AP2 Support 1.23") + ROMX_LOAD("presap2_123.rom", 0x0000, 0x2000, CRC(f796689c) SHA1(bc40a79e6d2b4cb5e549d5d21f673c66a661850d), ROM_BIOS(3)) + + ROM_SYSTEM_BIOS(3, "slogger", "Slogger Expansion 2.02") + ROMX_LOAD("slogger202.rom", 0x0000, 0x2000, CRC(32b440be) SHA1(dbc73e8d919c5615d0241d99db60e06324e16c86), ROM_BIOS(4)) +ROM_END + +//------------------------------------------------- +// INPUT_PORTS( plus1 ) +//------------------------------------------------- + +static INPUT_PORTS_START( plus1 ) + PORT_START("JOY1") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0x00, 0xff) PORT_PLAYER(1) PORT_REVERSE + + PORT_START("JOY2") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0x00, 0xff) PORT_PLAYER(1) PORT_REVERSE + + PORT_START("JOY3") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0x00, 0xff) PORT_PLAYER(2) PORT_REVERSE + + PORT_START("JOY4") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0x00, 0xff) PORT_PLAYER(2) PORT_REVERSE + + PORT_START("BUTTONS") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) +INPUT_PORTS_END + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +ioport_constructor electron_plus1_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( plus1 ); +} + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER( electron_plus1_device::device_add_mconfig ) + /* printer */ + MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") + MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(electron_plus1_device, busy_w)) + MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics") + + /* adc */ + MCFG_ADC0844_ADD("adc") + MCFG_ADC0844_INTR_CB(WRITELINE(electron_plus1_device, ready_w)) + MCFG_ADC0844_CH1_CB(IOPORT("JOY1")) + MCFG_ADC0844_CH2_CB(IOPORT("JOY2")) + MCFG_ADC0844_CH3_CB(IOPORT("JOY3")) + MCFG_ADC0844_CH4_CB(IOPORT("JOY4")) + + /* cartridges */ + MCFG_GENERIC_SOCKET_ADD("cart_sk1", generic_plain_slot, "electron_cart") + MCFG_GENERIC_LOAD(electron_plus1_device, electron_cart_sk1) + MCFG_GENERIC_SOCKET_ADD("cart_sk2", generic_plain_slot, "electron_cart") + MCFG_GENERIC_LOAD(electron_plus1_device, electron_cart_sk2) +MACHINE_CONFIG_END + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- + +const tiny_rom_entry *electron_plus1_device::device_rom_region() const +{ + return ROM_NAME( plus1 ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// electron_plus1_device - constructor +//------------------------------------------------- + +electron_plus1_device::electron_plus1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, ELECTRON_PLUS1, tag, owner, clock), + device_electron_expansion_interface(mconfig, *this), + m_exp_rom(*this, "exp_rom"), + m_cart_sk1(*this, "cart_sk1"), + m_cart_sk2(*this, "cart_sk2"), + m_centronics(*this, "centronics"), + m_cent_data_out(*this, "cent_data_out"), + m_adc(*this, "adc"), + m_joy(*this, "JOY%u", 1), + m_buttons(*this, "BUTTONS"), + m_centronics_busy(0), + m_adc_ready(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void electron_plus1_device::device_start() +{ + address_space& space = machine().device("maincpu")->memory().space(AS_PROGRAM); + m_slot = dynamic_cast<electron_expansion_slot_device *>(owner()); + + space.install_readwrite_handler(0xfc70, 0xfc70, READ8_DEVICE_DELEGATE(m_adc, adc0844_device, read), WRITE8_DEVICE_DELEGATE(m_adc, adc0844_device, write)); + space.install_write_handler(0xfc71, 0xfc71, WRITE8_DEVICE_DELEGATE("cent_data_out", output_latch_device, write)); + space.install_read_handler(0xfc72, 0xfc72, READ8_DELEGATE(electron_plus1_device, status_r)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void electron_plus1_device::device_reset() +{ + std::string region_tag; + memory_region *tmp_reg; + if (m_cart_sk2 && (tmp_reg = memregion(region_tag.assign(m_cart_sk2->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) + { + machine().root_device().membank("bank2")->configure_entries(0, 2, tmp_reg->base(), 0x4000); + } + if (m_cart_sk1 && (tmp_reg = memregion(region_tag.assign(m_cart_sk1->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) + { + machine().root_device().membank("bank2")->configure_entries(2, 2, tmp_reg->base(), 0x4000); + } + + machine().root_device().membank("bank2")->configure_entry(12, memregion("exp_rom")->base()); +} + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ8_MEMBER(electron_plus1_device::status_r) +{ + uint8_t data = 0x0f; + // Status: b7: printer Busy + // b6: ADC conversion end + // b5: Fire Button 1 + // b4: Fire Button 2 + data |= (m_centronics_busy << 7); + data |= (m_adc_ready << 6); + data |= m_buttons->read(); + + return data; +} + +WRITE_LINE_MEMBER(electron_plus1_device::busy_w) +{ + m_centronics_busy = !state; +} + +WRITE_LINE_MEMBER(electron_plus1_device::ready_w) +{ + m_adc_ready = !state; +} + +image_init_result electron_plus1_device::load_cart(device_image_interface &image, generic_slot_device *slot) +{ + if (image.software_entry() == nullptr) + { + uint32_t filesize = image.length(); + + if (filesize != 16384) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only size 16384 is supported"); + return image_init_result::FAIL; + } + + slot->rom_alloc(filesize, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); + image.fread(slot->get_rom_base(), filesize); + return image_init_result::PASS; + } + else + { + int upsize = image.get_software_region_length("uprom"); + int losize = image.get_software_region_length("lorom"); + + if (upsize != 16384 && upsize != 0) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for uprom"); + return image_init_result::FAIL; + } + + if (losize != 16384 && losize != 0) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for lorom"); + return image_init_result::FAIL; + } + + slot->rom_alloc(upsize + losize, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); + + if (upsize) + memcpy(slot->get_rom_base(), image.get_software_region("uprom"), upsize); + + if (losize) + memcpy(slot->get_rom_base() + upsize, image.get_software_region("lorom"), losize); + + return image_init_result::PASS; + } +} diff --git a/src/devices/bus/electron/plus1.h b/src/devices/bus/electron/plus1.h new file mode 100644 index 00000000000..75eb44ce91a --- /dev/null +++ b/src/devices/bus/electron/plus1.h @@ -0,0 +1,68 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + ALA11 - Acorn Plus 1 + +**********************************************************************/ + + +#ifndef MAME_BUS_ELECTRON_PLUS1_H +#define MAME_BUS_ELECTRON_PLUS1_H + +#include "exp.h" +#include "softlist.h" +#include "machine/adc0844.h" +#include "bus/centronics/ctronics.h" +#include "bus/generic/slot.h" +#include "bus/generic/carts.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class electron_plus1_device: + public device_t, + public device_electron_expansion_interface +{ +public: + // construction/destruction + electron_plus1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual ioport_constructor device_input_ports() const override; + +private: + DECLARE_READ8_MEMBER(status_r); + DECLARE_WRITE_LINE_MEMBER(busy_w); + DECLARE_WRITE_LINE_MEMBER(ready_w); + + image_init_result load_cart(device_image_interface &image, generic_slot_device *slot); + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(electron_cart_sk1) { return load_cart(image, m_cart_sk1); } + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(electron_cart_sk2) { return load_cart(image, m_cart_sk2); } + + required_memory_region m_exp_rom; + required_device<generic_slot_device> m_cart_sk1; + required_device<generic_slot_device> m_cart_sk2; + required_device<centronics_device> m_centronics; + required_device<output_latch_device> m_cent_data_out; + required_device<adc0844_device> m_adc; + required_ioport_array<4> m_joy; + required_ioport m_buttons; + + int m_centronics_busy; + int m_adc_ready; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(ELECTRON_PLUS1, electron_plus1_device) + + +#endif /* MAME_BUS_ELECTRON_PLUS1_H */ diff --git a/src/devices/bus/electron/plus3.cpp b/src/devices/bus/electron/plus3.cpp index 72a645c1728..5c339c1bcc7 100644 --- a/src/devices/bus/electron/plus3.cpp +++ b/src/devices/bus/electron/plus3.cpp @@ -17,7 +17,6 @@ #include "emu.h" #include "plus3.h" -#include "softlist.h" //************************************************************************** @@ -39,8 +38,6 @@ FLOPPY_FORMATS_END0 SLOT_INTERFACE_START(electron_floppies) SLOT_INTERFACE("35dd", FLOPPY_35_DD) - SLOT_INTERFACE("525sd", FLOPPY_525_SD) - SLOT_INTERFACE("525dd", FLOPPY_525_DD) SLOT_INTERFACE("525qd", FLOPPY_525_QD) SLOT_INTERFACE_END @@ -68,14 +65,11 @@ ROM_END MACHINE_CONFIG_MEMBER( electron_plus3_device::device_add_mconfig ) /* fdc */ MCFG_WD1770_ADD("fdc", XTAL_16MHz / 2) - MCFG_FLOPPY_DRIVE_ADD("fdc:0", electron_floppies, "35dd", floppy_formats) - MCFG_SLOT_FIXED(true) + MCFG_FLOPPY_DRIVE_ADD_FIXED("fdc:0", electron_floppies, "35dd", floppy_formats) MCFG_FLOPPY_DRIVE_SOUND(true) MCFG_FLOPPY_DRIVE_ADD("fdc:1", electron_floppies, nullptr, floppy_formats) MCFG_FLOPPY_DRIVE_SOUND(true) - /* software lists */ - MCFG_SOFTWARE_LIST_ADD("flop_ls", "electron_flop") /* pass-through */ MCFG_ELECTRON_PASSTHRU_EXPANSION_SLOT_ADD(nullptr) diff --git a/src/devices/bus/gba/rom.cpp b/src/devices/bus/gba/rom.cpp index 5d083f6479e..e3bcec5c442 100644 --- a/src/devices/bus/gba/rom.cpp +++ b/src/devices/bus/gba/rom.cpp @@ -158,7 +158,7 @@ void gba_rom_device::device_reset() m_gpio_regs[1] = 0; m_gpio_regs[2] = 0; m_gpio_regs[3] = 0; - m_gpio_write_only = 0; + m_gpio_write_only = 1; m_gpio_dirs = 0; } @@ -273,7 +273,6 @@ void gba_rom_3dmatrix_device::device_reset() READ32_MEMBER(gba_rom_device::read_gpio) { - logerror("read GPIO offs %X\n", offset); if (!m_gpio_write_only) { switch (offset) @@ -301,7 +300,6 @@ READ32_MEMBER(gba_rom_device::read_gpio) WRITE32_MEMBER(gba_rom_device::write_gpio) { - logerror("write GPIO offs %X data %X\n", offset, data); switch (offset) { case 0: diff --git a/src/devices/bus/hp80_io/82937.cpp b/src/devices/bus/hp80_io/82937.cpp index afeb561b8bc..abc5ad9f7fb 100644 --- a/src/devices/bus/hp80_io/82937.cpp +++ b/src/devices/bus/hp80_io/82937.cpp @@ -26,34 +26,34 @@ // Bit manipulation namespace { - static constexpr unsigned BIT_MASK(unsigned n) + template<typename T> constexpr T BIT_MASK(unsigned n) { - return 1U << n; + return (T)1U << n; } template<typename T> void BIT_SET(T& w , unsigned n) { - w |= (T)BIT_MASK(n); + w |= BIT_MASK<T>(n); } } // Bits in U3 (m_latch) -static constexpr unsigned LATCH_CA_BIT = 5; // Controller Active -static constexpr unsigned LATCH_TA_BIT = 4; // Talker Active -static constexpr unsigned LATCH_EN_IFC_INT_BIT = 3; // Enable IFC interrupt -static constexpr unsigned LATCH_EN_REN_INT_BIT = 2; // Enable REN interrupt -static constexpr unsigned LATCH_EN_ATN_INT_BIT = 1; // Enable ATN interrupt -static constexpr unsigned LATCH_EN_NDAC_BIT = 0; // Enable NDAC +constexpr unsigned LATCH_CA_BIT = 5; // Controller Active +constexpr unsigned LATCH_TA_BIT = 4; // Talker Active +constexpr unsigned LATCH_EN_IFC_INT_BIT = 3; // Enable IFC interrupt +constexpr unsigned LATCH_EN_REN_INT_BIT = 2; // Enable REN interrupt +constexpr unsigned LATCH_EN_ATN_INT_BIT = 1; // Enable ATN interrupt +constexpr unsigned LATCH_EN_NDAC_BIT = 0; // Enable NDAC // Bits on P1 port of 8049 -static constexpr unsigned P1_IFC_BIT = 7; -static constexpr unsigned P1_REN_BIT = 6; -static constexpr unsigned P1_SRQ_BIT = 5; -static constexpr unsigned P1_ATN_BIT = 4; -static constexpr unsigned P1_EOI_BIT = 3; -static constexpr unsigned P1_DAV_BIT = 2; -static constexpr unsigned P1_NDAC_BIT = 1; -static constexpr unsigned P1_NRFD_BIT = 0; +constexpr unsigned P1_IFC_BIT = 7; +constexpr unsigned P1_REN_BIT = 6; +constexpr unsigned P1_SRQ_BIT = 5; +constexpr unsigned P1_ATN_BIT = 4; +constexpr unsigned P1_EOI_BIT = 3; +constexpr unsigned P1_DAV_BIT = 2; +constexpr unsigned P1_NDAC_BIT = 1; +constexpr unsigned P1_NRFD_BIT = 0; hp82937_io_card_device::hp82937_io_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : hp80_io_card_device(mconfig , HP82937_IO_CARD , tag , owner , clock), diff --git a/src/devices/bus/hp80_io/82937.h b/src/devices/bus/hp80_io/82937.h index 4402eee8a13..373bdae271d 100644 --- a/src/devices/bus/hp80_io/82937.h +++ b/src/devices/bus/hp80_io/82937.h @@ -30,15 +30,8 @@ public: virtual void inten() override; virtual void clear_service() override; - DECLARE_WRITE_LINE_MEMBER(reset_w); - DECLARE_READ_LINE_MEMBER(t0_r); - DECLARE_READ8_MEMBER(p1_r); - DECLARE_WRITE8_MEMBER(p1_w); - DECLARE_READ8_MEMBER(dio_r); - DECLARE_WRITE8_MEMBER(dio_w); DECLARE_READ8_MEMBER(switch_r); DECLARE_WRITE8_MEMBER(latch_w); - DECLARE_WRITE_LINE_MEMBER(ieee488_ctrl_w); protected: virtual void device_start() override; @@ -61,6 +54,14 @@ private: uint8_t m_latch; // U3 bool m_updating; + DECLARE_WRITE_LINE_MEMBER(reset_w); + DECLARE_READ_LINE_MEMBER(t0_r); + DECLARE_READ8_MEMBER(p1_r); + DECLARE_WRITE8_MEMBER(p1_w); + DECLARE_READ8_MEMBER(dio_r); + DECLARE_WRITE8_MEMBER(dio_w); + DECLARE_WRITE_LINE_MEMBER(ieee488_ctrl_w); + void update_data_out(); void update_signals(); }; diff --git a/src/devices/bus/hp_dio/hp_dio.cpp b/src/devices/bus/hp_dio/hp_dio.cpp index 52b2a01d13a..6948beed7e9 100644 --- a/src/devices/bus/hp_dio/hp_dio.cpp +++ b/src/devices/bus/hp_dio/hp_dio.cpp @@ -147,7 +147,7 @@ void dio16_device::device_start() m_maincpu = subdevice<cpu_device>(m_cputag); m_prgspace = &m_maincpu->space(AS_PROGRAM); - m_prgwidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width; + m_prgwidth = m_maincpu->space_config(AS_PROGRAM)->m_data_width; } //------------------------------------------------- diff --git a/src/devices/bus/interpro/sr/gt.cpp b/src/devices/bus/interpro/sr/gt.cpp index c4ed9109792..a4fa7d18304 100644 --- a/src/devices/bus/interpro/sr/gt.cpp +++ b/src/devices/bus/interpro/sr/gt.cpp @@ -83,7 +83,7 @@ gt_device_base::gt_device_base(const machine_config &mconfig, device_type type, mpcb963_device::mpcb963_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : gt_device_base(mconfig, MPCB963, tag, owner, clock) - , m_screen{ { { *this, "ramdac0" }, {}, true } } + , m_screen{ { { *this, "ramdac0" }, {}, true } } { } diff --git a/src/devices/bus/interpro/sr/sr.cpp b/src/devices/bus/interpro/sr/sr.cpp index 5a8f7d23a68..112aa582746 100644 --- a/src/devices/bus/interpro/sr/sr.cpp +++ b/src/devices/bus/interpro/sr/sr.cpp @@ -266,16 +266,16 @@ sr_slot_device::sr_slot_device(const machine_config &mconfig, const char *tag, d : device_t(mconfig, SR_SLOT, tag, owner, clock) , device_slot_interface(mconfig, *this) , m_sr_tag(nullptr) - , m_sr_slottag(nullptr) + , m_sr_slot_tag(nullptr) { } -void sr_slot_device::static_set_sr_slot(device_t &device, const char *tag, const char *slottag) +void sr_slot_device::static_set_sr_slot(device_t &device, const char *tag, const char *slot_tag) { sr_slot_device &sr_card = dynamic_cast<sr_slot_device &>(device); sr_card.m_sr_tag = tag; - sr_card.m_sr_slottag = slottag; + sr_card.m_sr_slot_tag = slot_tag; } void sr_slot_device::device_start() @@ -283,28 +283,38 @@ void sr_slot_device::device_start() device_sr_card_interface *dev = dynamic_cast<device_sr_card_interface *>(get_card_device()); if (dev) - device_sr_card_interface::static_set_sr_tag(*dev, m_sr_tag, m_sr_slottag); + device_sr_card_interface::static_set_sr_tag(*dev, m_sr_tag, m_sr_slot_tag); } DEFINE_DEVICE_TYPE(SR, sr_device, "sr", "InterPro SR bus") sr_device::sr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, SR, tag, owner, clock) - , m_data_space(nullptr) - , m_io_space(nullptr) , m_out_irq0_cb(*this) , m_out_irq1_cb(*this) , m_out_irq2_cb(*this) + , m_memory_tag(nullptr) { } +void sr_device::static_set_memory(device_t &device, const char *const tag, const int data_spacenum, const int io_spacenum) +{ + sr_device &sr = dynamic_cast<sr_device &>(device); + + sr.m_memory_tag = tag; + sr.m_data_spacenum = data_spacenum; + sr.m_io_spacenum = io_spacenum; +} + void sr_device::device_start() { - // grab the main memory space from the mmu - device_memory_interface *mmu; - siblingdevice("mmu")->interface(mmu); - m_data_space = &mmu->space(0); - m_io_space = &mmu->space(1); + assert_always(m_memory_tag != nullptr, "memory tag and address spaces must be configured"); + + // get the memory spaces + device_memory_interface *memory; + siblingdevice(m_memory_tag)->interface(memory); + m_data_space = &memory->space(m_data_spacenum); + m_io_space = &memory->space(m_io_spacenum); // resolve callbacks m_out_irq0_cb.resolve_safe(); @@ -325,7 +335,7 @@ device_sr_card_interface::device_sr_card_interface(const machine_config &mconfig : device_slot_card_interface(mconfig, device) , m_sr(nullptr) , m_sr_tag(nullptr) - , m_sr_slottag(nullptr) + , m_sr_slot_tag(nullptr) { } @@ -333,12 +343,12 @@ device_sr_card_interface::~device_sr_card_interface() { } -void device_sr_card_interface::static_set_sr_tag(device_t &device, const char *tag, const char *slottag) +void device_sr_card_interface::static_set_sr_tag(device_t &device, const char *tag, const char *slot_tag) { device_sr_card_interface &sr_card = dynamic_cast<device_sr_card_interface &>(device); sr_card.m_sr_tag = tag; - sr_card.m_sr_slottag = slottag; + sr_card.m_sr_slot_tag = slot_tag; } void device_sr_card_interface::set_sr_device() diff --git a/src/devices/bus/interpro/sr/sr.h b/src/devices/bus/interpro/sr/sr.h index 236b4ea674b..f51b7f6a946 100644 --- a/src/devices/bus/interpro/sr/sr.h +++ b/src/devices/bus/interpro/sr/sr.h @@ -23,6 +23,9 @@ #define MCFG_SR_SLOT_REMOVE(_tag) \ MCFG_DEVICE_REMOVE(_tag) +#define MCFG_SR_MEMORY(_tag, _data_spacenum, _io_spacenum) \ + sr_device::static_set_memory(*device, _tag, _data_spacenum, _io_spacenum); + class sr_slot_device : public device_t, public device_slot_interface { public: @@ -30,7 +33,8 @@ public: sr_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // inline configuration - static void static_set_sr_slot(device_t &device, const char *tag, const char *slottag); + static void static_set_sr_slot(device_t &device, const char *tag, const char *slot_tag); + protected: sr_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); @@ -38,7 +42,8 @@ protected: virtual void device_start() override; // configuration - const char *m_sr_tag, *m_sr_slottag; + const char *m_sr_tag; + const char *m_sr_slot_tag; }; class device_sr_card_interface; @@ -54,6 +59,8 @@ public: template <class Object> static devcb_base &set_out_irq1_callback(device_t &device, Object &&cb) { return downcast<sr_device &>(device).m_out_irq1_cb.set_callback(std::forward<Object>(cb)); } template <class Object> static devcb_base &set_out_irq2_callback(device_t &device, Object &&cb) { return downcast<sr_device &>(device).m_out_irq2_cb.set_callback(std::forward<Object>(cb)); } + static void static_set_memory(device_t &device, const char *const tag, const int data_spacenum, const int io_spacenum); + static const u32 SR_BASE = 0x87000000; static const u32 SR_SIZE = 0x08000000; static const int SR_COUNT = 16; @@ -97,6 +104,10 @@ protected: private: device_sr_card_interface *m_slot[SR_COUNT]; int m_slot_count; + + const char *m_memory_tag; + int m_data_spacenum; + int m_io_spacenum; }; class device_sr_card_interface : public device_slot_card_interface @@ -110,13 +121,14 @@ public: void set_sr_device(); // inline configuration - static void static_set_sr_tag(device_t &device, const char *tag, const char *slottag); + static void static_set_sr_tag(device_t &device, const char *tag, const char *slot_tag); protected: device_sr_card_interface(const machine_config &mconfig, device_t &device); sr_device *m_sr; - const char *m_sr_tag, *m_sr_slottag; + const char *m_sr_tag; + const char *m_sr_slot_tag; }; class sr_card_device_base : public device_t, public device_sr_card_interface diff --git a/src/devices/bus/isa/cga.cpp b/src/devices/bus/isa/cga.cpp index 2f810bdafdb..91ee69d48b5 100644 --- a/src/devices/bus/isa/cga.cpp +++ b/src/devices/bus/isa/cga.cpp @@ -190,22 +190,22 @@ MC6845_UPDATE_ROW( isa8_cga_device::crtc_update_row ) switch (m_update_row_type) { case CGA_TEXT_INTEN: - cga_text_inten_update_row(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + cga_text<false, false, false, false, 8>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); break; case CGA_TEXT_INTEN_ALT: - cga_text_inten_alt_update_row(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + cga_text<false, false, false, true, 8>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); break; case CGA_TEXT_INTEN_CG: - cga_text_inten_comp_grey_update_row(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + cga_text<false, false, true, false, 8>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); break; case CGA_TEXT_BLINK: - cga_text_blink_update_row(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + cga_text<true, false, false, false, 8>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); break; case CGA_TEXT_BLINK_ALT: - cga_text_blink_alt_update_row(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + cga_text<true, false, false, true, 8>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); break; case CGA_TEXT_BLINK_SI: - cga_text_blink_update_row_si(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + cga_text<true, true, false, false, 8>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); break; case CGA_GFX_1BPP: cga_gfx_1bpp_update_row(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); @@ -467,200 +467,41 @@ isa8_cga_superimpose_device::isa8_cga_superimpose_device(const machine_config &m m_superimpose = true; } -/*************************************************************************** - Draw text mode with 40x25 characters (default) with high intensity bg. - The character cell size is 16x8 -***************************************************************************/ - -MC6845_UPDATE_ROW( isa8_cga_device::cga_text_inten_update_row ) -{ - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int i; - - if ( y == 0 ) CGA_LOG(1,"cga_text_inten_update_row",("\n")); - for ( i = 0; i < x_count; i++ ) - { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x3fff; - uint8_t chr = videoram[ offset ]; - uint8_t attr = videoram[ offset +1 ]; - uint8_t data = m_chr_gen[ chr * 8 + ra ]; - uint16_t fg = attr & 0x0F; - uint16_t bg = attr >> 4; - - if ( i == cursor_x && ( m_framecnt & 0x08 ) ) - { - data = 0xFF; - } - - *p = palette[( data & 0x80 ) ? fg : bg]; p++; - *p = palette[( data & 0x40 ) ? fg : bg]; p++; - *p = palette[( data & 0x20 ) ? fg : bg]; p++; - *p = palette[( data & 0x10 ) ? fg : bg]; p++; - *p = palette[( data & 0x08 ) ? fg : bg]; p++; - *p = palette[( data & 0x04 ) ? fg : bg]; p++; - *p = palette[( data & 0x02 ) ? fg : bg]; p++; - *p = palette[( data & 0x01 ) ? fg : bg]; p++; - } -} - - -/*************************************************************************** - Draw text mode with 40x25 characters (default) with high intensity bg. - The character cell size is 16x8. Composite monitor, greyscale. -***************************************************************************/ - -MC6845_UPDATE_ROW( isa8_cga_device::cga_text_inten_comp_grey_update_row ) -{ - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int i; - - if ( y == 0 ) CGA_LOG(1,"cga_text_inten_comp_grey_update_row",("\n")); - for ( i = 0; i < x_count; i++ ) - { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x3fff; - uint8_t chr = videoram[ offset ]; - uint8_t attr = videoram[ offset +1 ]; - uint8_t data = m_chr_gen[ chr * 8 + ra ]; - uint16_t fg = 0x10 + ( attr & 0x0F ); - uint16_t bg = 0x10 + ( ( attr >> 4 ) & 0x07 ); - - if ( i == cursor_x && ( m_framecnt & 0x08 ) ) - { - data = 0xFF; - } - - *p = palette[( data & 0x80 ) ? fg : bg]; p++; - *p = palette[( data & 0x40 ) ? fg : bg]; p++; - *p = palette[( data & 0x20 ) ? fg : bg]; p++; - *p = palette[( data & 0x10 ) ? fg : bg]; p++; - *p = palette[( data & 0x08 ) ? fg : bg]; p++; - *p = palette[( data & 0x04 ) ? fg : bg]; p++; - *p = palette[( data & 0x02 ) ? fg : bg]; p++; - *p = palette[( data & 0x01 ) ? fg : bg]; p++; - } -} - -/*************************************************************************** - Draw text mode with 40x25 characters (default) with high intensity bg. - The character cell size is 16x8 -***************************************************************************/ - -MC6845_UPDATE_ROW( isa8_cga_device::cga_text_inten_alt_update_row ) -{ - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int i; - - if ( y == 0 ) CGA_LOG(1,"cga_text_inten_alt_update_row",("\n")); - for ( i = 0; i < x_count; i++ ) - { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x3fff; - uint8_t chr = videoram[ offset ]; - uint8_t attr = videoram[ offset +1 ]; - uint8_t data = m_chr_gen[ chr * 8 + ra ]; - uint16_t fg = attr & 0x0F; - - if ( i == cursor_x && ( m_framecnt & 0x08 ) ) - { - data = 0xFF; - } - - *p = palette[( data & 0x80 ) ? fg : 0]; p++; - *p = palette[( data & 0x40 ) ? fg : 0]; p++; - *p = palette[( data & 0x20 ) ? fg : 0]; p++; - *p = palette[( data & 0x10 ) ? fg : 0]; p++; - *p = palette[( data & 0x08 ) ? fg : 0]; p++; - *p = palette[( data & 0x04 ) ? fg : 0]; p++; - *p = palette[( data & 0x02 ) ? fg : 0]; p++; - *p = palette[( data & 0x01 ) ? fg : 0]; p++; - } -} - - -/*************************************************************************** - Draw text mode with 40x25 characters (default) and blinking colors. - The character cell size is 16x8 -***************************************************************************/ - -MC6845_UPDATE_ROW( isa8_cga_device::cga_text_blink_update_row ) +template<bool blink, bool si, bool comp, bool alt, int width> +MC6845_UPDATE_ROW( isa8_cga_device::cga_text ) { uint8_t *videoram = &m_vram[m_start_offset]; uint32_t *p = &bitmap.pix32(y); const rgb_t *palette = m_palette->palette()->entry_list_raw(); int i; - if ( y == 0 ) CGA_LOG(1,"cga_text_blink_update_row",("\n")); + if ( y == 0 ) CGA_LOG(1,"cga_text_8",("\n")); for ( i = 0; i < x_count; i++ ) { uint16_t offset = ( ( ma + i ) << 1 ) & 0x3fff; uint8_t chr = videoram[ offset ]; uint8_t attr = videoram[ offset +1 ]; - uint8_t data = m_chr_gen[ chr * 8 + ra ]; - uint16_t fg = attr & 0x0F; - uint16_t bg = (attr >> 4) & 0x07; + uint8_t data = m_chr_gen[ chr * width + ra ]; + uint16_t fg, bg; + uint8_t xi; - if ( i == cursor_x ) + if ( comp ) { - if ( m_framecnt & 0x08 ) - { - data = 0xFF; - } + fg = 0x10 + ( attr & 0x0F ); + bg = alt ? 0 : ( 0x10 + ( ( attr >> 4 ) & 0x07 ) ); } else { - if ( ( attr & 0x80 ) && ( m_framecnt & 0x10 ) ) - { - data = 0x00; - } + fg = attr & 0x0F; + bg = alt ? 0 : ( ( attr >> 4 ) & ( blink ? 0x07 : 0x0f ) ); } - *p = palette[( data & 0x80 ) ? fg : bg]; p++; - *p = palette[( data & 0x40 ) ? fg : bg]; p++; - *p = palette[( data & 0x20 ) ? fg : bg]; p++; - *p = palette[( data & 0x10 ) ? fg : bg]; p++; - *p = palette[( data & 0x08 ) ? fg : bg]; p++; - *p = palette[( data & 0x04 ) ? fg : bg]; p++; - *p = palette[( data & 0x02 ) ? fg : bg]; p++; - *p = palette[( data & 0x01 ) ? fg : bg]; p++; - } -} - -MC6845_UPDATE_ROW( isa8_cga_device::cga_text_blink_update_row_si ) -{ - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int i; - - if ( y == 0 ) CGA_LOG(1,"cga_text_blink_update_row_si",("\n")); - for ( i = 0; i < x_count; i++ ) - { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x3fff; - uint8_t chr = videoram[ offset ]; - uint8_t attr = videoram[ offset +1 ]; - uint8_t data = m_chr_gen[ chr * 8 + ra ]; - uint16_t fg = attr & 0x0F; - uint16_t bg = (attr >> 4) & 0x07; - uint8_t xi; - - if ( i == cursor_x ) - { - if ( m_framecnt & 0x08 ) - { - data = 0xFF; - } - } - else + if ( ( i == cursor_x ) && ( m_framecnt & 0x08 ) ) + data = 0xFF; + else if ( blink && ( attr & 0x80 ) && ( m_framecnt & 0x10 ) ) { - if ( ( attr & 0x80 ) && ( m_framecnt & 0x10 ) ) - { - data = 0x00; - } + data = 0x00; + bg = ( attr >> 4 ) & 0x07; } for(xi=0;xi<8;xi++) @@ -669,62 +510,13 @@ MC6845_UPDATE_ROW( isa8_cga_device::cga_text_blink_update_row_si ) dot = (data & (1 << (7-xi))); pen_data = dot ? fg : bg; - if(pen_data || dot) + if(!si || (pen_data || dot)) *p = palette[pen_data]; p++; } } } -/*************************************************************************** - Draw text mode with 40x25 characters (default) and blinking colors. - The character cell size is 16x8 -***************************************************************************/ - -MC6845_UPDATE_ROW( isa8_cga_device::cga_text_blink_alt_update_row ) -{ - uint8_t *videoram = &m_vram[m_start_offset]; - uint32_t *p = &bitmap.pix32(y); - const rgb_t *palette = m_palette->palette()->entry_list_raw(); - int i; - - if ( y == 0 ) CGA_LOG(1,"cga_text_blink_alt_update_row",("\n")); - for ( i = 0; i < x_count; i++ ) - { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x3fff; - uint8_t chr = videoram[ offset ]; - uint8_t attr = videoram[ offset +1 ]; - uint8_t data = m_chr_gen[ chr * 8 + ra ]; - uint16_t fg = attr & 0x07; - uint16_t bg = 0; - - if ( i == cursor_x ) - { - if ( m_framecnt & 0x08 ) - { - data = 0xFF; - } - } - else - { - if ( ( attr & 0x80 ) && ( m_framecnt & 0x10 ) ) - { - data = 0x00; - bg = ( attr >> 4 ) & 0x07; - } - } - - *p = palette[( data & 0x80 ) ? fg : bg]; p++; - *p = palette[( data & 0x40 ) ? fg : bg]; p++; - *p = palette[( data & 0x20 ) ? fg : bg]; p++; - *p = palette[( data & 0x10 ) ? fg : bg]; p++; - *p = palette[( data & 0x08 ) ? fg : bg]; p++; - *p = palette[( data & 0x04 ) ? fg : bg]; p++; - *p = palette[( data & 0x02 ) ? fg : bg]; p++; - *p = palette[( data & 0x01 ) ? fg : bg]; p++; - } -} - /* The lo-res (320x200) graphics mode on a colour composite monitor */ @@ -1919,16 +1711,36 @@ MACHINE_CONFIG_MEMBER( isa8_cga_m24_device::device_add_mconfig ) MACHINE_CONFIG_END isa8_cga_m24_device::isa8_cga_m24_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - isa8_cga_device(mconfig, ISA8_CGA_M24, tag, owner, clock), m_mode2(0), m_index(0) + isa8_cga_m24_device(mconfig, ISA8_CGA_M24, tag, owner, clock) +{ +} + +isa8_cga_m24_device::isa8_cga_m24_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + isa8_cga_device(mconfig, type, tag, owner, clock), m_mode2(0), m_index(0) { m_vram_size = 0x8000; } +ROM_START(cga_m24) + ROM_REGION(0x2000, "gfx1", 0) + ROM_LOAD("m24 graphics board go380 258 pqbq.bin", 0x00000, 0x1000, CRC(04495786) SHA1(ea34ee527c5632d049ec11a7ae0fde9e6dee545f)) + + ROM_REGION(0x1000, "crtc_prom", 0) + ROM_LOAD("m24 graphics board go380 gi 9433-0088.bin", 0x00000, 0x1000, CRC(5725e660) SHA1(634c2d165d401883a955e144a0abfa2078a47013)) +ROM_END + +const tiny_rom_entry *isa8_cga_m24_device::device_rom_region() const +{ + return ROM_NAME(cga_m24); +} + void isa8_cga_m24_device::device_reset() { isa8_cga_device::device_reset(); m_mode2 = 0; m_start_offset = 0; + m_chr_gen_offset[0] = m_chr_gen_offset[2] = 0x0000; + m_chr_gen_offset[1] = m_chr_gen_offset[3] = 0x0000; } MC6845_RECONFIGURE( isa8_cga_m24_device::reconfigure ) @@ -1997,12 +1809,50 @@ READ8_MEMBER( isa8_cga_m24_device::io_read ) return data; } -MC6845_UPDATE_ROW( isa8_cga_m24_device::crtc_update_row ) + +MC6845_UPDATE_ROW(isa8_cga_m24_device::crtc_update_row) { if(m_mode2 & 1) m24_gfx_1bpp_m24_update_row(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); - else - isa8_cga_device::crtc_update_row(bitmap, cliprect, ma, ra >> 1, y, x_count, cursor_x, de, hbp, vbp); + + if (m_update_row_type == -1) + return; + + y = m_y; + if(m_y >= bitmap.height()) + return; + + switch (m_update_row_type) + { + case CGA_TEXT_INTEN: + cga_text<false, false, false, false, 16>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + break; + case CGA_TEXT_INTEN_ALT: + cga_text<false, false, false, true, 16>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + break; + case CGA_TEXT_INTEN_CG: // this hardware doesn't support composite + break; + case CGA_TEXT_BLINK: + cga_text<true, false, false, false, 16>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + break; + case CGA_TEXT_BLINK_ALT: + cga_text<true, false, false, true, 16>(bitmap, cliprect, ma, ra, y, x_count, cursor_x, de, hbp, vbp); + break; + case CGA_TEXT_BLINK_SI: + break; + case CGA_GFX_1BPP: + cga_gfx_1bpp_update_row(bitmap, cliprect, ma, ra >> 1, y, x_count, cursor_x, de, hbp, vbp); + break; + case CGA_GFX_2BPP: + cga_gfx_2bpp_update_row(bitmap, cliprect, ma, ra >> 1, y, x_count, cursor_x, de, hbp, vbp); + break; + case CGA_GFX_4BPPL: + cga_gfx_4bppl_update_row(bitmap, cliprect, ma, ra >> 1, y, x_count, cursor_x, de, hbp, vbp); + break; + case CGA_GFX_4BPPH: + cga_gfx_4bpph_update_row(bitmap, cliprect, ma, ra >> 1, y, x_count, cursor_x, de, hbp, vbp); + break; + } } MC6845_UPDATE_ROW( isa8_cga_m24_device::m24_gfx_1bpp_m24_update_row ) @@ -2040,3 +1890,71 @@ MC6845_UPDATE_ROW( isa8_cga_m24_device::m24_gfx_1bpp_m24_update_row ) *p = palette[( data & 0x01 ) ? fg : 0]; p++; } } + +DEFINE_DEVICE_TYPE(ISA8_CGA_CPORTIII, isa8_cga_cportiii_device, "cga_cportiii", "Compaq Portable III CGA") + +MACHINE_CONFIG_MEMBER( isa8_cga_cportiii_device::device_add_mconfig ) + isa8_cga_m24_device::device_add_mconfig(config); + + MCFG_DEVICE_MODIFY(CGA_SCREEN_NAME) + MCFG_SCREEN_COLOR(rgb_t(255, 125, 0)) +MACHINE_CONFIG_END + +isa8_cga_cportiii_device::isa8_cga_cportiii_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + isa8_cga_m24_device(mconfig, ISA8_CGA_CPORTIII, tag, owner, clock) +{ +} + +ROM_START(cga_cportiii) + ROM_REGION(0x2000, "gfx1", 0) + ROM_FILL(0, 0x2000, 0) +ROM_END + +const tiny_rom_entry *isa8_cga_cportiii_device::device_rom_region() const +{ + return ROM_NAME(cga_cportiii); +} + +void isa8_cga_cportiii_device::device_reset() +{ + isa8_cga_m24_device::device_reset(); + m_isa->install_device(0x13c6, 0x13c7, read8_delegate(FUNC(isa8_cga_cportiii_device::port_13c6_r), this), write8_delegate(FUNC(isa8_cga_cportiii_device::port_13c6_w), this)); + m_isa->install_device(0x23c6, 0x23c7, read8_delegate(FUNC(isa8_cga_cportiii_device::port_23c6_r), this), write8_delegate(FUNC(isa8_cga_cportiii_device::port_23c6_w), this)); + m_palette->set_pen_color(0, 100, 25, 0); + m_chr_gen_offset[0] = m_chr_gen_offset[2] = 0x0000; + m_chr_gen_offset[1] = m_chr_gen_offset[3] = 0x1000; +} + +WRITE8_MEMBER(isa8_cga_cportiii_device::char_ram_write) +{ + m_chr_gen_base[offset] = data; +} + +READ8_MEMBER(isa8_cga_cportiii_device::char_ram_read) +{ + return m_chr_gen_base[offset]; +} + +READ8_MEMBER(isa8_cga_cportiii_device::port_13c6_r) +{ + return 0x04; +} + +WRITE8_MEMBER(isa8_cga_cportiii_device::port_13c6_w) +{ +} + +READ8_MEMBER(isa8_cga_cportiii_device::port_23c6_r) +{ + return 0; +} + +WRITE8_MEMBER(isa8_cga_cportiii_device::port_23c6_w) +{ + m_mode2 = data & 1; + if(BIT(data, 3)) + m_isa->install_memory(0xb8000, 0xb9fff, read8_delegate(FUNC(isa8_cga_cportiii_device::char_ram_read), this), write8_delegate(FUNC(isa8_cga_cportiii_device::char_ram_write), this)); + else + m_isa->install_bank(0xb8000, 0xb8000 + 0x8000 - 1, "bank_cga", &m_vram[0]); +} + diff --git a/src/devices/bus/isa/cga.h b/src/devices/bus/isa/cga.h index d482859fbb4..ca799d9b8cc 100644 --- a/src/devices/bus/isa/cga.h +++ b/src/devices/bus/isa/cga.h @@ -31,12 +31,7 @@ public: isa8_cga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); virtual MC6845_UPDATE_ROW( crtc_update_row ); - MC6845_UPDATE_ROW( cga_text_inten_update_row ); - MC6845_UPDATE_ROW( cga_text_inten_comp_grey_update_row ); - MC6845_UPDATE_ROW( cga_text_inten_alt_update_row ); - MC6845_UPDATE_ROW( cga_text_blink_update_row ); - MC6845_UPDATE_ROW( cga_text_blink_update_row_si ); - MC6845_UPDATE_ROW( cga_text_blink_alt_update_row ); + template<bool blink, bool si, bool comp, bool alt, int width> MC6845_UPDATE_ROW( cga_text ); MC6845_UPDATE_ROW( cga_gfx_4bppl_update_row ); MC6845_UPDATE_ROW( cga_gfx_4bpph_update_row ); MC6845_UPDATE_ROW( cga_gfx_2bpp_update_row ); @@ -285,15 +280,34 @@ public: MC6845_RECONFIGURE(reconfigure); protected: + isa8_cga_m24_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); virtual void device_reset() override; // optional information overrides virtual void device_add_mconfig(machine_config &config) override; - -private: + virtual const tiny_rom_entry *device_rom_region() const override; uint8_t m_mode2, m_index; }; // device type definition DECLARE_DEVICE_TYPE(ISA8_CGA_M24, isa8_cga_m24_device) +class isa8_cga_cportiii_device : + public isa8_cga_m24_device +{ +public: + isa8_cga_cportiii_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + DECLARE_READ8_MEMBER(port_13c6_r); + DECLARE_WRITE8_MEMBER(port_13c6_w); + DECLARE_READ8_MEMBER(port_23c6_r); + DECLARE_WRITE8_MEMBER(port_23c6_w); + DECLARE_READ8_MEMBER(char_ram_read); + DECLARE_WRITE8_MEMBER(char_ram_write); +protected: + virtual void device_reset() override; + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; +}; + +DECLARE_DEVICE_TYPE(ISA8_CGA_CPORTIII, isa8_cga_cportiii_device) + #endif // MAME_BUS_ISA_CGA_H diff --git a/src/devices/bus/isa/isa.cpp b/src/devices/bus/isa/isa.cpp index bb7dc721d96..413911ee0f7 100644 --- a/src/devices/bus/isa/isa.cpp +++ b/src/devices/bus/isa/isa.cpp @@ -103,7 +103,7 @@ DEFINE_DEVICE_TYPE(ISA8, isa8_device, "isa8", "8-bit ISA bus") void isa8_device::static_set_cputag(device_t &device, const char *tag) { isa8_device &isa = downcast<isa8_device &>(device); - isa.m_cputag = tag; + isa.m_maincpu.set_tag(tag); } void isa8_device::static_set_custom_spaces(device_t &device) @@ -133,7 +133,7 @@ isa8_device::isa8_device(const machine_config &mconfig, device_type type, const m_io_config("ISA 8-bit I/O", ENDIANNESS_LITTLE, 8, 16, 0, nullptr), m_mem16_config("ISA 16-bit mem", ENDIANNESS_LITTLE, 16, 24, 0, nullptr), m_io16_config("ISA 16-bit I/O", ENDIANNESS_LITTLE, 16, 16, 0, nullptr), - m_maincpu(nullptr), + m_maincpu(*this, finder_base::DUMMY_TAG), m_iospace(nullptr), m_memspace(nullptr), m_out_irq2_cb(*this), @@ -144,7 +144,7 @@ isa8_device::isa8_device(const machine_config &mconfig, device_type type, const m_out_irq7_cb(*this), m_out_drq1_cb(*this), m_out_drq2_cb(*this), - m_out_drq3_cb(*this), m_cputag(nullptr), + m_out_drq3_cb(*this), m_write_iochck(*this) { for(int i=0;i<8;i++) @@ -222,8 +222,6 @@ void isa8_device::device_start() m_out_drq2_cb.resolve_safe(); m_out_drq3_cb.resolve_safe(); - m_maincpu = subdevice<cpu_device>(m_cputag); - if (m_allocspaces) { m_iospace = &space(AS_ISA_IO); @@ -234,9 +232,9 @@ void isa8_device::device_start() else // use host CPU's program and I/O spaces directly { m_iospace = &m_maincpu->space(AS_IO); - m_iowidth = m_maincpu->space_config(AS_IO)->m_databus_width; + m_iowidth = m_maincpu->space_config(AS_IO)->m_data_width; m_memspace = &m_maincpu->space(AS_PROGRAM); - m_memwidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width; + m_memwidth = m_maincpu->space_config(AS_PROGRAM)->m_data_width; } } @@ -337,7 +335,6 @@ void isa8_device::unmap_rom(offs_t start, offs_t end) bool isa8_device::is_option_rom_space_available(offs_t start, int size) { - m_maincpu = machine().device<cpu_device>(m_cputag); for(int i = 0; i < size; i += 4096) // 4KB granularity should be enough if(m_memspace->get_read_ptr(start + i)) return false; return true; diff --git a/src/devices/bus/isa/isa.h b/src/devices/bus/isa/isa.h index 32b344fdbb3..e41e5cf07ec 100644 --- a/src/devices/bus/isa/isa.h +++ b/src/devices/bus/isa/isa.h @@ -269,7 +269,7 @@ protected: virtual void device_reset() override; // internal state - cpu_device *m_maincpu; + required_device<cpu_device> m_maincpu; // address spaces address_space *m_iospace, *m_memspace; @@ -288,7 +288,6 @@ protected: device_isa8_card_interface *m_dma_device[8]; bool m_dma_eop[8]; - const char *m_cputag; bool m_nmi_enabled; private: diff --git a/src/devices/bus/isa/isa_cards.cpp b/src/devices/bus/isa/isa_cards.cpp index 218c0231baa..5f1e5243fd1 100644 --- a/src/devices/bus/isa/isa_cards.cpp +++ b/src/devices/bus/isa/isa_cards.cpp @@ -69,6 +69,7 @@ SLOT_INTERFACE_START( pc_isa8_cards ) SLOT_INTERFACE("cga_poisk2", ISA8_CGA_POISK2) SLOT_INTERFACE("cga_mc1502", ISA8_CGA_MC1502) SLOT_INTERFACE("cga_m24", ISA8_CGA_M24) + SLOT_INTERFACE("cga_cportiii", ISA8_CGA_CPORTIII) SLOT_INTERFACE("aga", ISA8_AGA) SLOT_INTERFACE("aga_pc200", ISA8_AGA_PC200) SLOT_INTERFACE("ega", ISA8_EGA) @@ -110,6 +111,7 @@ SLOT_INTERFACE_START( pc_isa16_cards ) // 8-bit SLOT_INTERFACE("mda", ISA8_MDA) SLOT_INTERFACE("cga", ISA8_CGA) + SLOT_INTERFACE("cga_cportiii", ISA8_CGA_CPORTIII) SLOT_INTERFACE("wyse700", ISA8_WYSE700) SLOT_INTERFACE("ega", ISA8_EGA) SLOT_INTERFACE("pgc", ISA8_PGC) diff --git a/src/devices/bus/isa/omti8621.cpp b/src/devices/bus/isa/omti8621.cpp index ddffb43575e..3490b7ae7fe 100644 --- a/src/devices/bus/isa/omti8621.cpp +++ b/src/devices/bus/isa/omti8621.cpp @@ -64,8 +64,6 @@ public: virtual bool is_reset_on_load() const override { return 0; } virtual bool support_command_line_image_creation() const override { return 1; } virtual const char *file_extensions() const override { return "awd"; } - virtual const char *custom_instance_name() const override { return "disk"; } - virtual const char *custom_brief_instance_name() const override { return "disk"; } virtual image_init_result call_create(int format_type, util::option_resolution *format_options) override; protected: diff --git a/src/devices/bus/lpci/i82371ab.cpp b/src/devices/bus/lpci/i82371ab.cpp index 1c6d2f0e166..df44ac6c1d1 100644 --- a/src/devices/bus/lpci/i82371ab.cpp +++ b/src/devices/bus/lpci/i82371ab.cpp @@ -23,7 +23,7 @@ DEFINE_DEVICE_TYPE(I82371AB, i82371ab_device, "i82371ab", "Intel 82371AB") i82371ab_device::i82371ab_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : southbridge_device(mconfig, I82371AB, tag, owner, clock) + : southbridge_extended_device(mconfig, I82371AB, tag, owner, clock) , pci_device_interface(mconfig, *this) { } @@ -53,11 +53,11 @@ void i82371ab_device::pci_isa_w(device_t *busdevice, int offset, uint32_t data, switch (offset) { case 0x04: - /* clear reserved bits */ + // clear reserved bits m_regs[0][offset] = cdata & 0x05; break; case 0x06: - /* set new status */ + // set new status m_regs[0][offset] |= 0x80; break; case 0x07: @@ -92,11 +92,11 @@ void i82371ab_device::pci_ide_w(device_t *busdevice, int offset, uint32_t data, switch (offset) { case 0x04: - /* clear reserved bits */ + // clear reserved bits m_regs[1][offset] = cdata & 0x05; break; case 0x06: - /* set new status */ + // set new status m_regs[1][offset] |= 0x80; break; case 0x07: @@ -131,11 +131,11 @@ void i82371ab_device::pci_usb_w(device_t *busdevice, int offset, uint32_t data, switch (offset) { case 0x04: - /* clear reserved bits */ + // clear reserved bits m_regs[2][offset] = cdata & 0x05; break; case 0x06: - /* set new status */ + // set new status m_regs[2][offset] |= 0x80; break; case 0x07: @@ -170,11 +170,11 @@ void i82371ab_device::pci_acpi_w(device_t *busdevice, int offset, uint32_t data, switch (offset) { case 0x04: - /* clear reserved bits */ + // clear reserved bits m_regs[3][offset] = cdata & 0x05; break; case 0x06: - /* set new status */ + // set new status m_regs[3][offset] |= 0x80; break; case 0x07: @@ -216,8 +216,8 @@ void i82371ab_device::pci_write(pci_bus_device *pcibus, int function, int offset void i82371ab_device::device_start() { - southbridge_device::device_start(); - /* setup save states */ + southbridge_extended_device::device_start(); + // setup save states save_item(NAME(m_regs)); } @@ -227,29 +227,29 @@ void i82371ab_device::device_start() void i82371ab_device::device_reset() { - southbridge_device::device_reset(); + southbridge_extended_device::device_reset(); memset(m_regs, 0, sizeof(m_regs)); uint32_t (*regs32)[64] = (uint32_t (*)[64])(m_regs); - /* isa */ + // isa regs32[0][0x00] = 0x71108086; regs32[0][0x04] = 0x00000000; regs32[0][0x08] = 0x06010000; regs32[0][0x0c] = 0x00800000; - /* ide */ + // ide regs32[1][0x00] = 0x71118086; regs32[1][0x04] = 0x02800000; regs32[1][0x08] = 0x01018000; regs32[1][0x0c] = 0x00000000; - /* usb */ + // usb regs32[2][0x00] = 0x71128086; regs32[2][0x04] = 0x02800000; regs32[2][0x08] = 0x0c030000; regs32[2][0x0c] = 0x00000000; - /* acpi */ + // acpi regs32[3][0x00] = 0x71138086; regs32[3][0x04] = 0x02800000; regs32[3][0x08] = 0x06800000; diff --git a/src/devices/bus/lpci/i82371ab.h b/src/devices/bus/lpci/i82371ab.h index dc251bee0bf..776ae8d00d5 100644 --- a/src/devices/bus/lpci/i82371ab.h +++ b/src/devices/bus/lpci/i82371ab.h @@ -18,7 +18,7 @@ // ======================> i82371ab_device -class i82371ab_device : public southbridge_device, +class i82371ab_device : public southbridge_extended_device, public pci_device_interface { public: diff --git a/src/devices/bus/lpci/i82371sb.cpp b/src/devices/bus/lpci/i82371sb.cpp index 6fd7308a922..e30640440e8 100644 --- a/src/devices/bus/lpci/i82371sb.cpp +++ b/src/devices/bus/lpci/i82371sb.cpp @@ -19,6 +19,7 @@ #include "emu.h" #include "i82371sb.h" +//#define VERBOSE /*************************************************************************** IMPLEMENTATION @@ -38,24 +39,28 @@ uint32_t i82371sb_device::pci_isa_r(device_t *busdevice,int offset, uint32_t mem { uint32_t result = m_regs[0][offset]; - //logerror("i82371sb_pci_isa_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); +#ifdef VERBOSE + logerror("i82371sb_pci_isa_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); +#endif return result; } void i82371sb_device::pci_isa_w(device_t *busdevice, int offset, uint32_t data, uint32_t mem_mask) { - //logerror("i82371sb_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); +#ifdef VERBOSE + logerror("i82371sb_pci_isa_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); +#endif switch (offset) { case 0x04: COMBINE_DATA(&m_regs[0][offset]); - /* clear reserved bits */ + // clear reserved bits m_regs[0][offset] &= 0x00000005; - /* set new status */ + // set new status m_regs[0][offset] |= 0x02800000; break; @@ -64,24 +69,30 @@ void i82371sb_device::pci_isa_w(device_t *busdevice, int offset, uint32_t data, uint32_t i82371sb_device::pci_ide_r(device_t *busdevice, int offset, uint32_t mem_mask) { - //logerror("i82371sb_pci_ide_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); uint32_t result = m_regs[1][offset]; + +#ifdef VERBOSE + logerror("i82371sb_pci_ide_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); +#endif + return result; } void i82371sb_device::pci_ide_w(device_t *busdevice, int offset, uint32_t data, uint32_t mem_mask) { - //logerror("i82371sb_pci_ide_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); +#ifdef VERBOSE + logerror("i82371sb_pci_ide_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); +#endif switch (offset) { case 0x04: COMBINE_DATA(&m_regs[1][offset]); - /* clear reserved bits */ + // clear reserved bits m_regs[1][offset] &= 0x00000005; - /* set new status */ + // set new status m_regs[1][offset] |= 0x02800000; break; @@ -92,24 +103,28 @@ uint32_t i82371sb_device::pci_usb_r(device_t *busdevice, int offset, uint32_t me { uint32_t result = m_regs[2][offset]; - //logerror("i82371sb_pci_usb_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); +#ifdef VERBOSE + logerror("i82371sb_pci_usb_r, offset = %02x, mem_mask = %08x\n", offset, mem_mask); +#endif return result; } void i82371sb_device::pci_usb_w(device_t *busdevice, int offset, uint32_t data, uint32_t mem_mask) { - //logerror("i82371sb_pci_usb_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); +#ifdef VERBOSE + logerror("i82371sb_pci_usb_w, offset = %02x, data = %08x, mem_mask = %08x\n", offset, data, mem_mask); +#endif switch (offset) { case 0x04: COMBINE_DATA(&m_regs[2][offset]); - /* clear reserved bits */ + // clear reserved bits m_regs[2][offset] &= 0x00000005; - /* set new status */ + // set new status m_regs[2][offset] |= 0x02800000; break; @@ -124,8 +139,9 @@ uint32_t i82371sb_device::pci_read(pci_bus_device *pcibus, int function, int off case 1: return pci_ide_r(pcibus, offset, mem_mask); case 2: return pci_usb_r(pcibus, offset, mem_mask); } - - //logerror("i82371sb_pci_read: read from undefined function %d\n", function); +#ifdef VERBOSE + logerror("i82371sb_pci_read: read from undefined function %d offset %08X mask %08X\n", function,offset,mem_mask); +#endif return 0; } @@ -138,7 +154,9 @@ void i82371sb_device::pci_write(pci_bus_device *pcibus, int function, int offset case 1: pci_ide_w(pcibus, offset, data, mem_mask); break; case 2: pci_usb_w(pcibus, offset, data, mem_mask); break; } - //logerror("i82371sb_pci_write: write to undefined function %d\n", function); +#ifdef VERBOSE + logerror("i82371sb_pci_write: write to undefined function %d offset %08X mask %08X data %08X\n", function, offset, mem_mask, data); +#endif } //------------------------------------------------- @@ -149,7 +167,7 @@ void i82371sb_device::device_start() { southbridge_device::device_start(); m_boot_state_hook.resolve_safe(); - /* setup save states */ + // setup save states save_item(NAME(m_regs)); } @@ -163,19 +181,19 @@ void i82371sb_device::device_reset() memset(m_regs, 0, sizeof(m_regs)); - /* isa */ + // isa m_regs[0][0x00] = 0x70008086; m_regs[0][0x04] = 0x00000000; m_regs[0][0x08] = 0x06010000; m_regs[0][0x0c] = 0x00800000; - /* ide */ + // ide m_regs[1][0x00] = 0x70108086; m_regs[1][0x04] = 0x02800000; m_regs[1][0x08] = 0x01018000; m_regs[1][0x0c] = 0x00000000; - /* usb */ + // usb m_regs[2][0x00] = 0x70208086; m_regs[2][0x04] = 0x02800000; m_regs[2][0x08] = 0x0c030000; diff --git a/src/devices/bus/lpci/i82439tx.cpp b/src/devices/bus/lpci/i82439tx.cpp index 39750f7cd7f..5c943036f8b 100644 --- a/src/devices/bus/lpci/i82439tx.cpp +++ b/src/devices/bus/lpci/i82439tx.cpp @@ -9,6 +9,8 @@ #include "emu.h" #include "i82439tx.h" +//#define VERBOSE + /*************************************************************************** IMPLEMENTATION ***************************************************************************/ @@ -57,37 +59,40 @@ uint32_t i82439tx_device::pci_read(pci_bus_device *pcibus, int function, int off { uint32_t result; +#ifdef VERBOSE + logerror("i82439tx_pci_read: read from function %d offset %08X mask %08X\n", function, offset, mem_mask); +#endif if (function != 0) return 0; switch(offset) { - case 0x00: /* vendor/device ID */ + case 0x00: // vendor/device ID result = 0x71008086; break; - case 0x08: /* revision identification register and class code register*/ + case 0x08: // revision identification register and class code register result = 0x06000001; break; - case 0x04: /* PCI command register */ + case 0x04: // PCI command register case 0x0C: - case 0x10: /* reserved */ - case 0x14: /* reserved */ - case 0x18: /* reserved */ - case 0x1C: /* reserved */ - case 0x20: /* reserved */ - case 0x24: /* reserved */ - case 0x28: /* reserved */ - case 0x2C: /* reserved */ - case 0x30: /* reserved */ - case 0x34: /* reserved */ - case 0x38: /* reserved */ - case 0x3C: /* reserved */ - case 0x40: /* reserved */ - case 0x44: /* reserved */ - case 0x48: /* reserved */ - case 0x4C: /* reserved */ + case 0x10: // reserved + case 0x14: // reserved + case 0x18: // reserved + case 0x1C: // reserved + case 0x20: // reserved + case 0x24: // reserved + case 0x28: // reserved + case 0x2C: // reserved + case 0x30: // reserved + case 0x34: // reserved + case 0x38: // reserved + case 0x3C: // reserved + case 0x40: // reserved + case 0x44: // reserved + case 0x48: // reserved + case 0x4C: // reserved logerror("i82439tx_pci_read(): Unemulated PCI read 0x%02X, returning 0\n", offset); result = 0; break; @@ -148,27 +153,30 @@ uint32_t i82439tx_device::pci_read(pci_bus_device *pcibus, int function, int off void i82439tx_device::pci_write(pci_bus_device *pcibus, int function, int offset, uint32_t data, uint32_t mem_mask) { +#ifdef VERBOSE + logerror("i82439tx_pci_write: write to function %d offset %08X mask %08X data %08X\n", function, offset, mem_mask, data); +#endif if (function != 0) return; switch(offset) { - case 0x00: /* vendor/device ID */ - case 0x10: /* reserved */ - case 0x14: /* reserved */ - case 0x18: /* reserved */ - case 0x1C: /* reserved */ - case 0x20: /* reserved */ - case 0x24: /* reserved */ - case 0x28: /* reserved */ - case 0x2C: /* reserved */ - case 0x30: /* reserved */ - case 0x3C: /* reserved */ - case 0x40: /* reserved */ - case 0x44: /* reserved */ - case 0x48: /* reserved */ - case 0x4C: /* reserved */ - /* read only */ + case 0x00: // vendor/device ID + case 0x10: // reserved + case 0x14: // reserved + case 0x18: // reserved + case 0x1C: // reserved + case 0x20: // reserved + case 0x24: // reserved + case 0x28: // reserved + case 0x2C: // reserved + case 0x30: // reserved + case 0x3C: // reserved + case 0x40: // reserved + case 0x44: // reserved + case 0x48: // reserved + case 0x4C: // reserved + // read only break; case 0x58: @@ -179,7 +187,7 @@ void i82439tx_device::pci_write(pci_bus_device *pcibus, int function, int offset if ((mem_mask & 0x00f00000)) i82439tx_configure_memory(data >> 20, 0xc4000, 0xc7fff); if ((mem_mask & 0x0f000000)) - i82439tx_configure_memory(data >> 24, 0xc8000, 0xccfff); + i82439tx_configure_memory(data >> 24, 0xc8000, 0xcbfff); if ((mem_mask & 0xf0000000)) i82439tx_configure_memory(data >> 28, 0xcc000, 0xcffff); COMBINE_DATA(&m_regs[(offset - 0x50) / 4]); @@ -199,13 +207,13 @@ void i82439tx_device::pci_write(pci_bus_device *pcibus, int function, int offset if ((mem_mask & 0x00f00000)) i82439tx_configure_memory(data >> 20, 0xe4000, 0xe7fff); if ((mem_mask & 0x0f000000)) - i82439tx_configure_memory(data >> 24, 0xe8000, 0xecfff); + i82439tx_configure_memory(data >> 24, 0xe8000, 0xebfff); if ((mem_mask & 0xf0000000)) i82439tx_configure_memory(data >> 28, 0xec000, 0xeffff); COMBINE_DATA(&m_regs[(offset - 0x50) / 4]); break; - case 0x04: /* PCI command register */ + case 0x04: // PCI command register case 0x0C: logerror("i82439tx_pci_write(): Unemulated PCI write 0x%02X = 0x%04X\n", offset, data); break; @@ -268,16 +276,16 @@ void i82439tx_device::pci_write(pci_bus_device *pcibus, int function, int offset void i82439tx_device::device_start() { northbridge_device::device_start(); - /* get address space we are working on */ + // get address space we are working on device_t *cpu = machine().device(m_cpu_tag); assert(cpu != nullptr); m_space = &cpu->memory().space(AS_PROGRAM); - /* get rom region */ + // get rom region m_rom = machine().root_device().memregion(m_region_tag)->base(); - /* setup save states */ + // setup save states save_item(NAME(m_regs)); save_item(NAME(m_bios_ram)); } @@ -289,7 +297,7 @@ void i82439tx_device::device_start() void i82439tx_device::device_reset() { northbridge_device::device_reset(); - /* setup initial values */ + // setup initial values m_regs[0x00] = 0x14020000; m_regs[0x01] = 0x01520000; m_regs[0x02] = 0x00000000; @@ -301,7 +309,7 @@ void i82439tx_device::device_reset() memset(m_bios_ram, 0, sizeof(m_bios_ram)); - /* configure initial memory state */ + // configure initial memory state i82439tx_configure_memory(0, 0xf0000, 0xfffff); i82439tx_configure_memory(0, 0xc0000, 0xc3fff); i82439tx_configure_memory(0, 0xc4000, 0xc7fff); diff --git a/src/devices/bus/lpci/i82439tx.h b/src/devices/bus/lpci/i82439tx.h index e94b95629c0..8853b9b96a6 100644 --- a/src/devices/bus/lpci/i82439tx.h +++ b/src/devices/bus/lpci/i82439tx.h @@ -50,7 +50,7 @@ private: address_space *m_space; uint8_t *m_rom; - uint32_t m_regs[8]; + uint32_t m_regs[8*256]; uint32_t m_bios_ram[0x40000 / 4]; }; diff --git a/src/devices/bus/lpci/southbridge.cpp b/src/devices/bus/lpci/southbridge.cpp index c571815ab06..06534804228 100644 --- a/src/devices/bus/lpci/southbridge.cpp +++ b/src/devices/bus/lpci/southbridge.cpp @@ -17,12 +17,9 @@ #include "speaker.h" -static SLOT_INTERFACE_START(pc_isa_onboard) - SLOT_INTERFACE("comat", ISA8_COM_AT) - SLOT_INTERFACE("lpt", ISA8_LPT) - SLOT_INTERFACE("fdcsmc", ISA8_FDC_SMC) -SLOT_INTERFACE_END - +/*************************************************************************** + Southbridge Device +***************************************************************************/ //------------------------------------------------- // device_add_mconfig - add device configuration @@ -30,11 +27,11 @@ SLOT_INTERFACE_END MACHINE_CONFIG_MEMBER( southbridge_device::device_add_mconfig ) MCFG_DEVICE_ADD("pit8254", PIT8254, 0) - MCFG_PIT8253_CLK0(4772720/4) /* heartbeat IRQ */ + MCFG_PIT8253_CLK0(4772720/4) // heartbeat IRQ MCFG_PIT8253_OUT0_HANDLER(WRITELINE(southbridge_device, at_pit8254_out0_changed)) - MCFG_PIT8253_CLK1(4772720/4) /* dram refresh */ + MCFG_PIT8253_CLK1(4772720/4) // dram refresh MCFG_PIT8253_OUT1_HANDLER(WRITELINE(southbridge_device, at_pit8254_out1_changed)) - MCFG_PIT8253_CLK2(4772720/4) /* pio port c pin 4, and speaker polling enough */ + MCFG_PIT8253_CLK2(4772720/4) // pio port c pin 4, and speaker polling enough MCFG_PIT8253_OUT2_HANDLER(WRITELINE(southbridge_device, at_pit8254_out2_changed)) MCFG_DEVICE_ADD( "dma8237_1", AM9517A, XTAL_14_31818MHz/3 ) @@ -79,21 +76,6 @@ MACHINE_CONFIG_MEMBER( southbridge_device::device_add_mconfig ) MCFG_PIC8259_OUT_INT_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir2_w)) MCFG_PIC8259_IN_SP_CB(GND) - MCFG_DEVICE_ADD("keybc", AT_KEYBOARD_CONTROLLER, XTAL_12MHz) - MCFG_AT_KEYBOARD_CONTROLLER_SYSTEM_RESET_CB(INPUTLINE(":maincpu", INPUT_LINE_RESET)) - MCFG_AT_KEYBOARD_CONTROLLER_GATE_A20_CB(INPUTLINE(":maincpu", INPUT_LINE_A20)) - MCFG_AT_KEYBOARD_CONTROLLER_INPUT_BUFFER_FULL_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir1_w)) - MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_CLOCK_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, clock_write_from_mb)) - MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_DATA_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, data_write_from_mb)) - MCFG_DEVICE_ADD("pc_kbdc", PC_KBDC, 0) - MCFG_PC_KBDC_OUT_CLOCK_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_clock_w)) - MCFG_PC_KBDC_OUT_DATA_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_data_w)) - MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL) - - MCFG_DS12885_ADD("rtc") - MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir0_w)) - MCFG_MC146818_CENTURY_INDEX(0x32) - MCFG_BUS_MASTER_IDE_CONTROLLER_ADD("ide", ata_devices, "hdd", nullptr, false) MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir6_w)) MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM) @@ -102,7 +84,7 @@ MACHINE_CONFIG_MEMBER( southbridge_device::device_add_mconfig ) MCFG_ATA_INTERFACE_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir7_w)) MCFG_BUS_MASTER_IDE_CONTROLLER_SPACE(":maincpu", AS_PROGRAM) - /* sound hardware */ + // sound hardware MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) @@ -127,10 +109,6 @@ MACHINE_CONFIG_MEMBER( southbridge_device::device_add_mconfig ) MCFG_ISA_OUT_DRQ5_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq1_w)) MCFG_ISA_OUT_DRQ6_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq2_w)) MCFG_ISA_OUT_DRQ7_CB(DEVWRITELINE("dma8237_2", am9517a_device, dreq3_w)) - // on board devices - MCFG_ISA16_SLOT_ADD("isabus","board1", pc_isa_onboard, "fdcsmc", true) - MCFG_ISA16_SLOT_ADD("isabus","board2", pc_isa_onboard, "comat", true) - MCFG_ISA16_SLOT_ADD("isabus","board3", pc_isa_onboard, "lpt", true) MACHINE_CONFIG_END southbridge_device::southbridge_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) @@ -141,15 +119,14 @@ southbridge_device::southbridge_device(const machine_config &mconfig, device_typ m_dma8237_1(*this, "dma8237_1"), m_dma8237_2(*this, "dma8237_2"), m_pit8254(*this, "pit8254"), - m_keybc(*this, "keybc"), m_isabus(*this, "isabus"), m_speaker(*this, "speaker"), - m_ds12885(*this, "rtc"), - m_pc_kbdc(*this, "pc_kbdc"), m_ide(*this, "ide"), - m_ide2(*this, "ide2"), m_at_spkrdata(0), m_pit_out2(0), m_dma_channel(0), m_cur_eop(false), m_dma_high_byte(0), m_at_speaker(0), m_refresh(false), m_channel_check(0), m_nmi_enabled(0) + m_ide2(*this, "ide2"), + m_at_spkrdata(0), m_pit_out2(0), m_dma_channel(0), m_cur_eop(false), m_dma_high_byte(0), m_at_speaker(0), m_refresh(false), m_channel_check(0), m_nmi_enabled(0) { } + /********************************************************** * * Init functions @@ -188,10 +165,7 @@ void southbridge_device::device_start() spaceio.install_readwrite_handler(0x0000, 0x001f, read8_delegate(FUNC(am9517a_device::read),&(*m_dma8237_1)), write8_delegate(FUNC(am9517a_device::write),&(*m_dma8237_1)), 0xffffffff); spaceio.install_readwrite_handler(0x0020, 0x003f, read8_delegate(FUNC(pic8259_device::read),&(*m_pic8259_master)), write8_delegate(FUNC(pic8259_device::write),&(*m_pic8259_master)), 0xffffffff); spaceio.install_readwrite_handler(0x0040, 0x005f, read8_delegate(FUNC(pit8254_device::read),&(*m_pit8254)), write8_delegate(FUNC(pit8254_device::write),&(*m_pit8254)), 0xffffffff); - spaceio.install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(at_keyboard_controller_device::data_r), &(*m_keybc)), write8_delegate(FUNC(at_keyboard_controller_device::data_w), &(*m_keybc)), 0x000000ff); spaceio.install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(southbridge_device::at_portb_r), this), write8_delegate(FUNC(southbridge_device::at_portb_w), this), 0x0000ff00); - spaceio.install_readwrite_handler(0x0064, 0x0067, read8_delegate(FUNC(at_keyboard_controller_device::status_r),&(*m_keybc)), write8_delegate(FUNC(at_keyboard_controller_device::command_w),&(*m_keybc)), 0xffffffff); - spaceio.install_readwrite_handler(0x0070, 0x007f, read8_delegate(FUNC(ds12885_device::read),&(*m_ds12885)), write8_delegate(FUNC(ds12885_device::write),&(*m_ds12885)), 0xffffffff); spaceio.install_readwrite_handler(0x0080, 0x009f, read8_delegate(FUNC(southbridge_device::at_page8_r),this), write8_delegate(FUNC(southbridge_device::at_page8_w),this), 0xffffffff); spaceio.install_readwrite_handler(0x00a0, 0x00bf, read8_delegate(FUNC(pic8259_device::read),&(*m_pic8259_slave)), write8_delegate(FUNC(pic8259_device::write),&(*m_pic8259_slave)), 0xffffffff); spaceio.install_readwrite_handler(0x00c0, 0x00df, read8_delegate(FUNC(southbridge_device::at_dma8237_2_r),this), write8_delegate(FUNC(southbridge_device::at_dma8237_2_w),this), 0xffffffff); @@ -328,7 +302,7 @@ WRITE_LINE_MEMBER( southbridge_device::pc_dma_hrq_changed ) { m_maincpu->set_input_line(INPUT_LINE_HALT, state ? ASSERT_LINE : CLEAR_LINE); - /* Assert HLDA */ + // Assert HLDA m_dma8237_2->hack_w( state ); } @@ -433,15 +407,15 @@ WRITE_LINE_MEMBER( southbridge_device::pc_dack7_w ) { pc_select_dma_channel(7, s READ8_MEMBER( southbridge_device::at_portb_r ) { uint8_t data = m_at_speaker; - data &= ~0xd0; /* AT BIOS don't likes this being set */ + data &= ~0xd0; // AT BIOS don't likes this being set - /* 0x10 is the dram refresh line bit on the 5170, just a timer here, 15.085us. */ + // 0x10 is the dram refresh line bit on the 5170, just a timer here, 15.085us. data |= m_refresh ? 0x10 : 0; if (m_pit_out2) data |= 0x20; else - data &= ~0x20; /* ps2m30 wants this */ + data &= ~0x20; // ps2m30 wants this return data; } @@ -465,7 +439,77 @@ WRITE8_MEMBER( southbridge_device::at_dma8237_2_w ) m_dma8237_2->write( space, offset / 2, data); } -WRITE8_MEMBER( southbridge_device::write_rtc ) +/*************************************************************************** + Extended Southbridge Device +***************************************************************************/ + +static SLOT_INTERFACE_START(pc_isa_onboard) + SLOT_INTERFACE("comat", ISA8_COM_AT) + SLOT_INTERFACE("lpt", ISA8_LPT) + SLOT_INTERFACE("fdcsmc", ISA8_FDC_SMC) +SLOT_INTERFACE_END + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER(southbridge_extended_device::device_add_mconfig) + southbridge_device::device_add_mconfig(config); + + MCFG_DEVICE_ADD("keybc", AT_KEYBOARD_CONTROLLER, XTAL_12MHz) + MCFG_AT_KEYBOARD_CONTROLLER_SYSTEM_RESET_CB(INPUTLINE(":maincpu", INPUT_LINE_RESET)) + MCFG_AT_KEYBOARD_CONTROLLER_GATE_A20_CB(INPUTLINE(":maincpu", INPUT_LINE_A20)) + MCFG_AT_KEYBOARD_CONTROLLER_INPUT_BUFFER_FULL_CB(DEVWRITELINE("pic8259_master", pic8259_device, ir1_w)) + MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_CLOCK_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, clock_write_from_mb)) + MCFG_AT_KEYBOARD_CONTROLLER_KEYBOARD_DATA_CB(DEVWRITELINE("pc_kbdc", pc_kbdc_device, data_write_from_mb)) + MCFG_DEVICE_ADD("pc_kbdc", PC_KBDC, 0) + MCFG_PC_KBDC_OUT_CLOCK_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_clock_w)) + MCFG_PC_KBDC_OUT_DATA_CB(DEVWRITELINE("keybc", at_keyboard_controller_device, keyboard_data_w)) + MCFG_PC_KBDC_SLOT_ADD("pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_MICROSOFT_NATURAL) + + MCFG_DS12885_ADD("rtc") + MCFG_MC146818_IRQ_HANDLER(DEVWRITELINE("pic8259_slave", pic8259_device, ir0_w)) + MCFG_MC146818_CENTURY_INDEX(0x32) + + // on board devices + MCFG_ISA16_SLOT_ADD("isabus", "board1", pc_isa_onboard, "fdcsmc", true) + MCFG_ISA16_SLOT_ADD("isabus", "board2", pc_isa_onboard, "comat", true) + MCFG_ISA16_SLOT_ADD("isabus", "board3", pc_isa_onboard, "lpt", true) +MACHINE_CONFIG_END + +southbridge_extended_device::southbridge_extended_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : southbridge_device(mconfig, type, tag, owner, clock), + m_keybc(*this, "keybc"), + m_ds12885(*this, "rtc"), + m_pc_kbdc(*this, "pc_kbdc") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void southbridge_extended_device::device_start() +{ + address_space& spaceio = machine().device(":maincpu")->memory().space(AS_IO); + + southbridge_device::device_start(); + + spaceio.install_readwrite_handler(0x0060, 0x0063, read8_delegate(FUNC(at_keyboard_controller_device::data_r), &(*m_keybc)), write8_delegate(FUNC(at_keyboard_controller_device::data_w), &(*m_keybc)), 0x000000ff); + spaceio.install_readwrite_handler(0x0064, 0x0067, read8_delegate(FUNC(at_keyboard_controller_device::status_r), &(*m_keybc)), write8_delegate(FUNC(at_keyboard_controller_device::command_w), &(*m_keybc)), 0xffffffff); + spaceio.install_readwrite_handler(0x0070, 0x007f, read8_delegate(FUNC(ds12885_device::read), &(*m_ds12885)), write8_delegate(FUNC(ds12885_device::write), &(*m_ds12885)), 0xffffffff); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void southbridge_extended_device::device_reset() +{ + southbridge_device::device_reset(); +} + +WRITE8_MEMBER( southbridge_extended_device::write_rtc ) { if (offset==0) { m_nmi_enabled = BIT(data,7); diff --git a/src/devices/bus/lpci/southbridge.h b/src/devices/bus/lpci/southbridge.h index 93d116c442b..011f43476ee 100644 --- a/src/devices/bus/lpci/southbridge.h +++ b/src/devices/bus/lpci/southbridge.h @@ -58,11 +58,8 @@ protected: required_device<am9517a_device> m_dma8237_1; required_device<am9517a_device> m_dma8237_2; required_device<pit8254_device> m_pit8254; - required_device<at_keyboard_controller_device> m_keybc; required_device<isa16_device> m_isabus; required_device<speaker_sound_device> m_speaker; - required_device<ds12885_device> m_ds12885; - required_device<pc_kbdc_device> m_pc_kbdc; required_device<bus_master_ide_controller_device> m_ide; required_device<bus_master_ide_controller_device> m_ide2; @@ -121,11 +118,36 @@ private: DECLARE_WRITE8_MEMBER(ide2_write_cs1_w); DECLARE_READ8_MEMBER(at_dma8237_2_r); DECLARE_WRITE8_MEMBER(at_dma8237_2_w); - DECLARE_WRITE8_MEMBER(write_rtc); DECLARE_READ8_MEMBER(pc_dma_read_byte); DECLARE_WRITE8_MEMBER(pc_dma_write_byte); DECLARE_READ8_MEMBER(pc_dma_read_word); DECLARE_WRITE8_MEMBER(pc_dma_write_word); }; +// ======================> southbridge_extended_device + +class southbridge_extended_device : + public southbridge_device +{ +public: + + +protected: + // construction/destruction + southbridge_extended_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + required_device<at_keyboard_controller_device> m_keybc; + required_device<ds12885_device> m_ds12885; + required_device<pc_kbdc_device> m_pc_kbdc; + +private: + DECLARE_WRITE8_MEMBER(write_rtc); +}; + #endif // MAME_BUS_LPCI_SOUTHBRIDGE_H diff --git a/src/devices/bus/msx_cart/msx_audio.cpp b/src/devices/bus/msx_cart/msx_audio.cpp index 75c0ccd7598..fba7b1efc2b 100644 --- a/src/devices/bus/msx_cart/msx_audio.cpp +++ b/src/devices/bus/msx_cart/msx_audio.cpp @@ -205,10 +205,8 @@ void msx_cart_msx_audio_nms1205_device::device_start() address_space &space = machine().device<cpu_device>("maincpu")->space(AS_IO); space.install_write_handler(0xc0, 0xc1, write8_delegate(FUNC(y8950_device::write), m_y8950.target())); space.install_read_handler(0xc0, 0xc1, read8_delegate(FUNC(y8950_device::read), m_y8950.target())); - space.install_write_handler(0x00, 0x00, write8_delegate(FUNC(acia6850_device::control_w), m_acia6850.target())); - space.install_write_handler(0x01, 0x01, write8_delegate(FUNC(acia6850_device::data_w), m_acia6850.target())); - space.install_read_handler(0x04,0x04, read8_delegate(FUNC(acia6850_device::status_r), m_acia6850.target())); - space.install_read_handler(0x05,0x05, read8_delegate(FUNC(acia6850_device::data_r), m_acia6850.target())); + space.install_write_handler(0x00, 0x01, write8_delegate(FUNC(acia6850_device::write), m_acia6850.target())); + space.install_read_handler(0x04, 0x05, read8_delegate(FUNC(acia6850_device::read), m_acia6850.target())); } diff --git a/src/devices/bus/nubus/nubus.cpp b/src/devices/bus/nubus/nubus.cpp index d94154244ae..9a3fbdca25e 100644 --- a/src/devices/bus/nubus/nubus.cpp +++ b/src/devices/bus/nubus/nubus.cpp @@ -125,7 +125,7 @@ void nubus_device::add_nubus_card(device_nubus_card_interface *card) void nubus_device::install_device(offs_t start, offs_t end, read8_delegate rhandler, write8_delegate whandler, uint32_t mask) { m_maincpu = machine().device<cpu_device>(m_cputag); - int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width; + int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_data_width; switch(buswidth) { case 32: @@ -142,7 +142,7 @@ void nubus_device::install_device(offs_t start, offs_t end, read8_delegate rhand void nubus_device::install_device(offs_t start, offs_t end, read16_delegate rhandler, write16_delegate whandler, uint32_t mask) { m_maincpu = machine().device<cpu_device>(m_cputag); - int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width; + int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_data_width; switch(buswidth) { case 32: @@ -159,7 +159,7 @@ void nubus_device::install_device(offs_t start, offs_t end, read16_delegate rhan void nubus_device::install_device(offs_t start, offs_t end, read32_delegate rhandler, write32_delegate whandler, uint32_t mask) { m_maincpu = machine().device<cpu_device>(m_cputag); - int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width; + int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_data_width; switch(buswidth) { case 32: @@ -176,7 +176,7 @@ void nubus_device::install_device(offs_t start, offs_t end, read32_delegate rhan void nubus_device::install_readonly_device(offs_t start, offs_t end, read32_delegate rhandler, uint32_t mask) { m_maincpu = machine().device<cpu_device>(m_cputag); - int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width; + int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_data_width; switch(buswidth) { case 32: @@ -193,7 +193,7 @@ void nubus_device::install_readonly_device(offs_t start, offs_t end, read32_dele void nubus_device::install_writeonly_device(offs_t start, offs_t end, write32_delegate whandler, uint32_t mask) { m_maincpu = machine().device<cpu_device>(m_cputag); - int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width; + int buswidth = m_maincpu->space_config(AS_PROGRAM)->m_data_width; switch(buswidth) { case 32: diff --git a/src/devices/bus/pc_kbd/pcat84.cpp b/src/devices/bus/pc_kbd/pcat84.cpp index d4d6c4e98de..8a079ad61a5 100644 --- a/src/devices/bus/pc_kbd/pcat84.cpp +++ b/src/devices/bus/pc_kbd/pcat84.cpp @@ -236,7 +236,7 @@ INPUT_PORTS_START( ibm_pc_at_84_keyboard ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) diff --git a/src/devices/bus/rs232/rs232.cpp b/src/devices/bus/rs232/rs232.cpp index ddac39b5764..544a0a9121c 100644 --- a/src/devices/bus/rs232/rs232.cpp +++ b/src/devices/bus/rs232/rs232.cpp @@ -1,5 +1,39 @@ // license:BSD-3-Clause // copyright-holders:smf +/*************************************************************************** + + Generic EIA RS-232/CCITT V.24 serial port emulation + +**************************************************************************** + + Source DB-25 DB-9 + 1 AA Protective Ground [Shield] + 7 5 AB Signal Ground [Common Return] + DTE → 2 3 BA Transmitted Data + ← DCE 3 2 BB Received Data + DTE → 4 7 CA Request to Send + ← DCE 5 8 CB Clear to Send + ← DCE 6 6 CC Data Set Ready [Data Mode] + DTE → 20 4 CD Data Terminal Ready + ← DCE 22 9 CE Ring Indicator + ← DCE 8 1 CF Received Line Signal Detector [Data Carrier Detect] + ← DCE 21 CG Signal Quality Detector + DTE → 23 CH Data Signal Rate Selector + ← DCE 23 CI Data Signal Rate Selector [Signaling Rate Indicator] + DTE → 24 DA Transmitter Signal Element Timing [External Tx Clock] + ← DCE 15 DB Transmitter Signal Element Timing + ← DCE 17 DD Receiver Signal Element Timing + DTE → 14 SBA Secondary Transmitted Data + ← DCE 16 SBB Secondary Received Data + DTE → 19 SCA Secondary Request to Send + ← DCE 13 SCB Secondary Clear to Send + ← DCE 12 SCF Secondary Received Line Signal Detector + DTE → 18 LL Local Loopback + DTE → 21 RL Remote Loopback + ← DCE 25 TM Test Mode + +***************************************************************************/ + #include "emu.h" #include "rs232.h" @@ -18,11 +52,15 @@ rs232_port_device::rs232_port_device(const machine_config &mconfig, device_type m_dsr(0), m_ri(0), m_cts(0), + m_dce_rxc(0), + m_dce_txc(0), m_rxd_handler(*this), m_dcd_handler(*this), m_dsr_handler(*this), m_ri_handler(*this), m_cts_handler(*this), + m_rxc_handler(*this), + m_txc_handler(*this), m_dev(nullptr) { } @@ -43,12 +81,16 @@ void rs232_port_device::device_start() m_dsr_handler.resolve_safe(); m_ri_handler.resolve_safe(); m_cts_handler.resolve_safe(); + m_rxc_handler.resolve_safe(); + m_txc_handler.resolve_safe(); save_item(NAME(m_rxd)); save_item(NAME(m_dcd)); save_item(NAME(m_dsr)); save_item(NAME(m_ri)); save_item(NAME(m_cts)); + save_item(NAME(m_dce_rxc)); + save_item(NAME(m_dce_txc)); m_rxd = 1; m_dcd = 1; diff --git a/src/devices/bus/rs232/rs232.h b/src/devices/bus/rs232/rs232.h index 5621609f76f..266bba34ca1 100644 --- a/src/devices/bus/rs232/rs232.h +++ b/src/devices/bus/rs232/rs232.h @@ -25,6 +25,12 @@ #define MCFG_RS232_CTS_HANDLER(_devcb) \ devcb = &rs232_port_device::set_cts_handler(*device, DEVCB_##_devcb); +#define MCFG_RS232_RXC_HANDLER(_devcb) \ + devcb = &rs232_port_device::set_rxc_handler(*device, DEVCB_##_devcb); + +#define MCFG_RS232_TXC_HANDLER(_devcb) \ + devcb = &rs232_port_device::set_txc_handler(*device, DEVCB_##_devcb); + #define RS232_BAUD_110 (0x00) #define RS232_BAUD_150 (0x01) #define RS232_BAUD_300 (0x02) @@ -40,10 +46,6 @@ #define RS232_BAUD_57600 (0x0c) #define RS232_BAUD_115200 (0x0d) -// Some systems may not include a dedicated XTAL capable of producing standard baud rates for the UART. -// These slightly deviant rates, which might lie within tolerance limits of actual hardware, have been found in use. -#define RS232_BAUD_9615 (0x0e) - #define MCFG_RS232_BAUD(_tag, _default_baud, _description, _class, _write_line) \ PORT_START(_tag) \ PORT_CONFNAME(0xff, _default_baud, _description) PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, _class, _write_line) \ @@ -55,7 +57,6 @@ PORT_CONFSETTING( RS232_BAUD_2400, "2400") \ PORT_CONFSETTING( RS232_BAUD_4800, "4800") \ PORT_CONFSETTING( RS232_BAUD_9600, "9600") \ - PORT_CONFSETTING( RS232_BAUD_9615, "9615") \ PORT_CONFSETTING( RS232_BAUD_14400, "14400") \ PORT_CONFSETTING( RS232_BAUD_19200, "19200") \ PORT_CONFSETTING( RS232_BAUD_28800, "28800") \ @@ -130,6 +131,8 @@ public: template <class Object> static devcb_base &set_dsr_handler(device_t &device, Object &&cb) { return downcast<rs232_port_device &>(device).m_dsr_handler.set_callback(std::forward<Object>(cb)); } template <class Object> static devcb_base &set_ri_handler(device_t &device, Object &&cb) { return downcast<rs232_port_device &>(device).m_ri_handler.set_callback(std::forward<Object>(cb)); } template <class Object> static devcb_base &set_cts_handler(device_t &device, Object &&cb) { return downcast<rs232_port_device &>(device).m_cts_handler.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_rxc_handler(device_t &device, Object &&cb) { return downcast<rs232_port_device &>(device).m_rxc_handler.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_txc_handler(device_t &device, Object &&cb) { return downcast<rs232_port_device &>(device).m_txc_handler.set_callback(std::forward<Object>(cb)); } DECLARE_WRITE_LINE_MEMBER( write_txd ); DECLARE_WRITE_LINE_MEMBER( write_dtr ); @@ -141,6 +144,8 @@ public: DECLARE_READ_LINE_MEMBER( dsr_r ) { return m_dsr; } DECLARE_READ_LINE_MEMBER( ri_r ) { return m_ri; } DECLARE_READ_LINE_MEMBER( cts_r ) { return m_cts; } + DECLARE_READ_LINE_MEMBER( rxc_r ) { return m_dce_rxc; } + DECLARE_READ_LINE_MEMBER( txc_r ) { return m_dce_txc; } protected: rs232_port_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -153,12 +158,16 @@ protected: int m_dsr; int m_ri; int m_cts; + int m_dce_rxc; + int m_dce_txc; devcb_write_line m_rxd_handler; devcb_write_line m_dcd_handler; devcb_write_line m_dsr_handler; devcb_write_line m_ri_handler; devcb_write_line m_cts_handler; + devcb_write_line m_rxc_handler; + devcb_write_line m_txc_handler; private: device_rs232_port_interface *m_dev; @@ -181,6 +190,8 @@ public: DECLARE_WRITE_LINE_MEMBER( output_dsr ) { m_port->m_dsr = state; m_port->m_dsr_handler(state); } DECLARE_WRITE_LINE_MEMBER( output_ri ) { m_port->m_ri = state; m_port->m_ri_handler(state); } DECLARE_WRITE_LINE_MEMBER( output_cts ) { m_port->m_cts = state; m_port->m_cts_handler(state); } + DECLARE_WRITE_LINE_MEMBER( output_rxc ) { m_port->m_dce_rxc = state; m_port->m_rxc_handler(state); } + DECLARE_WRITE_LINE_MEMBER( output_txc ) { m_port->m_dce_txc = state; m_port->m_txc_handler(state); } protected: device_rs232_port_interface(const machine_config &mconfig, device_t &device); @@ -204,8 +215,7 @@ protected: 28800, 38400, 57600, - 115200, - 9615 + 115200 }; return values[baud]; diff --git a/src/devices/bus/ss50/interface.cpp b/src/devices/bus/ss50/interface.cpp new file mode 100644 index 00000000000..3d51f76ba53 --- /dev/null +++ b/src/devices/bus/ss50/interface.cpp @@ -0,0 +1,222 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + SWTPC SS-50 I/O port interface + + The SS-50 bus is actually two buses in one: a 50-pin master bus + used by RAM boards and such, and a 30-pin I/O bus derived from it + either on the motherboard or a dedicated interface board, which + provides each of eight "interface" cards with its specific chip + select line and only a few address lines for register selection. + This 30-pin bus is what is emulated here. + + As originally introduced in the 6800 Computer System, the + interface bus only included two register select lines, just enough + to drive one MC6820 PIA. No defined signals were placed on the + first two lines, which cards were permitted to use for any + purpose. The original MP-B motherboard also quite wastefully + reserved 8K (technically 4K) of address space to map a maximum of + 32 read/write registers. The later MC6809-oriented systems not + only reduced the I/O segment to a selectable 1K, but appropriated + the two formerly undefined lines for two additional register + select lines, making it possible to use more complex interface + cards but breaking compatibility with some earlier ones. + + An unusual feature of the SS-50 bus is the presence of five baud + rate frequencies, selected from among the (inverted) outputs of + a MC14411 Bit Rate Generator. The 6800 Computer System provided + only rates between 110 and 1200 (multiplied by 16), and also used + the MC14411's master frequency to generate the CPU clocks. The + MP-09 CPU board retained the MC14411 at first, but provided an + independent XTAL for the MC6809 and jumpers to select higher + baud rates. Later the MC14411 was removed from the CPU board so + the five baud rate lines on the 50-pin bus could be reused to + provide 20-bit addressing and DMA. This was accomplished by + adding a separate MP-ID Interface Driver Board to decode I/O + accesses (and optionally slow them down to allow old 1 MHz + peripherals to be used with a faster CPU), generate the baud + rates (whose selection was changed yet again) from a dedicated + MC14411, and provide a few I/O functions of its own. + +*********************************************************************** + + +-+ + |o| RS2 (originally UD3) + |o| RS3 (originally UD4) + |o| -16V (originally -12V) + |o| +16V (originally +12V) + |o| GND + |o| GND + |o| INDEX + |o| /FIRQ (6800: /NMI) + |o| /IRQ + |o| RS0 + |o| RS1 + |o| D0 + |o| D1 + |o| D2 + |o| D3 + |o| D4 + |o| D5 + |o| D6 + |o| D7 + |o| E (6800: ϕ2) + |o| R/W + |o| +8V (unregulated) + |o| +8V (unregulated) + |o| 600b/1200b (originally 1200b) + |o| 4800b (originally 600b) + |o| 300b + |o| 150b/9600b (originally 150b) + |o| 110b + |o| /RESET + |o| I/O # + +-+ + +**********************************************************************/ + +#include "emu.h" +#include "bus/ss50/interface.h" + +#include "bus/ss50/mpc.h" +//#include "bus/ss50/mpl.h" +//#include "bus/ss50/mpr.h" +#include "bus/ss50/mps.h" +//#include "bus/ss50/mpt.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(SS50_INTERFACE, ss50_interface_port_device, "ss50_interface", "SS-50 Interface Port") + +//************************************************************************** +// SS-50 INTERFACE PORT DEVICE +//************************************************************************** + +//------------------------------------------------- +// ss50_interface_port_device - construction +//------------------------------------------------- + +ss50_interface_port_device::ss50_interface_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SS50_INTERFACE, tag, owner, clock), + device_slot_interface(mconfig, *this), + m_irq_cb(*this), + m_firq_cb(*this), + m_card(nullptr) +{ +} + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void ss50_interface_port_device::device_resolve_objects() +{ + logerror("Resolving objects...\n"); + + m_irq_cb.resolve_safe(); + m_firq_cb.resolve_safe(); + + m_card = dynamic_cast<ss50_card_interface *>(get_card_device()); + if (m_card != nullptr) + m_card->m_slot = this; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ss50_interface_port_device::device_start() +{ +} + +//------------------------------------------------- +// read - interface read access (pre-decoded) +//------------------------------------------------- + +READ8_MEMBER(ss50_interface_port_device::read) +{ + if (m_card == nullptr) + { + logerror("%s: Read from unspecified interface (RS = %X)\n", machine().describe_context(), offset); + return space.unmap(); + } + + return m_card->register_read(space, offset); +} + +//------------------------------------------------- +// write - interface write access (pre-decoded) +//------------------------------------------------- + +WRITE8_MEMBER(ss50_interface_port_device::write) +{ + if (m_card == nullptr) + { + logerror("%s: Write to unspecified interface (RS = %X, D = %02X)\n", machine().describe_context(), offset, data); + return; + } + + m_card->register_write(space, offset, data); +} + +//------------------------------------------------- +// fN_w - baud rate clocks for serial interfaces +//------------------------------------------------- + +WRITE_LINE_MEMBER(ss50_interface_port_device::f110_w) +{ + if (m_card != nullptr) + m_card->f110_w(state); +} + +WRITE_LINE_MEMBER(ss50_interface_port_device::f150_9600_w) +{ + if (m_card != nullptr) + m_card->f150_9600_w(state); +} + +WRITE_LINE_MEMBER(ss50_interface_port_device::f300_w) +{ + if (m_card != nullptr) + m_card->f300_w(state); +} + +WRITE_LINE_MEMBER(ss50_interface_port_device::f600_4800_w) +{ + if (m_card != nullptr) + m_card->f600_4800_w(state); +} + +WRITE_LINE_MEMBER(ss50_interface_port_device::f600_1200_w) +{ + if (m_card != nullptr) + m_card->f600_1200_w(state); +} + +//************************************************************************** +// SS-50 CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// ss50_card_interface - construction +//------------------------------------------------- + +ss50_card_interface::ss50_card_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device), + m_slot(nullptr) +{ +} + +SLOT_INTERFACE_START(ss50_default_2rs_devices) + SLOT_INTERFACE("mpc", SS50_MPC) + //SLOT_INTERFACE("mpl", SS50_MPL) + //SLOT_INTERFACE("mpn", SS50_MPN) + SLOT_INTERFACE("mps", SS50_MPS) + //SLOT_INTERFACE("mpt", SS50_MPT) +SLOT_INTERFACE_END diff --git a/src/devices/bus/ss50/interface.h b/src/devices/bus/ss50/interface.h new file mode 100644 index 00000000000..2e35b0abf2f --- /dev/null +++ b/src/devices/bus/ss50/interface.h @@ -0,0 +1,110 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + SWTPC SS-50 I/O port interface + +**********************************************************************/ + +#pragma once + +#ifndef MAME_DEVICES_BUS_SS50_INTERFACE_H +#define MAME_DEVICES_BUS_SS50_INTERFACE_H + +//************************************************************************** +// CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_SS50_INTERFACE_PORT_ADD(_tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, SS50_INTERFACE, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(ss50_##_slot_intf, _def_slot, false) + +#define MCFG_SS50_INTERFACE_IRQ_CALLBACK(_devcb) \ + devcb = &ss50_interface_port_device::set_irq_cb(*device, DEVCB_##_devcb); + +#define MCFG_SS50_INTERFACE_FIRQ_CALLBACK(_devcb) \ + devcb = &ss50_interface_port_device::set_firq_cb(*device, DEVCB_##_devcb); + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// forward declarations +class ss50_card_interface; + +// ======================> ss50_interface_port_device + +class ss50_interface_port_device : public device_t, public device_slot_interface +{ + friend class ss50_card_interface; + +public: + // construction/destruction + ss50_interface_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // static configuration + template<class Object> static devcb_base &set_irq_cb(device_t &device, Object &&object) { return downcast<ss50_interface_port_device &>(device).m_irq_cb.set_callback(std::forward<Object>(object)); } + template<class Object> static devcb_base &set_firq_cb(device_t &device, Object &&object) { return downcast<ss50_interface_port_device &>(device).m_firq_cb.set_callback(std::forward<Object>(object)); } + + // memory accesses + DECLARE_READ8_MEMBER(read); + DECLARE_WRITE8_MEMBER(write); + + // baud rates + DECLARE_WRITE_LINE_MEMBER(f110_w); + DECLARE_WRITE_LINE_MEMBER(f150_9600_w); + DECLARE_WRITE_LINE_MEMBER(f300_w); + DECLARE_WRITE_LINE_MEMBER(f600_4800_w); + DECLARE_WRITE_LINE_MEMBER(f600_1200_w); + +protected: + // device-specific overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + +private: + // output callbacks + devcb_write_line m_irq_cb; + devcb_write_line m_firq_cb; + + ss50_card_interface *m_card; +}; + + +// ======================> ss50_card_interface + +class ss50_card_interface : public device_slot_card_interface +{ + friend class ss50_interface_port_device; + +protected: + // construction/destruction + ss50_card_interface(const machine_config &mconfig, device_t &device); + + // required overrides + virtual DECLARE_READ8_MEMBER(register_read) = 0; + virtual DECLARE_WRITE8_MEMBER(register_write) = 0; + + // optional overrides + virtual DECLARE_WRITE_LINE_MEMBER(f110_w) { } + virtual DECLARE_WRITE_LINE_MEMBER(f150_9600_w) { } + virtual DECLARE_WRITE_LINE_MEMBER(f300_w) { } + virtual DECLARE_WRITE_LINE_MEMBER(f600_4800_w) { } + virtual DECLARE_WRITE_LINE_MEMBER(f600_1200_w) { } + + // IRQ/FIRQ/NMI outputs + DECLARE_WRITE_LINE_MEMBER(write_irq) { m_slot->m_irq_cb(state); } + DECLARE_WRITE_LINE_MEMBER(write_firq) { m_slot->m_firq_cb(state); } + +private: + ss50_interface_port_device *m_slot; +}; + + +// device type definition +extern const device_type SS50_INTERFACE; + +SLOT_INTERFACE_EXTERN(ss50_default_2rs_devices); +//SLOT_INTERFACE_EXTERN(ss50_default_4rs_devices); + +#endif diff --git a/src/devices/bus/ss50/mpc.cpp b/src/devices/bus/ss50/mpc.cpp new file mode 100644 index 00000000000..7f587d6bb62 --- /dev/null +++ b/src/devices/bus/ss50/mpc.cpp @@ -0,0 +1,216 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + SWTPC MP-C Serial Control Interface + +**********************************************************************/ + +#include "emu.h" +#include "bus/ss50/mpc.h" +#include "bus/ss50/interface.h" + +#include "bus/rs232/rs232.h" +#include "machine/6821pia.h" +#include "machine/input_merger.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> ss50_mpc_device + +class ss50_mpc_device : public device_t, public ss50_card_interface +{ +public: + // construction/destruction + ss50_mpc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SS50_MPC, tag, owner, clock), + ss50_card_interface(mconfig, *this), + m_pia(*this, "pia"), + m_loopback(*this, "loopback"), + m_baud_jumper(*this, "BAUD"), + m_cd4024ae_count(0), + m_cd4024ae_clock(false), + m_cd4024ae_reset(true), + m_count_select(false) + { + } + +protected: + // device-specific overrides + virtual ioport_constructor device_input_ports() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + + // interface-specific overrides + virtual DECLARE_READ8_MEMBER(register_read) override; + virtual DECLARE_WRITE8_MEMBER(register_write) override; + virtual DECLARE_WRITE_LINE_MEMBER(f110_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(f300_w) override; + +private: + DECLARE_WRITE_LINE_MEMBER(serial_input_w); + DECLARE_WRITE_LINE_MEMBER(reader_control_w); + DECLARE_READ_LINE_MEMBER(count_r); + DECLARE_WRITE_LINE_MEMBER(count_reset_w); + DECLARE_WRITE_LINE_MEMBER(count_select_w); + DECLARE_WRITE_LINE_MEMBER(clock_input_w); + + required_device<pia6821_device> m_pia; + required_device<input_merger_device> m_loopback; + required_ioport m_baud_jumper; + + u8 m_cd4024ae_count; + bool m_cd4024ae_clock; + bool m_cd4024ae_reset; + bool m_count_select; +}; + + +static INPUT_PORTS_START( mpc ) + PORT_START("BAUD") + PORT_DIPNAME(1, 0, "Baud Rate") + PORT_DIPSETTING(1, "110") + PORT_DIPSETTING(0, "300") + + PORT_START("STOP") + PORT_DIPNAME(1, 0, "Stop Bits") + PORT_DIPSETTING(0, "1") + PORT_DIPSETTING(1, "2") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor ss50_mpc_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(mpc); +} + + +static DEVICE_INPUT_DEFAULTS_START( terminal ) + DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0xff, RS232_BAUD_300) + DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0xff, RS232_BAUD_300) + DEVICE_INPUT_DEFAULTS("RS232_STARTBITS", 0xff, RS232_STARTBITS_1) + DEVICE_INPUT_DEFAULTS("RS232_DATABITS", 0xff, RS232_DATABITS_8) + DEVICE_INPUT_DEFAULTS("RS232_PARITY", 0xff, RS232_PARITY_NONE) + DEVICE_INPUT_DEFAULTS("RS232_STOPBITS", 0xff, RS232_STOPBITS_1) +DEVICE_INPUT_DEFAULTS_END + + +//------------------------------------------------- +// device_add_mconfig - add device-specific +// machine configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER(ss50_mpc_device::device_add_mconfig) + MCFG_DEVICE_ADD("pia", PIA6821, 0) // actually MC6820 + MCFG_PIA_WRITEPA_HANDLER(DEVWRITELINE("outgate", input_merger_device, in_w<0>)) MCFG_DEVCB_BIT(0) + MCFG_PIA_CB2_HANDLER(WRITELINE(ss50_mpc_device, reader_control_w)) + MCFG_PIA_READPB_HANDLER(IOPORT("STOP")) MCFG_DEVCB_BIT(6) + MCFG_DEVCB_CHAIN_INPUT(READLINE(ss50_mpc_device, count_r)) MCFG_DEVCB_BIT(7) + MCFG_PIA_WRITEPB_HANDLER(WRITELINE(ss50_mpc_device, count_select_w)) MCFG_DEVCB_BIT(2) + MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE(ss50_mpc_device, count_reset_w)) MCFG_DEVCB_BIT(0) + //MCFG_PIA_IRQA_HANDLER(WRITELINE(ss50_mpc_device, pia_irq_w)) + //MCFG_PIA_IRQB_HANDLER(WRITELINE(ss50_mpc_device, pia_irq_w)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(WRITELINE(ss50_mpc_device, serial_input_w)) + MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) + + MCFG_INPUT_MERGER_ALL_HIGH("outgate") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + + MCFG_INPUT_MERGER_ANY_HIGH("loopback") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(DEVWRITELINE("outgate", input_merger_device, in_w<1>)) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void ss50_mpc_device::device_start() +{ + save_item(NAME(m_cd4024ae_count)); + save_item(NAME(m_cd4024ae_clock)); + save_item(NAME(m_cd4024ae_reset)); + save_item(NAME(m_count_select)); +} + +WRITE_LINE_MEMBER(ss50_mpc_device::serial_input_w) +{ + m_pia->set_a_input(state << 7, 0x7f); + m_loopback->in_w<0>(state); +} + + +WRITE_LINE_MEMBER(ss50_mpc_device::reader_control_w) +{ + m_loopback->in_w<1>(state); +} + +READ_LINE_MEMBER(ss50_mpc_device::count_r) +{ + return BIT(m_cd4024ae_count, m_count_select ? 4 : 3); +} + +WRITE_LINE_MEMBER(ss50_mpc_device::count_reset_w) +{ + m_cd4024ae_reset = bool(state); + if (state) + m_cd4024ae_count = 0; +} + +WRITE_LINE_MEMBER(ss50_mpc_device::count_select_w) +{ + m_count_select = bool(state); +} + +WRITE_LINE_MEMBER(ss50_mpc_device::clock_input_w) +{ + if (m_cd4024ae_clock != bool(state)) + { + m_cd4024ae_clock = bool(state); + if (!state && !m_cd4024ae_reset) + m_cd4024ae_count++; + } +} + + +//------------------------------------------------- +// register_read - read from a port register +//------------------------------------------------- + +READ8_MEMBER(ss50_mpc_device::register_read) +{ + return m_pia->read(space, offset & 3, 0); +} + +//------------------------------------------------- +// register_write - write to a port register +//------------------------------------------------- + +WRITE8_MEMBER(ss50_mpc_device::register_write) +{ + m_pia->write(space, offset & 3, data); +} + +WRITE_LINE_MEMBER(ss50_mpc_device::f110_w) +{ + if (m_baud_jumper->read()) + clock_input_w(state); +} + +WRITE_LINE_MEMBER(ss50_mpc_device::f300_w) +{ + if (!m_baud_jumper->read()) + clock_input_w(state); +} + + +// device type definition +DEFINE_DEVICE_TYPE(SS50_MPC, ss50_mpc_device, "ss50_mpc", "MP-C Serial Control Interface") diff --git a/src/devices/bus/ss50/mpc.h b/src/devices/bus/ss50/mpc.h new file mode 100644 index 00000000000..2e769932b0c --- /dev/null +++ b/src/devices/bus/ss50/mpc.h @@ -0,0 +1,14 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + SWTPC MP-C Serial Control Interface + +**********************************************************************/ + +#ifndef MAME_DEVICE_BUS_SS50_MPC_H +#define MAME_DEVICE_BUS_SS50_MPC_H + +extern const device_type SS50_MPC; + +#endif // MAME_DEVICE_BUS_SS50_MPC_H diff --git a/src/devices/bus/ss50/mps.cpp b/src/devices/bus/ss50/mps.cpp new file mode 100644 index 00000000000..11b9051063d --- /dev/null +++ b/src/devices/bus/ss50/mps.cpp @@ -0,0 +1,183 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + SWTPC MP-S Serial Interface + +**********************************************************************/ + +#include "emu.h" +#include "bus/ss50/mps.h" +#include "bus/ss50/interface.h" + +#include "bus/rs232/rs232.h" +#include "machine/6850acia.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> ss50_mps_device + +class ss50_mps_device : public device_t, public ss50_card_interface +{ +public: + // construction/destruction + ss50_mps_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, SS50_MPS, tag, owner, clock), + ss50_card_interface(mconfig, *this), + m_acia(*this, "acia"), + m_irq_jumper(*this, "IRQ"), + m_rate_jumper(*this, "BAUD") + { + } + +protected: + // device-specific overrides + virtual ioport_constructor device_input_ports() const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override { } + + // interface-specific overrides + virtual DECLARE_READ8_MEMBER(register_read) override; + virtual DECLARE_WRITE8_MEMBER(register_write) override; + virtual DECLARE_WRITE_LINE_MEMBER(f110_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(f150_9600_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(f300_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(f600_4800_w) override; + virtual DECLARE_WRITE_LINE_MEMBER(f600_1200_w) override; + +private: + DECLARE_WRITE_LINE_MEMBER(acia_irq_w); + + required_device<acia6850_device> m_acia; + required_ioport m_irq_jumper; + required_ioport m_rate_jumper; +}; + + +static INPUT_PORTS_START( mps ) + PORT_START("IRQ") + PORT_DIPNAME(1, 0, "IRQ") + PORT_DIPSETTING(1, DEF_STR(Off)) + PORT_DIPSETTING(0, DEF_STR(On)) + + PORT_START("BAUD") + PORT_DIPNAME(0x1f, 0x0f, "Baud Rate") + PORT_DIPSETTING(0x1e, "110") + PORT_DIPSETTING(0x1d, "150") + PORT_DIPSETTING(0x1b, "300") + PORT_DIPSETTING(0x17, "600") + PORT_DIPSETTING(0x0f, "1200") +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor ss50_mps_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(mps); +} + + +static DEVICE_INPUT_DEFAULTS_START( terminal ) + DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0xff, RS232_BAUD_1200) + DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0xff, RS232_BAUD_1200) + DEVICE_INPUT_DEFAULTS("RS232_STARTBITS", 0xff, RS232_STARTBITS_1) + DEVICE_INPUT_DEFAULTS("RS232_DATABITS", 0xff, RS232_DATABITS_8) + DEVICE_INPUT_DEFAULTS("RS232_PARITY", 0xff, RS232_PARITY_NONE) + DEVICE_INPUT_DEFAULTS("RS232_STOPBITS", 0xff, RS232_STOPBITS_1) +DEVICE_INPUT_DEFAULTS_END + + +//------------------------------------------------- +// device_add_mconfig - add device-specific +// machine configuration +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER(ss50_mps_device::device_add_mconfig) + MCFG_DEVICE_ADD("acia", ACIA6850, 0) + MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + //MCFG_ACIA6850_RTS_HANDLER(WRITELINE(ss50_mps_device, reader_control_w)) + MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(ss50_mps_device, acia_irq_w)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) + MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// register_read - read from a port register +//------------------------------------------------- + +READ8_MEMBER(ss50_mps_device::register_read) +{ + return m_acia->read(space, offset & 1, 0); +} + +//------------------------------------------------- +// register_write - write to a port register +//------------------------------------------------- + +WRITE8_MEMBER(ss50_mps_device::register_write) +{ + m_acia->write(space, offset & 1, data); +} + +WRITE_LINE_MEMBER(ss50_mps_device::f110_w) +{ + if (!BIT(m_rate_jumper->read(), 0)) + { + m_acia->write_txc(state); + m_acia->write_rxc(state); + } +} + +WRITE_LINE_MEMBER(ss50_mps_device::f150_9600_w) +{ + if (!BIT(m_rate_jumper->read(), 1)) + { + m_acia->write_txc(state); + m_acia->write_rxc(state); + } +} + +WRITE_LINE_MEMBER(ss50_mps_device::f300_w) +{ + if (!BIT(m_rate_jumper->read(), 2)) + { + m_acia->write_txc(state); + m_acia->write_rxc(state); + } +} + +WRITE_LINE_MEMBER(ss50_mps_device::f600_4800_w) +{ + if (!BIT(m_rate_jumper->read(), 3)) + { + m_acia->write_txc(state); + m_acia->write_rxc(state); + } +} + +WRITE_LINE_MEMBER(ss50_mps_device::f600_1200_w) +{ + if (!BIT(m_rate_jumper->read(), 4)) + { + m_acia->write_txc(state); + m_acia->write_rxc(state); + } +} + +WRITE_LINE_MEMBER(ss50_mps_device::acia_irq_w) +{ + if (!m_irq_jumper->read()) + write_irq(state); +} + + +// device type definition +DEFINE_DEVICE_TYPE(SS50_MPS, ss50_mps_device, "ss50_mps", "MP-S Serial Interface") diff --git a/src/devices/bus/ss50/mps.h b/src/devices/bus/ss50/mps.h new file mode 100644 index 00000000000..29733f7eeda --- /dev/null +++ b/src/devices/bus/ss50/mps.h @@ -0,0 +1,14 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + SWTPC MP-S Serial Interface + +**********************************************************************/ + +#ifndef MAME_DEVICE_BUS_SS50_MPS_H +#define MAME_DEVICE_BUS_SS50_MPS_H + +extern const device_type SS50_MPS; + +#endif // MAME_DEVICE_BUS_SS50_MPS_H diff --git a/src/devices/bus/ti99/internal/998board.cpp b/src/devices/bus/ti99/internal/998board.cpp index f6eaf940e4d..0e3d7663684 100644 --- a/src/devices/bus/ti99/internal/998board.cpp +++ b/src/devices/bus/ti99/internal/998board.cpp @@ -2243,15 +2243,34 @@ enum CR7 = 0x01 }; +/* Line */ +enum +{ + LINE_HSK = 0x10, + LINE_BAV = 0x04, + LINE_BIT32 = 0xc0, + LINE_BIT10 = 0x03 +}; + oso_device::oso_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : bus::hexbus::hexbus_chained_device(mconfig, TI99_OSO, tag, owner, clock), + m_int(*this), m_data(0), m_status(0xff), m_control(0), - m_xmit(0), - m_clkcount(0), - m_xmit_send(0) -{ + m_xmit(0), m_lasthxvalue(0x01), + m_bav(false), m_sbav(false), m_sbavold(false), m_bavhold(false), + m_hsk(false), m_shsk(false), m_shskold(false), m_hskhold(false), + m_wq1(false), m_wq1old(false), m_wq2(false), m_wq2old(false), + m_wnp(false), m_wbusyold(false), m_sendbyte(false), + m_wrset(false), m_counting(false), m_clkcount(0), + m_rq1(false), m_rq2(false), m_rq2old(false), + m_rnib(false), m_rnibcold(false), + m_rdset(false), m_rdsetold(false), + m_msns(false), m_lsns(false), + m_rhsus(false) +{ + (void)m_shskold; m_hexbus_inbound = nullptr; m_hexbus_outbound = nullptr; } @@ -2266,11 +2285,17 @@ READ8_MEMBER( oso_device::read ) // read 5FF8: read data register if (TRACE_OSO) logerror("Read data register = %02x\n", value); value = m_data; + // Release the handshake + m_rhsus = false; break; case 1: // read 5FFA: read status register value = m_status; - if (TRACE_OSO) logerror("Read status %02x\n", value); + clear_int_status(); + if (TRACE_OSO) logerror("Read status %02x (HSKWT=%d,HSKRD=%d,BAVIAS=%d,BAVAIS=%d,SBAV=%d,WBUSY=%d,RBUSY=%d,SHSK=%d)\n", value, + (value&HSKWT)? 1:0, (value&HSKRD)? 1:0, (value&BAVIAS)? 1:0, + (value&BAVAIS)? 1:0, (value&SBAV)? 1:0, (value&WBUSY)? 1:0, + (value&RBUSY)? 1:0,(value&SHSK)? 1:0); break; case 2: // read 5FFC: read control register @@ -2294,14 +2319,33 @@ WRITE8_MEMBER( oso_device::write ) case 0: // write 5FF8: write transmit register if (TRACE_OSO) logerror("Write transmit register %02x\n", data); + + // trigger some actions in the write subsystem + m_sendbyte = true; + if (!m_wq1) + { + m_wbusyold = true; + set_status(WBUSY, true); + } + m_xmit = data; - m_xmit_send = 2; - m_status |= HSKWT; break; case 1: // write 5FFA: write control register - if (TRACE_OSO) logerror("Write control register %02x\n", data); + if (TRACE_OSO) logerror("Write control register %02x (WIEN=%d, RIEN=%d, BAVIAEN=%d, BAVAIEN=%d, BAVC=%d, WEN=%d, REN=%d)\n", + data, (data & WIEN)? 1:0, (data & RIEN)? 1:0, (data&BAVIAEN)? 1:0, (data&BAVAIEN)? 1:0, + (data & BAVC)? 1:0, (data & WEN)? 1:0, (data & REN)? 1:0); m_control = data; + + // Reset some flipflops in the write/read timing section + if (!control_bit(WEN)) + { + m_wq1 = m_wq2 = m_wrset = false; + } + if (!control_bit(REN)) + { + m_rq1 = m_rq2 = m_rdset = false; + } break; default: // write 5FFC, 5FFE: undefined @@ -2310,9 +2354,24 @@ WRITE8_MEMBER( oso_device::write ) } } +void oso_device::clear_int_status() +{ + m_status &= ~(HSKWT | HSKRD | BAVIAS | BAVAIS); + m_int(CLEAR_LINE); +} + void oso_device::hexbus_value_changed(uint8_t data) { if (TRACE_OSO) logerror("Hexbus value changed to %02x\n", data); + + m_bav = ((data & LINE_BAV)==0) | control_bit(BAVC); + + m_hsk = (data & LINE_HSK)==0; + int nibble = ((data & LINE_BIT32)>>4) | (data & LINE_BIT10); + if (m_msns) + m_data = (m_data & 0x0f) | (nibble<<4); + if (m_lsns) + m_data = (m_data & 0xf0) | nibble; } /* @@ -2320,28 +2379,229 @@ void oso_device::hexbus_value_changed(uint8_t data) */ WRITE_LINE_MEMBER( oso_device::clock_in ) { - if (state==ASSERT_LINE) m_clkcount++; - if (m_clkcount > 30 && ((m_control & WEN)!=0) && (m_xmit_send > 0)) + if (state==ASSERT_LINE) + { + // Control lines SHSK, SBAV + // When BAV/HSK is 0/1 for two rising edges of Phi3*, SBAV/SHSK goes to + // 0/1 at the following falling edge of Phi3*. + // Page 5 + m_sbav = m_bavhold && m_bav; // could mean "stable BAV" + m_bavhold = m_bav; + m_shsk = m_hskhold && m_hsk; + m_hskhold = m_hsk; + set_status(SHSK, m_shsk); + set_status(SBAV, m_sbav); + + // Raising edge of SBAV* + if (m_sbav == true && m_sbavold == false) + set_status(BAVIAS, true); + // Falling edge of SBAV* + if (m_sbav == false && m_sbavold == true) + set_status(BAVAIS, true); + m_sbavold = m_sbav; + + // Implement the write timing logic + // This subcircuit in the OSO chip autonomously runs the Hexbus + // protocol. After loading a byte into the transmit register, it sends + // both nibbles (little-endian) one after another over the Hexbus, + // pausing for 30 cycles, and checking the HSK line. + + // The schematics show some fascinating signal line spaghetti with + // embedded JK* flipflops which may give you some major headaches. + // Compared to that, the lines below are a true relief. + + if (control_bit(WEN)) // Nothing happens without WEN + { + if (TRACE_OSO) if (!m_wrset && m_sendbyte) logerror("Starting write process\n"); + // Page 3: Write timing + // Note: First pass counts to 30, second to 31 + bool cnt30 = ((m_clkcount & 0x1e) == 30); + bool cont = (m_wrset && !m_wq2 && !m_wq1) || (cnt30 && m_wq2 && !m_wq1) + || (cnt30 && !m_wq2 && m_wq1) || (m_shsk && m_wq2 && m_wq1); + + bool jwq1 = cont && m_wq2; + bool kwq1 = !((cont && !m_wq2) || (!cont && m_wq2 && m_wnp)); + + bool jwq2 = cont; + bool kwq2 = !(m_wq1 && !cont); + + if (m_wq1 == m_wq2) m_clkcount = 0; + + // Reset "byte loaded" flipflop during the second phase + if (m_wq1 == true) + m_sendbyte = false; + + // logerror("sendbyte=%d, wq1=%d, wq2=%d, jwq1=%d, kwq1=%d, jwq2=%d, kwq2=%d, shsk=%d\n", m_sendbyte, m_wq1, m_wq2, jwq1, kwq1, jwq2, kwq2, m_shsk); + // WBUSY is asserted on byte load, during phase 1, and phase 2. + bool wbusy = m_sendbyte || m_wq1 || m_wq2; + + // Set status bits and raise interrupt (p. 4) + set_status(WBUSY, wbusy); + + // Raising edge of wbusy* + if (m_wbusyold == true && wbusy == false) + set_status(HSKWT, true); + m_wbusyold = wbusy; + + // Operate flipflops + // Write phases + // 74LS109: J-K* flipflop (inverted K) + if (jwq1) + { + if (!kwq1) m_wq1 = !m_wq1; + else m_wq1 = true; + } + else + if (!kwq1) m_wq1 = false; + + if (jwq2) + { + if (!kwq2) m_wq2 = !m_wq2; + else m_wq2 = true; + } + else + if (!kwq2) m_wq2 = false; + + // Set WNP on rising edge of WQ2* + if (m_wq2 != m_wq2old) + { + if (!m_wq2) + m_wnp = true; + + m_wq2old = m_wq2; + } + m_wq1old = m_wq1; + + // Reset WNP if phases are done + if (!m_wq2 && !m_wq1) + { + m_wnp = false; + } + } + + // This is the reading behavior. In this case, the master (this + // component) pulls down BAV*, then the slave sets the data lines + // with the back nibble, pulls down HSK*, then releases HSK*, + // puts the front nibble on the data lines, pulls down HSK* again, + // releases it, and this continues until the master releases BAV* + + if (control_bit(REN)) + { + bool rbusy = m_rq1 || m_rq2; + set_status(RBUSY, rbusy); + + // Flipflop resets + if (!rbusy) m_rnib = false; + if (m_rq2) m_rdset = false; + + bool rdsetin = !control_bit(WBUSY) && m_sbav && m_shsk; + bool next = (m_rdset && !m_rq2) || (m_shsk && m_rq2); + bool drq1 = (next && m_rq2) || (m_rq2 && m_rq1 && !m_rnib); + bool jrq2 = next && !m_rq1; + bool krq2 = m_rq1 && !m_rnib; + m_msns = m_rnib && !m_rq1 && m_rq2; + m_lsns = !m_rnib && !m_rq1 && m_rq2; + bool rnibc = m_rq1; + + // Next state + if (!m_rdsetold && rdsetin) m_rdset = true; // raising edge + m_rdsetold = rdsetin; + m_rq1 = drq1; + + if (jrq2) + { + if (!krq2) m_rq2 = !m_rq2; + else m_rq2 = true; + } + else + if (!krq2) m_rq2 = false; + + if (m_rnibcold == false && rnibc == true) m_rnib = !m_rnib; // raising edge + m_rnibcold = rnibc; + + // Raising edge of RQ2* + if (m_rq2old == true && m_rq2 == false) + { + set_status(HSKRD, true); + m_rhsus = true; // byte is available for reading + } + m_rq2old = m_rq2; + } + else + { + m_rhsus = false; + } + + // Handshake control + // Set HSK (Page 6, RHSUS*) + bool hskwrite = !m_wq1 && m_wq2; + + // We can simplify this to a single flag because the CPU read operation + // is atomic here (starts and immediately terminates) + m_hsk = hskwrite || m_rhsus; + update_hexbus(); + } + // Actions that occur for Phi3=0 + else + { + m_wrset = m_sendbyte; + // Only count when one phase is active + m_counting = !(m_wq1==m_wq2); + + if (m_counting) + m_clkcount++; + else + m_clkcount = 0; // Reset when not counting + } + + // Flipflop resets (not related to clock) + if (!control_bit(WEN)) { - if (TRACE_OSO) logerror("Write nibble %d\n", 3-m_xmit_send); - hexbus_write(((m_xmit & 0x0c)<<4) | (m_xmit & 0x03)); - m_xmit >>= 4; + m_wq1 = m_wq2 = m_wrset = m_counting = false; m_clkcount = 0; - m_xmit_send--; + } + if (!control_bit(REN)) + { + m_rq1 = m_rq2 = m_rdset = false; + } + + // Raise interrupt + if ((control_bit(WIEN) && status_bit(HSKWT)) + || (control_bit(RIEN) && status_bit(HSKRD)) + || (control_bit(BAVAIEN) && status_bit(BAVAIS)) + || (control_bit(BAVIAEN) && status_bit(BAVIAS))) + { + m_int(ASSERT_LINE); } } +void oso_device::update_hexbus() +{ + uint8_t value = 0x00; + uint8_t nibble = m_xmit; + if (m_wnp) nibble >>= 4; + + value = ((m_xmit & 0x0c)<<4) | (m_xmit & 0x03); + if (!m_hsk) value |= 0x10; + if (!control_bit(BAVC)) value |= 0x04; + if (value != m_lasthxvalue) + { + if (TRACE_OSO) logerror("Set hexbus = %02x (BAV*=%d, HSK*=%d, data=%01x)\n", value, (value & 0x04)? 1:0, (value & 0x10)? 1:0, ((value>>4)&0x0c) | (value&0x03)); + hexbus_write(value); + } + m_lasthxvalue = value; +} + void oso_device::device_start() { logerror("Starting\n"); m_status = m_xmit = m_control = m_data = 0; + m_int.resolve_safe(); m_hexbus_outbound = dynamic_cast<bus::hexbus::hexbus_device*>(machine().device(TI_HEXBUS_TAG)); // Establish callback for inbound propagations m_hexbus_outbound->set_chain_element(this); - // Establish callback - m_hexbus_outbound->set_chain_element(this); save_item(NAME(m_data)); save_item(NAME(m_status)); diff --git a/src/devices/bus/ti99/internal/998board.h b/src/devices/bus/ti99/internal/998board.h index bde035d7d73..1787c0f9cec 100644 --- a/src/devices/bus/ti99/internal/998board.h +++ b/src/devices/bus/ti99/internal/998board.h @@ -436,15 +436,60 @@ public: WRITE_LINE_MEMBER( clock_in ); + // INT line + devcb_write_line m_int; + private: + bool control_bit(int bit) { return (m_control & bit)!=0; } + bool status_bit(int bit) { return (m_status & bit)!=0; } + void clear_int_status(); + void set_status(int bit, bool set) { m_status = (set)? (m_status | bit) : (m_status & ~bit); } + void update_hexbus(); + + // Registers uint8_t m_data; uint8_t m_status; uint8_t m_control; uint8_t m_xmit; - int m_clkcount; - - int m_xmit_send; + // Last hexbus value; when the new value is different, send it via the hexbus + uint8_t m_lasthxvalue; + + bool m_bav; // Bus available; when true, a communication is about to happen + bool m_sbav; // Stable BAV; the BAV signal is true for two clock cycles + bool m_sbavold; // Old SBAV state + bool m_bavhold; // For computing the SBAV signal + + bool m_hsk; // Handshake line; when true, a bus member needs more time to process the message + bool m_shsk; // Stable HSK + bool m_shskold; // see above + bool m_hskhold; // see above + + // Page 3 in OSO schematics: Write timing + bool m_wq1; // Flipflop 1 + bool m_wq1old; // Previous state + bool m_wq2; // Flipflop 2 + bool m_wq2old; // Previous state + bool m_wnp; // Write nibble selection; true means upper 4 bits + bool m_wbusyold; // Old state of the WBUSY line + bool m_sendbyte; // Byte has been loaded into the XMIT register + bool m_wrset; // Start sending + bool m_counting; // Counter running + int m_clkcount; // Counter for 30 cycles + + // Page 4 in OSO schematics: Read timing + bool m_rq1; // Flipflop 1 + bool m_rq2; // Flipflop 2 + bool m_rq2old; // Previous state + bool m_rnib; // Read nibble, true means upper 4 bits + bool m_rnibcold; // Needed to detect the raising edge + bool m_rdset; // Start reading + bool m_rdsetold; // Old state + bool m_msns; // Upper 4 bits + bool m_lsns; // Lower 4 bits + + // Page 6 (RHSUS*) + bool m_rhsus; // Needed to assert the HSK line until the CPU has read the byte }; class mainboard8_device : public device_t @@ -612,6 +657,9 @@ private: #define MCFG_MAINBOARD8_HOLD_CALLBACK(_write) \ devcb = &bus::ti99::internal::mainboard8_device::set_hold_wr_callback(*device, DEVCB_##_write); +#define MCFG_OSO_INT_CALLBACK(_int) \ + devcb = &bus::ti99::internal::oso_device::set_int_callback(*device, DEVCB##_int); + DECLARE_DEVICE_TYPE_NS(TI99_MAINBOARD8, bus::ti99::internal, mainboard8_device) DECLARE_DEVICE_TYPE_NS(TI99_VAQUERRO, bus::ti99::internal, vaquerro_device) DECLARE_DEVICE_TYPE_NS(TI99_MOFETTA, bus::ti99::internal, mofetta_device) diff --git a/src/devices/bus/tmc600/euro.cpp b/src/devices/bus/tmc600/euro.cpp new file mode 100644 index 00000000000..08324160bde --- /dev/null +++ b/src/devices/bus/tmc600/euro.cpp @@ -0,0 +1,77 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Telercas Telmac TMC-600 euro bus emulation + +**********************************************************************/ + +#include "emu.h" +#include "euro.h" + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(TMC600_EURO_BUS_SLOT, tmc600_euro_bus_slot_t, "tmc600_euro_bus_slot", "TMC-600 euro bus slot") + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// device_tmc600_euro_bus_card_interface - constructor +//------------------------------------------------- + +device_tmc600_euro_bus_card_interface::device_tmc600_euro_bus_card_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) +{ + m_slot = dynamic_cast<tmc600_euro_bus_slot_t *>(device.owner()); +} + + +//------------------------------------------------- +// tmc600_euro_bus_slot_t - constructor +//------------------------------------------------- + +tmc600_euro_bus_slot_t::tmc600_euro_bus_slot_t(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, TMC600_EURO_BUS_SLOT, tag, owner, clock), + device_slot_interface(mconfig, *this) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void tmc600_euro_bus_slot_t::device_start() +{ + m_card = dynamic_cast<device_tmc600_euro_bus_card_interface *>(get_card_device()); +} + + +//------------------------------------------------- +// SLOT_INTERFACE( tmc600_euro_bus_cards ) +//------------------------------------------------- + +SLOT_INTERFACE_START( tmc600_euro_bus_cards ) + //SLOT_INTERFACE("tmc710", TMC710) // 5-way expander + //SLOT_INTERFACE("tmc720", TMC720) // 5-way expander (new model) + //SLOT_INTERFACE("tmce200", TMCE200) // 8 KB RAM (CMOS) + //SLOT_INTERFACE("tmce220", TMCE220) // 16/32 KB RAM/EPROM + //SLOT_INTERFACE("tmce225", TMCE225) // 16 KB RAM (CMOS) + //SLOT_INTERFACE("tmce250", TMCE250) // 32-way input/output + //SLOT_INTERFACE("tmce260", TMCE260) // RS-232 + //SLOT_INTERFACE("tmce270", TMCE270) // generic ADC card (RCA CA3162 or CA3300, Teledyne 8700/01/02/03/04/05) + //SLOT_INTERFACE("tmce2701", TMCE2701) // TMCE-270 with CA3162 + //SLOT_INTERFACE("tmce2702", TMCE2702) // TMCE-270 with CA3300 + //SLOT_INTERFACE("tmce280", TMCE280) // floppy disc controller for 3x 5.25" and 4x 8" + //SLOT_INTERFACE("tmce285", TMCE285) // monochrome CRT controller (min. 80 cps) + //SLOT_INTERFACE("tmce300", TMCE300) // slave computer with parallel I/O + //SLOT_INTERFACE("tmce305", TMCE304) // slave computer with serial I/O +SLOT_INTERFACE_END diff --git a/src/devices/bus/tmc600/euro.h b/src/devices/bus/tmc600/euro.h new file mode 100644 index 00000000000..8e7f4c7cfe8 --- /dev/null +++ b/src/devices/bus/tmc600/euro.h @@ -0,0 +1,120 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Telercas Telmac TMC-600 euro bus emulation + +********************************************************************** + + C A + GND * 1 * GND + D1 * 2 * D0 + D3 * 3 * D2 + D5 * 4 * D4 + D7 * 5 * D6 + GND * 6 * GND + A1 * 7 * A0 + A3 * 8 * A2 + A5 * 9 * A4 + A7 * 10 * A6 + A9 * 11 * A8 + A11 * 12 * A10 + A13 * 13 * A12 + A15 * 14 * A14 + GND * 15 * GND + TPB * 16 * CLOCK + _MWR * 17 * _CLEAR + _MRD * 18 * _WAIT + TPA * 19 * _DMAO + SC0 * 20 * _DMAI + SC1 * 21 * _INT + N0 * 22 * _EF1 + N1 * 23 * _EF2 + N2 * 24 * _EF3 + Q * 25 * _EF4 + _MI * 26 * _EMS + SP1 * 27 * SP2 + GND * 28 * GND + -5V * 29 * -5V + +12v * 30 * +12V + +5V * 31 * +5V + +5V * 32 * +5V + +**********************************************************************/ + +#ifndef MAME_DEVICES_TMC600_EURO_H +#define MAME_DEVICES_TMC600_EURO_H + +#pragma once + + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +#define TMC600_EURO_BUS_TAG "bus" + + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_TMC600_EURO_BUS_SLOT_ADD(_tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, TMC600_EURO_BUS_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> device_tmc600_euro_bus_card_interface + +class tmc600_euro_bus_slot_t; + +class device_tmc600_euro_bus_card_interface : public device_slot_card_interface +{ +public: + +protected: + // construction/destruction + device_tmc600_euro_bus_card_interface(const machine_config &mconfig, device_t &device); + + tmc600_euro_bus_slot_t *m_slot; + + friend class tmc600_euro_bus_slot_t; +}; + + +// ======================> tmc600_euro_bus_slot_t + +class tmc600_euro_bus_slot_t : public device_t, + public device_slot_interface +{ +public: + // construction/destruction + tmc600_euro_bus_slot_t(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override { if (m_card) get_card_device()->reset(); } + + device_tmc600_euro_bus_card_interface *m_card; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(TMC600_EURO_BUS_SLOT, tmc600_euro_bus_slot_t) + + +SLOT_INTERFACE_EXTERN( tmc600_euro_bus_cards ); + + +typedef device_type_iterator<tmc600_euro_bus_slot_t> tmc600_euro_bus_slot_t_iterator; + + +#endif // MAME_DEVICES_TMC600_EURO_H diff --git a/src/devices/bus/vme/vme.cpp b/src/devices/bus/vme/vme.cpp index c27f4a44da4..69bc9d90fb8 100644 --- a/src/devices/bus/vme/vme.cpp +++ b/src/devices/bus/vme/vme.cpp @@ -266,7 +266,7 @@ void vme_device::device_start() LOG(" - using owner memory spaces for %s\n", m_cputag); m_maincpu = owner()->subdevice<cpu_device>(m_cputag); m_prgspace = &m_maincpu->space(AS_PROGRAM); - m_prgwidth = m_maincpu->space_config(AS_PROGRAM)->m_databus_width; + m_prgwidth = m_maincpu->space_config(AS_PROGRAM)->m_data_width; LOG(" - Done at %d width\n", m_prgwidth); } } diff --git a/src/devices/bus/vme/vme_fccpu20.cpp b/src/devices/bus/vme/vme_fccpu20.cpp index 0e1ace4ff8d..7391bc27993 100644 --- a/src/devices/bus/vme/vme_fccpu20.cpp +++ b/src/devices/bus/vme/vme_fccpu20.cpp @@ -489,9 +489,9 @@ READ32_MEMBER (vme_fccpu20_device::bootvect_r) WRITE32_MEMBER (vme_fccpu20_device::bootvect_w) { LOG("%s\n", FUNCNAME); - m_sysram[offset % sizeof(m_sysram)] &= ~mem_mask; - m_sysram[offset % sizeof(m_sysram)] |= (data & mem_mask); - m_sysrom = &m_sysram[0]; // redirect all upcomming accesses to masking RAM until reset. + m_sysram[offset % ARRAY_LENGTH(m_sysram)] &= ~mem_mask; + m_sysram[offset % ARRAY_LENGTH(m_sysram)] |= (data & mem_mask); + m_sysrom = &m_sysram[0]; // redirect all upcoming accesses to masking RAM until reset. } WRITE_LINE_MEMBER(vme_fccpu20_device::bim_irq_callback) diff --git a/src/devices/bus/vme/vme_hcpu30.cpp b/src/devices/bus/vme/vme_hcpu30.cpp index d94e5ed28cd..4e6e4d3aa8a 100644 --- a/src/devices/bus/vme/vme_hcpu30.cpp +++ b/src/devices/bus/vme/vme_hcpu30.cpp @@ -155,7 +155,7 @@ WRITE32_MEMBER(vme_hcpu30_card_device::bootvect_w) LOG("%s\n", FUNCNAME); m_sysram[offset % sizeof(m_sysram)] &= ~mem_mask; m_sysram[offset % sizeof(m_sysram)] |= (data & mem_mask); - m_sysrom = &m_sysram[0]; // redirect all upcomming accesses to masking RAM until reset. + m_sysrom = &m_sysram[0]; // redirect all upcoming accesses to masking RAM until reset. } vme_hcpu30_card_device::vme_hcpu30_card_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) diff --git a/src/devices/bus/vme/vme_mzr8300.cpp b/src/devices/bus/vme/vme_mzr8300.cpp index 44f3716135a..95acacbd39b 100644 --- a/src/devices/bus/vme/vme_mzr8300.cpp +++ b/src/devices/bus/vme/vme_mzr8300.cpp @@ -120,11 +120,6 @@ DEFINE_DEVICE_TYPE(VME_MZR8300, vme_mzr8300_card_device, "mzr8300", "Mizar 8300 * once a proper serial board hardware (ie MZ 8300) is found and emulated. */ -static DEVICE_INPUT_DEFAULTS_START( terminal ) - DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9615 ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9615 ) -DEVICE_INPUT_DEFAULTS_END - //------------------------------------------------- // device_add_mconfig - add device configuration //------------------------------------------------- @@ -137,10 +132,9 @@ MACHINE_CONFIG_MEMBER( vme_mzr8300_card_device::device_add_mconfig ) MCFG_DEVICE_ADD("sio1", UPD7201_NEW, XTAL_4MHz) - MCFG_RS232_PORT_ADD ("rs232p1", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("sio0", upd7201_new_device, rxb_w)) - MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("sio0", upd7201_new_device, ctsb_w)) - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) + MCFG_RS232_PORT_ADD("rs232p1", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio0", upd7201_new_device, rxb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio0", upd7201_new_device, ctsb_w)) MCFG_DEVICE_ADD("stc", AM9513, XTAL_4MHz) MCFG_AM9513_OUT1_CALLBACK(DEVWRITELINE("sio0", upd7201_new_device, rxca_w)) diff --git a/src/devices/cpu/8x300/8x300.cpp b/src/devices/cpu/8x300/8x300.cpp index 44bb9b34fe6..575b3f2d0d0 100644 --- a/src/devices/cpu/8x300/8x300.cpp +++ b/src/devices/cpu/8x300/8x300.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "8x300.h" +#include "8x300dasm.h" #include "debugger.h" #define FETCHOP(a) (m_direct->read_word(a)) @@ -96,7 +97,7 @@ uint8_t n8x300_cpu_device::get_reg(uint8_t reg) void n8x300_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_PC)); @@ -590,8 +591,7 @@ void n8x300_cpu_device::execute_run() } while (m_icount > 0); } -offs_t n8x300_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *n8x300_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( n8x300 ); - return CPU_DISASSEMBLE_NAME(n8x300)(this, stream, pc, oprom, opram, options); + return new n8x300_disassembler; } diff --git a/src/devices/cpu/8x300/8x300.h b/src/devices/cpu/8x300/8x300.h index 5bba395cca6..7a36dc941a6 100644 --- a/src/devices/cpu/8x300/8x300.h +++ b/src/devices/cpu/8x300/8x300.h @@ -63,9 +63,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_io_config; @@ -74,7 +72,7 @@ protected: bool m_increment_pc; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint16_t m_PC; // Program Counter diff --git a/src/devices/cpu/8x300/8x300dasm.cpp b/src/devices/cpu/8x300/8x300dasm.cpp index a6375072a49..db231195f04 100644 --- a/src/devices/cpu/8x300/8x300dasm.cpp +++ b/src/devices/cpu/8x300/8x300dasm.cpp @@ -8,7 +8,7 @@ */ #include "emu.h" -#include "8x300.h" +#include "8x300dasm.h" #define SRC ((opcode & 0x1f00) >> 8) #define DST (opcode & 0x001f) @@ -16,7 +16,7 @@ #define IMM8 (opcode & 0x00ff) #define IMM5 (opcode & 0x001f) -static const char *reg_names[32] = +const char *const n8x300_disassembler::reg_names[32] = { "AUX", "R1", "R2", "R3", "R4", "R5", "R6", "IVL", "OVF", "R11", "Unused12", "Unused13", "Unused14", "Unused15", "Unused16", "IVR", @@ -25,7 +25,7 @@ static const char *reg_names[32] = }; // determines if right rotate or I/O field length is to be used -static inline bool is_rot(uint16_t opcode) +bool n8x300_disassembler::is_rot(uint16_t opcode) { if((opcode & 0x1000) || (opcode & 0x0010)) return false; @@ -33,7 +33,7 @@ static inline bool is_rot(uint16_t opcode) return true; } -static inline bool is_src_rot(uint16_t opcode) +bool n8x300_disassembler::is_src_rot(uint16_t opcode) { if((opcode & 0x1000)) return false; @@ -41,10 +41,15 @@ static inline bool is_src_rot(uint16_t opcode) return true; } -CPU_DISASSEMBLE(n8x300) +u32 n8x300_disassembler::opcode_alignment() const +{ + return 2; +} + +offs_t n8x300_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned startpc = pc; - uint16_t opcode = (oprom[pc - startpc] << 8) | oprom[pc+1 - startpc]; + uint16_t opcode = opcodes.r16(pc); uint8_t inst = opcode >> 13; pc+=2; diff --git a/src/devices/cpu/8x300/8x300dasm.h b/src/devices/cpu/8x300/8x300dasm.h new file mode 100644 index 00000000000..f5fe389c614 --- /dev/null +++ b/src/devices/cpu/8x300/8x300dasm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Barry Rodewald +/* + * 8x300dasm.c + * Implementation of the Scientific Micro Systems SMS300 / Signetics 8X300 Microcontroller + * + * Created on: 18/12/2013 + */ + +#ifndef MAME_CPU_8X300_8X300DASM_H +#define MAME_CPU_8X300_8X300DASM_H + +#pragma once + +class n8x300_disassembler : public util::disasm_interface +{ +public: + n8x300_disassembler() = default; + virtual ~n8x300_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const reg_names[32]; + + bool is_rot(uint16_t opcode); + bool is_src_rot(uint16_t opcode); +}; + +#endif diff --git a/src/devices/cpu/adsp2100/2100dasm.cpp b/src/devices/cpu/adsp2100/2100dasm.cpp index a126cfa0bcb..b3efa6ac6ec 100644 --- a/src/devices/cpu/adsp2100/2100dasm.cpp +++ b/src/devices/cpu/adsp2100/2100dasm.cpp @@ -1,32 +1,32 @@ // license:BSD-3-Clause // copyright-holders:Aaron Giles #include "emu.h" -#include "adsp2100.h" +#include "2100dasm.h" -static const char *const flag_change[] = { "", "TOGGLE %s ", "RESET %s ", "SET %s " }; -static const char *const mode_change[] = { "", "", "DIS %s ", "ENA %s " }; +const char *const adsp21xx_disassembler::flag_change[] = { "", "TOGGLE %s ", "RESET %s ", "SET %s " }; +const char *const adsp21xx_disassembler::mode_change[] = { "", "", "DIS %s ", "ENA %s " }; -static const char *const alu_xop[] = { "AX0", "AX1", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; -static const char *const alu_yop[] = { "AY0", "AY1", "AF", "0" }; -static const char *const alu_dst[] = { "AR", "AF", "NONE" }; +const char *const adsp21xx_disassembler::alu_xop[] = { "AX0", "AX1", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; +const char *const adsp21xx_disassembler::alu_yop[] = { "AY0", "AY1", "AF", "0" }; +const char *const adsp21xx_disassembler::alu_dst[] = { "AR", "AF", "NONE" }; -static const char *const mac_xop[] = { "MX0", "MX1", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; -static const char *const mac_yop[] = { "MY0", "MY1", "MF", "0" }; -static const char *const mac_dst[] = { "MR", "MF", "NONE" }; +const char *const adsp21xx_disassembler::mac_xop[] = { "MX0", "MX1", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; +const char *const adsp21xx_disassembler::mac_yop[] = { "MY0", "MY1", "MF", "0" }; +const char *const adsp21xx_disassembler::mac_dst[] = { "MR", "MF", "NONE" }; -static const char *const shift_xop[] = { "SI", "??", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; +const char *const adsp21xx_disassembler::shift_xop[] = { "SI", "??", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }; -static const char *const reg_grp[][16] = +const char *const adsp21xx_disassembler::reg_grp[][16] = { { "AX0", "AX1", "MX0", "MX1", "AY0", "AY1", "MY0", "MY1", "SI", "SE", "AR", "MR0", "MR1", "MR2", "SR0", "SR1" }, { "I0", "I1", "I2", "I3", "M0", "M1", "M2", "M3", "L0", "L1", "L2", "L3", "??", "??", "PMOVLAY", "DMOVLAY" }, { "I4", "I5", "I6", "I7", "M4", "M5", "M6", "M7", "L4", "L5", "L6", "L7", "??", "??", "??", "??" }, { "ASTAT", "MSTAT", "SSTAT", "IMASK", "ICNTL", "CNTR", "SB", "PX", "RX0", "TX0", "RX1", "TX1", "IFC", "OWRCNTR", "??", "??" } }; -static const char *const dual_xreg[] = { "AX0", "AX1", "MX0", "MX1" }; -static const char *const dual_yreg[] = { "AY0", "AY1", "MY0", "MY1" }; +const char *const adsp21xx_disassembler::dual_xreg[] = { "AX0", "AX1", "MX0", "MX1" }; +const char *const adsp21xx_disassembler::dual_yreg[] = { "AY0", "AY1", "MY0", "MY1" }; -static const char *const condition[] = +const char *const adsp21xx_disassembler::condition[] = { "IF EQ ", "IF NE ", @@ -46,7 +46,7 @@ static const char *const condition[] = "" }; -static const char *const do_condition[] = +const char *const adsp21xx_disassembler::do_condition[] = { "NE", "EQ", @@ -66,7 +66,7 @@ static const char *const do_condition[] = "FOREVER" }; -static const char *const alumac_op[][2] = +const char *const adsp21xx_disassembler::alumac_op[][2] = { { "", "" }, { "%s = %s * %s (RND)", "%s = %s * %s (RND)" }, @@ -103,7 +103,7 @@ static const char *const alumac_op[][2] = { "%s = ABS %s", "%s = ABS %s" } }; -static const char *const shift_op[] = +const char *const adsp21xx_disassembler::shift_op[] = { "SR = LSHIFT %s (HI)", "SR = SR OR LSHIFT %s (HI)", @@ -123,7 +123,7 @@ static const char *const shift_op[] = "SB = EXPADJ %s", }; -static const char *const shift_by_op[] = +const char *const adsp21xx_disassembler::shift_by_op[] = { "SR = LSHIFT %s BY %d (HI)", "SR = SR OR LSHIFT %s BY %d (HI)", @@ -143,7 +143,7 @@ static const char *const shift_by_op[] = "???" }; -static const char *const constants[] = +const char *const adsp21xx_disassembler::constants[] = { "$0001", "$FFFE", @@ -180,9 +180,7 @@ static const char *const constants[] = }; - - -static void alumac(std::ostream &stream, int dest, int op) +void adsp21xx_disassembler::alumac(std::ostream &stream, int dest, int op) { int opindex = (op >> 13) & 31; const char *xop, *yop, *dst, *opstring; @@ -207,7 +205,7 @@ static void alumac(std::ostream &stream, int dest, int op) } -static void aluconst(std::ostream &stream, int dest, int op) +void adsp21xx_disassembler::aluconst(std::ostream &stream, int dest, int op) { int opindex = (op >> 13) & 31; const char *xop, *dst, *cval, *opstring; @@ -232,10 +230,9 @@ static void aluconst(std::ostream &stream, int dest, int op) } -/* execute instructions on this CPU until icount expires */ -CPU_DISASSEMBLE(adsp21xx) +offs_t adsp21xx_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned int op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16); + unsigned int op = opcodes.r32(pc); unsigned dasmflags = 0; int temp; @@ -281,7 +278,7 @@ CPU_DISASSEMBLE(adsp21xx) if (op & 1) { util::stream_format(stream, "%s", "CALL "); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else util::stream_format(stream, "%s", "JUMP "); @@ -295,7 +292,7 @@ CPU_DISASSEMBLE(adsp21xx) if (op & 0x000010) { util::stream_format(stream, "%s", "POP PC "); - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; } if (op & 0x000008) util::stream_format(stream, "%s", "POP LOOP "); if (op & 0x000004) util::stream_format(stream, "%s", "POP CNTR "); @@ -349,7 +346,7 @@ CPU_DISASSEMBLE(adsp21xx) util::stream_format(stream, "%s", "RTI"); else util::stream_format(stream, "%s", "RTS"); - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; } else util::stream_format(stream, "??? (%06X)", op); @@ -362,7 +359,7 @@ CPU_DISASSEMBLE(adsp21xx) if (op & 0x000010) { util::stream_format(stream, "CALL (I%d)", 4 + ((op >> 6) & 3)); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else util::stream_format(stream, "JUMP (I%d)", 4 + ((op >> 6) & 3)); @@ -440,7 +437,7 @@ CPU_DISASSEMBLE(adsp21xx) if (op & 0x040000) { util::stream_format(stream, "%sCALL $%04X", condition[op & 15], (op >> 4) & 0x3fff); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else util::stream_format(stream, "%sJUMP $%04X", condition[op & 15], (op >> 4) & 0x3fff); @@ -549,5 +546,10 @@ CPU_DISASSEMBLE(adsp21xx) break; } - return 1 | dasmflags | DASMFLAG_SUPPORTED; + return 1 | dasmflags | SUPPORTED; +} + +uint32_t adsp21xx_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/adsp2100/2100dasm.h b/src/devices/cpu/adsp2100/2100dasm.h new file mode 100644 index 00000000000..1c80c47a554 --- /dev/null +++ b/src/devices/cpu/adsp2100/2100dasm.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles + +#ifndef MAME_CPU_ADSP2100_2100DASM_H +#define MAME_CPU_ADSP2100_2100DASM_H + +#pragma once + +class adsp21xx_disassembler : public util::disasm_interface +{ +public: + adsp21xx_disassembler() = default; + virtual ~adsp21xx_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const flag_change[]; + static const char *const mode_change[]; + static const char *const alu_xop[]; + static const char *const alu_yop[]; + static const char *const alu_dst[]; + static const char *const mac_xop[]; + static const char *const mac_yop[]; + static const char *const mac_dst[]; + static const char *const shift_xop[];; + static const char *const reg_grp[][16]; + static const char *const dual_xreg[]; + static const char *const dual_yreg[]; + static const char *const condition[]; + static const char *const do_condition[]; + static const char *const alumac_op[][2]; + static const char *const shift_op[]; + static const char *const shift_by_op[]; + static const char *const constants[]; + + void alumac(std::ostream &stream, int dest, int op); + void aluconst(std::ostream &stream, int dest, int op); + +}; + +#endif diff --git a/src/devices/cpu/adsp2100/adsp2100.cpp b/src/devices/cpu/adsp2100/adsp2100.cpp index d0c10e06dce..7c9b6da7727 100644 --- a/src/devices/cpu/adsp2100/adsp2100.cpp +++ b/src/devices/cpu/adsp2100/adsp2100.cpp @@ -100,6 +100,7 @@ #include "emu.h" #include "debugger.h" #include "adsp2100.h" +#include "2100dasm.h" // device type definitions @@ -417,7 +418,7 @@ void adsp21xx_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-2>(); m_data = &space(AS_DATA); m_io = has_space(AS_IO) ? &space(AS_IO) : nullptr; @@ -758,78 +759,54 @@ void adsp21xx_device::state_string_export(const device_state_entry &entry, std:: //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t adsp21xx_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t adsp21xx_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t adsp21xx_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *adsp21xx_device::create_disassembler() { - extern CPU_DISASSEMBLE( adsp21xx ); - return CPU_DISASSEMBLE_NAME(adsp21xx)(this, stream, pc, oprom, opram, options); + return new adsp21xx_disassembler; } - /*************************************************************************** MEMORY ACCESSORS ***************************************************************************/ inline uint16_t adsp21xx_device::data_read(uint32_t addr) { - return m_data->read_word(addr << 1); + return m_data->read_word(addr); } inline void adsp21xx_device::data_write(uint32_t addr, uint16_t data) { - m_data->write_word(addr << 1, data); + m_data->write_word(addr, data); } inline uint16_t adsp21xx_device::io_read(uint32_t addr) { - return m_io->read_word(addr << 1); + return m_io->read_word(addr); } inline void adsp21xx_device::io_write(uint32_t addr, uint16_t data) { - m_io->write_word(addr << 1, data); + m_io->write_word(addr, data); } inline uint32_t adsp21xx_device::program_read(uint32_t addr) { - return m_program->read_dword(addr << 2); + return m_program->read_dword(addr); } inline void adsp21xx_device::program_write(uint32_t addr, uint32_t data) { - m_program->write_dword(addr << 2, data & 0xffffff); + m_program->write_dword(addr, data & 0xffffff); } inline uint32_t adsp21xx_device::opcode_read() { - return m_direct->read_dword(m_pc << 2); + return m_direct->read_dword(m_pc); } diff --git a/src/devices/cpu/adsp2100/adsp2100.h b/src/devices/cpu/adsp2100/adsp2100.h index faaddcdcc10..4b2cbcd98a8 100644 --- a/src/devices/cpu/adsp2100/adsp2100.h +++ b/src/devices/cpu/adsp2100/adsp2100.h @@ -243,9 +243,7 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // helpers void create_tables(); @@ -452,7 +450,7 @@ protected: address_space * m_program; address_space * m_data; address_space * m_io; - direct_read_data * m_direct; + direct_read_data<-2> *m_direct; // tables uint8_t m_condition_table[0x1000]; diff --git a/src/devices/cpu/alph8201/8201dasm.cpp b/src/devices/cpu/alph8201/8201dasm.cpp index 8e5e99ffd37..a987d5ededd 100644 --- a/src/devices/cpu/alph8201/8201dasm.cpp +++ b/src/devices/cpu/alph8201/8201dasm.cpp @@ -20,11 +20,10 @@ cpu/alph8201/ will be removed when the alpha 8304 has been dumped. ****************************************************************************/ #include "emu.h" +#include "8201dasm.h" #include <ctype.h> -typedef unsigned char byte; - #define FMT(a,b) a, b #define PTRS_PER_FORMAT 2 @@ -171,7 +170,7 @@ Notes: /****************************************************/ -static const char *const Formats[] = { +const char *const alpha8201_disassembler::Formats[] = { FMT("0000_0000", "NOP"), // 00 FMT("0000_0001", "RRCA"), // 01 FMT("0000_0010", "RLCA"), // 02 @@ -270,24 +269,10 @@ static const char *const Formats[] = { nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(Formats) - 1) / PTRS_PER_FORMAT) - -struct AD8201Opcode { - byte mask; - byte bits; - byte type; - byte pmask; - byte pdown; - const char *fmt; -}; - -static AD8201Opcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm8201(void) +alpha8201_disassembler::alpha8201_disassembler() { const char *p; - byte mask, bits; + u8 mask, bits; int bit; int i; char chr , type; @@ -345,11 +330,10 @@ static void InitDasm8201(void) Op[i].type |= 0x02; /* double param */ } } - - OpInizialized = 1; + op_count = i; } -CPU_DISASSEMBLE(alpha8201) +offs_t alpha8201_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { offs_t dasmflags = 0; int i; @@ -357,11 +341,9 @@ CPU_DISASSEMBLE(alpha8201) int cnt = 1; int code , disp; - if (!OpInizialized) InitDasm8201(); - - code = oprom[0]; + code = opcodes.r8(pc); op = -1; /* no matching opcode */ - for ( i = 0; i < MAX_OPS; i++) + for ( i = 0; i < op_count; i++) { if( (code & Op[i].mask) == Op[i].bits ) { @@ -382,7 +364,7 @@ CPU_DISASSEMBLE(alpha8201) if (Op[op].type & 0x10) { - disp = opram[1]; + disp = params.r8(pc+1); cnt++; } else @@ -403,13 +385,18 @@ CPU_DISASSEMBLE(alpha8201) case 0xcd: case 0xce: case 0xdf: - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; break; case 0xff: - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; break; } - return cnt | dasmflags | DASMFLAG_SUPPORTED; + return cnt | dasmflags | SUPPORTED; +} + +u32 alpha8201_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/alph8201/8201dasm.h b/src/devices/cpu/alph8201/8201dasm.h new file mode 100644 index 00000000000..85676c5de10 --- /dev/null +++ b/src/devices/cpu/alph8201/8201dasm.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Tatsuyuki Satoh +/* + +Notice: The alpha 8201 is now emulated using mame/alpha8201.* + +cpu/alph8201/ will be removed when the alpha 8304 has been dumped. + + + + +*/ + +/**************************************************************************** + Alpha 8201/8301 Disassembler + + Copyright Tatsuyuki Satoh + Originally written for the MAME project. + +****************************************************************************/ + +#ifndef MAME_CPU_ALPH8201_8201DASM_H +#define MAME_CPU_ALPH8201_8201DASM_H + +#pragma once + +class alpha8201_disassembler : public util::disasm_interface +{ +public: + alpha8201_disassembler(); + virtual ~alpha8201_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct AD8201Opcode { + u8 mask; + u8 bits; + u8 type; + u8 pmask; + u8 pdown; + const char *fmt; + }; + + static const char *const Formats[]; + AD8201Opcode Op[256]; + int op_count; +}; + +#endif diff --git a/src/devices/cpu/alph8201/alph8201.cpp b/src/devices/cpu/alph8201/alph8201.cpp index 5dc141d7d82..8a422d3a450 100644 --- a/src/devices/cpu/alph8201/alph8201.cpp +++ b/src/devices/cpu/alph8201/alph8201.cpp @@ -163,7 +163,7 @@ Timming #include "emu.h" #include "alph8201.h" #include "debugger.h" - +#include "8201dasm.h" DEFINE_DEVICE_TYPE(ALPHA8201L, alpha8201_cpu_device, "alpha8201l", "ALPHA-8201L") DEFINE_DEVICE_TYPE(ALPHA8301L, alpha8301_cpu_device, "alpha8301l", "ALPHA-8301L") @@ -394,7 +394,7 @@ const alpha8201_cpu_device::s_opcode alpha8201_cpu_device::opcode_8301[256]= void alpha8201_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); state_add( ALPHA8201_PC, "PC", m_pc.w.l ).callimport().mask(0x3ff).formatstr("%03X"); state_add( ALPHA8201_SP, "SP", m_sp ).callimport().callexport().formatstr("%02X"); @@ -690,9 +690,7 @@ void alpha8201_cpu_device::execute_set_input(int inputnum, int state) } } - -offs_t alpha8201_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *alpha8201_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( alpha8201 ); - return CPU_DISASSEMBLE_NAME(alpha8201)(this, stream, pc, oprom, opram, options); + return new alpha8201_disassembler; } diff --git a/src/devices/cpu/alph8201/alph8201.h b/src/devices/cpu/alph8201/alph8201.h index 93640f17301..5627bf23068 100644 --- a/src/devices/cpu/alph8201/alph8201.h +++ b/src/devices/cpu/alph8201/alph8201.h @@ -83,9 +83,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 4; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; u8 M_RDMEM(u16 A) { return m_program->read_byte(A); } void M_WRMEM(u16 A, u8 V) { m_program->write_byte(A, V); } @@ -390,7 +388,7 @@ protected: u8 m_halt; /* halt input line */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; int m_inst_cycles; diff --git a/src/devices/cpu/alto2/a2ram.cpp b/src/devices/cpu/alto2/a2ram.cpp index 39996f98fa7..3aab054871d 100644 --- a/src/devices/cpu/alto2/a2ram.cpp +++ b/src/devices/cpu/alto2/a2ram.cpp @@ -99,7 +99,7 @@ void alto2_cpu_device::rdram() #if DEBUG_RDRAM char buffer[256]; uint8_t* oprom = m_ucode_cram.get() + 4 * wordaddr; - disasm_disassemble(buffer, wordaddr, oprom, oprom, 0); + disassemble(buffer, wordaddr, oprom, oprom, 0); printf("RD CRAM_BANKSEL=%d RAM%d [%04o] upper:%06o lower:%06o value:%011o '%s'\n", GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr, m_myl, m_alu, value, buffer); @@ -144,7 +144,7 @@ void alto2_cpu_device::wrtram() #if DEBUG_WRTRAM char buffer[256]; uint8_t* oprom = m_ucode_cram.get() + 4 * wordaddr; - disasm_disassemble(buffer, wordaddr, oprom, oprom, 0); + disassemble(buffer, wordaddr, oprom, oprom, 0); printf("WR CRAM_BANKSEL=%d RAM%d [%04o] upper:%06o lower:%06o value:%011o '%s'\n", GET_CRAM_BANKSEL(m_cram_addr), bank, wordaddr, m_myl, m_alu, value, buffer); diff --git a/src/devices/cpu/alto2/alto2cpu.cpp b/src/devices/cpu/alto2/alto2cpu.cpp index fd7a1f6dede..21f9faa2625 100644 --- a/src/devices/cpu/alto2/alto2cpu.cpp +++ b/src/devices/cpu/alto2/alto2cpu.cpp @@ -7,6 +7,7 @@ *****************************************************************************/ #include "emu.h" #include "alto2cpu.h" +#include "alto2dsm.h" #include "a2roms.h" #define DEBUG_UCODE_CONST_DATA 0 //!< define to 1 to dump decoded micro code and constants @@ -2980,3 +2981,8 @@ void alto2_cpu_device::soft_reset() m_unload_time = 0; // reset the word unload timing accu m_bitclk_time = 0; // reset the bitclk timing accu } + +util::disasm_interface *alto2_cpu_device::create_disassembler() +{ + return new alto2_disassembler; +} diff --git a/src/devices/cpu/alto2/alto2cpu.h b/src/devices/cpu/alto2/alto2cpu.h index f71b183b52a..6bebea1f803 100644 --- a/src/devices/cpu/alto2/alto2cpu.h +++ b/src/devices/cpu/alto2/alto2cpu.h @@ -238,9 +238,7 @@ protected: 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; + virtual util::disasm_interface *create_disassembler() override; private: diff --git a/src/devices/cpu/alto2/alto2dsm.cpp b/src/devices/cpu/alto2/alto2dsm.cpp index b70c35d182c..c621daaf3e7 100644 --- a/src/devices/cpu/alto2/alto2dsm.cpp +++ b/src/devices/cpu/alto2/alto2dsm.cpp @@ -5,7 +5,7 @@ * **********************************************************/ #include "emu.h" -#include "alto2cpu.h" +#include "alto2dsm.h" #define loc_DASTART 0000420 // display list header #define loc_DVIBITS 0000421 // display vertical field interrupt bitword @@ -68,7 +68,7 @@ /** * @brief short names for the 16 tasks */ -static const char *taskname[16] = { +const char *const alto2_disassembler::taskname[16] = { "EMU", // emulator task "T01", "T02", @@ -90,7 +90,7 @@ static const char *taskname[16] = { /** * @brief names for the 32 R registers */ -static const char *regname[32] = { +const char *const alto2_disassembler::regname[32] = { "AC(3)", // emulator accu 3 "AC(2)", // emulator accu 2 "AC(1)", // emulator accu 1 @@ -126,7 +126,7 @@ static const char *regname[32] = { }; //! for ALUF which is the value loaded into T, if t flags is set -static const char* t_bus_alu[16] = { +const char *const alto2_disassembler::t_bus_alu[16] = { "ALU", "BUS", "ALU", @@ -148,7 +148,7 @@ static const char* t_bus_alu[16] = { /** * @brief copy of the constant PROM, which this disassembler may not have access to */ -static uint16_t const_prom[PROM_SIZE] = { +uint16_t alto2_disassembler::const_prom[PROM_SIZE] = { /* 0000 */ 0x0000, 0x0001, 0x0002, 0xfffe, 0xffff, 0xffff, 0x000f, 0xffff, /* 0008 */ 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0xfff8, 0xfff8, /* 0010 */ 0x0010, 0x001f, 0x0020, 0x003f, 0x0040, 0x007f, 0x0080, 0x0007, @@ -187,34 +187,22 @@ static uint16_t const_prom[PROM_SIZE] = { * @brief print a symbolic name for an mpc address * * @param a microcode address (mpc) - * @return pointer to const string with the address or symbolic name + * @return string with the address or symbolic name */ -static const char *addrname(int a) +std::string alto2_disassembler::addrname(int a) const { - static char buffer[4][32]; - static int which = 0; - char *dst; - - which = (which + 1) % 4; - dst = buffer[which]; - - if (a < 020) { + if (a < 020) // start value for mpc per task is the task number - snprintf(dst, sizeof(buffer[0]), "*%s", taskname[a]); - } else { - snprintf(dst, sizeof(buffer[0]), "%04o", a); - } - return dst; + return util::string_format("*%s", taskname[a]); + else + return util::string_format("%04o", a); } -offs_t alto2_cpu_device::disasm_disassemble(std::ostream &main_stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +offs_t alto2_disassembler::disassemble(std::ostream &main_stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { std::ostringstream stream; - uint32_t mir = (static_cast<uint32_t>(oprom[0]) << 24) | - (static_cast<uint32_t>(oprom[1]) << 16) | - (static_cast<uint32_t>(oprom[2]) << 8) | - (static_cast<uint32_t>(oprom[3]) << 0); + uint32_t mir = opcodes.r32(pc); int rsel = (mir >> 27) & 31; int aluf = (mir >> 23) & 15; int bs = (mir >> 20) & 7; @@ -223,17 +211,13 @@ offs_t alto2_cpu_device::disasm_disassemble(std::ostream &main_stream, offs_t pc int t = (mir >> 11) & 1; int l = (mir >> 10) & 1; offs_t next = mir & 1023; - const uint8_t* src = oprom - 4 * pc + 4 * next; - uint32_t next2 = (static_cast<uint32_t>(src[0]) << 24) | - (static_cast<uint32_t>(src[1]) << 16) | - (static_cast<uint32_t>(src[2]) << 8) | - (static_cast<uint32_t>(src[3]) << 0); + uint32_t next2 = opcodes.r32(next); uint16_t prefetch = next2 & 1023; - offs_t result = 1 | DASMFLAG_SUPPORTED; + offs_t result = 1 | SUPPORTED; uint8_t pa; if (next != pc + 1) - result |= DASMFLAG_STEP_OUT; + result |= STEP_OUT; if (t) util::stream_format(stream, "T<-%s ", t_bus_alu[aluf]); @@ -395,3 +379,9 @@ offs_t alto2_cpu_device::disasm_disassemble(std::ostream &main_stream, offs_t pc return result; } + + +u32 alto2_disassembler::opcode_alignment() const +{ + return 1; +} diff --git a/src/devices/cpu/alto2/alto2dsm.h b/src/devices/cpu/alto2/alto2dsm.h new file mode 100644 index 00000000000..cb0d734fd58 --- /dev/null +++ b/src/devices/cpu/alto2/alto2dsm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/********************************************************** + * Xerox AltoII disassembler + * + **********************************************************/ + +#ifndef MAME_CPU_ALTO2_ALTO2DSM_H +#define MAME_CPU_ALTO2_ALTO2DSM_H + +#pragma once + +class alto2_disassembler : public util::disasm_interface +{ +public: + alto2_disassembler() = default; + virtual ~alto2_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const taskname[16]; + static const char *const regname[32]; + static const char *const t_bus_alu[16]; + static uint16_t const_prom[]; + + std::string addrname(int a) const; +}; + +#endif diff --git a/src/devices/cpu/am29000/am29000.cpp b/src/devices/cpu/am29000/am29000.cpp index cd0d4624d9c..fffd26c3cbc 100644 --- a/src/devices/cpu/am29000/am29000.cpp +++ b/src/devices/cpu/am29000/am29000.cpp @@ -17,6 +17,7 @@ #include "emu.h" #include "debugger.h" #include "am29000.h" +#include "am29dasm.h" DEFINE_DEVICE_TYPE(AM29000, am29000_cpu_device, "am29000", "AMC Am29000") @@ -130,9 +131,9 @@ device_memory_interface::space_config_vector am29000_cpu_device::memory_space_co void am29000_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); - m_datadirect = &m_data->direct(); + m_datadirect = m_data->direct<0>(); m_io = &space(AS_IO); m_cfg = (PRL_AM29000 | PRL_REV_D) << CFG_PRL_SHIFT; @@ -702,9 +703,7 @@ void am29000_cpu_device::execute_set_input(int inputnum, int state) // TODO : CHECK IRQs } - -offs_t am29000_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *am29000_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( am29000 ); - return CPU_DISASSEMBLE_NAME(am29000)(this, stream, pc, oprom, opram, options); + return new am29000_disassembler; } diff --git a/src/devices/cpu/am29000/am29000.h b/src/devices/cpu/am29000/am29000.h index 084b0fdd995..d7d061996e8 100644 --- a/src/devices/cpu/am29000/am29000.h +++ b/src/devices/cpu/am29000/am29000.h @@ -458,9 +458,7 @@ protected: 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; + virtual util::disasm_interface *create_disassembler() override; void signal_exception(uint32_t type); void external_irq_check(); @@ -632,9 +630,10 @@ protected: uint32_t m_next_pc; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; - direct_read_data *m_datadirect; + + direct_read_data<0> *m_datadirect; address_space *m_io; typedef void ( am29000_cpu_device::*opcode_func ) (); diff --git a/src/devices/cpu/am29000/am29dasm.cpp b/src/devices/cpu/am29000/am29dasm.cpp index 8c7f832e69f..7e69544ab2c 100644 --- a/src/devices/cpu/am29000/am29dasm.cpp +++ b/src/devices/cpu/am29000/am29dasm.cpp @@ -9,7 +9,7 @@ ***************************************************************************/ #include "emu.h" -#include "am29000.h" +#include "am29dasm.h" /*************************************************************************** @@ -36,38 +36,38 @@ CODE ***************************************************************************/ -static std::string dasm_type1(uint32_t op) +std::string am29000_disassembler::dasm_type1(uint32_t op) { return (op & OP_M_BIT) ? string_format("r%d, r%d, $%02x", OP_RC, OP_RA, OP_I8) : string_format("r%d, r%d, r%d", OP_RC, OP_RA, OP_RB); } -static std::string dasm_type2(uint32_t op) +std::string am29000_disassembler::dasm_type2(uint32_t op) { return string_format("r%d, r%d, r%d", OP_RC, OP_RA, OP_RB); } -static std::string dasm_type3(uint32_t op) +std::string am29000_disassembler::dasm_type3(uint32_t op) { return string_format("r%d, $%04x", OP_RA, OP_I16); } -static std::string dasm_type4(uint32_t op, uint32_t pc) +std::string am29000_disassembler::dasm_type4(uint32_t op, uint32_t pc) { return (op & OP_M_BIT) ? string_format("r%d, $%04x", OP_RA, OP_IJMP) : string_format("r%d, $%04x", OP_RA, pc + OP_SJMP); } -static std::string dasm_type5(uint32_t op) +std::string am29000_disassembler::dasm_type5(uint32_t op) { return (op & OP_M_BIT) ? string_format("trap%d, r%d, $%02x", OP_VN, OP_RA, OP_I8) : string_format("trap%d, r%d, r%d", OP_VN, OP_RA, OP_RB); } -static std::string dasm_type6(uint32_t op) +std::string am29000_disassembler::dasm_type6(uint32_t op) { return (op & OP_M_BIT) ? string_format("%d, %x, r%d, $%02x", OP_CE, OP_CNTL, OP_RA, OP_I8) @@ -82,7 +82,7 @@ static std::string dasm_type6(uint32_t op) #define TYPE_6 dasm_type6(op) -static const char* get_spr(int spid) +const char* am29000_disassembler::get_spr(int spid) { switch (spid) { @@ -117,9 +117,14 @@ static const char* get_spr(int spid) } } -CPU_DISASSEMBLE(am29000) +u32 am29000_disassembler::opcode_alignment() const { - uint32_t op = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[2] << 8) | oprom[3]; + return 4; +} + +offs_t am29000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint32_t op = opcodes.r32(pc); uint32_t flags = 0; switch (op >> 24) @@ -228,5 +233,5 @@ CPU_DISASSEMBLE(am29000) default: util::stream_format(stream, "??????"); break; } - return 4 | flags | DASMFLAG_SUPPORTED; + return 4 | flags | SUPPORTED; } diff --git a/src/devices/cpu/am29000/am29dasm.h b/src/devices/cpu/am29000/am29dasm.h new file mode 100644 index 00000000000..40507a7332e --- /dev/null +++ b/src/devices/cpu/am29000/am29dasm.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:Philip Bennett +/*************************************************************************** + + am29dasm.c + Disassembler for the portable Am29000 emulator. + Written by Phil Bennett + +***************************************************************************/ + +#ifndef MAME_CPU_AM29000_AM29DASM_H +#define MAME_CPU_AM29000_AM29DASM_H + +#pragma once + +class am29000_disassembler : public util::disasm_interface +{ +public: + am29000_disassembler() = default; + virtual ~am29000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + std::string dasm_type1(uint32_t op); + std::string dasm_type2(uint32_t op); + std::string dasm_type3(uint32_t op); + std::string dasm_type4(uint32_t op, uint32_t pc); + std::string dasm_type5(uint32_t op); + std::string dasm_type6(uint32_t op); + const char* get_spr(int spid); + +}; + +#endif diff --git a/src/devices/cpu/amis2000/amis2000.cpp b/src/devices/cpu/amis2000/amis2000.cpp index 457a99ead5d..bd3eda7852a 100644 --- a/src/devices/cpu/amis2000/amis2000.cpp +++ b/src/devices/cpu/amis2000/amis2000.cpp @@ -20,6 +20,7 @@ #include "emu.h" #include "amis2000.h" +#include "amis2000d.h" #include "debugger.h" @@ -98,10 +99,9 @@ void amis2000_base_device::state_string_export(const device_state_entry &entry, } } -offs_t amis2000_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *amis2000_base_device::create_disassembler() { - extern CPU_DISASSEMBLE(amis2000); - return CPU_DISASSEMBLE_NAME(amis2000)(this, stream, pc, oprom, opram, options); + return new amis2000_disassembler; } diff --git a/src/devices/cpu/amis2000/amis2000.h b/src/devices/cpu/amis2000/amis2000.h index e3caee13b14..1bf4bf66460 100644 --- a/src/devices/cpu/amis2000/amis2000.h +++ b/src/devices/cpu/amis2000/amis2000.h @@ -87,9 +87,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 1; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; diff --git a/src/devices/cpu/amis2000/amis2000d.cpp b/src/devices/cpu/amis2000/amis2000d.cpp index adf5e2ed338..cff6155fa0a 100644 --- a/src/devices/cpu/amis2000/amis2000d.cpp +++ b/src/devices/cpu/amis2000/amis2000d.cpp @@ -7,21 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "amis2000.h" +#include "amis2000d.h" - -enum e_mnemonics -{ - mLAB = 0, mLAE, mLAI, mLBE, mLBEP, mLBF, mLBZ, mXAB, mXABU, mXAE, - mLAM, mXC, mXCI, mXCD, mSTM, mRSM, - mADD, mADCS, mADIS, mAND, mXOR, mCMA, mSTC, mRSC, mSF1, mRF1, mSF2, mRF2, - mSAM, mSZM, mSBE, mSZC, mSOS, mSZK, mSZI, mTF1, mTF2, - mPP, mJMP, mJMS, mRT, mRTS, mNOP, mHALT, - mINP, mOUT, mDISB, mDISN, mMVS, mPSH, mPSL, mEUR -}; - -static const char *const s_mnemonics[] = +const char *const amis2000_disassembler::s_mnemonics[] = { "LAB", "LAE", "LAI", "LBE", "LBEP", "LBF", "LBZ", "XAB", "XABU", "XAE", "LAM", "XC", "XCI", "XCD", "STM", "RSM", @@ -32,7 +20,7 @@ static const char *const s_mnemonics[] = }; // number of bits per opcode parameter, negative indicates complement -static const s8 s_bits[] = +const s8 amis2000_disassembler::s_bits[] = { 0, 0, 4, 2, 2, 2, 2, 0, 0, 0, -2, -2, -2, -2, 2, 2, @@ -42,21 +30,18 @@ static const s8 s_bits[] = 0, 0, 0, 0, 0, 0, 0, 0 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 amis2000_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, _OVER, _OUT, _OUT, 0, 0, + 0, 0, STEP_OVER, STEP_OUT, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static const u8 s2000_mnemonic[0x100] = +const u8 amis2000_disassembler::s2000_mnemonic[0x100] = { /* 0x00 */ mNOP, mHALT, mRT, mRTS, mPSH, mPSL, mAND, mSOS, @@ -98,12 +83,9 @@ static const u8 s2000_mnemonic[0x100] = mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP }; - - -CPU_DISASSEMBLE(amis2000) +offs_t amis2000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int pos = 0; - u8 op = oprom[pos++]; + u8 op = opcodes.r8(pc); u8 instr = s2000_mnemonic[op]; util::stream_format(stream, "%-5s ", s_mnemonics[instr]); @@ -128,5 +110,10 @@ CPU_DISASSEMBLE(amis2000) util::stream_format(stream, "$%02X", param); } - return pos | s_flags[instr] | DASMFLAG_SUPPORTED; + return 1 | s_flags[instr] | SUPPORTED; +} + +u32 amis2000_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/amis2000/amis2000d.h b/src/devices/cpu/amis2000/amis2000d.h new file mode 100644 index 00000000000..0de1a455fa8 --- /dev/null +++ b/src/devices/cpu/amis2000/amis2000d.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + AMI S2000-family disassembler + +*/ + +#ifndef MAME_CPU_AMIS2000_AMIS2000D_H +#define MAME_CPU_AMIS2000_AMIS2000D_H + +#pragma once + +class amis2000_disassembler : public util::disasm_interface +{ +public: + amis2000_disassembler() = default; + virtual ~amis2000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + mLAB = 0, mLAE, mLAI, mLBE, mLBEP, mLBF, mLBZ, mXAB, mXABU, mXAE, + mLAM, mXC, mXCI, mXCD, mSTM, mRSM, + mADD, mADCS, mADIS, mAND, mXOR, mCMA, mSTC, mRSC, mSF1, mRF1, mSF2, mRF2, + mSAM, mSZM, mSBE, mSZC, mSOS, mSZK, mSZI, mTF1, mTF2, + mPP, mJMP, mJMS, mRT, mRTS, mNOP, mHALT, + mINP, mOUT, mDISB, mDISN, mMVS, mPSH, mPSL, mEUR + }; + + static const char *const s_mnemonics[]; + static const s8 s_bits[]; + static const u32 s_flags[]; + static const u8 s2000_mnemonic[0x100]; +}; + +#endif diff --git a/src/devices/cpu/apexc/apexc.cpp b/src/devices/cpu/apexc/apexc.cpp index e26c6c094b4..4278d5b2d48 100644 --- a/src/devices/cpu/apexc/apexc.cpp +++ b/src/devices/cpu/apexc/apexc.cpp @@ -327,6 +327,7 @@ field: X address D Function Y address D (part 2) #include "emu.h" #include "apexc.h" +#include "apexcdsm.h" #include "debugger.h" @@ -854,9 +855,7 @@ void apexc_cpu_device::execute_run() } while (m_icount > 0); } - -offs_t apexc_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *apexc_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( apexc ); - return CPU_DISASSEMBLE_NAME(apexc)(this, stream, pc, oprom, opram, options); + return new apexc_disassembler; } diff --git a/src/devices/cpu/apexc/apexc.h b/src/devices/cpu/apexc/apexc.h index 76a91a98207..92cc60d7f09 100644 --- a/src/devices/cpu/apexc/apexc.h +++ b/src/devices/cpu/apexc/apexc.h @@ -40,9 +40,7 @@ protected: virtual void state_import(const device_state_entry &entry) 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; + virtual util::disasm_interface *create_disassembler() override; inline uint32_t apexc_readmem(uint32_t address) { return m_program->read_dword((address)<<2); } inline void apexc_writemem(uint32_t address, uint32_t data) { m_program->write_dword((address)<<2, (data)); } diff --git a/src/devices/cpu/apexc/apexcdsm.cpp b/src/devices/cpu/apexc/apexcdsm.cpp index e3626a40af9..bb581dd2850 100644 --- a/src/devices/cpu/apexc/apexcdsm.cpp +++ b/src/devices/cpu/apexc/apexcdsm.cpp @@ -10,9 +10,7 @@ #include "emu.h" -#include "debugger.h" - -#include "apexc.h" +#include "apexcdsm.h" /* Here is the format used for debugger output. @@ -63,15 +61,8 @@ The X value shows where the data word is located, and the Y value is the address of the next instruction. */ -enum format_type {branch, shiftl, shiftr, multiply, store, swap, one_address, two_address}; - -struct instr_desc -{ - const char *mnemonic; - format_type format; /* -> X and Y are format */ -}; -static const instr_desc instructions[16] = +const apexc_disassembler::instr_desc apexc_disassembler::instructions[16] = { { "Stop", one_address }, { "I", one_address }, { "P", one_address }, { "B", branch }, @@ -83,7 +74,12 @@ static const instr_desc instructions[16] = { "A", store }, { "S", swap } }; -CPU_DISASSEMBLE(apexc) +u32 apexc_disassembler::opcode_alignment() const +{ + return 4; +} + +offs_t apexc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t instruction; /* 32-bit machine instruction */ int x, y, function, c6, vector; /* instruction fields */ @@ -92,7 +88,7 @@ CPU_DISASSEMBLE(apexc) char mnemonic[9]; /* storage for generated mnemonic */ /* read the instruction to disassemble */ - instruction = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3]; + instruction = opcodes.r32(pc); /* isolate the instruction fields */ x = (instruction >> 22) & 0x3FF; diff --git a/src/devices/cpu/apexc/apexcdsm.h b/src/devices/cpu/apexc/apexcdsm.h new file mode 100644 index 00000000000..b310df1f496 --- /dev/null +++ b/src/devices/cpu/apexc/apexcdsm.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Raphael Nabet +/* + cpu/apexc/apexcsm.c : APE(X)C CPU disassembler + + By Raphael Nabet + + see cpu/apexc.c for background and tech info +*/ + +#ifndef MAME_CPU_APEXC_APEXCDSM_H +#define MAME_CPU_APEXC_APEXCDSM_H + +#pragma once + +class apexc_disassembler : public util::disasm_interface +{ +public: + apexc_disassembler() = default; + virtual ~apexc_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum format_type {branch, shiftl, shiftr, multiply, store, swap, one_address, two_address}; + + struct instr_desc + { + const char *mnemonic; + format_type format; /* -> X and Y are format */ + }; + + static const instr_desc instructions[16]; +}; + +#endif diff --git a/src/devices/cpu/arc/arc.cpp b/src/devices/cpu/arc/arc.cpp index eb71302468a..fa421875bd1 100644 --- a/src/devices/cpu/arc/arc.cpp +++ b/src/devices/cpu/arc/arc.cpp @@ -12,6 +12,7 @@ #include "emu.h" #include "debugger.h" #include "arc.h" +#include "arcdasm.h" DEFINE_DEVICE_TYPE(ARC, arc_cpu_device, "arc_a4", "ARCtangent A4") @@ -26,13 +27,11 @@ arc_cpu_device::arc_cpu_device(const machine_config &mconfig, const char *tag, d } -offs_t arc_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *arc_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( arc ); - return CPU_DISASSEMBLE_NAME(arc)(this, stream, pc, oprom, opram, options); + return new arc_disassembler; } - /*****************************************************************************/ /*****************************************************************************/ diff --git a/src/devices/cpu/arc/arc.h b/src/devices/cpu/arc/arc.h index cf244c8f5b2..7bdf1123ec8 100644 --- a/src/devices/cpu/arc/arc.h +++ b/src/devices/cpu/arc/arc.h @@ -43,9 +43,7 @@ protected: virtual void state_export(const device_state_entry &entry) 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/arc/arcdasm.cpp b/src/devices/cpu/arc/arcdasm.cpp index e8c2d425736..fa7b6f2028e 100644 --- a/src/devices/cpu/arc/arcdasm.cpp +++ b/src/devices/cpu/arc/arcdasm.cpp @@ -7,7 +7,7 @@ \*********************************/ #include "emu.h" -#include <stdarg.h> +#include "arcdasm.h" /*****************************************************************************/ @@ -15,7 +15,7 @@ /*****************************************************************************/ -static const char *basic[0x20] = +const char *const arc_disassembler::basic[0x20] = { /* 00 */ "LD r+r", /* 01 */ "LD r+o", @@ -51,7 +51,7 @@ static const char *basic[0x20] = /* 1f */ "MIN" }; -static const char *conditions[0x20] = +const char *arc_disassembler::conditions[0x20] = { /* 00 */ "AL", // (aka RA - Always) /* 01 */ "EQ", // (aka Z - Zero @@ -87,7 +87,7 @@ static const char *conditions[0x20] = /* 1f */ "0x1f Reserved" }; -static const char *delaytype[0x4] = +const char *arc_disassembler::delaytype[0x4] = { "ND", // NO DELAY - execute next instruction only when NOT jumping "D", // always execute next instruction @@ -95,7 +95,7 @@ static const char *delaytype[0x4] = "Res!", // reserved / invalid }; -static const char *regnames[0x40] = +const char *arc_disassembler::regnames[0x40] = { /* 0x00 */ "r00", /* 0x01 */ "r01", @@ -180,10 +180,14 @@ static const char *regnames[0x40] = #define ARC_REGOP_SHIMM ((op & 0x000001ff) >> 0 ) // aka D -CPU_DISASSEMBLE(arc) +u32 arc_disassembler::opcode_alignment() const { - uint32_t op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); - op = big_endianize_int32(op); + return 4; +} + +offs_t arc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint32_t op = opcodes.r32(pc); uint8_t opcode = ARC_OPERATION; @@ -205,5 +209,5 @@ CPU_DISASSEMBLE(arc) break; } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } diff --git a/src/devices/cpu/arc/arcdasm.h b/src/devices/cpu/arc/arcdasm.h new file mode 100644 index 00000000000..a6bfe559f25 --- /dev/null +++ b/src/devices/cpu/arc/arcdasm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/*********************************\ + + ARCtangent A4 disassembler + +\*********************************/ + +#ifndef MAME_CPU_ARC_ARCDASM_H +#define MAME_CPU_ARC_ARCDASM_H + +#pragma once + +class arc_disassembler : public util::disasm_interface +{ +public: + arc_disassembler() = default; + virtual ~arc_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const basic[0x20]; + static const char *conditions[0x20]; + static const char *delaytype[0x4]; + static const char *regnames[0x40]; + +}; + +#endif diff --git a/src/devices/cpu/arcompact/arcompact.cpp b/src/devices/cpu/arcompact/arcompact.cpp index 79ae7c6d6c6..bffbcda8213 100644 --- a/src/devices/cpu/arcompact/arcompact.cpp +++ b/src/devices/cpu/arcompact/arcompact.cpp @@ -21,7 +21,7 @@ #include "emu.h" #include "debugger.h" #include "arcompact.h" -#include "arcompact_common.h" +#include "arcompactdasm.h" DEFINE_DEVICE_TYPE(ARCA5, arcompact_device, "arc_a5", "ARCtangent A5") @@ -64,10 +64,9 @@ device_memory_interface::space_config_vector arcompact_device::memory_space_conf }; } -offs_t arcompact_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *arcompact_device::create_disassembler() { - extern CPU_DISASSEMBLE( arcompact ); - return CPU_DISASSEMBLE_NAME(arcompact)(this, stream, pc, oprom, opram, options); + return new arcompact_disassembler; } @@ -104,7 +103,7 @@ void arcompact_device::device_start() for (int i = 0x100; i < 0x140; i++) { - state_add(i, regnames[i-0x100], m_debugger_temp).callimport().callexport().formatstr("%08X"); + state_add(i, arcompact_disassembler::regnames[i-0x100], m_debugger_temp).callimport().callexport().formatstr("%08X"); } diff --git a/src/devices/cpu/arcompact/arcompact.h b/src/devices/cpu/arcompact/arcompact.h index 0a88fc119bf..fc7d7dbe5dc 100644 --- a/src/devices/cpu/arcompact/arcompact.h +++ b/src/devices/cpu/arcompact/arcompact.h @@ -102,9 +102,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; diff --git a/src/devices/cpu/arcompact/arcompact_common.cpp b/src/devices/cpu/arcompact/arcompact_common.cpp deleted file mode 100644 index f9b74683461..00000000000 --- a/src/devices/cpu/arcompact/arcompact_common.cpp +++ /dev/null @@ -1,527 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:David Haywood -/*********************************\ - - ARCompact Core - -\*********************************/ - -// condition codes (basic ones are the same as arc -const char *conditions[0x20] = -{ - /* 00 */ "AL", // (aka RA - Always) - /* 01 */ "EQ", // (aka Z - Zero - /* 02 */ "NE", // (aka NZ - Non-Zero) - /* 03 */ "PL", // (aka P - Positive) - /* 04 */ "MI", // (aka N - Negative) - /* 05 */ "CS", // (aka C, LO - Carry set / Lower than) (unsigned) - /* 06 */ "CC", // (aka CC, NC, HS - Carry Clear / Higher or Same) (unsigned) - /* 07 */ "VS", // (aka V - Overflow set) - /* 08 */ "VC", // (aka NV - Overflow clear) - /* 09 */ "GT", // ( - Greater than) (signed) - /* 0a */ "GE", // ( - Greater than or Equal) (signed) - /* 0b */ "LT", // ( - Less than) (signed) - /* 0c */ "LE", // ( - Less than or Equal) (signed) - /* 0d */ "HI", // ( - Higher than) (unsigned) - /* 0e */ "LS", // ( - Lower or Same) (unsigned) - /* 0f */ "PNZ",// ( - Positive non-0 value) - /* 10 */ "0x10 Reserved", // possible CPU implementation specifics - /* 11 */ "0x11 Reserved", - /* 12 */ "0x12 Reserved", - /* 13 */ "0x13 Reserved", - /* 14 */ "0x14 Reserved", - /* 15 */ "0x15 Reserved", - /* 16 */ "0x16 Reserved", - /* 17 */ "0x17 Reserved", - /* 18 */ "0x18 Reserved", - /* 19 */ "0x19 Reserved", - /* 1a */ "0x1a Reserved", - /* 1b */ "0x1b Reserved", - /* 1c */ "0x1c Reserved", - /* 1d */ "0x1d Reserved", - /* 1e */ "0x1e Reserved", - /* 1f */ "0x1f Reserved" -}; - -#define UNUSED_REG "unusedreg" - -#define AUX_UNUSED_16 \ - /* 0xxx0 */ UNUSED_REG, /* 0xxx1 */ UNUSED_REG, /* 0xxx2 */ UNUSED_REG, /* 0xxx3 */ UNUSED_REG, /* 0xxx4 */ UNUSED_REG, /* 0xxx5 */ UNUSED_REG, /* 0xxx6 */ UNUSED_REG, /* 0xxx7 */ UNUSED_REG, /* 0xxx8 */ UNUSED_REG, /* 0xxx9 */ UNUSED_REG, /* 0xxxa */ UNUSED_REG, /* 0xxxb */ UNUSED_REG, /* 0xxxc */ UNUSED_REG, /* 0xxxd */ UNUSED_REG, /* 0xxxe */ UNUSED_REG, /* 0xxxf */ UNUSED_REG, - -// the Auxiliary Register set is actually a 2^32 dword address space (so 16 GB / 34-bit) -// this table just allows us to improve the debugger display for some of the common core / internal ones -const char *auxregnames[0x420] = -{ - /* 0x000 */ "STATUS", - /* 0x001 */ "SEMAPHOR", - /* 0x002 */ "LP_START", - /* 0x003 */ "LP_END", - /* 0x004 */ "IDENTITY", - /* 0x005 */ "DEBUG", - /* 0x006 */ "PC", - /* 0x007 */ UNUSED_REG, - /* 0x008 */ UNUSED_REG, - /* 0x009 */ UNUSED_REG, - /* 0x00a */ "STATUS32", - /* 0x00b */ "STATUS32_L1", - /* 0x00c */ "STATUS32_L2", - /* 0x00d */ UNUSED_REG, - /* 0x00e */ UNUSED_REG, - /* 0x00f */ UNUSED_REG, - - /* 0x010 */ UNUSED_REG, - /* 0x011 */ UNUSED_REG, - /* 0x012 */ "MULHI", // extension register - /* 0x013 */ UNUSED_REG, - /* 0x014 */ UNUSED_REG, - /* 0x015 */ UNUSED_REG, - /* 0x016 */ UNUSED_REG, - /* 0x017 */ UNUSED_REG, - /* 0x018 */ UNUSED_REG, - /* 0x019 */ UNUSED_REG, - /* 0x01a */ UNUSED_REG, - /* 0x01b */ UNUSED_REG, - /* 0x01c */ UNUSED_REG, - /* 0x01d */ UNUSED_REG, - /* 0x01e */ UNUSED_REG, - /* 0x01f */ UNUSED_REG, - - /* 0x020 */ UNUSED_REG, - /* 0x021 */ "COUNT0", - /* 0x022 */ "CONTROL0", - /* 0x023 */ "LIMIT0", - /* 0x024 */ UNUSED_REG, - /* 0x025 */ "INT_VECTOR_BASE", - /* 0x026 */ UNUSED_REG, - /* 0x027 */ UNUSED_REG, - /* 0x028 */ UNUSED_REG, - /* 0x029 */ UNUSED_REG, - /* 0x02a */ UNUSED_REG, - /* 0x02b */ UNUSED_REG, - /* 0x02c */ UNUSED_REG, - /* 0x02d */ UNUSED_REG, - /* 0x02e */ UNUSED_REG, - /* 0x02f */ UNUSED_REG, - AUX_UNUSED_16 /* 0x030 - 0x03f */ - /* 0x040 */ UNUSED_REG, - /* 0x041 */ "AUX_MACMODE", - /* 0x042 */ UNUSED_REG, - /* 0x043 */ "AUX_IRQLV12", - /* 0x044 */ UNUSED_REG, - /* 0x045 */ UNUSED_REG, - /* 0x046 */ UNUSED_REG, - /* 0x047 */ UNUSED_REG, - /* 0x048 */ UNUSED_REG, - /* 0x049 */ UNUSED_REG, - /* 0x04a */ UNUSED_REG, - /* 0x04b */ UNUSED_REG, - /* 0x04c */ UNUSED_REG, - /* 0x04d */ UNUSED_REG, - /* 0x04e */ UNUSED_REG, - /* 0x04f */ UNUSED_REG, - AUX_UNUSED_16 /* 0x050 - 0x05f */ - // build configuration registers 0x060 - 0x07f - /* 0x060 */ "RESERVED AUX 0x60",/* 0x061 */ "RESERVED AUX 0x61",/* 0x062 */ "RESERVED AUX 0x62",/* 0x063 */ "RESERVED AUX 0x63",/* 0x064 */ "RESERVED AUX 0x64",/* 0x065 */ "RESERVED AUX 0x65",/* 0x066 */ "RESERVED AUX 0x66",/* 0x067 */ "RESERVED AUX 0x67",/* 0x068 */ "RESERVED AUX 0x68",/* 0x069 */ "RESERVED AUX 0x69",/* 0x06a */ "RESERVED AUX 0x6a",/* 0x06b */ "RESERVED AUX 0x6b",/* 0x06c */ "RESERVED AUX 0x6c",/* 0x06d */ "RESERVED AUX 0x6d",/* 0x06e */ "RESERVED AUX 0x6e",/* 0x06f */ "RESERVED AUX 0x6f", - /* 0x070 */ "RESERVED AUX 0x70",/* 0x071 */ "RESERVED AUX 0x71",/* 0x072 */ "RESERVED AUX 0x72",/* 0x073 */ "RESERVED AUX 0x73",/* 0x074 */ "RESERVED AUX 0x74",/* 0x075 */ "RESERVED AUX 0x75",/* 0x076 */ "RESERVED AUX 0x76",/* 0x077 */ "RESERVED AUX 0x77",/* 0x078 */ "RESERVED AUX 0x78",/* 0x079 */ "RESERVED AUX 0x79",/* 0x07a */ "RESERVED AUX 0x7a",/* 0x07b */ "RESERVED AUX 0x7b",/* 0x07c */ "RESERVED AUX 0x7c",/* 0x07d */ "RESERVED AUX 0x7d",/* 0x07e */ "RESERVED AUX 0x7e",/* 0x07f */ "RESERVED AUX 0x7f", - AUX_UNUSED_16 /* 0x080 - 0x08f */ - AUX_UNUSED_16 /* 0x090 - 0x09f */ - AUX_UNUSED_16 /* 0x0a0 - 0x0af */ - AUX_UNUSED_16 /* 0x0b0 - 0x0bf */ - // build configuration registers 0x0c0 - 0x0ff - /* 0x0c0 */ "RESERVED AUX 0xc0",/* 0x0c1 */ "RESERVED AUX 0xc1",/* 0x0c2 */ "RESERVED AUX 0xc2",/* 0x0c3 */ "RESERVED AUX 0xc3",/* 0x0c4 */ "RESERVED AUX 0xc4",/* 0x0c5 */ "RESERVED AUX 0xc5",/* 0x0c6 */ "RESERVED AUX 0xc6",/* 0x0c7 */ "RESERVED AUX 0xc7",/* 0x0c8 */ "RESERVED AUX 0xc8",/* 0x0c9 */ "RESERVED AUX 0xc9",/* 0x0ca */ "RESERVED AUX 0xca",/* 0x0cb */ "RESERVED AUX 0xcb",/* 0x0cc */ "RESERVED AUX 0xcc",/* 0x0cd */ "RESERVED AUX 0xcd",/* 0x0ce */ "RESERVED AUX 0xce",/* 0x0cf */ "RESERVED AUX 0xcf", - /* 0x0d0 */ "RESERVED AUX 0xd0",/* 0x0d1 */ "RESERVED AUX 0xd1",/* 0x0d2 */ "RESERVED AUX 0xd2",/* 0x0d3 */ "RESERVED AUX 0xd3",/* 0x0d4 */ "RESERVED AUX 0xd4",/* 0x0d5 */ "RESERVED AUX 0xd5",/* 0x0d6 */ "RESERVED AUX 0xd6",/* 0x0d7 */ "RESERVED AUX 0xd7",/* 0x0d8 */ "RESERVED AUX 0xd8",/* 0x0d9 */ "RESERVED AUX 0xd9",/* 0x0da */ "RESERVED AUX 0xda",/* 0x0db */ "RESERVED AUX 0xdb",/* 0x0dc */ "RESERVED AUX 0xdc",/* 0x0dd */ "RESERVED AUX 0xdd",/* 0x0de */ "RESERVED AUX 0xde",/* 0x0df */ "RESERVED AUX 0xdf", - /* 0x0e0 */ "RESERVED AUX 0xe0",/* 0x0e1 */ "RESERVED AUX 0xe1",/* 0x0e2 */ "RESERVED AUX 0xe2",/* 0x0e3 */ "RESERVED AUX 0xe3",/* 0x0e4 */ "RESERVED AUX 0xe4",/* 0x0e5 */ "RESERVED AUX 0xe5",/* 0x0e6 */ "RESERVED AUX 0xe6",/* 0x0e7 */ "RESERVED AUX 0xe7",/* 0x0e8 */ "RESERVED AUX 0xe8",/* 0x0e9 */ "RESERVED AUX 0xe9",/* 0x0ea */ "RESERVED AUX 0xea",/* 0x0eb */ "RESERVED AUX 0xeb",/* 0x0ec */ "RESERVED AUX 0xec",/* 0x0ed */ "RESERVED AUX 0xed",/* 0x0ee */ "RESERVED AUX 0xee",/* 0x0ef */ "RESERVED AUX 0xef", - /* 0x0f0 */ "RESERVED AUX 0xf0",/* 0x0f1 */ "RESERVED AUX 0xf1",/* 0x0f2 */ "RESERVED AUX 0xf2",/* 0x0f3 */ "RESERVED AUX 0xf3",/* 0x0f4 */ "RESERVED AUX 0xf4",/* 0x0f5 */ "RESERVED AUX 0xf5",/* 0x0f6 */ "RESERVED AUX 0xf6",/* 0x0f7 */ "RESERVED AUX 0xf7",/* 0x0f8 */ "RESERVED AUX 0xf8",/* 0x0f9 */ "RESERVED AUX 0xf9",/* 0x0fa */ "RESERVED AUX 0xfa",/* 0x0fb */ "RESERVED AUX 0xfb",/* 0x0fc */ "RESERVED AUX 0xfc",/* 0x0fd */ "RESERVED AUX 0xfd",/* 0x0fe */ "RESERVED AUX 0xfe",/* 0x0ff */ "RESERVED AUX 0xff", - /* 0x100 */ "COUNT1", - /* 0x101 */ "CONTROL1", - /* 0x102 */ "LIMIT1", - /* 0x103 */ UNUSED_REG, - /* 0x104 */ UNUSED_REG, - /* 0x105 */ UNUSED_REG, - /* 0x106 */ UNUSED_REG, - /* 0x107 */ UNUSED_REG, - /* 0x108 */ UNUSED_REG, - /* 0x109 */ UNUSED_REG, - /* 0x10a */ UNUSED_REG, - /* 0x10b */ UNUSED_REG, - /* 0x10c */ UNUSED_REG, - /* 0x10d */ UNUSED_REG, - /* 0x10e */ UNUSED_REG, - /* 0x10f */ UNUSED_REG, - AUX_UNUSED_16 /* 0x110 - 0x11f */ - AUX_UNUSED_16 /* 0x120 - 0x12f */ - AUX_UNUSED_16 /* 0x130 - 0x13f */ - AUX_UNUSED_16 /* 0x140 - 0x14f */ - AUX_UNUSED_16 /* 0x150 - 0x15f */ - AUX_UNUSED_16 /* 0x160 - 0x16f */ - AUX_UNUSED_16 /* 0x170 - 0x17f */ - AUX_UNUSED_16 /* 0x180 - 0x18f */ - AUX_UNUSED_16 /* 0x190 - 0x19f */ - AUX_UNUSED_16 /* 0x1a0 - 0x1af */ - AUX_UNUSED_16 /* 0x1b0 - 0x1bf */ - AUX_UNUSED_16 /* 0x1c0 - 0x1cf */ - AUX_UNUSED_16 /* 0x1d0 - 0x1df */ - AUX_UNUSED_16 /* 0x1e0 - 0x1ef */ - AUX_UNUSED_16 /* 0x1f0 - 0x1ff */ - /* 0x200 */ "AUX_IRQ_LEV", - /* 0x201 */ "AUX_IRQ_HINT", - /* 0x203 */ UNUSED_REG, - /* 0x203 */ UNUSED_REG, - /* 0x204 */ UNUSED_REG, - /* 0x205 */ UNUSED_REG, - /* 0x206 */ UNUSED_REG, - /* 0x207 */ UNUSED_REG, - /* 0x208 */ UNUSED_REG, - /* 0x209 */ UNUSED_REG, - /* 0x20a */ UNUSED_REG, - /* 0x20b */ UNUSED_REG, - /* 0x20c */ UNUSED_REG, - /* 0x20d */ UNUSED_REG, - /* 0x20e */ UNUSED_REG, - /* 0x20f */ UNUSED_REG, - AUX_UNUSED_16 /* 0x210 - 0x21f */ - AUX_UNUSED_16 /* 0x220 - 0x22f */ - AUX_UNUSED_16 /* 0x230 - 0x23f */ - AUX_UNUSED_16 /* 0x240 - 0x24f */ - AUX_UNUSED_16 /* 0x250 - 0x25f */ - AUX_UNUSED_16 /* 0x260 - 0x26f */ - AUX_UNUSED_16 /* 0x270 - 0x27f */ - AUX_UNUSED_16 /* 0x280 - 0x28f */ - AUX_UNUSED_16 /* 0x290 - 0x29f */ - AUX_UNUSED_16 /* 0x2a0 - 0x2af */ - AUX_UNUSED_16 /* 0x2b0 - 0x2bf */ - AUX_UNUSED_16 /* 0x2c0 - 0x2cf */ - AUX_UNUSED_16 /* 0x2d0 - 0x2df */ - AUX_UNUSED_16 /* 0x2e0 - 0x2ef */ - AUX_UNUSED_16 /* 0x2f0 - 0x2ff */ - - AUX_UNUSED_16 /* 0x300 - 0x30f */ - AUX_UNUSED_16 /* 0x310 - 0x31f */ - AUX_UNUSED_16 /* 0x320 - 0x32f */ - AUX_UNUSED_16 /* 0x330 - 0x33f */ - AUX_UNUSED_16 /* 0x340 - 0x34f */ - AUX_UNUSED_16 /* 0x350 - 0x35f */ - AUX_UNUSED_16 /* 0x360 - 0x36f */ - AUX_UNUSED_16 /* 0x370 - 0x37f */ - AUX_UNUSED_16 /* 0x380 - 0x38f */ - AUX_UNUSED_16 /* 0x390 - 0x39f */ - AUX_UNUSED_16 /* 0x3a0 - 0x3af */ - AUX_UNUSED_16 /* 0x3b0 - 0x3bf */ - AUX_UNUSED_16 /* 0x3c0 - 0x3cf */ - AUX_UNUSED_16 /* 0x3d0 - 0x3df */ - AUX_UNUSED_16 /* 0x3e0 - 0x3ef */ - AUX_UNUSED_16 /* 0x3f0 - 0x3ff */ - - /* 0x400 */ "ERET", - /* 0x401 */ "ERBTA", - /* 0x403 */ "ERSTATUS", - /* 0x403 */ "ECR", - /* 0x404 */ "EFA", - /* 0x405 */ UNUSED_REG, - /* 0x406 */ UNUSED_REG, - /* 0x407 */ UNUSED_REG, - /* 0x408 */ UNUSED_REG, - /* 0x409 */ UNUSED_REG, - /* 0x40a */ "ICAUSE1", - /* 0x40b */ "ICAUSE2", - /* 0x40c */ "AUX_IENABLE", - /* 0x40d */ "AUX_ITRIGGER", - /* 0x40e */ UNUSED_REG, - /* 0x40f */ UNUSED_REG, - - /* 0x410 */ "XPU", - /* 0x411 */ UNUSED_REG, - /* 0x412 */ "BTA", - /* 0x413 */ "BTA_L1", - /* 0x414 */ "BTA_L2", - /* 0x415 */ "AUX_IRQ_PULSE_CANCEL", - /* 0x416 */ "AUX_IRQ_PENDING", - /* 0x417 */ UNUSED_REG, - /* 0x418 */ UNUSED_REG, - /* 0x419 */ UNUSED_REG, - /* 0x41a */ UNUSED_REG, - /* 0x41b */ UNUSED_REG, - /* 0x41c */ UNUSED_REG, - /* 0x41d */ UNUSED_REG, - /* 0x41e */ UNUSED_REG, - /* 0x41f */ UNUSED_REG -}; - -//#define EXPLICIT_EXTENSIONS - -const char *datasize[0x4] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".L", // Dword (default) (can use no extension, using .L to be explicit) -#else - /* 00 */ "",// Dword (default) -#endif - /* 01 */ ".B", // Byte - /* 02 */ ".W", // Word - /* 03 */ ".<illegal data size>" -}; - -const char *dataextend[0x2] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".ZX", // Zero Extend (can use no extension, using .ZX to be explicit) -#else - /* 00 */ "", // Zero Extend -#endif - /* 01 */ ".X" // Sign Extend -}; - -const char *addressmode[0x4] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".AN", // No Writeback (can use no extension, using .AN to be explicit) -#else - /* 00 */ "", // No Writeback -#endif - /* 01 */ ".AW", // Writeback pre memory access - /* 02 */ ".AB", // Writeback post memory access - /* 03 */ ".AS" // scaled -}; - -const char *cachebit[0x2] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".EN", // Data Cache Enabled (can use no extension, using .EN to be explicit) -#else - /* 00 */ "", // Data Cache Enabled -#endif - /* 01 */ ".DI" // Direct to Memory (Cache Bypass) -}; - -const char *flagbit[0x2] = -{ -#ifdef EXPLICIT_EXTENSIONS - /* 00 */ ".NF", // Don't Set Flags (can use no extension, using .NF to be explicit) -#else - /* 00 */ "", // Don't Set Flags -#endif - /* 01 */ ".F" // Set Flags -}; - -const char *delaybit[0x2] = -{ - /* 00 */ ".ND", // Don't execute opcode in delay slot - /* 01 */ ".D" // Execute Opcode in delay slot -}; - - -const char *regnames[0x40] = -{ - /* 00 */ "r0", - /* 01 */ "r1", - /* 02 */ "r2", - /* 03 */ "r3", - /* 04 */ "r4", - /* 05 */ "r5", - /* 06 */ "r6", - /* 07 */ "r7", - /* 08 */ "r8", - /* 09 */ "r9", - /* 0a */ "r10", - /* 0b */ "r11", - /* 0c */ "r12", - /* 0d */ "r13", - /* 0e */ "r14", - /* 0f */ "r15", - - /* 10 */ "r16", - /* 11 */ "r17", - /* 12 */ "r18", - /* 13 */ "r19", - /* 14 */ "r20", - /* 15 */ "r21", - /* 16 */ "r22", - /* 17 */ "r23", - /* 18 */ "r24", - /* 19 */ "r25", - /* 1a */ "r26_GP", - /* 1b */ "r27_FP", - /* 1c */ "r28_SP", - /* 1d */ "r29_ILINK1", - /* 1e */ "r30_ILINK2", - /* 1f */ "r31_BLINK", - - /* 20 */ "r32(ext)", - /* 21 */ "r33(ext)", - /* 22 */ "r34(ext)", - /* 23 */ "r35(ext)", - /* 24 */ "r36(ext)", - /* 25 */ "r37(ext)", - /* 26 */ "r38(ext)", - /* 27 */ "r39(ext)", - /* 28 */ "r40(ext)", - /* 29 */ "r41(ext)", - /* 2a */ "r42(ext)", - /* 2b */ "r43(ext)", - /* 2c */ "r44(ext)", - /* 2d */ "r45(ext)", - /* 2e */ "r46(ext)", - /* 2f */ "r47(ext)", - - /* 30 */ "r48(ext)", - /* 31 */ "r49(ext)", - /* 32 */ "r50(ext)", - /* 33 */ "r51(ext)", - /* 34 */ "r52(ext)", - /* 35 */ "r53(ext)", - /* 36 */ "r54(ext)", - /* 37 */ "r55(ext)", - /* 38 */ "r56(ext)", - /* 39 */ "r57(M-LO)", // MLO (result registers for optional multply functions) - /* 3a */ "r58(M-MID)", // MMID - /* 3b */ "r59(M-HI)", // MHI - /* 3c */ "r60(LP_COUNT)", - /* 3d */ "r61(reserved)", - /* 3e */ "r62(LIMM)", // use Long Immediate Data instead of register - /* 3f */ "r63(PCL)" -}; - -#if 0 -const char *opcodes_temp[0x40] = -{ - /* 00 */ "0x00", - /* 01 */ "0x01", - /* 02 */ "0x02", - /* 03 */ "0x03", - /* 04 */ "0x04", - /* 05 */ "0x05", - /* 06 */ "0x06", - /* 07 */ "0x07", - /* 08 */ "0x08", - /* 09 */ "0x09", - /* 0a */ "0x0a", - /* 0b */ "0x0b", - /* 0c */ "0x0c", - /* 0d */ "0x0d", - /* 0e */ "0x0e", - /* 0f */ "0x0f", - - /* 10 */ "0x10", - /* 11 */ "0x11", - /* 12 */ "0x12", - /* 13 */ "0x13", - /* 14 */ "0x14", - /* 15 */ "0x15", - /* 16 */ "0x16", - /* 17 */ "0x17", - /* 18 */ "0x18", - /* 19 */ "0x19", - /* 1a */ "0x1a", - /* 1b */ "0x1b", - /* 1c */ "0x1c", - /* 1d */ "0x1d", - /* 1e */ "0x1e", - /* 1f */ "0x1f", - - /* 20 */ "0x20", - /* 21 */ "0x21", - /* 22 */ "0x22", - /* 23 */ "0x23", - /* 24 */ "0x24", - /* 25 */ "0x25", - /* 26 */ "0x26", - /* 27 */ "0x27", - /* 28 */ "0x28", - /* 29 */ "0x29", - /* 2a */ "0x2a", - /* 2b */ "0x2b", - /* 2c */ "0x2c", - /* 2d */ "0x2d", - /* 2e */ "0x2e", - /* 2f */ "0x2f", - - /* 30 */ "0x30", - /* 31 */ "0x31", - /* 32 */ "0x32", - /* 33 */ "0x33", - /* 34 */ "0x34", - /* 35 */ "0x35", - /* 36 */ "0x36", - /* 37 */ "0x37", - /* 38 */ "0x38", - /* 39 */ "0x39", - /* 3a */ "0x3a", - /* 3b */ "0x3b", - /* 3c */ "0x3c", - /* 3d */ "0x3d", - /* 3e */ "0x3e", - /* 3f */ "0x3f", -}; -#endif - - -const char *opcodes_04[0x40] = -{ - /* 00 */ "ADD", - /* 01 */ "ADC", - /* 02 */ "SUB", - /* 03 */ "SBC", - /* 04 */ "AND", - /* 05 */ "OR", - /* 06 */ "BIC", - /* 07 */ "XOR", - /* 08 */ "MAX", - /* 09 */ "MIN", - /* 0a */ "MOV", - /* 0b */ "TST", - /* 0c */ "CMP", - /* 0d */ "RCMP", - /* 0e */ "RSUB", - /* 0f */ "BSET", - - /* 10 */ "BCLR", - /* 11 */ "BTST", - /* 12 */ "BXOR", - /* 13 */ "BSMK", - /* 14 */ "ADD1", - /* 15 */ "ADD2", - /* 16 */ "ADD3", - /* 17 */ "SUB1", - /* 18 */ "SUB2", - /* 19 */ "SUB3", - /* 1a */ "MPY", - /* 1b */ "MPYH", - /* 1c */ "MPYHU", - /* 1d */ "MPYU", - /* 1e */ "0x1e", - /* 1f */ "0x1f", - - /* 20 */ "Jcc", - /* 21 */ "Jcc.D", - /* 22 */ "JLcc", - /* 23 */ "JLcc.D", - /* 24 */ "0x24", - /* 25 */ "0x25", - /* 26 */ "0x26", - /* 27 */ "0x27", - /* 28 */ "LPcc", - /* 29 */ "FLAG", - /* 2a */ "LR", - /* 2b */ "SR", - /* 2c */ "0x2c", - /* 2d */ "0x2d", - /* 2e */ "0x2e", - /* 2f */ "SOP table", - - /* 30 */ "LD", - /* 31 */ "LD", - /* 32 */ "LD", - /* 33 */ "LD", - /* 34 */ "LD", - /* 35 */ "LD", - /* 36 */ "LD", - /* 37 */ "LD", - /* 38 */ "0x38", - /* 39 */ "0x39", - /* 3a */ "0x3a", - /* 3b */ "0x3b", - /* 3c */ "0x3c", - /* 3d */ "0x3d", - /* 3e */ "0x3e", - /* 3f */ "0x3f", -}; diff --git a/src/devices/cpu/arcompact/arcompact_common.h b/src/devices/cpu/arcompact/arcompact_common.h deleted file mode 100644 index 86259ba2972..00000000000 --- a/src/devices/cpu/arcompact/arcompact_common.h +++ /dev/null @@ -1,24 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:David Haywood -/*********************************\ - - ARCompact Core - -\*********************************/ - -extern const char *conditions[0x20]; -extern const char *auxregnames[0x420]; -extern const char *datasize[0x4]; -extern const char *dataextend[0x2]; -extern const char *addressmode[0x4]; -extern const char *cachebit[0x2]; -extern const char *flagbit[0x2]; -extern const char *delaybit[0x2]; -extern const char *regnames[0x40]; -extern const char *opcodes_04[0x40]; - -#define REG_BLINK (0x1f) // r31 -#define REG_SP (0x1c) // r28 -#define REG_ILINK1 (0x1d) // r29 -#define REG_ILINK2 (0x1e) // r30 -#define REG_LP_COUNT (0x3c) // r60 diff --git a/src/devices/cpu/arcompact/arcompact_execute.cpp b/src/devices/cpu/arcompact/arcompact_execute.cpp index 53d3ce742cb..fc4dcca37a6 100644 --- a/src/devices/cpu/arcompact/arcompact_execute.cpp +++ b/src/devices/cpu/arcompact/arcompact_execute.cpp @@ -4,7 +4,13 @@ #include "emu.h" #include "debugger.h" #include "arcompact.h" -#include "arcompact_common.h" +#include "arcompactdasm.h" + +#define REG_BLINK (0x1f) // r31 +#define REG_SP (0x1c) // r28 +#define REG_ILINK1 (0x1d) // r29 +#define REG_ILINK2 (0x1e) // r30 +#define REG_LP_COUNT (0x3c) // r60 #define ARCOMPACT_LOGGING 1 @@ -128,35 +134,35 @@ int arcompact_device::check_condition(uint8_t condition) case 0x00: return 1; // AL case 0x01: return CONDITION_EQ; case 0x02: return !CONDITION_EQ; // NE - case 0x03: fatalerror("unhandled condition check %s", conditions[condition]); return -1; + case 0x03: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; case 0x04: return CONDITION_MI; // MI (N) case 0x05: return CONDITION_CS; // CS (Carry Set / Lower than) - case 0x06: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x07: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x08: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x09: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0a: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0b: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0c: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0d: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0e: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x0f: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x10: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x11: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x12: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x13: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x14: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x15: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x16: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x17: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x18: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x19: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1a: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1b: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1c: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1d: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1e: fatalerror("unhandled condition check %s", conditions[condition]); return -1; - case 0x1f: fatalerror("unhandled condition check %s", conditions[condition]); return -1; + case 0x06: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x07: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x08: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x09: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0a: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0b: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0c: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0d: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0e: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x0f: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x10: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x11: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x12: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x13: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x14: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x15: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x16: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x17: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x18: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x19: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1a: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1b: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1c: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1d: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1e: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; + case 0x1f: fatalerror("unhandled condition check %s", arcompact_disassembler::conditions[condition]); return -1; } return -1; @@ -1844,58 +1850,58 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_helper(OPS_32, const char ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_01(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x01], /*"ADC"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x01], /*"ADC"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_03(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x03], /*"SBC"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x03], /*"SBC"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_08(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x08], /*"MAX"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x08], /*"MAX"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_09(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x09], /*"MIN"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x09], /*"MIN"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_0b(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x0b], /*"TST"*/ 1,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x0b], /*"TST"*/ 1,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_0c(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x0c], /*"CMP"*/ 1,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x0c], /*"CMP"*/ 1,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_0d(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x0d], /*"RCMP"*/ 1,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x0d], /*"RCMP"*/ 1,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_10(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x10], /*"BCLR"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x10], /*"BCLR"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_11(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x11], /*"BTST"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x11], /*"BTST"*/ 0,0); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_12(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x12], /*"BXOR"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x12], /*"BXOR"*/ 0,0); } @@ -1905,22 +1911,22 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_12(OPS_32) ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_1a(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x1a], /*"MPY"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x1a], /*"MPY"*/ 0,0); } // * ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_1b(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x1b], /*"MPYH"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x1b], /*"MPYH"*/ 0,0); } // * ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_1c(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x1c], /*"MPYHU"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x1c], /*"MPYHU"*/ 0,0); } // * ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_1d(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x1d], /*"MPYU"*/ 0,0); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x1d], /*"MPYU"*/ 0,0); } // * ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_20_p00(OPS_32) @@ -2202,12 +2208,12 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_21_p11_m1(OPS_32) ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_22(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x22], /*"JL"*/ 1,1); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x22], /*"JL"*/ 1,1); } ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_23(OPS_32) { - return arcompact_handle04_helper(PARAMS, opcodes_04[0x23], /*"JL.D"*/ 1,1); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x23], /*"JL.D"*/ 1,1); } @@ -2238,7 +2244,7 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_28(OPS_32) // LPcc (loop { // 0010 0RRR 1110 1000 0RRR uuuu uu1Q QQQQ COMMON32_GET_u6 COMMON32_GET_CONDITION - //arcompact_fatal("Lp conditional %s not supported %d", conditions[condition], u); + //arcompact_fatal("Lp conditional %s not supported %d", arcompact_disassembler::conditions[condition], u); // if the loop condition fails then just jump to after the end of the loop, don't set any registers if (!check_condition(condition)) @@ -2264,7 +2270,7 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_28(OPS_32) // LPcc (loop ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_29(OPS_32) { // leapster bios uses formats for FLAG that are not defined, bug I guess work anyway (P modes 0 / 1) - return arcompact_handle04_helper(PARAMS, opcodes_04[0x29], /*"FLAG"*/ 1,1); + return arcompact_handle04_helper(PARAMS, arcompact_disassembler::opcodes_04[0x29], /*"FLAG"*/ 1,1); } diff --git a/src/devices/cpu/arcompact/arcompactdasm.cpp b/src/devices/cpu/arcompact/arcompactdasm.cpp index cd557017332..7283cfd06b6 100644 --- a/src/devices/cpu/arcompact/arcompactdasm.cpp +++ b/src/devices/cpu/arcompact/arcompactdasm.cpp @@ -7,51 +7,564 @@ \*********************************/ #include "emu.h" -#include <stdarg.h> +#include "arcompactdasm.h" -#include "arcompactdasm_dispatch.h" -#include "arcompactdasm_ops.h" +u32 arcompact_disassembler::opcode_alignment() const +{ + return 2; +} + + +// condition codes (basic ones are the same as arc +const char *const arcompact_disassembler::conditions[0x20] = +{ + /* 00 */ "AL", // (aka RA - Always) + /* 01 */ "EQ", // (aka Z - Zero + /* 02 */ "NE", // (aka NZ - Non-Zero) + /* 03 */ "PL", // (aka P - Positive) + /* 04 */ "MI", // (aka N - Negative) + /* 05 */ "CS", // (aka C, LO - Carry set / Lower than) (unsigned) + /* 06 */ "CC", // (aka CC, NC, HS - Carry Clear / Higher or Same) (unsigned) + /* 07 */ "VS", // (aka V - Overflow set) + /* 08 */ "VC", // (aka NV - Overflow clear) + /* 09 */ "GT", // ( - Greater than) (signed) + /* 0a */ "GE", // ( - Greater than or Equal) (signed) + /* 0b */ "LT", // ( - Less than) (signed) + /* 0c */ "LE", // ( - Less than or Equal) (signed) + /* 0d */ "HI", // ( - Higher than) (unsigned) + /* 0e */ "LS", // ( - Lower or Same) (unsigned) + /* 0f */ "PNZ",// ( - Positive non-0 value) + /* 10 */ "0x10 Reserved", // possible CPU implementation specifics + /* 11 */ "0x11 Reserved", + /* 12 */ "0x12 Reserved", + /* 13 */ "0x13 Reserved", + /* 14 */ "0x14 Reserved", + /* 15 */ "0x15 Reserved", + /* 16 */ "0x16 Reserved", + /* 17 */ "0x17 Reserved", + /* 18 */ "0x18 Reserved", + /* 19 */ "0x19 Reserved", + /* 1a */ "0x1a Reserved", + /* 1b */ "0x1b Reserved", + /* 1c */ "0x1c Reserved", + /* 1d */ "0x1d Reserved", + /* 1e */ "0x1e Reserved", + /* 1f */ "0x1f Reserved" +}; + +#define UNUSED_REG "unusedreg" + +#define AUX_UNUSED_16 \ + /* 0xxx0 */ UNUSED_REG, /* 0xxx1 */ UNUSED_REG, /* 0xxx2 */ UNUSED_REG, /* 0xxx3 */ UNUSED_REG, /* 0xxx4 */ UNUSED_REG, /* 0xxx5 */ UNUSED_REG, /* 0xxx6 */ UNUSED_REG, /* 0xxx7 */ UNUSED_REG, /* 0xxx8 */ UNUSED_REG, /* 0xxx9 */ UNUSED_REG, /* 0xxxa */ UNUSED_REG, /* 0xxxb */ UNUSED_REG, /* 0xxxc */ UNUSED_REG, /* 0xxxd */ UNUSED_REG, /* 0xxxe */ UNUSED_REG, /* 0xxxf */ UNUSED_REG, + +// the Auxiliary Register set is actually a 2^32 dword address space (so 16 GB / 34-bit) +// this table just allows us to improve the debugger display for some of the common core / internal ones +const char *const arcompact_disassembler::auxregnames[0x420] = +{ + /* 0x000 */ "STATUS", + /* 0x001 */ "SEMAPHOR", + /* 0x002 */ "LP_START", + /* 0x003 */ "LP_END", + /* 0x004 */ "IDENTITY", + /* 0x005 */ "DEBUG", + /* 0x006 */ "PC", + /* 0x007 */ UNUSED_REG, + /* 0x008 */ UNUSED_REG, + /* 0x009 */ UNUSED_REG, + /* 0x00a */ "STATUS32", + /* 0x00b */ "STATUS32_L1", + /* 0x00c */ "STATUS32_L2", + /* 0x00d */ UNUSED_REG, + /* 0x00e */ UNUSED_REG, + /* 0x00f */ UNUSED_REG, + + /* 0x010 */ UNUSED_REG, + /* 0x011 */ UNUSED_REG, + /* 0x012 */ "MULHI", // extension register + /* 0x013 */ UNUSED_REG, + /* 0x014 */ UNUSED_REG, + /* 0x015 */ UNUSED_REG, + /* 0x016 */ UNUSED_REG, + /* 0x017 */ UNUSED_REG, + /* 0x018 */ UNUSED_REG, + /* 0x019 */ UNUSED_REG, + /* 0x01a */ UNUSED_REG, + /* 0x01b */ UNUSED_REG, + /* 0x01c */ UNUSED_REG, + /* 0x01d */ UNUSED_REG, + /* 0x01e */ UNUSED_REG, + /* 0x01f */ UNUSED_REG, + /* 0x020 */ UNUSED_REG, + /* 0x021 */ "COUNT0", + /* 0x022 */ "CONTROL0", + /* 0x023 */ "LIMIT0", + /* 0x024 */ UNUSED_REG, + /* 0x025 */ "INT_VECTOR_BASE", + /* 0x026 */ UNUSED_REG, + /* 0x027 */ UNUSED_REG, + /* 0x028 */ UNUSED_REG, + /* 0x029 */ UNUSED_REG, + /* 0x02a */ UNUSED_REG, + /* 0x02b */ UNUSED_REG, + /* 0x02c */ UNUSED_REG, + /* 0x02d */ UNUSED_REG, + /* 0x02e */ UNUSED_REG, + /* 0x02f */ UNUSED_REG, + AUX_UNUSED_16 /* 0x030 - 0x03f */ + /* 0x040 */ UNUSED_REG, + /* 0x041 */ "AUX_MACMODE", + /* 0x042 */ UNUSED_REG, + /* 0x043 */ "AUX_IRQLV12", + /* 0x044 */ UNUSED_REG, + /* 0x045 */ UNUSED_REG, + /* 0x046 */ UNUSED_REG, + /* 0x047 */ UNUSED_REG, + /* 0x048 */ UNUSED_REG, + /* 0x049 */ UNUSED_REG, + /* 0x04a */ UNUSED_REG, + /* 0x04b */ UNUSED_REG, + /* 0x04c */ UNUSED_REG, + /* 0x04d */ UNUSED_REG, + /* 0x04e */ UNUSED_REG, + /* 0x04f */ UNUSED_REG, + AUX_UNUSED_16 /* 0x050 - 0x05f */ + // build configuration registers 0x060 - 0x07f + /* 0x060 */ "RESERVED AUX 0x60",/* 0x061 */ "RESERVED AUX 0x61",/* 0x062 */ "RESERVED AUX 0x62",/* 0x063 */ "RESERVED AUX 0x63",/* 0x064 */ "RESERVED AUX 0x64",/* 0x065 */ "RESERVED AUX 0x65",/* 0x066 */ "RESERVED AUX 0x66",/* 0x067 */ "RESERVED AUX 0x67",/* 0x068 */ "RESERVED AUX 0x68",/* 0x069 */ "RESERVED AUX 0x69",/* 0x06a */ "RESERVED AUX 0x6a",/* 0x06b */ "RESERVED AUX 0x6b",/* 0x06c */ "RESERVED AUX 0x6c",/* 0x06d */ "RESERVED AUX 0x6d",/* 0x06e */ "RESERVED AUX 0x6e",/* 0x06f */ "RESERVED AUX 0x6f", + /* 0x070 */ "RESERVED AUX 0x70",/* 0x071 */ "RESERVED AUX 0x71",/* 0x072 */ "RESERVED AUX 0x72",/* 0x073 */ "RESERVED AUX 0x73",/* 0x074 */ "RESERVED AUX 0x74",/* 0x075 */ "RESERVED AUX 0x75",/* 0x076 */ "RESERVED AUX 0x76",/* 0x077 */ "RESERVED AUX 0x77",/* 0x078 */ "RESERVED AUX 0x78",/* 0x079 */ "RESERVED AUX 0x79",/* 0x07a */ "RESERVED AUX 0x7a",/* 0x07b */ "RESERVED AUX 0x7b",/* 0x07c */ "RESERVED AUX 0x7c",/* 0x07d */ "RESERVED AUX 0x7d",/* 0x07e */ "RESERVED AUX 0x7e",/* 0x07f */ "RESERVED AUX 0x7f", + AUX_UNUSED_16 /* 0x080 - 0x08f */ + AUX_UNUSED_16 /* 0x090 - 0x09f */ + AUX_UNUSED_16 /* 0x0a0 - 0x0af */ + AUX_UNUSED_16 /* 0x0b0 - 0x0bf */ + // build configuration registers 0x0c0 - 0x0ff + /* 0x0c0 */ "RESERVED AUX 0xc0",/* 0x0c1 */ "RESERVED AUX 0xc1",/* 0x0c2 */ "RESERVED AUX 0xc2",/* 0x0c3 */ "RESERVED AUX 0xc3",/* 0x0c4 */ "RESERVED AUX 0xc4",/* 0x0c5 */ "RESERVED AUX 0xc5",/* 0x0c6 */ "RESERVED AUX 0xc6",/* 0x0c7 */ "RESERVED AUX 0xc7",/* 0x0c8 */ "RESERVED AUX 0xc8",/* 0x0c9 */ "RESERVED AUX 0xc9",/* 0x0ca */ "RESERVED AUX 0xca",/* 0x0cb */ "RESERVED AUX 0xcb",/* 0x0cc */ "RESERVED AUX 0xcc",/* 0x0cd */ "RESERVED AUX 0xcd",/* 0x0ce */ "RESERVED AUX 0xce",/* 0x0cf */ "RESERVED AUX 0xcf", + /* 0x0d0 */ "RESERVED AUX 0xd0",/* 0x0d1 */ "RESERVED AUX 0xd1",/* 0x0d2 */ "RESERVED AUX 0xd2",/* 0x0d3 */ "RESERVED AUX 0xd3",/* 0x0d4 */ "RESERVED AUX 0xd4",/* 0x0d5 */ "RESERVED AUX 0xd5",/* 0x0d6 */ "RESERVED AUX 0xd6",/* 0x0d7 */ "RESERVED AUX 0xd7",/* 0x0d8 */ "RESERVED AUX 0xd8",/* 0x0d9 */ "RESERVED AUX 0xd9",/* 0x0da */ "RESERVED AUX 0xda",/* 0x0db */ "RESERVED AUX 0xdb",/* 0x0dc */ "RESERVED AUX 0xdc",/* 0x0dd */ "RESERVED AUX 0xdd",/* 0x0de */ "RESERVED AUX 0xde",/* 0x0df */ "RESERVED AUX 0xdf", + /* 0x0e0 */ "RESERVED AUX 0xe0",/* 0x0e1 */ "RESERVED AUX 0xe1",/* 0x0e2 */ "RESERVED AUX 0xe2",/* 0x0e3 */ "RESERVED AUX 0xe3",/* 0x0e4 */ "RESERVED AUX 0xe4",/* 0x0e5 */ "RESERVED AUX 0xe5",/* 0x0e6 */ "RESERVED AUX 0xe6",/* 0x0e7 */ "RESERVED AUX 0xe7",/* 0x0e8 */ "RESERVED AUX 0xe8",/* 0x0e9 */ "RESERVED AUX 0xe9",/* 0x0ea */ "RESERVED AUX 0xea",/* 0x0eb */ "RESERVED AUX 0xeb",/* 0x0ec */ "RESERVED AUX 0xec",/* 0x0ed */ "RESERVED AUX 0xed",/* 0x0ee */ "RESERVED AUX 0xee",/* 0x0ef */ "RESERVED AUX 0xef", + /* 0x0f0 */ "RESERVED AUX 0xf0",/* 0x0f1 */ "RESERVED AUX 0xf1",/* 0x0f2 */ "RESERVED AUX 0xf2",/* 0x0f3 */ "RESERVED AUX 0xf3",/* 0x0f4 */ "RESERVED AUX 0xf4",/* 0x0f5 */ "RESERVED AUX 0xf5",/* 0x0f6 */ "RESERVED AUX 0xf6",/* 0x0f7 */ "RESERVED AUX 0xf7",/* 0x0f8 */ "RESERVED AUX 0xf8",/* 0x0f9 */ "RESERVED AUX 0xf9",/* 0x0fa */ "RESERVED AUX 0xfa",/* 0x0fb */ "RESERVED AUX 0xfb",/* 0x0fc */ "RESERVED AUX 0xfc",/* 0x0fd */ "RESERVED AUX 0xfd",/* 0x0fe */ "RESERVED AUX 0xfe",/* 0x0ff */ "RESERVED AUX 0xff", + /* 0x100 */ "COUNT1", + /* 0x101 */ "CONTROL1", + /* 0x102 */ "LIMIT1", + /* 0x103 */ UNUSED_REG, + /* 0x104 */ UNUSED_REG, + /* 0x105 */ UNUSED_REG, + /* 0x106 */ UNUSED_REG, + /* 0x107 */ UNUSED_REG, + /* 0x108 */ UNUSED_REG, + /* 0x109 */ UNUSED_REG, + /* 0x10a */ UNUSED_REG, + /* 0x10b */ UNUSED_REG, + /* 0x10c */ UNUSED_REG, + /* 0x10d */ UNUSED_REG, + /* 0x10e */ UNUSED_REG, + /* 0x10f */ UNUSED_REG, + AUX_UNUSED_16 /* 0x110 - 0x11f */ + AUX_UNUSED_16 /* 0x120 - 0x12f */ + AUX_UNUSED_16 /* 0x130 - 0x13f */ + AUX_UNUSED_16 /* 0x140 - 0x14f */ + AUX_UNUSED_16 /* 0x150 - 0x15f */ + AUX_UNUSED_16 /* 0x160 - 0x16f */ + AUX_UNUSED_16 /* 0x170 - 0x17f */ + AUX_UNUSED_16 /* 0x180 - 0x18f */ + AUX_UNUSED_16 /* 0x190 - 0x19f */ + AUX_UNUSED_16 /* 0x1a0 - 0x1af */ + AUX_UNUSED_16 /* 0x1b0 - 0x1bf */ + AUX_UNUSED_16 /* 0x1c0 - 0x1cf */ + AUX_UNUSED_16 /* 0x1d0 - 0x1df */ + AUX_UNUSED_16 /* 0x1e0 - 0x1ef */ + AUX_UNUSED_16 /* 0x1f0 - 0x1ff */ + /* 0x200 */ "AUX_IRQ_LEV", + /* 0x201 */ "AUX_IRQ_HINT", + /* 0x203 */ UNUSED_REG, + /* 0x203 */ UNUSED_REG, + /* 0x204 */ UNUSED_REG, + /* 0x205 */ UNUSED_REG, + /* 0x206 */ UNUSED_REG, + /* 0x207 */ UNUSED_REG, + /* 0x208 */ UNUSED_REG, + /* 0x209 */ UNUSED_REG, + /* 0x20a */ UNUSED_REG, + /* 0x20b */ UNUSED_REG, + /* 0x20c */ UNUSED_REG, + /* 0x20d */ UNUSED_REG, + /* 0x20e */ UNUSED_REG, + /* 0x20f */ UNUSED_REG, + AUX_UNUSED_16 /* 0x210 - 0x21f */ + AUX_UNUSED_16 /* 0x220 - 0x22f */ + AUX_UNUSED_16 /* 0x230 - 0x23f */ + AUX_UNUSED_16 /* 0x240 - 0x24f */ + AUX_UNUSED_16 /* 0x250 - 0x25f */ + AUX_UNUSED_16 /* 0x260 - 0x26f */ + AUX_UNUSED_16 /* 0x270 - 0x27f */ + AUX_UNUSED_16 /* 0x280 - 0x28f */ + AUX_UNUSED_16 /* 0x290 - 0x29f */ + AUX_UNUSED_16 /* 0x2a0 - 0x2af */ + AUX_UNUSED_16 /* 0x2b0 - 0x2bf */ + AUX_UNUSED_16 /* 0x2c0 - 0x2cf */ + AUX_UNUSED_16 /* 0x2d0 - 0x2df */ + AUX_UNUSED_16 /* 0x2e0 - 0x2ef */ + AUX_UNUSED_16 /* 0x2f0 - 0x2ff */ -/*****************************************************************************/ + AUX_UNUSED_16 /* 0x300 - 0x30f */ + AUX_UNUSED_16 /* 0x310 - 0x31f */ + AUX_UNUSED_16 /* 0x320 - 0x32f */ + AUX_UNUSED_16 /* 0x330 - 0x33f */ + AUX_UNUSED_16 /* 0x340 - 0x34f */ + AUX_UNUSED_16 /* 0x350 - 0x35f */ + AUX_UNUSED_16 /* 0x360 - 0x36f */ + AUX_UNUSED_16 /* 0x370 - 0x37f */ + AUX_UNUSED_16 /* 0x380 - 0x38f */ + AUX_UNUSED_16 /* 0x390 - 0x39f */ + AUX_UNUSED_16 /* 0x3a0 - 0x3af */ + AUX_UNUSED_16 /* 0x3b0 - 0x3bf */ + AUX_UNUSED_16 /* 0x3c0 - 0x3cf */ + AUX_UNUSED_16 /* 0x3d0 - 0x3df */ + AUX_UNUSED_16 /* 0x3e0 - 0x3ef */ + AUX_UNUSED_16 /* 0x3f0 - 0x3ff */ + /* 0x400 */ "ERET", + /* 0x401 */ "ERBTA", + /* 0x403 */ "ERSTATUS", + /* 0x403 */ "ECR", + /* 0x404 */ "EFA", + /* 0x405 */ UNUSED_REG, + /* 0x406 */ UNUSED_REG, + /* 0x407 */ UNUSED_REG, + /* 0x408 */ UNUSED_REG, + /* 0x409 */ UNUSED_REG, + /* 0x40a */ "ICAUSE1", + /* 0x40b */ "ICAUSE2", + /* 0x40c */ "AUX_IENABLE", + /* 0x40d */ "AUX_ITRIGGER", + /* 0x40e */ UNUSED_REG, + /* 0x40f */ UNUSED_REG, + /* 0x410 */ "XPU", + /* 0x411 */ UNUSED_REG, + /* 0x412 */ "BTA", + /* 0x413 */ "BTA_L1", + /* 0x414 */ "BTA_L2", + /* 0x415 */ "AUX_IRQ_PULSE_CANCEL", + /* 0x416 */ "AUX_IRQ_PENDING", + /* 0x417 */ UNUSED_REG, + /* 0x418 */ UNUSED_REG, + /* 0x419 */ UNUSED_REG, + /* 0x41a */ UNUSED_REG, + /* 0x41b */ UNUSED_REG, + /* 0x41c */ UNUSED_REG, + /* 0x41d */ UNUSED_REG, + /* 0x41e */ UNUSED_REG, + /* 0x41f */ UNUSED_REG +}; + +//#define EXPLICIT_EXTENSIONS + +const char *const arcompact_disassembler::datasize[0x4] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".L", // Dword (default) (can use no extension, using .L to be explicit) +#else + /* 00 */ "",// Dword (default) +#endif + /* 01 */ ".B", // Byte + /* 02 */ ".W", // Word + /* 03 */ ".<illegal data size>" +}; + +const char *const arcompact_disassembler::dataextend[0x2] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".ZX", // Zero Extend (can use no extension, using .ZX to be explicit) +#else + /* 00 */ "", // Zero Extend +#endif + /* 01 */ ".X" // Sign Extend +}; + +const char *const arcompact_disassembler::addressmode[0x4] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".AN", // No Writeback (can use no extension, using .AN to be explicit) +#else + /* 00 */ "", // No Writeback +#endif + /* 01 */ ".AW", // Writeback pre memory access + /* 02 */ ".AB", // Writeback post memory access + /* 03 */ ".AS" // scaled +}; + +const char *const arcompact_disassembler::cachebit[0x2] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".EN", // Data Cache Enabled (can use no extension, using .EN to be explicit) +#else + /* 00 */ "", // Data Cache Enabled +#endif + /* 01 */ ".DI" // Direct to Memory (Cache Bypass) +}; + +const char *const arcompact_disassembler::flagbit[0x2] = +{ +#ifdef EXPLICIT_EXTENSIONS + /* 00 */ ".NF", // Don't Set Flags (can use no extension, using .NF to be explicit) +#else + /* 00 */ "", // Don't Set Flags +#endif + /* 01 */ ".F" // Set Flags +}; + +const char *const arcompact_disassembler::delaybit[0x2] = +{ + /* 00 */ ".ND", // Don't execute opcode in delay slot + /* 01 */ ".D" // Execute Opcode in delay slot +}; + + +const char *const arcompact_disassembler::regnames[0x40] = +{ + /* 00 */ "r0", + /* 01 */ "r1", + /* 02 */ "r2", + /* 03 */ "r3", + /* 04 */ "r4", + /* 05 */ "r5", + /* 06 */ "r6", + /* 07 */ "r7", + /* 08 */ "r8", + /* 09 */ "r9", + /* 0a */ "r10", + /* 0b */ "r11", + /* 0c */ "r12", + /* 0d */ "r13", + /* 0e */ "r14", + /* 0f */ "r15", + + /* 10 */ "r16", + /* 11 */ "r17", + /* 12 */ "r18", + /* 13 */ "r19", + /* 14 */ "r20", + /* 15 */ "r21", + /* 16 */ "r22", + /* 17 */ "r23", + /* 18 */ "r24", + /* 19 */ "r25", + /* 1a */ "r26_GP", + /* 1b */ "r27_FP", + /* 1c */ "r28_SP", + /* 1d */ "r29_ILINK1", + /* 1e */ "r30_ILINK2", + /* 1f */ "r31_BLINK", + + /* 20 */ "r32(ext)", + /* 21 */ "r33(ext)", + /* 22 */ "r34(ext)", + /* 23 */ "r35(ext)", + /* 24 */ "r36(ext)", + /* 25 */ "r37(ext)", + /* 26 */ "r38(ext)", + /* 27 */ "r39(ext)", + /* 28 */ "r40(ext)", + /* 29 */ "r41(ext)", + /* 2a */ "r42(ext)", + /* 2b */ "r43(ext)", + /* 2c */ "r44(ext)", + /* 2d */ "r45(ext)", + /* 2e */ "r46(ext)", + /* 2f */ "r47(ext)", + + /* 30 */ "r48(ext)", + /* 31 */ "r49(ext)", + /* 32 */ "r50(ext)", + /* 33 */ "r51(ext)", + /* 34 */ "r52(ext)", + /* 35 */ "r53(ext)", + /* 36 */ "r54(ext)", + /* 37 */ "r55(ext)", + /* 38 */ "r56(ext)", + /* 39 */ "r57(M-LO)", // MLO (result registers for optional multply functions) + /* 3a */ "r58(M-MID)", // MMID + /* 3b */ "r59(M-HI)", // MHI + /* 3c */ "r60(LP_COUNT)", + /* 3d */ "r61(reserved)", + /* 3e */ "r62(LIMM)", // use Long Immediate Data instead of register + /* 3f */ "r63(PCL)" +}; + +#if 0 +const char *const arcompact_disassembler::opcodes_temp[0x40] = +{ + /* 00 */ "0x00", + /* 01 */ "0x01", + /* 02 */ "0x02", + /* 03 */ "0x03", + /* 04 */ "0x04", + /* 05 */ "0x05", + /* 06 */ "0x06", + /* 07 */ "0x07", + /* 08 */ "0x08", + /* 09 */ "0x09", + /* 0a */ "0x0a", + /* 0b */ "0x0b", + /* 0c */ "0x0c", + /* 0d */ "0x0d", + /* 0e */ "0x0e", + /* 0f */ "0x0f", + + /* 10 */ "0x10", + /* 11 */ "0x11", + /* 12 */ "0x12", + /* 13 */ "0x13", + /* 14 */ "0x14", + /* 15 */ "0x15", + /* 16 */ "0x16", + /* 17 */ "0x17", + /* 18 */ "0x18", + /* 19 */ "0x19", + /* 1a */ "0x1a", + /* 1b */ "0x1b", + /* 1c */ "0x1c", + /* 1d */ "0x1d", + /* 1e */ "0x1e", + /* 1f */ "0x1f", + + /* 20 */ "0x20", + /* 21 */ "0x21", + /* 22 */ "0x22", + /* 23 */ "0x23", + /* 24 */ "0x24", + /* 25 */ "0x25", + /* 26 */ "0x26", + /* 27 */ "0x27", + /* 28 */ "0x28", + /* 29 */ "0x29", + /* 2a */ "0x2a", + /* 2b */ "0x2b", + /* 2c */ "0x2c", + /* 2d */ "0x2d", + /* 2e */ "0x2e", + /* 2f */ "0x2f", + + /* 30 */ "0x30", + /* 31 */ "0x31", + /* 32 */ "0x32", + /* 33 */ "0x33", + /* 34 */ "0x34", + /* 35 */ "0x35", + /* 36 */ "0x36", + /* 37 */ "0x37", + /* 38 */ "0x38", + /* 39 */ "0x39", + /* 3a */ "0x3a", + /* 3b */ "0x3b", + /* 3c */ "0x3c", + /* 3d */ "0x3d", + /* 3e */ "0x3e", + /* 3f */ "0x3f", +}; +#endif + + +const char *const arcompact_disassembler::opcodes_04[0x40] = +{ + /* 00 */ "ADD", + /* 01 */ "ADC", + /* 02 */ "SUB", + /* 03 */ "SBC", + /* 04 */ "AND", + /* 05 */ "OR", + /* 06 */ "BIC", + /* 07 */ "XOR", + /* 08 */ "MAX", + /* 09 */ "MIN", + /* 0a */ "MOV", + /* 0b */ "TST", + /* 0c */ "CMP", + /* 0d */ "RCMP", + /* 0e */ "RSUB", + /* 0f */ "BSET", -/*****************************************************************************/ + /* 10 */ "BCLR", + /* 11 */ "BTST", + /* 12 */ "BXOR", + /* 13 */ "BSMK", + /* 14 */ "ADD1", + /* 15 */ "ADD2", + /* 16 */ "ADD3", + /* 17 */ "SUB1", + /* 18 */ "SUB2", + /* 19 */ "SUB3", + /* 1a */ "MPY", + /* 1b */ "MPYH", + /* 1c */ "MPYHU", + /* 1d */ "MPYU", + /* 1e */ "0x1e", + /* 1f */ "0x1f", + /* 20 */ "Jcc", + /* 21 */ "Jcc.D", + /* 22 */ "JLcc", + /* 23 */ "JLcc.D", + /* 24 */ "0x24", + /* 25 */ "0x25", + /* 26 */ "0x26", + /* 27 */ "0x27", + /* 28 */ "LPcc", + /* 29 */ "FLAG", + /* 2a */ "LR", + /* 2b */ "SR", + /* 2c */ "0x2c", + /* 2d */ "0x2d", + /* 2e */ "0x2e", + /* 2f */ "SOP table", -#define ARCOMPACT_OPERATION ((op & 0xf800) >> 11) + /* 30 */ "LD", + /* 31 */ "LD", + /* 32 */ "LD", + /* 33 */ "LD", + /* 34 */ "LD", + /* 35 */ "LD", + /* 36 */ "LD", + /* 37 */ "LD", + /* 38 */ "0x38", + /* 39 */ "0x39", + /* 3a */ "0x3a", + /* 3b */ "0x3b", + /* 3c */ "0x3c", + /* 3d */ "0x3d", + /* 3e */ "0x3e", + /* 3f */ "0x3f", +}; -CPU_DISASSEMBLE(arcompact) +offs_t arcompact_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int size; - uint32_t op = oprom[0] | (oprom[1] << 8); + uint32_t op = opcodes.r16(pc); - uint8_t instruction = ARCOMPACT_OPERATION; + uint8_t instruction = ((op & 0xf800) >> 11); if (instruction < 0x0c) { size = 4; op <<= 16; - op |= oprom[2] | (oprom[3] << 8); + op |= opcodes.r16(pc+2); op &= ~0xf8000000; switch (instruction) // 32-bit instructions (with optional extra dword for immediate data) { - case 0x00: size = arcompact_handle00_dasm(DASM_PARAMS); break; // Bcc - case 0x01: size = arcompact_handle01_dasm(DASM_PARAMS); break; // BLcc/BRcc - case 0x02: size = arcompact_handle02_dasm(DASM_PARAMS); break; // LD r+o - case 0x03: size = arcompact_handle03_dasm(DASM_PARAMS); break; // ST r+o - case 0x04: size = arcompact_handle04_dasm(DASM_PARAMS); break; // op a,b,c (basecase) - case 0x05: size = arcompact_handle05_dasm(DASM_PARAMS); break; // op a,b,c (05 ARC ext) - case 0x06: size = arcompact_handle06_dasm(DASM_PARAMS); break; // op a,b,c (06 ARC ext) - case 0x07: size = arcompact_handle07_dasm(DASM_PARAMS); break; // op a,b,c (07 User ext) - case 0x08: size = arcompact_handle08_dasm(DASM_PARAMS); break; // op a,b,c (08 User ext) - case 0x09: size = arcompact_handle09_dasm(DASM_PARAMS); break; // op a,b,c (09 Market ext) - case 0x0a: size = arcompact_handle0a_dasm(DASM_PARAMS); break; // op a,b,c (0a Market ext) - case 0x0b: size = arcompact_handle0b_dasm(DASM_PARAMS); break; // op a,b,c (0b Market ext) + case 0x00: size = handle00_dasm(stream, pc, op, opcodes); break; // Bcc + case 0x01: size = handle01_dasm(stream, pc, op, opcodes); break; // BLcc/BRcc + case 0x02: size = handle02_dasm(stream, pc, op, opcodes); break; // LD r+o + case 0x03: size = handle03_dasm(stream, pc, op, opcodes); break; // ST r+o + case 0x04: size = handle04_dasm(stream, pc, op, opcodes); break; // op a,b,c (basecase) + case 0x05: size = handle05_dasm(stream, pc, op, opcodes); break; // op a,b,c (05 ARC ext) + case 0x06: size = handle06_dasm(stream, pc, op, opcodes); break; // op a,b,c (06 ARC ext) + case 0x07: size = handle07_dasm(stream, pc, op, opcodes); break; // op a,b,c (07 User ext) + case 0x08: size = handle08_dasm(stream, pc, op, opcodes); break; // op a,b,c (08 User ext) + case 0x09: size = handle09_dasm(stream, pc, op, opcodes); break; // op a,b,c (09 Market ext) + case 0x0a: size = handle0a_dasm(stream, pc, op, opcodes); break; // op a,b,c (0a Market ext) + case 0x0b: size = handle0b_dasm(stream, pc, op, opcodes); break; // op a,b,c (0b Market ext) } } else @@ -62,28 +575,28 @@ CPU_DISASSEMBLE(arcompact) switch (instruction) // 16-bit instructions { - case 0x0c: size = arcompact_handle0c_dasm(DASM_PARAMS); break; // Load/Add reg-reg - case 0x0d: size = arcompact_handle0d_dasm(DASM_PARAMS); break; // Add/Sub/Shft imm - case 0x0e: size = arcompact_handle0e_dasm(DASM_PARAMS); break; // Mov/Cmp/Add - case 0x0f: size = arcompact_handle0f_dasm(DASM_PARAMS); break; // op_S b,b,c (single 16-bit ops) - case 0x10: size = arcompact_handle10_dasm(DASM_PARAMS); break; // LD_S - case 0x11: size = arcompact_handle11_dasm(DASM_PARAMS); break; // LDB_S - case 0x12: size = arcompact_handle12_dasm(DASM_PARAMS); break; // LDW_S - case 0x13: size = arcompact_handle13_dasm(DASM_PARAMS); break; // LSW_S.X - case 0x14: size = arcompact_handle14_dasm(DASM_PARAMS); break; // ST_S - case 0x15: size = arcompact_handle15_dasm(DASM_PARAMS); break; // STB_S - case 0x16: size = arcompact_handle16_dasm(DASM_PARAMS); break; // STW_S - case 0x17: size = arcompact_handle17_dasm(DASM_PARAMS); break; // Shift/Sub/Bit - case 0x18: size = arcompact_handle18_dasm(DASM_PARAMS); break; // Stack Instr - case 0x19: size = arcompact_handle19_dasm(DASM_PARAMS); break; // GP Instr - case 0x1a: size = arcompact_handle1a_dasm(DASM_PARAMS); break; // PCL Instr - case 0x1b: size = arcompact_handle1b_dasm(DASM_PARAMS); break; // MOV_S - case 0x1c: size = arcompact_handle1c_dasm(DASM_PARAMS); break; // ADD_S/CMP_S - case 0x1d: size = arcompact_handle1d_dasm(DASM_PARAMS); break; // BRcc_S - case 0x1e: size = arcompact_handle1e_dasm(DASM_PARAMS); break; // Bcc_S - case 0x1f: size = arcompact_handle1f_dasm(DASM_PARAMS); break; // BL_S + case 0x0c: size = handle0c_dasm(stream, pc, op, opcodes); break; // Load/Add reg-reg + case 0x0d: size = handle0d_dasm(stream, pc, op, opcodes); break; // Add/Sub/Shft imm + case 0x0e: size = handle0e_dasm(stream, pc, op, opcodes); break; // Mov/Cmp/Add + case 0x0f: size = handle0f_dasm(stream, pc, op, opcodes); break; // op_S b,b,c (single 16-bit ops) + case 0x10: size = handle10_dasm(stream, pc, op, opcodes); break; // LD_S + case 0x11: size = handle11_dasm(stream, pc, op, opcodes); break; // LDB_S + case 0x12: size = handle12_dasm(stream, pc, op, opcodes); break; // LDW_S + case 0x13: size = handle13_dasm(stream, pc, op, opcodes); break; // LSW_S.X + case 0x14: size = handle14_dasm(stream, pc, op, opcodes); break; // ST_S + case 0x15: size = handle15_dasm(stream, pc, op, opcodes); break; // STB_S + case 0x16: size = handle16_dasm(stream, pc, op, opcodes); break; // STW_S + case 0x17: size = handle17_dasm(stream, pc, op, opcodes); break; // Shift/Sub/Bit + case 0x18: size = handle18_dasm(stream, pc, op, opcodes); break; // Stack Instr + case 0x19: size = handle19_dasm(stream, pc, op, opcodes); break; // GP Instr + case 0x1a: size = handle1a_dasm(stream, pc, op, opcodes); break; // PCL Instr + case 0x1b: size = handle1b_dasm(stream, pc, op, opcodes); break; // MOV_S + case 0x1c: size = handle1c_dasm(stream, pc, op, opcodes); break; // ADD_S/CMP_S + case 0x1d: size = handle1d_dasm(stream, pc, op, opcodes); break; // BRcc_S + case 0x1e: size = handle1e_dasm(stream, pc, op, opcodes); break; // Bcc_S + case 0x1f: size = handle1f_dasm(stream, pc, op, opcodes); break; // BL_S } } - return size | DASMFLAG_SUPPORTED; + return size | SUPPORTED; } diff --git a/src/devices/cpu/arcompact/arcompactdasm.h b/src/devices/cpu/arcompact/arcompactdasm.h new file mode 100644 index 00000000000..7594c673a0d --- /dev/null +++ b/src/devices/cpu/arcompact/arcompactdasm.h @@ -0,0 +1,721 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/*********************************\ + + ARCompact disassembler + +\*********************************/ + + +#ifndef MAME_CPU_ARCOMPACT_ARCOMPACTDASM_H +#define MAME_CPU_ARCOMPACT_ARCOMPACTDASM_H + +#pragma once + +class arcompact_disassembler : public util::disasm_interface +{ +public: + arcompact_disassembler() = default; + virtual ~arcompact_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + static const char *const conditions[0x20]; + static const char *const auxregnames[0x420]; + static const char *const datasize[0x4]; + static const char *const dataextend[0x2]; + static const char *const addressmode[0x4]; + static const char *const cachebit[0x2]; + static const char *const flagbit[0x2]; + static const char *const delaybit[0x2]; + static const char *const regnames[0x40]; + static const char *const opcodes_04[0x40]; + +private: + int handle01_01_00_helper(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext); + int handle01_01_01_helper(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext); + + int handle04_p00_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved); + int handle04_p01_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved); + int handle04_p10_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved); + int handle04_p11_m0_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved); + int handle04_p11_m1_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved); + int handle04_p11_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved); + int handle04_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved); + int handle04_2f_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext); + int handle04_3x_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, int dsize, int extend); + int handle05_2f_0x_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext); + int handle0c_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int format); + int handle0d_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle0e_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int revop); + int handle0f_00_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle0f_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int nodst); + int handle_ld_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int shift, int swap); + int handle_l7_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle18_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int st, int format); + int handle19_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int shift, int format); + int handle1d_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle1e_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + int handle1e_03_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext); + + int handle00_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle00_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_00_00dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_00_01dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle0c_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0c_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0c_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0c_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1c_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1c_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1d_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1d_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + + /************************************************************************************************************************************ + * * + * illegal opcode handlers (disassembly) * + * * + ************************************************************************************************************************************/ + + int handle01_01_00_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle01_01_01_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + + int handle04_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle04_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle04_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle04_2f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle04_2f_3f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_2f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_2f_3f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + + int handle04_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle0f_00_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + + int handle18_05_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + + + + + int handle00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle01_01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle04_2f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + int handle05_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + int handle05_2f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes); + + + int handle0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle0f_00_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle18_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + int handle1e_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes); + +}; + +#endif diff --git a/src/devices/cpu/arcompact/arcompactdasm_dispatch.cpp b/src/devices/cpu/arcompact/arcompactdasm_dispatch.cpp index 769a8604fc8..f9b296baf34 100644 --- a/src/devices/cpu/arcompact/arcompactdasm_dispatch.cpp +++ b/src/devices/cpu/arcompact/arcompactdasm_dispatch.cpp @@ -7,12 +7,9 @@ \*********************************/ #include "emu.h" -#include <stdarg.h> +#include "arcompactdasm.h" -#include "arcompactdasm_dispatch.h" -#include "arcompactdasm_ops.h" - -int arcompact_handle00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr = (op & 0x00010000) >> 16; @@ -20,14 +17,14 @@ int arcompact_handle00_dasm(DASM_OPS_32) switch (subinstr) { - case 0x00: size = arcompact_handle00_00_dasm(DASM_PARAMS); break; // Branch Conditionally - case 0x01: size = arcompact_handle00_01_dasm(DASM_PARAMS); break; // Branch Unconditionally Far + case 0x00:size = handle00_00_dasm(stream, pc, op, opcodes); break; // Branch Conditionally + case 0x01:size = handle00_01_dasm(stream, pc, op, opcodes); break; // Branch Unconditionally Far } return size; } -int arcompact_handle01_dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr = (op & 0x00010000) >> 16; @@ -35,14 +32,14 @@ int arcompact_handle01_dasm(DASM_OPS_32) switch (subinstr) { - case 0x00: size = arcompact_handle01_00_dasm(DASM_PARAMS); break; // Branh & Link - case 0x01: size = arcompact_handle01_01_dasm(DASM_PARAMS); break; // Branch on Compare + case 0x00:size = handle01_00_dasm(stream, pc, op, opcodes); break; // Branh & Link + case 0x01:size = handle01_01_dasm(stream, pc, op, opcodes); break; // Branch on Compare } return size; } -int arcompact_handle01_00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr2 = (op & 0x00020000) >> 17; @@ -50,14 +47,14 @@ int arcompact_handle01_00_dasm(DASM_OPS_32) switch (subinstr2) { - case 0x00: size = arcompact_handle01_00_00dasm(DASM_PARAMS); break; // Branch and Link Conditionally - case 0x01: size = arcompact_handle01_00_01dasm(DASM_PARAMS); break; // Branch and Link Unconditional Far + case 0x00:size = handle01_00_00dasm(stream, pc, op, opcodes); break; // Branch and Link Conditionally + case 0x01:size = handle01_00_01dasm(stream, pc, op, opcodes); break; // Branch and Link Unconditional Far } return size; } -int arcompact_handle01_01_dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; @@ -66,14 +63,14 @@ int arcompact_handle01_01_dasm(DASM_OPS_32) switch (subinstr2) { - case 0x00: size = arcompact_handle01_01_00_dasm(DASM_PARAMS); break; // Branch on Compare Register-Register - case 0x01: size = arcompact_handle01_01_01_dasm(DASM_PARAMS); break; // Branch on Compare/Bit Test Register-Immediate + case 0x00:size = handle01_01_00_dasm(stream, pc, op, opcodes); break; // Branch on Compare Register-Register + case 0x01:size = handle01_01_01_dasm(stream, pc, op, opcodes); break; // Branch on Compare/Bit Test Register-Immediate } return size; } -int arcompact_handle01_01_00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr3 = (op & 0x0000000f) >> 0; @@ -81,28 +78,28 @@ int arcompact_handle01_01_00_dasm(DASM_OPS_32) switch (subinstr3) { - case 0x00: size = arcompact_handle01_01_00_00_dasm(DASM_PARAMS); break; // BREQ (reg-reg) - case 0x01: size = arcompact_handle01_01_00_01_dasm(DASM_PARAMS); break; // BRNE (reg-reg) - case 0x02: size = arcompact_handle01_01_00_02_dasm(DASM_PARAMS); break; // BRLT (reg-reg) - case 0x03: size = arcompact_handle01_01_00_03_dasm(DASM_PARAMS); break; // BRGE (reg-reg) - case 0x04: size = arcompact_handle01_01_00_04_dasm(DASM_PARAMS); break; // BRLO (reg-reg) - case 0x05: size = arcompact_handle01_01_00_05_dasm(DASM_PARAMS); break; // BRHS (reg-reg) - case 0x06: size = arcompact_handle01_01_00_06_dasm(DASM_PARAMS); break; // reserved - case 0x07: size = arcompact_handle01_01_00_07_dasm(DASM_PARAMS); break; // reserved - case 0x08: size = arcompact_handle01_01_00_08_dasm(DASM_PARAMS); break; // reserved - case 0x09: size = arcompact_handle01_01_00_09_dasm(DASM_PARAMS); break; // reserved - case 0x0a: size = arcompact_handle01_01_00_0a_dasm(DASM_PARAMS); break; // reserved - case 0x0b: size = arcompact_handle01_01_00_0b_dasm(DASM_PARAMS); break; // reserved - case 0x0c: size = arcompact_handle01_01_00_0c_dasm(DASM_PARAMS); break; // reserved - case 0x0d: size = arcompact_handle01_01_00_0d_dasm(DASM_PARAMS); break; // reserved - case 0x0e: size = arcompact_handle01_01_00_0e_dasm(DASM_PARAMS); break; // BBIT0 (reg-reg) - case 0x0f: size = arcompact_handle01_01_00_0f_dasm(DASM_PARAMS); break; // BBIT1 (reg-reg) + case 0x00:size = handle01_01_00_00_dasm(stream, pc, op, opcodes); break; // BREQ (reg-reg) + case 0x01:size = handle01_01_00_01_dasm(stream, pc, op, opcodes); break; // BRNE (reg-reg) + case 0x02:size = handle01_01_00_02_dasm(stream, pc, op, opcodes); break; // BRLT (reg-reg) + case 0x03:size = handle01_01_00_03_dasm(stream, pc, op, opcodes); break; // BRGE (reg-reg) + case 0x04:size = handle01_01_00_04_dasm(stream, pc, op, opcodes); break; // BRLO (reg-reg) + case 0x05:size = handle01_01_00_05_dasm(stream, pc, op, opcodes); break; // BRHS (reg-reg) + case 0x06:size = handle01_01_00_06_dasm(stream, pc, op, opcodes); break; // reserved + case 0x07:size = handle01_01_00_07_dasm(stream, pc, op, opcodes); break; // reserved + case 0x08:size = handle01_01_00_08_dasm(stream, pc, op, opcodes); break; // reserved + case 0x09:size = handle01_01_00_09_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0a:size = handle01_01_00_0a_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0b:size = handle01_01_00_0b_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0c:size = handle01_01_00_0c_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0d:size = handle01_01_00_0d_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0e:size = handle01_01_00_0e_dasm(stream, pc, op, opcodes); break; // BBIT0 (reg-reg) + case 0x0f:size = handle01_01_00_0f_dasm(stream, pc, op, opcodes); break; // BBIT1 (reg-reg) } return size; } -int arcompact_handle01_01_01_dasm(DASM_OPS_32) // Branch on Compare/Bit Test Register-Immediate +int arcompact_disassembler::handle01_01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // Branch on Compare/Bit Test Register-Immediate { int size = 4; uint8_t subinstr3 = (op & 0x0000000f) >> 0; @@ -110,28 +107,28 @@ int arcompact_handle01_01_01_dasm(DASM_OPS_32) // Branch on Compare/Bit Test Re switch (subinstr3) { - case 0x00: size = arcompact_handle01_01_01_00_dasm(DASM_PARAMS); break; // BREQ (reg-imm) - case 0x01: size = arcompact_handle01_01_01_01_dasm(DASM_PARAMS); break; // BRNE (reg-imm) - case 0x02: size = arcompact_handle01_01_01_02_dasm(DASM_PARAMS); break; // BRLT (reg-imm) - case 0x03: size = arcompact_handle01_01_01_03_dasm(DASM_PARAMS); break; // BRGE (reg-imm) - case 0x04: size = arcompact_handle01_01_01_04_dasm(DASM_PARAMS); break; // BRLO (reg-imm) - case 0x05: size = arcompact_handle01_01_01_05_dasm(DASM_PARAMS); break; // BRHS (reg-imm) - case 0x06: size = arcompact_handle01_01_01_06_dasm(DASM_PARAMS); break; // reserved - case 0x07: size = arcompact_handle01_01_01_07_dasm(DASM_PARAMS); break; // reserved - case 0x08: size = arcompact_handle01_01_01_08_dasm(DASM_PARAMS); break; // reserved - case 0x09: size = arcompact_handle01_01_01_09_dasm(DASM_PARAMS); break; // reserved - case 0x0a: size = arcompact_handle01_01_01_0a_dasm(DASM_PARAMS); break; // reserved - case 0x0b: size = arcompact_handle01_01_01_0b_dasm(DASM_PARAMS); break; // reserved - case 0x0c: size = arcompact_handle01_01_01_0c_dasm(DASM_PARAMS); break; // reserved - case 0x0d: size = arcompact_handle01_01_01_0d_dasm(DASM_PARAMS); break; // reserved - case 0x0e: size = arcompact_handle01_01_01_0e_dasm(DASM_PARAMS); break; // BBIT0 (reg-imm) - case 0x0f: size = arcompact_handle01_01_01_0f_dasm(DASM_PARAMS); break; // BBIT1 (reg-imm) + case 0x00:size = handle01_01_01_00_dasm(stream, pc, op, opcodes); break; // BREQ (reg-imm) + case 0x01:size = handle01_01_01_01_dasm(stream, pc, op, opcodes); break; // BRNE (reg-imm) + case 0x02:size = handle01_01_01_02_dasm(stream, pc, op, opcodes); break; // BRLT (reg-imm) + case 0x03:size = handle01_01_01_03_dasm(stream, pc, op, opcodes); break; // BRGE (reg-imm) + case 0x04:size = handle01_01_01_04_dasm(stream, pc, op, opcodes); break; // BRLO (reg-imm) + case 0x05:size = handle01_01_01_05_dasm(stream, pc, op, opcodes); break; // BRHS (reg-imm) + case 0x06:size = handle01_01_01_06_dasm(stream, pc, op, opcodes); break; // reserved + case 0x07:size = handle01_01_01_07_dasm(stream, pc, op, opcodes); break; // reserved + case 0x08:size = handle01_01_01_08_dasm(stream, pc, op, opcodes); break; // reserved + case 0x09:size = handle01_01_01_09_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0a:size = handle01_01_01_0a_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0b:size = handle01_01_01_0b_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0c:size = handle01_01_01_0c_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0d:size = handle01_01_01_0d_dasm(stream, pc, op, opcodes); break; // reserved + case 0x0e:size = handle01_01_01_0e_dasm(stream, pc, op, opcodes); break; // BBIT0 (reg-imm) + case 0x0f:size = handle01_01_01_0f_dasm(stream, pc, op, opcodes); break; // BBIT1 (reg-imm) } return size; } -int arcompact_handle04_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; // General Operations @@ -151,76 +148,76 @@ int arcompact_handle04_dasm(DASM_OPS_32) switch (subinstr) { - case 0x00: size = arcompact_handle04_00_dasm(DASM_PARAMS); break; // ADD - case 0x01: size = arcompact_handle04_01_dasm(DASM_PARAMS); break; // ADC - case 0x02: size = arcompact_handle04_02_dasm(DASM_PARAMS); break; // SUB - case 0x03: size = arcompact_handle04_03_dasm(DASM_PARAMS); break; // SBC - case 0x04: size = arcompact_handle04_04_dasm(DASM_PARAMS); break; // AND - case 0x05: size = arcompact_handle04_05_dasm(DASM_PARAMS); break; // OR - case 0x06: size = arcompact_handle04_06_dasm(DASM_PARAMS); break; // BIC - case 0x07: size = arcompact_handle04_07_dasm(DASM_PARAMS); break; // XOR - case 0x08: size = arcompact_handle04_08_dasm(DASM_PARAMS); break; // MAX - case 0x09: size = arcompact_handle04_09_dasm(DASM_PARAMS); break; // MIN - case 0x0a: size = arcompact_handle04_0a_dasm(DASM_PARAMS); break; // MOV - case 0x0b: size = arcompact_handle04_0b_dasm(DASM_PARAMS); break; // TST - case 0x0c: size = arcompact_handle04_0c_dasm(DASM_PARAMS); break; // CMP - case 0x0d: size = arcompact_handle04_0d_dasm(DASM_PARAMS); break; // RCMP - case 0x0e: size = arcompact_handle04_0e_dasm(DASM_PARAMS); break; // RSUB - case 0x0f: size = arcompact_handle04_0f_dasm(DASM_PARAMS); break; // BSET - case 0x10: size = arcompact_handle04_10_dasm(DASM_PARAMS); break; // BCLR - case 0x11: size = arcompact_handle04_11_dasm(DASM_PARAMS); break; // BTST - case 0x12: size = arcompact_handle04_12_dasm(DASM_PARAMS); break; // BXOR - case 0x13: size = arcompact_handle04_13_dasm(DASM_PARAMS); break; // BMSK - case 0x14: size = arcompact_handle04_14_dasm(DASM_PARAMS); break; // ADD1 - case 0x15: size = arcompact_handle04_15_dasm(DASM_PARAMS); break; // ADD2 - case 0x16: size = arcompact_handle04_16_dasm(DASM_PARAMS); break; // ADD3 - case 0x17: size = arcompact_handle04_17_dasm(DASM_PARAMS); break; // SUB1 - case 0x18: size = arcompact_handle04_18_dasm(DASM_PARAMS); break; // SUB2 - case 0x19: size = arcompact_handle04_19_dasm(DASM_PARAMS); break; // SUB3 - case 0x1a: size = arcompact_handle04_1a_dasm(DASM_PARAMS); break; // MPY * - case 0x1b: size = arcompact_handle04_1b_dasm(DASM_PARAMS); break; // MPYH * - case 0x1c: size = arcompact_handle04_1c_dasm(DASM_PARAMS); break; // MPYHU * - case 0x1d: size = arcompact_handle04_1d_dasm(DASM_PARAMS); break; // MPYU * - case 0x1e: size = arcompact_handle04_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle04_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle04_20_dasm(DASM_PARAMS); break; // Jcc - case 0x21: size = arcompact_handle04_21_dasm(DASM_PARAMS); break; // Jcc.D - case 0x22: size = arcompact_handle04_22_dasm(DASM_PARAMS); break; // JLcc - case 0x23: size = arcompact_handle04_23_dasm(DASM_PARAMS); break; // JLcc.D - case 0x24: size = arcompact_handle04_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle04_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle04_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle04_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle04_28_dasm(DASM_PARAMS); break; // LPcc - case 0x29: size = arcompact_handle04_29_dasm(DASM_PARAMS); break; // FLAG - case 0x2a: size = arcompact_handle04_2a_dasm(DASM_PARAMS); break; // LR - case 0x2b: size = arcompact_handle04_2b_dasm(DASM_PARAMS); break; // SR - case 0x2c: size = arcompact_handle04_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle04_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle04_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle04_2f_dasm(DASM_PARAMS); break; // Sub Opcode - case 0x30: size = arcompact_handle04_30_dasm(DASM_PARAMS); break; // LD r-r - case 0x31: size = arcompact_handle04_31_dasm(DASM_PARAMS); break; // LD r-r - case 0x32: size = arcompact_handle04_32_dasm(DASM_PARAMS); break; // LD r-r - case 0x33: size = arcompact_handle04_33_dasm(DASM_PARAMS); break; // LD r-r - case 0x34: size = arcompact_handle04_34_dasm(DASM_PARAMS); break; // LD r-r - case 0x35: size = arcompact_handle04_35_dasm(DASM_PARAMS); break; // LD r-r - case 0x36: size = arcompact_handle04_36_dasm(DASM_PARAMS); break; // LD r-r - case 0x37: size = arcompact_handle04_37_dasm(DASM_PARAMS); break; // LD r-r - case 0x38: size = arcompact_handle04_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle04_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle04_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle04_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle04_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle04_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle04_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle04_3f_dasm(DASM_PARAMS); break; // illegal + case 0x00:size = handle04_00_dasm(stream, pc, op, opcodes); break; // ADD + case 0x01:size = handle04_01_dasm(stream, pc, op, opcodes); break; // ADC + case 0x02:size = handle04_02_dasm(stream, pc, op, opcodes); break; // SUB + case 0x03:size = handle04_03_dasm(stream, pc, op, opcodes); break; // SBC + case 0x04:size = handle04_04_dasm(stream, pc, op, opcodes); break; // AND + case 0x05:size = handle04_05_dasm(stream, pc, op, opcodes); break; // OR + case 0x06:size = handle04_06_dasm(stream, pc, op, opcodes); break; // BIC + case 0x07:size = handle04_07_dasm(stream, pc, op, opcodes); break; // XOR + case 0x08:size = handle04_08_dasm(stream, pc, op, opcodes); break; // MAX + case 0x09:size = handle04_09_dasm(stream, pc, op, opcodes); break; // MIN + case 0x0a:size = handle04_0a_dasm(stream, pc, op, opcodes); break; // MOV + case 0x0b:size = handle04_0b_dasm(stream, pc, op, opcodes); break; // TST + case 0x0c:size = handle04_0c_dasm(stream, pc, op, opcodes); break; // CMP + case 0x0d:size = handle04_0d_dasm(stream, pc, op, opcodes); break; // RCMP + case 0x0e:size = handle04_0e_dasm(stream, pc, op, opcodes); break; // RSUB + case 0x0f:size = handle04_0f_dasm(stream, pc, op, opcodes); break; // BSET + case 0x10:size = handle04_10_dasm(stream, pc, op, opcodes); break; // BCLR + case 0x11:size = handle04_11_dasm(stream, pc, op, opcodes); break; // BTST + case 0x12:size = handle04_12_dasm(stream, pc, op, opcodes); break; // BXOR + case 0x13:size = handle04_13_dasm(stream, pc, op, opcodes); break; // BMSK + case 0x14:size = handle04_14_dasm(stream, pc, op, opcodes); break; // ADD1 + case 0x15:size = handle04_15_dasm(stream, pc, op, opcodes); break; // ADD2 + case 0x16:size = handle04_16_dasm(stream, pc, op, opcodes); break; // ADD3 + case 0x17:size = handle04_17_dasm(stream, pc, op, opcodes); break; // SUB1 + case 0x18:size = handle04_18_dasm(stream, pc, op, opcodes); break; // SUB2 + case 0x19:size = handle04_19_dasm(stream, pc, op, opcodes); break; // SUB3 + case 0x1a:size = handle04_1a_dasm(stream, pc, op, opcodes); break; // MPY * + case 0x1b:size = handle04_1b_dasm(stream, pc, op, opcodes); break; // MPYH * + case 0x1c:size = handle04_1c_dasm(stream, pc, op, opcodes); break; // MPYHU * + case 0x1d:size = handle04_1d_dasm(stream, pc, op, opcodes); break; // MPYU * + case 0x1e:size = handle04_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle04_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle04_20_dasm(stream, pc, op, opcodes); break; // Jcc + case 0x21:size = handle04_21_dasm(stream, pc, op, opcodes); break; // Jcc.D + case 0x22:size = handle04_22_dasm(stream, pc, op, opcodes); break; // JLcc + case 0x23:size = handle04_23_dasm(stream, pc, op, opcodes); break; // JLcc.D + case 0x24:size = handle04_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle04_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle04_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle04_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle04_28_dasm(stream, pc, op, opcodes); break; // LPcc + case 0x29:size = handle04_29_dasm(stream, pc, op, opcodes); break; // FLAG + case 0x2a:size = handle04_2a_dasm(stream, pc, op, opcodes); break; // LR + case 0x2b:size = handle04_2b_dasm(stream, pc, op, opcodes); break; // SR + case 0x2c:size = handle04_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle04_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle04_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle04_2f_dasm(stream, pc, op, opcodes); break; // Sub Opcode + case 0x30:size = handle04_30_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x31:size = handle04_31_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x32:size = handle04_32_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x33:size = handle04_33_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x34:size = handle04_34_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x35:size = handle04_35_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x36:size = handle04_36_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x37:size = handle04_37_dasm(stream, pc, op, opcodes); break; // LD r-r + case 0x38:size = handle04_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle04_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle04_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle04_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle04_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle04_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle04_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle04_3f_dasm(stream, pc, op, opcodes); break; // illegal } return size; } -int arcompact_handle04_2f_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr2 = (op & 0x0000003f) >> 0; @@ -228,77 +225,77 @@ int arcompact_handle04_2f_dasm(DASM_OPS_32) switch (subinstr2) { - case 0x00: size = arcompact_handle04_2f_00_dasm(DASM_PARAMS); break; // ASL - case 0x01: size = arcompact_handle04_2f_01_dasm(DASM_PARAMS); break; // ASR - case 0x02: size = arcompact_handle04_2f_02_dasm(DASM_PARAMS); break; // LSR - case 0x03: size = arcompact_handle04_2f_03_dasm(DASM_PARAMS); break; // ROR - case 0x04: size = arcompact_handle04_2f_04_dasm(DASM_PARAMS); break; // RCC - case 0x05: size = arcompact_handle04_2f_05_dasm(DASM_PARAMS); break; // SEXB - case 0x06: size = arcompact_handle04_2f_06_dasm(DASM_PARAMS); break; // SEXW - case 0x07: size = arcompact_handle04_2f_07_dasm(DASM_PARAMS); break; // EXTB - case 0x08: size = arcompact_handle04_2f_08_dasm(DASM_PARAMS); break; // EXTW - case 0x09: size = arcompact_handle04_2f_09_dasm(DASM_PARAMS); break; // ABS - case 0x0a: size = arcompact_handle04_2f_0a_dasm(DASM_PARAMS); break; // NOT - case 0x0b: size = arcompact_handle04_2f_0b_dasm(DASM_PARAMS); break; // RLC - case 0x0c: size = arcompact_handle04_2f_0c_dasm(DASM_PARAMS); break; // EX - case 0x0d: size = arcompact_handle04_2f_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle04_2f_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle04_2f_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle04_2f_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle04_2f_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle04_2f_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle04_2f_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle04_2f_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle04_2f_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle04_2f_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle04_2f_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle04_2f_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle04_2f_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle04_2f_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle04_2f_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle04_2f_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle04_2f_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle04_2f_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle04_2f_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle04_2f_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle04_2f_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle04_2f_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle04_2f_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle04_2f_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle04_2f_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle04_2f_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle04_2f_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle04_2f_28_dasm(DASM_PARAMS); break; // illegal - case 0x29: size = arcompact_handle04_2f_29_dasm(DASM_PARAMS); break; // illegal - case 0x2a: size = arcompact_handle04_2f_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle04_2f_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle04_2f_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle04_2f_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle04_2f_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle04_2f_2f_dasm(DASM_PARAMS); break; // illegal - case 0x30: size = arcompact_handle04_2f_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle04_2f_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle04_2f_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle04_2f_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle04_2f_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle04_2f_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle04_2f_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle04_2f_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle04_2f_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle04_2f_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle04_2f_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle04_2f_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle04_2f_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle04_2f_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle04_2f_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle04_2f_3f_dasm(DASM_PARAMS); break; // ZOPs (Zero Operand Opcodes) + case 0x00:size = handle04_2f_00_dasm(stream, pc, op, opcodes); break; // ASL + case 0x01:size = handle04_2f_01_dasm(stream, pc, op, opcodes); break; // ASR + case 0x02:size = handle04_2f_02_dasm(stream, pc, op, opcodes); break; // LSR + case 0x03:size = handle04_2f_03_dasm(stream, pc, op, opcodes); break; // ROR + case 0x04:size = handle04_2f_04_dasm(stream, pc, op, opcodes); break; // RCC + case 0x05:size = handle04_2f_05_dasm(stream, pc, op, opcodes); break; // SEXB + case 0x06:size = handle04_2f_06_dasm(stream, pc, op, opcodes); break; // SEXW + case 0x07:size = handle04_2f_07_dasm(stream, pc, op, opcodes); break; // EXTB + case 0x08:size = handle04_2f_08_dasm(stream, pc, op, opcodes); break; // EXTW + case 0x09:size = handle04_2f_09_dasm(stream, pc, op, opcodes); break; // ABS + case 0x0a:size = handle04_2f_0a_dasm(stream, pc, op, opcodes); break; // NOT + case 0x0b:size = handle04_2f_0b_dasm(stream, pc, op, opcodes); break; // RLC + case 0x0c:size = handle04_2f_0c_dasm(stream, pc, op, opcodes); break; // EX + case 0x0d:size = handle04_2f_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle04_2f_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle04_2f_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle04_2f_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle04_2f_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle04_2f_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle04_2f_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle04_2f_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle04_2f_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle04_2f_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle04_2f_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle04_2f_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle04_2f_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle04_2f_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle04_2f_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle04_2f_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle04_2f_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle04_2f_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle04_2f_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle04_2f_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle04_2f_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle04_2f_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle04_2f_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle04_2f_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle04_2f_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle04_2f_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle04_2f_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle04_2f_28_dasm(stream, pc, op, opcodes); break; // illegal + case 0x29:size = handle04_2f_29_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2a:size = handle04_2f_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle04_2f_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle04_2f_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle04_2f_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle04_2f_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle04_2f_2f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x30:size = handle04_2f_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle04_2f_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle04_2f_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle04_2f_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle04_2f_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle04_2f_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle04_2f_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle04_2f_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle04_2f_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle04_2f_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle04_2f_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle04_2f_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle04_2f_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle04_2f_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle04_2f_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle04_2f_3f_dasm(stream, pc, op, opcodes); break; // ZOPs (Zero Operand Opcodes) } return size; } -int arcompact_handle05_2f_dasm(DASM_OPS_32) +int arcompact_disassembler::handle05_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr2 = (op & 0x0000003f) >> 0; @@ -306,76 +303,76 @@ int arcompact_handle05_2f_dasm(DASM_OPS_32) switch (subinstr2) { - case 0x00: size = arcompact_handle05_2f_00_dasm(DASM_PARAMS); break; // SWAP - case 0x01: size = arcompact_handle05_2f_01_dasm(DASM_PARAMS); break; // NORM - case 0x02: size = arcompact_handle05_2f_02_dasm(DASM_PARAMS); break; // SAT16 - case 0x03: size = arcompact_handle05_2f_03_dasm(DASM_PARAMS); break; // RND16 - case 0x04: size = arcompact_handle05_2f_04_dasm(DASM_PARAMS); break; // ABSSW - case 0x05: size = arcompact_handle05_2f_05_dasm(DASM_PARAMS); break; // ABSS - case 0x06: size = arcompact_handle05_2f_06_dasm(DASM_PARAMS); break; // NEGSW - case 0x07: size = arcompact_handle05_2f_07_dasm(DASM_PARAMS); break; // NEGS - case 0x08: size = arcompact_handle05_2f_08_dasm(DASM_PARAMS); break; // NORMW - case 0x09: size = arcompact_handle05_2f_09_dasm(DASM_PARAMS); break; // illegal - case 0x0a: size = arcompact_handle05_2f_0a_dasm(DASM_PARAMS); break; // illegal - case 0x0b: size = arcompact_handle05_2f_0b_dasm(DASM_PARAMS); break; // illegal - case 0x0c: size = arcompact_handle05_2f_0c_dasm(DASM_PARAMS); break; // illegal - case 0x0d: size = arcompact_handle05_2f_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle05_2f_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle05_2f_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle05_2f_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle05_2f_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle05_2f_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle05_2f_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle05_2f_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle05_2f_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle05_2f_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle05_2f_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle05_2f_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle05_2f_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle05_2f_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle05_2f_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle05_2f_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle05_2f_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle05_2f_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle05_2f_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle05_2f_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle05_2f_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle05_2f_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle05_2f_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle05_2f_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle05_2f_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle05_2f_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle05_2f_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle05_2f_28_dasm(DASM_PARAMS); break; // illegal - case 0x29: size = arcompact_handle05_2f_29_dasm(DASM_PARAMS); break; // illegal - case 0x2a: size = arcompact_handle05_2f_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle05_2f_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle05_2f_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle05_2f_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle05_2f_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle05_2f_2f_dasm(DASM_PARAMS); break; // illegal - case 0x30: size = arcompact_handle05_2f_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle05_2f_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle05_2f_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle05_2f_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle05_2f_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle05_2f_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle05_2f_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle05_2f_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle05_2f_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle05_2f_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle05_2f_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle05_2f_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle05_2f_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle05_2f_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle05_2f_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle05_2f_3f_dasm(DASM_PARAMS); break; // ZOPs (Zero Operand Opcodes) + case 0x00:size = handle05_2f_00_dasm(stream, pc, op, opcodes); break; // SWAP + case 0x01:size = handle05_2f_01_dasm(stream, pc, op, opcodes); break; // NORM + case 0x02:size = handle05_2f_02_dasm(stream, pc, op, opcodes); break; // SAT16 + case 0x03:size = handle05_2f_03_dasm(stream, pc, op, opcodes); break; // RND16 + case 0x04:size = handle05_2f_04_dasm(stream, pc, op, opcodes); break; // ABSSW + case 0x05:size = handle05_2f_05_dasm(stream, pc, op, opcodes); break; // ABSS + case 0x06:size = handle05_2f_06_dasm(stream, pc, op, opcodes); break; // NEGSW + case 0x07:size = handle05_2f_07_dasm(stream, pc, op, opcodes); break; // NEGS + case 0x08:size = handle05_2f_08_dasm(stream, pc, op, opcodes); break; // NORMW + case 0x09:size = handle05_2f_09_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0a:size = handle05_2f_0a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0b:size = handle05_2f_0b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0c:size = handle05_2f_0c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0d:size = handle05_2f_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle05_2f_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle05_2f_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle05_2f_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle05_2f_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle05_2f_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle05_2f_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle05_2f_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle05_2f_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle05_2f_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle05_2f_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle05_2f_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle05_2f_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle05_2f_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle05_2f_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle05_2f_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle05_2f_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle05_2f_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle05_2f_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle05_2f_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle05_2f_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle05_2f_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle05_2f_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle05_2f_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle05_2f_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle05_2f_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle05_2f_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle05_2f_28_dasm(stream, pc, op, opcodes); break; // illegal + case 0x29:size = handle05_2f_29_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2a:size = handle05_2f_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle05_2f_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle05_2f_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle05_2f_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle05_2f_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle05_2f_2f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x30:size = handle05_2f_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle05_2f_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle05_2f_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle05_2f_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle05_2f_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle05_2f_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle05_2f_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle05_2f_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle05_2f_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle05_2f_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle05_2f_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle05_2f_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle05_2f_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle05_2f_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle05_2f_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle05_2f_3f_dasm(stream, pc, op, opcodes); break; // ZOPs (Zero Operand Opcodes) } return size; } -int arcompact_handle04_2f_3f_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_2f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr3 = (op & 0x07000000) >> 24; @@ -385,77 +382,77 @@ int arcompact_handle04_2f_3f_dasm(DASM_OPS_32) switch (subinstr3) { - case 0x00: size = arcompact_handle04_2f_3f_00_dasm(DASM_PARAMS); break; // illegal - case 0x01: size = arcompact_handle04_2f_3f_01_dasm(DASM_PARAMS); break; // SLEEP - case 0x02: size = arcompact_handle04_2f_3f_02_dasm(DASM_PARAMS); break; // SWI / TRAP9 - case 0x03: size = arcompact_handle04_2f_3f_03_dasm(DASM_PARAMS); break; // SYNC - case 0x04: size = arcompact_handle04_2f_3f_04_dasm(DASM_PARAMS); break; // RTIE - case 0x05: size = arcompact_handle04_2f_3f_05_dasm(DASM_PARAMS); break; // BRK - case 0x06: size = arcompact_handle04_2f_3f_06_dasm(DASM_PARAMS); break; // illegal - case 0x07: size = arcompact_handle04_2f_3f_07_dasm(DASM_PARAMS); break; // illegal - case 0x08: size = arcompact_handle04_2f_3f_08_dasm(DASM_PARAMS); break; // illegal - case 0x09: size = arcompact_handle04_2f_3f_09_dasm(DASM_PARAMS); break; // illegal - case 0x0a: size = arcompact_handle04_2f_3f_0a_dasm(DASM_PARAMS); break; // illegal - case 0x0b: size = arcompact_handle04_2f_3f_0b_dasm(DASM_PARAMS); break; // illegal - case 0x0c: size = arcompact_handle04_2f_3f_0c_dasm(DASM_PARAMS); break; // illegal - case 0x0d: size = arcompact_handle04_2f_3f_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle04_2f_3f_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle04_2f_3f_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle04_2f_3f_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle04_2f_3f_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle04_2f_3f_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle04_2f_3f_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle04_2f_3f_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle04_2f_3f_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle04_2f_3f_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle04_2f_3f_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle04_2f_3f_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle04_2f_3f_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle04_2f_3f_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle04_2f_3f_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle04_2f_3f_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle04_2f_3f_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle04_2f_3f_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle04_2f_3f_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle04_2f_3f_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle04_2f_3f_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle04_2f_3f_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle04_2f_3f_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle04_2f_3f_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle04_2f_3f_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle04_2f_3f_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle04_2f_3f_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle04_2f_3f_28_dasm(DASM_PARAMS); break; // illegal - case 0x29: size = arcompact_handle04_2f_3f_29_dasm(DASM_PARAMS); break; // illegal - case 0x2a: size = arcompact_handle04_2f_3f_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle04_2f_3f_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle04_2f_3f_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle04_2f_3f_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle04_2f_3f_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle04_2f_3f_2f_dasm(DASM_PARAMS); break; // illegal - case 0x30: size = arcompact_handle04_2f_3f_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle04_2f_3f_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle04_2f_3f_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle04_2f_3f_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle04_2f_3f_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle04_2f_3f_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle04_2f_3f_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle04_2f_3f_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle04_2f_3f_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle04_2f_3f_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle04_2f_3f_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle04_2f_3f_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle04_2f_3f_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle04_2f_3f_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle04_2f_3f_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle04_2f_3f_3f_dasm(DASM_PARAMS); break; // illegal + case 0x00:size = handle04_2f_3f_00_dasm(stream, pc, op, opcodes); break; // illegal + case 0x01:size = handle04_2f_3f_01_dasm(stream, pc, op, opcodes); break; // SLEEP + case 0x02:size = handle04_2f_3f_02_dasm(stream, pc, op, opcodes); break; // SWI / TRAP9 + case 0x03:size = handle04_2f_3f_03_dasm(stream, pc, op, opcodes); break; // SYNC + case 0x04:size = handle04_2f_3f_04_dasm(stream, pc, op, opcodes); break; // RTIE + case 0x05:size = handle04_2f_3f_05_dasm(stream, pc, op, opcodes); break; // BRK + case 0x06:size = handle04_2f_3f_06_dasm(stream, pc, op, opcodes); break; // illegal + case 0x07:size = handle04_2f_3f_07_dasm(stream, pc, op, opcodes); break; // illegal + case 0x08:size = handle04_2f_3f_08_dasm(stream, pc, op, opcodes); break; // illegal + case 0x09:size = handle04_2f_3f_09_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0a:size = handle04_2f_3f_0a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0b:size = handle04_2f_3f_0b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0c:size = handle04_2f_3f_0c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0d:size = handle04_2f_3f_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle04_2f_3f_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle04_2f_3f_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle04_2f_3f_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle04_2f_3f_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle04_2f_3f_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle04_2f_3f_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle04_2f_3f_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle04_2f_3f_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle04_2f_3f_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle04_2f_3f_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle04_2f_3f_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle04_2f_3f_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle04_2f_3f_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle04_2f_3f_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle04_2f_3f_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle04_2f_3f_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle04_2f_3f_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle04_2f_3f_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle04_2f_3f_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle04_2f_3f_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle04_2f_3f_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle04_2f_3f_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle04_2f_3f_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle04_2f_3f_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle04_2f_3f_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle04_2f_3f_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle04_2f_3f_28_dasm(stream, pc, op, opcodes); break; // illegal + case 0x29:size = handle04_2f_3f_29_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2a:size = handle04_2f_3f_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle04_2f_3f_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle04_2f_3f_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle04_2f_3f_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle04_2f_3f_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle04_2f_3f_2f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x30:size = handle04_2f_3f_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle04_2f_3f_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle04_2f_3f_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle04_2f_3f_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle04_2f_3f_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle04_2f_3f_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle04_2f_3f_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle04_2f_3f_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle04_2f_3f_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle04_2f_3f_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle04_2f_3f_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle04_2f_3f_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle04_2f_3f_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle04_2f_3f_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle04_2f_3f_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle04_2f_3f_3f_dasm(stream, pc, op, opcodes); break; // illegal } return size; } -int arcompact_handle05_2f_3f_dasm(DASM_OPS_32) // useless ZOP group, no actual opcodes +int arcompact_disassembler::handle05_2f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // useless ZOP group, no actual opcodes { int size = 4; uint8_t subinstr3 = (op & 0x07000000) >> 24; @@ -465,70 +462,70 @@ int arcompact_handle05_2f_3f_dasm(DASM_OPS_32) // useless ZOP group, no actual o switch (subinstr3) { - case 0x00: size = arcompact_handle05_2f_3f_00_dasm(DASM_PARAMS); break; // illegal - case 0x01: size = arcompact_handle05_2f_3f_01_dasm(DASM_PARAMS); break; // illegal - case 0x02: size = arcompact_handle05_2f_3f_02_dasm(DASM_PARAMS); break; // illegal - case 0x03: size = arcompact_handle05_2f_3f_03_dasm(DASM_PARAMS); break; // illegal - case 0x04: size = arcompact_handle05_2f_3f_04_dasm(DASM_PARAMS); break; // illegal - case 0x05: size = arcompact_handle05_2f_3f_05_dasm(DASM_PARAMS); break; // illegal - case 0x06: size = arcompact_handle05_2f_3f_06_dasm(DASM_PARAMS); break; // illegal - case 0x07: size = arcompact_handle05_2f_3f_07_dasm(DASM_PARAMS); break; // illegal - case 0x08: size = arcompact_handle05_2f_3f_08_dasm(DASM_PARAMS); break; // illegal - case 0x09: size = arcompact_handle05_2f_3f_09_dasm(DASM_PARAMS); break; // illegal - case 0x0a: size = arcompact_handle05_2f_3f_0a_dasm(DASM_PARAMS); break; // illegal - case 0x0b: size = arcompact_handle05_2f_3f_0b_dasm(DASM_PARAMS); break; // illegal - case 0x0c: size = arcompact_handle05_2f_3f_0c_dasm(DASM_PARAMS); break; // illegal - case 0x0d: size = arcompact_handle05_2f_3f_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle05_2f_3f_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle05_2f_3f_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle05_2f_3f_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle05_2f_3f_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle05_2f_3f_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle05_2f_3f_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle05_2f_3f_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle05_2f_3f_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle05_2f_3f_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle05_2f_3f_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle05_2f_3f_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle05_2f_3f_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle05_2f_3f_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle05_2f_3f_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle05_2f_3f_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle05_2f_3f_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle05_2f_3f_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle05_2f_3f_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle05_2f_3f_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle05_2f_3f_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle05_2f_3f_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle05_2f_3f_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle05_2f_3f_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle05_2f_3f_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle05_2f_3f_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle05_2f_3f_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle05_2f_3f_28_dasm(DASM_PARAMS); break; // illegal - case 0x29: size = arcompact_handle05_2f_3f_29_dasm(DASM_PARAMS); break; // illegal - case 0x2a: size = arcompact_handle05_2f_3f_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle05_2f_3f_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle05_2f_3f_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle05_2f_3f_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle05_2f_3f_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle05_2f_3f_2f_dasm(DASM_PARAMS); break; // illegal - case 0x30: size = arcompact_handle05_2f_3f_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle05_2f_3f_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle05_2f_3f_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle05_2f_3f_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle05_2f_3f_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle05_2f_3f_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle05_2f_3f_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle05_2f_3f_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle05_2f_3f_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle05_2f_3f_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle05_2f_3f_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle05_2f_3f_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle05_2f_3f_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle05_2f_3f_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle05_2f_3f_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle05_2f_3f_3f_dasm(DASM_PARAMS); break; // illegal + case 0x00:size = handle05_2f_3f_00_dasm(stream, pc, op, opcodes); break; // illegal + case 0x01:size = handle05_2f_3f_01_dasm(stream, pc, op, opcodes); break; // illegal + case 0x02:size = handle05_2f_3f_02_dasm(stream, pc, op, opcodes); break; // illegal + case 0x03:size = handle05_2f_3f_03_dasm(stream, pc, op, opcodes); break; // illegal + case 0x04:size = handle05_2f_3f_04_dasm(stream, pc, op, opcodes); break; // illegal + case 0x05:size = handle05_2f_3f_05_dasm(stream, pc, op, opcodes); break; // illegal + case 0x06:size = handle05_2f_3f_06_dasm(stream, pc, op, opcodes); break; // illegal + case 0x07:size = handle05_2f_3f_07_dasm(stream, pc, op, opcodes); break; // illegal + case 0x08:size = handle05_2f_3f_08_dasm(stream, pc, op, opcodes); break; // illegal + case 0x09:size = handle05_2f_3f_09_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0a:size = handle05_2f_3f_0a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0b:size = handle05_2f_3f_0b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0c:size = handle05_2f_3f_0c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0d:size = handle05_2f_3f_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle05_2f_3f_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle05_2f_3f_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle05_2f_3f_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle05_2f_3f_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle05_2f_3f_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle05_2f_3f_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle05_2f_3f_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle05_2f_3f_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle05_2f_3f_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle05_2f_3f_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle05_2f_3f_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle05_2f_3f_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle05_2f_3f_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle05_2f_3f_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle05_2f_3f_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle05_2f_3f_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle05_2f_3f_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle05_2f_3f_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle05_2f_3f_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle05_2f_3f_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle05_2f_3f_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle05_2f_3f_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle05_2f_3f_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle05_2f_3f_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle05_2f_3f_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle05_2f_3f_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle05_2f_3f_28_dasm(stream, pc, op, opcodes); break; // illegal + case 0x29:size = handle05_2f_3f_29_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2a:size = handle05_2f_3f_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle05_2f_3f_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle05_2f_3f_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle05_2f_3f_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle05_2f_3f_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle05_2f_3f_2f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x30:size = handle05_2f_3f_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle05_2f_3f_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle05_2f_3f_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle05_2f_3f_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle05_2f_3f_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle05_2f_3f_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle05_2f_3f_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle05_2f_3f_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle05_2f_3f_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle05_2f_3f_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle05_2f_3f_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle05_2f_3f_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle05_2f_3f_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle05_2f_3f_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle05_2f_3f_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle05_2f_3f_3f_dasm(stream, pc, op, opcodes); break; // illegal } return size; @@ -536,7 +533,7 @@ int arcompact_handle05_2f_3f_dasm(DASM_OPS_32) // useless ZOP group, no actual o // this is an Extension ALU group, maybe optional on some CPUs? -int arcompact_handle05_dasm(DASM_OPS_32) +int arcompact_disassembler::handle05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint8_t subinstr = (op & 0x003f0000) >> 16; @@ -544,76 +541,76 @@ int arcompact_handle05_dasm(DASM_OPS_32) switch (subinstr) { - case 0x00: size = arcompact_handle05_00_dasm(DASM_PARAMS); break; // ASL - case 0x01: size = arcompact_handle05_01_dasm(DASM_PARAMS); break; // LSR - case 0x02: size = arcompact_handle05_02_dasm(DASM_PARAMS); break; // ASR - case 0x03: size = arcompact_handle05_03_dasm(DASM_PARAMS); break; // ROR - case 0x04: size = arcompact_handle05_04_dasm(DASM_PARAMS); break; // MUL64 - case 0x05: size = arcompact_handle05_05_dasm(DASM_PARAMS); break; // MULU64 - case 0x06: size = arcompact_handle05_06_dasm(DASM_PARAMS); break; // ADDS - case 0x07: size = arcompact_handle05_07_dasm(DASM_PARAMS); break; // SUBS - case 0x08: size = arcompact_handle05_08_dasm(DASM_PARAMS); break; // DIVAW - case 0x09: size = arcompact_handle05_09_dasm(DASM_PARAMS); break; // illegal - case 0x0a: size = arcompact_handle05_0a_dasm(DASM_PARAMS); break; // ASLS - case 0x0b: size = arcompact_handle05_0b_dasm(DASM_PARAMS); break; // ASRS - case 0x0c: size = arcompact_handle05_0c_dasm(DASM_PARAMS); break; // illegal - case 0x0d: size = arcompact_handle05_0d_dasm(DASM_PARAMS); break; // illegal - case 0x0e: size = arcompact_handle05_0e_dasm(DASM_PARAMS); break; // illegal - case 0x0f: size = arcompact_handle05_0f_dasm(DASM_PARAMS); break; // illegal - case 0x10: size = arcompact_handle05_10_dasm(DASM_PARAMS); break; // illegal - case 0x11: size = arcompact_handle05_11_dasm(DASM_PARAMS); break; // illegal - case 0x12: size = arcompact_handle05_12_dasm(DASM_PARAMS); break; // illegal - case 0x13: size = arcompact_handle05_13_dasm(DASM_PARAMS); break; // illegal - case 0x14: size = arcompact_handle05_14_dasm(DASM_PARAMS); break; // illegal - case 0x15: size = arcompact_handle05_15_dasm(DASM_PARAMS); break; // illegal - case 0x16: size = arcompact_handle05_16_dasm(DASM_PARAMS); break; // illegal - case 0x17: size = arcompact_handle05_17_dasm(DASM_PARAMS); break; // illegal - case 0x18: size = arcompact_handle05_18_dasm(DASM_PARAMS); break; // illegal - case 0x19: size = arcompact_handle05_19_dasm(DASM_PARAMS); break; // illegal - case 0x1a: size = arcompact_handle05_1a_dasm(DASM_PARAMS); break; // illegal - case 0x1b: size = arcompact_handle05_1b_dasm(DASM_PARAMS); break; // illegal - case 0x1c: size = arcompact_handle05_1c_dasm(DASM_PARAMS); break; // illegal - case 0x1d: size = arcompact_handle05_1d_dasm(DASM_PARAMS); break; // illegal - case 0x1e: size = arcompact_handle05_1e_dasm(DASM_PARAMS); break; // illegal - case 0x1f: size = arcompact_handle05_1f_dasm(DASM_PARAMS); break; // illegal - case 0x20: size = arcompact_handle05_20_dasm(DASM_PARAMS); break; // illegal - case 0x21: size = arcompact_handle05_21_dasm(DASM_PARAMS); break; // illegal - case 0x22: size = arcompact_handle05_22_dasm(DASM_PARAMS); break; // illegal - case 0x23: size = arcompact_handle05_23_dasm(DASM_PARAMS); break; // illegal - case 0x24: size = arcompact_handle05_24_dasm(DASM_PARAMS); break; // illegal - case 0x25: size = arcompact_handle05_25_dasm(DASM_PARAMS); break; // illegal - case 0x26: size = arcompact_handle05_26_dasm(DASM_PARAMS); break; // illegal - case 0x27: size = arcompact_handle05_27_dasm(DASM_PARAMS); break; // illegal - case 0x28: size = arcompact_handle05_28_dasm(DASM_PARAMS); break; // ADDSDW - case 0x29: size = arcompact_handle05_29_dasm(DASM_PARAMS); break; // SUBSDW - case 0x2a: size = arcompact_handle05_2a_dasm(DASM_PARAMS); break; // illegal - case 0x2b: size = arcompact_handle05_2b_dasm(DASM_PARAMS); break; // illegal - case 0x2c: size = arcompact_handle05_2c_dasm(DASM_PARAMS); break; // illegal - case 0x2d: size = arcompact_handle05_2d_dasm(DASM_PARAMS); break; // illegal - case 0x2e: size = arcompact_handle05_2e_dasm(DASM_PARAMS); break; // illegal - case 0x2f: size = arcompact_handle05_2f_dasm(DASM_PARAMS); break; // SOPs - case 0x30: size = arcompact_handle05_30_dasm(DASM_PARAMS); break; // illegal - case 0x31: size = arcompact_handle05_31_dasm(DASM_PARAMS); break; // illegal - case 0x32: size = arcompact_handle05_32_dasm(DASM_PARAMS); break; // illegal - case 0x33: size = arcompact_handle05_33_dasm(DASM_PARAMS); break; // illegal - case 0x34: size = arcompact_handle05_34_dasm(DASM_PARAMS); break; // illegal - case 0x35: size = arcompact_handle05_35_dasm(DASM_PARAMS); break; // illegal - case 0x36: size = arcompact_handle05_36_dasm(DASM_PARAMS); break; // illegal - case 0x37: size = arcompact_handle05_37_dasm(DASM_PARAMS); break; // illegal - case 0x38: size = arcompact_handle05_38_dasm(DASM_PARAMS); break; // illegal - case 0x39: size = arcompact_handle05_39_dasm(DASM_PARAMS); break; // illegal - case 0x3a: size = arcompact_handle05_3a_dasm(DASM_PARAMS); break; // illegal - case 0x3b: size = arcompact_handle05_3b_dasm(DASM_PARAMS); break; // illegal - case 0x3c: size = arcompact_handle05_3c_dasm(DASM_PARAMS); break; // illegal - case 0x3d: size = arcompact_handle05_3d_dasm(DASM_PARAMS); break; // illegal - case 0x3e: size = arcompact_handle05_3e_dasm(DASM_PARAMS); break; // illegal - case 0x3f: size = arcompact_handle05_3f_dasm(DASM_PARAMS); break; // illegal + case 0x00:size = handle05_00_dasm(stream, pc, op, opcodes); break; // ASL + case 0x01:size = handle05_01_dasm(stream, pc, op, opcodes); break; // LSR + case 0x02:size = handle05_02_dasm(stream, pc, op, opcodes); break; // ASR + case 0x03:size = handle05_03_dasm(stream, pc, op, opcodes); break; // ROR + case 0x04:size = handle05_04_dasm(stream, pc, op, opcodes); break; // MUL64 + case 0x05:size = handle05_05_dasm(stream, pc, op, opcodes); break; // MULU64 + case 0x06:size = handle05_06_dasm(stream, pc, op, opcodes); break; // ADDS + case 0x07:size = handle05_07_dasm(stream, pc, op, opcodes); break; // SUBS + case 0x08:size = handle05_08_dasm(stream, pc, op, opcodes); break; // DIVAW + case 0x09:size = handle05_09_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0a:size = handle05_0a_dasm(stream, pc, op, opcodes); break; // ASLS + case 0x0b:size = handle05_0b_dasm(stream, pc, op, opcodes); break; // ASRS + case 0x0c:size = handle05_0c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0d:size = handle05_0d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0e:size = handle05_0e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x0f:size = handle05_0f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x10:size = handle05_10_dasm(stream, pc, op, opcodes); break; // illegal + case 0x11:size = handle05_11_dasm(stream, pc, op, opcodes); break; // illegal + case 0x12:size = handle05_12_dasm(stream, pc, op, opcodes); break; // illegal + case 0x13:size = handle05_13_dasm(stream, pc, op, opcodes); break; // illegal + case 0x14:size = handle05_14_dasm(stream, pc, op, opcodes); break; // illegal + case 0x15:size = handle05_15_dasm(stream, pc, op, opcodes); break; // illegal + case 0x16:size = handle05_16_dasm(stream, pc, op, opcodes); break; // illegal + case 0x17:size = handle05_17_dasm(stream, pc, op, opcodes); break; // illegal + case 0x18:size = handle05_18_dasm(stream, pc, op, opcodes); break; // illegal + case 0x19:size = handle05_19_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1a:size = handle05_1a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1b:size = handle05_1b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1c:size = handle05_1c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1d:size = handle05_1d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1e:size = handle05_1e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x1f:size = handle05_1f_dasm(stream, pc, op, opcodes); break; // illegal + case 0x20:size = handle05_20_dasm(stream, pc, op, opcodes); break; // illegal + case 0x21:size = handle05_21_dasm(stream, pc, op, opcodes); break; // illegal + case 0x22:size = handle05_22_dasm(stream, pc, op, opcodes); break; // illegal + case 0x23:size = handle05_23_dasm(stream, pc, op, opcodes); break; // illegal + case 0x24:size = handle05_24_dasm(stream, pc, op, opcodes); break; // illegal + case 0x25:size = handle05_25_dasm(stream, pc, op, opcodes); break; // illegal + case 0x26:size = handle05_26_dasm(stream, pc, op, opcodes); break; // illegal + case 0x27:size = handle05_27_dasm(stream, pc, op, opcodes); break; // illegal + case 0x28:size = handle05_28_dasm(stream, pc, op, opcodes); break; // ADDSDW + case 0x29:size = handle05_29_dasm(stream, pc, op, opcodes); break; // SUBSDW + case 0x2a:size = handle05_2a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2b:size = handle05_2b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2c:size = handle05_2c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2d:size = handle05_2d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2e:size = handle05_2e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x2f:size = handle05_2f_dasm(stream, pc, op, opcodes); break; // SOPs + case 0x30:size = handle05_30_dasm(stream, pc, op, opcodes); break; // illegal + case 0x31:size = handle05_31_dasm(stream, pc, op, opcodes); break; // illegal + case 0x32:size = handle05_32_dasm(stream, pc, op, opcodes); break; // illegal + case 0x33:size = handle05_33_dasm(stream, pc, op, opcodes); break; // illegal + case 0x34:size = handle05_34_dasm(stream, pc, op, opcodes); break; // illegal + case 0x35:size = handle05_35_dasm(stream, pc, op, opcodes); break; // illegal + case 0x36:size = handle05_36_dasm(stream, pc, op, opcodes); break; // illegal + case 0x37:size = handle05_37_dasm(stream, pc, op, opcodes); break; // illegal + case 0x38:size = handle05_38_dasm(stream, pc, op, opcodes); break; // illegal + case 0x39:size = handle05_39_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3a:size = handle05_3a_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3b:size = handle05_3b_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3c:size = handle05_3c_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3d:size = handle05_3d_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3e:size = handle05_3e_dasm(stream, pc, op, opcodes); break; // illegal + case 0x3f:size = handle05_3f_dasm(stream, pc, op, opcodes); break; // illegal } return size; } -int arcompact_handle0c_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0018) >> 3; @@ -621,15 +618,15 @@ int arcompact_handle0c_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0c_00_dasm(DASM_PARAMS); break; // LD_S - case 0x01: size = arcompact_handle0c_01_dasm(DASM_PARAMS); break; // LDB_S - case 0x02: size = arcompact_handle0c_02_dasm(DASM_PARAMS); break; // LDW_S - case 0x03: size = arcompact_handle0c_03_dasm(DASM_PARAMS); break; // ADD_S + case 0x00:size = handle0c_00_dasm(stream, pc, op, opcodes); break; // LD_S + case 0x01:size = handle0c_01_dasm(stream, pc, op, opcodes); break; // LDB_S + case 0x02:size = handle0c_02_dasm(stream, pc, op, opcodes); break; // LDW_S + case 0x03:size = handle0c_03_dasm(stream, pc, op, opcodes); break; // ADD_S } return size; } -int arcompact_handle0d_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0018) >> 3; @@ -637,15 +634,15 @@ int arcompact_handle0d_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0d_00_dasm(DASM_PARAMS); break; // ADD_S - case 0x01: size = arcompact_handle0d_01_dasm(DASM_PARAMS); break; // SUB_S - case 0x02: size = arcompact_handle0d_02_dasm(DASM_PARAMS); break; // ASL_S - case 0x03: size = arcompact_handle0d_03_dasm(DASM_PARAMS); break; // ASR_S + case 0x00:size = handle0d_00_dasm(stream, pc, op, opcodes); break; // ADD_S + case 0x01:size = handle0d_01_dasm(stream, pc, op, opcodes); break; // SUB_S + case 0x02:size = handle0d_02_dasm(stream, pc, op, opcodes); break; // ASL_S + case 0x03:size = handle0d_03_dasm(stream, pc, op, opcodes); break; // ASR_S } return size; } -int arcompact_handle0e_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0018) >> 3; @@ -653,15 +650,15 @@ int arcompact_handle0e_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0e_00_dasm(DASM_PARAMS); break; // ADD_S - case 0x01: size = arcompact_handle0e_01_dasm(DASM_PARAMS); break; // MOV_S - case 0x02: size = arcompact_handle0e_02_dasm(DASM_PARAMS); break; // CMP_S - case 0x03: size = arcompact_handle0e_03_dasm(DASM_PARAMS); break; // MOV_S + case 0x00:size = handle0e_00_dasm(stream, pc, op, opcodes); break; // ADD_S + case 0x01:size = handle0e_01_dasm(stream, pc, op, opcodes); break; // MOV_S + case 0x02:size = handle0e_02_dasm(stream, pc, op, opcodes); break; // CMP_S + case 0x03:size = handle0e_03_dasm(stream, pc, op, opcodes); break; // MOV_S } return size; } -int arcompact_handle0f_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; // General Register Instructions (16-bit) @@ -671,44 +668,44 @@ int arcompact_handle0f_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0f_00_dasm(DASM_PARAMS); break; // SOPs - case 0x01: size = arcompact_handle0f_01_dasm(DASM_PARAMS); break; // 0x01 <illegal> - case 0x02: size = arcompact_handle0f_02_dasm(DASM_PARAMS); break; // SUB_S - case 0x03: size = arcompact_handle0f_03_dasm(DASM_PARAMS); break; // 0x03 <illegal> - case 0x04: size = arcompact_handle0f_04_dasm(DASM_PARAMS); break; // AND_S - case 0x05: size = arcompact_handle0f_05_dasm(DASM_PARAMS); break; // OR_S - case 0x06: size = arcompact_handle0f_06_dasm(DASM_PARAMS); break; // BIC_S - case 0x07: size = arcompact_handle0f_07_dasm(DASM_PARAMS); break; // XOR_S - case 0x08: size = arcompact_handle0f_08_dasm(DASM_PARAMS); break; // 0x08 <illegal> - case 0x09: size = arcompact_handle0f_09_dasm(DASM_PARAMS); break; // 0x09 <illegal> - case 0x0a: size = arcompact_handle0f_0a_dasm(DASM_PARAMS); break; // 0x0a <illegal> - case 0x0b: size = arcompact_handle0f_0b_dasm(DASM_PARAMS); break; // TST_S - case 0x0c: size = arcompact_handle0f_0c_dasm(DASM_PARAMS); break; // MUL64_S - case 0x0d: size = arcompact_handle0f_0d_dasm(DASM_PARAMS); break; // SEXB_S - case 0x0e: size = arcompact_handle0f_0e_dasm(DASM_PARAMS); break; // SEXW_S - case 0x0f: size = arcompact_handle0f_0f_dasm(DASM_PARAMS); break; // EXTB_S - case 0x10: size = arcompact_handle0f_10_dasm(DASM_PARAMS); break; // EXTW_S - case 0x11: size = arcompact_handle0f_11_dasm(DASM_PARAMS); break; // ABS_S - case 0x12: size = arcompact_handle0f_12_dasm(DASM_PARAMS); break; // NOT_S - case 0x13: size = arcompact_handle0f_13_dasm(DASM_PARAMS); break; // NEG_S - case 0x14: size = arcompact_handle0f_14_dasm(DASM_PARAMS); break; // ADD1_S - case 0x15: size = arcompact_handle0f_15_dasm(DASM_PARAMS); break; // ADD2_S - case 0x16: size = arcompact_handle0f_16_dasm(DASM_PARAMS); break; // ADD3_S - case 0x17: size = arcompact_handle0f_17_dasm(DASM_PARAMS); break; // 0x17 <illegal> - case 0x18: size = arcompact_handle0f_18_dasm(DASM_PARAMS); break; // ASL_S (multiple) - case 0x19: size = arcompact_handle0f_19_dasm(DASM_PARAMS); break; // LSR_S (multiple) - case 0x1a: size = arcompact_handle0f_1a_dasm(DASM_PARAMS); break; // ASR_S (multiple) - case 0x1b: size = arcompact_handle0f_1b_dasm(DASM_PARAMS); break; // ASL_S (single) - case 0x1c: size = arcompact_handle0f_1c_dasm(DASM_PARAMS); break; // LSR_S (single) - case 0x1d: size = arcompact_handle0f_1d_dasm(DASM_PARAMS); break; // ASR_S (single) - case 0x1e: size = arcompact_handle0f_1e_dasm(DASM_PARAMS); break; // TRAP (not a5?) - case 0x1f: size = arcompact_handle0f_1f_dasm(DASM_PARAMS); break; // BRK_S ( 0x7fff only? ) + case 0x00:size = handle0f_00_dasm(stream, pc, op, opcodes); break; // SOPs + case 0x01:size = handle0f_01_dasm(stream, pc, op, opcodes); break; // 0x01 <illegal> + case 0x02:size = handle0f_02_dasm(stream, pc, op, opcodes); break; // SUB_S + case 0x03:size = handle0f_03_dasm(stream, pc, op, opcodes); break; // 0x03 <illegal> + case 0x04:size = handle0f_04_dasm(stream, pc, op, opcodes); break; // AND_S + case 0x05:size = handle0f_05_dasm(stream, pc, op, opcodes); break; // OR_S + case 0x06:size = handle0f_06_dasm(stream, pc, op, opcodes); break; // BIC_S + case 0x07:size = handle0f_07_dasm(stream, pc, op, opcodes); break; // XOR_S + case 0x08:size = handle0f_08_dasm(stream, pc, op, opcodes); break; // 0x08 <illegal> + case 0x09:size = handle0f_09_dasm(stream, pc, op, opcodes); break; // 0x09 <illegal> + case 0x0a:size = handle0f_0a_dasm(stream, pc, op, opcodes); break; // 0x0a <illegal> + case 0x0b:size = handle0f_0b_dasm(stream, pc, op, opcodes); break; // TST_S + case 0x0c:size = handle0f_0c_dasm(stream, pc, op, opcodes); break; // MUL64_S + case 0x0d:size = handle0f_0d_dasm(stream, pc, op, opcodes); break; // SEXB_S + case 0x0e:size = handle0f_0e_dasm(stream, pc, op, opcodes); break; // SEXW_S + case 0x0f:size = handle0f_0f_dasm(stream, pc, op, opcodes); break; // EXTB_S + case 0x10:size = handle0f_10_dasm(stream, pc, op, opcodes); break; // EXTW_S + case 0x11:size = handle0f_11_dasm(stream, pc, op, opcodes); break; // ABS_S + case 0x12:size = handle0f_12_dasm(stream, pc, op, opcodes); break; // NOT_S + case 0x13:size = handle0f_13_dasm(stream, pc, op, opcodes); break; // NEG_S + case 0x14:size = handle0f_14_dasm(stream, pc, op, opcodes); break; // ADD1_S + case 0x15:size = handle0f_15_dasm(stream, pc, op, opcodes); break; // ADD2_S + case 0x16:size = handle0f_16_dasm(stream, pc, op, opcodes); break; // ADD3_S + case 0x17:size = handle0f_17_dasm(stream, pc, op, opcodes); break; // 0x17 <illegal> + case 0x18:size = handle0f_18_dasm(stream, pc, op, opcodes); break; // ASL_S (multiple) + case 0x19:size = handle0f_19_dasm(stream, pc, op, opcodes); break; // LSR_S (multiple) + case 0x1a:size = handle0f_1a_dasm(stream, pc, op, opcodes); break; // ASR_S (multiple) + case 0x1b:size = handle0f_1b_dasm(stream, pc, op, opcodes); break; // ASL_S (single) + case 0x1c:size = handle0f_1c_dasm(stream, pc, op, opcodes); break; // LSR_S (single) + case 0x1d:size = handle0f_1d_dasm(stream, pc, op, opcodes); break; // ASR_S (single) + case 0x1e:size = handle0f_1e_dasm(stream, pc, op, opcodes); break; // TRAP (not a5?) + case 0x1f:size = handle0f_1f_dasm(stream, pc, op, opcodes); break; // BRK_S ( 0x7fff only? ) } return size; } -int arcompact_handle0f_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0f_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x00e0) >> 5; @@ -716,21 +713,21 @@ int arcompact_handle0f_00_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle0f_00_00_dasm(DASM_PARAMS); break; // J_S - case 0x01: size = arcompact_handle0f_00_01_dasm(DASM_PARAMS); break; // J_S.D - case 0x02: size = arcompact_handle0f_00_02_dasm(DASM_PARAMS); break; // JL_S - case 0x03: size = arcompact_handle0f_00_03_dasm(DASM_PARAMS); break; // JL_S.D - case 0x04: size = arcompact_handle0f_00_04_dasm(DASM_PARAMS); break; // 0x04 <illegal> - case 0x05: size = arcompact_handle0f_00_05_dasm(DASM_PARAMS); break; // 0x05 <illegal> - case 0x06: size = arcompact_handle0f_00_06_dasm(DASM_PARAMS); break; // SUB_S.NE - case 0x07: size = arcompact_handle0f_00_07_dasm(DASM_PARAMS); break; // ZOPs + case 0x00:size = handle0f_00_00_dasm(stream, pc, op, opcodes); break; // J_S + case 0x01:size = handle0f_00_01_dasm(stream, pc, op, opcodes); break; // J_S.D + case 0x02:size = handle0f_00_02_dasm(stream, pc, op, opcodes); break; // JL_S + case 0x03:size = handle0f_00_03_dasm(stream, pc, op, opcodes); break; // JL_S.D + case 0x04:size = handle0f_00_04_dasm(stream, pc, op, opcodes); break; // 0x04 <illegal> + case 0x05:size = handle0f_00_05_dasm(stream, pc, op, opcodes); break; // 0x05 <illegal> + case 0x06:size = handle0f_00_06_dasm(stream, pc, op, opcodes); break; // SUB_S.NE + case 0x07:size = handle0f_00_07_dasm(stream, pc, op, opcodes); break; // ZOPs } return size; } -int arcompact_handle0f_00_07_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0f_00_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; // General Operations w/o Register @@ -740,20 +737,20 @@ int arcompact_handle0f_00_07_dasm(DASM_OPS_16) switch (subinstr3) { - case 0x00: size = arcompact_handle0f_00_07_00_dasm(DASM_PARAMS); break; // NOP_S - case 0x01: size = arcompact_handle0f_00_07_01_dasm(DASM_PARAMS); break; // UNIMP_S - case 0x02: size = arcompact_handle0f_00_07_02_dasm(DASM_PARAMS); break; // 0x02 <illegal> - case 0x03: size = arcompact_handle0f_00_07_03_dasm(DASM_PARAMS); break; // 0x03 <illegal> - case 0x04: size = arcompact_handle0f_00_07_04_dasm(DASM_PARAMS); break; // JEQ_S [BLINK] - case 0x05: size = arcompact_handle0f_00_07_05_dasm(DASM_PARAMS); break; // JNE_S [BLINK] - case 0x06: size = arcompact_handle0f_00_07_06_dasm(DASM_PARAMS); break; // J_S [BLINK] - case 0x07: size = arcompact_handle0f_00_07_07_dasm(DASM_PARAMS); break; // J_S.D [BLINK] + case 0x00:size = handle0f_00_07_00_dasm(stream, pc, op, opcodes); break; // NOP_S + case 0x01:size = handle0f_00_07_01_dasm(stream, pc, op, opcodes); break; // UNIMP_S + case 0x02:size = handle0f_00_07_02_dasm(stream, pc, op, opcodes); break; // 0x02 <illegal> + case 0x03:size = handle0f_00_07_03_dasm(stream, pc, op, opcodes); break; // 0x03 <illegal> + case 0x04:size = handle0f_00_07_04_dasm(stream, pc, op, opcodes); break; // JEQ_S [BLINK] + case 0x05:size = handle0f_00_07_05_dasm(stream, pc, op, opcodes); break; // JNE_S [BLINK] + case 0x06:size = handle0f_00_07_06_dasm(stream, pc, op, opcodes); break; // J_S [BLINK] + case 0x07:size = handle0f_00_07_07_dasm(stream, pc, op, opcodes); break; // J_S.D [BLINK] } return size; } -int arcompact_handle17_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x00e0) >> 5; @@ -761,20 +758,20 @@ int arcompact_handle17_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle17_00_dasm(DASM_PARAMS); break; // ASL_S - case 0x01: size = arcompact_handle17_01_dasm(DASM_PARAMS); break; // LSR_S - case 0x02: size = arcompact_handle17_02_dasm(DASM_PARAMS); break; // ASR_S - case 0x03: size = arcompact_handle17_03_dasm(DASM_PARAMS); break; // SUB_S - case 0x04: size = arcompact_handle17_04_dasm(DASM_PARAMS); break; // BSET_S - case 0x05: size = arcompact_handle17_05_dasm(DASM_PARAMS); break; // BCLR_S - case 0x06: size = arcompact_handle17_06_dasm(DASM_PARAMS); break; // BMSK_S - case 0x07: size = arcompact_handle17_07_dasm(DASM_PARAMS); break; // BTST_S + case 0x00:size = handle17_00_dasm(stream, pc, op, opcodes); break; // ASL_S + case 0x01:size = handle17_01_dasm(stream, pc, op, opcodes); break; // LSR_S + case 0x02:size = handle17_02_dasm(stream, pc, op, opcodes); break; // ASR_S + case 0x03:size = handle17_03_dasm(stream, pc, op, opcodes); break; // SUB_S + case 0x04:size = handle17_04_dasm(stream, pc, op, opcodes); break; // BSET_S + case 0x05:size = handle17_05_dasm(stream, pc, op, opcodes); break; // BCLR_S + case 0x06:size = handle17_06_dasm(stream, pc, op, opcodes); break; // BMSK_S + case 0x07:size = handle17_07_dasm(stream, pc, op, opcodes); break; // BTST_S } return size; } -int arcompact_handle18_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; // Stack Pointer Based Instructions (16-bit) @@ -784,20 +781,20 @@ int arcompact_handle18_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle18_00_dasm(DASM_PARAMS); break; // LD_S (SP) - case 0x01: size = arcompact_handle18_01_dasm(DASM_PARAMS); break; // LDB_S (SP) - case 0x02: size = arcompact_handle18_02_dasm(DASM_PARAMS); break; // ST_S (SP) - case 0x03: size = arcompact_handle18_03_dasm(DASM_PARAMS); break; // STB_S (SP) - case 0x04: size = arcompact_handle18_04_dasm(DASM_PARAMS); break; // ADD_S (SP) - case 0x05: size = arcompact_handle18_05_dasm(DASM_PARAMS); break; // subtable 18_05 - case 0x06: size = arcompact_handle18_06_dasm(DASM_PARAMS); break; // subtable 18_06 - case 0x07: size = arcompact_handle18_07_dasm(DASM_PARAMS); break; // subtable 18_07 + case 0x00:size = handle18_00_dasm(stream, pc, op, opcodes); break; // LD_S (SP) + case 0x01:size = handle18_01_dasm(stream, pc, op, opcodes); break; // LDB_S (SP) + case 0x02:size = handle18_02_dasm(stream, pc, op, opcodes); break; // ST_S (SP) + case 0x03:size = handle18_03_dasm(stream, pc, op, opcodes); break; // STB_S (SP) + case 0x04:size = handle18_04_dasm(stream, pc, op, opcodes); break; // ADD_S (SP) + case 0x05:size = handle18_05_dasm(stream, pc, op, opcodes); break; // subtable 18_05 + case 0x06:size = handle18_06_dasm(stream, pc, op, opcodes); break; // subtable 18_06 + case 0x07:size = handle18_07_dasm(stream, pc, op, opcodes); break; // subtable 18_07 } return size; } -int arcompact_handle18_05_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr2 = (op & 0x0700) >> 8; @@ -805,20 +802,20 @@ int arcompact_handle18_05_dasm(DASM_OPS_16) switch (subinstr2) { - case 0x00: size = arcompact_handle18_05_00_dasm(DASM_PARAMS); break; // ADD_S (SP) - case 0x01: size = arcompact_handle18_05_01_dasm(DASM_PARAMS); break; // SUB_S (SP) - case 0x02: size = arcompact_handle18_05_02_dasm(DASM_PARAMS); break; // <illegal 0x18_05_02> - case 0x03: size = arcompact_handle18_05_03_dasm(DASM_PARAMS); break; // <illegal 0x18_05_03> - case 0x04: size = arcompact_handle18_05_04_dasm(DASM_PARAMS); break; // <illegal 0x18_05_04> - case 0x05: size = arcompact_handle18_05_05_dasm(DASM_PARAMS); break; // <illegal 0x18_05_05> - case 0x06: size = arcompact_handle18_05_06_dasm(DASM_PARAMS); break; // <illegal 0x18_05_06> - case 0x07: size = arcompact_handle18_05_07_dasm(DASM_PARAMS); break; // <illegal 0x18_05_07> + case 0x00:size = handle18_05_00_dasm(stream, pc, op, opcodes); break; // ADD_S (SP) + case 0x01:size = handle18_05_01_dasm(stream, pc, op, opcodes); break; // SUB_S (SP) + case 0x02:size = handle18_05_02_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_02> + case 0x03:size = handle18_05_03_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_03> + case 0x04:size = handle18_05_04_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_04> + case 0x05:size = handle18_05_05_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_05> + case 0x06:size = handle18_05_06_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_06> + case 0x07:size = handle18_05_07_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_05_07> } return size; } -int arcompact_handle18_06_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr2 = (op & 0x001f) >> 0; @@ -826,44 +823,44 @@ int arcompact_handle18_06_dasm(DASM_OPS_16) switch (subinstr2) { - case 0x00: size = arcompact_handle18_06_00_dasm(DASM_PARAMS); break; // <illegal 0x18_06_00> - case 0x01: size = arcompact_handle18_06_01_dasm(DASM_PARAMS); break; // POP_S b - case 0x02: size = arcompact_handle18_06_02_dasm(DASM_PARAMS); break; // <illegal 0x18_06_02> - case 0x03: size = arcompact_handle18_06_03_dasm(DASM_PARAMS); break; // <illegal 0x18_06_03> - case 0x04: size = arcompact_handle18_06_04_dasm(DASM_PARAMS); break; // <illegal 0x18_06_04> - case 0x05: size = arcompact_handle18_06_05_dasm(DASM_PARAMS); break; // <illegal 0x18_06_05> - case 0x06: size = arcompact_handle18_06_06_dasm(DASM_PARAMS); break; // <illegal 0x18_06_06> - case 0x07: size = arcompact_handle18_06_07_dasm(DASM_PARAMS); break; // <illegal 0x18_06_07> - case 0x08: size = arcompact_handle18_06_08_dasm(DASM_PARAMS); break; // <illegal 0x18_06_08> - case 0x09: size = arcompact_handle18_06_09_dasm(DASM_PARAMS); break; // <illegal 0x18_06_09> - case 0x0a: size = arcompact_handle18_06_0a_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0a> - case 0x0b: size = arcompact_handle18_06_0b_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0b> - case 0x0c: size = arcompact_handle18_06_0c_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0c> - case 0x0d: size = arcompact_handle18_06_0d_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0d> - case 0x0e: size = arcompact_handle18_06_0e_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0e> - case 0x0f: size = arcompact_handle18_06_0f_dasm(DASM_PARAMS); break; // <illegal 0x18_06_0f> - case 0x10: size = arcompact_handle18_06_10_dasm(DASM_PARAMS); break; // <illegal 0x18_06_10> - case 0x11: size = arcompact_handle18_06_11_dasm(DASM_PARAMS); break; // POP_S blink - case 0x12: size = arcompact_handle18_06_12_dasm(DASM_PARAMS); break; // <illegal 0x18_06_12> - case 0x13: size = arcompact_handle18_06_13_dasm(DASM_PARAMS); break; // <illegal 0x18_06_13> - case 0x14: size = arcompact_handle18_06_14_dasm(DASM_PARAMS); break; // <illegal 0x18_06_14> - case 0x15: size = arcompact_handle18_06_15_dasm(DASM_PARAMS); break; // <illegal 0x18_06_15> - case 0x16: size = arcompact_handle18_06_16_dasm(DASM_PARAMS); break; // <illegal 0x18_06_16> - case 0x17: size = arcompact_handle18_06_17_dasm(DASM_PARAMS); break; // <illegal 0x18_06_17> - case 0x18: size = arcompact_handle18_06_18_dasm(DASM_PARAMS); break; // <illegal 0x18_06_18> - case 0x19: size = arcompact_handle18_06_19_dasm(DASM_PARAMS); break; // <illegal 0x18_06_19> - case 0x1a: size = arcompact_handle18_06_1a_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1a> - case 0x1b: size = arcompact_handle18_06_1b_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1b> - case 0x1c: size = arcompact_handle18_06_1c_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1c> - case 0x1d: size = arcompact_handle18_06_1d_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1d> - case 0x1e: size = arcompact_handle18_06_1e_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1e> - case 0x1f: size = arcompact_handle18_06_1f_dasm(DASM_PARAMS); break; // <illegal 0x18_06_1f> + case 0x00:size = handle18_06_00_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_00> + case 0x01:size = handle18_06_01_dasm(stream, pc, op, opcodes); break; // POP_S b + case 0x02:size = handle18_06_02_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_02> + case 0x03:size = handle18_06_03_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_03> + case 0x04:size = handle18_06_04_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_04> + case 0x05:size = handle18_06_05_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_05> + case 0x06:size = handle18_06_06_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_06> + case 0x07:size = handle18_06_07_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_07> + case 0x08:size = handle18_06_08_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_08> + case 0x09:size = handle18_06_09_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_09> + case 0x0a:size = handle18_06_0a_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0a> + case 0x0b:size = handle18_06_0b_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0b> + case 0x0c:size = handle18_06_0c_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0c> + case 0x0d:size = handle18_06_0d_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0d> + case 0x0e:size = handle18_06_0e_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0e> + case 0x0f:size = handle18_06_0f_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_0f> + case 0x10:size = handle18_06_10_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_10> + case 0x11:size = handle18_06_11_dasm(stream, pc, op, opcodes); break; // POP_S blink + case 0x12:size = handle18_06_12_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_12> + case 0x13:size = handle18_06_13_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_13> + case 0x14:size = handle18_06_14_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_14> + case 0x15:size = handle18_06_15_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_15> + case 0x16:size = handle18_06_16_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_16> + case 0x17:size = handle18_06_17_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_17> + case 0x18:size = handle18_06_18_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_18> + case 0x19:size = handle18_06_19_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_19> + case 0x1a:size = handle18_06_1a_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1a> + case 0x1b:size = handle18_06_1b_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1b> + case 0x1c:size = handle18_06_1c_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1c> + case 0x1d:size = handle18_06_1d_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1d> + case 0x1e:size = handle18_06_1e_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1e> + case 0x1f:size = handle18_06_1f_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_06_1f> } return size; } -int arcompact_handle18_07_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr2 = (op & 0x001f) >> 0; @@ -871,44 +868,44 @@ int arcompact_handle18_07_dasm(DASM_OPS_16) switch (subinstr2) { - case 0x00: size = arcompact_handle18_07_00_dasm(DASM_PARAMS); break; // <illegal 0x18_07_00> - case 0x01: size = arcompact_handle18_07_01_dasm(DASM_PARAMS); break; // PUSH_S b - case 0x02: size = arcompact_handle18_07_02_dasm(DASM_PARAMS); break; // <illegal 0x18_07_02> - case 0x03: size = arcompact_handle18_07_03_dasm(DASM_PARAMS); break; // <illegal 0x18_07_03> - case 0x04: size = arcompact_handle18_07_04_dasm(DASM_PARAMS); break; // <illegal 0x18_07_04> - case 0x05: size = arcompact_handle18_07_05_dasm(DASM_PARAMS); break; // <illegal 0x18_07_05> - case 0x06: size = arcompact_handle18_07_06_dasm(DASM_PARAMS); break; // <illegal 0x18_07_06> - case 0x07: size = arcompact_handle18_07_07_dasm(DASM_PARAMS); break; // <illegal 0x18_07_07> - case 0x08: size = arcompact_handle18_07_08_dasm(DASM_PARAMS); break; // <illegal 0x18_07_08> - case 0x09: size = arcompact_handle18_07_09_dasm(DASM_PARAMS); break; // <illegal 0x18_07_09> - case 0x0a: size = arcompact_handle18_07_0a_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0a> - case 0x0b: size = arcompact_handle18_07_0b_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0b> - case 0x0c: size = arcompact_handle18_07_0c_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0c> - case 0x0d: size = arcompact_handle18_07_0d_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0d> - case 0x0e: size = arcompact_handle18_07_0e_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0e> - case 0x0f: size = arcompact_handle18_07_0f_dasm(DASM_PARAMS); break; // <illegal 0x18_07_0f> - case 0x10: size = arcompact_handle18_07_10_dasm(DASM_PARAMS); break; // <illegal 0x18_07_10> - case 0x11: size = arcompact_handle18_07_11_dasm(DASM_PARAMS); break; // PUSH_S blink - case 0x12: size = arcompact_handle18_07_12_dasm(DASM_PARAMS); break; // <illegal 0x18_07_12> - case 0x13: size = arcompact_handle18_07_13_dasm(DASM_PARAMS); break; // <illegal 0x18_07_13> - case 0x14: size = arcompact_handle18_07_14_dasm(DASM_PARAMS); break; // <illegal 0x18_07_14> - case 0x15: size = arcompact_handle18_07_15_dasm(DASM_PARAMS); break; // <illegal 0x18_07_15> - case 0x16: size = arcompact_handle18_07_16_dasm(DASM_PARAMS); break; // <illegal 0x18_07_16> - case 0x17: size = arcompact_handle18_07_17_dasm(DASM_PARAMS); break; // <illegal 0x18_07_17> - case 0x18: size = arcompact_handle18_07_18_dasm(DASM_PARAMS); break; // <illegal 0x18_07_18> - case 0x19: size = arcompact_handle18_07_19_dasm(DASM_PARAMS); break; // <illegal 0x18_07_19> - case 0x1a: size = arcompact_handle18_07_1a_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1a> - case 0x1b: size = arcompact_handle18_07_1b_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1b> - case 0x1c: size = arcompact_handle18_07_1c_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1c> - case 0x1d: size = arcompact_handle18_07_1d_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1d> - case 0x1e: size = arcompact_handle18_07_1e_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1e> - case 0x1f: size = arcompact_handle18_07_1f_dasm(DASM_PARAMS); break; // <illegal 0x18_07_1f> + case 0x00:size = handle18_07_00_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_00> + case 0x01:size = handle18_07_01_dasm(stream, pc, op, opcodes); break; // PUSH_S b + case 0x02:size = handle18_07_02_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_02> + case 0x03:size = handle18_07_03_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_03> + case 0x04:size = handle18_07_04_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_04> + case 0x05:size = handle18_07_05_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_05> + case 0x06:size = handle18_07_06_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_06> + case 0x07:size = handle18_07_07_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_07> + case 0x08:size = handle18_07_08_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_08> + case 0x09:size = handle18_07_09_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_09> + case 0x0a:size = handle18_07_0a_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0a> + case 0x0b:size = handle18_07_0b_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0b> + case 0x0c:size = handle18_07_0c_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0c> + case 0x0d:size = handle18_07_0d_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0d> + case 0x0e:size = handle18_07_0e_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0e> + case 0x0f:size = handle18_07_0f_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_0f> + case 0x10:size = handle18_07_10_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_10> + case 0x11:size = handle18_07_11_dasm(stream, pc, op, opcodes); break; // PUSH_S blink + case 0x12:size = handle18_07_12_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_12> + case 0x13:size = handle18_07_13_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_13> + case 0x14:size = handle18_07_14_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_14> + case 0x15:size = handle18_07_15_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_15> + case 0x16:size = handle18_07_16_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_16> + case 0x17:size = handle18_07_17_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_17> + case 0x18:size = handle18_07_18_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_18> + case 0x19:size = handle18_07_19_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_19> + case 0x1a:size = handle18_07_1a_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1a> + case 0x1b:size = handle18_07_1b_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1b> + case 0x1c:size = handle18_07_1c_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1c> + case 0x1d:size = handle18_07_1d_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1d> + case 0x1e:size = handle18_07_1e_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1e> + case 0x1f:size = handle18_07_1f_dasm(stream, pc, op, opcodes); break; // <illegal 0x18_07_1f> } return size; } -int arcompact_handle19_dasm(DASM_OPS_16) +int arcompact_disassembler::handle19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0600) >> 9; @@ -916,15 +913,15 @@ int arcompact_handle19_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle19_00_dasm(DASM_PARAMS); break; // LD_S (GP) - case 0x01: size = arcompact_handle19_01_dasm(DASM_PARAMS); break; // LDB_S (GP) - case 0x02: size = arcompact_handle19_02_dasm(DASM_PARAMS); break; // LDW_S (GP) - case 0x03: size = arcompact_handle19_03_dasm(DASM_PARAMS); break; // ADD_S (GP) + case 0x00:size = handle19_00_dasm(stream, pc, op, opcodes); break; // LD_S (GP) + case 0x01:size = handle19_01_dasm(stream, pc, op, opcodes); break; // LDB_S (GP) + case 0x02:size = handle19_02_dasm(stream, pc, op, opcodes); break; // LDW_S (GP) + case 0x03:size = handle19_03_dasm(stream, pc, op, opcodes); break; // ADD_S (GP) } return size; } -int arcompact_handle1c_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0080) >> 7; @@ -932,13 +929,13 @@ int arcompact_handle1c_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle1c_00_dasm(DASM_PARAMS); break; // ADD_S - case 0x01: size = arcompact_handle1c_01_dasm(DASM_PARAMS); break; // CMP_S + case 0x00:size = handle1c_00_dasm(stream, pc, op, opcodes); break; // ADD_S + case 0x01:size = handle1c_01_dasm(stream, pc, op, opcodes); break; // CMP_S } return size; } -int arcompact_handle1d_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0080) >> 7; @@ -946,13 +943,13 @@ int arcompact_handle1d_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle1d_00_dasm(DASM_PARAMS); break; // BREQ_S - case 0x01: size = arcompact_handle1d_01_dasm(DASM_PARAMS); break; // BRNE_S + case 0x00:size = handle1d_00_dasm(stream, pc, op, opcodes); break; // BREQ_S + case 0x01:size = handle1d_01_dasm(stream, pc, op, opcodes); break; // BRNE_S } return size; } -int arcompact_handle1e_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr = (op & 0x0600) >> 9; @@ -960,15 +957,15 @@ int arcompact_handle1e_dasm(DASM_OPS_16) switch (subinstr) { - case 0x00: size = arcompact_handle1e_00_dasm(DASM_PARAMS); break; // B_S - case 0x01: size = arcompact_handle1e_01_dasm(DASM_PARAMS); break; // BEQ_S - case 0x02: size = arcompact_handle1e_02_dasm(DASM_PARAMS); break; // BNE_S - case 0x03: size = arcompact_handle1e_03_dasm(DASM_PARAMS); break; // Bcc_S + case 0x00:size = handle1e_00_dasm(stream, pc, op, opcodes); break; // B_S + case 0x01:size = handle1e_01_dasm(stream, pc, op, opcodes); break; // BEQ_S + case 0x02:size = handle1e_02_dasm(stream, pc, op, opcodes); break; // BNE_S + case 0x03:size = handle1e_03_dasm(stream, pc, op, opcodes); break; // Bcc_S } return size; } -int arcompact_handle1e_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1e_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int size = 2; uint8_t subinstr2 = (op & 0x01c0) >> 6; @@ -976,14 +973,14 @@ int arcompact_handle1e_03_dasm(DASM_OPS_16) switch (subinstr2) { - case 0x00: size = arcompact_handle1e_03_00_dasm(DASM_PARAMS); break; // BGT_S - case 0x01: size = arcompact_handle1e_03_01_dasm(DASM_PARAMS); break; // BGE_S - case 0x02: size = arcompact_handle1e_03_02_dasm(DASM_PARAMS); break; // BLT_S - case 0x03: size = arcompact_handle1e_03_03_dasm(DASM_PARAMS); break; // BLE_S - case 0x04: size = arcompact_handle1e_03_04_dasm(DASM_PARAMS); break; // BHI_S - case 0x05: size = arcompact_handle1e_03_05_dasm(DASM_PARAMS); break; // BHS_S - case 0x06: size = arcompact_handle1e_03_06_dasm(DASM_PARAMS); break; // BLO_S - case 0x07: size = arcompact_handle1e_03_07_dasm(DASM_PARAMS); break; // BLS_S + case 0x00:size = handle1e_03_00_dasm(stream, pc, op, opcodes); break; // BGT_S + case 0x01:size = handle1e_03_01_dasm(stream, pc, op, opcodes); break; // BGE_S + case 0x02:size = handle1e_03_02_dasm(stream, pc, op, opcodes); break; // BLT_S + case 0x03:size = handle1e_03_03_dasm(stream, pc, op, opcodes); break; // BLE_S + case 0x04:size = handle1e_03_04_dasm(stream, pc, op, opcodes); break; // BHI_S + case 0x05:size = handle1e_03_05_dasm(stream, pc, op, opcodes); break; // BHS_S + case 0x06:size = handle1e_03_06_dasm(stream, pc, op, opcodes); break; // BLO_S + case 0x07:size = handle1e_03_07_dasm(stream, pc, op, opcodes); break; // BLS_S } return size; diff --git a/src/devices/cpu/arcompact/arcompactdasm_dispatch.h b/src/devices/cpu/arcompact/arcompactdasm_dispatch.h deleted file mode 100644 index 519f4b7ae4e..00000000000 --- a/src/devices/cpu/arcompact/arcompactdasm_dispatch.h +++ /dev/null @@ -1,50 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:David Haywood -/*********************************\ - - ARCompact disassembler - -\*********************************/ - -#define DASM_OPS_16 std::ostream &stream, offs_t pc, uint16_t op, const uint8_t* oprom -#define DASM_OPS_32 std::ostream &stream, offs_t pc, uint32_t op, const uint8_t* oprom -#define DASM_PARAMS stream, pc, op, oprom - -#define LIMM_REG 62 - -#define GET_LIMM_32 \ - limm = oprom[6] | (oprom[7] << 8); \ - limm |= (oprom[4] << 16) | (oprom[5] << 24); - - -int arcompact_handle00_dasm(DASM_OPS_32); -int arcompact_handle01_dasm(DASM_OPS_32); -int arcompact_handle01_00_dasm(DASM_OPS_32); -int arcompact_handle01_01_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_dasm(DASM_OPS_32); -int arcompact_handle04_dasm(DASM_OPS_32); -int arcompact_handle04_2f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_dasm(DASM_OPS_32); -int arcompact_handle05_dasm(DASM_OPS_32); - -int arcompact_handle05_2f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_dasm(DASM_OPS_32); - - -int arcompact_handle0c_dasm(DASM_OPS_16); -int arcompact_handle0d_dasm(DASM_OPS_16); -int arcompact_handle0e_dasm(DASM_OPS_16); -int arcompact_handle0f_dasm(DASM_OPS_16); -int arcompact_handle0f_00_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_dasm(DASM_OPS_16); -int arcompact_handle17_dasm(DASM_OPS_16); -int arcompact_handle18_dasm(DASM_OPS_16); -int arcompact_handle18_05_dasm(DASM_OPS_16); -int arcompact_handle18_06_dasm(DASM_OPS_16); -int arcompact_handle18_07_dasm(DASM_OPS_16); -int arcompact_handle19_dasm(DASM_OPS_16); -int arcompact_handle1c_dasm(DASM_OPS_16); -int arcompact_handle1d_dasm(DASM_OPS_16); -int arcompact_handle1e_dasm(DASM_OPS_16); -int arcompact_handle1e_03_dasm(DASM_OPS_16); diff --git a/src/devices/cpu/arcompact/arcompactdasm_ops.cpp b/src/devices/cpu/arcompact/arcompactdasm_ops.cpp index dd214e0cb02..dadc0f856a4 100644 --- a/src/devices/cpu/arcompact/arcompactdasm_ops.cpp +++ b/src/devices/cpu/arcompact/arcompactdasm_ops.cpp @@ -7,9 +7,8 @@ \*********************************/ #include "emu.h" -#include <stdarg.h> -#include "arcompactdasm_ops.h" +#include "arcompactdasm.h" #define GET_01_01_01_BRANCH_ADDR \ int32_t address = (op & 0x00fe0000) >> 17; \ @@ -79,9 +78,9 @@ // this is as messed up as the rest of the 16-bit alignment in LE mode... +#define LIMM_REG 62 #define GET_LIMM \ - limm = oprom[4] | (oprom[5] << 8); \ - limm |= (oprom[2] << 16) | (oprom[3] << 24); + limm = opcodes.r32(pc+2); #define PC_ALIGNED32 \ (pc&0xfffffffc) @@ -92,7 +91,7 @@ * * ************************************************************************************************************************************/ -int arcompact_handle00_00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle00_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; // Branch Conditionally @@ -107,7 +106,7 @@ int arcompact_handle00_00_dasm(DASM_OPS_32) return size; } -int arcompact_handle00_01_dasm(DASM_OPS_32) +int arcompact_disassembler::handle00_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; // Branch Unconditionally Far @@ -125,7 +124,7 @@ int arcompact_handle00_01_dasm(DASM_OPS_32) return size; } -int arcompact_handle01_00_00dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_00_00dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; @@ -142,7 +141,7 @@ int arcompact_handle01_00_00dasm(DASM_OPS_32) return size; } -int arcompact_handle01_00_01dasm(DASM_OPS_32) +int arcompact_disassembler::handle01_00_01dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; // Branch and Link Unconditionally Far @@ -162,7 +161,7 @@ int arcompact_handle01_00_01dasm(DASM_OPS_32) -int arcompact_01_01_00_helper(DASM_OPS_32, const char* optext) +int arcompact_disassembler::handle01_01_00_helper(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext) { int size = 4; @@ -184,7 +183,7 @@ int arcompact_01_01_00_helper(DASM_OPS_32, const char* optext) else { uint32_t limm; - GET_LIMM_32; + GET_LIMM; size = 8; if ((breg == LIMM_REG) && (creg != LIMM_REG)) @@ -208,16 +207,48 @@ int arcompact_01_01_00_helper(DASM_OPS_32, const char* optext) // register - register cases -int arcompact_handle01_01_00_00_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BREQ"); } -int arcompact_handle01_01_00_01_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRNE"); } -int arcompact_handle01_01_00_02_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRLT"); } -int arcompact_handle01_01_00_03_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRGE"); } -int arcompact_handle01_01_00_04_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRLO"); } -int arcompact_handle01_01_00_05_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BRHS"); } -int arcompact_handle01_01_00_0e_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BBIT0");} -int arcompact_handle01_01_00_0f_dasm(DASM_OPS_32) { return arcompact_01_01_00_helper( DASM_PARAMS, "BBIT1");} +int arcompact_disassembler::handle01_01_00_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BREQ"); +} + +int arcompact_disassembler::handle01_01_00_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRNE"); +} + +int arcompact_disassembler::handle01_01_00_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRLT"); +} + +int arcompact_disassembler::handle01_01_00_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRGE"); +} + +int arcompact_disassembler::handle01_01_00_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRLO"); +} -int arcompact_01_01_01_helper(DASM_OPS_32, const char* optext) +int arcompact_disassembler::handle01_01_00_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BRHS"); +} + +int arcompact_disassembler::handle01_01_00_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BBIT0"); +} + +int arcompact_disassembler::handle01_01_00_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_00_helper( stream, pc, op, opcodes, "BBIT1"); +} + + +int arcompact_disassembler::handle01_01_01_helper(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext) { int size = 4; @@ -240,17 +271,48 @@ int arcompact_01_01_01_helper(DASM_OPS_32, const char* optext) } // register -immediate cases -int arcompact_handle01_01_01_00_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BREQ"); } -int arcompact_handle01_01_01_01_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRNE"); } -int arcompact_handle01_01_01_02_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRLT"); } -int arcompact_handle01_01_01_03_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRGE"); } -int arcompact_handle01_01_01_04_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRLO"); } -int arcompact_handle01_01_01_05_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BRHS"); } -int arcompact_handle01_01_01_0e_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BBIT0"); } -int arcompact_handle01_01_01_0f_dasm(DASM_OPS_32) { return arcompact_01_01_01_helper(DASM_PARAMS, "BBIT1"); } +int arcompact_disassembler::handle01_01_01_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BREQ"); +} + +int arcompact_disassembler::handle01_01_01_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRNE"); +} +int arcompact_disassembler::handle01_01_01_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRLT"); +} + +int arcompact_disassembler::handle01_01_01_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRGE"); +} + +int arcompact_disassembler::handle01_01_01_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRLO"); +} + +int arcompact_disassembler::handle01_01_01_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BRHS"); +} + +int arcompact_disassembler::handle01_01_01_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BBIT0"); +} + +int arcompact_disassembler::handle01_01_01_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle01_01_01_helper(stream, pc, op, opcodes, "BBIT1"); +} -int arcompact_handle02_dasm(DASM_OPS_32) + +int arcompact_disassembler::handle02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { // bitpos // 1111 1111 1111 1111 0000 0000 0000 0000 @@ -273,7 +335,7 @@ int arcompact_handle02_dasm(DASM_OPS_32) uint32_t limm = 0; if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; } @@ -293,7 +355,7 @@ int arcompact_handle02_dasm(DASM_OPS_32) return size; } -int arcompact_handle03_dasm(DASM_OPS_32) +int arcompact_disassembler::handle03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { int size = 4; uint32_t limm = 0; @@ -317,7 +379,7 @@ int arcompact_handle03_dasm(DASM_OPS_32) if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; } @@ -339,7 +401,7 @@ int arcompact_handle03_dasm(DASM_OPS_32) { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } util::stream_format(stream, "(%08x)", limm); @@ -356,7 +418,7 @@ int arcompact_handle03_dasm(DASM_OPS_32) return size; } -int arcompact_handle04_p00_helper_dasm(DASM_OPS_32, const char* optext, int ignore_dst, int b_reserved) +int arcompact_disassembler::handle04_p00_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved) { // PP // 0010 0bbb 00ii iiii FBBB CCCC CCAA AAAA @@ -376,7 +438,7 @@ int arcompact_handle04_p00_helper_dasm(DASM_OPS_32, const char* optext, int igno if ((!b_reserved) && (breg == LIMM_REG)) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; } @@ -385,7 +447,7 @@ int arcompact_handle04_p00_helper_dasm(DASM_OPS_32, const char* optext, int igno { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } } @@ -428,7 +490,7 @@ int arcompact_handle04_p00_helper_dasm(DASM_OPS_32, const char* optext, int igno } // like p00 but with 'u6' istead of C -int arcompact_handle04_p01_helper_dasm(DASM_OPS_32, const char* optext, int ignore_dst, int b_reserved) +int arcompact_disassembler::handle04_p01_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved) { // PP // 0010 0bbb 01ii iiii FBBB uuuu uuAA AAAA @@ -448,7 +510,7 @@ int arcompact_handle04_p01_helper_dasm(DASM_OPS_32, const char* optext, int igno if ((!b_reserved) && (breg == LIMM_REG)) { - GET_LIMM_32; + GET_LIMM; size = 8; // got_limm = 1; } @@ -488,7 +550,7 @@ int arcompact_handle04_p01_helper_dasm(DASM_OPS_32, const char* optext, int igno } -int arcompact_handle04_p10_helper_dasm(DASM_OPS_32, const char* optext, int b_reserved) +int arcompact_disassembler::handle04_p10_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved) { int size = 4; uint32_t limm; @@ -507,7 +569,7 @@ int arcompact_handle04_p10_helper_dasm(DASM_OPS_32, const char* optext, int b_re { if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; //got_limm = 1; util::stream_format(stream, " 0x%08x ", limm); @@ -527,7 +589,7 @@ int arcompact_handle04_p10_helper_dasm(DASM_OPS_32, const char* optext, int b_re return size; } -int arcompact_handle04_p11_m0_helper_dasm(DASM_OPS_32, const char* optext, int b_reserved) +int arcompact_disassembler::handle04_p11_m0_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved) { int size = 4; uint32_t limm = 0; @@ -546,7 +608,7 @@ int arcompact_handle04_p11_m0_helper_dasm(DASM_OPS_32, const char* optext, int b { if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; util::stream_format(stream, " 0x%08x ", limm); @@ -570,7 +632,7 @@ int arcompact_handle04_p11_m0_helper_dasm(DASM_OPS_32, const char* optext, int b { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } util::stream_format(stream, " 0x%08x ", limm); @@ -583,7 +645,7 @@ int arcompact_handle04_p11_m0_helper_dasm(DASM_OPS_32, const char* optext, int b return size; } -int arcompact_handle04_p11_m1_helper_dasm(DASM_OPS_32, const char* optext, int b_reserved) +int arcompact_disassembler::handle04_p11_m1_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved) { int size = 4; uint32_t limm; @@ -602,7 +664,7 @@ int arcompact_handle04_p11_m1_helper_dasm(DASM_OPS_32, const char* optext, int b { if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; //got_limm = 1; util::stream_format(stream, " 0x%08x ", limm); @@ -627,213 +689,213 @@ int arcompact_handle04_p11_m1_helper_dasm(DASM_OPS_32, const char* optext, int b return size; } -int arcompact_handle04_p11_helper_dasm(DASM_OPS_32, const char* optext, int b_reserved) +int arcompact_disassembler::handle04_p11_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int b_reserved) { int M = (op & 0x00000020) >> 5; op &= ~0x00000020; switch (M) { - case 0x00: return arcompact_handle04_p11_m0_helper_dasm(DASM_PARAMS, optext, b_reserved); - case 0x01: return arcompact_handle04_p11_m1_helper_dasm(DASM_PARAMS, optext, b_reserved); + case 0x00: return handle04_p11_m0_helper_dasm(stream, pc, op, opcodes, optext, b_reserved); + case 0x01: return handle04_p11_m1_helper_dasm(stream, pc, op, opcodes, optext, b_reserved); } return 0; } -int arcompact_handle04_helper_dasm(DASM_OPS_32, const char* optext, int ignore_dst, int b_reserved) +int arcompact_disassembler::handle04_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext, int ignore_dst, int b_reserved) { COMMON32_GET_p; switch (p) { - case 0x00: return arcompact_handle04_p00_helper_dasm(DASM_PARAMS, optext, ignore_dst, b_reserved); - case 0x01: return arcompact_handle04_p01_helper_dasm(DASM_PARAMS, optext, ignore_dst, b_reserved); - case 0x02: return arcompact_handle04_p10_helper_dasm(DASM_PARAMS, optext, b_reserved); - case 0x03: return arcompact_handle04_p11_helper_dasm(DASM_PARAMS, optext, b_reserved); + case 0x00: return handle04_p00_helper_dasm(stream, pc, op, opcodes, optext, ignore_dst, b_reserved); + case 0x01: return handle04_p01_helper_dasm(stream, pc, op, opcodes, optext, ignore_dst, b_reserved); + case 0x02: return handle04_p10_helper_dasm(stream, pc, op, opcodes, optext, b_reserved); + case 0x03: return handle04_p11_helper_dasm(stream, pc, op, opcodes, optext, b_reserved); } return 0; } -int arcompact_handle04_00_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADD", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADD", 0,0); } -int arcompact_handle04_01_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADC", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADC", 0,0); } -int arcompact_handle04_02_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUB", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SUB", 0,0); } -int arcompact_handle04_03_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SBC", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SBC", 0,0); } -int arcompact_handle04_04_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "AND", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "AND", 0,0); } -int arcompact_handle04_05_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "OR", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "OR", 0,0); } -int arcompact_handle04_06_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BIC", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BIC", 0,0); } -int arcompact_handle04_07_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "XOR", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "XOR", 0,0); } -int arcompact_handle04_08_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MAX", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MAX", 0,0); } -int arcompact_handle04_09_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MIN", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MIN", 0,0); } -int arcompact_handle04_0a_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MOV", 1,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MOV", 1,0); } -int arcompact_handle04_0b_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "TST", 1,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "TST", 1,0); } -int arcompact_handle04_0c_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "CMP", 1,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "CMP", 1,0); } -int arcompact_handle04_0d_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "RCMP", 1,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "RCMP", 1,0); } -int arcompact_handle04_0e_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "RSUB", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "RSUB", 0,0); } -int arcompact_handle04_0f_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BSET", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BSET", 0,0); } -int arcompact_handle04_10_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BCLR", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BCLR", 0,0); } -int arcompact_handle04_11_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BTST", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BTST", 0,0); } -int arcompact_handle04_12_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BXOR", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BXOR", 0,0); } -int arcompact_handle04_13_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "BMSK", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "BMSK", 0,0); } -int arcompact_handle04_14_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADD1", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADD1", 0,0); } -int arcompact_handle04_15_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADD2", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADD2", 0,0); } -int arcompact_handle04_16_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADD3", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "ADD3", 0,0); } -int arcompact_handle04_17_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUB1", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SUB1", 0,0); } -int arcompact_handle04_18_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUB2", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SUB2", 0,0); } -int arcompact_handle04_19_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUB3", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "SUB3", 0,0); } -int arcompact_handle04_1a_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MPY", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MPY", 0,0); } // * -int arcompact_handle04_1b_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MPYH", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MPYH", 0,0); } // * -int arcompact_handle04_1c_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MPYHU", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MPYHU", 0,0); } // * -int arcompact_handle04_1d_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "MPYU", 0,0); + return handle04_helper_dasm(stream, pc, op, opcodes, "MPYU", 0,0); } // * -int arcompact_handle04_20_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "J", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "J", 1,1); } -int arcompact_handle04_21_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "J.D", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "J.D", 1,1); } -int arcompact_handle04_22_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "JL", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "JL", 1,1); } -int arcompact_handle04_23_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { - return arcompact_handle04_helper_dasm(DASM_PARAMS, "JL.D", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "JL.D", 1,1); } -int arcompact_handle04_28_dasm(DASM_OPS_32) // LPcc (loop setup) +int arcompact_disassembler::handle04_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // LPcc (loop setup) { COMMON32_GET_breg; // breg is reserved COMMON32_GET_p; @@ -879,7 +941,8 @@ int arcompact_handle04_28_dasm(DASM_OPS_32) // LPcc (loop setup) } \ else \ util::stream_format(stream, "[%03x]", auxreg); -int arcompact_handle04_2a_dasm(DASM_OPS_32) // Load FROM Auxiliary register TO register + +int arcompact_disassembler::handle04_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // Load FROM Auxiliary register TO register { // pp F // 0010 0bbb 0010 1010 0BBB CCCC CCRR RRRR @@ -922,7 +985,7 @@ int arcompact_handle04_2a_dasm(DASM_OPS_32) // Load FROM Auxiliary register TO { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } @@ -962,7 +1025,7 @@ int arcompact_handle04_2a_dasm(DASM_OPS_32) // Load FROM Auxiliary register TO return size; } -int arcompact_handle04_2b_dasm(DASM_OPS_32) // Store TO Auxiliary register FROM register +int arcompact_disassembler::handle04_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) // Store TO Auxiliary register FROM register { // code at ~ 40073DFE in leapster bios is manually setting up a loop this way // rather than using the lPcc opcode @@ -983,7 +1046,7 @@ int arcompact_handle04_2b_dasm(DASM_OPS_32) // Store TO Auxiliary register FROM if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; util::stream_format(stream, " %08x -> ", limm); @@ -1005,7 +1068,7 @@ int arcompact_handle04_2b_dasm(DASM_OPS_32) // Store TO Auxiliary register FROM { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } @@ -1052,14 +1115,14 @@ int arcompact_handle04_2b_dasm(DASM_OPS_32) // Store TO Auxiliary register FROM return size;} -int arcompact_handle04_29_dasm(DASM_OPS_32) +int arcompact_disassembler::handle04_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { // leapster bios uses formats for FLAG that are not defined, bug I guess work anyway (P modes 0 / 1) - return arcompact_handle04_helper_dasm(DASM_PARAMS, "FLAG", 1,1); + return handle04_helper_dasm(stream, pc, op, opcodes, "FLAG", 1,1); } -int arcompact_handle04_2f_helper_dasm(DASM_OPS_32, const char* optext) +int arcompact_disassembler::handle04_2f_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext) { // // 0010 0bbb pp10 1111 FBBB CCCC CCII IIII @@ -1090,7 +1153,7 @@ int arcompact_handle04_2f_helper_dasm(DASM_OPS_32, const char* optext) if (creg == LIMM_REG) { uint32_t limm; - GET_LIMM_32; + GET_LIMM; size = 8; util::stream_format(stream, "(%08x) ", limm); @@ -1119,29 +1182,106 @@ int arcompact_handle04_2f_helper_dasm(DASM_OPS_32, const char* optext) } -int arcompact_handle04_2f_00_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "ASL"); } // ASL -int arcompact_handle04_2f_01_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "ASR"); } // ASR -int arcompact_handle04_2f_02_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "LSR"); } // LSR -int arcompact_handle04_2f_03_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "ROR"); } // ROR -int arcompact_handle04_2f_04_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "RCC"); } // RCC -int arcompact_handle04_2f_05_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "SEXB"); } // SEXB -int arcompact_handle04_2f_06_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "SEXW"); } // SEXW -int arcompact_handle04_2f_07_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "EXTB"); } // EXTB +int arcompact_disassembler::handle04_2f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "ASL"); +} // ASL + +int arcompact_disassembler::handle04_2f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "ASR"); +} // ASR + +int arcompact_disassembler::handle04_2f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "LSR"); +} // LSR + +int arcompact_disassembler::handle04_2f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "ROR"); +} // ROR + +int arcompact_disassembler::handle04_2f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "RCC"); +} // RCC + +int arcompact_disassembler::handle04_2f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "SEXB"); +} // SEXB + +int arcompact_disassembler::handle04_2f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "SEXW"); +} // SEXW + +int arcompact_disassembler::handle04_2f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "EXTB"); +} // EXTB + + +int arcompact_disassembler::handle04_2f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "EXTW"); +} // EXTW + + + +int arcompact_disassembler::handle04_2f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "ABS"); +} // ABS + +int arcompact_disassembler::handle04_2f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "NOT"); +} // NOT + +int arcompact_disassembler::handle04_2f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "RCL"); +} // RLC + +int arcompact_disassembler::handle04_2f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_2f_helper_dasm(stream, pc, op, opcodes, "EX"); +} // EX + -int arcompact_handle04_2f_08_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "EXTW"); } // EXTW +int arcompact_disassembler::handle04_2f_3f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "SLEEP (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "SWI / TRAP0 (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "SYNC (%08x)", op); + return 4; +} -int arcompact_handle04_2f_09_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "ABS"); } // ABS -int arcompact_handle04_2f_0a_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "NOT"); } // NOT -int arcompact_handle04_2f_0b_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "RCL"); } // RLC -int arcompact_handle04_2f_0c_dasm(DASM_OPS_32) { return arcompact_handle04_2f_helper_dasm(DASM_PARAMS, "EX"); } // EX +int arcompact_disassembler::handle04_2f_3f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "RTIE (%08x)", op); + return 4; +} +int arcompact_disassembler::handle04_2f_3f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "BRK (%08x)", op); + return 4; +} -int arcompact_handle04_2f_3f_01_dasm(DASM_OPS_32) { util::stream_format( stream, "SLEEP (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_02_dasm(DASM_OPS_32) { util::stream_format( stream, "SWI / TRAP0 (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_03_dasm(DASM_OPS_32) { util::stream_format( stream, "SYNC (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_04_dasm(DASM_OPS_32) { util::stream_format( stream, "RTIE (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_05_dasm(DASM_OPS_32) { util::stream_format( stream, "BRK (%08x)", op); return 4; } @@ -1151,7 +1291,7 @@ int arcompact_handle04_2f_3f_05_dasm(DASM_OPS_32) { util::stream_format( stream // 0010 0bbb aa11 0ZZX DBBB CCCC CCAA AAAA // note, bits 11 0ZZX are part of the sub-opcode # already - this is a special encoding -int arcompact_handle04_3x_helper_dasm(DASM_OPS_32, int dsize, int extend) +int arcompact_disassembler::handle04_3x_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, int dsize, int extend) { int size = 4; uint32_t limm=0; @@ -1174,7 +1314,7 @@ int arcompact_handle04_3x_helper_dasm(DASM_OPS_32, int dsize, int extend) if (breg == LIMM_REG) { - GET_LIMM_32; + GET_LIMM; size = 8; got_limm = 1; util::stream_format(stream, "[%08x, ", limm); @@ -1189,7 +1329,7 @@ int arcompact_handle04_3x_helper_dasm(DASM_OPS_32, int dsize, int extend) { if (!got_limm) { - GET_LIMM_32; + GET_LIMM; size = 8; } util::stream_format(stream, "(%08x)]", limm); @@ -1207,43 +1347,127 @@ int arcompact_handle04_3x_helper_dasm(DASM_OPS_32, int dsize, int extend) } -int arcompact_handle04_30_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,0,0); } +int arcompact_disassembler::handle04_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,0,0); +} + // ZZ value of 0x0 with X of 1 is illegal -int arcompact_handle04_31_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,0,1); } -int arcompact_handle04_32_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,1,0); } -int arcompact_handle04_33_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,1,1); } -int arcompact_handle04_34_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,2,0); } -int arcompact_handle04_35_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,2,1); } +int arcompact_disassembler::handle04_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,0,1); +} + +int arcompact_disassembler::handle04_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,1,0); +} + +int arcompact_disassembler::handle04_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,1,1); +} + +int arcompact_disassembler::handle04_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,2,0); +} + +int arcompact_disassembler::handle04_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,2,1); +} + // ZZ value of 0x3 is illegal -int arcompact_handle04_36_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,3,0); } -int arcompact_handle04_37_dasm(DASM_OPS_32) { return arcompact_handle04_3x_helper_dasm(DASM_PARAMS,3,1); } +int arcompact_disassembler::handle04_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,3,0); +} + +int arcompact_disassembler::handle04_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_3x_helper_dasm(stream, pc, op, opcodes,3,1); +} + + + + + + + +int arcompact_disassembler::handle05_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ASL", 0,0); +} + +int arcompact_disassembler::handle05_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "LSR", 0,0); +} + +int arcompact_disassembler::handle05_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ASR", 0,0); +} + +int arcompact_disassembler::handle05_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ROR", 0,0); +} + +int arcompact_disassembler::handle05_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "MUL64", 2,0); +} // special + +int arcompact_disassembler::handle05_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "MULU64", 2,0); +} // special + +int arcompact_disassembler::handle05_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ADDS", 0,0); +} + +int arcompact_disassembler::handle05_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "SUBS", 0,0); +} +int arcompact_disassembler::handle05_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "DIVAW", 0,0); +} +int arcompact_disassembler::handle05_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ASLS", 0,0); +} -int arcompact_handle05_00_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ASL", 0,0); } -int arcompact_handle05_01_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "LSR", 0,0); } -int arcompact_handle05_02_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ASR", 0,0); } -int arcompact_handle05_03_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ROR", 0,0); } -int arcompact_handle05_04_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "MUL64", 2,0); } // special -int arcompact_handle05_05_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "MULU64", 2,0);} // special -int arcompact_handle05_06_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADDS", 0,0); } -int arcompact_handle05_07_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUBS", 0,0); } -int arcompact_handle05_08_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "DIVAW", 0,0); } +int arcompact_disassembler::handle05_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ASRS", 0,0); +} +int arcompact_disassembler::handle05_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "ADDSDW", 0,0); +} -int arcompact_handle05_0a_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ASLS", 0,0); } -int arcompact_handle05_0b_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ASRS", 0,0); } +int arcompact_disassembler::handle05_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle04_helper_dasm(stream, pc, op, opcodes, "SUBSDW", 0,0); +} -int arcompact_handle05_28_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "ADDSDW", 0,0); } -int arcompact_handle05_29_dasm(DASM_OPS_32) { return arcompact_handle04_helper_dasm(DASM_PARAMS, "SUBSDW", 0,0); } -int arcompact_handle05_2f_0x_helper_dasm(DASM_OPS_32, const char* optext) +int arcompact_disassembler::handle05_2f_0x_helper_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes, const char* optext) { // // 0010 1bbb pp10 1111 FBBB CCCC CCII IIII when pp == 0x00 @@ -1271,7 +1495,7 @@ int arcompact_handle05_2f_0x_helper_dasm(DASM_OPS_32, const char* optext) if (creg == LIMM_REG) { uint32_t limm; - GET_LIMM_32; + GET_LIMM; size = 8; util::stream_format(stream, "(%08x) ", limm); @@ -1299,48 +1523,84 @@ int arcompact_handle05_2f_0x_helper_dasm(DASM_OPS_32, const char* optext) } -int arcompact_handle05_2f_00_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "SWAP"); } -int arcompact_handle05_2f_01_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "NORM"); } -int arcompact_handle05_2f_02_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "SAT16"); } -int arcompact_handle05_2f_03_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "RND16"); } -int arcompact_handle05_2f_04_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "ABSSW"); } -int arcompact_handle05_2f_05_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "ABSS"); } -int arcompact_handle05_2f_06_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "NEGSW"); } -int arcompact_handle05_2f_07_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "NEGS"); } -int arcompact_handle05_2f_08_dasm(DASM_OPS_32) { return arcompact_handle05_2f_0x_helper_dasm(DASM_PARAMS, "NORMW"); } +int arcompact_disassembler::handle05_2f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "SWAP"); +} + +int arcompact_disassembler::handle05_2f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "NORM"); +} + +int arcompact_disassembler::handle05_2f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "SAT16"); +} +int arcompact_disassembler::handle05_2f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "RND16"); +} -int arcompact_handle06_dasm(DASM_OPS_32) +int arcompact_disassembler::handle05_2f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "ABSSW"); +} + +int arcompact_disassembler::handle05_2f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "ABSS"); +} + +int arcompact_disassembler::handle05_2f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "NEGSW"); +} + +int arcompact_disassembler::handle05_2f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "NEGS"); +} + +int arcompact_disassembler::handle05_2f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + return handle05_2f_0x_helper_dasm(stream, pc, op, opcodes, "NORMW"); +} + + + +int arcompact_disassembler::handle06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (06 ARC ext) (%08x)", op ); return 4; } -int arcompact_handle07_dasm(DASM_OPS_32) +int arcompact_disassembler::handle07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (07 User ext) (%08x)", op ); return 4; } -int arcompact_handle08_dasm(DASM_OPS_32) +int arcompact_disassembler::handle08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (08 User ext) (%08x)", op ); return 4; } -int arcompact_handle09_dasm(DASM_OPS_32) +int arcompact_disassembler::handle09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (09 Market ext) (%08x)", op ); return 4; } -int arcompact_handle0a_dasm(DASM_OPS_32) +int arcompact_disassembler::handle0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (0a Market ext) (%08x)", op ); return 4; } -int arcompact_handle0b_dasm(DASM_OPS_32) +int arcompact_disassembler::handle0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) { util::stream_format( stream, "op a,b,c (0b Market ext) (%08x)", op ); return 4; @@ -1348,7 +1608,7 @@ int arcompact_handle0b_dasm(DASM_OPS_32) -int arcompact_handle0c_helper_dasm(DASM_OPS_16, const char* optext, int format) +int arcompact_disassembler::handle0c_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int format) { int areg, breg, creg; @@ -1368,28 +1628,28 @@ int arcompact_handle0c_helper_dasm(DASM_OPS_16, const char* optext, int format) } -int arcompact_handle0c_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0c_helper_dasm(DASM_PARAMS, "LD_S", 0); + return handle0c_helper_dasm(stream, pc, op, opcodes, "LD_S", 0); } -int arcompact_handle0c_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0c_helper_dasm(DASM_PARAMS, "LDB_S", 0); + return handle0c_helper_dasm(stream, pc, op, opcodes, "LDB_S", 0); } -int arcompact_handle0c_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0c_helper_dasm(DASM_PARAMS, "LDW_S", 0); + return handle0c_helper_dasm(stream, pc, op, opcodes, "LDW_S", 0); } -int arcompact_handle0c_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0c_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0c_helper_dasm(DASM_PARAMS, "ADD_S", 1); + return handle0c_helper_dasm(stream, pc, op, opcodes, "ADD_S", 1); } -int arcompact_handle0d_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle0d_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int u, breg, creg; @@ -1405,29 +1665,29 @@ int arcompact_handle0d_helper_dasm(DASM_OPS_16, const char* optext) } -int arcompact_handle0d_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0d_helper_dasm(DASM_PARAMS, "ADD_S"); + return handle0d_helper_dasm(stream, pc, op, opcodes, "ADD_S"); } -int arcompact_handle0d_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0d_helper_dasm(DASM_PARAMS, "SUB_S"); + return handle0d_helper_dasm(stream, pc, op, opcodes, "SUB_S"); } -int arcompact_handle0d_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0d_helper_dasm(DASM_PARAMS, "ASL_S"); + return handle0d_helper_dasm(stream, pc, op, opcodes, "ASL_S"); } -int arcompact_handle0d_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0d_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0d_helper_dasm(DASM_PARAMS, "ASR_S"); + return handle0d_helper_dasm(stream, pc, op, opcodes, "ASR_S"); } -int arcompact_handle0e_0x_helper_dasm(DASM_OPS_16, const char* optext, int revop) +int arcompact_disassembler::handle0e_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int revop) { int h,breg; int size = 2; @@ -1455,29 +1715,29 @@ int arcompact_handle0e_0x_helper_dasm(DASM_OPS_16, const char* optext, int revop } -int arcompact_handle0e_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0e_0x_helper_dasm(DASM_PARAMS, "ADD_S", 0); + return handle0e_0x_helper_dasm(stream, pc, op, opcodes, "ADD_S", 0); } -int arcompact_handle0e_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0e_0x_helper_dasm(DASM_PARAMS, "MOV_S", 0); + return handle0e_0x_helper_dasm(stream, pc, op, opcodes, "MOV_S", 0); } -int arcompact_handle0e_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0e_0x_helper_dasm(DASM_PARAMS, "CMP_S", 0); + return handle0e_0x_helper_dasm(stream, pc, op, opcodes, "CMP_S", 0); } -int arcompact_handle0e_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle0e_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle0e_0x_helper_dasm(DASM_PARAMS, "MOV_S", 1); + return handle0e_0x_helper_dasm(stream, pc, op, opcodes, "MOV_S", 1); } -int arcompact_handle0f_00_0x_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle0f_00_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int breg; @@ -1492,28 +1752,72 @@ int arcompact_handle0f_00_0x_helper_dasm(DASM_OPS_16, const char* optext) -int arcompact_handle0f_00_00_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "J_S"); } -int arcompact_handle0f_00_01_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "J_S.D"); } -int arcompact_handle0f_00_02_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "JL_S"); } -int arcompact_handle0f_00_03_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "JL_S.D"); } -int arcompact_handle0f_00_06_dasm(DASM_OPS_16) { return arcompact_handle0f_00_0x_helper_dasm(DASM_PARAMS, "SUB_S.NE"); } +int arcompact_disassembler::handle0f_00_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "J_S"); +} + +int arcompact_disassembler::handle0f_00_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "J_S.D"); +} + +int arcompact_disassembler::handle0f_00_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "JL_S"); +} + +int arcompact_disassembler::handle0f_00_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "JL_S.D"); +} + +int arcompact_disassembler::handle0f_00_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_00_0x_helper_dasm(stream, pc, op, opcodes, "SUB_S.NE"); +} + // Zero parameters (ZOP) -int arcompact_handle0f_00_07_00_dasm(DASM_OPS_16) { util::stream_format( stream, "NOP_S"); return 2; } -int arcompact_handle0f_00_07_01_dasm(DASM_OPS_16) { util::stream_format( stream, "UNIMP_S"); return 2; } // Unimplemented Instruction, same as illegal, but recommended to fill blank space -int arcompact_handle0f_00_07_04_dasm(DASM_OPS_16) { util::stream_format( stream, "JEQ_S [blink]"); return 2; } -int arcompact_handle0f_00_07_05_dasm(DASM_OPS_16) { util::stream_format( stream, "JNE_S [blink]"); return 2; } -int arcompact_handle0f_00_07_06_dasm(DASM_OPS_16) { util::stream_format( stream, "J_S [blink]"); return 2; } -int arcompact_handle0f_00_07_07_dasm(DASM_OPS_16) { util::stream_format( stream, "J_S.D [blink]"); return 2; } +int arcompact_disassembler::handle0f_00_07_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "NOP_S"); return 2; +} +int arcompact_disassembler::handle0f_00_07_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "UNIMP_S"); return 2; +} // Unimplemented Instruction, same as illegal, but recommended to fill blank space +int arcompact_disassembler::handle0f_00_07_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "JEQ_S [blink]"); return 2; +} +int arcompact_disassembler::handle0f_00_07_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "JNE_S [blink]"); return 2; +} +int arcompact_disassembler::handle0f_00_07_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "J_S [blink]"); return 2; +} -int arcompact_handle0f_0x_helper_dasm(DASM_OPS_16, const char* optext, int nodst) +int arcompact_disassembler::handle0f_00_07_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format( stream, "J_S.D [blink]"); return 2; +} + + + + + + +int arcompact_disassembler::handle0f_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int nodst) { int breg, creg; @@ -1530,39 +1834,131 @@ int arcompact_handle0f_0x_helper_dasm(DASM_OPS_16, const char* optext, int nodst return 2; } -int arcompact_handle0f_02_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "SUB_S",0); } -int arcompact_handle0f_04_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "AND_S",0); } -int arcompact_handle0f_05_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "OR_S",0); } -int arcompact_handle0f_06_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "BIC_S",0); } -int arcompact_handle0f_07_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "XOR_S",0); } -int arcompact_handle0f_0b_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "TST_S",1); } -int arcompact_handle0f_0c_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "MUL64_S",2); } // actual destination is special multiply registers -int arcompact_handle0f_0d_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "SEXB_S",0); } -int arcompact_handle0f_0e_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "SEXW_S",0); } -int arcompact_handle0f_0f_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "EXTB_S",0); } -int arcompact_handle0f_10_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "EXTW_S",0); } -int arcompact_handle0f_11_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ABS_S",0); } -int arcompact_handle0f_12_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "NOT_S",0); } -int arcompact_handle0f_13_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "NEG_S",0); } -int arcompact_handle0f_14_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ADD1_S",0); } -int arcompact_handle0f_15_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ADD2_S",0); } -int arcompact_handle0f_16_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ADD3_S",0); } -int arcompact_handle0f_18_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ASL_S",0); } -int arcompact_handle0f_19_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "LSR_S",0); } -int arcompact_handle0f_1a_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ASR_S",0); } -int arcompact_handle0f_1b_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ASL1_S",0); } -int arcompact_handle0f_1c_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "ASR1_S",0); } -int arcompact_handle0f_1d_dasm(DASM_OPS_16) { return arcompact_handle0f_0x_helper_dasm(DASM_PARAMS, "LSR1_S",0); } - - -int arcompact_handle0f_1e_dasm(DASM_OPS_16) // special +int arcompact_disassembler::handle0f_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "SUB_S",0); +} + +int arcompact_disassembler::handle0f_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "AND_S",0); +} + +int arcompact_disassembler::handle0f_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "OR_S",0); +} + +int arcompact_disassembler::handle0f_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "BIC_S",0); +} + +int arcompact_disassembler::handle0f_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "XOR_S",0); +} + +int arcompact_disassembler::handle0f_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "TST_S",1); +} + +int arcompact_disassembler::handle0f_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "MUL64_S",2); +} // actual destination is special multiply registers + +int arcompact_disassembler::handle0f_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "SEXB_S",0); +} + +int arcompact_disassembler::handle0f_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "SEXW_S",0); +} + +int arcompact_disassembler::handle0f_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "EXTB_S",0); +} + +int arcompact_disassembler::handle0f_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "EXTW_S",0); +} + +int arcompact_disassembler::handle0f_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ABS_S",0); +} + +int arcompact_disassembler::handle0f_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "NOT_S",0); +} + +int arcompact_disassembler::handle0f_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "NEG_S",0); +} + +int arcompact_disassembler::handle0f_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ADD1_S",0); +} + +int arcompact_disassembler::handle0f_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ADD2_S",0); +} + +int arcompact_disassembler::handle0f_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ADD3_S",0); +} + +int arcompact_disassembler::handle0f_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ASL_S",0); +} + +int arcompact_disassembler::handle0f_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "LSR_S",0); +} + +int arcompact_disassembler::handle0f_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ASR_S",0); +} + +int arcompact_disassembler::handle0f_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ASL1_S",0); +} + +int arcompact_disassembler::handle0f_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "ASR1_S",0); +} + +int arcompact_disassembler::handle0f_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle0f_0x_helper_dasm(stream, pc, op, opcodes, "LSR1_S",0); +} + + + +int arcompact_disassembler::handle0f_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) // special { // 0111 1uuu uuu1 1110 int u = (op & 0x07e0)>>5; util::stream_format( stream, "TRAP_S %02x",u); return 2; } -int arcompact_handle0f_1f_dasm(DASM_OPS_16) // special +int arcompact_disassembler::handle0f_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) // special { int u = (op & 0x07e0)>>5; op &= ~0x07e0; @@ -1578,7 +1974,7 @@ int arcompact_handle0f_1f_dasm(DASM_OPS_16) // special } -int arcompact_handle_ld_helper_dasm(DASM_OPS_16, const char* optext, int shift, int swap) +int arcompact_disassembler::handle_ld_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int shift, int swap) { int breg, creg, u; @@ -1598,43 +1994,43 @@ int arcompact_handle_ld_helper_dasm(DASM_OPS_16, const char* optext, int shift, } -int arcompact_handle10_dasm(DASM_OPS_16) +int arcompact_disassembler::handle10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "LD_S", 2, 0); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "LD_S", 2, 0); } -int arcompact_handle11_dasm(DASM_OPS_16) +int arcompact_disassembler::handle11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "LDB_S", 0, 0); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "LDB_S", 0, 0); } -int arcompact_handle12_dasm(DASM_OPS_16) +int arcompact_disassembler::handle12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "LDW_S", 1, 0); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "LDW_S", 1, 0); } -int arcompact_handle13_dasm(DASM_OPS_16) +int arcompact_disassembler::handle13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "LDW_S.X", 1, 0); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "LDW_S.X", 1, 0); } -int arcompact_handle14_dasm(DASM_OPS_16) +int arcompact_disassembler::handle14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "ST_S", 2, 1); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "ST_S", 2, 1); } -int arcompact_handle15_dasm(DASM_OPS_16) +int arcompact_disassembler::handle15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "STB_S", 0, 1); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "STB_S", 0, 1); } -int arcompact_handle16_dasm(DASM_OPS_16) +int arcompact_disassembler::handle16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_ld_helper_dasm(DASM_PARAMS, "STW_S", 1, 1); + return handle_ld_helper_dasm(stream, pc, op, opcodes, "STW_S", 1, 1); } -int arcompact_handle_l7_0x_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle_l7_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int breg, u; @@ -1649,50 +2045,50 @@ int arcompact_handle_l7_0x_helper_dasm(DASM_OPS_16, const char* optext) } -int arcompact_handle17_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "ASL_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "ASL_S"); } -int arcompact_handle17_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "LSR_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "LSR_S"); } -int arcompact_handle17_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "ASR_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "ASR_S"); } -int arcompact_handle17_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "SUB_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "SUB_S"); } -int arcompact_handle17_04_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "BSET_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "BSET_S"); } -int arcompact_handle17_05_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "BCLR_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "BCLR_S"); } -int arcompact_handle17_06_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "BSMK_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "BSMK_S"); } -int arcompact_handle17_07_dasm(DASM_OPS_16) +int arcompact_disassembler::handle17_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle_l7_0x_helper_dasm(DASM_PARAMS, "BTST_S"); + return handle_l7_0x_helper_dasm(stream, pc, op, opcodes, "BTST_S"); } // op bits remaining for 0x18_xx subgroups 0x071f -int arcompact_handle18_0x_helper_dasm(DASM_OPS_16, const char* optext, int st, int format) +int arcompact_disassembler::handle18_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int st, int format) { int breg, u; @@ -1712,33 +2108,33 @@ int arcompact_handle18_0x_helper_dasm(DASM_OPS_16, const char* optext, int st, i return 2; } -int arcompact_handle18_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "LD_S", 0,0); + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "LD_S", 0,0); } -int arcompact_handle18_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "LDB_S", 0,0); + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "LDB_S", 0,0); } -int arcompact_handle18_02_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "ST_S", 1,0); + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "ST_S", 1,0); } -int arcompact_handle18_03_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "STB_S", 1,0); + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "STB_S", 1,0); } -int arcompact_handle18_04_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { - return arcompact_handle18_0x_helper_dasm(DASM_PARAMS, "ADD_S", 1,1); // check format + return handle18_0x_helper_dasm(stream, pc, op, opcodes, "ADD_S", 1,1); // check format } // op bits remaining for 0x18_05_xx subgroups 0x001f -int arcompact_handle18_05_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_05_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int u; COMMON16_GET_u5; @@ -1748,7 +2144,7 @@ int arcompact_handle18_05_00_dasm(DASM_OPS_16) } -int arcompact_handle18_05_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_05_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int u; COMMON16_GET_u5; @@ -1758,7 +2154,7 @@ int arcompact_handle18_05_01_dasm(DASM_OPS_16) } // op bits remaining for 0x18_06_xx subgroups 0x0700 -int arcompact_handle18_06_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_06_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg; COMMON16_GET_breg @@ -1769,7 +2165,7 @@ int arcompact_handle18_06_01_dasm(DASM_OPS_16) return 2; } -int arcompact_handle18_06_11_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_06_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int res = (op & 0x0700) >> 8; op &= ~0x0700; // all bits now used @@ -1783,7 +2179,7 @@ int arcompact_handle18_06_11_dasm(DASM_OPS_16) } // op bits remaining for 0x18_07_xx subgroups 0x0700 -int arcompact_handle18_07_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_07_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg; COMMON16_GET_breg @@ -1795,7 +2191,7 @@ int arcompact_handle18_07_01_dasm(DASM_OPS_16) } -int arcompact_handle18_07_11_dasm(DASM_OPS_16) +int arcompact_disassembler::handle18_07_11_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int res = (op & 0x0700) >> 8; op &= ~0x0700; // all bits now used @@ -1809,7 +2205,7 @@ int arcompact_handle18_07_11_dasm(DASM_OPS_16) } -int arcompact_handle19_0x_helper_dasm(DASM_OPS_16, const char* optext, int shift, int format) +int arcompact_disassembler::handle19_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext, int shift, int format) { int s; @@ -1831,12 +2227,28 @@ int arcompact_handle19_0x_helper_dasm(DASM_OPS_16, const char* optext, int shift return 2; } -int arcompact_handle19_00_dasm(DASM_OPS_16) { return arcompact_handle19_0x_helper_dasm(DASM_PARAMS, "LD_S", 2, 0); } -int arcompact_handle19_01_dasm(DASM_OPS_16) { return arcompact_handle19_0x_helper_dasm(DASM_PARAMS, "LDB_S", 0, 0); } -int arcompact_handle19_02_dasm(DASM_OPS_16) { return arcompact_handle19_0x_helper_dasm(DASM_PARAMS, "LDW_S", 1, 0); } -int arcompact_handle19_03_dasm(DASM_OPS_16) { return arcompact_handle19_0x_helper_dasm(DASM_PARAMS, "ADD_S", 2, 1); } +int arcompact_disassembler::handle19_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle19_0x_helper_dasm(stream, pc, op, opcodes, "LD_S", 2, 0); +} + +int arcompact_disassembler::handle19_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle19_0x_helper_dasm(stream, pc, op, opcodes, "LDB_S", 0, 0); +} + +int arcompact_disassembler::handle19_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle19_0x_helper_dasm(stream, pc, op, opcodes, "LDW_S", 1, 0); +} -int arcompact_handle1a_dasm(DASM_OPS_16) +int arcompact_disassembler::handle19_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle19_0x_helper_dasm(stream, pc, op, opcodes, "ADD_S", 2, 1); +} + + +int arcompact_disassembler::handle1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg, u; COMMON16_GET_breg; @@ -1848,7 +2260,7 @@ int arcompact_handle1a_dasm(DASM_OPS_16) return 2; } -int arcompact_handle1b_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg, u; COMMON16_GET_breg; @@ -1859,7 +2271,7 @@ int arcompact_handle1b_dasm(DASM_OPS_16) return 2; } -int arcompact_handle1c_00_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1c_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg, u; COMMON16_GET_breg; @@ -1870,7 +2282,7 @@ int arcompact_handle1c_00_dasm(DASM_OPS_16) return 2; } -int arcompact_handle1c_01_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1c_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int breg, u; COMMON16_GET_breg; @@ -1881,7 +2293,7 @@ int arcompact_handle1c_01_dasm(DASM_OPS_16) return 2; } -int arcompact_handle1d_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle1d_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int breg; COMMON16_GET_breg; @@ -1895,11 +2307,19 @@ int arcompact_handle1d_helper_dasm(DASM_OPS_16, const char* optext) } -int arcompact_handle1d_00_dasm(DASM_OPS_16) { return arcompact_handle1d_helper_dasm(DASM_PARAMS,"BREQ_S"); } -int arcompact_handle1d_01_dasm(DASM_OPS_16) { return arcompact_handle1d_helper_dasm(DASM_PARAMS,"BRNE_S"); } +int arcompact_disassembler::handle1d_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1d_helper_dasm(stream, pc, op, opcodes,"BREQ_S"); +} +int arcompact_disassembler::handle1d_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1d_helper_dasm(stream, pc, op, opcodes,"BRNE_S"); +} -int arcompact_handle1e_0x_helper_dasm(DASM_OPS_16, const char* optext) + + +int arcompact_disassembler::handle1e_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int s = (op & 0x01ff) >> 0; op &= ~0x01ff; if (s & 0x100) s = -0x100 + (s & 0xff); @@ -1910,11 +2330,23 @@ int arcompact_handle1e_0x_helper_dasm(DASM_OPS_16, const char* optext) -int arcompact_handle1e_00_dasm(DASM_OPS_16) { return arcompact_handle1e_0x_helper_dasm(DASM_PARAMS, "B_S"); } -int arcompact_handle1e_01_dasm(DASM_OPS_16) { return arcompact_handle1e_0x_helper_dasm(DASM_PARAMS, "BEQ_S"); } -int arcompact_handle1e_02_dasm(DASM_OPS_16) { return arcompact_handle1e_0x_helper_dasm(DASM_PARAMS, "BNE_S"); } +int arcompact_disassembler::handle1e_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_0x_helper_dasm(stream, pc, op, opcodes, "B_S"); +} + +int arcompact_disassembler::handle1e_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_0x_helper_dasm(stream, pc, op, opcodes, "BEQ_S"); +} + +int arcompact_disassembler::handle1e_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_0x_helper_dasm(stream, pc, op, opcodes, "BNE_S"); +} + -int arcompact_handle1e_03_0x_helper_dasm(DASM_OPS_16, const char* optext) +int arcompact_disassembler::handle1e_03_0x_helper_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes, const char* optext) { int s = (op & 0x003f) >> 0; op &= ~0x003f; if (s & 0x020) s = -0x20 + (s & 0x1f); @@ -1923,16 +2355,48 @@ int arcompact_handle1e_03_0x_helper_dasm(DASM_OPS_16, const char* optext) return 2; } -int arcompact_handle1e_03_00_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BGT_S"); } -int arcompact_handle1e_03_01_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BGE_S"); } -int arcompact_handle1e_03_02_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BLT_S"); } -int arcompact_handle1e_03_03_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BLE_S"); } -int arcompact_handle1e_03_04_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BHI_S"); } -int arcompact_handle1e_03_05_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BHS_S"); } -int arcompact_handle1e_03_06_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BLO_S"); } -int arcompact_handle1e_03_07_dasm(DASM_OPS_16) { return arcompact_handle1e_03_0x_helper_dasm(DASM_PARAMS, "BLS_S"); } +int arcompact_disassembler::handle1e_03_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BGT_S"); +} + +int arcompact_disassembler::handle1e_03_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BGE_S"); +} + +int arcompact_disassembler::handle1e_03_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BLT_S"); +} + +int arcompact_disassembler::handle1e_03_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BLE_S"); +} -int arcompact_handle1f_dasm(DASM_OPS_16) +int arcompact_disassembler::handle1e_03_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BHI_S"); +} + +int arcompact_disassembler::handle1e_03_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BHS_S"); +} + +int arcompact_disassembler::handle1e_03_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BLO_S"); +} + +int arcompact_disassembler::handle1e_03_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + return handle1e_03_0x_helper_dasm(stream, pc, op, opcodes, "BLS_S"); +} + + +int arcompact_disassembler::handle1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) { int s = (op & 0x07ff) >> 0; op &= ~0x07ff; if (s & 0x400) s = -0x400 + (s & 0x3ff); @@ -1947,411 +2411,2340 @@ int arcompact_handle1f_dasm(DASM_OPS_16) * * ************************************************************************************************************************************/ -int arcompact_handle01_01_00_06_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_06> (%08x)", op); return 4; } -int arcompact_handle01_01_00_07_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_07> (%08x)", op); return 4; } -int arcompact_handle01_01_00_08_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_08> (%08x)", op); return 4; } -int arcompact_handle01_01_00_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_09> (%08x)", op); return 4; } -int arcompact_handle01_01_00_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_0a> (%08x)", op); return 4; } -int arcompact_handle01_01_00_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_0b> (%08x)", op); return 4; } -int arcompact_handle01_01_00_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_0c> (%08x)", op); return 4; } -int arcompact_handle01_01_00_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_00_0d> (%08x)", op); return 4; } - -int arcompact_handle01_01_01_06_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_06> (%08x)", op); return 4; } -int arcompact_handle01_01_01_07_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_07> (%08x)", op); return 4; } -int arcompact_handle01_01_01_08_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_08> (%08x)", op); return 4; } -int arcompact_handle01_01_01_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_09> (%08x)", op); return 4; } -int arcompact_handle01_01_01_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_0a> (%08x)", op); return 4; } -int arcompact_handle01_01_01_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_0b> (%08x)", op); return 4; } -int arcompact_handle01_01_01_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_0c> (%08x)", op); return 4; } -int arcompact_handle01_01_01_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 01_01_01_0d> (%08x)", op); return 4; } - - -int arcompact_handle04_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_1e> (%08x)", op); return 4; } -int arcompact_handle04_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_1f> (%08x)", op); return 4; } - -int arcompact_handle04_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_24> (%08x)", op); return 4; } -int arcompact_handle04_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_25> (%08x)", op); return 4; } -int arcompact_handle04_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_26> (%08x)", op); return 4; } -int arcompact_handle04_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_27> (%08x)", op); return 4; } - -int arcompact_handle04_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2c> (%08x)", op); return 4; } -int arcompact_handle04_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2d> (%08x)", op); return 4; } -int arcompact_handle04_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2e> (%08x)", op); return 4; } - -int arcompact_handle04_2f_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_0d> (%08x)", op); return 4; } -int arcompact_handle04_2f_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_0e> (%08x)", op); return 4; } -int arcompact_handle04_2f_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_0f> (%08x)", op); return 4; } -int arcompact_handle04_2f_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_10> (%08x)", op); return 4; } -int arcompact_handle04_2f_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_11> (%08x)", op); return 4; } -int arcompact_handle04_2f_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_12> (%08x)", op); return 4; } -int arcompact_handle04_2f_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_13> (%08x)", op); return 4; } -int arcompact_handle04_2f_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_14> (%08x)", op); return 4; } -int arcompact_handle04_2f_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_15> (%08x)", op); return 4; } -int arcompact_handle04_2f_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_16> (%08x)", op); return 4; } -int arcompact_handle04_2f_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_17> (%08x)", op); return 4; } -int arcompact_handle04_2f_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_18> (%08x)", op); return 4; } -int arcompact_handle04_2f_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_19> (%08x)", op); return 4; } -int arcompact_handle04_2f_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1a> (%08x)", op); return 4; } -int arcompact_handle04_2f_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1b> (%08x)", op); return 4; } -int arcompact_handle04_2f_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1c> (%08x)", op); return 4; } -int arcompact_handle04_2f_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1d> (%08x)", op); return 4; } -int arcompact_handle04_2f_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1e> (%08x)", op); return 4; } -int arcompact_handle04_2f_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_1f> (%08x)", op); return 4; } -int arcompact_handle04_2f_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_20> (%08x)", op); return 4; } -int arcompact_handle04_2f_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_21> (%08x)", op); return 4; } -int arcompact_handle04_2f_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_22> (%08x)", op); return 4; } -int arcompact_handle04_2f_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_23> (%08x)", op); return 4; } -int arcompact_handle04_2f_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_24> (%08x)", op); return 4; } -int arcompact_handle04_2f_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_25> (%08x)", op); return 4; } -int arcompact_handle04_2f_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_26> (%08x)", op); return 4; } -int arcompact_handle04_2f_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_27> (%08x)", op); return 4; } -int arcompact_handle04_2f_28_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_28> (%08x)", op); return 4; } -int arcompact_handle04_2f_29_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_29> (%08x)", op); return 4; } -int arcompact_handle04_2f_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2a> (%08x)", op); return 4; } -int arcompact_handle04_2f_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2b> (%08x)", op); return 4; } -int arcompact_handle04_2f_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2c> (%08x)", op); return 4; } -int arcompact_handle04_2f_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2d> (%08x)", op); return 4; } -int arcompact_handle04_2f_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2e> (%08x)", op); return 4; } -int arcompact_handle04_2f_2f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_2f> (%08x)", op); return 4; } -int arcompact_handle04_2f_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_30> (%08x)", op); return 4; } -int arcompact_handle04_2f_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_31> (%08x)", op); return 4; } -int arcompact_handle04_2f_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_32> (%08x)", op); return 4; } -int arcompact_handle04_2f_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_33> (%08x)", op); return 4; } -int arcompact_handle04_2f_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_34> (%08x)", op); return 4; } -int arcompact_handle04_2f_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_35> (%08x)", op); return 4; } -int arcompact_handle04_2f_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_36> (%08x)", op); return 4; } -int arcompact_handle04_2f_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_37> (%08x)", op); return 4; } -int arcompact_handle04_2f_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_38> (%08x)", op); return 4; } -int arcompact_handle04_2f_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_39> (%08x)", op); return 4; } -int arcompact_handle04_2f_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3e> (%08x)", op); return 4; } - - - -int arcompact_handle05_2f_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_09> (%08x)", op); return 4; } -int arcompact_handle05_2f_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0a> (%08x)", op); return 4; } -int arcompact_handle05_2f_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0b> (%08x)", op); return 4; } -int arcompact_handle05_2f_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0c> (%08x)", op); return 4; } -int arcompact_handle05_2f_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0d> (%08x)", op); return 4; } -int arcompact_handle05_2f_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0e> (%08x)", op); return 4; } -int arcompact_handle05_2f_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_0f> (%08x)", op); return 4; } -int arcompact_handle05_2f_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_10> (%08x)", op); return 4; } -int arcompact_handle05_2f_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_11> (%08x)", op); return 4; } -int arcompact_handle05_2f_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_12> (%08x)", op); return 4; } -int arcompact_handle05_2f_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_13> (%08x)", op); return 4; } -int arcompact_handle05_2f_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_14> (%08x)", op); return 4; } -int arcompact_handle05_2f_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_15> (%08x)", op); return 4; } -int arcompact_handle05_2f_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_16> (%08x)", op); return 4; } -int arcompact_handle05_2f_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_17> (%08x)", op); return 4; } -int arcompact_handle05_2f_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_18> (%08x)", op); return 4; } -int arcompact_handle05_2f_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_19> (%08x)", op); return 4; } -int arcompact_handle05_2f_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1a> (%08x)", op); return 4; } -int arcompact_handle05_2f_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1b> (%08x)", op); return 4; } -int arcompact_handle05_2f_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1c> (%08x)", op); return 4; } -int arcompact_handle05_2f_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1d> (%08x)", op); return 4; } -int arcompact_handle05_2f_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1e> (%08x)", op); return 4; } -int arcompact_handle05_2f_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_1f> (%08x)", op); return 4; } -int arcompact_handle05_2f_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_20> (%08x)", op); return 4; } -int arcompact_handle05_2f_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_21> (%08x)", op); return 4; } -int arcompact_handle05_2f_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_22> (%08x)", op); return 4; } -int arcompact_handle05_2f_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_23> (%08x)", op); return 4; } -int arcompact_handle05_2f_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_24> (%08x)", op); return 4; } -int arcompact_handle05_2f_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_25> (%08x)", op); return 4; } -int arcompact_handle05_2f_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_26> (%08x)", op); return 4; } -int arcompact_handle05_2f_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_27> (%08x)", op); return 4; } -int arcompact_handle05_2f_28_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_28> (%08x)", op); return 4; } -int arcompact_handle05_2f_29_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_29> (%08x)", op); return 4; } -int arcompact_handle05_2f_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2a> (%08x)", op); return 4; } -int arcompact_handle05_2f_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2b> (%08x)", op); return 4; } -int arcompact_handle05_2f_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2c> (%08x)", op); return 4; } -int arcompact_handle05_2f_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2d> (%08x)", op); return 4; } -int arcompact_handle05_2f_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2e> (%08x)", op); return 4; } -int arcompact_handle05_2f_2f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_2f> (%08x)", op); return 4; } -int arcompact_handle05_2f_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_30> (%08x)", op); return 4; } -int arcompact_handle05_2f_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_31> (%08x)", op); return 4; } -int arcompact_handle05_2f_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_32> (%08x)", op); return 4; } -int arcompact_handle05_2f_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_33> (%08x)", op); return 4; } -int arcompact_handle05_2f_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_34> (%08x)", op); return 4; } -int arcompact_handle05_2f_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_35> (%08x)", op); return 4; } -int arcompact_handle05_2f_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_36> (%08x)", op); return 4; } -int arcompact_handle05_2f_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_37> (%08x)", op); return 4; } -int arcompact_handle05_2f_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_38> (%08x)", op); return 4; } -int arcompact_handle05_2f_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_39> (%08x)", op); return 4; } -int arcompact_handle05_2f_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3e> (%08x)", op); return 4; } - - -int arcompact_handle04_2f_3f_00_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_00> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_06_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_06> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_07_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_07> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_08_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_08> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_09> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0e> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_0f> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_10> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_11> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_12> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_13> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_14> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_15> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_16> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_17> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_18> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_19> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1e> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_1f> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_20> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_21> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_22> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_23> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_24> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_25> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_26> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_27> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_28_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_28> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_29_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_29> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2e> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_2f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_2f> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_30> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_31> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_32> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_33> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_34> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_35> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_36> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_37> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_38> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_39> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3a> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3b> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3c> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3d> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3e> (%08x)", op); return 4; } -int arcompact_handle04_2f_3f_3f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_2f_3f_3f> (%08x)", op); return 4; } - -int arcompact_handle05_2f_3f_00_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_00> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_01_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_01> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_02_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_02> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_03_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_03> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_04_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_04> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_05_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_05> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_06_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_06> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_07_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_07> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_08_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_08> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_09> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0e> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_0f> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_10> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_11> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_12> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_13> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_14> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_15> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_16> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_17> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_18> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_19> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1e> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_1f> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_20> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_21> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_22> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_23> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_24> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_25> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_26> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_27> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_28_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_28> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_29_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_29> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2e> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_2f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_2f> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_30> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_31> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_32> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_33> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_34> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_35> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_36> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_37> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_38> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_39> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3a> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3b> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3c> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3d> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3e> (%08x)", op); return 4; } -int arcompact_handle05_2f_3f_3f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2f_3f_3f> (%08x)", op); return 4; } - - - - -int arcompact_handle04_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_38> (%08x)", op); return 4; } -int arcompact_handle04_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_39> (%08x)", op); return 4; } -int arcompact_handle04_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3a> (%08x)", op); return 4; } -int arcompact_handle04_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3b> (%08x)", op); return 4; } -int arcompact_handle04_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3c> (%08x)", op); return 4; } -int arcompact_handle04_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3d> (%08x)", op); return 4; } -int arcompact_handle04_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3e> (%08x)", op); return 4; } -int arcompact_handle04_3f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x04_3f> (%08x)", op); return 4; } - - -int arcompact_handle05_09_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_09> (%08x)", op); return 4; } -int arcompact_handle05_0c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_0c> (%08x)", op); return 4; } -int arcompact_handle05_0d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_0d> (%08x)", op); return 4; } -int arcompact_handle05_0e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_0e> (%08x)", op); return 4; } -int arcompact_handle05_0f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_0f> (%08x)", op); return 4; } -int arcompact_handle05_10_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_10> (%08x)", op); return 4; } -int arcompact_handle05_11_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_11> (%08x)", op); return 4; } -int arcompact_handle05_12_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_12> (%08x)", op); return 4; } -int arcompact_handle05_13_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_13> (%08x)", op); return 4; } -int arcompact_handle05_14_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_14> (%08x)", op); return 4; } -int arcompact_handle05_15_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_15> (%08x)", op); return 4; } -int arcompact_handle05_16_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_16> (%08x)", op); return 4; } -int arcompact_handle05_17_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_17> (%08x)", op); return 4; } -int arcompact_handle05_18_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_18> (%08x)", op); return 4; } -int arcompact_handle05_19_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_19> (%08x)", op); return 4; } -int arcompact_handle05_1a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1a> (%08x)", op); return 4; } -int arcompact_handle05_1b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1b> (%08x)", op); return 4; } -int arcompact_handle05_1c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1c> (%08x)", op); return 4; } -int arcompact_handle05_1d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1d> (%08x)", op); return 4; } -int arcompact_handle05_1e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1e> (%08x)", op); return 4; } -int arcompact_handle05_1f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_1f> (%08x)", op); return 4; } -int arcompact_handle05_20_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_20> (%08x)", op); return 4; } -int arcompact_handle05_21_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_21> (%08x)", op); return 4; } -int arcompact_handle05_22_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_22> (%08x)", op); return 4; } -int arcompact_handle05_23_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_23> (%08x)", op); return 4; } -int arcompact_handle05_24_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_24> (%08x)", op); return 4; } -int arcompact_handle05_25_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_25> (%08x)", op); return 4; } -int arcompact_handle05_26_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_26> (%08x)", op); return 4; } -int arcompact_handle05_27_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_27> (%08x)", op); return 4; } - -int arcompact_handle05_2a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2a> (%08x)", op); return 4; } -int arcompact_handle05_2b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2b> (%08x)", op); return 4; } -int arcompact_handle05_2c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2c> (%08x)", op); return 4; } -int arcompact_handle05_2d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2d> (%08x)", op); return 4; } -int arcompact_handle05_2e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_2e> (%08x)", op); return 4; } - -int arcompact_handle05_30_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_30> (%08x)", op); return 4; } -int arcompact_handle05_31_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_31> (%08x)", op); return 4; } -int arcompact_handle05_32_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_32> (%08x)", op); return 4; } -int arcompact_handle05_33_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_33> (%08x)", op); return 4; } -int arcompact_handle05_34_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_34> (%08x)", op); return 4; } -int arcompact_handle05_35_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_35> (%08x)", op); return 4; } -int arcompact_handle05_36_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_36> (%08x)", op); return 4; } -int arcompact_handle05_37_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_37> (%08x)", op); return 4; } -int arcompact_handle05_38_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_38> (%08x)", op); return 4; } -int arcompact_handle05_39_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_39> (%08x)", op); return 4; } -int arcompact_handle05_3a_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3a> (%08x)", op); return 4; } -int arcompact_handle05_3b_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3b> (%08x)", op); return 4; } -int arcompact_handle05_3c_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3c> (%08x)", op); return 4; } -int arcompact_handle05_3d_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3d> (%08x)", op); return 4; } -int arcompact_handle05_3e_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3e> (%08x)", op); return 4; } -int arcompact_handle05_3f_dasm(DASM_OPS_32) { util::stream_format(stream, "<illegal 0x05_3f> (%08x)", op); return 4; } - -int arcompact_handle0f_00_04_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_00_00> (%08x)", op); return 2; } -int arcompact_handle0f_00_05_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_00_00> (%08x)", op); return 2; } -int arcompact_handle0f_00_07_02_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_00_07_02> (%08x)", op); return 2; } -int arcompact_handle0f_00_07_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_00_07_03> (%08x)", op); return 2; } -int arcompact_handle0f_01_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_01> (%08x)", op); return 2; } -int arcompact_handle0f_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_03> (%08x)", op); return 2; } -int arcompact_handle0f_08_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_08> (%08x)", op); return 2; } -int arcompact_handle0f_09_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_09> (%08x)", op); return 2; } -int arcompact_handle0f_0a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_0a> (%08x)", op); return 2; } -int arcompact_handle0f_17_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x0f_17> (%08x)", op); return 2; } - -int arcompact_handle18_05_02_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_02> (%04x)", op); return 2; } -int arcompact_handle18_05_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_03> (%04x)", op); return 2; } -int arcompact_handle18_05_04_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_04> (%04x)", op); return 2; } -int arcompact_handle18_05_05_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_05> (%04x)", op); return 2; } -int arcompact_handle18_05_06_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_06> (%04x)", op); return 2; } -int arcompact_handle18_05_07_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_05_07> (%04x)", op); return 2; } -int arcompact_handle18_06_00_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_00> (%04x)", op); return 2; } -int arcompact_handle18_06_02_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_02> (%04x)", op); return 2; } -int arcompact_handle18_06_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_03> (%04x)", op); return 2; } -int arcompact_handle18_06_04_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_04> (%04x)", op); return 2; } -int arcompact_handle18_06_05_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_05> (%04x)", op); return 2; } -int arcompact_handle18_06_06_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_06> (%04x)", op); return 2; } -int arcompact_handle18_06_07_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_07> (%04x)", op); return 2; } -int arcompact_handle18_06_08_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_08> (%04x)", op); return 2; } -int arcompact_handle18_06_09_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_09> (%04x)", op); return 2; } -int arcompact_handle18_06_0a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0a> (%04x)", op); return 2; } -int arcompact_handle18_06_0b_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0b> (%04x)", op); return 2; } -int arcompact_handle18_06_0c_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0c> (%04x)", op); return 2; } -int arcompact_handle18_06_0d_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0d> (%04x)", op); return 2; } -int arcompact_handle18_06_0e_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0e> (%04x)", op); return 2; } -int arcompact_handle18_06_0f_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_0f> (%04x)", op); return 2; } -int arcompact_handle18_06_10_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_10> (%04x)", op); return 2; } -int arcompact_handle18_06_12_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_12> (%04x)", op); return 2; } -int arcompact_handle18_06_13_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_13> (%04x)", op); return 2; } -int arcompact_handle18_06_14_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_14> (%04x)", op); return 2; } -int arcompact_handle18_06_15_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_15> (%04x)", op); return 2; } -int arcompact_handle18_06_16_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_16> (%04x)", op); return 2; } -int arcompact_handle18_06_17_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_17> (%04x)", op); return 2; } -int arcompact_handle18_06_18_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_18> (%04x)", op); return 2; } -int arcompact_handle18_06_19_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_19> (%04x)", op); return 2; } -int arcompact_handle18_06_1a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1a> (%04x)", op); return 2; } -int arcompact_handle18_06_1b_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1b> (%04x)", op); return 2; } -int arcompact_handle18_06_1c_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1c> (%04x)", op); return 2; } -int arcompact_handle18_06_1d_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1d> (%04x)", op); return 2; } -int arcompact_handle18_06_1e_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1e> (%04x)", op); return 2; } -int arcompact_handle18_06_1f_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_06_1f> (%04x)", op); return 2; } -int arcompact_handle18_07_00_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_00> (%04x)", op); return 2; } -int arcompact_handle18_07_02_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_02> (%04x)", op); return 2; } -int arcompact_handle18_07_03_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_03> (%04x)", op); return 2; } -int arcompact_handle18_07_04_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_04> (%04x)", op); return 2; } -int arcompact_handle18_07_05_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_05> (%04x)", op); return 2; } -int arcompact_handle18_07_06_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_06> (%04x)", op); return 2; } -int arcompact_handle18_07_07_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_07> (%04x)", op); return 2; } -int arcompact_handle18_07_08_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_08> (%04x)", op); return 2; } -int arcompact_handle18_07_09_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_09> (%04x)", op); return 2; } -int arcompact_handle18_07_0a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0a> (%04x)", op); return 2; } -int arcompact_handle18_07_0b_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0b> (%04x)", op); return 2; } -int arcompact_handle18_07_0c_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0c> (%04x)", op); return 2; } -int arcompact_handle18_07_0d_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0d> (%04x)", op); return 2; } -int arcompact_handle18_07_0e_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0e> (%04x)", op); return 2; } -int arcompact_handle18_07_0f_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_0f> (%04x)", op); return 2; } -int arcompact_handle18_07_10_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_10> (%04x)", op); return 2; } -int arcompact_handle18_07_12_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_12> (%04x)", op); return 2; } -int arcompact_handle18_07_13_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_13> (%04x)", op); return 2; } -int arcompact_handle18_07_14_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_14> (%04x)", op); return 2; } -int arcompact_handle18_07_15_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_15> (%04x)", op); return 2; } -int arcompact_handle18_07_16_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_16> (%04x)", op); return 2; } -int arcompact_handle18_07_17_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_17> (%04x)", op); return 2; } -int arcompact_handle18_07_18_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_18> (%04x)", op); return 2; } -int arcompact_handle18_07_19_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_19> (%04x)", op); return 2; } -int arcompact_handle18_07_1a_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1a> (%04x)", op); return 2; } -int arcompact_handle18_07_1b_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1b> (%04x)", op); return 2; } -int arcompact_handle18_07_1c_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1c> (%04x)", op); return 2; } -int arcompact_handle18_07_1d_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1d> (%04x)", op); return 2; } -int arcompact_handle18_07_1e_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1e> (%04x)", op); return 2; } -int arcompact_handle18_07_1f_dasm(DASM_OPS_16) { util::stream_format(stream, "<illegal 0x18_07_1f> (%04x)", op); return 2; } +int arcompact_disassembler::handle01_01_00_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_06> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_07> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_08> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_00_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_00_0d> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle01_01_01_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_06> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_07> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_08> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle01_01_01_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 01_01_01_0d> (%08x)", op); + return 4; +} + + + +int arcompact_disassembler::handle04_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_1f> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle04_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_27> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle04_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2e> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle04_2f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_27> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_28> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_29> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_2f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3e> (%08x)", op); + return 4; +} + + + + +int arcompact_disassembler::handle05_2f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_27> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_28> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_29> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_2f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3e> (%08x)", op); + return 4; +} + + + +int arcompact_disassembler::handle04_2f_3f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_00> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_06> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_07> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_08> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_27> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_28> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_29> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_2f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_2f_3f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_2f_3f_3f> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle05_2f_3f_00_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_00> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_01_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_01> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_02_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_02> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_03_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_03> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_04_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_04> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_05_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_05> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_06_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_06> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_07_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_07> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_08_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_08> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_27> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_28_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_28> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_29_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_29> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_2f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_2f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2f_3f_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2f_3f_3f> (%08x)", op); + return 4; +} + + + + + +int arcompact_disassembler::handle04_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle04_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x04_3f> (%08x)", op); + return 4; +} + + + +int arcompact_disassembler::handle05_09_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_09> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_0c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_0c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_0d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_0d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_0e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_0e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_0f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_0f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_10_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_10> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_11_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_11> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_12_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_12> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_13_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_13> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_14_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_14> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_15_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_15> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_16_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_16> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_17_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_17> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_18_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_18> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_19_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_19> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_1f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_1f> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_20_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_20> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_21_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_21> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_22_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_22> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_23_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_23> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_24_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_24> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_25_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_25> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_26_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_26> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_27_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_27> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle05_2a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_2e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_2e> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle05_30_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_30> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_31_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_31> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_32_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_32> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_33_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_33> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_34_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_34> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_35_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_35> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_36_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_36> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_37_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_37> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_38_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_38> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_39_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_39> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3a_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3a> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3b_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3b> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3c_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3c> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3d_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3d> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3e_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3e> (%08x)", op); + return 4; +} + +int arcompact_disassembler::handle05_3f_dasm(std::ostream &stream, offs_t pc, uint32_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x05_3f> (%08x)", op); + return 4; +} + + +int arcompact_disassembler::handle0f_00_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_00_00> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_00_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_00_00> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_00_07_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_00_07_02> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_00_07_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_00_07_03> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_01_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_01> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_03> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_08> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_09> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_0a> (%08x)", op); + return 2; +} + +int arcompact_disassembler::handle0f_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x0f_17> (%08x)", op); + return 2; +} + + +int arcompact_disassembler::handle18_05_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_02> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_03> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_04> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_05> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_06> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_05_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_05_07> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_00> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_02> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_03> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_04> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_05> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_06> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_07> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_08> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_09> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0a> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0b> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0c> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0d> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0e> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_0f> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_10> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_12> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_13> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_14> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_15> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_16> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_17> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_18> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_19> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1a> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1b> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1c> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1d> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1e> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_06_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_06_1f> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_00_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_00> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_02_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_02> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_03_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_03> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_04_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_04> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_05_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_05> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_06_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_06> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_07_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_07> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_08_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_08> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_09_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_09> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0a> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0b> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0c> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0d> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0e> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_0f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_0f> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_10_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_10> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_12_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_12> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_13_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_13> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_14_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_14> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_15_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_15> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_16_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_16> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_17_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_17> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_18_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_18> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_19_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_19> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1a_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1a> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1b_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1b> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1c_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1c> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1d_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1d> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1e_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1e> (%04x)", op); + return 2; +} + +int arcompact_disassembler::handle18_07_1f_dasm(std::ostream &stream, offs_t pc, uint16_t op, const data_buffer &opcodes) +{ + util::stream_format(stream, "<illegal 0x18_07_1f> (%04x)", op); + return 2; +} diff --git a/src/devices/cpu/arcompact/arcompactdasm_ops.h b/src/devices/cpu/arcompact/arcompactdasm_ops.h deleted file mode 100644 index 84b79e6e1e7..00000000000 --- a/src/devices/cpu/arcompact/arcompactdasm_ops.h +++ /dev/null @@ -1,642 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:David Haywood - -/************************************************************************************************************************************ -* * -* individual opcode handlers (disassembly) * -* * -************************************************************************************************************************************/ - -#include "arcompact_common.h" - -#define DASM_OPS_16 std::ostream &stream, offs_t pc, uint16_t op, const uint8_t* oprom -#define DASM_OPS_32 std::ostream &stream, offs_t pc, uint32_t op, const uint8_t* oprom -#define DASM_PARAMS stream, pc, op, oprom - -#define LIMM_REG 62 - -#define GET_LIMM_32 \ - limm = oprom[6] | (oprom[7] << 8); \ - limm |= (oprom[4] << 16) | (oprom[5] << 24); - -int arcompact_handle00_00_dasm(DASM_OPS_32); -int arcompact_handle00_01_dasm(DASM_OPS_32); -int arcompact_handle01_00_00dasm(DASM_OPS_32); -int arcompact_handle01_00_01dasm(DASM_OPS_32); -int arcompact_handle01_01_00_00_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_01_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_02_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_03_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_04_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_05_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0e_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0f_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_00_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_01_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_02_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_03_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_04_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_05_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0e_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0f_dasm(DASM_OPS_32); -int arcompact_handle02_dasm(DASM_OPS_32); -int arcompact_handle03_dasm(DASM_OPS_32); -int arcompact_handle04_00_dasm(DASM_OPS_32); -int arcompact_handle04_01_dasm(DASM_OPS_32); -int arcompact_handle04_02_dasm(DASM_OPS_32); -int arcompact_handle04_03_dasm(DASM_OPS_32); -int arcompact_handle04_04_dasm(DASM_OPS_32); -int arcompact_handle04_05_dasm(DASM_OPS_32); -int arcompact_handle04_06_dasm(DASM_OPS_32); -int arcompact_handle04_07_dasm(DASM_OPS_32); -int arcompact_handle04_08_dasm(DASM_OPS_32); -int arcompact_handle04_09_dasm(DASM_OPS_32); -int arcompact_handle04_0a_dasm(DASM_OPS_32); -int arcompact_handle04_0b_dasm(DASM_OPS_32); -int arcompact_handle04_0c_dasm(DASM_OPS_32); -int arcompact_handle04_0d_dasm(DASM_OPS_32); -int arcompact_handle04_0e_dasm(DASM_OPS_32); -int arcompact_handle04_0f_dasm(DASM_OPS_32); -int arcompact_handle04_10_dasm(DASM_OPS_32); -int arcompact_handle04_11_dasm(DASM_OPS_32); -int arcompact_handle04_12_dasm(DASM_OPS_32); -int arcompact_handle04_13_dasm(DASM_OPS_32); -int arcompact_handle04_14_dasm(DASM_OPS_32); -int arcompact_handle04_15_dasm(DASM_OPS_32); -int arcompact_handle04_16_dasm(DASM_OPS_32); -int arcompact_handle04_17_dasm(DASM_OPS_32); -int arcompact_handle04_18_dasm(DASM_OPS_32); -int arcompact_handle04_19_dasm(DASM_OPS_32); -int arcompact_handle04_1a_dasm(DASM_OPS_32); -int arcompact_handle04_1b_dasm(DASM_OPS_32); -int arcompact_handle04_1c_dasm(DASM_OPS_32); -int arcompact_handle04_1d_dasm(DASM_OPS_32); -int arcompact_handle04_20_dasm(DASM_OPS_32); -int arcompact_handle04_21_dasm(DASM_OPS_32); -int arcompact_handle04_22_dasm(DASM_OPS_32); -int arcompact_handle04_23_dasm(DASM_OPS_32); -int arcompact_handle04_28_dasm(DASM_OPS_32); -int arcompact_handle04_29_dasm(DASM_OPS_32); -int arcompact_handle04_2a_dasm(DASM_OPS_32); -int arcompact_handle04_2b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_00_dasm(DASM_OPS_32); -int arcompact_handle04_2f_01_dasm(DASM_OPS_32); -int arcompact_handle04_2f_02_dasm(DASM_OPS_32); -int arcompact_handle04_2f_03_dasm(DASM_OPS_32); -int arcompact_handle04_2f_04_dasm(DASM_OPS_32); -int arcompact_handle04_2f_05_dasm(DASM_OPS_32); -int arcompact_handle04_2f_06_dasm(DASM_OPS_32); -int arcompact_handle04_2f_07_dasm(DASM_OPS_32); -int arcompact_handle04_2f_08_dasm(DASM_OPS_32); -int arcompact_handle04_2f_09_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_01_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_02_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_03_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_04_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_05_dasm(DASM_OPS_32); -int arcompact_handle04_30_dasm(DASM_OPS_32); -int arcompact_handle04_31_dasm(DASM_OPS_32); -int arcompact_handle04_32_dasm(DASM_OPS_32); -int arcompact_handle04_33_dasm(DASM_OPS_32); -int arcompact_handle04_34_dasm(DASM_OPS_32); -int arcompact_handle04_35_dasm(DASM_OPS_32); -int arcompact_handle04_36_dasm(DASM_OPS_32); -int arcompact_handle04_37_dasm(DASM_OPS_32); -int arcompact_handle05_00_dasm(DASM_OPS_32); -int arcompact_handle05_01_dasm(DASM_OPS_32); -int arcompact_handle05_02_dasm(DASM_OPS_32); -int arcompact_handle05_03_dasm(DASM_OPS_32); -int arcompact_handle05_04_dasm(DASM_OPS_32); -int arcompact_handle05_05_dasm(DASM_OPS_32); -int arcompact_handle05_06_dasm(DASM_OPS_32); -int arcompact_handle05_07_dasm(DASM_OPS_32); -int arcompact_handle05_08_dasm(DASM_OPS_32); -int arcompact_handle05_0a_dasm(DASM_OPS_32); -int arcompact_handle05_0b_dasm(DASM_OPS_32); -int arcompact_handle05_28_dasm(DASM_OPS_32); -int arcompact_handle05_29_dasm(DASM_OPS_32); - -int arcompact_handle06_dasm(DASM_OPS_32); -int arcompact_handle07_dasm(DASM_OPS_32); -int arcompact_handle08_dasm(DASM_OPS_32); -int arcompact_handle09_dasm(DASM_OPS_32); -int arcompact_handle0a_dasm(DASM_OPS_32); -int arcompact_handle0b_dasm(DASM_OPS_32); - -int arcompact_handle0c_00_dasm(DASM_OPS_16); -int arcompact_handle0c_01_dasm(DASM_OPS_16); -int arcompact_handle0c_02_dasm(DASM_OPS_16); -int arcompact_handle0c_03_dasm(DASM_OPS_16); -int arcompact_handle0d_00_dasm(DASM_OPS_16); -int arcompact_handle0d_01_dasm(DASM_OPS_16); -int arcompact_handle0d_02_dasm(DASM_OPS_16); -int arcompact_handle0d_03_dasm(DASM_OPS_16); -int arcompact_handle0e_00_dasm(DASM_OPS_16); -int arcompact_handle0e_01_dasm(DASM_OPS_16); -int arcompact_handle0e_02_dasm(DASM_OPS_16); -int arcompact_handle0e_03_dasm(DASM_OPS_16); -int arcompact_handle0f_00_00_dasm(DASM_OPS_16); -int arcompact_handle0f_00_01_dasm(DASM_OPS_16); -int arcompact_handle0f_00_02_dasm(DASM_OPS_16); -int arcompact_handle0f_00_03_dasm(DASM_OPS_16); -int arcompact_handle0f_00_06_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_00_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_01_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_04_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_05_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_06_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_07_dasm(DASM_OPS_16); -int arcompact_handle0f_02_dasm(DASM_OPS_16); -int arcompact_handle0f_04_dasm(DASM_OPS_16); -int arcompact_handle0f_05_dasm(DASM_OPS_16); -int arcompact_handle0f_06_dasm(DASM_OPS_16); -int arcompact_handle0f_07_dasm(DASM_OPS_16); -int arcompact_handle0f_0b_dasm(DASM_OPS_16); -int arcompact_handle0f_0c_dasm(DASM_OPS_16); -int arcompact_handle0f_0d_dasm(DASM_OPS_16); -int arcompact_handle0f_0e_dasm(DASM_OPS_16); -int arcompact_handle0f_0f_dasm(DASM_OPS_16); -int arcompact_handle0f_10_dasm(DASM_OPS_16); -int arcompact_handle0f_11_dasm(DASM_OPS_16); -int arcompact_handle0f_12_dasm(DASM_OPS_16); -int arcompact_handle0f_13_dasm(DASM_OPS_16); -int arcompact_handle0f_14_dasm(DASM_OPS_16); -int arcompact_handle0f_15_dasm(DASM_OPS_16); -int arcompact_handle0f_16_dasm(DASM_OPS_16); -int arcompact_handle0f_18_dasm(DASM_OPS_16); -int arcompact_handle0f_19_dasm(DASM_OPS_16); -int arcompact_handle0f_1a_dasm(DASM_OPS_16); -int arcompact_handle0f_1b_dasm(DASM_OPS_16); -int arcompact_handle0f_1c_dasm(DASM_OPS_16); -int arcompact_handle0f_1d_dasm(DASM_OPS_16); -int arcompact_handle0f_1e_dasm(DASM_OPS_16); -int arcompact_handle0f_1f_dasm(DASM_OPS_16); -int arcompact_handle10_dasm(DASM_OPS_16); -int arcompact_handle11_dasm(DASM_OPS_16); -int arcompact_handle12_dasm(DASM_OPS_16); -int arcompact_handle13_dasm(DASM_OPS_16); -int arcompact_handle14_dasm(DASM_OPS_16); -int arcompact_handle15_dasm(DASM_OPS_16); -int arcompact_handle16_dasm(DASM_OPS_16); -int arcompact_handle17_00_dasm(DASM_OPS_16); -int arcompact_handle17_01_dasm(DASM_OPS_16); -int arcompact_handle17_02_dasm(DASM_OPS_16); -int arcompact_handle17_03_dasm(DASM_OPS_16); -int arcompact_handle17_04_dasm(DASM_OPS_16); -int arcompact_handle17_05_dasm(DASM_OPS_16); -int arcompact_handle17_06_dasm(DASM_OPS_16); -int arcompact_handle17_07_dasm(DASM_OPS_16); -int arcompact_handle18_00_dasm(DASM_OPS_16); -int arcompact_handle18_01_dasm(DASM_OPS_16); -int arcompact_handle18_02_dasm(DASM_OPS_16); -int arcompact_handle18_03_dasm(DASM_OPS_16); -int arcompact_handle18_04_dasm(DASM_OPS_16); -int arcompact_handle18_05_00_dasm(DASM_OPS_16); -int arcompact_handle18_05_01_dasm(DASM_OPS_16); -int arcompact_handle18_06_01_dasm(DASM_OPS_16); -int arcompact_handle18_06_11_dasm(DASM_OPS_16); -int arcompact_handle18_07_01_dasm(DASM_OPS_16); -int arcompact_handle18_07_11_dasm(DASM_OPS_16); -int arcompact_handle19_00_dasm(DASM_OPS_16); -int arcompact_handle19_01_dasm(DASM_OPS_16); -int arcompact_handle19_02_dasm(DASM_OPS_16); -int arcompact_handle19_03_dasm(DASM_OPS_16); -int arcompact_handle1a_dasm(DASM_OPS_16); -int arcompact_handle1b_dasm(DASM_OPS_16); -int arcompact_handle1c_00_dasm(DASM_OPS_16); -int arcompact_handle1c_01_dasm(DASM_OPS_16); -int arcompact_handle1d_00_dasm(DASM_OPS_16); -int arcompact_handle1d_01_dasm(DASM_OPS_16); -int arcompact_handle1e_00_dasm(DASM_OPS_16); -int arcompact_handle1e_01_dasm(DASM_OPS_16); -int arcompact_handle1e_02_dasm(DASM_OPS_16); -int arcompact_handle1e_03_00_dasm(DASM_OPS_16); -int arcompact_handle1e_03_01_dasm(DASM_OPS_16); -int arcompact_handle1e_03_02_dasm(DASM_OPS_16); -int arcompact_handle1e_03_03_dasm(DASM_OPS_16); -int arcompact_handle1e_03_04_dasm(DASM_OPS_16); -int arcompact_handle1e_03_05_dasm(DASM_OPS_16); -int arcompact_handle1e_03_06_dasm(DASM_OPS_16); -int arcompact_handle1e_03_07_dasm(DASM_OPS_16); -int arcompact_handle1f_dasm(DASM_OPS_16); - -/************************************************************************************************************************************ -* * -* illegal opcode handlers (disassembly) * -* * -************************************************************************************************************************************/ - -int arcompact_handle01_01_00_06_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_07_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_08_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_09_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0a_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0b_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0c_dasm(DASM_OPS_32); -int arcompact_handle01_01_00_0d_dasm(DASM_OPS_32); - -int arcompact_handle01_01_01_06_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_07_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_08_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_09_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0a_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0b_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0c_dasm(DASM_OPS_32); -int arcompact_handle01_01_01_0d_dasm(DASM_OPS_32); - - -int arcompact_handle04_1e_dasm(DASM_OPS_32); -int arcompact_handle04_1f_dasm(DASM_OPS_32); - -int arcompact_handle04_24_dasm(DASM_OPS_32); -int arcompact_handle04_25_dasm(DASM_OPS_32); -int arcompact_handle04_26_dasm(DASM_OPS_32); -int arcompact_handle04_27_dasm(DASM_OPS_32); - -int arcompact_handle04_2c_dasm(DASM_OPS_32); -int arcompact_handle04_2d_dasm(DASM_OPS_32); -int arcompact_handle04_2e_dasm(DASM_OPS_32); - -int arcompact_handle04_2f_0d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_0f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_10_dasm(DASM_OPS_32); -int arcompact_handle04_2f_11_dasm(DASM_OPS_32); -int arcompact_handle04_2f_12_dasm(DASM_OPS_32); -int arcompact_handle04_2f_13_dasm(DASM_OPS_32); -int arcompact_handle04_2f_14_dasm(DASM_OPS_32); -int arcompact_handle04_2f_15_dasm(DASM_OPS_32); -int arcompact_handle04_2f_16_dasm(DASM_OPS_32); -int arcompact_handle04_2f_17_dasm(DASM_OPS_32); -int arcompact_handle04_2f_18_dasm(DASM_OPS_32); -int arcompact_handle04_2f_19_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_1f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_20_dasm(DASM_OPS_32); -int arcompact_handle04_2f_21_dasm(DASM_OPS_32); -int arcompact_handle04_2f_22_dasm(DASM_OPS_32); -int arcompact_handle04_2f_23_dasm(DASM_OPS_32); -int arcompact_handle04_2f_24_dasm(DASM_OPS_32); -int arcompact_handle04_2f_25_dasm(DASM_OPS_32); -int arcompact_handle04_2f_26_dasm(DASM_OPS_32); -int arcompact_handle04_2f_27_dasm(DASM_OPS_32); -int arcompact_handle04_2f_28_dasm(DASM_OPS_32); -int arcompact_handle04_2f_29_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_2f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_30_dasm(DASM_OPS_32); -int arcompact_handle04_2f_31_dasm(DASM_OPS_32); -int arcompact_handle04_2f_32_dasm(DASM_OPS_32); -int arcompact_handle04_2f_33_dasm(DASM_OPS_32); -int arcompact_handle04_2f_34_dasm(DASM_OPS_32); -int arcompact_handle04_2f_35_dasm(DASM_OPS_32); -int arcompact_handle04_2f_36_dasm(DASM_OPS_32); -int arcompact_handle04_2f_37_dasm(DASM_OPS_32); -int arcompact_handle04_2f_38_dasm(DASM_OPS_32); -int arcompact_handle04_2f_39_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3e_dasm(DASM_OPS_32); - -int arcompact_handle04_2f_3f_00_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_06_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_07_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_08_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_09_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_0f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_10_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_11_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_12_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_13_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_14_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_15_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_16_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_17_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_18_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_19_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_1f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_20_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_21_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_22_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_23_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_24_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_25_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_26_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_27_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_28_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_29_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_2f_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_30_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_31_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_32_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_33_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_34_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_35_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_36_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_37_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_38_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_39_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3a_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3b_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3c_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3d_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3e_dasm(DASM_OPS_32); -int arcompact_handle04_2f_3f_3f_dasm(DASM_OPS_32); - -int arcompact_handle05_2f_00_dasm(DASM_OPS_32); -int arcompact_handle05_2f_01_dasm(DASM_OPS_32); -int arcompact_handle05_2f_02_dasm(DASM_OPS_32); -int arcompact_handle05_2f_03_dasm(DASM_OPS_32); -int arcompact_handle05_2f_04_dasm(DASM_OPS_32); -int arcompact_handle05_2f_05_dasm(DASM_OPS_32); -int arcompact_handle05_2f_06_dasm(DASM_OPS_32); -int arcompact_handle05_2f_07_dasm(DASM_OPS_32); -int arcompact_handle05_2f_08_dasm(DASM_OPS_32); -int arcompact_handle05_2f_09_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_0f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_10_dasm(DASM_OPS_32); -int arcompact_handle05_2f_11_dasm(DASM_OPS_32); -int arcompact_handle05_2f_12_dasm(DASM_OPS_32); -int arcompact_handle05_2f_13_dasm(DASM_OPS_32); -int arcompact_handle05_2f_14_dasm(DASM_OPS_32); -int arcompact_handle05_2f_15_dasm(DASM_OPS_32); -int arcompact_handle05_2f_16_dasm(DASM_OPS_32); -int arcompact_handle05_2f_17_dasm(DASM_OPS_32); -int arcompact_handle05_2f_18_dasm(DASM_OPS_32); -int arcompact_handle05_2f_19_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_1f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_20_dasm(DASM_OPS_32); -int arcompact_handle05_2f_21_dasm(DASM_OPS_32); -int arcompact_handle05_2f_22_dasm(DASM_OPS_32); -int arcompact_handle05_2f_23_dasm(DASM_OPS_32); -int arcompact_handle05_2f_24_dasm(DASM_OPS_32); -int arcompact_handle05_2f_25_dasm(DASM_OPS_32); -int arcompact_handle05_2f_26_dasm(DASM_OPS_32); -int arcompact_handle05_2f_27_dasm(DASM_OPS_32); -int arcompact_handle05_2f_28_dasm(DASM_OPS_32); -int arcompact_handle05_2f_29_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_2f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_30_dasm(DASM_OPS_32); -int arcompact_handle05_2f_31_dasm(DASM_OPS_32); -int arcompact_handle05_2f_32_dasm(DASM_OPS_32); -int arcompact_handle05_2f_33_dasm(DASM_OPS_32); -int arcompact_handle05_2f_34_dasm(DASM_OPS_32); -int arcompact_handle05_2f_35_dasm(DASM_OPS_32); -int arcompact_handle05_2f_36_dasm(DASM_OPS_32); -int arcompact_handle05_2f_37_dasm(DASM_OPS_32); -int arcompact_handle05_2f_38_dasm(DASM_OPS_32); -int arcompact_handle05_2f_39_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3e_dasm(DASM_OPS_32); - -int arcompact_handle05_2f_3f_00_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_01_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_02_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_03_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_04_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_05_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_06_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_07_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_08_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_09_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_0f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_10_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_11_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_12_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_13_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_14_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_15_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_16_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_17_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_18_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_19_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_1f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_20_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_21_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_22_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_23_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_24_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_25_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_26_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_27_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_28_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_29_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_2f_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_30_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_31_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_32_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_33_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_34_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_35_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_36_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_37_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_38_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_39_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3a_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3b_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3c_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3d_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3e_dasm(DASM_OPS_32); -int arcompact_handle05_2f_3f_3f_dasm(DASM_OPS_32); - - -int arcompact_handle04_38_dasm(DASM_OPS_32); -int arcompact_handle04_39_dasm(DASM_OPS_32); -int arcompact_handle04_3a_dasm(DASM_OPS_32); -int arcompact_handle04_3b_dasm(DASM_OPS_32); -int arcompact_handle04_3c_dasm(DASM_OPS_32); -int arcompact_handle04_3d_dasm(DASM_OPS_32); -int arcompact_handle04_3e_dasm(DASM_OPS_32); -int arcompact_handle04_3f_dasm(DASM_OPS_32); - -int arcompact_handle05_09_dasm(DASM_OPS_32); -int arcompact_handle05_0c_dasm(DASM_OPS_32); -int arcompact_handle05_0d_dasm(DASM_OPS_32); -int arcompact_handle05_0e_dasm(DASM_OPS_32); -int arcompact_handle05_0f_dasm(DASM_OPS_32); -int arcompact_handle05_10_dasm(DASM_OPS_32); -int arcompact_handle05_11_dasm(DASM_OPS_32); -int arcompact_handle05_12_dasm(DASM_OPS_32); -int arcompact_handle05_13_dasm(DASM_OPS_32); -int arcompact_handle05_14_dasm(DASM_OPS_32); -int arcompact_handle05_15_dasm(DASM_OPS_32); -int arcompact_handle05_16_dasm(DASM_OPS_32); -int arcompact_handle05_17_dasm(DASM_OPS_32); -int arcompact_handle05_18_dasm(DASM_OPS_32); -int arcompact_handle05_19_dasm(DASM_OPS_32); -int arcompact_handle05_1a_dasm(DASM_OPS_32); -int arcompact_handle05_1b_dasm(DASM_OPS_32); -int arcompact_handle05_1c_dasm(DASM_OPS_32); -int arcompact_handle05_1d_dasm(DASM_OPS_32); -int arcompact_handle05_1e_dasm(DASM_OPS_32); -int arcompact_handle05_1f_dasm(DASM_OPS_32); -int arcompact_handle05_20_dasm(DASM_OPS_32); -int arcompact_handle05_21_dasm(DASM_OPS_32); -int arcompact_handle05_22_dasm(DASM_OPS_32); -int arcompact_handle05_23_dasm(DASM_OPS_32); -int arcompact_handle05_24_dasm(DASM_OPS_32); -int arcompact_handle05_25_dasm(DASM_OPS_32); -int arcompact_handle05_26_dasm(DASM_OPS_32); -int arcompact_handle05_27_dasm(DASM_OPS_32); - -int arcompact_handle05_2a_dasm(DASM_OPS_32); -int arcompact_handle05_2b_dasm(DASM_OPS_32); -int arcompact_handle05_2c_dasm(DASM_OPS_32); -int arcompact_handle05_2d_dasm(DASM_OPS_32); -int arcompact_handle05_2e_dasm(DASM_OPS_32); - -int arcompact_handle05_30_dasm(DASM_OPS_32); -int arcompact_handle05_31_dasm(DASM_OPS_32); -int arcompact_handle05_32_dasm(DASM_OPS_32); -int arcompact_handle05_33_dasm(DASM_OPS_32); -int arcompact_handle05_34_dasm(DASM_OPS_32); -int arcompact_handle05_35_dasm(DASM_OPS_32); -int arcompact_handle05_36_dasm(DASM_OPS_32); -int arcompact_handle05_37_dasm(DASM_OPS_32); -int arcompact_handle05_38_dasm(DASM_OPS_32); -int arcompact_handle05_39_dasm(DASM_OPS_32); -int arcompact_handle05_3a_dasm(DASM_OPS_32); -int arcompact_handle05_3b_dasm(DASM_OPS_32); -int arcompact_handle05_3c_dasm(DASM_OPS_32); -int arcompact_handle05_3d_dasm(DASM_OPS_32); -int arcompact_handle05_3e_dasm(DASM_OPS_32); -int arcompact_handle05_3f_dasm(DASM_OPS_32); - -int arcompact_handle0f_00_04_dasm(DASM_OPS_16); -int arcompact_handle0f_00_05_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_02_dasm(DASM_OPS_16); -int arcompact_handle0f_00_07_03_dasm(DASM_OPS_16); -int arcompact_handle0f_01_dasm(DASM_OPS_16); -int arcompact_handle0f_03_dasm(DASM_OPS_16); -int arcompact_handle0f_08_dasm(DASM_OPS_16); -int arcompact_handle0f_09_dasm(DASM_OPS_16); -int arcompact_handle0f_0a_dasm(DASM_OPS_16); -int arcompact_handle0f_17_dasm(DASM_OPS_16); - -int arcompact_handle18_05_02_dasm(DASM_OPS_16); -int arcompact_handle18_05_03_dasm(DASM_OPS_16); -int arcompact_handle18_05_04_dasm(DASM_OPS_16); -int arcompact_handle18_05_05_dasm(DASM_OPS_16); -int arcompact_handle18_05_06_dasm(DASM_OPS_16); -int arcompact_handle18_05_07_dasm(DASM_OPS_16); -int arcompact_handle18_06_00_dasm(DASM_OPS_16); -int arcompact_handle18_06_02_dasm(DASM_OPS_16); -int arcompact_handle18_06_03_dasm(DASM_OPS_16); -int arcompact_handle18_06_04_dasm(DASM_OPS_16); -int arcompact_handle18_06_05_dasm(DASM_OPS_16); -int arcompact_handle18_06_06_dasm(DASM_OPS_16); -int arcompact_handle18_06_07_dasm(DASM_OPS_16); -int arcompact_handle18_06_08_dasm(DASM_OPS_16); -int arcompact_handle18_06_09_dasm(DASM_OPS_16); -int arcompact_handle18_06_0a_dasm(DASM_OPS_16); -int arcompact_handle18_06_0b_dasm(DASM_OPS_16); -int arcompact_handle18_06_0c_dasm(DASM_OPS_16); -int arcompact_handle18_06_0d_dasm(DASM_OPS_16); -int arcompact_handle18_06_0e_dasm(DASM_OPS_16); -int arcompact_handle18_06_0f_dasm(DASM_OPS_16); -int arcompact_handle18_06_10_dasm(DASM_OPS_16); -int arcompact_handle18_06_12_dasm(DASM_OPS_16); -int arcompact_handle18_06_13_dasm(DASM_OPS_16); -int arcompact_handle18_06_14_dasm(DASM_OPS_16); -int arcompact_handle18_06_15_dasm(DASM_OPS_16); -int arcompact_handle18_06_16_dasm(DASM_OPS_16); -int arcompact_handle18_06_17_dasm(DASM_OPS_16); -int arcompact_handle18_06_18_dasm(DASM_OPS_16); -int arcompact_handle18_06_19_dasm(DASM_OPS_16); -int arcompact_handle18_06_1a_dasm(DASM_OPS_16); -int arcompact_handle18_06_1b_dasm(DASM_OPS_16); -int arcompact_handle18_06_1c_dasm(DASM_OPS_16); -int arcompact_handle18_06_1d_dasm(DASM_OPS_16); -int arcompact_handle18_06_1e_dasm(DASM_OPS_16); -int arcompact_handle18_06_1f_dasm(DASM_OPS_16); -int arcompact_handle18_07_00_dasm(DASM_OPS_16); -int arcompact_handle18_07_02_dasm(DASM_OPS_16); -int arcompact_handle18_07_03_dasm(DASM_OPS_16); -int arcompact_handle18_07_04_dasm(DASM_OPS_16); -int arcompact_handle18_07_05_dasm(DASM_OPS_16); -int arcompact_handle18_07_06_dasm(DASM_OPS_16); -int arcompact_handle18_07_07_dasm(DASM_OPS_16); -int arcompact_handle18_07_08_dasm(DASM_OPS_16); -int arcompact_handle18_07_09_dasm(DASM_OPS_16); -int arcompact_handle18_07_0a_dasm(DASM_OPS_16); -int arcompact_handle18_07_0b_dasm(DASM_OPS_16); -int arcompact_handle18_07_0c_dasm(DASM_OPS_16); -int arcompact_handle18_07_0d_dasm(DASM_OPS_16); -int arcompact_handle18_07_0e_dasm(DASM_OPS_16); -int arcompact_handle18_07_0f_dasm(DASM_OPS_16); -int arcompact_handle18_07_10_dasm(DASM_OPS_16); -int arcompact_handle18_07_12_dasm(DASM_OPS_16); -int arcompact_handle18_07_13_dasm(DASM_OPS_16); -int arcompact_handle18_07_14_dasm(DASM_OPS_16); -int arcompact_handle18_07_15_dasm(DASM_OPS_16); -int arcompact_handle18_07_16_dasm(DASM_OPS_16); -int arcompact_handle18_07_17_dasm(DASM_OPS_16); -int arcompact_handle18_07_18_dasm(DASM_OPS_16); -int arcompact_handle18_07_19_dasm(DASM_OPS_16); -int arcompact_handle18_07_1a_dasm(DASM_OPS_16); -int arcompact_handle18_07_1b_dasm(DASM_OPS_16); -int arcompact_handle18_07_1c_dasm(DASM_OPS_16); -int arcompact_handle18_07_1d_dasm(DASM_OPS_16); -int arcompact_handle18_07_1e_dasm(DASM_OPS_16); -int arcompact_handle18_07_1f_dasm(DASM_OPS_16); diff --git a/src/devices/cpu/arm/arm.cpp b/src/devices/cpu/arm/arm.cpp index 077f693b144..77c8a44ac6d 100644 --- a/src/devices/cpu/arm/arm.cpp +++ b/src/devices/cpu/arm/arm.cpp @@ -20,9 +20,7 @@ #include "emu.h" #include "arm.h" #include "debugger.h" - -CPU_DISASSEMBLE( arm ); -CPU_DISASSEMBLE( arm_be ); +#include "armdasm.h" #define ARM_DEBUG_CORE 0 #define ARM_DEBUG_COPRO 0 @@ -512,7 +510,7 @@ void arm_cpu_device::execute_set_input(int irqline, int state) void arm_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_sArmRegister)); save_item(NAME(m_coproRegister)); @@ -1562,15 +1560,7 @@ void arm_cpu_device::HandleCoPro( uint32_t insn ) } -offs_t arm_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( arm ); - return CPU_DISASSEMBLE_NAME(arm)(this, stream, pc, oprom, opram, options); -} - - -offs_t arm_be_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *arm_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( arm_be ); - return CPU_DISASSEMBLE_NAME(arm_be)(this, stream, pc, oprom, opram, options); + return new arm_disassembler; } diff --git a/src/devices/cpu/arm/arm.h b/src/devices/cpu/arm/arm.h index 2de5fb3a39b..3cfb1386fa9 100644 --- a/src/devices/cpu/arm/arm.h +++ b/src/devices/cpu/arm/arm.h @@ -64,9 +64,7 @@ protected: 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; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -76,7 +74,7 @@ protected: uint8_t m_pendingIrq; uint8_t m_pendingFiq; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; endianness_t m_endian; copro_type m_copro_type; @@ -111,9 +109,6 @@ class arm_be_cpu_device : public arm_cpu_device public: // construction/destruction arm_be_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; }; diff --git a/src/devices/cpu/arm/armdasm.cpp b/src/devices/cpu/arm/armdasm.cpp index 67d65209871..657ceb43550 100644 --- a/src/devices/cpu/arm/armdasm.cpp +++ b/src/devices/cpu/arm/armdasm.cpp @@ -7,9 +7,9 @@ */ #include "emu.h" -#include "arm.h" +#include "armdasm.h" -static void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) +void arm_disassembler::WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) const { /* rrrrbbbbbbbb */ uint32_t imm; @@ -21,7 +21,7 @@ static void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) util::stream_format( stream, ", #$%x", imm ); } -static void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) +void arm_disassembler::WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) const { /* ccccctttmmmm */ static const char *const pRegOp[4] = { "LSL","LSR","ASR","ROR" }; @@ -57,7 +57,7 @@ static void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, i } } -static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) +void arm_disassembler::WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) const { /* ccccctttmmmm */ static const char *const pRegOp[4] = { "LSL","LSR","ASR","ROR" }; @@ -81,7 +81,7 @@ static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) } /* WriteRegisterOperand */ -static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode ) +void arm_disassembler::WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode ) const { opcode &= 0x00ffffff; if( opcode&0x00800000 ) @@ -92,14 +92,14 @@ static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opco util::stream_format( stream, "$%x", pc ); } /* WriteBranchAddress */ -static void WritePadding(std::ostream &stream, std::streampos start_position) +void arm_disassembler::WritePadding(std::ostream &stream, std::streampos start_position) const { std::streamoff difference = stream.tellp() - start_position; for (std::streamoff i = difference; i < 8; i++) stream << ' '; } -static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) +offs_t arm_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { static const char *const pConditionCodeTable[16] = { @@ -119,6 +119,8 @@ static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) uint32_t dasmflags = 0; std::streampos start_position = stream.tellp(); + u32 opcode = opcodes.r32(pc); + pConditionCode= pConditionCodeTable[opcode>>28]; if( (opcode&0x0fc000f0)==0x00000090u ) @@ -193,7 +195,7 @@ static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) case 0x0d: /* look for mov pc,lr */ if (((opcode >> 12) & 0x0f) == 15 && ((opcode >> 0) & 0x0f) == 14 && (opcode & 0x02000000) == 0) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; case 0x0f: WriteDataProcessingOperand(stream, opcode, 1, 0, 1); break; @@ -325,7 +327,7 @@ static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) if( opcode&0x01000000 ) { util::stream_format( stream, "BL" ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { @@ -380,24 +382,21 @@ static uint32_t arm_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) util::stream_format( stream, "SWI%s $%x", pConditionCode, opcode&0x00ffffff ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { util::stream_format( stream, "Undefined" ); } - return dasmflags | DASMFLAG_SUPPORTED; + return 4 | dasmflags | SUPPORTED; } -CPU_DISASSEMBLE( arm ) +u32 arm_disassembler::opcode_alignment() const { - uint32_t opcode = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); - return 4 | arm_disasm(stream, pc, opcode); + return 4; } -CPU_DISASSEMBLE( arm_be ) +arm_disassembler::arm_disassembler() { - uint32_t opcode = oprom[3] | (oprom[2] << 8) | (oprom[1] << 16) | (oprom[0] << 24); - return 4 | arm_disasm(stream, pc, opcode); } diff --git a/src/devices/cpu/arm/armdasm.h b/src/devices/cpu/arm/armdasm.h new file mode 100644 index 00000000000..1e2ed19f394 --- /dev/null +++ b/src/devices/cpu/arm/armdasm.h @@ -0,0 +1,23 @@ + +#ifndef MAME_CPU_ARM_ARMDASM_H +#define MAME_CPU_ARM_ARMDASM_H + +#pragma once + +class arm_disassembler : public util::disasm_interface +{ +public: + arm_disassembler(); + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) const; + void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) const; + void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) const; + void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode ) const; + void WritePadding(std::ostream &stream, std::streampos start_position) const; + +}; + +#endif diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index 4e11ddec049..7a3a7ba30db 100644 --- a/src/devices/cpu/arm7/arm7.cpp +++ b/src/devices/cpu/arm7/arm7.cpp @@ -53,6 +53,7 @@ DEFINE_DEVICE_TYPE(ARM920T, arm920t_cpu_device, "arm920t", "ARM920T") DEFINE_DEVICE_TYPE(ARM946ES, arm946es_cpu_device, "arm946es", "ARM946ES") DEFINE_DEVICE_TYPE(PXA255, pxa255_cpu_device, "pxa255", "Intel XScale PXA255") DEFINE_DEVICE_TYPE(SA1110, sa1110_cpu_device, "sa1110", "Intel StrongARM SA-1110") +DEFINE_DEVICE_TYPE(IGS036, igs036_cpu_device, "igs036", "IGS036") arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : arm7_cpu_device(mconfig, ARM7, tag, owner, clock, 4, ARCHFLAG_T, ENDIANNESS_LITTLE) @@ -67,6 +68,7 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type , m_endian(endianness) , m_archRev(archRev) , m_archFlags(archFlags) + , m_vectorbase(0) , m_pc(0) { memset(m_r, 0x00, sizeof(m_r)); @@ -147,12 +149,24 @@ arm920t_cpu_device::arm920t_cpu_device(const machine_config &mconfig, const char arm946es_cpu_device::arm946es_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : arm9_cpu_device(mconfig, ARM946ES, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E, ENDIANNESS_LITTLE) + : arm9_cpu_device(mconfig, ARM946ES, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E, ENDIANNESS_LITTLE), + cp15_control(0x78) { m_copro_id = ARM9_COPRO_ID_MFR_ARM | ARM9_COPRO_ID_ARCH_V5TE | ARM9_COPRO_ID_PART_ARM946 | ARM9_COPRO_ID_STEP_ARM946_A0; + + memset(ITCM, 0, 0x8000); + memset(DTCM, 0, 0x4000); + + cp15_itcm_base = 0xffffffff; + cp15_itcm_size = 0; + cp15_itcm_end = 0; + cp15_dtcm_base = 0xffffffff; + cp15_dtcm_size = 0; + cp15_dtcm_end = 0; + cp15_itcm_reg = cp15_dtcm_reg = 0; } pxa255_cpu_device::pxa255_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) @@ -175,6 +189,13 @@ sa1110_cpu_device::sa1110_cpu_device(const machine_config &mconfig, const char * | ARM9_COPRO_ID_STEP_SA1110_A0; } +// unknown configuration +igs036_cpu_device::igs036_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : arm9_cpu_device(mconfig, IGS036, tag, owner, clock, 5, ARCHFLAG_T | ARCHFLAG_E, ENDIANNESS_LITTLE) +{ +} + + device_memory_interface::space_config_vector arm7_cpu_device::memory_space_config() const { return space_config_vector { @@ -534,7 +555,7 @@ bool arm7_cpu_device::memory_translate(int spacenum, int intention, offs_t &addr void arm7_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_r)); save_item(NAME(m_pendingIrq)); @@ -654,7 +675,7 @@ void arm7_cpu_device::device_reset() /* start up in SVC mode with interrupts disabled. */ m_r[eCPSR] = I_MASK | F_MASK | 0x10; SwitchMode(eARM7_MODE_SVC); - m_r[eR15] = 0; + m_r[eR15] = 0 | m_vectorbase; m_impstate.cache_dirty = true; } @@ -908,83 +929,14 @@ void arm7_cpu_device::execute_set_input(int irqline, int state) } -offs_t arm7_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *arm7_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( arm7arm ); - extern CPU_DISASSEMBLE( arm7thumb ); - extern CPU_DISASSEMBLE( arm7arm_be ); - extern CPU_DISASSEMBLE( arm7thumb_be ); - - uint8_t fetched_op[4]; - uint32_t op = 0; - int prefetch_index = get_insn_prefetch_index(pc); - if (prefetch_index < 0) - { - memcpy(fetched_op, oprom, 4); - if (T_IS_SET(m_r[eCPSR])) - { - if ( m_endian == ENDIANNESS_BIG ) - { - return CPU_DISASSEMBLE_NAME(arm7thumb_be)(this, stream, pc, fetched_op, opram, options); - } - else - { - return CPU_DISASSEMBLE_NAME(arm7thumb)(this, stream, pc, fetched_op, opram, options); - } - } - else - { - if ( m_endian == ENDIANNESS_BIG ) - { - return CPU_DISASSEMBLE_NAME(arm7arm_be)(this, stream, pc, fetched_op, opram, options); - } - else - { - return CPU_DISASSEMBLE_NAME(arm7arm)(this, stream, pc, fetched_op, opram, options); - } - } - } - else - { - op = m_insn_prefetch_buffer[prefetch_index]; - if (T_IS_SET(m_r[eCPSR])) - { - if (m_endian == ENDIANNESS_BIG) - { - op >>= ((pc & 2) ? 0 : 16); - fetched_op[1] = op & 0xff; - fetched_op[0] = (op >> 8) & 0xff; - return CPU_DISASSEMBLE_NAME(arm7thumb_be)(this, stream, pc, fetched_op, opram, options); - } - else - { - op >>= ((pc & 2) ? 16 : 0); - fetched_op[0] = op & 0xff; - fetched_op[1] = (op >> 8) & 0xff; - return CPU_DISASSEMBLE_NAME(arm7thumb)(this, stream, pc, fetched_op, opram, options); - } - } - else - { - if (m_endian == ENDIANNESS_BIG) - { - fetched_op[3] = op & 0xff; - fetched_op[2] = (op >> 8) & 0xff; - fetched_op[1] = (op >> 16) & 0xff; - fetched_op[0] = (op >> 24) & 0xff; - return CPU_DISASSEMBLE_NAME(arm7arm_be)(this, stream, pc, fetched_op, opram, options); - } - else - { - fetched_op[0] = op & 0xff; - fetched_op[1] = (op >> 8) & 0xff; - fetched_op[2] = (op >> 16) & 0xff; - fetched_op[3] = (op >> 24) & 0xff; - return CPU_DISASSEMBLE_NAME(arm7arm)(this, stream, pc, fetched_op, opram, options); - } - } - } - return 0; + return new arm7_disassembler(this); +} + +bool arm7_cpu_device::get_t_flag() const +{ + return T_IS_SET(m_r[eCPSR]); } @@ -1222,6 +1174,298 @@ WRITE32_MEMBER( arm7_cpu_device::arm7_rt_w_callback ) } } +READ32_MEMBER( arm946es_cpu_device::arm7_rt_r_callback ) +{ + uint32_t opcode = offset; + uint8_t cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT; + uint8_t op2 = ( opcode & INSN_COPRO_OP2 ) >> INSN_COPRO_OP2_SHIFT; + uint8_t op3 = opcode & INSN_COPRO_OP3; + uint8_t cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT; + uint32_t data = 0; + + //printf("arm7946: read cpnum %d cReg %d op2 %d op3 %d (%x)\n", cpnum, cReg, op2, op3, opcode); + if (cpnum == 15) + { + switch( cReg ) + { + case 0: + switch (op2) + { + case 0: // chip ID + data = 0x41059461; + break; + + case 1: // cache ID + data = 0x0f0d2112; + break; + + case 2: // TCM size + data = (6 << 6) | (5 << 18); + break; + } + break; + + case 1: + return cp15_control; + break; + + case 9: + if (op3 == 1) + { + if (op2 == 0) + { + return cp15_dtcm_reg; + } + else + { + return cp15_itcm_reg; + } + } + break; + } + } + + return data; +} + +WRITE32_MEMBER( arm946es_cpu_device::arm7_rt_w_callback ) +{ + uint32_t opcode = offset; + uint8_t cReg = ( opcode & INSN_COPRO_CREG ) >> INSN_COPRO_CREG_SHIFT; + uint8_t op2 = ( opcode & INSN_COPRO_OP2 ) >> INSN_COPRO_OP2_SHIFT; + uint8_t op3 = opcode & INSN_COPRO_OP3; + uint8_t cpnum = (opcode & INSN_COPRO_CPNUM) >> INSN_COPRO_CPNUM_SHIFT; + +// printf("arm7946: copro %d write %x to cReg %d op2 %d op3 %d (mask %08x)\n", cpnum, data, cReg, op2, op3, mem_mask); + + if (cpnum == 15) + { + switch (cReg) + { + case 1: // control + cp15_control = data; + RefreshDTCM(); + RefreshITCM(); + break; + + case 2: // Protection Unit cacheability bits + break; + + case 3: // write bufferability bits for PU + break; + + case 5: // protection unit region controls + break; + + case 6: // protection unit region controls 2 + break; + + case 7: // cache commands + break; + + case 9: // cache lockdown & TCM controls + if (op3 == 1) + { + if (op2 == 0) + { + cp15_dtcm_reg = data; + RefreshDTCM(); + } + else if (op2 == 1) + { + cp15_itcm_reg = data; + RefreshITCM(); + } + } + break; + } + } +} + +void arm946es_cpu_device::RefreshDTCM() +{ + if (cp15_control & (1<<16)) + { + cp15_dtcm_base = (cp15_dtcm_reg & ~0xfff); + cp15_dtcm_size = 512 << ((cp15_dtcm_reg & 0x3f) >> 1); + cp15_dtcm_end = cp15_dtcm_base + cp15_dtcm_size; + //printf("DTCM enabled: base %08x size %x\n", cp15_dtcm_base, cp15_dtcm_size); + } + else + { + cp15_dtcm_base = 0xffffffff; + cp15_dtcm_size = cp15_dtcm_end = 0; + } +} + +void arm946es_cpu_device::RefreshITCM() +{ + if (cp15_control & (1<<18)) + { + cp15_itcm_base = 0; //(cp15_itcm_reg & ~0xfff); + cp15_itcm_size = 512 << ((cp15_itcm_reg & 0x3f) >> 1); + cp15_itcm_end = cp15_itcm_base + cp15_itcm_size; + //printf("ITCM enabled: base %08x size %x\n", cp15_dtcm_base, cp15_dtcm_size); + } + else + { + cp15_itcm_base = 0xffffffff; + cp15_itcm_size = cp15_itcm_end = 0; + } +} + +void arm946es_cpu_device::arm7_cpu_write32(uint32_t addr, uint32_t data) +{ + addr &= ~3; + + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + uint32_t *wp = (uint32_t *)&ITCM[addr&0x7fff]; + *wp = data; + return; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + uint32_t *wp = (uint32_t *)&DTCM[addr&0x3fff]; + *wp = data; + return; + } + + m_program->write_dword(addr, data); +} + + +void arm946es_cpu_device::arm7_cpu_write16(uint32_t addr, uint16_t data) +{ + addr &= ~1; + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + uint16_t *wp = (uint16_t *)&ITCM[addr&0x7fff]; + *wp = data; + return; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + uint16_t *wp = (uint16_t *)&DTCM[addr&0x3fff]; + *wp = data; + return; + } + + m_program->write_word(addr, data); +} + +void arm946es_cpu_device::arm7_cpu_write8(uint32_t addr, uint8_t data) +{ + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + ITCM[addr&0x7fff] = data; + return; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + DTCM[addr&0x3fff] = data; + return; + } + + m_program->write_byte(addr, data); +} + +uint32_t arm946es_cpu_device::arm7_cpu_read32(uint32_t addr) +{ + uint32_t result; + + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + if (addr & 3) + { + uint32_t *wp = (uint32_t *)&ITCM[(addr & ~3)&0x7fff]; + result = *wp; + result = (result >> (8 * (addr & 3))) | (result << (32 - (8 * (addr & 3)))); + } + else + { + uint32_t *wp = (uint32_t *)&ITCM[addr&0x7fff]; + result = *wp; + } + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + if (addr & 3) + { + uint32_t *wp = (uint32_t *)&DTCM[(addr & ~3)&0x3fff]; + result = *wp; + result = (result >> (8 * (addr & 3))) | (result << (32 - (8 * (addr & 3)))); + } + else + { + uint32_t *wp = (uint32_t *)&DTCM[addr&0x3fff]; + result = *wp; + } + } + else + { + if (addr & 3) + { + result = m_program->read_dword(addr & ~3); + result = (result >> (8 * (addr & 3))) | (result << (32 - (8 * (addr & 3)))); + } + else + { + result = m_program->read_dword(addr); + } + } + return result; +} + +uint32_t arm946es_cpu_device::arm7_cpu_read16(uint32_t addr) +{ + uint32_t result; + + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + uint16_t *wp = (uint16_t *)&ITCM[(addr & ~1)&0x7fff]; + result = *wp; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + uint16_t *wp = (uint16_t *)&DTCM[(addr & ~1)&0x3fff]; + result = *wp; + } + else + { + result = m_program->read_word(addr & ~1); + } + + if (addr & 1) + { + result = ((result >> 8) & 0xff) | ((result & 0xff) << 24); + } + + return result; +} + +uint8_t arm946es_cpu_device::arm7_cpu_read8(uint32_t addr) +{ + if ((addr >= cp15_itcm_base) && (addr <= cp15_itcm_end)) + { + return ITCM[addr & 0x7fff]; + } + else if ((addr >= cp15_dtcm_base) && (addr <= cp15_dtcm_end)) + { + return DTCM[addr & 0x3fff]; + } + + // Handle through normal 8 bit handler (for 32 bit cpu) + return m_program->read_byte(addr); +} + +WRITE32_MEMBER(igs036_cpu_device::arm7_rt_w_callback) +{ + arm7_cpu_device::arm7_rt_w_callback(space, offset, data, mem_mask); + /* disable the MMU for now, it doesn't seem to set up valid mappings + so could be entirely different here */ + COPRO_CTRL &= ~COPRO_CTRL_MMU_EN; +} void arm7_cpu_device::arm7_dt_r_callback(uint32_t insn, uint32_t *prn) { @@ -1323,9 +1567,9 @@ uint32_t arm7_cpu_device::arm7_cpu_read32(uint32_t addr) return result; } -uint16_t arm7_cpu_device::arm7_cpu_read16(uint32_t addr) +uint32_t arm7_cpu_device::arm7_cpu_read16(uint32_t addr) { - uint16_t result; + uint32_t result; if( COPRO_CTRL & COPRO_CTRL_MMU_EN ) { @@ -1339,7 +1583,7 @@ uint16_t arm7_cpu_device::arm7_cpu_read16(uint32_t addr) if (addr & 1) { - result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); + result = ((result >> 8) & 0xff) | ((result & 0xff) << 24); } return result; diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h index e6777b39227..f6eecc4e4e1 100644 --- a/src/devices/cpu/arm7/arm7.h +++ b/src/devices/cpu/arm7/arm7.h @@ -23,6 +23,8 @@ #pragma once +#include "arm7dasm.h" + #include "cpu/drcfe.h" #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" @@ -31,6 +33,9 @@ #define ARM7_MAX_FASTRAM 4 #define ARM7_MAX_HOTSPOTS 16 +#define MCFG_ARM_HIGH_VECTORS() \ + arm7_cpu_device::set_high_vectors(*device); + /*************************************************************************** COMPILER-SPECIFIC OPTIONS @@ -46,12 +51,18 @@ * PUBLIC FUNCTIONS ***************************************************************************************************/ -class arm7_cpu_device : public cpu_device +class arm7_cpu_device : public cpu_device, public arm7_disassembler::config { public: // construction/destruction arm7_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + static void set_high_vectors(device_t &device) + { + arm7_cpu_device &dev = downcast<arm7_cpu_device &>(device); + dev.m_vectorbase = 0xffff0000; + } + protected: enum { @@ -121,9 +132,8 @@ protected: 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 2; } - 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; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_t_flag() const override; address_space_config m_program_config; @@ -152,7 +162,7 @@ protected: int m_icount; endianness_t m_endian; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; /* Coprocessor Registers */ uint32_t m_control; @@ -168,6 +178,8 @@ protected: uint8_t m_archRev; // ARM architecture revision (3, 4, and 5 are valid) uint8_t m_archFlags; // architecture flags + uint32_t m_vectorbase; + //#if ARM7_MMU_ENABLE_HACK // uint32_t mmu_enable_addr; // workaround for "MMU is enabled when PA != VA" problem //#endif @@ -220,17 +232,17 @@ protected: int detect_fault(int desc_lvl1, int ap, int flags); void arm7_check_irq_state(); void update_irq_state(); - void arm7_cpu_write32(uint32_t addr, uint32_t data); - void arm7_cpu_write16(uint32_t addr, uint16_t data); - void arm7_cpu_write8(uint32_t addr, uint8_t data); - uint32_t arm7_cpu_read32(uint32_t addr); - uint16_t arm7_cpu_read16(uint32_t addr); - uint8_t arm7_cpu_read8(uint32_t addr); + virtual void arm7_cpu_write32(uint32_t addr, uint32_t data); + virtual void arm7_cpu_write16(uint32_t addr, uint16_t data); + virtual void arm7_cpu_write8(uint32_t addr, uint8_t data); + virtual uint32_t arm7_cpu_read32(uint32_t addr); + virtual uint32_t arm7_cpu_read16(uint32_t addr); + virtual uint8_t arm7_cpu_read8(uint32_t addr); // Coprocessor support DECLARE_WRITE32_MEMBER( arm7_do_callback ); - DECLARE_READ32_MEMBER( arm7_rt_r_callback ); - DECLARE_WRITE32_MEMBER( arm7_rt_w_callback ); + virtual DECLARE_READ32_MEMBER( arm7_rt_r_callback ); + virtual DECLARE_WRITE32_MEMBER( arm7_rt_w_callback ); void arm7_dt_r_callback(uint32_t insn, uint32_t *prn); void arm7_dt_w_callback(uint32_t insn, uint32_t *prn); @@ -602,6 +614,25 @@ class arm946es_cpu_device : public arm9_cpu_device public: // construction/destruction arm946es_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // 946E-S has Protection Unit instead of ARM MMU so CP15 is quite different + virtual DECLARE_READ32_MEMBER( arm7_rt_r_callback ) override; + virtual DECLARE_WRITE32_MEMBER( arm7_rt_w_callback ) override; + + virtual void arm7_cpu_write32(uint32_t addr, uint32_t data) override; + virtual void arm7_cpu_write16(uint32_t addr, uint16_t data) override; + virtual void arm7_cpu_write8(uint32_t addr, uint8_t data) override; + virtual uint32_t arm7_cpu_read32(uint32_t addr) override; + virtual uint32_t arm7_cpu_read16(uint32_t addr) override; + virtual uint8_t arm7_cpu_read8(uint32_t addr) override; + +private: + uint32_t cp15_control, cp15_itcm_base, cp15_dtcm_base, cp15_itcm_size, cp15_dtcm_size; + uint32_t cp15_itcm_end, cp15_dtcm_end, cp15_itcm_reg, cp15_dtcm_reg; + uint8_t ITCM[0x8000], DTCM[0x4000]; + + void RefreshITCM(); + void RefreshDTCM(); }; @@ -620,6 +651,14 @@ public: sa1110_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; +class igs036_cpu_device : public arm9_cpu_device +{ +public: + // construction/destruction + igs036_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual DECLARE_WRITE32_MEMBER( arm7_rt_w_callback ) override; +}; + DECLARE_DEVICE_TYPE(ARM7, arm7_cpu_device) DECLARE_DEVICE_TYPE(ARM7_BE, arm7_be_cpu_device) @@ -629,5 +668,6 @@ DECLARE_DEVICE_TYPE(ARM920T, arm920t_cpu_device) DECLARE_DEVICE_TYPE(ARM946ES, arm946es_cpu_device) DECLARE_DEVICE_TYPE(PXA255, pxa255_cpu_device) DECLARE_DEVICE_TYPE(SA1110, sa1110_cpu_device) +DECLARE_DEVICE_TYPE(IGS036, igs036_cpu_device) #endif // MAME_CPU_ARM7_ARM7_H diff --git a/src/devices/cpu/arm7/arm7core.h b/src/devices/cpu/arm7/arm7core.h index 14d6f6267e8..9ae499ae109 100644 --- a/src/devices/cpu/arm7/arm7core.h +++ b/src/devices/cpu/arm7/arm7core.h @@ -163,7 +163,7 @@ struct arm_state int m_icount; endianness_t m_endian; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; /* Coprocessor Registers */ uint32_t m_control; diff --git a/src/devices/cpu/arm7/arm7core.hxx b/src/devices/cpu/arm7/arm7core.hxx index 0e418209e73..0fbe5f00868 100644 --- a/src/devices/cpu/arm7/arm7core.hxx +++ b/src/devices/cpu/arm7/arm7core.hxx @@ -136,6 +136,7 @@ void arm7_cpu_device::arm7_check_irq_state() set_cpsr(GET_CPSR | I_MASK | F_MASK); /* Mask both IRQ & FIQ */ set_cpsr(GET_CPSR & ~T_MASK); R15 = 0x1c; /* IRQ Vector address */ + R15 |= m_vectorbase; if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; return; } @@ -159,6 +160,7 @@ void arm7_cpu_device::arm7_check_irq_state() temp = (GET_CPSR & 0x0FFFFF3F) /* N Z C V I F */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */; set_cpsr(temp); /* Mask IRQ */ } + R15 |= m_vectorbase; if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; return; } @@ -172,7 +174,7 @@ void arm7_cpu_device::arm7_check_irq_state() SetRegister(SPSR, cpsr); /* Save current CPSR */ set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */ set_cpsr(GET_CPSR & ~T_MASK); - R15 = 0x0c; /* IRQ Vector address */ + R15 = 0x0c | m_vectorbase; /* IRQ Vector address */ if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; m_pendingAbtP = false; update_irq_state(); @@ -196,7 +198,7 @@ void arm7_cpu_device::arm7_check_irq_state() SetRegister(SPSR, cpsr); /* Save current CPSR */ set_cpsr(GET_CPSR | I_MASK); /* Mask IRQ */ set_cpsr(GET_CPSR & ~T_MASK); - R15 = 0x04; /* IRQ Vector address */ + R15 = 0x04 | m_vectorbase; /* IRQ Vector address */ if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; m_pendingUnd = false; update_irq_state(); @@ -230,6 +232,7 @@ void arm7_cpu_device::arm7_check_irq_state() temp = (GET_CPSR & 0x0FFFFF3F) /* N Z C V I F */ | (R15 & 0xF0000000) /* N Z C V */ | ((R15 & 0x0C000000) >> (26 - 6)) /* I F */; set_cpsr(temp); /* Mask IRQ */ } + R15 |= m_vectorbase; if ((COPRO_CTRL & COPRO_CTRL_MMU_EN) && (COPRO_CTRL & COPRO_CTRL_INTVEC_ADJUST)) R15 |= 0xFFFF0000; m_pendingSwi = false; update_irq_state(); diff --git a/src/devices/cpu/arm7/arm7dasm.cpp b/src/devices/cpu/arm7/arm7dasm.cpp index 3d38ea29872..efe3459898c 100644 --- a/src/devices/cpu/arm7/arm7dasm.cpp +++ b/src/devices/cpu/arm7/arm7dasm.cpp @@ -23,16 +23,17 @@ ******************************************************************************/ #include "emu.h" +#include "arm7dasm.h" #include "arm7core.h" -static void WritePadding(std::ostream &stream, std::streampos start_position) +void arm7_disassembler::WritePadding(std::ostream &stream, std::streampos start_position) { std::streamoff difference = stream.tellp() - start_position; for (std::streamoff i = difference; i < 8; i++) stream << ' '; } -static void DasmCoProc_RT(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) +void arm7_disassembler::DasmCoProc_RT(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) { /* co processor register transfer */ /* xxxx 1110 oooL nnnn dddd cccc ppp1 mmmm */ @@ -51,7 +52,7 @@ static void DasmCoProc_RT(std::ostream &stream, uint32_t opcode, const char *pCo if((opcode>>5)&7) util::stream_format( stream, ", %d",(opcode>>5)&7); } -static void DasmCoProc_DT(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) +void arm7_disassembler::DasmCoProc_DT(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) { /* co processor data transfer */ /* xxxx 111P UNWL nnnn dddd pppp oooooooo */ @@ -75,7 +76,7 @@ static void DasmCoProc_DT(std::ostream &stream, uint32_t opcode, const char *pCo util::stream_format(stream, "%s%s",(opcode&0x1000000)?"]":"",(opcode&0x200000)?"{!}":""); } -static void DasmCoProc_DO(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) +void arm7_disassembler::DasmCoProc_DO(std::ostream &stream, uint32_t opcode, const char *pConditionCode, std::streampos start_position) { /* co processor data operation */ /* xxxx 1110 oooo nnnn dddd cccc ppp0 mmmm */ @@ -88,7 +89,7 @@ static void DasmCoProc_DO(std::ostream &stream, uint32_t opcode, const char *pCo if((opcode>>5)&7) util::stream_format(stream, ", %d",(opcode>>5)&7); } -static void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) +void arm7_disassembler::WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) { /* rrrrbbbbbbbb */ uint32_t imm; @@ -100,7 +101,7 @@ static void WriteImmediateOperand( std::ostream &stream, uint32_t opcode ) util::stream_format( stream, ", #$%x", imm ); } -static void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) +void arm7_disassembler::WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, int printOp0, int printOp1, int printOp2 ) { /* ccccctttmmmm */ static const char *const pRegOp[4] = { "LSL","LSR","ASR","ROR" }; @@ -142,7 +143,7 @@ static void WriteDataProcessingOperand( std::ostream &stream, uint32_t opcode, i } } -static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) +void arm7_disassembler::WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) { /* ccccctttmmmm */ static const char *const pRegOp[4] = { "LSL","LSR","ASR","ROR" }; @@ -172,7 +173,7 @@ static void WriteRegisterOperand1( std::ostream &stream, uint32_t opcode ) } /* WriteRegisterOperand */ -static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode, bool h_bit ) +void arm7_disassembler::WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opcode, bool h_bit ) { opcode <<= 2; if (h_bit && (opcode & 0x04000000)) @@ -188,7 +189,7 @@ static void WriteBranchAddress( std::ostream &stream, uint32_t pc, uint32_t opco util::stream_format( stream, "$%x", pc ); } /* WriteBranchAddress */ -static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) +u32 arm7_disassembler::arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode ) { static const char *const pConditionCodeTable[16] = { @@ -212,14 +213,22 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode if( (opcode&0xfe000000)==0xfa000000 ) //bits 31-25 == 1111 101 (BLX - v5) { - /* BLX */ + /* BLX(1) */ util::stream_format( stream, "BLX" ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; WritePadding(stream, start_position); WriteBranchAddress( stream, pc, opcode, true ); } + else if( (opcode&0x0ff000f0)==0x01200030 ) // (BLX - v5) + { + /* BLX(2) */ + util::stream_format( stream, "BLX" ); + dasmflags = STEP_OVER; + WritePadding(stream, start_position); + util::stream_format( stream, "R%d",(opcode&0xf)); + } else if( (opcode&0x0ffffff0)==0x012fff10 ) //bits 27-4 == 000100101111111111110001 { /* Branch and Exchange (BX) */ @@ -228,7 +237,7 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode WritePadding(stream, start_position); util::stream_format( stream, "R%d",(opcode&0xf)); if ((opcode & 0x0f) == 14) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; } else if ((opcode & 0x0ff000f0) == 0x01600010) // CLZ - v5 { @@ -492,7 +501,7 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode case 0x0d: /* look for mov pc,lr */ if (((opcode >> 12) & 0x0f) == 15 && ((opcode >> 0) & 0x0f) == 14 && (opcode & 0x02000000) == 0) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; case 0x0f: WriteDataProcessingOperand(stream, opcode, 1, 0, 1); break; @@ -641,7 +650,7 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode if( opcode&0x01000000 ) { util::stream_format( stream, "BL" ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { @@ -680,16 +689,16 @@ static uint32_t arm7_disasm( std::ostream &stream, uint32_t pc, uint32_t opcode util::stream_format( stream, "SWI%s $%x", pConditionCode, opcode&0x00ffffff ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { util::stream_format( stream, "Undefined" ); } - return dasmflags | DASMFLAG_SUPPORTED; + return 4 | dasmflags | SUPPORTED; } -static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) +u32 arm7_disassembler::thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) { std::streampos start_position = stream.tellp(); uint32_t dasmflags = 0; @@ -970,7 +979,7 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) rd = ( ( opcode & THUMB_HIREG_RS ) >> THUMB_HIREG_RS_SHIFT ) + 8; util::stream_format( stream, "BX R%d", rd ); if (rd == 14) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; break; case 0x2: rd = ( opcode & THUMB_HIREG_RS ) >> THUMB_HIREG_RS_SHIFT; @@ -1279,7 +1288,7 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) { addr = ( ( opcode & THUMB_BLOP_OFFS ) << 1 ) & 0xfffc; util::stream_format( stream, "BLX (LO) %08x", addr ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { @@ -1295,7 +1304,7 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) if( opcode & THUMB_BLOP_LO ) { util::stream_format( stream, "BL (LO) %08x", ( opcode & THUMB_BLOP_OFFS ) << 1 ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } else { @@ -1305,7 +1314,7 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) addr |= 0xff800000; } util::stream_format( stream, "BL (HI) %08x", addr ); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } break; default: @@ -1313,25 +1322,22 @@ static uint32_t thumb_disasm(std::ostream &stream, uint32_t pc, uint16_t opcode) break; } - return dasmflags | DASMFLAG_SUPPORTED; + return 2 | dasmflags | SUPPORTED; } -CPU_DISASSEMBLE( arm7arm ) +arm7_disassembler::arm7_disassembler(config *conf) : m_config(conf) { - return arm7_disasm(stream, pc, oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24)) | 4; } -CPU_DISASSEMBLE( arm7arm_be ) +u32 arm7_disassembler::opcode_alignment() const { - return arm7_disasm(stream, pc, oprom[3] | (oprom[2] << 8) | (oprom[1] << 16) | (oprom[0] << 24)) | 4; + return m_config->get_t_flag() ? 2 : 4; } -CPU_DISASSEMBLE( arm7thumb ) +offs_t arm7_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - return thumb_disasm(stream, pc, oprom[0] | (oprom[1] << 8)) | 2; -} - -CPU_DISASSEMBLE( arm7thumb_be ) -{ - return thumb_disasm(stream, pc, oprom[1] | (oprom[0] << 8)) | 2; + if(m_config->get_t_flag()) + return thumb_disasm(stream, pc, opcodes.r16(pc)); + else + return arm7_disasm(stream, pc, opcodes.r32(pc)); } diff --git a/src/devices/cpu/arm7/arm7dasm.h b/src/devices/cpu/arm7/arm7dasm.h new file mode 100644 index 00000000000..9f90b47308f --- /dev/null +++ b/src/devices/cpu/arm7/arm7dasm.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Steve Ellenoff,R. Belmont,Ryan Holtz +/***************************************************************************** + * + * arm7dasm.c + * Portable ARM7TDMI Core Emulator - Disassembler + * + * Copyright Steve Ellenoff, all rights reserved. + * + * This work is based on: + * #1) 'Atmel Corporation ARM7TDMI (Thumb) Datasheet - January 1999' + * #2) Arm 2/3/6 emulator By Bryan McPhail (bmcphail@tendril.co.uk) and Phil Stroffolino (MAME CORE 0.76) + * + *****************************************************************************/ + +#ifndef MAME_CPU_ARM7_ARM7DASM_H +#define MAME_CPU_ARM7_ARM7DASM_H + +#pragma once + +class arm7_disassembler : public util::disasm_interface +{ +public: + class config { + public: + virtual ~config() = default; + virtual bool get_t_flag() const = 0; + }; + + arm7_disassembler(config *conf); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + config *m_config; + + void WritePadding(std::ostream &stream, std::streampos start_position); + void DasmCoProc_RT(std::ostream &stream, u32 opcode, const char *pConditionCode, std::streampos start_position); + void DasmCoProc_DT(std::ostream &stream, u32 opcode, const char *pConditionCode, std::streampos start_position); + void DasmCoProc_DO(std::ostream &stream, u32 opcode, const char *pConditionCode, std::streampos start_position); + void WriteImmediateOperand( std::ostream &stream, u32 opcode ); + void WriteDataProcessingOperand( std::ostream &stream, u32 opcode, int printOp0, int printOp1, int printOp2 ); + void WriteRegisterOperand1( std::ostream &stream, u32 opcode ); + void WriteBranchAddress( std::ostream &stream, u32 pc, u32 opcode, bool h_bit ); + u32 arm7_disasm( std::ostream &stream, u32 pc, u32 opcode ); + u32 thumb_disasm(std::ostream &stream, u32 pc, u16 opcode); +}; + + +#endif diff --git a/src/devices/cpu/arm7/arm7ops.cpp b/src/devices/cpu/arm7/arm7ops.cpp index 9f6c998abed..3e0b9a599c2 100644 --- a/src/devices/cpu/arm7/arm7ops.cpp +++ b/src/devices/cpu/arm7/arm7ops.cpp @@ -66,18 +66,12 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry) if ((insn & 0x80) == 0x80) LOG(("%08x: RegShift ERROR (p36)\n", R15)); #endif - - // see p35 for check on this - //k = GetRegister(k >> 1) & 0x1f; - // Keep only the bottom 8 bits for a Register Shift k = GetRegister(k >> 1) & 0xff; if (k == 0) /* Register shift by 0 is a no-op */ { // LOG(("%08x: NO-OP Regshift\n", R15)); - /* TODO this is wrong for at least ROR by reg with lower - * 5 bits 0 but lower 8 bits non zero */ if (pCarry) *pCarry = GET_CPSR & C_MASK; return rm; @@ -145,11 +139,19 @@ uint32_t arm7_cpu_device::decodeShift(uint32_t insn, uint32_t *pCarry) case 3: /* ROR and RRX */ if (k) { - while (k > 32) - k -= 32; - if (pCarry) - *pCarry = rm & (1 << (k - 1)); - return ROR(rm, k); + k &= 31; + if (k) + { + if (pCarry) + *pCarry = rm & (1 << (k - 1)); + return ROR(rm, k); + } + else + { + if (pCarry) + *pCarry = rm & SIGN_BIT; + return rm; + } } else { @@ -378,8 +380,8 @@ void arm7_cpu_device::HandleBranch(uint32_t insn, bool h_bit) off |= (insn & 0x01000000) >> 23; } - /* Save PC into LR if this is a branch with link */ - if (insn & INSN_BL) + /* Save PC into LR if this is a branch with link or a BLX */ + if ((insn & INSN_BL) || ((m_archRev >= 5) && ((insn & 0xfe000000) == 0xfa000000))) { SetRegister(14, R15 + 4); } @@ -490,8 +492,13 @@ void arm7_cpu_device::HandleMemSingle(uint32_t insn) R15 = data - 4; else R15 = (R15 & ~0x03FFFFFC) /* N Z C V I F M1 M0 */ | ((data - 4) & 0x03FFFFFC); - // LDR, PC takes 2S + 2N + 1I (5 total cycles) + // LDR, PC takes 2S + 2N + 1I (5 total cycles) ARM7_ICOUNT -= 2; + if ((data & 1) && m_archRev >= 5) + { + set_cpsr(GET_CPSR | T_MASK); + R15--; + } } else { @@ -641,10 +648,10 @@ void arm7_cpu_device::HandleHalfWordDT(uint32_t insn) // Signed Half Word? if (insn & 0x20) { - uint16_t signbyte, databyte; - databyte = READ16(rnv) & 0xFFFF; - signbyte = (databyte & 0x8000) ? 0xffff : 0; - newval = (uint32_t)(signbyte << 16)|databyte; + uint32_t databyte = READ16(rnv); + uint32_t mask = 0x0000ffff; + mask >>= (rnv & 1) ? 8 : 0; + newval = databyte | ((databyte & ((mask + 1) >> 1)) ? ~mask : 0); } // Signed Byte else { @@ -1371,6 +1378,12 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn) SwitchMode(temp & 3); } } + else + if ((R15 & 1) && m_archRev >= 5) + { + set_cpsr(GET_CPSR | T_MASK); + R15--; + } // LDM PC - takes 2 extra cycles ARM7_ICOUNT -= 2; } @@ -1428,6 +1441,12 @@ void arm7_cpu_device::HandleMemBlock(uint32_t insn) SwitchMode(temp & 3); } } + else + if ((R15 & 1) && m_archRev >= 5) + { + set_cpsr(GET_CPSR | T_MASK); + R15--; + } // LDM PC - takes 2 extra cycles ARM7_ICOUNT -= 2; } @@ -1641,6 +1660,18 @@ void arm7_cpu_device::arm7ops_0123(uint32_t insn) R15--; } } + else if ((insn & 0x0ff000f0) == 0x01200030) // BLX Rn - v5 + { + // save link address + SetRegister(14, R15 + 4); + + R15 = GetRegister(insn & 0x0f); + // If new PC address has A0 set, switch to Thumb mode + if (R15 & 1) { + set_cpsr(GET_CPSR|T_MASK); + R15--; + } + } else if ((insn & 0x0ff000f0) == 0x01600010) // CLZ - v5 { uint32_t rm = insn&0xf; diff --git a/src/devices/cpu/arm7/arm7thmb.cpp b/src/devices/cpu/arm7/arm7thmb.cpp index 251e5b16408..0d25d62fcf3 100644 --- a/src/devices/cpu/arm7/arm7thmb.cpp +++ b/src/devices/cpu/arm7/arm7thmb.cpp @@ -1557,18 +1557,21 @@ void arm7_cpu_device::tg0e_0(uint32_t pc, uint32_t op) void arm7_cpu_device::tg0e_1(uint32_t pc, uint32_t op) { + /* BLX (LO) */ + uint32_t addr = GetRegister(14); addr += (op & THUMB_BLOP_OFFS) << 1; addr &= 0xfffffffc; - SetRegister(14, (R15 + 4) | 1); + SetRegister(14, (R15 + 2) | 1); R15 = addr; set_cpsr(GET_CPSR & ~T_MASK); } - /* BL */ void arm7_cpu_device::tg0f_0(uint32_t pc, uint32_t op) { + /* BL (HI) */ + uint32_t addr = (op & THUMB_BLOP_OFFS) << 12; if (addr & (1 << 22)) { @@ -1581,6 +1584,8 @@ void arm7_cpu_device::tg0f_0(uint32_t pc, uint32_t op) void arm7_cpu_device::tg0f_1(uint32_t pc, uint32_t op) /* BL */ { + /* BL (LO) */ + uint32_t addr = GetRegister(14) & ~1; addr += (op & THUMB_BLOP_OFFS) << 1; SetRegister(14, (R15 + 2) | 1); diff --git a/src/devices/cpu/asap/asap.cpp b/src/devices/cpu/asap/asap.cpp index e808f3fbb6c..c5d91084a83 100644 --- a/src/devices/cpu/asap/asap.cpp +++ b/src/devices/cpu/asap/asap.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "asap.h" +#include "asapdasm.h" #include "debugger.h" @@ -183,7 +184,7 @@ void asap_device::device_start() { // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // register our state for the debugger state_add(STATE_GENPC, "GENPC", m_pc).noshow(); @@ -300,40 +301,16 @@ void asap_device::state_string_export(const device_state_entry &entry, std::stri //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t asap_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t asap_device::disasm_max_opcode_bytes() const -{ - return 12; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t asap_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *asap_device::create_disassembler() { - extern CPU_DISASSEMBLE( asap ); - return CPU_DISASSEMBLE_NAME(asap)(this, stream, pc, oprom, opram, options); + return new asap_disassembler; } - //************************************************************************** // INLINE HELPERS //************************************************************************** diff --git a/src/devices/cpu/asap/asap.h b/src/devices/cpu/asap/asap.h index 55d78d5b6cf..bfeb7c60350 100644 --- a/src/devices/cpu/asap/asap.h +++ b/src/devices/cpu/asap/asap.h @@ -89,9 +89,7 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // helpers inline uint32_t readop(offs_t pc); @@ -240,7 +238,7 @@ protected: uint8_t m_irq_state; int m_icount; address_space * m_program; - direct_read_data * m_direct; + direct_read_data<0> *m_direct; // src2val table, registers are at the end uint32_t m_src2val[65536]; diff --git a/src/devices/cpu/asap/asapdasm.cpp b/src/devices/cpu/asap/asapdasm.cpp index 840c50f2635..8f652b6dad4 100644 --- a/src/devices/cpu/asap/asapdasm.cpp +++ b/src/devices/cpu/asap/asapdasm.cpp @@ -9,10 +9,10 @@ ***************************************************************************/ #include "emu.h" -#include "asap.h" +#include "asapdasm.h" -static const char *const reg[32] = +const char *const asap_disassembler::reg[32] = { "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -20,12 +20,12 @@ static const char *const reg[32] = "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" }; -static const char *const setcond[2] = +const char *const asap_disassembler::setcond[2] = { " ", ".c" }; -static const char *const condition[16] = +const char *const asap_disassembler::condition[16] = { "sp", "mz", "gt", "le", "ge", "lt", "hi", "ls", "cc", "cs", "pl", "mi", "ne", "eq", "vc", "vs" }; @@ -35,19 +35,17 @@ static const char *const condition[16] = CODE CODE ***************************************************************************/ -static inline char *src2(uint32_t op, int scale) +std::string asap_disassembler::src2(uint32_t op, int scale) { - static char temp[20]; if ((op & 0xffe0) == 0xffe0) - sprintf(temp, "%s", reg[op & 31]); + return util::string_format("%s", reg[op & 31]); else - sprintf(temp, "$%x", (op & 0xffff) << scale); - return temp; + return util::string_format("$%x", (op & 0xffff) << scale); } -CPU_DISASSEMBLE(asap) +offs_t asap_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); + uint32_t op = opcodes.r32(pc); int opcode = op >> 27; int cond = (op >> 21) & 1; int rdst = (op >> 22) & 31; @@ -58,21 +56,21 @@ CPU_DISASSEMBLE(asap) switch (opcode) { - case 0x00: util::stream_format(stream, "trap $00"); flags = DASMFLAG_STEP_OVER; break; + case 0x00: util::stream_format(stream, "trap $00"); flags = STEP_OVER; break; case 0x01: util::stream_format(stream, "b%s $%08x", condition[rdst & 15], pc + ((int32_t)(op << 10) >> 8)); break; case 0x02: if ((op & 0x003fffff) == 3) { - uint32_t nextop = oprom[4] | (oprom[5] << 8) | (oprom[6] << 16) | (oprom[7] << 24); + uint32_t nextop = opcodes.r32(pc+4); if ((nextop >> 27) == 0x10 && ((nextop >> 22) & 31) == rdst && (nextop & 0xffff) == 0) { - uint32_t nextnextop = oprom[8] | (oprom[9] << 8) | (oprom[10] << 16) | (oprom[11] << 24); + uint32_t nextnextop = opcodes.r32(pc+8); util::stream_format(stream, "llit%s $%08x,%s", setcond[cond], nextnextop, reg[rdst]); - return 12 | DASMFLAG_STEP_OVER | DASMFLAG_SUPPORTED; + return 12 | STEP_OVER | SUPPORTED; } } if (rdst) { - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); util::stream_format(stream, "bsr %s,$%08x", reg[rdst], pc + ((int32_t)(op << 10) >> 8)); } else @@ -123,24 +121,29 @@ CPU_DISASSEMBLE(asap) case 0x1d: util::stream_format(stream, "putps %s", src2(op,0)); break; case 0x1e: if (rdst && rsrc2_iszero) { - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); util::stream_format(stream, "jsr%s %s,%s", setcond[cond], reg[rdst], reg[rsrc1]); } else if (rdst) { - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); util::stream_format(stream, "jsr%s %s,%s[%s]", setcond[cond], reg[rdst], reg[rsrc1], src2(op,2)); } else if (rsrc2_iszero) { if (rsrc1 == 28) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; util::stream_format(stream, "jmp%s %s", setcond[cond], reg[rsrc1]); } else util::stream_format(stream, "jmp%s %s[%s]", setcond[cond], reg[rsrc1], src2(op,2)); break; - case 0x1f: util::stream_format(stream, "trap $1f"); flags = DASMFLAG_STEP_OVER; break; + case 0x1f: util::stream_format(stream, "trap $1f"); flags = STEP_OVER; break; } - return 4 | flags | DASMFLAG_SUPPORTED; + return 4 | flags | SUPPORTED; +} + +u32 asap_disassembler::opcode_alignment() const +{ + return 4; } diff --git a/src/devices/cpu/asap/asapdasm.h b/src/devices/cpu/asap/asapdasm.h new file mode 100644 index 00000000000..45ca554368d --- /dev/null +++ b/src/devices/cpu/asap/asapdasm.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + asapdasm.c + Disassembler for the portable ASAP emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_ASAP_ASAPDASM_H +#define MAME_CPU_ASAP_ASAPDASM_H + +#pragma once + +class asap_disassembler : public util::disasm_interface +{ +public: + asap_disassembler() = default; + virtual ~asap_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const reg[32]; + static const char *const setcond[2]; + static const char *const condition[16]; + std::string src2(uint32_t op, int scale); + +}; + +#endif diff --git a/src/devices/cpu/avr8/avr8.cpp b/src/devices/cpu/avr8/avr8.cpp index 763cdad799e..2f55b4a0317 100644 --- a/src/devices/cpu/avr8/avr8.cpp +++ b/src/devices/cpu/avr8/avr8.cpp @@ -59,6 +59,7 @@ #include "emu.h" #include "avr8.h" +#include "avr8dasm.h" #include "debugger.h" #define VERBOSE_LEVEL (0) @@ -911,36 +912,13 @@ void avr8_device::state_string_export(const device_state_entry &entry, std::stri //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t avr8_device::disasm_min_opcode_bytes() const -{ - return 2; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t avr8_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t avr8_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *avr8_device::create_disassembler() { - extern CPU_DISASSEMBLE( avr8 ); - return CPU_DISASSEMBLE_NAME(avr8)(this, stream, pc, oprom, opram, options); + return new avr8_disassembler; } diff --git a/src/devices/cpu/avr8/avr8.h b/src/devices/cpu/avr8/avr8.h index 0da73a4cc1c..f8c953a3aa3 100644 --- a/src/devices/cpu/avr8/avr8.h +++ b/src/devices/cpu/avr8/avr8.h @@ -123,9 +123,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -848,6 +846,4 @@ enum #define AVR8_SPCR_CPHA_MASK 0x04 #define AVR8_SPCR_SPR_MASK 0x03 -CPU_DISASSEMBLE( avr8 ); - #endif /* __AVR8_H__ */ diff --git a/src/devices/cpu/avr8/avr8dasm.cpp b/src/devices/cpu/avr8/avr8dasm.cpp index cfc99b955d3..5f47198c425 100644 --- a/src/devices/cpu/avr8/avr8dasm.cpp +++ b/src/devices/cpu/avr8/avr8dasm.cpp @@ -7,7 +7,7 @@ */ #include "emu.h" -#include "avr8.h" +#include "avr8dasm.h" #define RD2(op) (((op) >> 4) & 0x0003) #define RD3(op) (((op) >> 4) & 0x0007) @@ -25,11 +25,16 @@ #define ACONST6(op) ((((op) >> 5) & 0x0030) | ((op) & 0x000f)) #define MULCONST2(op) ((((op) >> 6) & 0x0002) | (((op) >> 3) & 0x0001)) -CPU_DISASSEMBLE(avr8) +u32 avr8_disassembler::opcode_alignment() const { - int pos = 0; - uint32_t op = oprom[pos++]; - op |= oprom[pos++] << 8; + return 2; +} + +offs_t avr8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + offs_t base_pc = pc; + uint32_t op = opcodes.r16(pc); + pc += 2; uint32_t addr; const char* register_names[0x40] = {"PINA", "DDRA", "PORTA", "PINB", "DDRB", "PORTB", "PINC", "DDRC", "PORTC", "PIND", "DDRD", "PORTD", "PINE", "DDRE", "PORTE", "PINF", "DDRF", "PORTF", "PING", "DDRG", "PORTG", "TIFR0", "TIFR1", "TIFR2","TIFR3", "TIFR4", "TIFR5", "PCIFR", "EIFR", "EIMSK", "GPIOR0", "EECR", "EEDR", "EEARL", "EEARH", "GTCCR", "TCCR0A", "TCCR0B", "TCNT0", "OCR0A", "OCR0B", "0x29", "GPIOR1", "GPIOR2", "SPCR", "SPSR", "SPDR", "0x2F", "ACSR", "OCDR", "0x32", "SMCR", "MCUSR", "MCUCR", "0x36", "SPMCSR", "0x38", "0x39", "0x3A", "RAMPZ", "EIND", "SPL", "SPH", "SREG"}; @@ -226,8 +231,8 @@ CPU_DISASSEMBLE(avr8) { case 0x0000: op <<= 16; - op |= oprom[pos++]; - op |= oprom[pos++] << 8; + op |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "LDS R%d, (0x%04x)", RD5(op >> 16), op & 0x0000ffff); break; case 0x0001: @@ -277,8 +282,8 @@ CPU_DISASSEMBLE(avr8) { case 0x0000: op <<= 16; - op |= oprom[pos++]; - op |= oprom[pos++] << 8; + op |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "STS (0x%04x), R%d", op & 0x0000ffff, RD5(op >> 16)); break; case 0x0001: @@ -410,15 +415,15 @@ CPU_DISASSEMBLE(avr8) case 0x000c: case 0x000d: addr = KCONST22(op) << 16; - addr |= oprom[pos++]; - addr |= oprom[pos++] << 8; + addr |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "JMP 0x%06x", addr << 1); break; case 0x000e: case 0x000f: addr = KCONST22(op) << 16; - addr |= oprom[pos++]; - addr |= oprom[pos++] << 8; + addr |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "CALL 0x%06x", addr << 1); break; default: @@ -505,15 +510,15 @@ CPU_DISASSEMBLE(avr8) case 0x000c: case 0x000d: op <<= 16; - op |= oprom[pos++]; - op |= oprom[pos++] << 8; + op |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "JMP 0x%06x", KCONST22(op) << 1); break; case 0x000e: case 0x000f: op <<= 16; - op |= oprom[pos++]; - op |= oprom[pos++] << 8; + op |= opcodes.r16(pc); + pc += 2; util::stream_format(stream, "CALL 0x%06x", KCONST22(op) << 1); break; } @@ -669,5 +674,5 @@ CPU_DISASSEMBLE(avr8) break; } - return pos | DASMFLAG_SUPPORTED; + return (pc - base_pc) | SUPPORTED; } diff --git a/src/devices/cpu/avr8/avr8dasm.h b/src/devices/cpu/avr8/avr8dasm.h new file mode 100644 index 00000000000..a7f55fdb86b --- /dev/null +++ b/src/devices/cpu/avr8/avr8dasm.h @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + Atmel 8-bit AVR disassembler + + Written by Ryan Holtz +*/ + +#ifndef MAME_CPU_AVR8_AVR8DASM_H +#define MAME_CPU_AVR8_AVR8DASM_H + +#pragma once + +class avr8_disassembler : public util::disasm_interface +{ +public: + avr8_disassembler() = default; + virtual ~avr8_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/capricorn/capricorn.cpp b/src/devices/cpu/capricorn/capricorn.cpp index b25800a6541..b41a3892667 100644 --- a/src/devices/cpu/capricorn/capricorn.cpp +++ b/src/devices/cpu/capricorn/capricorn.cpp @@ -7,6 +7,7 @@ // #include "emu.h" #include "capricorn.h" +#include "capricorn_dasm.h" #include "debugger.h" // Register indexes @@ -169,7 +170,7 @@ void capricorn_cpu_device::device_start() state_add(STATE_GENFLAGS , "GENFLAGS" , m_flags).noshow().formatstr("%9s"); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_reg)); save_item(NAME(m_arp)); @@ -237,10 +238,9 @@ void capricorn_cpu_device::state_string_export(const device_state_entry &entry, } } -offs_t capricorn_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *capricorn_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(capricorn); - return CPU_DISASSEMBLE_NAME(capricorn)(this, stream, pc, oprom, opram, options); + return new capricorn_disassembler; } void capricorn_cpu_device::start_mem_burst(ea_addr_t addr) diff --git a/src/devices/cpu/capricorn/capricorn.h b/src/devices/cpu/capricorn/capricorn.h index 7cf11b7f0ae..e20d6875def 100644 --- a/src/devices/cpu/capricorn/capricorn.h +++ b/src/devices/cpu/capricorn/capricorn.h @@ -39,16 +39,12 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override - { return 1; } - virtual u32 disasm_max_opcode_bytes() const override - { return 9; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; diff --git a/src/devices/cpu/capricorn/capricorn_dasm.cpp b/src/devices/cpu/capricorn/capricorn_dasm.cpp index 5a45cb2c832..1b1794a954f 100644 --- a/src/devices/cpu/capricorn/capricorn_dasm.cpp +++ b/src/devices/cpu/capricorn/capricorn_dasm.cpp @@ -5,204 +5,197 @@ // ******************************************************************************** #include "emu.h" -#include "capricorn.h" +#include "capricorn_dasm.h" -typedef offs_t (*fn_dis_param)(std::ostream &stream , offs_t pc , const uint8_t *oprom); - -typedef struct { - uint8_t m_op_mask; - uint8_t m_opcode; - const char *m_mnemonic; - bool m_has_mb; - char m_addr_mode; - fn_dis_param m_param_fn; - uint32_t m_dasm_flags; -} dis_entry_t; - -static void direct_addr(std::ostream &stream , const uint8_t *oprom) +void capricorn_disassembler::direct_addr(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { - util::stream_format(stream , "$%02x%02x" , oprom[ 1 ] , oprom[ 0 ]); + util::stream_format(stream, "$%04x", opcodes.r16(pc)); } -static offs_t param_arp_drp(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_arp_drp(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { stream << "R"; - util::stream_format(stream , "%02o" , oprom[ 0 ] & 0x3f); + util::stream_format(stream, "%02o", opcodes.r8(pc) & 0x3f); return 0; } -static offs_t param_dr(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { stream << "DR"; return 0; } -static offs_t param_dr_ar(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_ar(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { stream << "DR,AR"; return 0; } -static offs_t param_dr_lit(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_lit(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { stream << "DR,="; // Here we assume that multi-byte instructions operate on 2 bytes because we // have no way of knowing how many they are (the actual number of bytes is // dynamically determined by the value of DRP register at run-time) - unsigned bytes = BIT(oprom[ 0 ] , 0) ? 2 : 1; + unsigned bytes = BIT(opcodes.r8(pc), 0) ? 2 : 1; for (unsigned i = 1; i <= bytes; i++) { - util::stream_format(stream , "$%02x " , oprom[ i ]); + util::stream_format(stream, "$%02x ", opcodes.r8(pc+i)); } return bytes; } -static offs_t param_dr_lit_dir(std::ostream &stream , offs_t pc ,const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_lit_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes) { stream << "DR,="; - direct_addr(stream , &oprom[ 1 ]); + direct_addr(stream, pc+1, opcodes); return 2; } -static offs_t param_dr_idx_dir(std::ostream &stream , offs_t pc ,const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_idx_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes) { stream << "DR,XAR,"; - direct_addr(stream , &oprom[ 1 ]); + direct_addr(stream, pc+1, opcodes); return 2; } -static offs_t param_xr_lit(std::ostream &stream , offs_t pc ,const uint8_t *oprom) +offs_t capricorn_disassembler::param_xr_lit(std::ostream &stream, offs_t pc,const data_buffer &opcodes) { stream << "XR,"; - direct_addr(stream , &oprom[ 1 ]); + direct_addr(stream, pc+1, opcodes); return 2; } -static offs_t param_lit_dir(std::ostream &stream , offs_t pc ,const uint8_t *oprom) +offs_t capricorn_disassembler::param_lit_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes) { stream << "="; - direct_addr(stream , &oprom[ 1 ]); + direct_addr(stream, pc+1, opcodes); return 2; } -static offs_t param_dr_id_ar(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_dr_id_ar(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { - stream << "DR," << (BIT(oprom[ 0 ] , 1) ? '-' : '+') << "AR"; + stream << "DR," << (BIT(opcodes.r8(pc), 1) ? '-' : '+') << "AR"; return 0; } -static offs_t param_jmp_off(std::ostream &stream , offs_t pc , const uint8_t *oprom) +offs_t capricorn_disassembler::param_jmp_off(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { - uint16_t off = oprom[ 1 ]; - if (BIT(off , 7)) { + uint16_t off = opcodes.r8(pc+1); + if (BIT(off, 7)) { off -= 0x100; } - util::stream_format(stream , "$%04x" , (pc + 2 + off) & 0xffff); + util::stream_format(stream, "$%04x", (pc + 2 + off) & 0xffff); return 1; } -static const dis_entry_t dis_table[] = { - { 0xff , 0x01 , "ARP R*" , false , '\0' , nullptr , 0 }, - { 0xc0 , 0x00 , "ARP" , false , '\0' , param_arp_drp , 0 }, - { 0xff , 0x41 , "DRP R*" , false , '\0' , nullptr , 0 }, - { 0xc0 , 0x40 , "DRP" , false , '\0' , param_arp_drp , 0 }, - { 0xfe , 0x80 , "EL" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x82 , "ER" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x84 , "LL" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x86 , "LR" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x88 , "IC" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x8a , "DC" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x8c , "TC" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x8e , "NC" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x90 , "TS" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x92 , "CL" , true , '\0' , param_dr , 0 }, - { 0xfe , 0x94 , "OR" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0x96 , "XR" , true , '\0' , param_dr_ar , 0 }, - { 0xff , 0x98 , "BIN" , false , '\0' , nullptr , 0 }, - { 0xff , 0x99 , "BCD" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9a , "SAD" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9b , "DCE" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9c , "ICE" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9d , "CLE" , false , '\0' , nullptr , 0 }, - { 0xff , 0x9e , "RTN" , false , '\0' , nullptr , DASMFLAG_STEP_OUT }, - { 0xff , 0x9f , "PAD" , false , '\0' , nullptr , 0 }, - { 0xfe , 0xa0 , "LD" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xa2 , "ST" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xa4 , "LD" , true , 'D' , param_dr_ar , 0 }, - { 0xfe , 0xa6 , "ST" , true , 'D' , param_dr_ar , 0 }, - { 0xfe , 0xa8 , "LD" , true , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xaa , "ST" , true , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xac , "LD" , true , 'I' , param_dr_ar , 0 }, - { 0xfe , 0xae , "ST" , true , 'I' , param_dr_ar , 0 }, - { 0xfe , 0xb0 , "LD" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xb2 , "ST" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xb4 , "LD" , true , 'D' , param_dr_idx_dir , 0 }, - { 0xfe , 0xb6 , "ST" , true , 'D' , param_dr_idx_dir , 0 }, - { 0xfe , 0xb8 , "LD" , true , 'I' , param_dr_lit_dir , 0 }, - { 0xfe , 0xba , "ST" , true , 'I' , param_dr_lit_dir , 0 }, - { 0xfe , 0xbc , "LD" , true , 'I' , param_dr_idx_dir , 0 }, - { 0xfe , 0xbe , "ST" , true , 'I' , param_dr_idx_dir , 0 }, - { 0xfe , 0xc0 , "CM" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xc2 , "AD" , true , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xc4 , "SB" , true , '\0' , param_dr_ar , 0 }, - { 0xff , 0xc6 , "JSB" , false , '\0' , param_xr_lit , DASMFLAG_STEP_OVER }, - { 0xff , 0xc7 , "ANM" , false , '\0' , param_dr_ar , 0 }, - { 0xfe , 0xc8 , "CM" , true , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xca , "AD" , true , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xcc , "SB" , true , '\0' , param_dr_lit , 0 }, - { 0xff , 0xce , "JSB" , false , '\0' , param_lit_dir , DASMFLAG_STEP_OVER }, - { 0xff , 0xcf , "ANM" , false , '\0' , param_dr_lit , 0 }, - { 0xfe , 0xd0 , "CM" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xd2 , "AD" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xd4 , "SB" , true , 'D' , param_dr_lit_dir , 0 }, - { 0xff , 0xd7 , "ANM" , false , 'D' , param_dr_lit_dir , 0 }, - { 0xfe , 0xd8 , "CM" , true , 'D' , param_dr_ar , 0 }, - { 0xfe , 0xda , "AD" , true , 'D' , param_dr_ar , 0 }, - { 0xfe , 0xdc , "SB" , true , 'D' , param_dr_ar , 0 }, - { 0xff , 0xdf , "ANM" , false , 'D' , param_dr_ar , 0 }, - { 0xfc , 0xe0 , "PO" , true , 'D' , param_dr_id_ar , 0 }, - { 0xfc , 0xe4 , "PU" , true , 'D' , param_dr_id_ar , 0 }, - { 0xfc , 0xe8 , "PO" , true , 'I' , param_dr_id_ar , 0 }, - { 0xfc , 0xec , "PU" , true , 'I' , param_dr_id_ar , 0 }, - { 0xff , 0xf0 , "JMP" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf1 , "JNO" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf2 , "JOD" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf3 , "JEV" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf4 , "JNG" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf5 , "JPS" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf6 , "JNZ" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf7 , "JZR" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf8 , "JEN" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xf9 , "JEZ" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfa , "JNC" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfb , "JCY" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfc , "JLZ" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfd , "JLN" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xfe , "JRZ" , false , '\0' , param_jmp_off , 0 }, - { 0xff , 0xff , "JRN" , false , '\0' , param_jmp_off , 0 }, +const capricorn_disassembler::dis_entry_t capricorn_disassembler::dis_table[] = { + { 0xff, 0x01, "ARP R*", false, '\0', nullptr, 0 }, + { 0xc0, 0x00, "ARP" , false, '\0', &capricorn_disassembler::param_arp_drp, 0 }, + { 0xff, 0x41, "DRP R*", false, '\0', nullptr, 0 }, + { 0xc0, 0x40, "DRP" , false, '\0', &capricorn_disassembler::param_arp_drp, 0 }, + { 0xfe, 0x80, "EL" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x82, "ER" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x84, "LL" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x86, "LR" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x88, "IC" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x8a, "DC" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x8c, "TC" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x8e, "NC" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x90, "TS" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x92, "CL" , true , '\0', &capricorn_disassembler::param_dr, 0 }, + { 0xfe, 0x94, "OR" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0x96, "XR" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xff, 0x98, "BIN" , false, '\0', nullptr, 0 }, + { 0xff, 0x99, "BCD" , false, '\0', nullptr, 0 }, + { 0xff, 0x9a, "SAD" , false, '\0', nullptr, 0 }, + { 0xff, 0x9b, "DCE" , false, '\0', nullptr, 0 }, + { 0xff, 0x9c, "ICE" , false, '\0', nullptr, 0 }, + { 0xff, 0x9d, "CLE" , false, '\0', nullptr, 0 }, + { 0xff, 0x9e, "RTN" , false, '\0', nullptr, STEP_OUT }, + { 0xff, 0x9f, "PAD" , false, '\0', nullptr, 0 }, + { 0xfe, 0xa0, "LD" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xa2, "ST" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xa4, "LD" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xa6, "ST" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xa8, "LD" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xaa, "ST" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xac, "LD" , true , 'I' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xae, "ST" , true , 'I' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xb0, "LD" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xb2, "ST" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xb4, "LD" , true , 'D' , &capricorn_disassembler::param_dr_idx_dir, 0 }, + { 0xfe, 0xb6, "ST" , true , 'D' , &capricorn_disassembler::param_dr_idx_dir, 0 }, + { 0xfe, 0xb8, "LD" , true , 'I' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xba, "ST" , true , 'I' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xbc, "LD" , true , 'I' , &capricorn_disassembler::param_dr_idx_dir, 0 }, + { 0xfe, 0xbe, "ST" , true , 'I' , &capricorn_disassembler::param_dr_idx_dir, 0 }, + { 0xfe, 0xc0, "CM" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xc2, "AD" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xc4, "SB" , true , '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xff, 0xc6, "JSB" , false, '\0', &capricorn_disassembler::param_xr_lit, STEP_OVER }, + { 0xff, 0xc7, "ANM" , false, '\0', &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xc8, "CM" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xca, "AD" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xcc, "SB" , true , '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xff, 0xce, "JSB" , false, '\0', &capricorn_disassembler::param_lit_dir, STEP_OVER }, + { 0xff, 0xcf, "ANM" , false, '\0', &capricorn_disassembler::param_dr_lit, 0 }, + { 0xfe, 0xd0, "CM" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xd2, "AD" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xd4, "SB" , true , 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xff, 0xd7, "ANM" , false, 'D' , &capricorn_disassembler::param_dr_lit_dir, 0 }, + { 0xfe, 0xd8, "CM" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xda, "AD" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfe, 0xdc, "SB" , true , 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xff, 0xdf, "ANM" , false, 'D' , &capricorn_disassembler::param_dr_ar, 0 }, + { 0xfc, 0xe0, "PO" , true , 'D' , &capricorn_disassembler::param_dr_id_ar, 0 }, + { 0xfc, 0xe4, "PU" , true , 'D' , &capricorn_disassembler::param_dr_id_ar, 0 }, + { 0xfc, 0xe8, "PO" , true , 'I' , &capricorn_disassembler::param_dr_id_ar, 0 }, + { 0xfc, 0xec, "PU" , true , 'I' , &capricorn_disassembler::param_dr_id_ar, 0 }, + { 0xff, 0xf0, "JMP" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf1, "JNO" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf2, "JOD" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf3, "JEV" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf4, "JNG" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf5, "JPS" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf6, "JNZ" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf7, "JZR" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf8, "JEN" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xf9, "JEZ" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfa, "JNC" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfb, "JCY" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfc, "JLZ" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfd, "JLN" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xfe, "JRZ" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, + { 0xff, 0xff, "JRN" , false, '\0', &capricorn_disassembler::param_jmp_off, 0 }, // *** END *** - {0 , 0 , nullptr , false , 0 , nullptr , 0 } + {0, 0, nullptr, false, 0, nullptr, 0 } }; -CPU_DISASSEMBLE(capricorn) +u32 capricorn_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t capricorn_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const dis_entry_t *p; - uint8_t opcode = oprom[ 0 ]; + uint8_t opcode = opcodes.r8(pc); for (p = dis_table; p->m_op_mask; p++) { if ((opcode & p->m_op_mask) == p->m_opcode) { - offs_t res = 1 | p->m_dasm_flags | DASMFLAG_SUPPORTED; + offs_t res = 1 | p->m_dasm_flags | SUPPORTED; stream << p->m_mnemonic; if (p->m_has_mb) { - stream << (BIT(opcode , 0) ? 'M' : 'B'); + stream << (BIT(opcode, 0) ? 'M' : 'B'); } if (p->m_addr_mode != '\0') { stream << p->m_addr_mode; } if (p->m_param_fn != nullptr) { stream << " "; - res += p->m_param_fn(stream , pc , oprom); + res += (this->*(p->m_param_fn))(stream, pc, opcodes); } return res; } @@ -210,5 +203,5 @@ CPU_DISASSEMBLE(capricorn) // Unknown opcode stream << "???"; - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } diff --git a/src/devices/cpu/capricorn/capricorn_dasm.h b/src/devices/cpu/capricorn/capricorn_dasm.h new file mode 100644 index 00000000000..af3525fd03b --- /dev/null +++ b/src/devices/cpu/capricorn/capricorn_dasm.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:F. Ulivi +// ******************************************************************************** +// * HP Capricorn processor disassembler +// ******************************************************************************** + +#ifndef MAME_CPU_CAPRICORN_CAPRICORN_DASM_H +#define MAME_CPU_CAPRICORN_CAPRICORN_DASM_H + +#pragma once + +class capricorn_disassembler : public util::disasm_interface +{ +public: + capricorn_disassembler() = default; + virtual ~capricorn_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + typedef offs_t (capricorn_disassembler::*fn_dis_param)(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + + struct dis_entry_t { + uint8_t m_op_mask; + uint8_t m_opcode; + const char *m_mnemonic; + bool m_has_mb; + char m_addr_mode; + fn_dis_param m_param_fn; + uint32_t m_dasm_flags; + }; + + static const dis_entry_t dis_table[]; + + void direct_addr(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_arp_drp(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_dr(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_dr_ar(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_dr_lit(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_dr_lit_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes); + offs_t param_dr_idx_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes); + offs_t param_xr_lit(std::ostream &stream, offs_t pc,const data_buffer &opcodes); + offs_t param_lit_dir(std::ostream &stream, offs_t pc,const data_buffer &opcodes); + offs_t param_dr_id_ar(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + offs_t param_jmp_off(std::ostream &stream, offs_t pc, const data_buffer &opcodes); + +}; + +#endif diff --git a/src/devices/cpu/ccpu/ccpu.cpp b/src/devices/cpu/ccpu/ccpu.cpp index cc13d8e9125..467b5eb2402 100644 --- a/src/devices/cpu/ccpu/ccpu.cpp +++ b/src/devices/cpu/ccpu/ccpu.cpp @@ -12,6 +12,7 @@ #include "emu.h" #include "ccpu.h" +#include "ccpudasm.h" #include "debugger.h" @@ -24,8 +25,8 @@ DEFINE_DEVICE_TYPE(CCPU, ccpu_cpu_device, "ccpu", "Cinematronics CPU") #define READOP(a) (m_direct->read_byte(a)) -#define RDMEM(a) (m_data->read_word((a) * 2) & 0xfff) -#define WRMEM(a,v) (m_data->write_word((a) * 2, (v))) +#define RDMEM(a) (m_data->read_word((a) & 0xfff)) +#define WRMEM(a,v) (m_data->write_word((a), (v))) #define READPORT(a) (m_io->read_byte(a)) #define WRITEPORT(a,v) (m_io->write_byte((a), (v))) @@ -106,7 +107,7 @@ void ccpu_cpu_device::device_start() assert(!m_vector_callback.isnull()); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); @@ -695,8 +696,7 @@ void ccpu_cpu_device::execute_run() } -offs_t ccpu_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ccpu_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( ccpu ); - return CPU_DISASSEMBLE_NAME(ccpu)(this, stream, pc, oprom, opram, options); + return new ccpu_disassembler; } diff --git a/src/devices/cpu/ccpu/ccpu.h b/src/devices/cpu/ccpu/ccpu.h index 3a74c21a1fe..4cad4d66965 100644 --- a/src/devices/cpu/ccpu/ccpu.h +++ b/src/devices/cpu/ccpu/ccpu.h @@ -78,9 +78,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_data_config; @@ -111,7 +109,7 @@ protected: int m_icount; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; address_space *m_io; diff --git a/src/devices/cpu/ccpu/ccpudasm.cpp b/src/devices/cpu/ccpu/ccpudasm.cpp index bb843374c2b..feb4ebcb58d 100644 --- a/src/devices/cpu/ccpu/ccpudasm.cpp +++ b/src/devices/cpu/ccpu/ccpudasm.cpp @@ -11,13 +11,17 @@ ***************************************************************************/ #include "emu.h" -#include "ccpu.h" +#include "ccpudasm.h" +u32 ccpu_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(ccpu) +offs_t ccpu_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned startpc = pc; - uint8_t opcode = oprom[pc++ - startpc]; + uint8_t opcode = opcodes.r8(pc++); uint8_t tempval; switch (opcode) @@ -40,7 +44,7 @@ CPU_DISASSEMBLE(ccpu) /* A8I */ case 0x20: - util::stream_format(stream, "A8I $%X", oprom[pc++ - startpc]); + util::stream_format(stream, "A8I $%X", opcodes.r8(pc++)); break; /* A4I */ @@ -53,7 +57,7 @@ CPU_DISASSEMBLE(ccpu) /* S8I */ case 0x30: - util::stream_format(stream, "S8I $%X", oprom[pc++ - startpc]); + util::stream_format(stream, "S8I $%X", opcodes.r8(pc++)); break; /* S4I */ @@ -69,7 +73,7 @@ CPU_DISASSEMBLE(ccpu) case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: - tempval = oprom[pc++ - startpc]; + tempval = opcodes.r8(pc++); util::stream_format(stream, "LPAI $%03X", (opcode & 0x0f) + (tempval & 0xf0) + ((tempval & 0x0f) << 8)); break; @@ -326,5 +330,5 @@ CPU_DISASSEMBLE(ccpu) break; } - return (pc - startpc) | DASMFLAG_SUPPORTED; + return (pc - startpc) | SUPPORTED; } diff --git a/src/devices/cpu/ccpu/ccpudasm.h b/src/devices/cpu/ccpu/ccpudasm.h new file mode 100644 index 00000000000..b9c4b83c6e6 --- /dev/null +++ b/src/devices/cpu/ccpu/ccpudasm.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + ccpudasm.c + Core implementation for the portable Cinematronics CPU disassembler. + + Written by Aaron Giles + Special thanks to Zonn Moore for his detailed documentation. + +***************************************************************************/ + +#ifndef MAME_CPU_CCPU_CCPUDASM_H +#define MAME_CPU_CCPU_CCPUDASM_H + +#pragma once + +class ccpu_disassembler : public util::disasm_interface +{ +public: + ccpu_disassembler() = default; + virtual ~ccpu_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/clipper/clipper.cpp b/src/devices/cpu/clipper/clipper.cpp index c2d057d8d35..d9812b4a987 100644 --- a/src/devices/cpu/clipper/clipper.cpp +++ b/src/devices/cpu/clipper/clipper.cpp @@ -4,15 +4,13 @@ /* * An implementation of the Fairchild/Intergraph CLIPPER CPU family. * - * Primary source: http://bitsavers.trailing-edge.com/pdf/fairchild/clipper/Clipper_Instruction_Set_Oct85.pdf + * Primary source: http://bitsavers.org/pdf/fairchild/clipper/Clipper_Instruction_Set_Oct85.pdf * * TODO: * - save/restore state - * - unimplemented instructions - * - C100, C300, C400 variants + * - unimplemented C400 instructions * - correct boot logic * - condition codes for multiply instructions - * - most cpu traps/faults * - instruction timing * - big endian support (not present in the wild) */ @@ -20,11 +18,12 @@ #include "emu.h" #include "debugger.h" #include "clipper.h" +#include "clipperd.h" #define LOG_GENERAL (1U << 0) -#define LOG_INTERRUPT (1U << 1) +#define LOG_EXCEPTION (1U << 1) -//#define VERBOSE (LOG_GENERAL | LOG_INTERRUPT) +//#define VERBOSE (LOG_GENERAL | LOG_EXCEPTION) #include "logmacro.h" @@ -57,25 +56,30 @@ DEFINE_DEVICE_TYPE(CLIPPER_C300, clipper_c300_device, "clipper_c300", "C300 CLIP DEFINE_DEVICE_TYPE(CLIPPER_C400, clipper_c400_device, "clipper_c400", "C400 CLIPPER") clipper_c100_device::clipper_c100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : clipper_device(mconfig, CLIPPER_C100, tag, owner, clock, 0) { } + : clipper_device(mconfig, CLIPPER_C100, tag, owner, clock, ENDIANNESS_LITTLE, 0) +{ +} clipper_c300_device::clipper_c300_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : clipper_device(mconfig, CLIPPER_C300, tag, owner, clock, 0) { } + : clipper_device(mconfig, CLIPPER_C300, tag, owner, clock, ENDIANNESS_LITTLE, 0) +{ +} clipper_c400_device::clipper_c400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : clipper_device(mconfig, CLIPPER_C400, tag, owner, clock, SSW_ID_C400R4) { } - -clipper_device::clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const u32 cpuid) - : cpu_device(mconfig, type, tag, owner, clock), - m_pc(0), - m_psw(0), - m_ssw(cpuid), - m_r(m_rs), - m_insn_config("insn", ENDIANNESS_LITTLE, 32, 32, 0), - m_data_config("data", ENDIANNESS_LITTLE, 32, 32, 0), - m_insn(nullptr), - m_data(nullptr), - m_icount(0) + : clipper_device(mconfig, CLIPPER_C400, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C400R4) +{ +} + +clipper_device::clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const endianness_t endianness, const u32 cpuid) + : cpu_device(mconfig, type, tag, owner, clock) + , m_insn_config("insn", endianness, 32, 32, 0) + , m_data_config("data", endianness, 32, 32, 0) + , m_insn(nullptr) + , m_data(nullptr) + , m_icount(0) + , m_psw(endianness == ENDIANNESS_BIG ? PSW_BIG : 0) + , m_ssw(cpuid) + , m_r(m_rs) { } @@ -119,58 +123,29 @@ void clipper_device::device_start() save_item(NAME(m_ru)); save_item(NAME(m_rs)); save_item(NAME(m_f)); + save_item(NAME(m_fp_pc)); + save_item(NAME(m_fp_dst)); save_item(NAME(m_nmi)); save_item(NAME(m_irq)); save_item(NAME(m_ivec)); - state_add(STATE_GENPC, "GENPC", m_pc).noshow(); - state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow(); + state_add(STATE_GENPC, "GENPC", m_ip).noshow(); + state_add(STATE_GENPCBASE, "CURPC", m_ip).noshow(); state_add(STATE_GENSP, "GENSP", m_r[15]).noshow(); state_add(STATE_GENFLAGS, "GENFLAGS", m_psw).mask(0xf).formatstr("%4s").noshow(); - state_add(CLIPPER_PC, "pc", m_pc); + state_add(CLIPPER_PC, "pc", m_ip); state_add(CLIPPER_PSW, "psw", m_psw); state_add(CLIPPER_SSW, "ssw", m_ssw); - state_add(CLIPPER_R0, "r0", m_r[0]); - state_add(CLIPPER_R1, "r1", m_r[1]); - state_add(CLIPPER_R2, "r2", m_r[2]); - state_add(CLIPPER_R3, "r3", m_r[3]); - state_add(CLIPPER_R4, "r4", m_r[4]); - state_add(CLIPPER_R5, "r5", m_r[5]); - state_add(CLIPPER_R6, "r6", m_r[6]); - state_add(CLIPPER_R7, "r7", m_r[7]); - state_add(CLIPPER_R8, "r8", m_r[8]); - state_add(CLIPPER_R9, "r9", m_r[9]); - state_add(CLIPPER_R10, "r10", m_r[10]); - state_add(CLIPPER_R11, "r11", m_r[11]); - state_add(CLIPPER_R12, "r12", m_r[12]); - state_add(CLIPPER_R13, "r13", m_r[13]); - state_add(CLIPPER_R14, "r14", m_r[14]); - state_add(CLIPPER_R15, "r15", m_r[15]); - - state_add(CLIPPER_F0, "f0", m_f[0]); - state_add(CLIPPER_F1, "f1", m_f[1]); - state_add(CLIPPER_F2, "f2", m_f[2]); - state_add(CLIPPER_F3, "f3", m_f[3]); - state_add(CLIPPER_F4, "f4", m_f[4]); - state_add(CLIPPER_F5, "f5", m_f[5]); - state_add(CLIPPER_F6, "f6", m_f[6]); - state_add(CLIPPER_F7, "f7", m_f[7]); - - // C400 has 8 additional floating point registers - if (type() == CLIPPER_C400) - { - state_add(CLIPPER_F8, "f8", m_f[8]); - state_add(CLIPPER_F9, "f9", m_f[9]); - state_add(CLIPPER_F10, "f10", m_f[10]); - state_add(CLIPPER_F11, "f11", m_f[11]); - state_add(CLIPPER_F12, "f12", m_f[12]); - state_add(CLIPPER_F13, "f13", m_f[13]); - state_add(CLIPPER_F14, "f14", m_f[14]); - state_add(CLIPPER_F15, "f15", m_f[15]); - } + // integer regsters + for (int i = 0; i < get_ireg_count(); i++) + state_add(CLIPPER_IREG + i, util::string_format("r%d", i).c_str(), m_r[i]); + + // floating point registers + for (int i = 0; i < get_freg_count(); i++) + state_add(CLIPPER_FREG + i, util::string_format("f%d", i).c_str(), m_f[i]); } void clipper_device::device_reset() @@ -180,20 +155,19 @@ void clipper_device::device_reset() * psw: T cleared, BIG set from hardware, others undefined * ssw: EI, TP, M, U, K, KU, UU, P cleared, ID set from hardware, others undefined */ - m_psw = 0; - set_ssw(0); - m_r = SSW(U) ? m_ru : m_rs; - - // we'll opt to clear the integer and floating point registers too - memset(m_r, 0, sizeof(s32)*16); - memset(m_f, 0, sizeof(m_f)); + // clear the psw and ssw + set_psw(0); + set_ssw(0); // FIXME: figure out how to branch to the boot code properly - m_pc = 0x7f100000; + m_pc = 0x6000; + m_ip = 0x7f100000; + m_irq = CLEAR_LINE; m_nmi = CLEAR_LINE; m_ivec = 0; + m_exception = 0; } void clipper_device::state_string_export(const device_state_entry &entry, std::string &str) const @@ -212,20 +186,18 @@ void clipper_device::state_string_export(const device_state_entry &entry, std::s void clipper_device::execute_run() { - u16 insn; - // check for non-maskable and prioritised interrupts if (m_nmi) { // acknowledge non-maskable interrupt standard_irq_callback(INPUT_LINE_NMI); - LOGMASKED(LOG_INTERRUPT, "non-maskable interrupt\n"); - m_pc = intrap(EXCEPTION_INTERRUPT_BASE, m_pc); + LOGMASKED(LOG_EXCEPTION, "non-maskable interrupt\n"); + m_ip = intrap(EXCEPTION_INTERRUPT_BASE, m_ip); } else if (SSW(EI) && m_irq) { - LOGMASKED(LOG_INTERRUPT, "received prioritised interrupt ivec 0x%02x\n", m_ivec); + LOGMASKED(LOG_EXCEPTION, "received prioritised interrupt ivec 0x%02x\n", m_ivec); // allow equal/higher priority interrupts if ((m_ivec & IVEC_LEVEL) <= SSW(IL)) @@ -233,23 +205,74 @@ void clipper_device::execute_run() // acknowledge interrupt standard_irq_callback(INPUT_LINE_IRQ0); - LOGMASKED(LOG_INTERRUPT, "transferring control to ivec 0x%02x\n", m_ivec); - m_pc = intrap(EXCEPTION_INTERRUPT_BASE + m_ivec * 8, m_pc); + LOGMASKED(LOG_EXCEPTION, "transferring control to ivec 0x%02x\n", m_ivec); + m_ip = intrap(EXCEPTION_INTERRUPT_BASE + m_ivec * 8, m_ip); } } - while (m_icount > 0) { + while (m_icount > 0) + { + debugger_instruction_hook(this, m_ip); + + // fetch and decode an instruction + if (decode_instruction()) + { + float_exception_flags = 0; - debugger_instruction_hook(this, m_pc); + // execute instruction + execute_instruction(); - // fetch instruction word - insn = m_insn->read_word(m_pc + 0); + // check floating point exceptions + if (float_exception_flags) + fp_exception(); + } - // decode instruction - decode_instruction(insn); + if (m_exception) + { + /* + * For traced instructions which are interrupted or cause traps, the TP + * flag is set by hardware when the interrupt or trap occurs to ensure + * that the trace trap will occur immediately after the interrupt or other + * trap has been serviced. + */ + // FIXME: don't know why/when the trace pending flag is needed + if (PSW(T)) + m_ssw |= SSW_TP; + + switch (m_exception) + { + // data memory trap group + case EXCEPTION_D_CORRECTED_MEMORY_ERROR: + case EXCEPTION_D_UNCORRECTABLE_MEMORY_ERROR: + case EXCEPTION_D_ALIGNMENT_FAULT: + case EXCEPTION_D_PAGE_FAULT: + case EXCEPTION_D_READ_PROTECT_FAULT: + case EXCEPTION_D_WRITE_PROTECT_FAULT: + + // instruction memory trap group + case EXCEPTION_I_CORRECTED_MEMORY_ERROR: + case EXCEPTION_I_UNCORRECTABLE_MEMORY_ERROR: + case EXCEPTION_I_ALIGNMENT_FAULT: + case EXCEPTION_I_PAGE_FAULT: + case EXCEPTION_I_EXECUTE_PROTECT_FAULT: + + // illegal operation trap group + case EXCEPTION_ILLEGAL_OPERATION: + case EXCEPTION_PRIVILEGED_INSTRUCTION: + // return address is faulting instruction + m_ip = intrap(m_exception, m_pc); + break; + + default: + // return address is following instruction + m_ip = intrap(m_exception, m_ip); + break; + } + } - // execute instruction, return next pc - m_pc = execute_instruction(); + // FIXME: trace trap logic not working properly yet + //else if (PSW(T)) + // m_ip = intrap(EXCEPTION_TRACE, m_ip); // FIXME: some instructions take longer (significantly) than one cycle // and also the timings are often slower for the C100 and C300 @@ -283,13 +306,29 @@ device_memory_interface::space_config_vector clipper_device::memory_space_config }; } +WRITE16_MEMBER(clipper_device::set_exception) +{ + LOGMASKED(LOG_EXCEPTION, "external exception 0x%04x triggered\n", data); + + // check if corrected memory errors are masked + if (!SSW(ECM) && (data == EXCEPTION_D_CORRECTED_MEMORY_ERROR || data == EXCEPTION_I_CORRECTED_MEMORY_ERROR)) + return; + + m_exception = data; +} + /* - * This function decodes instruction operands and computes effective addresses (for + * Fetch and decode an instruction and compute an effective address (for * instructions with addressing modes). The results are contained in the m_info * structure to simplify passing between here and execute_instruction(). */ -void clipper_device::decode_instruction (u16 insn) +bool clipper_device::decode_instruction() { + // fetch instruction word + u16 insn = m_insn->read_word(m_ip + 0); + if (m_exception) + return false; + // decode the primary parcel m_info.opcode = insn >> 8; m_info.subopcode = insn & 0xff; @@ -299,16 +338,20 @@ void clipper_device::decode_instruction (u16 insn) // initialise the other fields m_info.imm = 0; m_info.macro = 0; - m_info.size = 0; m_info.address = 0; + // default instruction size is 2 bytes + int size = 2; + if ((insn & 0xf800) == 0x3800) { // instruction has a 16 bit immediate operand // fetch 16 bit immediate and sign extend - m_info.imm = (s16)m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.imm = (s16)m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; } else if ((insn & 0xd300) == 0x8300) { @@ -316,14 +359,18 @@ void clipper_device::decode_instruction (u16 insn) if (insn & 0x0080) { // fetch 16 bit immediate and sign extend - m_info.imm = (s16)m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.imm = (s16)m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; } else { - // fetch 32 bit immediate and sign extend - m_info.imm = (s32)m_insn->read_dword_unaligned(m_pc + 2); - m_info.size = 6; + // fetch 32 bit immediate + m_info.imm = m_insn->read_dword_unaligned(m_ip + 2); + if (m_exception) + return false; + size = 6; } } else if ((insn & 0xc000) == 0x4000) @@ -337,87 +384,103 @@ void clipper_device::decode_instruction (u16 insn) switch (insn & 0x00f0) { case ADDR_MODE_PC32: - m_info.address = m_pc + (s32)m_insn->read_dword_unaligned(m_pc + 2); - m_info.size = 6; + m_info.address = m_ip + m_insn->read_dword_unaligned(m_ip + 2); + if (m_exception) + return false; + size = 6; break; case ADDR_MODE_ABS32: - m_info.address = m_insn->read_dword_unaligned(m_pc + 2); - m_info.size = 6; + m_info.address = m_insn->read_dword_unaligned(m_ip + 2); + if (m_exception) + return false; + size = 6; break; case ADDR_MODE_REL32: - m_info.r2 = m_insn->read_word(m_pc + 2) & 0xf; - m_info.address = m_r[insn & 0xf] + (s32)m_insn->read_dword_unaligned(m_pc + 4); - m_info.size = 8; + m_info.r2 = m_insn->read_word(m_ip + 2) & 0xf; + if (m_exception) + return false; + + m_info.address = m_r[insn & 0xf] + m_insn->read_dword_unaligned(m_ip + 4); + if (m_exception) + return false; + size = 8; break; case ADDR_MODE_PC16: - m_info.address = m_pc + (s16)m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.address = m_ip + (s16)m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; break; case ADDR_MODE_REL12: - temp = m_insn->read_word(m_pc + 2); + temp = m_insn->read_word(m_ip + 2); + if (m_exception) + return false; m_info.r2 = temp & 0xf; m_info.address = m_r[insn & 0xf] + ((s16)temp >> 4); - m_info.size = 4; + size = 4; break; case ADDR_MODE_ABS16: - m_info.address = (s16)m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.address = (s16)m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; break; case ADDR_MODE_PCX: - temp = m_insn->read_word(m_pc + 2); + temp = m_insn->read_word(m_ip + 2); + if (m_exception) + return false; m_info.r2 = temp & 0xf; - m_info.address = m_pc + m_r[(temp >> 4) & 0xf]; - m_info.size = 4; + m_info.address = m_ip + m_r[(temp >> 4) & 0xf]; + size = 4; break; case ADDR_MODE_RELX: - temp = m_insn->read_word(m_pc + 2); + temp = m_insn->read_word(m_ip + 2); + if (m_exception) + return false; m_info.r2 = temp & 0xf; m_info.address = m_r[insn & 0xf] + m_r[(temp >> 4) & 0xf]; - m_info.size = 4; + size = 4; break; default: - LOG("illegal addressing mode pc 0x%08x\n", m_pc); - machine().debug_break(); - break; + m_exception = EXCEPTION_ILLEGAL_OPERATION; + return false; } } else - { // relative addressing mode m_info.address = m_r[m_info.r1]; - m_info.size = 2; - } } else if ((insn & 0xfd00) == 0xb400) { // macro instructions - m_info.macro = m_insn->read_word(m_pc + 2); - m_info.size = 4; + m_info.macro = m_insn->read_word(m_ip + 2); + if (m_exception) + return false; + size = 4; } - else - // all other instruction formats are 16 bits - m_info.size = 2; + + // instruction fetch and decode complete + m_pc = m_ip; + m_ip = m_pc + size; + + return true; } -int clipper_device::execute_instruction () +void clipper_device::execute_instruction() { - // the address of the next instruction - u32 next_pc; - - // next instruction follows the current one by default, but - // may be changed for branch, call or trap instructions - next_pc = m_pc + m_info.size; + // memory fetch temporary + u64 temp; switch (m_info.opcode) { @@ -429,12 +492,9 @@ int clipper_device::execute_instruction () // treated as a noop if target ssw in user mode // R1 == 3 means "fast" mode - avoids pipeline flush if (R1 == 0) - m_psw = m_r[R2]; + set_psw(m_r[R2]); else if (!SSW(U) && (R1 == 1 || R1 == 3)) - { set_ssw(m_r[R2]); - m_r = SSW(U) ? m_ru : m_rs; - } // FLAGS: CVZN break; case 0x11: @@ -447,12 +507,16 @@ int clipper_device::execute_instruction () break; case 0x12: // calls: call supervisor - next_pc = intrap(EXCEPTION_SUPERVISOR_CALL_BASE + (m_info.subopcode & 0x7f) * 8, next_pc); + m_exception = EXCEPTION_SUPERVISOR_CALL_BASE + (m_info.subopcode & 0x7f) * 8; break; case 0x13: // ret: return from subroutine - next_pc = m_data->read_dword(m_r[R2]); - m_r[R2] += 4; + temp = m_data->read_dword(m_r[R2]); + if (!m_exception) + { + m_ip = temp; + m_r[R2] += 4; + } // TRAPS: C,U,A,P,R break; case 0x14: @@ -465,235 +529,244 @@ int clipper_device::execute_instruction () case 0x16: // popw: pop word m_r[R1] += 4; - m_r[R2] = m_data->read_dword(m_r[R1] - 4); + temp = m_data->read_dword(m_r[R1] - 4); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R break; case 0x20: // adds: add single floating - *((float *)&m_f[R2]) += *((float *)&m_f[R1]); + set_fp(R2, float32_add(get_fp32(R2), get_fp32(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x21: // subs: subtract single floating - *((float *)&m_f[R2]) -= *((float *)&m_f[R1]); + set_fp(R2, float32_sub(get_fp32(R2), get_fp32(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x22: // addd: add double floating - m_f[R2] += m_f[R1]; + set_fp(R2, float64_add(get_fp64(R2), get_fp64(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x23: // subd: subtract double floating - m_f[R2] -= m_f[R1]; + set_fp(R2, float64_sub(get_fp64(R2), get_fp64(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x24: // movs: move single floating - *((float *)&m_f[R2]) = *((float *)&m_f[R1]); + set_fp(R2, get_fp32(R1), F_NONE); break; case 0x25: // cmps: compare single floating - FLAGS(0, 0, *((float *)&m_f[R2]) == *((float *)&m_f[R1]), *((float *)&m_f[R2]) < *((float *)&m_f[R1])) + FLAGS(0, 0, float32_eq(get_fp32(R2), get_fp32(R1)), float32_lt(get_fp32(R2), get_fp32(R1))) + // flag unordered + if (float_exception_flags & float_flag_invalid) + m_psw |= PSW_Z | PSW_N; + float_exception_flags &= F_NONE; break; case 0x26: // movd: move double floating - m_f[R2] = m_f[R1]; + set_fp(R2, get_fp64(R1), F_NONE); break; case 0x27: // cmpd: compare double floating - FLAGS(0, 0, m_f[R2] == m_f[R1], m_f[R2] < m_f[R1]) - // FLAGS: 00ZN + FLAGS(0, 0, float64_eq(get_fp64(R2), get_fp64(R1)), float64_lt(get_fp64(R2), get_fp64(R1))) + // flag unordered + if (float_exception_flags & float_flag_invalid) + m_psw |= PSW_Z | PSW_N; + float_exception_flags &= F_NONE; break; case 0x28: // muls: multiply single floating - *((float *)&m_f[R2]) *= *((float *)&m_f[R1]); + set_fp(R2, float32_mul(get_fp32(R2), get_fp32(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x29: // divs: divide single floating - *((float *)&m_f[R2]) /= *((float *)&m_f[R1]); + set_fp(R2, float32_div(get_fp32(R2), get_fp32(R1)), F_IVDUX); // TRAPS: F_IVDUX break; case 0x2a: // muld: multiply double floating - m_f[R2] *= m_f[R1]; + set_fp(R2, float64_mul(get_fp64(R2), get_fp64(R1)), F_IVUX); // TRAPS: F_IVUX break; case 0x2b: // divd: divide double floating - m_f[R2] /= m_f[R1]; + set_fp(R2, float64_div(get_fp64(R2), get_fp64(R1)), F_IVDUX); // TRAPS: F_IVDUX break; case 0x2c: // movsw: move single floating to word - m_r[R2] = *((s32 *)&m_f[R1]); + m_r[R2] = get_fp32(R1); break; case 0x2d: // movws: move word to single floating - *((s32 *)&m_f[R2]) = m_r[R1]; + set_fp(R2, m_r[R1], F_NONE); break; case 0x2e: // movdl: move double floating to longword - ((double *)m_r)[R2 >> 1] = m_f[R1]; + ((u64 *)m_r)[R2 >> 1] = get_fp64(R1); break; case 0x2f: // movld: move longword to double floating - m_f[R2] = ((double *)m_r)[R1 >> 1]; + set_fp(R2, ((u64 *)m_r)[R1 >> 1], F_NONE); break; case 0x30: // shaw: shift arithmetic word - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) { // save the bits that will be shifted out plus new sign bit - s32 v = m_r[R2] >> (31 - m_r[R1]); + s32 v = (s32)m_r[R2] >> (31 - m_r[R1]); m_r[R2] <<= m_r[R1]; // overflow is set if sign changes during shift - FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, (s32)m_r[R2] < 0) } else { - m_r[R2] >>= -m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + ((s32 *)m_r)[R2] >>= -m_r[R1]; + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) } // FLAGS: 0VZN break; case 0x31: // shal: shift arithmetic longword - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) { // save the bits that will be shifted out plus new sign bit s64 v = ((s64 *)m_r)[R2 >> 1] >> (63 - m_r[R1]); - ((s64 *)m_r)[R2 >> 1] <<= m_r[R1]; + ((u64 *)m_r)[R2 >> 1] <<= m_r[R1]; // overflow is set if sign changes during shift - FLAGS(0, v != 0 && v != -1, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) + FLAGS(0, v != 0 && v != -1, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) } else { ((s64 *)m_r)[R2 >> 1] >>= -m_r[R1]; - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) } // FLAGS: 0VZN break; case 0x32: // shlw: shift logical word - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) m_r[R2] <<= m_r[R1]; else - ((u32 *)m_r)[R2] >>= -m_r[R1]; + m_r[R2] >>= -m_r[R1]; // FLAGS: 00ZN - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0); + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0); break; case 0x33: // shll: shift logical longword - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) ((u64 *)m_r)[R2 >> 1] <<= m_r[R1]; else ((u64 *)m_r)[R2 >> 1] >>= -m_r[R1]; // FLAGS: 00ZN - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); break; case 0x34: // rotw: rotate word - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) m_r[R2] = rotl32(m_r[R2], m_r[R1]); else m_r[R2] = rotr32(m_r[R2], -m_r[R1]); // FLAGS: 00ZN - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0); + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0); break; case 0x35: // rotl: rotate longword - if (m_r[R1] > 0) + if ((s32)m_r[R1] > 0) ((u64 *)m_r)[R2 >> 1] = rotl64(((u64 *)m_r)[R2 >> 1], m_r[R1]); else ((u64 *)m_r)[R2 >> 1] = rotr64(((u64 *)m_r)[R2 >> 1], -m_r[R1]); // FLAGS: 00ZN - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); break; case 0x38: // shai: shift arithmetic immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) { // save the bits that will be shifted out plus new sign bit - s32 v = m_r[R2] >> (31 - m_info.imm); + s32 v = (s32)m_r[R2] >> (31 - m_info.imm); m_r[R2] <<= m_info.imm; // overflow is set if sign changes during shift - FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, v != 0 && v != -1, m_r[R2] == 0, (s32)m_r[R2] < 0) } else { - m_r[R2] >>= -m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + ((s32 *)m_r)[R2] >>= -m_info.imm; + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) } // FLAGS: 0VZN // TRAPS: I break; case 0x39: // shali: shift arithmetic longword immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) { // save the bits that will be shifted out plus new sign bit s64 v = ((s64 *)m_r)[R2 >> 1] >> (63 - m_info.imm); - ((s64 *)m_r)[R2 >> 1] <<= m_info.imm; + ((u64 *)m_r)[R2 >> 1] <<= m_info.imm; // overflow is set if sign changes during shift - FLAGS(0, v != 0 && v != -1, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) + FLAGS(0, v != 0 && v != -1, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) } else { ((s64 *)m_r)[R2 >> 1] >>= -m_info.imm; - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0) } // FLAGS: 0VZN // TRAPS: I break; case 0x3a: // shli: shift logical immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) m_r[R2] <<= m_info.imm; else - ((u32 *)m_r)[R2] >>= -m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0); + m_r[R2] >>= -m_info.imm; + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0); // FLAGS: 00ZN // TRAPS: I break; case 0x3b: // shlli: shift logical longword immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) ((u64 *)m_r)[R2 >> 1] <<= m_info.imm; else ((u64 *)m_r)[R2 >> 1] >>= -m_info.imm; - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); // FLAGS: 00ZN // TRAPS: I break; case 0x3c: // roti: rotate immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) m_r[R2] = rotl32(m_r[R2], m_info.imm); else m_r[R2] = rotr32(m_r[R2], -m_info.imm); - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0); + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0); // FLAGS: 00ZN // TRAPS: I break; case 0x3d: // rotli: rotate longword immediate - if (m_info.imm > 0) + if ((s32)m_info.imm > 0) ((u64 *)m_r)[R2 >> 1] = rotl64(((u64 *)m_r)[R2 >> 1], m_info.imm); else ((u64 *)m_r)[R2 >> 1] = rotr64(((u64 *)m_r)[R2 >> 1], -m_info.imm); - FLAGS(0, 0, ((s64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); + FLAGS(0, 0, ((u64 *)m_r)[R2 >> 1] == 0, ((s64 *)m_r)[R2 >> 1] < 0); // FLAGS: 00ZN // TRAPS: I break; @@ -701,53 +774,53 @@ int clipper_device::execute_instruction () case 0x44: case 0x45: // call: call subroutine - m_r[R2] -= 4; - m_data->write_dword(m_r[R2], next_pc); - next_pc = m_info.address; + m_data->write_dword(m_r[R2] - 4, m_ip); + if (!m_exception) + { + m_ip = m_info.address; + m_r[R2] -= 4; + } // TRAPS: A,P,W break; -#ifdef UNIMPLEMENTED_C400 - case 0x46: - case 0x47: - // loadd2: - break; -#endif + case 0x48: case 0x49: // b*: branch on condition if (evaluate_branch()) - next_pc = m_info.address; + m_ip = m_info.address; // TRAPS: A,I break; -#ifdef UNIMPLEMENTED_C400 - case 0x4a: - case 0x4b: - // cdb: - break; - case 0x4c: - case 0x4d: - // cdbeq: - break; - case 0x4e: - case 0x4f: - // cdbne: - break; - case 0x50: - case 0x51: - // db*: - break; -#endif -#ifdef UNIMPLEMENTED + case 0x4c: case 0x4d: - // bf*: + // bf*: branch on floating exception + // FIXME: documentation is not clear, implementation is guesswork + switch (R2) + { + case BF_ANY: + // bfany: floating any exception + if (m_psw & (PSW_FI | PSW_FV | PSW_FD | PSW_FU | PSW_FX)) + m_ip = m_info.address; + break; + case BF_BAD: + // bfbad: floating bad result + if (m_psw & (PSW_FI | PSW_FD)) + m_ip = m_info.address; + break; + default: + // reserved + // FIXME: not sure if this should trigger an exception? + m_exception = EXCEPTION_ILLEGAL_OPERATION; + break; + } break; -#endif case 0x60: case 0x61: // loadw: load word - m_r[R2] = m_data->read_dword(m_info.address); + temp = m_data->read_dword(m_info.address); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x62: @@ -759,37 +832,49 @@ int clipper_device::execute_instruction () case 0x64: case 0x65: // loads: load single floating - ((u64 *)&m_f)[R2] = m_data->read_dword(m_info.address); + temp = m_data->read_dword(m_info.address); + if (!m_exception) + set_fp(R2, (float32)temp, F_NONE); // TRAPS: C,U,A,P,R,I break; case 0x66: case 0x67: // loadd: load double floating - ((u64 *)&m_f)[R2] = m_data->read_qword(m_info.address); + temp = m_data->read_qword(m_info.address); + if (!m_exception) + set_fp(R2, (float64)temp, F_NONE); // TRAPS: C,U,A,P,R,I break; case 0x68: case 0x69: // loadb: load byte - m_r[R2] = (s8)m_data->read_byte(m_info.address); + temp = s64(s8(m_data->read_byte(m_info.address))); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x6a: case 0x6b: // loadbu: load byte unsigned - m_r[R2] = m_data->read_byte(m_info.address); + temp = m_data->read_byte(m_info.address); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x6c: case 0x6d: // loadh: load halfword - m_r[R2] = (s16)m_data->read_word(m_info.address); + temp = s64(s16(m_data->read_word(m_info.address))); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x6e: case 0x6f: // loadhu: load halfword unsigned - m_r[R2] = m_data->read_word(m_info.address); + temp = m_data->read_word(m_info.address); + if (!m_exception) + m_r[R2] = temp; // TRAPS: C,U,A,P,R,I break; case 0x70: @@ -801,33 +886,38 @@ int clipper_device::execute_instruction () case 0x72: case 0x73: // tsts: test and set - m_r[R2] = m_data->read_dword(m_info.address); - m_data->write_dword(m_info.address, m_r[R2] | 0x80000000); + temp = m_data->read_dword(m_info.address); + if (!m_exception) + { + m_data->write_dword(m_info.address, temp | 0x80000000U); + if (!m_exception) + m_r[R2] = temp; + } // TRAPS: C,U,A,P,R,W,I break; case 0x74: case 0x75: // stors: store single floating - m_data->write_dword(m_info.address, *((u32 *)&m_f[R2])); + m_data->write_dword(m_info.address, get_fp32(R2)); // TRAPS: A,P,W,I break; case 0x76: case 0x77: // stord: store double floating - m_data->write_qword(m_info.address, *((u64 *)&m_f[R2])); + m_data->write_qword(m_info.address, get_fp64(R2)); // TRAPS: A,P,W,I break; case 0x78: case 0x79: // storb: store byte - m_data->write_byte(m_info.address, (u8)m_r[R2]); + m_data->write_byte(m_info.address, m_r[R2]); // TRAPS: A,P,W,I break; case 0x7c: case 0x7d: // storh: store halfword - m_data->write_word(m_info.address, (u16)m_r[R2]); + m_data->write_word(m_info.address, m_r[R2]); // TRAPS: A,P,W,I break; @@ -835,7 +925,7 @@ int clipper_device::execute_instruction () // addw: add word FLAGS_CV(C_ADD(m_r[R2], m_r[R1]), V_ADD(m_r[R2], m_r[R1])) m_r[R2] += m_r[R1]; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; @@ -843,21 +933,21 @@ int clipper_device::execute_instruction () // addq: add quick FLAGS_CV(C_ADD(m_r[R2], R1), V_ADD(m_r[R2], R1)) m_r[R2] += R1; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; case 0x83: // addi: add immediate FLAGS_CV(C_ADD(m_r[R2], m_info.imm), V_ADD(m_r[R2], m_info.imm)) m_r[R2] += m_info.imm; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN // TRAPS: I break; case 0x84: // movw: move word m_r[R2] = m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; @@ -870,35 +960,35 @@ int clipper_device::execute_instruction () case 0x87: // loadi: load immediate m_r[R2] = m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN // TRAPS: I break; case 0x88: // andw: and word m_r[R2] &= m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; case 0x8b: // andi: and immediate m_r[R2] &= m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN // TRAPS: I break; case 0x8c: // orw: or word m_r[R2] |= m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; case 0x8f: // ori: or immediate m_r[R2] |= m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN // TRAPS: I break; @@ -906,14 +996,14 @@ int clipper_device::execute_instruction () // addwc: add word with carry FLAGS_CV(C_ADD(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0))), V_ADD(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0)))) m_r[R2] += m_r[R1] + (PSW(C) ? 1 : 0); - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; case 0x91: // subwc: subtract word with carry FLAGS_CV(C_SUB(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0))), V_SUB(m_r[R2], (m_r[R1] + (PSW(C) ? 1 : 0)))) m_r[R2] -= m_r[R1] + (PSW(C) ? 1 : 0); - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; @@ -921,13 +1011,13 @@ int clipper_device::execute_instruction () // negw: negate word FLAGS_CV(m_r[R1] != 0, m_r[R1] == INT32_MIN) m_r[R2] = -m_r[R1]; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; case 0x98: // mulw: multiply word - m_r[R2] = m_r[R2] * m_r[R1]; + m_r[R2] = (s32)m_r[R2] * (s32)m_r[R1]; // FLAGS: 0V00 break; case 0x99: @@ -937,7 +1027,7 @@ int clipper_device::execute_instruction () break; case 0x9a: // mulwu: multiply word unsigned - m_r[R2] = (u32)m_r[R2] * (u32)m_r[R1]; + m_r[R2] = m_r[R2] * m_r[R1]; // FLAGS: 0V00 break; case 0x9b: @@ -949,51 +1039,55 @@ int clipper_device::execute_instruction () // divw: divide word if (m_r[R1] != 0) { + // FLAGS: 0V00 FLAGS(0, m_r[R2] == INT32_MIN && m_r[R1] == -1, 0, 0) - m_r[R2] = m_r[R2] / m_r[R1]; + m_r[R2] = (s32)m_r[R2] / (s32)m_r[R1]; } else - next_pc = intrap(EXCEPTION_INTEGER_DIVIDE_BY_ZERO, next_pc, CTS_DIVIDE_BY_ZERO); - // FLAGS: 0V00 - // TRAPS: D + // TRAPS: D + m_exception = EXCEPTION_INTEGER_DIVIDE_BY_ZERO; break; case 0x9d: // modw: modulus word if (m_r[R1] != 0) { + // FLAGS: 0V00 FLAGS(0, m_r[R2] == INT32_MIN && m_r[R1] == -1, 0, 0) - m_r[R2] = m_r[R2] % m_r[R1]; + m_r[R2] = (s32)m_r[R2] % (s32)m_r[R1]; } else - next_pc = intrap(EXCEPTION_INTEGER_DIVIDE_BY_ZERO, next_pc, CTS_DIVIDE_BY_ZERO); - // FLAGS: 0V00 - // TRAPS: D + // TRAPS: D + m_exception = EXCEPTION_INTEGER_DIVIDE_BY_ZERO; break; case 0x9e: // divwu: divide word unsigned - if ((u32)m_r[R1] != 0) - m_r[R2] = (u32)m_r[R2] / (u32)m_r[R1]; + if (m_r[R1] != 0) + { + m_r[R2] = m_r[R2] / m_r[R1]; + // FLAGS: 0000 + FLAGS(0, 0, 0, 0) + } else - next_pc = intrap(EXCEPTION_INTEGER_DIVIDE_BY_ZERO, next_pc, CTS_DIVIDE_BY_ZERO); - FLAGS(0, 0, 0, 0) - // FLAGS: 0000 - // TRAPS: D + // TRAPS: D + m_exception = EXCEPTION_INTEGER_DIVIDE_BY_ZERO; break; case 0x9f: // modwu: modulus word unsigned - if ((u32)m_r[R1] != 0) - m_r[R2] = (u32)m_r[R2] % (u32)m_r[R1]; + if (m_r[R1] != 0) + { + m_r[R2] = m_r[R2] % m_r[R1]; + // FLAGS: 0000 + FLAGS(0, 0, 0, 0) + } else - next_pc = intrap(EXCEPTION_INTEGER_DIVIDE_BY_ZERO, next_pc, CTS_DIVIDE_BY_ZERO); - FLAGS(0, 0, 0, 0) - // FLAGS: 0000 - // TRAPS: D + // TRAPS: D + m_exception = EXCEPTION_INTEGER_DIVIDE_BY_ZERO; break; case 0xa0: // subw: subtract word FLAGS_CV(C_SUB(m_r[R2], m_r[R1]), V_SUB(m_r[R2], m_r[R1])) m_r[R2] -= m_r[R1]; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; @@ -1001,52 +1095,52 @@ int clipper_device::execute_instruction () // subq: subtract quick FLAGS_CV(C_SUB(m_r[R2], R1), V_SUB(m_r[R2], R1)) m_r[R2] -= R1; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN break; case 0xa3: // subi: subtract immediate FLAGS_CV(C_SUB(m_r[R2], m_info.imm), V_SUB(m_r[R2], m_info.imm)) m_r[R2] -= m_info.imm; - FLAGS_ZN(m_r[R2] == 0, m_r[R2] < 0) + FLAGS_ZN(m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: CVZN // TRAPS: I break; case 0xa4: // cmpw: compare word - FLAGS(C_SUB(m_r[R2], m_r[R1]), V_SUB(m_r[R2], m_r[R1]), m_r[R2] == m_r[R1], m_r[R2] < m_r[R1]) + FLAGS(C_SUB(m_r[R2], m_r[R1]), V_SUB(m_r[R2], m_r[R1]), m_r[R2] == m_r[R1], (s32)m_r[R2] < (s32)m_r[R1]) // FLAGS: CVZN break; case 0xa6: // cmpq: compare quick - FLAGS(C_SUB(m_r[R2], R1), V_SUB(m_r[R2], R1), m_r[R2] == (s32)R1, m_r[R2] < (s32)R1) + FLAGS(C_SUB(m_r[R2], R1), V_SUB(m_r[R2], R1), m_r[R2] == R1, (s32)m_r[R2] < (s32)R1) // FLAGS: CVZN break; case 0xa7: // cmpi: compare immediate - FLAGS(C_SUB(m_r[R2], m_info.imm), V_SUB(m_r[R2], m_info.imm), m_r[R2] == m_info.imm, m_r[R2] < m_info.imm) + FLAGS(C_SUB(m_r[R2], m_info.imm), V_SUB(m_r[R2], m_info.imm), m_r[R2] == m_info.imm, (s32)m_r[R2] < (s32)m_info.imm) // FLAGS: CVZN // TRAPS: I break; case 0xa8: // xorw: exclusive or word m_r[R2] ^= m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; case 0xab: // xori: exclusive or immediate m_r[R2] ^= m_info.imm; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN // TRAPS: I break; case 0xac: // notw: not word m_r[R2] = ~m_r[R1]; - FLAGS(0, 0, m_r[R2] == 0, m_r[R2] < 0) + FLAGS(0, 0, m_r[R2] == 0, (s32)m_r[R2] < 0) // FLAGS: 00ZN break; @@ -1057,16 +1151,6 @@ int clipper_device::execute_instruction () // FLAGS: 0001 break; -#ifdef UNIMPLEMENTED_C400 - case 0xb0: - // abss: absolute value single floating? - break; - - case 0xb2: - // absd: absolute value double floating? - break; -#endif - case 0xb4: // unprivileged macro instructions switch (m_info.subopcode) @@ -1078,11 +1162,12 @@ int clipper_device::execute_instruction () // savew0..savew12: push registers rN:r14 // store ri at sp - 4 * (15 - i) - for (int i = R2; i < 15; i++) + for (int i = R2; i < 15 && !m_exception; i++) m_data->write_dword(m_r[15] - 4 * (15 - i), m_r[i]); // decrement sp after push to allow restart on exceptions - m_r[15] -= 4 * (15 - R2); + if (!m_exception) + m_r[15] -= 4 * (15 - R2); // TRAPS: A,P,W break; // NOTE: the movc, initc and cmpc macro instructions are implemented in a very basic way because @@ -1094,7 +1179,13 @@ int clipper_device::execute_instruction () while (m_r[0]) { - m_data->write_byte(m_r[2], m_data->read_byte(m_r[1])); + const u8 byte = m_data->read_byte(m_r[1]); + if (m_exception) + break; + + m_data->write_byte(m_r[2], byte); + if (m_exception) + break; m_r[0]--; m_r[1]++; @@ -1106,7 +1197,9 @@ int clipper_device::execute_instruction () // initc: initialise r0 bytes at r1 with value in r2 while (m_r[0]) { - m_data->write_byte(m_r[1], m_r[2] & 0xff); + m_data->write_byte(m_r[1], m_r[2]); + if (m_exception) + break; m_r[0]--; m_r[1]++; @@ -1123,8 +1216,12 @@ int clipper_device::execute_instruction () while (m_r[0]) { // set condition codes and abort the loop if the current byte does not match - s32 byte1 = (s8)m_data->read_byte(m_r[1]); - s32 byte2 = (s8)m_data->read_byte(m_r[2]); + s32 byte1 = s8(m_data->read_byte(m_r[1])); + if (m_exception) + break; + s32 byte2 = s8(m_data->read_byte(m_r[2])); + if (m_exception) + break; if (byte1 != byte2) { FLAGS(C_SUB(byte2, byte1), V_SUB(byte2, byte1), byte2 == byte1, byte2 < byte1) @@ -1145,10 +1242,16 @@ int clipper_device::execute_instruction () // load ri from sp + 4 * (i - N) for (int i = R2; i < 15; i++) - m_r[i] = m_data->read_dword(m_r[15] + 4 * (i - R2)); + { + temp = m_data->read_dword(m_r[15] + 4 * (i - R2)); + if (m_exception) + break; + m_r[i] = temp; + } // increment sp after pop to allow restart on exceptions - m_r[15] += 4 * (15 - R2); + if (!m_exception) + m_r[15] += 4 * (15 - R2); // TRAPS: C,U,A,P,R break; @@ -1157,11 +1260,12 @@ int clipper_device::execute_instruction () // saved0..saved7: push registers fN:f7 // store fi at sp - 8 * (8 - i) - for (int i = R2; i < 8; i++) - m_data->write_qword(m_r[15] - 8 * (8 - i), m_f[i]); + for (int i = R2; i < 8 && !m_exception; i++) + m_data->write_qword(m_r[15] - 8 * (8 - i), get_fp64(i)); // decrement sp after push to allow restart on exceptions - m_r[15] -= 8 * (8 - R2); + if (!m_exception) + m_r[15] -= 8 * (8 - R2); // TRAPS: A,P,W break; case 0x28: case 0x29: case 0x2a: case 0x2b: @@ -1170,71 +1274,145 @@ int clipper_device::execute_instruction () // load fi from sp + 8 * (i - N) for (int i = R2; i < 8; i++) - m_f[i] = m_data->read_qword(m_r[15] + 8 * (i - R2)); + { + temp = m_data->read_qword(m_r[15] + 8 * (i - R2)); + if (m_exception) + break; + set_fp(i, (float64)temp, F_NONE); + } // increment sp after pop to allow restart on exceptions - m_r[15] += 8 * (8 - R2); + if (!m_exception) + m_r[15] += 8 * (8 - R2); // TRAPS: C,U,A,P,R break; -#ifdef UNIMPLEMENTED case 0x30: - // cnvsw + // cnvsw: convert single floating to word + m_fp_pc = m_pc; + + m_r[m_info.macro & 0xf] = float32_to_int32(get_fp32((m_info.macro >> 4) & 0xf)); + // TRAPS: F_IX + float_exception_flags &= F_IX; + break; case 0x31: - // cnvrsw + // cnvrsw: convert rounding single floating to word (non-IEEE +0.5/-0.5 rounding) + m_fp_pc = m_pc; + + if (float32_lt(get_fp32((m_info.macro >> 4) & 0xf), 0)) + m_r[m_info.macro & 0xf] = float32_to_int32_round_to_zero(float32_sub(get_fp32((m_info.macro >> 4) & 0xf), + float32_div(int32_to_float32(1), int32_to_float32(2)))); + else + m_r[m_info.macro & 0xf] = float32_to_int32_round_to_zero(float32_add(get_fp32((m_info.macro >> 4) & 0xf), + float32_div(int32_to_float32(1), int32_to_float32(2)))); // TRAPS: F_IX + float_exception_flags &= F_IX; + break; case 0x32: - // cnvtsw + // cnvtsw: convert truncating single floating to word + m_fp_pc = m_pc; + + m_r[m_info.macro & 0xf] = float32_to_int32_round_to_zero(get_fp32((m_info.macro >> 4) & 0xf)); // TRAPS: F_IX + float_exception_flags &= F_IX; + break; case 0x33: - // cnvws + // cnvws: convert word to single floating + set_fp(m_info.macro & 0xf, int32_to_float32(m_r[(m_info.macro >> 4) & 0xf]), F_X); // TRAPS: F_X + break; case 0x34: - // cnvdw + // cnvdw: convert double floating to word + m_fp_pc = m_pc; + + m_r[m_info.macro & 0xf] = float64_to_int32(get_fp64((m_info.macro >> 4) & 0xf)); // TRAPS: F_IX + float_exception_flags &= F_IX; + break; case 0x35: - // cnvrdw + // cnvrdw: convert rounding double floating to word (non-IEEE +0.5/-0.5 rounding) + m_fp_pc = m_pc; + + if (float64_lt(get_fp64((m_info.macro >> 4) & 0xf), 0)) + m_r[m_info.macro & 0xf] = float64_to_int32_round_to_zero(float64_sub(get_fp64((m_info.macro >> 4) & 0xf), + float64_div(int32_to_float64(1), int32_to_float64(2)))); + else + m_r[m_info.macro & 0xf] = float64_to_int32_round_to_zero(float64_add(get_fp64((m_info.macro >> 4) & 0xf), + float64_div(int32_to_float64(1), int32_to_float64(2)))); // TRAPS: F_IX + float_exception_flags &= F_IX; break; -#endif - case 0x36: // cnvtdw - m_r[m_info.macro & 0xf] = (s32)m_f[(m_info.macro >> 4) & 0xf]; + case 0x36: + // cnvtdw: convert truncating double floating to word + m_fp_pc = m_pc; + + m_r[m_info.macro & 0xf] = float64_to_int32_round_to_zero(get_fp64((m_info.macro >> 4) & 0xf)); // TRAPS: F_IX + float_exception_flags &= F_IX; break; - case 0x37: // cnvwd - m_f[m_info.macro & 0xf] = (double)m_r[(m_info.macro >> 4) & 0xf]; + case 0x37: + // cnvwd: convert word to double floating + set_fp(m_info.macro & 0xf, int32_to_float64(m_r[(m_info.macro >> 4) & 0xf]), F_NONE); break; -#ifdef UNIMPLEMENTED case 0x38: - // cnvsd + // cnvsd: convert single to double floating + set_fp(m_info.macro & 0xf, float32_to_float64(get_fp32((m_info.macro >> 4) & 0xf)), F_I); // TRAPS: F_I + break; case 0x39: - // cnvds + // cnvds: convert double to single floating + set_fp(m_info.macro & 0xf, float64_to_float32(get_fp64((m_info.macro >> 4) & 0xf)), F_IVUX); // TRAPS: F_IVUX + break; case 0x3a: - // negs + // negs: negate single floating + set_fp(m_info.macro & 0xf, float32_mul(get_fp32((m_info.macro >> 4) & 0xf), int32_to_float32(-1)), F_NONE); + break; case 0x3b: - // negds + // negd: negate double floating + set_fp(m_info.macro & 0xf, float64_mul(get_fp64((m_info.macro >> 4) & 0xf), int32_to_float64(-1)), F_NONE); + break; case 0x3c: - // scalbs + /* + * This implementation for scalbd and scalbs is a bit opaque, but + * essentially we check if the integer value is within range, and + * directly create a floating constant representing 2^n or NaN + * respectively, which is used as an input to a multiply, producing + * the desired result. While doing an actual multiply is both + * inefficient and unnecessary, it's a tidy way to ensure the + * correct exception flags are set. + */ + // scalbs: scale by, single floating + set_fp(m_info.macro & 0xf, float32_mul(get_fp32(m_info.macro & 0xf), + (((s32)m_r[(m_info.macro >> 4) & 0xf] > -127 && (s32)m_r[(m_info.macro >> 4) & 0xf] < 128) + ? (float32)(((s32)m_r[(m_info.macro >> 4) & 0xf] + 127) << 23) + : (float32)~u32(0))), F_IVUX); // TRAPS: F_IVUX + break; case 0x3d: - // scalbd - // FLAGS: N + // scalbd: scale by, double floating + set_fp(m_info.macro & 0xf, float64_mul(get_fp64(m_info.macro & 0xf), + ((s32)m_r[(m_info.macro >> 4) & 0xf] > -1023 && (s32)m_r[(m_info.macro >> 4) & 0xf] < 1024) + ? (float64)((u64)((s32)m_r[(m_info.macro >> 4) & 0xf] + 1023) << 52) + : (float64)~u64(0)), F_IVUX); // TRAPS: F_IVUX + break; case 0x3e: - // trapfn + // trapfn: trap floating unordered // TRAPS: I + if (PSW(Z) && PSW(N)) + m_exception = EXCEPTION_ILLEGAL_OPERATION; + break; case 0x3f: - // loadfs + // loadfs: load floating status + m_r[(m_info.macro >> 4) & 0xf] = m_fp_pc; + m_f[m_info.macro & 0xf] = m_fp_dst; + m_ssw |= SSW_FRD; break; -#endif + default: - LOG("illegal unprivileged macro opcode at 0x%08x\n", m_pc); - next_pc = intrap(EXCEPTION_ILLEGAL_OPERATION, next_pc, CTS_ILLEGAL_OPERATION); - machine().debug_break(); + m_exception = EXCEPTION_ILLEGAL_OPERATION; break; } - break; case 0xb6: @@ -1246,158 +1424,184 @@ int clipper_device::execute_instruction () case 0x00: // movus: move user to supervisor m_rs[m_info.macro & 0xf] = m_ru[(m_info.macro >> 4) & 0xf]; - FLAGS(0, 0, m_rs[m_info.macro & 0xf] == 0, m_rs[m_info.macro & 0xf] < 0) + FLAGS(0, 0, m_rs[m_info.macro & 0xf] == 0, (s32)m_rs[m_info.macro & 0xf] < 0) // FLAGS: 00ZN // TRAPS: S break; case 0x01: // movsu: move supervisor to user m_ru[m_info.macro & 0xf] = m_rs[(m_info.macro >> 4) & 0xf]; - FLAGS(0, 0, m_ru[m_info.macro & 0xf] == 0, m_ru[m_info.macro & 0xf] < 0) + FLAGS(0, 0, m_ru[m_info.macro & 0xf] == 0, (s32)m_ru[m_info.macro & 0xf] < 0) // FLAGS: 00ZN // TRAPS: S break; case 0x02: // saveur: save user registers - for (int i = 0; i < 16; i++) + for (int i = 0; i < 16 && !m_exception; i++) m_data->write_dword(m_rs[(m_info.macro >> 4) & 0xf] - 4 * (i + 1), m_ru[15 - i]); - m_rs[(m_info.macro >> 4) & 0xf] -= 64; + if (!m_exception) + m_rs[(m_info.macro >> 4) & 0xf] -= 64; // TRAPS: A,P,W,S break; case 0x03: // restur: restore user registers for (int i = 0; i < 16; i++) - m_ru[i] = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4 * i); + { + temp = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4 * i); + if (m_exception) + break; + m_ru[i] = temp; + } - m_rs[(m_info.macro >> 4) & 0xf] += 64; + if (!m_exception) + m_rs[(m_info.macro >> 4) & 0xf] += 64; // TRAPS: C,U,A,P,R,S break; case 0x04: // reti: restore psw, ssw and pc from supervisor stack - LOGMASKED(LOG_INTERRUPT, "reti r%d ssp 0x%08x pc 0x%08x next_pc 0x%08x\n", - (m_info.macro >> 4) & 0xf, m_rs[(m_info.macro >> 4) & 0xf], m_pc, m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 8)); - - m_psw = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 0); - set_ssw(m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4)); - next_pc = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 8); - - m_rs[(m_info.macro >> 4) & 0xf] += 12; - - m_r = SSW(U) ? m_ru : m_rs; + m_ip = reti(); // TRAPS: S break; case 0x05: // wait: wait for interrupt - next_pc = m_pc; + m_ip = m_pc; // TRAPS: S break; -#ifdef UNIMPLEMENTED_C400 - case 0x07: - // loadts: unknown? - break; -#endif default: - // illegal operation - LOG("illegal privileged macro opcode at 0x%08x\n", m_pc); - next_pc = intrap(EXCEPTION_ILLEGAL_OPERATION, next_pc, CTS_ILLEGAL_OPERATION); - machine().debug_break(); + m_exception = EXCEPTION_ILLEGAL_OPERATION; break; } } else - next_pc = intrap(EXCEPTION_PRIVILEGED_INSTRUCTION, next_pc, CTS_PRIVILEGED_INSTRUCTION); - break; - -#ifdef UNIMPLEMENTED_C400 - case 0xbc: - // waitd: + m_exception = EXCEPTION_PRIVILEGED_INSTRUCTION; break; - case 0xc0: - // s*: - break; -#endif - default: - LOG("illegal opcode at 0x%08x\n", m_pc); - next_pc = intrap(EXCEPTION_ILLEGAL_OPERATION, next_pc, CTS_ILLEGAL_OPERATION); + m_exception = EXCEPTION_ILLEGAL_OPERATION; break; } +} - return next_pc; +u32 clipper_device::reti() +{ + // fetch the psw, ssw and pc from the supervisor stack + const u32 new_psw = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 0); + if (m_exception) + fatalerror("reti unrecoverable fault 0x%04x read psw address 0x%08x pc 0x%08x\n", m_exception, m_rs[(m_info.macro >> 4) & 0xf] + 0, m_pc); + + const u32 new_ssw = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4); + if (m_exception) + fatalerror("reti unrecoverable fault 0x%04x read ssw address 0x%08x pc 0x%08x\n", m_exception, m_rs[(m_info.macro >> 4) & 0xf] + 4, m_pc); + + const u32 new_pc = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 8); + if (m_exception) + fatalerror("reti unrecoverable fault 0x%04x read pc address 0x%08x pc 0x%08x\n", m_exception, m_rs[(m_info.macro >> 4) & 0xf] + 8, m_pc); + + LOGMASKED(LOG_EXCEPTION, "reti r%d ssp 0x%08x pc 0x%08x ssw 0x%08x psw 0x%08x new_pc 0x%08x new_ssw 0x%08x new_psw 0x%08x\n", + (m_info.macro >> 4) & 0xf, m_rs[(m_info.macro >> 4) & 0xf], m_pc, m_ssw, m_psw, new_pc, new_ssw, new_psw); + + // pop the stack + m_rs[(m_info.macro >> 4) & 0xf] += 12; + + // restore the psw and ssw + set_psw(new_psw); + set_ssw(new_ssw); + + // return the restored pc + return new_pc; } /* -* Common entry point for transferring control in the event of an interrupt or exception. -*/ -u32 clipper_device::intrap(u32 vector, u32 pc, u32 cts, u32 mts) + * Common entry point for transferring control in the event of an interrupt or + * exception. Reading between the lines, it appears this logic was implemented + * using the macro instruction ROM and a special macro instruction (intrap). + */ +u32 clipper_device::intrap(const u16 vector, const u32 old_pc) { - // fetch pc and ssw from interrupt vector - u32 next_pc = m_data->read_dword(vector + 0); - u32 next_ssw = m_data->read_dword(vector + 4); + const u32 old_ssw = m_ssw; + const u32 old_psw = m_psw; - LOGMASKED(LOG_INTERRUPT, "intrap vector 0x%08x pc 0x%08x next_pc 0x%08x ssp 0x%08x\n", vector, pc, next_pc, m_rs[15]); + // clear ssw bits to enable supervisor memory access + m_ssw &= ~(SSW_U | SSW_K | SSW_UU | SSW_KU); - // set cts and mts to indicate source of exception - m_psw = (m_psw & ~(PSW_CTS | PSW_MTS)) | mts | cts; + // clear exception state + m_exception = 0; - // push pc, ssw and psw onto supervisor stack - m_data->write_dword(m_rs[15] - 0x4, pc); - m_data->write_dword(m_rs[15] - 0x8, m_ssw); - m_data->write_dword(m_rs[15] - 0xc, m_psw); + // fetch next pc and ssw from interrupt vector + const u32 new_pc = m_data->read_dword(vector + get_evpc_offset()); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x read pc address 0x%08x pc 0x%08x\n", m_exception, vector + get_evpc_offset(), old_pc); - // decrement supervisor stack pointer - m_rs[15] -= 12; - - // load ssw from trap vector and set previous mode - set_ssw((next_ssw & ~(SSW(P))) | (SSW(U) << 1)); + const u32 new_ssw = m_data->read_dword(vector + get_evssw_offset()); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x read ssw address 0x%08x pc 0x%08x\n", m_exception, vector + get_evssw_offset(), old_pc); - // clear psw - m_psw = 0; + LOGMASKED(LOG_EXCEPTION, "intrap vector 0x%04x pc 0x%08x ssp 0x%08x new_pc 0x%08x new_ssw 0x%08x\n", vector, old_pc, m_rs[15], new_pc, new_ssw); - m_r = SSW(U) ? m_ru : m_rs; + // derive cts and mts from vector + u32 source = 0; + switch (vector) + { + // data memory trap group + case EXCEPTION_D_CORRECTED_MEMORY_ERROR: + case EXCEPTION_D_UNCORRECTABLE_MEMORY_ERROR: + case EXCEPTION_D_ALIGNMENT_FAULT: + case EXCEPTION_D_PAGE_FAULT: + case EXCEPTION_D_READ_PROTECT_FAULT: + case EXCEPTION_D_WRITE_PROTECT_FAULT: - // return new pc from trap vector - return next_pc; -} + // instruction memory trap group + case EXCEPTION_I_CORRECTED_MEMORY_ERROR: + case EXCEPTION_I_UNCORRECTABLE_MEMORY_ERROR: + case EXCEPTION_I_ALIGNMENT_FAULT: + case EXCEPTION_I_PAGE_FAULT: + case EXCEPTION_I_EXECUTE_PROTECT_FAULT: + source = (vector & MTS_VMASK) << (MTS_SHIFT - MTS_VSHIFT); + break; -u32 clipper_c400_device::intrap(u32 vector, u32 pc, u32 cts, u32 mts) -{ - // C400 reverses order of pc and ssw in interrupt vector - u32 next_pc = m_data->read_dword(vector + 4); - u32 next_ssw = m_data->read_dword(vector + 0); + // integer arithmetic trap group + case EXCEPTION_INTEGER_DIVIDE_BY_ZERO: + source = CTS_DIVIDE_BY_ZERO; + break; - LOGMASKED(LOG_INTERRUPT, "intrap vector 0x%08x pc 0x%08x next_pc 0x%08x ssp 0x%08x\n", vector, pc, next_pc, m_rs[15]); + // illegal operation trap group + case EXCEPTION_ILLEGAL_OPERATION: + source = CTS_ILLEGAL_OPERATION; + break; + case EXCEPTION_PRIVILEGED_INSTRUCTION: + source = CTS_PRIVILEGED_INSTRUCTION; + break; - // set cts and mts to indicate source of exception - m_psw = (m_psw & ~(PSW_CTS | PSW_MTS)) | mts | cts; + // diagnostic trap group + case EXCEPTION_TRACE: + source = CTS_TRACE_TRAP; + break; + } // push pc, ssw and psw onto supervisor stack - m_data->write_dword(m_rs[15] - 0x4, pc); - m_data->write_dword(m_rs[15] - 0x8, m_ssw); - m_data->write_dword(m_rs[15] - 0xc, m_psw); + m_data->write_dword(m_rs[15] - 0x4, old_pc); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x write pc address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x4, old_pc); + m_data->write_dword(m_rs[15] - 0x8, old_ssw); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x write ssw address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x8, old_pc); + m_data->write_dword(m_rs[15] - 0xc, (old_psw & ~(PSW_CTS | PSW_MTS)) | source); + if (m_exception) + fatalerror("intrap unrecoverable fault 0x%04x write psw address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0xc, old_pc); // decrement supervisor stack pointer + m_rs[15] -= get_eframe_size(); - // NOTE: while not explicitly stated anywhere, it seems the InterPro C400 boot code has been - // developed with the assumption that the SSP is decremented by 24 bytes during an exception, - // rather than the 12 bytes for the InterPro C300 version. This means the exception handler - // code must explicitly increment the SSP by 12 prior to executing the RETI instruction, - // as otherwise the SSP will not be pointing at a valid return frame. - m_rs[15] -= 24; - - // load ssw from trap vector and set previous mode - set_ssw((next_ssw & ~(SSW(P))) | (SSW(U) << 1)); + // set ssw from vector and previous mode + set_ssw((new_ssw & ~SSW_P) | (old_ssw & SSW_U) << 1); // clear psw - m_psw = 0; - - m_r = SSW(U) ? m_ru : m_rs; + set_psw(0); // return new pc from trap vector - return next_pc; + return new_pc; } bool clipper_device::evaluate_branch() const @@ -1460,7 +1664,140 @@ bool clipper_device::evaluate_branch() const return false; } -offs_t clipper_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +void clipper_device::set_psw(const u32 psw) +{ + // retain read-only endianness field + m_psw = (m_psw & PSW_BIG) | (psw & ~PSW_BIG); + + // set the softfloat rounding mode based on the psw rounding mode + switch (PSW(FR)) + { + case FR_0: float_rounding_mode = float_round_nearest_even; break; + case FR_1: float_rounding_mode = float_round_up; break; + case FR_2: float_rounding_mode = float_round_down; break; + case FR_3: float_rounding_mode = float_round_to_zero; break; + } +} + +void clipper_device::set_ssw(const u32 ssw) +{ + // retain read-only id field + m_ssw = (m_ssw & SSW_ID) | (ssw & ~SSW_ID); + + // select the register file + m_r = SSW(U) ? m_ru : m_rs; +} + +void clipper_device::fp_exception() +{ + u16 exception = 0; + + /* + * Set the psw floating exception flags, and identify any enabled + * exceptions. The order here is important, but since the documentation + * doesn't explicitly specify, this is a guess. Simply put, exceptions + * are considered in sequence with an increasing order of priority. + */ + if (float_exception_flags & float_flag_inexact) + { + m_psw |= PSW_FX; + if (PSW(EFX)) + exception = EXCEPTION_FLOATING_INEXACT; + } + if (float_exception_flags & float_flag_underflow) + { + m_psw |= PSW_FU; + if (PSW(EFU)) + exception = EXCEPTION_FLOATING_UNDERFLOW; + } + if (float_exception_flags & float_flag_overflow) + { + m_psw |= PSW_FV; + if (PSW(EFV)) + exception = EXCEPTION_FLOATING_OVERFLOW; + } + if (float_exception_flags & float_flag_divbyzero) + { + m_psw |= PSW_FD; + if (PSW(EFD)) + exception = EXCEPTION_FLOATING_DIVIDE_BY_ZERO; + } + if (float_exception_flags & float_flag_invalid) + { + m_psw |= PSW_FI; + if (PSW(EFI)) + exception = EXCEPTION_FLOATING_INVALID_OPERATION; + } + + // trigger a floating point exception + if (PSW(EFT) && exception) + m_exception = exception; +} + +void clipper_c400_device::execute_instruction() +{ + switch (m_info.opcode) + { +#ifdef UNIMPLEMENTED_C400 + case 0x46: + case 0x47: + // loadd2: + break; + + case 0x4a: + case 0x4b: + // cdb: + break; + case 0x4c: + case 0x4d: + // cdbeq: + break; + case 0x4e: + case 0x4f: + // cdbne: + break; + case 0x50: + case 0x51: + // db*: + break; + + case 0xb0: + // abss: absolute value single floating? + break; + + case 0xb2: + // absd: absolute value double floating? + break; + + case 0xb6: + // privileged macro instructions + if (!SSW(U)) + { + switch (m_info.subopcode) + { + case 0x07: + // loadts: unknown? + break; + } + } + break; + + case 0xbc: + // waitd: + break; + + case 0xc0: + // s*: + break; +#endif + + default: + clipper_device::execute_instruction(); + break; + } +} + +util::disasm_interface *clipper_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(clipper)(this, stream, pc, oprom, opram, options); + return new clipper_disassembler; } diff --git a/src/devices/cpu/clipper/clipper.h b/src/devices/cpu/clipper/clipper.h index 27624b4e05a..1781401fece 100644 --- a/src/devices/cpu/clipper/clipper.h +++ b/src/devices/cpu/clipper/clipper.h @@ -7,6 +7,8 @@ #pragma once #include <limits.h> +#include "softfloat/milieu.h" +#include "softfloat/softfloat.h" // convenience macros for dealing with the psw and ssw #define PSW(mask) (m_psw & PSW_##mask) @@ -17,55 +19,48 @@ class clipper_device : public cpu_device public: DECLARE_READ32_MEMBER(get_ssw) const { return m_ssw; } DECLARE_WRITE8_MEMBER(set_ivec) { m_ivec = data; } + DECLARE_WRITE16_MEMBER(set_exception); -protected: - enum registers + enum addressing_modes : u8 { - CLIPPER_R0, CLIPPER_R1, CLIPPER_R2, CLIPPER_R3, CLIPPER_R4, CLIPPER_R5, CLIPPER_R6, CLIPPER_R7, - CLIPPER_R8, CLIPPER_R9, CLIPPER_R10, CLIPPER_R11, CLIPPER_R12, CLIPPER_R13, CLIPPER_R14, CLIPPER_R15, - - CLIPPER_F0, CLIPPER_F1, CLIPPER_F2, CLIPPER_F3, CLIPPER_F4, CLIPPER_F5, CLIPPER_F6, CLIPPER_F7, - CLIPPER_F8, CLIPPER_F9, CLIPPER_F10, CLIPPER_F11, CLIPPER_F12, CLIPPER_F13, CLIPPER_F14, CLIPPER_F15, - - CLIPPER_PSW, - CLIPPER_SSW, - CLIPPER_PC, + ADDR_MODE_PC32 = 0x10, // pc relative with 32 bit displacement + ADDR_MODE_ABS32 = 0x30, // 32 bit absolute + ADDR_MODE_REL32 = 0x60, // relative with 32 bit displacement + ADDR_MODE_PC16 = 0x90, // pc relative with 16 bit displacement + ADDR_MODE_REL12 = 0xa0, // relative with 12 bit displacement + ADDR_MODE_ABS16 = 0xb0, // 16 bit absolute + ADDR_MODE_PCX = 0xd0, // pc indexed + ADDR_MODE_RELX = 0xe0 // relative indexed }; - enum addressing_modes + // branch conditions (first description for comparison, second for move/logical) + enum branch_conditions : u8 { - ADDR_MODE_PC32 = 0x10, - ADDR_MODE_ABS32 = 0x30, - ADDR_MODE_REL32 = 0x60, - ADDR_MODE_PC16 = 0x90, - ADDR_MODE_REL12 = 0xa0, - ADDR_MODE_ABS16 = 0xb0, - ADDR_MODE_PCX = 0xd0, - ADDR_MODE_RELX = 0xe0, + BRANCH_T = 0x0, // always + BRANCH_LT = 0x1, // less than greater than + BRANCH_LE = 0x2, // less or equal greater or equal + BRANCH_EQ = 0x3, // equal + BRANCH_GT = 0x4, // greater than less than + BRANCH_GE = 0x5, // greater or equal less or equal + BRANCH_NE = 0x6, // not equal + BRANCH_LTU = 0x7, // less than unsigned greater than unsigned + BRANCH_LEU = 0x8, // less or equal unsigned greater or equal unsigned + BRANCH_GTU = 0x9, // greater than unsigned less than unsigned + BRANCH_GEU = 0xa, // greater or equal unsigned less or equal unsigned + BRANCH_V = 0xb, // overflow + BRANCH_NV = 0xc, // not overflow + BRANCH_N = 0xd, // negative + BRANCH_NN = 0xe, // not negative + BRANCH_FN = 0xf // floating unordered }; - // branch conditions - enum branch_conditions + enum bf_conditions : u8 { - BRANCH_T = 0x0, - BRANCH_LT = 0x1, - BRANCH_LE = 0x2, - BRANCH_EQ = 0x3, - BRANCH_GT = 0x4, - BRANCH_GE = 0x5, - BRANCH_NE = 0x6, - BRANCH_LTU = 0x7, - BRANCH_LEU = 0x8, - BRANCH_GTU = 0x9, - BRANCH_GEU = 0xa, - BRANCH_V = 0xb, - BRANCH_NV = 0xc, - BRANCH_N = 0xd, - BRANCH_NN = 0xe, - BRANCH_FN = 0xf, + BF_ANY = 0x0, // floating any exception + BF_BAD = 0x1 // floating bad result }; - enum psw + enum psw : u32 { PSW_N = 0x00000001, // negative PSW_Z = 0x00000002, // zero @@ -88,29 +83,37 @@ protected: PSW_BIG = 0x00400000, // c400 - big endian (hardware) PSW_T = 0x00800000, // trace trap PSW_CTS = 0x0f000000, // cpu trap status (4 bits) - PSW_MTS = 0xf0000000, // memory trap status (4 bits) + PSW_MTS = 0xf0000000 // memory trap status (4 bits) }; - enum clipper_ssw + enum psw_fr : u32 + { + FR_0 = 0x00000000, // round to nearest + FR_1 = 0x00008000, // round toward + infinity + FR_2 = 0x00010000, // round toward - infinity + FR_3 = 0x00018000 // round toward zero + }; + + enum ssw : u32 { SSW_IN = 0x0000000f, // interrupt number (4 bits) SSW_IL = 0x000000f0, // interrupt level (4 bits) SSW_EI = 0x00000100, // enable interrupts SSW_ID = 0x0001fe00, // cpu rev # and type (8 bits) - // unused (5 bits) + // unused (5 bits) SSW_FRD = 0x00400000, // floating registers dirty SSW_TP = 0x00800000, // trace trap pending - SSW_ECM = 0x01000000, // enabled corrected memory error + SSW_ECM = 0x01000000, // enable corrected memory error SSW_DF = 0x02000000, // fpu disabled SSW_M = 0x04000000, // mapped mode SSW_KU = 0x08000000, // user protect key SSW_UU = 0x10000000, // user data mode SSW_K = 0x20000000, // protect key SSW_U = 0x40000000, // user mode - SSW_P = 0x80000000, // previous mode + SSW_P = 0x80000000 // previous mode }; - enum clipper_ssw_id + enum ssw_id : u32 { SSW_ID_C400R0 = 0x00000, SSW_ID_C400R1 = 0x04000, @@ -119,7 +122,7 @@ protected: SSW_ID_C400R4 = 0x10000 }; - enum exception_vectors + enum exception_vectors : u16 { // data memory trap group EXCEPTION_D_CORRECTED_MEMORY_ERROR = 0x108, @@ -157,37 +160,55 @@ protected: EXCEPTION_SUPERVISOR_CALL_BASE = 0x400, // prioritized interrupts (0x800-0xff8) - EXCEPTION_INTERRUPT_BASE = 0x800, + EXCEPTION_INTERRUPT_BASE = 0x800 }; // trap source values are shifted into the correct field in the psw - enum cpu_trap_sources + static const int CTS_SHIFT = 24; + enum cpu_trap_sources : u32 { - CTS_NO_CPU_TRAP = 0 << 24, - CTS_DIVIDE_BY_ZERO = 2 << 24, - CTS_ILLEGAL_OPERATION = 4 << 24, - CTS_PRIVILEGED_INSTRUCTION = 5 << 24, - CTS_TRACE_TRAP = 7 << 24, + CTS_NO_CPU_TRAP = 0 << CTS_SHIFT, + CTS_DIVIDE_BY_ZERO = 2 << CTS_SHIFT, + CTS_ILLEGAL_OPERATION = 4 << CTS_SHIFT, + CTS_PRIVILEGED_INSTRUCTION = 5 << CTS_SHIFT, + CTS_TRACE_TRAP = 7 << CTS_SHIFT }; - enum memory_trap_sources + static const int MTS_SHIFT = 28; + enum memory_trap_sources : u32 { - MTS_NO_MEMORY_TRAP = 0 << 28, - MTS_CORRECTED_MEMORY_ERROR = 1 << 28, - MTS_UNCORRECTABLE_MEMORY_ERROR = 2 << 28, - MTS_ALIGNMENT_FAULT = 4 << 28, - MTS_PAGE_FAULT = 5 << 28, - MTS_READ_OR_EXECUTE_PROTECT_FAULT = 6 << 28, - MTS_WRITE_PROTECT_FAULT = 7 << 28, + MTS_NO_MEMORY_TRAP = 0 << MTS_SHIFT, + MTS_CORRECTED_MEMORY_ERROR = 1 << MTS_SHIFT, + MTS_UNCORRECTABLE_MEMORY_ERROR = 2 << MTS_SHIFT, + MTS_ALIGNMENT_FAULT = 4 << MTS_SHIFT, + MTS_PAGE_FAULT = 5 << MTS_SHIFT, + MTS_READ_OR_EXECUTE_PROTECT_FAULT = 6 << MTS_SHIFT, + MTS_WRITE_PROTECT_FAULT = 7 << MTS_SHIFT }; - enum ivec_mask + // extract an mts code from a vector + static const u32 MTS_VMASK = 0x00000038; + static const int MTS_VSHIFT = 3; + + enum ivec_mask : u8 { IVEC_NUMBER = 0x0f, IVEC_LEVEL = 0xf0 }; - clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const u32 cpuid); + // combinations of floating point exceptions (from softfloat flags) + enum fp_exception_mask : u8 + { + F_NONE = (0), + F_I = (float_flag_invalid), + F_X = (float_flag_inexact), + F_IX = (float_flag_invalid | float_flag_inexact), + F_IVUX = (float_flag_invalid | float_flag_overflow | float_flag_underflow | float_flag_inexact), + F_IVDUX = (float_flag_invalid | float_flag_overflow | float_flag_divbyzero | float_flag_underflow | float_flag_inexact) + }; + +protected: + clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const endianness_t endianness, const u32 cpuid); // device-level overrides virtual void device_start() override; @@ -204,67 +225,147 @@ protected: virtual space_config_vector memory_space_config() const override; // device_state_interface overrides -#if 0 - virtual void state_import(const device_state_entry &entry) override; - virtual void state_export(const device_state_entry &entry) override; -#endif 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 2; } // smallest instruction - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } // largest instruction - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; - void set_ssw(u32 data) { m_ssw = (m_ssw & SSW(ID)) | (data & ~SSW(ID)); } + // cpu execution logic + bool decode_instruction(); + virtual void execute_instruction(); + bool evaluate_branch() const; + + // exception entry and return helpers + u32 intrap(const u16 vector, const u32 old_pc); + u32 reti(); - // core registers - u32 m_pc; - u32 m_psw; - u32 m_ssw; + // cpu state helpers + void set_psw(const u32 psw); + void set_ssw(const u32 ssw); + void fp_exception(); - // integer registers - s32 *m_r; // active registers - s32 m_ru[16]; // user registers - s32 m_rs[16]; // supervisor registers + // register count helpers + virtual int get_ireg_count() const { return 16; } + virtual int get_freg_count() const { return 8; } - // floating registers - double m_f[16]; + // exception vector and frame helpers + virtual int get_eframe_size() const { return 12; } + virtual int get_evpc_offset() const { return 0; } + virtual int get_evssw_offset() const { return 4; } + // floating point helpers + float32 get_fp32(const u8 reg) const { return m_f[reg & 0xf]; } + float64 get_fp64(const u8 reg) const { return m_f[reg & 0xf]; } + template <typename T> void set_fp(const u8 reg, const T data, const fp_exception_mask exception_mask) + { + // suppress unexpected exceptions + float_exception_flags &= exception_mask; + + // save floating exception state + m_fp_pc = m_pc; + m_fp_dst = m_f[reg & 0xf]; + + // assign data + if (float_exception_flags & float_flag_overflow && PSW(EFV)) + { + /* + * If the EFV flag is set, the computed result is delivered to the + * destination with the normalized rounded fraction of the true + * result (though the delivered exponent is usually wrong because + * of missing additional leading bits in the exponent field). For + * single-precision overflows, if the biased exponent of the true + * result is 255, then biased exponent 255 is delivered to the + * destination. If the true biased exponent of the result is + * 256..408, then the true biased exponent minus 256 is delivered + * to the destination. Note that this is not the exponent wrapped + * result called for by the IEEE 754 specification; the wrap must + * be adjusted by system software before delivery to a user's trap + * handler. This is done to allow the user to provide software that + * handles traps in an application-specific way. For double- + * precision, the overflow exponents (biased) lie in the range + * 2047..3120. These are mapped to 2047 and 0..1072 respectively. + * These must be adjusted by (3/4)x2^11 (1536) to obtain the IEEE + * Standard wrapped exponent. + */ + // FIXME: implement non-IEEE behaviour described above + m_f[reg & 0xf] = data; + } + else if (float_exception_flags & float_flag_underflow && PSW(EFU)) + { + /* + * If EFU is set, the floating underflow exception is signalled + * when the result of an operation (before rounding) has a biased + * exponent less than the minimum representable biased exponent for + * a normalized number. If the true biased exponent of the result + * is zero, then biased exponent zero is delivered to the + * destination. If the true biased exponent is less than zero, then + * the exponent delivered to the destination is true biased + * exponent plus 256 (2048 for double). The exponent must be + * adjusted by system software before delivery to the program's + * trap handler in order to conform to the IEEE 754 specification. + * The range of underflowed biased exponents for single-precision + * is 0..-275; for double-precision the range is 0..-1125. + */ + // FIXME: implement non-IEEE behaviour described above + m_f[reg & 0xf] = data; + } + else + m_f[reg & 0xf] = data; + + // set floating dirty flag + m_ssw |= SSW_FRD; + }; + + // emulation state address_space_config m_insn_config; address_space_config m_data_config; address_space *m_insn; address_space *m_data; -private: - int m_icount; - - int m_irq; - int m_nmi; - u8 m_ivec; - - // decoded instruction information - struct + enum registers { - u8 opcode, subopcode; - u8 r1, r2; + CLIPPER_IREG = 0, + CLIPPER_FREG = 16, + CLIPPER_PSW = 32, + CLIPPER_SSW = 33, + CLIPPER_PC = 34, + }; - s32 imm; - u16 macro; + int m_icount; // instruction cycle count - // total size of instruction in bytes - u32 size; + // program-visible cpu state + u32 m_pc; // current instruction address + u32 m_psw; // program status word + u32 m_ssw; // system status word - // computed effective address - u32 address; - } m_info; + u32 *m_r; // active registers + u32 m_ru[16]; // user registers + u32 m_rs[16]; // supervisor registers - void decode_instruction(u16 insn); - int execute_instruction(); - bool evaluate_branch() const; + u64 m_f[16]; // floating point registers + u32 m_fp_pc; // address of floating point instruction causing exception + u64 m_fp_dst; // original value of destination register during fp exception -protected: - virtual uint32_t intrap(u32 vector, u32 pc, u32 cts = CTS_NO_CPU_TRAP, u32 mts = MTS_NO_MEMORY_TRAP); + // non-visible cpu state + u32 m_ip; // next instruction address + int m_irq; // interrupt request state + int m_nmi; // non-maskable interrupt state + u8 m_ivec; // interrupt vector + u16 m_exception; // pending exception + + // decoded instruction information + struct decode + { + u8 opcode; // primary instruction opcode + u8 subopcode; // secondary instruction opcode + u8 r1; // r1 instruction operand + u8 r2; // r2 instruction operand + u32 imm; // immediate value operand + u16 macro; // macro instruction operands + u32 address; // computed effective address + } + m_info; }; class clipper_c100_device : public clipper_device @@ -285,13 +386,23 @@ public: clipper_c400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: - virtual uint32_t intrap(u32 vector, u32 pc, u32 cts = CTS_NO_CPU_TRAP, u32 mts = MTS_NO_MEMORY_TRAP) override; + // C400 has additional 8 floating point registers + virtual int get_freg_count() const override { return 16; } + + // C400 creates a 24 byte exception frame (C100/C300 is 12 bytes), but the + // service routine must increment sp by 12 prior to executing reti + // exception frame size + virtual int get_eframe_size() const override { return 24; } + + // C400 pc and ssw are reversed in exception vector compared to C100/C300 + virtual int get_evpc_offset() const override { return 4; } + virtual int get_evssw_offset() const override { return 0; } + + virtual void execute_instruction() override; }; DECLARE_DEVICE_TYPE(CLIPPER_C100, clipper_c100_device) DECLARE_DEVICE_TYPE(CLIPPER_C300, clipper_c300_device) DECLARE_DEVICE_TYPE(CLIPPER_C400, clipper_c400_device) -extern CPU_DISASSEMBLE(clipper); - #endif // MAME_CPU_CLIPPER_CLIPPER_H diff --git a/src/devices/cpu/clipper/clipperd.cpp b/src/devices/cpu/clipper/clipperd.cpp index 521f13d1c8d..d328d3b4631 100644 --- a/src/devices/cpu/clipper/clipperd.cpp +++ b/src/devices/cpu/clipper/clipperd.cpp @@ -2,6 +2,7 @@ // copyright-holders:Patrick Mackinlay #include "emu.h" +#include "clipperd.h" /* * TODO @@ -14,33 +15,20 @@ // enable C400 instruction decoding #define C400_INSTRUCTIONS 1 -// the CLIPPER addressing modes (unshifted) -enum -{ - ADDR_MODE_PC32 = 0x10, - ADDR_MODE_ABS32 = 0x30, - ADDR_MODE_REL32 = 0x60, - ADDR_MODE_PC16 = 0x90, - ADDR_MODE_REL12 = 0xa0, - ADDR_MODE_ABS16 = 0xb0, - ADDR_MODE_PCX = 0xd0, - ADDR_MODE_RELX = 0xe0 -}; - // macros for decoding various operand fields -#define R1 ((insn[0] & 0x00f0) >> 4) -#define R2 (insn[0] & 0x000f) +#define R1 ((opcodes.r16(pc) & 0x00f0) >> 4) +#define R2 (opcodes.r16(pc) & 0x000f) -#define I16 ((int16_t)insn[1]) -#define I32 (*(int32_t *)&insn[1]) -#define IMM_VALUE (insn[0] & 0x0080 ? I16 : I32) -#define IMM_SIZE (insn[0] & 0x0080 ? 2 : 4) +#define I16 (int16_t(opcodes.r16(pc+2))) +#define I32 (int32_t(opcodes.r32(pc+2))) +#define IMM_VALUE (opcodes.r16(pc) & 0x0080 ? I16 : I32) +#define IMM_SIZE (opcodes.r16(pc) & 0x0080 ? 2 : 4) -#define ADDR_MODE (insn[0] & 0x00f0) -#define ADDR_R2 ((insn[0] & 0x0050) == 0x0010 ? (insn[0] & 0x000f) : (insn[1] & 0x000f)) +#define ADDR_MODE (opcodes.r16(pc) & 0x00f0) +#define ADDR_R2 ((opcodes.r16(pc) & 0x0050) == 0x0010 ? (opcodes.r16(pc) & 0x000f) : (opcodes.r16(pc+2) & 0x000f)) #define ADDR_SIZE (ADDR_MODE > ADDR_MODE_REL32 ? 2 : ADDR_MODE == ADDR_MODE_REL32 ? 6 : 4) -#define ADDR_RX ((insn[1] & 0xf0) >> 4) -#define ADDR_I12 (((int16_t)insn[1]) >> 4) +#define ADDR_RX ((opcodes.r16(pc+2) & 0xf0) >> 4) +#define ADDR_I12 (((int16_t)opcodes.r16(pc+2)) >> 4) /* * Branch condition code mnemonics - the forms beginning with 'c' are @@ -49,7 +37,7 @@ enum * instructions. We use the first form because we can't know which type * should be used without some kind of dynamic information. */ -static const char *const cc[] = +const char *const clipper_disassembler::cc[] = { "", "clt", // rgt @@ -72,13 +60,13 @@ static const char *const cc[] = /* * Decode an addressing mode into a string. */ -std::string address (offs_t pc, u16 *insn) +std::string clipper_disassembler::address (offs_t pc, const data_buffer &opcodes) { switch (ADDR_MODE) { case ADDR_MODE_PC32: return util::string_format("0x%x", pc + I32); case ADDR_MODE_ABS32: return util::string_format("0x%x", I32); - case ADDR_MODE_REL32: return util::string_format("%d(r%d)", *(int32_t *)&insn[2], R2); + case ADDR_MODE_REL32: return util::string_format("%d(r%d)", opcodes.r32(pc+4), R2); case ADDR_MODE_PC16: return util::string_format("0x%x", pc + I16); case ADDR_MODE_REL12: return util::string_format("%d(r%d)", ADDR_I12, R2); case ADDR_MODE_ABS16: return util::string_format("0x%x", I16); @@ -96,26 +84,30 @@ std::string address (offs_t pc, u16 *insn) * an on-CPU macro instruction ROM. It appears at least some of these macro instructions were removed * from the C400 and generate traps which can be used to implement them in software instead. */ -CPU_DISASSEMBLE(clipper) +u32 clipper_disassembler::opcode_alignment() const +{ + return 2; +} + +offs_t clipper_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u16 *insn = (u16 *)oprom; - u32 flags = DASMFLAG_SUPPORTED; + u32 flags = SUPPORTED; offs_t bytes; - switch (insn[0] >> 8) + switch (opcodes.r16(pc) >> 8) { case 0x00: - if (oprom[0] == 0) + if (opcodes.r16(pc) == 0) util::stream_format(stream, "noop"); else - util::stream_format(stream, "noop $%d", oprom[0]); + util::stream_format(stream, "noop $%d", opcodes.r16(pc)); bytes = 2; break; case 0x10: util::stream_format(stream, "movwp r%d,%s", R2, R1 == 0 ? "psw" : R1 == 1 ? "ssw" : "sswf"); bytes = 2; break; case 0x11: util::stream_format(stream, "movpw %s,r%d", R1 == 0 ? "psw" : "ssw", R2); bytes = 2; break; - case 0x12: util::stream_format(stream, "calls $%d", insn[0] & 0x7F); bytes = 2; flags |= DASMFLAG_STEP_OVER; break; - case 0x13: util::stream_format(stream, "ret r%d", R2); bytes = 2; flags |= DASMFLAG_STEP_OUT; break; + case 0x12: util::stream_format(stream, "calls $%d", opcodes.r16(pc) & 0x7F); bytes = 2; flags |= STEP_OVER; break; + case 0x13: util::stream_format(stream, "ret r%d", R2); bytes = 2; flags |= STEP_OUT; break; case 0x14: util::stream_format(stream, "pushw r%d,r%d", R2, R1); bytes = 2; break; case 0x16: util::stream_format(stream, "popw r%d,r%d", R1, R2); bytes = 2; break; @@ -151,60 +143,60 @@ CPU_DISASSEMBLE(clipper) case 0x3c: util::stream_format(stream, "roti $%d,r%d", I16, R2); bytes = 4; break; case 0x3d: util::stream_format(stream, "rotli $%d,r%d:r%d", I16, R2 + 0, R2 + 1); bytes = 4; break; - case 0x44: util::stream_format(stream, "call r%d,(r%d)", R2, R1); bytes = 2; flags |= DASMFLAG_STEP_OVER; break; - case 0x45: util::stream_format(stream, "call r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; flags |= DASMFLAG_STEP_OVER; break; + case 0x44: util::stream_format(stream, "call r%d,(r%d)", R2, R1); bytes = 2; flags |= STEP_OVER; break; + case 0x45: util::stream_format(stream, "call r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; flags |= STEP_OVER; break; #if C400_INSTRUCTIONS case 0x46: util::stream_format(stream, "loadd2 (r%d),f%d", R1, R2); bytes = 2; break; - case 0x47: util::stream_format(stream, "loadd2 %s,f%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x47: util::stream_format(stream, "loadd2 %s,f%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; #endif case 0x48: util::stream_format(stream, "b%-4s (r%d)", cc[R2], R1); bytes = 2; break; - case 0x49: util::stream_format(stream, "b%-4s %s", cc[ADDR_R2], address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x49: util::stream_format(stream, "b%-4s %s", cc[ADDR_R2], address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; #if C400_INSTRUCTIONS // delayed branches case 0x4a: util::stream_format(stream, "cdb r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x4b: util::stream_format(stream, "cdb r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x4b: util::stream_format(stream, "cdb r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x4c: util::stream_format(stream, "cdbeq r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x4d: util::stream_format(stream, "cdbeq r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x4d: util::stream_format(stream, "cdbeq r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x4e: util::stream_format(stream, "cdbne r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x4f: util::stream_format(stream, "cdbne r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x4f: util::stream_format(stream, "cdbne r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x50: util::stream_format(stream, "db%-4s (r%d)", cc[R2], R1); bytes = 2; break; - case 0x51: util::stream_format(stream, "db%-4s %s", cc[ADDR_R2], address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x51: util::stream_format(stream, "db%-4s %s", cc[ADDR_R2], address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; #else // these instructions are in the C300 documentation, but appear to be replaced in the C400 case 0x4c: util::stream_format(stream, "bf%s (r%d)", R2 == 0 ? "any" : "bad", R1); bytes = 2; break; - case 0x4d: util::stream_format(stream, "bf%s %s", ADDR_R2 == 0 ? "any" : "bad", address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x4d: util::stream_format(stream, "bf%s %s", ADDR_R2 == 0 ? "any" : "bad", address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; #endif case 0x60: util::stream_format(stream, "loadw (r%d),r%d", R1, R2); bytes = 2; break; - case 0x61: util::stream_format(stream, "loadw %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x61: util::stream_format(stream, "loadw %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x62: util::stream_format(stream, "loada (r%d),r%d", R1, R2); bytes = 2; break; - case 0x63: util::stream_format(stream, "loada %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x63: util::stream_format(stream, "loada %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x64: util::stream_format(stream, "loads (r%d),f%d", R1, R2); bytes = 2; break; - case 0x65: util::stream_format(stream, "loads %s,f%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x65: util::stream_format(stream, "loads %s,f%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x66: util::stream_format(stream, "loadd (r%d),f%d", R1, R2); bytes = 2; break; - case 0x67: util::stream_format(stream, "loadd %s,f%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x67: util::stream_format(stream, "loadd %s,f%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x68: util::stream_format(stream, "loadb (r%d),r%d", R1, R2); bytes = 2; break; - case 0x69: util::stream_format(stream, "loadb %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x69: util::stream_format(stream, "loadb %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x6a: util::stream_format(stream, "loadbu (r%d),r%d", R1, R2); bytes = 2; break; - case 0x6b: util::stream_format(stream, "loadbu %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x6b: util::stream_format(stream, "loadbu %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x6c: util::stream_format(stream, "loadh (r%d),r%d", R1, R2); bytes = 2; break; - case 0x6d: util::stream_format(stream, "loadh %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x6d: util::stream_format(stream, "loadh %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x6e: util::stream_format(stream, "loadhu (r%d),r%d", R1, R2); bytes = 2; break; - case 0x6f: util::stream_format(stream, "loadhu %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x6f: util::stream_format(stream, "loadhu %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x70: util::stream_format(stream, "storw r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x71: util::stream_format(stream, "storw r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x71: util::stream_format(stream, "storw r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x72: util::stream_format(stream, "tsts (r%d),r%d", R1, R2); bytes = 2; break; - case 0x73: util::stream_format(stream, "tsts %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break; + case 0x73: util::stream_format(stream, "tsts %s,r%d", address(pc, opcodes), ADDR_R2); bytes = 2 + ADDR_SIZE; break; case 0x74: util::stream_format(stream, "stors f%d,(r%d)", R2, R1); bytes = 2; break; - case 0x75: util::stream_format(stream, "stors f%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x75: util::stream_format(stream, "stors f%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x76: util::stream_format(stream, "stord f%d,(r%d)", R2, R1); bytes = 2; break; - case 0x77: util::stream_format(stream, "stord f%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x77: util::stream_format(stream, "stord f%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x78: util::stream_format(stream, "storb r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x79: util::stream_format(stream, "storb r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x79: util::stream_format(stream, "storb r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x7c: util::stream_format(stream, "storh r%d,(r%d)", R2, R1); bytes = 2; break; - case 0x7d: util::stream_format(stream, "storh r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break; + case 0x7d: util::stream_format(stream, "storh r%d,%s", ADDR_R2, address(pc, opcodes)); bytes = 2 + ADDR_SIZE; break; case 0x80: util::stream_format(stream, "addw r%d,r%d", R1, R2); bytes = 2; break; @@ -258,7 +250,7 @@ CPU_DISASSEMBLE(clipper) case 0xb4: case 0xb5: // unprivileged macro instructions - switch (insn[0] & 0xff) + switch (opcodes.r16(pc) & 0xff) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: @@ -288,25 +280,25 @@ CPU_DISASSEMBLE(clipper) util::stream_format(stream, "restd%d", R2); break; - case 0x30: util::stream_format(stream, "cnvsw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x31: util::stream_format(stream, "cnvrsw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x32: util::stream_format(stream, "cnvtsw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x33: util::stream_format(stream, "cnvws r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x34: util::stream_format(stream, "cnvdw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x35: util::stream_format(stream, "cnvrdw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x36: util::stream_format(stream, "cnvtdw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x37: util::stream_format(stream, "cnvwd r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x38: util::stream_format(stream, "cnvsd f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x39: util::stream_format(stream, "cnvds f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x3a: util::stream_format(stream, "negs f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x3b: util::stream_format(stream, "negd f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x3c: util::stream_format(stream, "scalbs r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x3d: util::stream_format(stream, "scalbd r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; + case 0x30: util::stream_format(stream, "cnvsw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x31: util::stream_format(stream, "cnvrsw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x32: util::stream_format(stream, "cnvtsw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x33: util::stream_format(stream, "cnvws r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x34: util::stream_format(stream, "cnvdw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x35: util::stream_format(stream, "cnvrdw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x36: util::stream_format(stream, "cnvtdw f%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x37: util::stream_format(stream, "cnvwd r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x38: util::stream_format(stream, "cnvsd f%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x39: util::stream_format(stream, "cnvds f%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x3a: util::stream_format(stream, "negs f%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x3b: util::stream_format(stream, "negd f%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x3c: util::stream_format(stream, "scalbs r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x3d: util::stream_format(stream, "scalbd r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; case 0x3e: util::stream_format(stream, "trapfn"); break; - case 0x3f: util::stream_format(stream, "loadfs r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; + case 0x3f: util::stream_format(stream, "loadfs r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; default: - util::stream_format(stream, "macro 0x%04x 0x%04x", insn[0], insn[1]); + util::stream_format(stream, "macro 0x%04x 0x%04x", opcodes.r16(pc), opcodes.r16(pc+2)); break; } bytes = 4; @@ -314,19 +306,19 @@ CPU_DISASSEMBLE(clipper) case 0xb6: case 0xb7: // privileged macro instructions - switch (insn[0] & 0xff) + switch (opcodes.r16(pc) & 0xff) { - case 0x00: util::stream_format(stream, "movus r%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x01: util::stream_format(stream, "movsu r%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; - case 0x02: util::stream_format(stream, "saveur r%d", (insn[1] & 0xf0) >> 4); break; - case 0x03: util::stream_format(stream, "restur r%d", (insn[1] & 0xf0) >> 4); break; - case 0x04: util::stream_format(stream, "reti r%d", (insn[1] & 0xf0) >> 4); flags |= DASMFLAG_STEP_OUT; break; + case 0x00: util::stream_format(stream, "movus r%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x01: util::stream_format(stream, "movsu r%d,r%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; + case 0x02: util::stream_format(stream, "saveur r%d", (opcodes.r16(pc+2) & 0xf0) >> 4); break; + case 0x03: util::stream_format(stream, "restur r%d", (opcodes.r16(pc+2) & 0xf0) >> 4); break; + case 0x04: util::stream_format(stream, "reti r%d", (opcodes.r16(pc+2) & 0xf0) >> 4); flags |= STEP_OUT; break; case 0x05: util::stream_format(stream, "wait"); break; #if C400_INSTRUCTIONS - case 0x07: util::stream_format(stream, "loadts r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break; + case 0x07: util::stream_format(stream, "loadts r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break; #endif default: - util::stream_format(stream, "macro 0x%04x 0x%04x", insn[0], insn[1]); + util::stream_format(stream, "macro 0x%04x 0x%04x", opcodes.r16(pc), opcodes.r16(pc+2)); break; } bytes = 4; @@ -338,7 +330,7 @@ CPU_DISASSEMBLE(clipper) #endif default: - util::stream_format(stream, ".word 0x%04x", insn[0]); + util::stream_format(stream, ".word 0x%04x", opcodes.r16(pc)); bytes = 2; break; } diff --git a/src/devices/cpu/clipper/clipperd.h b/src/devices/cpu/clipper/clipperd.h new file mode 100644 index 00000000000..1dd757fde63 --- /dev/null +++ b/src/devices/cpu/clipper/clipperd.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_CPU_CLIPPER_CLIPPERDASM_H +#define MAME_CPU_CLIPPER_CLIPPERDASM_H + +#pragma once + +class clipper_disassembler : public util::disasm_interface +{ +public: + clipper_disassembler() = default; + virtual ~clipper_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum addressing_modes : u8 + { + ADDR_MODE_PC32 = 0x10, // pc relative with 32 bit displacement + ADDR_MODE_ABS32 = 0x30, // 32 bit absolute + ADDR_MODE_REL32 = 0x60, // relative with 32 bit displacement + ADDR_MODE_PC16 = 0x90, // pc relative with 16 bit displacement + ADDR_MODE_REL12 = 0xa0, // relative with 12 bit displacement + ADDR_MODE_ABS16 = 0xb0, // 16 bit absolute + ADDR_MODE_PCX = 0xd0, // pc indexed + ADDR_MODE_RELX = 0xe0 // relative indexed + }; + + static const char *const cc[]; + std::string address (offs_t pc, const data_buffer &opcodes); + + +}; + +#endif diff --git a/src/devices/cpu/cop400/cop400.cpp b/src/devices/cpu/cop400/cop400.cpp index 696e504835d..03416a54b28 100644 --- a/src/devices/cpu/cop400/cop400.cpp +++ b/src/devices/cpu/cop400/cop400.cpp @@ -56,6 +56,10 @@ #include "emu.h" #include "debugger.h" #include "cop400.h" +#include "cop410ds.h" +#include "cop420ds.h" +#include "cop424ds.h" +#include "cop444ds.h" DEFINE_DEVICE_TYPE(COP401, cop401_cpu_device, "cop401", "COP401") @@ -1064,7 +1068,7 @@ void cop400_cpu_device::device_start() { /* find address spaces */ m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); /* find i/o handlers */ @@ -1362,29 +1366,24 @@ void cop400_cpu_device::state_string_export(const device_state_entry &entry, std } -offs_t cop400_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cop400_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cop410 ); - extern CPU_DISASSEMBLE( cop420 ); - extern CPU_DISASSEMBLE( cop444 ); - extern CPU_DISASSEMBLE( cop424 ); - if ( m_featuremask & COP424C_FEATURE ) { - return CPU_DISASSEMBLE_NAME(cop424)(this, stream, pc, oprom, opram, options); + return new cop424_disassembler; } if ( m_featuremask & COP444L_FEATURE ) { - return CPU_DISASSEMBLE_NAME(cop444)(this, stream, pc, oprom, opram, options); + return new cop444_disassembler; } if ( m_featuremask & COP420_FEATURE ) { - return CPU_DISASSEMBLE_NAME(cop420)(this, stream, pc, oprom, opram, options); + return new cop420_disassembler; } - return CPU_DISASSEMBLE_NAME(cop410)(this, stream, pc, oprom, opram, options); + return new cop410_disassembler; } READ8_MEMBER( cop400_cpu_device::microbus_rd ) diff --git a/src/devices/cpu/cop400/cop400.h b/src/devices/cpu/cop400/cop400.h index 3a047d10c8a..d98d7bbbc6f 100644 --- a/src/devices/cpu/cop400/cop400.h +++ b/src/devices/cpu/cop400/cop400.h @@ -165,9 +165,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_data_config; @@ -207,7 +205,7 @@ protected: bool m_has_inil; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; uint8_t m_featuremask; diff --git a/src/devices/cpu/cop400/cop410ds.cpp b/src/devices/cpu/cop400/cop410ds.cpp index 4570417538f..9da69df8034 100644 --- a/src/devices/cpu/cop400/cop410ds.cpp +++ b/src/devices/cpu/cop400/cop410ds.cpp @@ -9,11 +9,17 @@ ***************************************************************************/ #include "emu.h" +#include "cop410ds.h" -CPU_DISASSEMBLE(cop410) +u32 cop410_disassembler::opcode_alignment() const { - uint8_t opcode = oprom[0]; - uint8_t next_opcode = oprom[1]; + return 1; +} + +offs_t cop410_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t opcode = opcodes.r8(pc); + uint8_t next_opcode = opcodes.r8(pc+1); uint16_t address; uint32_t flags = 0; int bytes = 1; @@ -38,7 +44,7 @@ CPU_DISASSEMBLE(cop410) { address = (uint16_t)(0x80 | (opcode & 0x3F)); util::stream_format(stream, "JSRP %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } } } @@ -72,7 +78,7 @@ CPU_DISASSEMBLE(cop410) { address = ((opcode & 0x01) << 8) | next_opcode; util::stream_format(stream, "JSR %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; bytes = 2; } else if (opcode >= 0x70 && opcode <= 0x7F) @@ -302,12 +308,12 @@ CPU_DISASSEMBLE(cop410) case 0x48: util::stream_format(stream, "RET"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x49: util::stream_format(stream, "RETSK"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x4B: @@ -348,5 +354,5 @@ CPU_DISASSEMBLE(cop410) } } - return bytes | flags | DASMFLAG_SUPPORTED; + return bytes | flags | SUPPORTED; } diff --git a/src/devices/cpu/cop400/cop410ds.h b/src/devices/cpu/cop400/cop410ds.h new file mode 100644 index 00000000000..c1841ec996c --- /dev/null +++ b/src/devices/cpu/cop400/cop410ds.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cop410ds.c + + National Semiconductor COP410 Emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_COP410_COP410DS_H +#define MAME_CPU_COP410_COP410DS_H + +#pragma once + +class cop410_disassembler : public util::disasm_interface +{ +public: + cop410_disassembler() = default; + virtual ~cop410_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cop400/cop420ds.cpp b/src/devices/cpu/cop400/cop420ds.cpp index 39ea87ba9b4..f8f910f174b 100644 --- a/src/devices/cpu/cop400/cop420ds.cpp +++ b/src/devices/cpu/cop400/cop420ds.cpp @@ -9,11 +9,17 @@ ***************************************************************************/ #include "emu.h" +#include "cop420ds.h" -CPU_DISASSEMBLE(cop420) +u32 cop420_disassembler::opcode_alignment() const { - uint8_t opcode = oprom[0]; - uint8_t next_opcode = oprom[1]; + return 1; +} + +offs_t cop420_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t opcode = opcodes.r8(pc); + uint8_t next_opcode = opcodes.r8(pc+1); uint16_t address; uint32_t flags = 0; int bytes = 1; @@ -38,7 +44,7 @@ CPU_DISASSEMBLE(cop420) { address = (uint16_t)(0x80 | (opcode & 0x3F)); util::stream_format(stream, "JSRP %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } } } @@ -72,7 +78,7 @@ CPU_DISASSEMBLE(cop420) { address = ((opcode & 0x03) << 8) | next_opcode; util::stream_format(stream, "JSR %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; bytes = 2; } else if (opcode >= 0x70 && opcode <= 0x7F) @@ -346,12 +352,12 @@ CPU_DISASSEMBLE(cop420) case 0x48: util::stream_format(stream, "RET"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x49: util::stream_format(stream, "RETSK"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x4A: @@ -396,5 +402,5 @@ CPU_DISASSEMBLE(cop420) } } - return bytes | flags | DASMFLAG_SUPPORTED; + return bytes | flags | SUPPORTED; } diff --git a/src/devices/cpu/cop400/cop420ds.h b/src/devices/cpu/cop400/cop420ds.h new file mode 100644 index 00000000000..a92ba84a54f --- /dev/null +++ b/src/devices/cpu/cop400/cop420ds.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cop420ds.c + + National Semiconductor COP420 Emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_COP420_COP420DS_H +#define MAME_CPU_COP420_COP420DS_H + +#pragma once + +class cop420_disassembler : public util::disasm_interface +{ +public: + cop420_disassembler() = default; + virtual ~cop420_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cop400/cop424ds.cpp b/src/devices/cpu/cop400/cop424ds.cpp index fc8396f4903..e42c5dc3120 100644 --- a/src/devices/cpu/cop400/cop424ds.cpp +++ b/src/devices/cpu/cop400/cop424ds.cpp @@ -9,11 +9,17 @@ ***************************************************************************/ #include "emu.h" +#include "cop424ds.h" -CPU_DISASSEMBLE(cop424) +u32 cop424_disassembler::opcode_alignment() const { - uint8_t opcode = oprom[0]; - uint8_t next_opcode = oprom[1]; + return 1; +} + +offs_t cop424_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t opcode = opcodes.r8(pc); + uint8_t next_opcode = opcodes.r8(pc+1); uint16_t address; uint32_t flags = 0; int bytes = 1; @@ -38,7 +44,7 @@ CPU_DISASSEMBLE(cop424) { address = (uint16_t)(0x80 | (opcode & 0x3F)); util::stream_format(stream, "JSRP %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } } } @@ -72,7 +78,7 @@ CPU_DISASSEMBLE(cop424) { address = ((opcode & 0x07) << 8) | next_opcode; util::stream_format(stream, "JSR %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; bytes = 2; } else if (opcode >= 0x70 && opcode <= 0x7F) @@ -347,12 +353,12 @@ CPU_DISASSEMBLE(cop424) case 0x48: util::stream_format(stream, "RET"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x49: util::stream_format(stream, "RETSK"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x4A: @@ -397,5 +403,5 @@ CPU_DISASSEMBLE(cop424) } } - return bytes | flags | DASMFLAG_SUPPORTED; + return bytes | flags | SUPPORTED; } diff --git a/src/devices/cpu/cop400/cop424ds.h b/src/devices/cpu/cop400/cop424ds.h new file mode 100644 index 00000000000..e093568a913 --- /dev/null +++ b/src/devices/cpu/cop400/cop424ds.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cop424ds.c + + National Semiconductor COP424 Emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_COP424_COP424DS_H +#define MAME_CPU_COP424_COP424DS_H + +#pragma once + +class cop424_disassembler : public util::disasm_interface +{ +public: + cop424_disassembler() = default; + virtual ~cop424_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cop400/cop444ds.cpp b/src/devices/cpu/cop400/cop444ds.cpp index cae2274546c..23e6cd23cec 100644 --- a/src/devices/cpu/cop400/cop444ds.cpp +++ b/src/devices/cpu/cop400/cop444ds.cpp @@ -9,11 +9,17 @@ ***************************************************************************/ #include "emu.h" +#include "cop444ds.h" -CPU_DISASSEMBLE(cop444) +u32 cop444_disassembler::opcode_alignment() const { - uint8_t opcode = oprom[0]; - uint8_t next_opcode = oprom[1]; + return 1; +} + +offs_t cop444_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t opcode = opcodes.r8(pc); + uint8_t next_opcode = opcodes.r8(pc+1); uint16_t address; uint32_t flags = 0; int bytes = 1; @@ -38,7 +44,7 @@ CPU_DISASSEMBLE(cop444) { address = (uint16_t)(0x80 | (opcode & 0x3F)); util::stream_format(stream, "JSRP %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } } } @@ -72,7 +78,7 @@ CPU_DISASSEMBLE(cop444) { address = ((opcode & 0x07) << 8) | next_opcode; util::stream_format(stream, "JSR %03X", address); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; bytes = 2; } else if (opcode >= 0x70 && opcode <= 0x7F) @@ -330,12 +336,12 @@ CPU_DISASSEMBLE(cop444) case 0x48: util::stream_format(stream, "RET"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x49: util::stream_format(stream, "RETSK"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x4A: @@ -380,5 +386,5 @@ CPU_DISASSEMBLE(cop444) } } - return bytes | flags | DASMFLAG_SUPPORTED; + return bytes | flags | SUPPORTED; } diff --git a/src/devices/cpu/cop400/cop444ds.h b/src/devices/cpu/cop400/cop444ds.h new file mode 100644 index 00000000000..c268616f846 --- /dev/null +++ b/src/devices/cpu/cop400/cop444ds.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cop444ds.c + + National Semiconductor COP444 Emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_COP444_COP444DS_H +#define MAME_CPU_COP444_COP444DS_H + +#pragma once + +class cop444_disassembler : public util::disasm_interface +{ +public: + cop444_disassembler() = default; + virtual ~cop444_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cosmac/cosdasm.cpp b/src/devices/cpu/cosmac/cosdasm.cpp index 72f039037b5..c818fd2c9a9 100644 --- a/src/devices/cpu/cosmac/cosdasm.cpp +++ b/src/devices/cpu/cosmac/cosdasm.cpp @@ -10,56 +10,62 @@ ***************************************************************************/ #include "emu.h" - -enum -{ - TYPE_1801, - TYPE_1802 -}; +#include "cosdasm.h" #define CDP1801_OPCODE(...) \ util::stream_format(stream, __VA_ARGS__) #define CDP1802_OPCODE(...) \ - if (variant < TYPE_1802) stream << "illegal"; else util::stream_format(stream, __VA_ARGS__) + if (m_variant < TYPE_1802) stream << "illegal"; else util::stream_format(stream, __VA_ARGS__) -static offs_t implied(const uint8_t opcode) +offs_t cosmac_disassembler::implied(const uint8_t opcode) { return opcode & 0x0f; } -static offs_t immediate(const uint8_t **opram) +offs_t cosmac_disassembler::immediate(offs_t &pc, const data_buffer ¶ms) { - return *(*opram)++; + return params.r8(pc++); } -static offs_t short_branch(offs_t pc, const uint8_t **opram) +offs_t cosmac_disassembler::short_branch(offs_t base_pc, offs_t &pc, const data_buffer ¶ms) { - return (pc & 0xff00) | immediate(opram); + return (base_pc & 0xff00) | immediate(pc, params); } -static offs_t long_branch(const uint8_t **opram) +offs_t cosmac_disassembler::long_branch(offs_t &pc, const data_buffer ¶ms) { - return (immediate(opram) << 8) | immediate(opram); + u16 res = params.r16(pc); + pc += 2; + return res; } -static offs_t short_skip(offs_t pc) +offs_t cosmac_disassembler::short_skip(offs_t pc) { return pc + 2; } -static offs_t long_skip(offs_t pc) +offs_t cosmac_disassembler::long_skip(offs_t pc) { return pc + 3; } -static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t variant) + +u32 cosmac_disassembler::opcode_alignment() const +{ + return 1; +} + +cosmac_disassembler::cosmac_disassembler(int variant) : m_variant(variant) +{ +} + +offs_t cosmac_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint8_t *startram = opram; + offs_t base_pc = pc; uint32_t flags = 0; - opram++; - uint8_t opcode = *oprom++; + uint8_t opcode = opcodes.r8(pc++); switch (opcode) { @@ -73,20 +79,20 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: CDP1801_OPCODE("DEC R%01X", implied(opcode)); break; - case 0x30: CDP1801_OPCODE("BR %04X", short_branch(pc, &opram)); break; - case 0x32: CDP1801_OPCODE("BZ %04X", short_branch(pc, &opram)); break; - case 0x33: CDP1801_OPCODE("BDF %04X", short_branch(pc, &opram)); break; - case 0x34: CDP1801_OPCODE("B1 %04X", short_branch(pc, &opram)); break; - case 0x35: CDP1801_OPCODE("B2 %04X", short_branch(pc, &opram)); break; - case 0x36: CDP1801_OPCODE("B3 %04X", short_branch(pc, &opram)); break; - case 0x37: CDP1801_OPCODE("B4 %04X", short_branch(pc, &opram)); break; + case 0x30: CDP1801_OPCODE("BR %04X", short_branch(base_pc, pc, params)); break; + case 0x32: CDP1801_OPCODE("BZ %04X", short_branch(base_pc, pc, params)); break; + case 0x33: CDP1801_OPCODE("BDF %04X", short_branch(base_pc, pc, params)); break; + case 0x34: CDP1801_OPCODE("B1 %04X", short_branch(base_pc, pc, params)); break; + case 0x35: CDP1801_OPCODE("B2 %04X", short_branch(base_pc, pc, params)); break; + case 0x36: CDP1801_OPCODE("B3 %04X", short_branch(base_pc, pc, params)); break; + case 0x37: CDP1801_OPCODE("B4 %04X", short_branch(base_pc, pc, params)); break; case 0x38: CDP1801_OPCODE("SKP %04X", short_skip(pc)); break; - case 0x3a: CDP1801_OPCODE("BNZ %04X", short_branch(pc, &opram)); break; - case 0x3b: CDP1801_OPCODE("BNF %04X", short_branch(pc, &opram)); break; - case 0x3c: CDP1801_OPCODE("BN1 %04X", short_branch(pc, &opram)); break; - case 0x3d: CDP1801_OPCODE("BN2 %04X", short_branch(pc, &opram)); break; - case 0x3e: CDP1801_OPCODE("BN3 %04X", short_branch(pc, &opram)); break; - case 0x3f: CDP1801_OPCODE("BN4 %04X", short_branch(pc, &opram)); break; + case 0x3a: CDP1801_OPCODE("BNZ %04X", short_branch(base_pc, pc, params)); break; + case 0x3b: CDP1801_OPCODE("BNF %04X", short_branch(base_pc, pc, params)); break; + case 0x3c: CDP1801_OPCODE("BN1 %04X", short_branch(base_pc, pc, params)); break; + case 0x3d: CDP1801_OPCODE("BN2 %04X", short_branch(base_pc, pc, params)); break; + case 0x3e: CDP1801_OPCODE("BN3 %04X", short_branch(base_pc, pc, params)); break; + case 0x3f: CDP1801_OPCODE("BN4 %04X", short_branch(base_pc, pc, params)); break; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: CDP1801_OPCODE("LDA R%01X", implied(opcode)); break; @@ -107,8 +113,8 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c case 0x6d: CDP1801_OPCODE("INP 5"); break; case 0x6e: CDP1801_OPCODE("INP 6"); break; case 0x6f: CDP1801_OPCODE("INP 7"); break; - case 0x70: CDP1801_OPCODE("RET"); flags = DASMFLAG_STEP_OUT; break; - case 0x71: CDP1801_OPCODE("DIS"); flags = DASMFLAG_STEP_OUT; break; + case 0x70: CDP1801_OPCODE("RET"); flags = STEP_OUT; break; + case 0x71: CDP1801_OPCODE("DIS"); flags = STEP_OUT; break; case 0x78: CDP1801_OPCODE("SAV"); break; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: @@ -124,7 +130,7 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c CDP1801_OPCODE("PHI R%01X", implied(opcode)); break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - CDP1801_OPCODE("SEP R%01X", implied(opcode)); flags = DASMFLAG_STEP_OVER; break; + CDP1801_OPCODE("SEP R%01X", implied(opcode)); flags = STEP_OVER; break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7: case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef: CDP1801_OPCODE("SEX R%01X", implied(opcode)); break; @@ -136,16 +142,16 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c case 0xf5: CDP1801_OPCODE("SD"); break; case 0xf6: CDP1801_OPCODE("SHR"); break; case 0xf7: CDP1801_OPCODE("SM"); break; - case 0xf8: CDP1801_OPCODE("LDI #%02X", immediate(&opram)); break; - case 0xf9: CDP1801_OPCODE("ORI #%02X", immediate(&opram)); break; - case 0xfa: CDP1801_OPCODE("ANI #%02X", immediate(&opram)); break; - case 0xfb: CDP1801_OPCODE("XRI #%02X", immediate(&opram)); break; - case 0xfc: CDP1801_OPCODE("ADI #%02X", immediate(&opram)); break; - case 0xfd: CDP1801_OPCODE("SDI #%02X", immediate(&opram)); break; - case 0xff: CDP1801_OPCODE("SMI #%02X", immediate(&opram)); break; + case 0xf8: CDP1801_OPCODE("LDI #%02X", immediate(pc, params)); break; + case 0xf9: CDP1801_OPCODE("ORI #%02X", immediate(pc, params)); break; + case 0xfa: CDP1801_OPCODE("ANI #%02X", immediate(pc, params)); break; + case 0xfb: CDP1801_OPCODE("XRI #%02X", immediate(pc, params)); break; + case 0xfc: CDP1801_OPCODE("ADI #%02X", immediate(pc, params)); break; + case 0xfd: CDP1801_OPCODE("SDI #%02X", immediate(pc, params)); break; + case 0xff: CDP1801_OPCODE("SMI #%02X", immediate(pc, params)); break; // CDP1802 - case 0x31: CDP1802_OPCODE("BQ %04X", short_branch(pc, &opram)); break; - case 0x39: CDP1802_OPCODE("BNQ %04X", short_branch(pc, &opram)); break; + case 0x31: CDP1802_OPCODE("BQ %04X", short_branch(base_pc, pc, params)); break; + case 0x39: CDP1802_OPCODE("BNQ %04X", short_branch(base_pc, pc, params)); break; case 0x60: CDP1802_OPCODE("IRX"); break; case 0x72: CDP1802_OPCODE("LDXA"); break; case 0x73: CDP1802_OPCODE("STXD"); break; @@ -156,14 +162,14 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c case 0x79: CDP1802_OPCODE("MARK"); break; case 0x7a: CDP1802_OPCODE("REQ"); break; case 0x7b: CDP1802_OPCODE("SEQ"); break; - case 0x7c: CDP1802_OPCODE("ADCI #%02X", immediate(&opram)); break; - case 0x7d: CDP1802_OPCODE("SDBI #%02X", immediate(&opram)); break; + case 0x7c: CDP1802_OPCODE("ADCI #%02X", immediate(pc, params)); break; + case 0x7d: CDP1802_OPCODE("SDBI #%02X", immediate(pc, params)); break; case 0x7e: CDP1802_OPCODE("SHLC"); break; - case 0x7f: CDP1802_OPCODE("SMBI #%02X", immediate(&opram)); break; - case 0xc0: CDP1802_OPCODE("LBR %04X", long_branch(&opram)); break; - case 0xc1: CDP1802_OPCODE("LBQ %04X", long_branch(&opram)); break; - case 0xc2: CDP1802_OPCODE("LBZ %04X", long_branch(&opram)); break; - case 0xc3: CDP1802_OPCODE("LBDF %04X", long_branch(&opram)); break; + case 0x7f: CDP1802_OPCODE("SMBI #%02X", immediate(pc, params)); break; + case 0xc0: CDP1802_OPCODE("LBR %04X", long_branch(pc, params)); break; + case 0xc1: CDP1802_OPCODE("LBQ %04X", long_branch(pc, params)); break; + case 0xc2: CDP1802_OPCODE("LBZ %04X", long_branch(pc, params)); break; + case 0xc3: CDP1802_OPCODE("LBDF %04X", long_branch(pc, params)); break; case 0xc4: CDP1802_OPCODE("NOP"); break; case 0xc5: CDP1802_OPCODE("LSNQ %04X", long_skip(pc)); break; case 0xc6: CDP1802_OPCODE("LSNZ %04X", long_skip(pc)); break; @@ -181,17 +187,5 @@ static uint32_t disassemble(device_t *device, std::ostream &stream, offs_t pc, c default: CDP1801_OPCODE("illegal"); break; } - return (opram - startram) | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( cdp1801 ) -{ - return disassemble(device, stream, pc, oprom, opram, TYPE_1801); -} - - -CPU_DISASSEMBLE( cdp1802 ) -{ - return disassemble(device, stream, pc, oprom, opram, TYPE_1802); + return (pc - base_pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/cosmac/cosdasm.h b/src/devices/cpu/cosmac/cosdasm.h new file mode 100644 index 00000000000..38011b792c6 --- /dev/null +++ b/src/devices/cpu/cosmac/cosdasm.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/*************************************************************************** + + cosdasm.c + + Simple RCA COSMAC disassembler. + Written by Curt Coder + +***************************************************************************/ + +#ifndef MAME_CPU_COSMAC_COSDASM_H +#define MAME_CPU_COSMAC_COSDASM_H + +#pragma once + +class cosmac_disassembler : public util::disasm_interface +{ +public: + enum + { + TYPE_1801, + TYPE_1802 + }; + + cosmac_disassembler(int variant); + virtual ~cosmac_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + int m_variant; + + offs_t implied(const uint8_t opcode); + offs_t immediate(offs_t &pc, const data_buffer ¶ms); + offs_t short_branch(offs_t base_pc, offs_t &pc, const data_buffer ¶ms); + offs_t long_branch(offs_t &pc, const data_buffer ¶ms); + offs_t short_skip(offs_t pc); + offs_t long_skip(offs_t pc); +}; + +#endif diff --git a/src/devices/cpu/cosmac/cosmac.cpp b/src/devices/cpu/cosmac/cosmac.cpp index feff0141494..60b28dee897 100644 --- a/src/devices/cpu/cosmac/cosmac.cpp +++ b/src/devices/cpu/cosmac/cosmac.cpp @@ -9,6 +9,7 @@ #include "emu.h" #include "debugger.h" #include "cosmac.h" +#include "cosdasm.h" #include "coreutil.h" // permit our enums to be saved @@ -324,8 +325,8 @@ cdp1802_device::cdp1802_device(const machine_config &mconfig, const char *tag, d void cosmac_device::device_start() { // resolve callbacks - m_read_wait.resolve_safe(0); - m_read_clear.resolve_safe(0); + m_read_wait.resolve(); + m_read_clear.resolve(); m_read_ef1.resolve(); m_read_ef2.resolve(); m_read_ef3.resolve(); @@ -337,7 +338,7 @@ void cosmac_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); // register our state for the debugger @@ -479,45 +480,21 @@ void cosmac_device::state_string_export(const device_state_entry &entry, std::st //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t cosmac_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t cosmac_device::disasm_max_opcode_bytes() const -{ - return 3; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t cdp1801_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cdp1801_device::create_disassembler() { - extern CPU_DISASSEMBLE( cdp1801 ); - return CPU_DISASSEMBLE_NAME( cdp1801 )(this, stream, pc, oprom, opram, options); + return new cosmac_disassembler(cosmac_disassembler::TYPE_1801); } -offs_t cdp1802_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) + +util::disasm_interface *cdp1802_device::create_disassembler() { - extern CPU_DISASSEMBLE( cdp1802 ); - return CPU_DISASSEMBLE_NAME( cdp1802 )(this, stream, pc, oprom, opram, options); + return new cosmac_disassembler(cosmac_disassembler::TYPE_1802); } - //************************************************************************** // INLINE HELPERS //************************************************************************** @@ -648,6 +625,14 @@ void cosmac_device::execute_set_input(int inputnum, int state) case COSMAC_INPUT_LINE_EF4: EF[inputnum - COSMAC_INPUT_LINE_EF1] = state; break; + + case COSMAC_INPUT_LINE_CLEAR: + m_clear = state; + break; + + case COSMAC_INPUT_LINE_WAIT: + m_wait = state; + break; } } @@ -792,11 +777,11 @@ inline void cosmac_device::debug() inline void cosmac_device::sample_wait_clear() { - int wait = m_read_wait(); - int clear = m_read_clear(); + if (!m_read_wait.isnull()) m_wait = m_read_wait(); + if (!m_read_clear.isnull()) m_clear = m_read_clear(); m_pmode = m_mode; - m_mode = (cosmac_mode) ((clear << 1) | wait); + m_mode = (cosmac_mode) ((m_clear << 1) | m_wait); } diff --git a/src/devices/cpu/cosmac/cosmac.h b/src/devices/cpu/cosmac/cosmac.h index 649a3ca6a2b..515dde74d45 100644 --- a/src/devices/cpu/cosmac/cosmac.h +++ b/src/devices/cpu/cosmac/cosmac.h @@ -126,7 +126,9 @@ // input lines enum { - COSMAC_INPUT_LINE_INT = 0, + COSMAC_INPUT_LINE_WAIT = 0, + COSMAC_INPUT_LINE_CLEAR, + COSMAC_INPUT_LINE_INT, COSMAC_INPUT_LINE_DMAIN, COSMAC_INPUT_LINE_DMAOUT, COSMAC_INPUT_LINE_EF1, @@ -205,6 +207,8 @@ public: // public interfaces offs_t get_memory_address(); + DECLARE_WRITE_LINE_MEMBER( wait_w ) { set_input_line(COSMAC_INPUT_LINE_WAIT, state); } + DECLARE_WRITE_LINE_MEMBER( clear_w ) { set_input_line(COSMAC_INPUT_LINE_CLEAR, state); } DECLARE_WRITE_LINE_MEMBER( int_w ) { set_input_line(COSMAC_INPUT_LINE_INT, state); } DECLARE_WRITE_LINE_MEMBER( dma_in_w ) { set_input_line(COSMAC_INPUT_LINE_DMAIN, state); } DECLARE_WRITE_LINE_MEMBER( dma_out_w ) { set_input_line(COSMAC_INPUT_LINE_DMAOUT, state); } @@ -236,10 +240,6 @@ protected: virtual void state_export(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; - virtual uint32_t disasm_max_opcode_bytes() const override; - // helpers inline uint8_t read_opcode(offs_t pc); inline uint8_t read_byte(offs_t address); @@ -411,6 +411,8 @@ protected: cosmac_state m_state; // state cosmac_mode m_mode; // control mode cosmac_mode m_pmode; // previous control mode + bool m_wait; + bool m_clear; int m_irq; // interrupt request int m_dmain; // DMA input request int m_dmaout; // DMA output request @@ -435,7 +437,7 @@ protected: int m_icount; address_space * m_program; address_space * m_io; - direct_read_data * m_direct; + direct_read_data<0> *m_direct; // opcode/condition tables typedef void (cosmac_device::*ophandler)(); @@ -453,7 +455,7 @@ public: protected: // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual cosmac_device::ophandler get_ophandler(uint8_t opcode) override; @@ -471,7 +473,7 @@ public: protected: // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual cosmac_device::ophandler get_ophandler(uint8_t opcode) override; diff --git a/src/devices/cpu/cp1610/1610dasm.cpp b/src/devices/cpu/cp1610/1610dasm.cpp index 0e9ed461dd3..112bbda6523 100644 --- a/src/devices/cpu/cp1610/1610dasm.cpp +++ b/src/devices/cpu/cp1610/1610dasm.cpp @@ -1,12 +1,16 @@ // license:BSD-3-Clause // copyright-holders:Frank Palazzolo #include "emu.h" -#include "debugger.h" -#include "cp1610.h" +#include "1610dasm.h" -CPU_DISASSEMBLE(cp1610) +u32 cp1610_disassembler::opcode_alignment() const { - uint16_t oprom16[4]={ static_cast<uint16_t>((oprom[0] << 8) | oprom[1]), static_cast<uint16_t>((oprom[2] << 8) | oprom[3]), static_cast<uint16_t>((oprom[4] << 8) | oprom[5]), static_cast<uint16_t>((oprom[6] << 8) | oprom[7]) }; + return 1; +} + +offs_t cp1610_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint16_t oprom16[4]={ opcodes.r16(pc), opcodes.r16(pc+1), opcodes.r16(pc+2), opcodes.r16(pc+3) }; uint16_t op = oprom16[0]; uint16_t subop; uint16_t ea, ea1, ea2; unsigned size = 1; diff --git a/src/devices/cpu/cp1610/1610dasm.h b/src/devices/cpu/cp1610/1610dasm.h new file mode 100644 index 00000000000..59cc61b36f9 --- /dev/null +++ b/src/devices/cpu/cp1610/1610dasm.h @@ -0,0 +1,19 @@ +// license:BSD-3-Clause +// copyright-holders:Frank Palazzolo + +#ifndef MAME_CPU_CP1610_CP1610DASM_H +#define MAME_CPU_CP1610_CP1610DASM_H + +#pragma once + +class cp1610_disassembler : public util::disasm_interface +{ +public: + cp1610_disassembler() = default; + virtual ~cp1610_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cp1610/cp1610.cpp b/src/devices/cpu/cp1610/cp1610.cpp index 5a113b4e954..aafbe86fbe9 100644 --- a/src/devices/cpu/cp1610/cp1610.cpp +++ b/src/devices/cpu/cp1610/cp1610.cpp @@ -16,7 +16,7 @@ #include "emu.h" #include "cp1610.h" #include "debugger.h" - +#include "1610dasm.h" DEFINE_DEVICE_TYPE(CP1610, cp1610_cpu_device, "cp1610", "GI CP1610") @@ -27,9 +27,9 @@ DEFINE_DEVICE_TYPE(CP1610, cp1610_cpu_device, "cp1610", "GI CP1610") #define C 0x10 -#define cp1610_readop(A) m_program->read_word((A)<<1) -#define cp1610_readmem16(A) m_program->read_word((A)<<1) -#define cp1610_writemem16(A,B) m_program->write_word((A)<<1,B) +#define cp1610_readop(A) m_program->read_word(A) +#define cp1610_readmem16(A) m_program->read_word(A) +#define cp1610_writemem16(A,B) m_program->write_word(A,B) /* clear all flags */ #define CLR_SZOC \ @@ -3422,9 +3422,7 @@ void cp1610_cpu_device::state_string_export(const device_state_entry &entry, std } } - -offs_t cp1610_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cp1610_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cp1610 ); - return CPU_DISASSEMBLE_NAME(cp1610)(this, stream, pc, oprom, opram, options); + return new cp1610_disassembler; } diff --git a/src/devices/cpu/cp1610/cp1610.h b/src/devices/cpu/cp1610/cp1610.h index c3a844189e3..54daa10b4bc 100644 --- a/src/devices/cpu/cp1610/cp1610.h +++ b/src/devices/cpu/cp1610/cp1610.h @@ -60,9 +60,7 @@ protected: 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -211,7 +209,4 @@ private: DECLARE_DEVICE_TYPE(CP1610, cp1610_cpu_device) - -CPU_DISASSEMBLE( cp1610 ); - #endif // MAME_CPU_CP1610_CP1610_H diff --git a/src/devices/cpu/cubeqcpu/cubedasm.cpp b/src/devices/cpu/cubeqcpu/cubedasm.cpp index 20fd5a266d0..2bfb3ac0431 100644 --- a/src/devices/cpu/cubeqcpu/cubedasm.cpp +++ b/src/devices/cpu/cubeqcpu/cubedasm.cpp @@ -9,7 +9,7 @@ ***************************************************************************/ #include "emu.h" -#include "cubeqcpu.h" +#include "cubedasm.h" /*************************************************************************** @@ -17,7 +17,7 @@ ***************************************************************************/ /* Am2901 Instruction Fields */ -static const char *const ins[] = +const char *const cubeq_disassembler::ins[] = { "ADD ", "SUBR ", @@ -29,7 +29,7 @@ static const char *const ins[] = "EXNOR", }; -static const char *const src[] = +const char *const cubeq_disassembler::src[] = { "A,Q", "A,B", @@ -41,7 +41,7 @@ static const char *const src[] = "D,0", }; -static const char *const dst[] = +const char *const cubeq_disassembler::dst[] = { "QREG ", "NOP ", @@ -53,12 +53,16 @@ static const char *const dst[] = "RAMU ", }; +u32 cubeq_disassembler::opcode_alignment() const +{ + return 1; +} /*************************************************************************** SOUND DISASSEMBLY HOOK ***************************************************************************/ -CPU_DISASSEMBLE(cquestsnd) +offs_t cquestsnd_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { static const char *const jmps[] = { @@ -81,7 +85,7 @@ CPU_DISASSEMBLE(cquestsnd) " ", }; - uint64_t inst = big_endianize_int64(*(uint64_t *)oprom); + uint64_t inst = opcodes.r64(pc); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -121,7 +125,7 @@ CPU_DISASSEMBLE(cquestsnd) _ipwrt ? ' ' : 'W', inca ? 'I' : ' '); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } @@ -129,7 +133,7 @@ CPU_DISASSEMBLE(cquestsnd) ROTATE DISASSEMBLY HOOK ***************************************************************************/ -CPU_DISASSEMBLE(cquestrot) +offs_t cquestrot_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { static const char *const jmps[] = { @@ -185,7 +189,7 @@ CPU_DISASSEMBLE(cquestrot) "??? " }; - uint64_t inst = big_endianize_int64(*(uint64_t *)oprom); + uint64_t inst = opcodes.r64(pc); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -217,7 +221,7 @@ CPU_DISASSEMBLE(cquestrot) spfs[spf], t); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } @@ -225,7 +229,7 @@ CPU_DISASSEMBLE(cquestrot) LINE DRAWER DISASSEMBLY HOOK ***************************************************************************/ -CPU_DISASSEMBLE(cquestlin) +offs_t cquestlin_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { static const char *const jmps[] = { @@ -272,7 +276,7 @@ CPU_DISASSEMBLE(cquestlin) "BRES ", }; - uint64_t inst = big_endianize_int64(*(uint64_t *)oprom); + uint64_t inst = opcodes.r64(pc); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -303,5 +307,5 @@ CPU_DISASSEMBLE(cquestlin) _pbcs ? " " : "PB", spfs[spf]); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } diff --git a/src/devices/cpu/cubeqcpu/cubedasm.h b/src/devices/cpu/cubeqcpu/cubedasm.h new file mode 100644 index 00000000000..e43018a1998 --- /dev/null +++ b/src/devices/cpu/cubeqcpu/cubedasm.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:Philip Bennett +/*************************************************************************** + + cubedasm.c + + Implementation of the Cube Quest AM2901-based CPUs + +***************************************************************************/ + +#ifndef MAME_CPU_CUBEQCPU_CUBEDASM_H +#define MAME_CPU_CUBEQCPU_CUBEDASM_H + +#pragma once + +class cubeq_disassembler : public util::disasm_interface +{ +public: + cubeq_disassembler() = default; + virtual ~cubeq_disassembler() = default; + + virtual u32 opcode_alignment() const override; + +protected: + static const char *const ins[]; + static const char *const src[]; + static const char *const dst[]; +}; + +class cquestsnd_disassembler : public cubeq_disassembler +{ +public: + cquestsnd_disassembler() = default; + virtual ~cquestsnd_disassembler() = default; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +class cquestrot_disassembler : public cubeq_disassembler +{ +public: + cquestrot_disassembler() = default; + virtual ~cquestrot_disassembler() = default; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +class cquestlin_disassembler : public cubeq_disassembler +{ +public: + cquestlin_disassembler() = default; + virtual ~cquestlin_disassembler() = default; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/cubeqcpu/cubeqcpu.cpp b/src/devices/cpu/cubeqcpu/cubeqcpu.cpp index 9c3652fd40e..f00ed3eefa0 100644 --- a/src/devices/cpu/cubeqcpu/cubeqcpu.cpp +++ b/src/devices/cpu/cubeqcpu/cubeqcpu.cpp @@ -16,6 +16,7 @@ #include "emu.h" #include "debugger.h" #include "cubeqcpu.h" +#include "cubedasm.h" /*************************************************************************** @@ -91,10 +92,9 @@ device_memory_interface::space_config_vector cquestsnd_cpu_device::memory_space_ } -offs_t cquestsnd_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cquestsnd_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cquestsnd ); - return CPU_DISASSEMBLE_NAME(cquestsnd)(this, stream, pc, oprom, opram, options); + return new cquestsnd_disassembler; } @@ -112,10 +112,9 @@ READ16_MEMBER( cquestrot_cpu_device::linedata_r ) } -offs_t cquestrot_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cquestrot_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cquestrot ); - return CPU_DISASSEMBLE_NAME(cquestrot)(this, stream, pc, oprom, opram, options); + return new cquestsnd_disassembler; } @@ -135,10 +134,9 @@ device_memory_interface::space_config_vector cquestlin_cpu_device::memory_space_ }; } -offs_t cquestlin_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *cquestlin_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( cquestlin ); - return CPU_DISASSEMBLE_NAME(cquestlin)(this, stream, pc, oprom, opram, options); + return new cquestlin_disassembler; } @@ -185,7 +183,7 @@ void cquestsnd_cpu_device::device_start() m_sound_data = (uint16_t*)machine().root_device().memregion(m_sound_region_tag)->base(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); memset(m_ram, 0, sizeof(m_ram)); m_q = 0; @@ -264,7 +262,7 @@ void cquestrot_cpu_device::device_start() m_linedata_w.resolve_safe(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); memset(m_ram, 0, sizeof(m_ram)); m_q = 0; @@ -395,7 +393,7 @@ void cquestlin_cpu_device::device_start() m_linedata_r.resolve_safe(0); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); memset(m_ram, 0, sizeof(m_ram)); m_q = 0; @@ -544,7 +542,7 @@ void cquestsnd_cpu_device::execute_run() do { /* Decode the instruction */ - uint64_t inst = m_direct->read_qword(SND_PC << 3); + uint64_t inst = m_direct->read_qword(SND_PC); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -800,7 +798,7 @@ void cquestrot_cpu_device::execute_run() do { /* Decode the instruction */ - uint64_t inst = m_direct->read_qword(ROT_PC << 3); + uint64_t inst = m_direct->read_qword(ROT_PC); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; @@ -1220,7 +1218,7 @@ void cquestlin_cpu_device::execute_run() int prog = (m_clkcnt & 3) ? BACKGROUND : FOREGROUND; m_curpc = LINE_PC; - uint64_t inst = m_direct->read_qword(LINE_PC << 3); + uint64_t inst = m_direct->read_qword(LINE_PC); uint32_t inslow = inst & 0xffffffff; uint32_t inshig = inst >> 32; diff --git a/src/devices/cpu/cubeqcpu/cubeqcpu.h b/src/devices/cpu/cubeqcpu/cubeqcpu.h index de80a2830d5..46b3235c6be 100644 --- a/src/devices/cpu/cubeqcpu/cubeqcpu.h +++ b/src/devices/cpu/cubeqcpu/cubeqcpu.h @@ -87,9 +87,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -120,7 +118,7 @@ private: uint16_t *m_sound_data; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; int m_icount; int do_sndjmp(int jmp); @@ -190,9 +188,7 @@ protected: 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 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -231,7 +227,7 @@ private: uint8_t m_clkcnt; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; int m_icount; // For the debugger @@ -304,9 +300,7 @@ protected: 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 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -350,7 +344,7 @@ private: uint32_t m_o_stack[32768]; /* Stack DRAM: 32kx20 */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; int m_icount; // For the debugger diff --git a/src/devices/cpu/dsp16/dsp16.cpp b/src/devices/cpu/dsp16/dsp16.cpp index 4426502cdf7..33c25a32dc6 100644 --- a/src/devices/cpu/dsp16/dsp16.cpp +++ b/src/devices/cpu/dsp16/dsp16.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "debugger.h" #include "dsp16.h" +#include "dsp16dis.h" // // TODO: @@ -161,7 +162,7 @@ void dsp16_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); m_data = &space(AS_DATA); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); // set our instruction counter m_icountptr = &m_icount; @@ -321,60 +322,35 @@ void dsp16_device::state_string_export(const device_state_entry &entry, std::str } } - -//------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t dsp16_device::disasm_min_opcode_bytes() const -{ - return 2; -} - - //------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t dsp16_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t dsp16_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *dsp16_device::create_disassembler() { - extern CPU_DISASSEMBLE( dsp16a ); - return CPU_DISASSEMBLE_NAME(dsp16a)(this, stream, pc, oprom, opram, options); + return new dsp16a_disassembler; } - /*************************************************************************** MEMORY ACCESSORS ***************************************************************************/ inline uint32_t dsp16_device::data_read(const uint16_t& addr) { - return m_data->read_word(addr << 1); + return m_data->read_word(addr); } inline void dsp16_device::data_write(const uint16_t& addr, const uint16_t& data) { - m_data->write_word(addr << 1, data & 0xffff); + m_data->write_word(addr, data & 0xffff); } inline uint32_t dsp16_device::opcode_read(const uint8_t pcOffset) { const uint16_t readPC = m_pc + pcOffset; - return m_direct->read_dword(readPC << 1); + return m_direct->read_dword(readPC); } diff --git a/src/devices/cpu/dsp16/dsp16.h b/src/devices/cpu/dsp16/dsp16.h index fd41dd03ef1..2dcf6892833 100644 --- a/src/devices/cpu/dsp16/dsp16.h +++ b/src/devices/cpu/dsp16/dsp16.h @@ -83,9 +83,7 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // address spaces const address_space_config m_program_config; @@ -148,7 +146,7 @@ protected: // address spaces address_space* m_program; address_space* m_data; - direct_read_data* m_direct; + direct_read_data<-1> *m_direct; // other internal states int m_icount; diff --git a/src/devices/cpu/dsp16/dsp16dis.cpp b/src/devices/cpu/dsp16/dsp16dis.cpp index eb371719cb6..40e122741e3 100644 --- a/src/devices/cpu/dsp16/dsp16dis.cpp +++ b/src/devices/cpu/dsp16/dsp16dis.cpp @@ -1,9 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Andrew Gardner #include "emu.h" -#include "dsp16.h" +#include "dsp16dis.h" -std::string disasmF1Field(const uint8_t& F1, const uint8_t& D, const uint8_t& S) +std::string dsp16a_disassembler::disasmF1Field(const uint8_t& F1, const uint8_t& D, const uint8_t& S) { switch (F1) { @@ -28,7 +28,7 @@ std::string disasmF1Field(const uint8_t& F1, const uint8_t& D, const uint8_t& S) } } -std::string disasmYField(const uint8_t& Y) +std::string dsp16a_disassembler::disasmYField(const uint8_t& Y) { switch (Y) { @@ -58,7 +58,7 @@ std::string disasmYField(const uint8_t& Y) //return ""; } -std::string disasmZField(const uint8_t& Z) +std::string dsp16a_disassembler::disasmZField(const uint8_t& Z) { switch (Z) { @@ -88,7 +88,7 @@ std::string disasmZField(const uint8_t& Z) //return ""; } -std::string disasmF2Field(const uint8_t& F2, const uint8_t& D, const uint8_t& S) +std::string dsp16a_disassembler::disasmF2Field(const uint8_t& F2, const uint8_t& D, const uint8_t& S) { std::string ret = ""; switch (F2) @@ -116,7 +116,7 @@ std::string disasmF2Field(const uint8_t& F2, const uint8_t& D, const uint8_t& S) return ret; } -std::string disasmCONField(const uint8_t& CON) +std::string dsp16a_disassembler::disasmCONField(const uint8_t& CON) { switch (CON) { @@ -145,7 +145,7 @@ std::string disasmCONField(const uint8_t& CON) //return ""; } -std::string disasmBField(const uint8_t& B) +std::string dsp16a_disassembler::disasmBField(const uint8_t& B) { switch (B) { @@ -164,7 +164,7 @@ std::string disasmBField(const uint8_t& B) //return ""; } -std::string disasmRImmediateField(const uint8_t& R) +std::string dsp16a_disassembler::disasmRImmediateField(const uint8_t& R) { switch (R) { @@ -183,7 +183,7 @@ std::string disasmRImmediateField(const uint8_t& R) //return ""; } -std::string disasmRField(const uint8_t& R) +std::string dsp16a_disassembler::disasmRField(const uint8_t& R) { switch (R) { @@ -222,7 +222,7 @@ std::string disasmRField(const uint8_t& R) //return ""; } -std::string disasmIField(const uint8_t& I) +std::string dsp16a_disassembler::disasmIField(const uint8_t& I) { switch (I) { @@ -237,7 +237,7 @@ std::string disasmIField(const uint8_t& I) //return ""; } -bool disasmSIField(const uint8_t& SI) +bool dsp16a_disassembler::disasmSIField(const uint8_t& SI) { switch (SI) { @@ -248,12 +248,17 @@ bool disasmSIField(const uint8_t& SI) } -CPU_DISASSEMBLE(dsp16a) +u32 dsp16a_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t dsp16a_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint8_t opSize = 1; uint32_t dasmflags = 0; - uint16_t op = oprom[0] | (oprom[1] << 8); - uint16_t op2 = oprom[2] | (oprom[3] << 8); + uint16_t op = opcodes.r16(pc); + uint16_t op2 = opcodes.r16(pc+1); // TODO: Test for previous "if CON" instruction and tab the next instruction in? @@ -582,5 +587,5 @@ CPU_DISASSEMBLE(dsp16a) } } - return opSize | dasmflags | DASMFLAG_SUPPORTED; + return opSize | dasmflags | SUPPORTED; } diff --git a/src/devices/cpu/dsp16/dsp16dis.h b/src/devices/cpu/dsp16/dsp16dis.h new file mode 100644 index 00000000000..9d5361e75ae --- /dev/null +++ b/src/devices/cpu/dsp16/dsp16dis.h @@ -0,0 +1,32 @@ +// license:BSD-3-Clause +// copyright-holders:Andrew Gardner + +#ifndef MAME_CPU_DSP16_DSP16DIS_H +#define MAME_CPU_DSP16_DSP16DIS_H + +#pragma once + +class dsp16a_disassembler : public util::disasm_interface +{ +public: + dsp16a_disassembler() = default; + virtual ~dsp16a_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + std::string disasmF1Field(const uint8_t& F1, const uint8_t& D, const uint8_t& S); + std::string disasmYField(const uint8_t& Y); + std::string disasmZField(const uint8_t& Z); + std::string disasmF2Field(const uint8_t& F2, const uint8_t& D, const uint8_t& S); + std::string disasmCONField(const uint8_t& CON); + std::string disasmBField(const uint8_t& B); + std::string disasmRImmediateField(const uint8_t& R); + std::string disasmRField(const uint8_t& R); + std::string disasmIField(const uint8_t& I); + bool disasmSIField(const uint8_t& SI); + +}; + +#endif diff --git a/src/devices/cpu/dsp32/dsp32.cpp b/src/devices/cpu/dsp32/dsp32.cpp index e91a0fddf29..e700edd0075 100644 --- a/src/devices/cpu/dsp32/dsp32.cpp +++ b/src/devices/cpu/dsp32/dsp32.cpp @@ -30,6 +30,7 @@ #include "emu.h" #include "dsp32.h" +#include "dsp32dis.h" #include "debugger.h" @@ -191,7 +192,7 @@ void dsp32c_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // register our state for the debugger state_add(STATE_GENPC, "GENPC", m_r[15]).noshow(); @@ -397,41 +398,17 @@ void dsp32c_device::state_string_export(const device_state_entry &entry, std::st //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t dsp32c_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t dsp32c_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t dsp32c_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *dsp32c_device::create_disassembler() { - extern CPU_DISASSEMBLE( dsp32c ); - return CPU_DISASSEMBLE_NAME(dsp32c)(this, stream, pc, oprom, opram, options); + return new dsp32c_disassembler; } - //************************************************************************** // MEMORY ACCESSORS //************************************************************************** diff --git a/src/devices/cpu/dsp32/dsp32.h b/src/devices/cpu/dsp32/dsp32.h index b11f5ad1d89..8f8ad369736 100644 --- a/src/devices/cpu/dsp32/dsp32.h +++ b/src/devices/cpu/dsp32/dsp32.h @@ -126,9 +126,7 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // memory accessors uint32_t ROPCODE(offs_t pc); @@ -423,7 +421,7 @@ protected: uint8_t m_lastpins; uint32_t m_ppc; address_space * m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; devcb_write32 m_output_pins_changed; // tables diff --git a/src/devices/cpu/dsp32/dsp32dis.cpp b/src/devices/cpu/dsp32/dsp32dis.cpp index 88399882df9..8748b2b55ab 100644 --- a/src/devices/cpu/dsp32/dsp32dis.cpp +++ b/src/devices/cpu/dsp32/dsp32dis.cpp @@ -9,7 +9,7 @@ ***************************************************************************/ #include "emu.h" -#include "dsp32.h" +#include "dsp32dis.h" /*************************************************************************** @@ -23,17 +23,17 @@ CODE CODE ***************************************************************************/ -static const char *const sizesuffix[] = { "", "e" }; -static const char *const unarysign[] = { "", "-" }; -static const char *const sign[] = { "+", "-" }; -static const char *const aMvals[] = { "a0", "a1", "a2", "a3", "0.0", "1.0", "Format 4", "Reserved" }; -static const char *const memsuffix[] = { "h", "l", "", "e" }; -static const char *const functable[] = +const char *const dsp32c_disassembler::sizesuffix[] = { "", "e" }; +const char *const dsp32c_disassembler::unarysign[] = { "", "-" }; +const char *const dsp32c_disassembler::sign[] = { "+", "-" }; +const char *const dsp32c_disassembler::aMvals[] = { "a0", "a1", "a2", "a3", "0.0", "1.0", "Format 4", "Reserved" }; +const char *const dsp32c_disassembler::memsuffix[] = { "h", "l", "", "e" }; +const char *const dsp32c_disassembler::functable[] = { "ic", "oc", "float", "int", "round", "ifalt", "ifaeq", "ifagt", "reserved8", "reserved9", "float24", "int24", "ieee", "dsp", "seed", "reservedf" }; -static const char *const condtable[] = +const char *const dsp32c_disassembler::condtable[] = { "false", "true", "pl", "mi", @@ -68,14 +68,14 @@ static const char *const condtable[] = "!?1e", "?1e", "!?1f", "?1f" }; -static const char *const regname[] = +const char *const dsp32c_disassembler::regname[] = { "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc", "0", "r15", "r16", "r17", "r18", "r19", "-1", "1", "r20", "r21", "dauc", "ioc", "res1c", "r22", "pcsh", "res1f" }; -static const char *const regnamee[] = +const char *const dsp32c_disassembler::regnamee[] = { "0", "r1e", "r2e", "r3e", "r4e", "r5e", "r6e", "r7e", "r8e", "r9e", "r10e", "r11e", "r12e", "r13e", "r14e", "pce", @@ -83,48 +83,39 @@ static const char *const regnamee[] = "r20e", "r21e", "dauce", "ioce", "res1ce", "r22e", "pcshe", "res1fe" }; -static inline char *signed_16bit_unary(int16_t val) +std::string dsp32c_disassembler::signed_16bit_unary(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "$%x", val); - return temp; + return util::string_format("$%x", val); } -static inline char *signed_16bit_sep(int16_t val) +std::string dsp32c_disassembler::signed_16bit_sep(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, " - $%x", -val); + return util::string_format(" - $%x", -val); else - sprintf(temp, " + $%x", val); - return temp; + return util::string_format(" + $%x", val); } -static inline char *signed_16bit_sep_nospace(int16_t val) +std::string dsp32c_disassembler::signed_16bit_sep_nospace(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "+$%x", val); - return temp; + return util::string_format("+$%x", val); } -static inline char *unsigned_16bit_size(int16_t val, uint8_t size) +std::string dsp32c_disassembler::unsigned_16bit_size(int16_t val, uint8_t size) { - static char temp[10]; if (size) - sprintf(temp, "$%06x", (int32_t)val & 0xffffff); + return util::string_format("$%06x", (int32_t)val & 0xffffff); else - sprintf(temp, "$%04x", val & 0xffff); - return temp; + return util::string_format("$%04x", val & 0xffff); } -static uint8_t lastp; -static std::string dasm_XYZ(uint8_t bits) +std::string dsp32c_disassembler::dasm_XYZ(uint8_t bits) { std::string buffer; uint8_t p = bits >> 3; @@ -164,7 +155,7 @@ static std::string dasm_XYZ(uint8_t bits) } -static std::string dasm_PI(uint16_t bits) +std::string dsp32c_disassembler::dasm_PI(uint16_t bits) { std::string buffer; uint8_t p = bits >> 5; @@ -199,10 +190,11 @@ static std::string dasm_PI(uint16_t bits) } -static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) +offs_t dsp32c_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; + uint32_t op = opcodes.r32(pc); switch (op >> 25) { /* DA format 1 */ @@ -344,7 +336,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) else { if (((op >> 16) & 0x1f) == 20) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; util::stream_format(stream, "goto %s", rH); } } @@ -359,7 +351,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) else { if (((op >> 16) & 0x1f) == 20) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; util::stream_format(stream, "if (%s) goto %s", condtable[C], rH); } } @@ -377,7 +369,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) { util::stream_format(stream, "if (%s-- >= 0) goto %s%s [%x]", rM, rH, signed_16bit_sep_nospace(N), (pc + 8 + N) & 0xffffff); if (((pc + 8 + N) & 0xffffff) < pc) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } else if (N && rH[0] != '0') util::stream_format(stream, "if (%s-- >= 0) goto %s%s", rM, rH, signed_16bit_sep_nospace(N)); @@ -385,13 +377,13 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) { util::stream_format(stream, "if (%s-- >= 0) goto $%x", rM, ((int32_t)N & 0xffffff)); if (((int32_t)N & 0xffffff) < pc) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } else { util::stream_format(stream, "if (%s-- >= 0) goto %s", rM, rH); if (((op >> 16) & 0x1f) == 20) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } break; } @@ -419,7 +411,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) util::stream_format(stream, "call $%x (%s)", ((int32_t)N & 0xffffff), rM); else util::stream_format(stream, "call %s (%s)", rH, rM); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -659,7 +651,7 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) else { if (((op >> 16) & 0x1f) == 20) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; util::stream_format(stream, "goto %s", rH); } break; @@ -685,20 +677,15 @@ static unsigned dasm_dsp32(std::ostream &stream, unsigned pc, uint32_t op) int32_t N = (op & 0xffff) | ((int32_t)((op & 0x1fe00000) << 3) >> 8); const char *rM = regname[(op >> 16) & 0x1f]; util::stream_format(stream, "call $%x (%s)", N & 0xffffff, rM); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } } - return 4 | flags | DASMFLAG_SUPPORTED; + return 4 | flags | SUPPORTED; } - -/*************************************************************************** - DISASSEMBLY HOOK -***************************************************************************/ - -CPU_DISASSEMBLE( dsp32c ) +uint32_t dsp32c_disassembler::opcode_alignment() const { - return dasm_dsp32(stream, pc, oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24)); + return 4; } diff --git a/src/devices/cpu/dsp32/dsp32dis.h b/src/devices/cpu/dsp32/dsp32dis.h new file mode 100644 index 00000000000..96a36de954c --- /dev/null +++ b/src/devices/cpu/dsp32/dsp32dis.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + dsp32dis.c + Disassembler for the portable AT&T/Lucent DSP32C emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_DSP32_DSP32DIS_H +#define MAME_CPU_DSP32_DSP32DIS_H + +#pragma once + +class dsp32c_disassembler : public util::disasm_interface +{ +public: + dsp32c_disassembler() = default; + virtual ~dsp32c_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const sizesuffix[]; + static const char *const unarysign[]; + static const char *const sign[]; + static const char *const aMvals[]; + static const char *const memsuffix[]; + static const char *const functable[]; + static const char *const condtable[]; + static const char *const regname[]; + static const char *const regnamee[]; + std::string signed_16bit_unary(int16_t val); + std::string signed_16bit_sep(int16_t val); + std::string signed_16bit_sep_nospace(int16_t val); + std::string unsigned_16bit_size(int16_t val, uint8_t size); + std::string dasm_XYZ(uint8_t bits); + std::string dasm_PI(uint16_t bits); + + uint8_t lastp; +}; + +#endif diff --git a/src/devices/cpu/dsp56k/dsp56dsm.cpp b/src/devices/cpu/dsp56k/dsp56dsm.cpp index 5ca4aab30a0..847a4bda6a0 100644 --- a/src/devices/cpu/dsp56k/dsp56dsm.cpp +++ b/src/devices/cpu/dsp56k/dsp56dsm.cpp @@ -10,22 +10,25 @@ #include "emu.h" #include "opcode.h" +#include "dsp56dsm.h" -#include "emu.h" -#include "dsp56k.h" +u32 dsp56k_disassembler::opcode_alignment() const +{ + return 1; +} /*****************************/ /* Main disassembly function */ /*****************************/ -CPU_DISASSEMBLE(dsp56k) +offs_t dsp56k_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint16_t w0 = oprom[0] | (oprom[1] << 8); - const uint16_t w1 = oprom[2] | (oprom[3] << 8); + const uint16_t w0 = opcodes.r16(pc); + const uint16_t w1 = opcodes.r16(pc+1); // Decode and disassemble. DSP56K::Opcode op(w0, w1); stream << op.disassemble(); const unsigned size = op.size(); - return (size | DASMFLAG_SUPPORTED); + return (size | SUPPORTED); } diff --git a/src/devices/cpu/dsp56k/dsp56dsm.h b/src/devices/cpu/dsp56k/dsp56dsm.h new file mode 100644 index 00000000000..3e0f7cb87ff --- /dev/null +++ b/src/devices/cpu/dsp56k/dsp56dsm.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Andrew Gardner +/*************************************************************************** + + dsp56dsm.c + Disassembler for the portable Motorola/Freescale dsp56k emulator. + Written by Andrew Gardner + +***************************************************************************/ + +#ifndef MAME_CPU_DSP56K_DSP56DSM_H +#define MAME_CPU_DSP56K_DSP56DSM_H + +#pragma once + +class dsp56k_disassembler : public util::disasm_interface +{ +public: + dsp56k_disassembler() = default; + virtual ~dsp56k_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/dsp56k/dsp56k.cpp b/src/devices/cpu/dsp56k/dsp56k.cpp index c84948701ef..132ccb55c98 100644 --- a/src/devices/cpu/dsp56k/dsp56k.cpp +++ b/src/devices/cpu/dsp56k/dsp56k.cpp @@ -33,6 +33,7 @@ #include "emu.h" #include "dsp56k.h" +#include "dsp56dsm.h" #include "opcode.h" @@ -289,7 +290,7 @@ void dsp56k_device::device_start() save_item(NAME(m_dsp56k_core.peripheral_ram)); m_dsp56k_core.program = &space(AS_PROGRAM); - m_dsp56k_core.direct = &m_dsp56k_core.program->direct(); + m_dsp56k_core.direct = m_dsp56k_core.program->direct<-1>(); m_dsp56k_core.data = &space(AS_DATA); state_add(DSP56K_PC, "PC", m_dsp56k_core.PCU.pc).formatstr("%04X"); @@ -463,9 +464,9 @@ static size_t execute_one_new(dsp56k_core* cpustate) cpustate->ppc = PC; debugger_instruction_hook(cpustate->device, PC); - cpustate->op = ROPCODE(ADDRESS(PC)); - uint16_t w0 = ROPCODE(ADDRESS(PC)); - uint16_t w1 = ROPCODE(ADDRESS(PC) + ADDRESS(1)); + cpustate->op = ROPCODE(PC); + uint16_t w0 = ROPCODE(PC); + uint16_t w1 = ROPCODE(PC + 1); Opcode op(w0, w1); op.evaluate(cpustate); @@ -503,9 +504,9 @@ void dsp56k_device::execute_run() } -offs_t dsp56k_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *dsp56k_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(dsp56k)(this, stream, pc, oprom, opram, options); + return new dsp56k_disassembler; } } // namespace DSP56K diff --git a/src/devices/cpu/dsp56k/dsp56k.h b/src/devices/cpu/dsp56k/dsp56k.h index 4ab93b9b9ca..43e94e60442 100644 --- a/src/devices/cpu/dsp56k/dsp56k.h +++ b/src/devices/cpu/dsp56k/dsp56k.h @@ -192,7 +192,7 @@ struct dsp56k_core void (*output_pins_changed)(uint32_t pins); cpu_device *device; address_space *program; - direct_read_data *direct; + direct_read_data<-1> *direct; address_space *data; uint16_t peripheral_ram[0x40]; @@ -235,9 +235,7 @@ protected: 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 2; } - 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -256,6 +254,4 @@ private: DECLARE_DEVICE_TYPE_NS(DSP56156, DSP56K, dsp56k_device) using DSP56K::dsp56k_device; -extern CPU_DISASSEMBLE( dsp56k ); - #endif // MAME_CPU_DSP56K_DSP56K_H diff --git a/src/devices/cpu/dsp56k/dsp56ops.hxx b/src/devices/cpu/dsp56k/dsp56ops.hxx index 0c898e7c674..a7815da5a4d 100644 --- a/src/devices/cpu/dsp56k/dsp56ops.hxx +++ b/src/devices/cpu/dsp56k/dsp56ops.hxx @@ -42,7 +42,6 @@ struct typed_pointer char data_type; }; -//#define ADDRESS(X) (X<<1) #define BITS(CUR,MASK) (Dsp56kOpMask(CUR,MASK)) /*********************/ @@ -243,10 +242,10 @@ static void execute_one(dsp56k_core* cpustate) cpustate->ppc = PC; debugger_instruction_hook(cpustate->device, PC); - cpustate->op = ROPCODE(ADDRESS(PC)); + cpustate->op = ROPCODE(PC); /* The words we're going to be working with */ - op = ROPCODE(ADDRESS(PC)); - op2 = ROPCODE(ADDRESS(PC) + ADDRESS(1)); + op = ROPCODE(PC); + op2 = ROPCODE(PC + 1); /* DECODE */ @@ -2308,7 +2307,7 @@ static size_t dsp56k_op_bfop(dsp56k_core* cpustate, const uint16_t op, const uin decode_BBB_bitmask(cpustate, BITS(op2,0xe000), &iVal); workAddr = assemble_address_from_Pppppp_table(cpustate, BITS(op,0x0020), BITS(op,0x001f)); - previousValue = cpustate->data->read_word(ADDRESS(workAddr)); + previousValue = cpustate->data->read_word(workAddr); workingWord = previousValue; switch(BITS(op2, 0x1f00)) @@ -2332,7 +2331,7 @@ static size_t dsp56k_op_bfop(dsp56k_core* cpustate, const uint16_t op, const uin tempTP.addr = &workingWord; tempTP.data_type = DT_WORD; - SetDataMemoryValue(cpustate, tempTP, ADDRESS(workAddr)); + SetDataMemoryValue(cpustate, tempTP, workAddr); /* S L E U N Z V C */ /* - * - - - - - ? */ @@ -2374,7 +2373,7 @@ static size_t dsp56k_op_bfop_1(dsp56k_core* cpustate, const uint16_t op, const u decode_RR_table(cpustate, BITS(op,0x0003), &R); workAddr = *((uint16_t*)R.addr); - previousValue = cpustate->data->read_word(ADDRESS(workAddr)); + previousValue = cpustate->data->read_word(workAddr); workingWord = previousValue; switch(BITS(op2, 0x1f00)) @@ -2398,7 +2397,7 @@ static size_t dsp56k_op_bfop_1(dsp56k_core* cpustate, const uint16_t op, const u tempTP.addr = &workingWord; tempTP.data_type = DT_WORD; - SetDataMemoryValue(cpustate, tempTP, ADDRESS(workAddr)); + SetDataMemoryValue(cpustate, tempTP, workAddr); /* S L E U N Z V C */ /* - * - - - - - ? */ @@ -3112,7 +3111,7 @@ static size_t dsp56k_op_jsr(dsp56k_core* cpustate, const uint16_t op, const uint PC += 2; /* TODO: This is a hacky implementation of Long vs Fast Interrupts. Do it right someday! */ - if (PC < ADDRESS(0x40)) + if (PC < 0x80) { /* Long interrupt gets the previous PC, not the current one */ SP++; @@ -3265,7 +3264,7 @@ static size_t dsp56k_op_movec(dsp56k_core* cpustate, const uint16_t op, uint8_t* if (W) { /* Write D */ - uint16_t value = cpustate->data->read_word(ADDRESS(*((uint16_t*)R.addr))) ; + uint16_t value = cpustate->data->read_word(*((uint16_t*)R.addr)) ; typed_pointer temp_src = { &value, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -3273,7 +3272,7 @@ static size_t dsp56k_op_movec(dsp56k_core* cpustate, const uint16_t op, uint8_t* { /* Read S */ uint16_t dataMemOffset = *((uint16_t*)R.addr); - SetDataMemoryValue(cpustate, SD, ADDRESS(dataMemOffset)); + SetDataMemoryValue(cpustate, SD, dataMemOffset); } execute_MM_table(cpustate, BITS(op,0x0003), BITS(op,0x000c)); @@ -3307,7 +3306,7 @@ static size_t dsp56k_op_movec_1(dsp56k_core* cpustate, const uint16_t op, uint8_ if (W) { /* Write D */ - uint16_t tempData = cpustate->data->read_word(ADDRESS(memOffset)); + uint16_t tempData = cpustate->data->read_word(memOffset); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -3316,7 +3315,7 @@ static size_t dsp56k_op_movec_1(dsp56k_core* cpustate, const uint16_t op, uint8_ /* Read S */ uint16_t tempData = *((uint16_t*)SD.addr); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; - SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset)); + SetDataMemoryValue(cpustate, temp_src, memOffset); } /* S L E U N Z V C */ @@ -3351,7 +3350,7 @@ static size_t dsp56k_op_movec_2(dsp56k_core* cpustate, const uint16_t op, uint8_ if (W) { /* Write D */ - uint16_t tempData = cpustate->data->read_word(ADDRESS(memOffset)); + uint16_t tempData = cpustate->data->read_word(memOffset); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -3360,7 +3359,7 @@ static size_t dsp56k_op_movec_2(dsp56k_core* cpustate, const uint16_t op, uint8_ /* Read S */ uint16_t tempData = *((uint16_t*)SD.addr); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; - SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset)); + SetDataMemoryValue(cpustate, temp_src, memOffset); } @@ -3402,7 +3401,7 @@ static size_t dsp56k_op_movec_3(dsp56k_core* cpustate, const uint16_t op, const else { /* 16-bit long address */ - uint16_t tempD = cpustate->data->read_word(ADDRESS(op2)); + uint16_t tempD = cpustate->data->read_word(op2); typed_pointer tempTP = {&tempD, DT_WORD}; SetDestinationValue(tempTP, SD); } @@ -3418,7 +3417,7 @@ static size_t dsp56k_op_movec_3(dsp56k_core* cpustate, const uint16_t op, const else { /* 16-bit long address */ - SetDataMemoryValue(cpustate, SD, ADDRESS(op2)); + SetDataMemoryValue(cpustate, SD, op2); } } @@ -3480,7 +3479,7 @@ static size_t dsp56k_op_movec_5(dsp56k_core* cpustate, const uint16_t op, const if (W) { /* Write D */ - uint16_t tempData = cpustate->data->read_word(ADDRESS(memOffset)); + uint16_t tempData = cpustate->data->read_word(memOffset); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -3489,7 +3488,7 @@ static size_t dsp56k_op_movec_5(dsp56k_core* cpustate, const uint16_t op, const /* Read S */ uint16_t tempData = *((uint16_t*)SD.addr); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; - SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset)); + SetDataMemoryValue(cpustate, temp_src, memOffset); } /* S L E U N Z V C */ @@ -3543,7 +3542,7 @@ static size_t dsp56k_op_movem(dsp56k_core* cpustate, const uint16_t op, uint8_t* { /* Read from Program Memory */ typed_pointer data; - uint16_t ldata = cpustate->program->read_word(ADDRESS(*((uint16_t*)R.addr))); + uint16_t ldata = cpustate->program->read_word(*((uint16_t*)R.addr)); data.addr = &ldata; data.data_type = DT_WORD; @@ -3552,7 +3551,7 @@ static size_t dsp56k_op_movem(dsp56k_core* cpustate, const uint16_t op, uint8_t* else { /* Write to Program Memory */ - SetProgramMemoryValue(cpustate, SD, ADDRESS(*((uint16_t*)R.addr))) ; + SetProgramMemoryValue(cpustate, SD, *((uint16_t*)R.addr)) ; } execute_MM_table(cpustate, BITS(op,0x00c0), BITS(op,0x0018)); @@ -3597,7 +3596,7 @@ static size_t dsp56k_op_movep(dsp56k_core* cpustate, const uint16_t op, uint8_t* if (W) { - uint16_t data = cpustate->data->read_word(ADDRESS(pp)); + uint16_t data = cpustate->data->read_word(pp); typed_pointer tempTP; tempTP.addr = &data; @@ -3607,7 +3606,7 @@ static size_t dsp56k_op_movep(dsp56k_core* cpustate, const uint16_t op, uint8_t* } else { - SetDataMemoryValue(cpustate, SD, ADDRESS(pp)); + SetDataMemoryValue(cpustate, SD, pp); } /* S L E U N Z V C */ @@ -3636,13 +3635,13 @@ static size_t dsp56k_op_movep_1(dsp56k_core* cpustate, const uint16_t op, uint8_ /* A little different than most W if's - opposite read and write */ if (W) { - uint16_t data = cpustate->data->read_word(ADDRESS(*((uint16_t*)SD.addr))); + uint16_t data = cpustate->data->read_word(*((uint16_t*)SD.addr)); typed_pointer tempTP; tempTP.addr = &data; tempTP.data_type = DT_WORD; - SetDataMemoryValue(cpustate, tempTP, ADDRESS(pp)); + SetDataMemoryValue(cpustate, tempTP, pp); } else { @@ -3770,7 +3769,7 @@ static size_t dsp56k_op_rep_1(dsp56k_core* cpustate, const uint16_t op, uint8_t* LC = iVal; cpustate->repFlag = 1; - cpustate->repAddr = PC + ADDRESS(1); + cpustate->repAddr = PC + 2; cycles += 4; /* TODO: + mv oscillator clock cycles */ } @@ -3806,7 +3805,7 @@ static size_t dsp56k_op_rep_2(dsp56k_core* cpustate, const uint16_t op, uint8_t* LC = repValue; cpustate->repFlag = 1; - cpustate->repAddr = PC + ADDRESS(1); + cpustate->repAddr = PC + 2; cycles += 4; /* TODO: + mv oscillator clock cycles */ } @@ -4663,7 +4662,7 @@ static void execute_x_memory_data_move(dsp56k_core* cpustate, const uint16_t op, if (W) { /* From X:<ea> to SD */ - uint16_t data = cpustate->data->read_word(ADDRESS(*((uint16_t*)R.addr))); + uint16_t data = cpustate->data->read_word(*((uint16_t*)R.addr)); typed_pointer tempTP; tempTP.addr = &data; @@ -4681,11 +4680,11 @@ static void execute_x_memory_data_move(dsp56k_core* cpustate, const uint16_t op, tempTP.addr = prev_accum_value; tempTP.data_type = DT_LONG_WORD; - SetDataMemoryValue(cpustate, tempTP, ADDRESS(*((uint16_t*)R.addr))) ; + SetDataMemoryValue(cpustate, tempTP, *((uint16_t*)R.addr)) ; } else { - SetDataMemoryValue(cpustate, SD, ADDRESS(*((uint16_t*)R.addr))) ; + SetDataMemoryValue(cpustate, SD, *((uint16_t*)R.addr)) ; } } @@ -4711,14 +4710,14 @@ static void execute_x_memory_data_move2(dsp56k_core* cpustate, const uint16_t op if (W) { /* Write D */ - uint16_t value = cpustate->data->read_word(ADDRESS(*mem_offset)); + uint16_t value = cpustate->data->read_word(*mem_offset); typed_pointer tempV = {&value, DT_WORD}; SetDestinationValue(tempV, SD); } else { /* Read S */ - SetDataMemoryValue(cpustate, SD, ADDRESS(*mem_offset)); + SetDataMemoryValue(cpustate, SD, *mem_offset); } } @@ -4739,7 +4738,7 @@ static void execute_x_memory_data_move_with_short_displacement(dsp56k_core* cpus if (W) { /* Write D */ - uint16_t tempData = cpustate->data->read_word(ADDRESS(memOffset)); + uint16_t tempData = cpustate->data->read_word(memOffset); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; SetDestinationValue(temp_src, SD); } @@ -4748,7 +4747,7 @@ static void execute_x_memory_data_move_with_short_displacement(dsp56k_core* cpus /* Read S */ uint16_t tempData = *((uint16_t*)SD.addr); typed_pointer temp_src = { (void*)&tempData, DT_WORD }; - SetDataMemoryValue(cpustate, temp_src, ADDRESS(memOffset)); + SetDataMemoryValue(cpustate, temp_src, memOffset); } } @@ -4775,13 +4774,13 @@ static void execute_dual_x_memory_data_read(dsp56k_core* cpustate, const uint16_ fatalerror("Dsp56k: Unimplemented access to external X Data Memory >= 0xffc0 in Dual X Memory Data Read.\n"); /* First memmove */ - srcVal1 = cpustate->data->read_word(ADDRESS(*((uint16_t*)R.addr))); + srcVal1 = cpustate->data->read_word(*((uint16_t*)R.addr)); tempV.addr = &srcVal1; tempV.data_type = DT_WORD; SetDestinationValue(tempV, D1); /* Second memmove */ - srcVal2 = cpustate->data->read_word(ADDRESS(R3)); + srcVal2 = cpustate->data->read_word(R3); tempV.addr = &srcVal2; tempV.data_type = DT_WORD; SetDestinationValue(tempV, D2); diff --git a/src/devices/cpu/dsp56k/inst.h b/src/devices/cpu/dsp56k/inst.h index 91a624f030a..d2db2a013e9 100644 --- a/src/devices/cpu/dsp56k/inst.h +++ b/src/devices/cpu/dsp56k/inst.h @@ -15,7 +15,6 @@ // namespace DSP56K { -#define ADDRESS(X) ((X)<<1) #define UNIMPLEMENTED_OPCODE() osd_printf_error("Unimplemented opcode: PC=%04x | %s;\n", PC, __PRETTY_FUNCTION__); class Opcode; @@ -759,7 +758,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 2; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: op_mnem m_mnem; @@ -790,7 +789,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: op_mnem m_mnem; @@ -821,7 +820,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 2; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: int16_t m_immediate; @@ -847,7 +846,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } }; // CHKAAU : 0000 0000 0000 0100 : A-58 ///////////////////////////////////////// @@ -1597,7 +1596,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 2; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: op_mnem m_mnem; @@ -1628,7 +1627,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: op_mnem m_mnem; @@ -1658,7 +1657,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 2; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: uint16_t m_displacement; @@ -1688,7 +1687,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } private: uint8_t m_bAddr; @@ -1714,7 +1713,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OVER; } + size_t flags() const override { return util::disasm_interface::STEP_OVER; } }; // LEA : 0000 0001 11TT MMRR : A-116 /////////////////////////////////////////// @@ -3236,7 +3235,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OUT; } + size_t flags() const override { return util::disasm_interface::STEP_OUT; } }; // RTS : 0000 0000 0000 0110 : A-196 /////////////////////////////////////////// @@ -3258,7 +3257,7 @@ public: void evaluate(dsp56k_core* cpustate) override {} size_t size() const override { return 1; } size_t accumulatorBitsModified() const override { return BM_HIGH | BM_MIDDLE | BM_LOW; } - size_t flags() const override { return DASMFLAG_STEP_OUT; } + size_t flags() const override { return util::disasm_interface::STEP_OUT; } }; // SBC : .... .... 0101 F01J : A-198 /////////////////////////////////////////// diff --git a/src/devices/cpu/e0c6200/e0c6200.cpp b/src/devices/cpu/e0c6200/e0c6200.cpp index ad4e99ba8c6..4deadeb6bff 100644 --- a/src/devices/cpu/e0c6200/e0c6200.cpp +++ b/src/devices/cpu/e0c6200/e0c6200.cpp @@ -20,6 +20,7 @@ #include "emu.h" #include "e0c6200.h" +#include "e0c6200d.h" #include "debugger.h" @@ -49,10 +50,9 @@ void e0c6200_cpu_device::state_string_export(const device_state_entry &entry, st } } -offs_t e0c6200_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *e0c6200_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(e0c6200); - return CPU_DISASSEMBLE_NAME(e0c6200)(this, stream, pc, oprom, opram, options); + return new e0c6200_disassembler; } @@ -211,7 +211,7 @@ void e0c6200_cpu_device::execute_run() // fetch next opcode debugger_instruction_hook(this, m_pc); - m_op = m_program->read_word(m_pc << 1) & 0xfff; + m_op = m_program->read_word(m_pc) & 0xfff; m_pc = (m_pc & 0x1000) | ((m_pc + 1) & 0x0fff); // minimal opcode time is 5 clock cycles, opcodes take 5, 7, or 12 clock cycles diff --git a/src/devices/cpu/e0c6200/e0c6200.h b/src/devices/cpu/e0c6200/e0c6200.h index 2a8c02734ec..9328aed7cf1 100644 --- a/src/devices/cpu/e0c6200/e0c6200.h +++ b/src/devices/cpu/e0c6200/e0c6200.h @@ -34,9 +34,8 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 2; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; address_space_config m_program_config; diff --git a/src/devices/cpu/e0c6200/e0c6200d.cpp b/src/devices/cpu/e0c6200/e0c6200d.cpp index fde754ef051..be2a4ea4d6d 100644 --- a/src/devices/cpu/e0c6200/e0c6200d.cpp +++ b/src/devices/cpu/e0c6200/e0c6200d.cpp @@ -7,21 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "e0c6200.h" +#include "e0c6200d.h" -// opcode mnemonics -enum e_mnemonics -{ - em_JP, em_RETD, em_CALL, em_CALZ, - em_LD, em_LBPX, em_ADC, em_CP, em_ADD, em_SUB, em_SBC, em_AND, em_OR, em_XOR, - em_RLC, em_FAN, em_PSET, em_LDPX, em_LDPY, em_SET, em_RST, em_INC, em_DEC, - em_RRC, em_ACPX, em_ACPY, em_SCPX, em_SCPY, em_PUSH, em_POP, - em_RETS, em_RET, em_JPBA, em_HALT, em_SLP, em_NOP5, em_NOP7, - em_NOT, em_SCF, em_SZF, em_SDF, em_EI, em_DI, em_RDF, em_RZF, em_RCF, em_ILL -}; - -static const char *const em_name[] = +const char *const e0c6200_disassembler::em_name[] = { "JP", "RETD", "CALL", "CALZ", "LD", "LBPX", "ADC", "CP", "ADD", "SUB", "SBC", "AND", "OR", "XOR", @@ -31,32 +19,20 @@ static const char *const em_name[] = "NOT", "SCF", "SZF", "SDF", "EI", "DI", "RDF", "RZF", "RCF", "?" }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 em_flags[] = +const u32 e0c6200_disassembler::em_flags[] = { - 0, _OUT, _OVER, _OVER, + 0, STEP_OUT, STEP_OVER, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - _OUT, _OUT, 0, _OVER, _OVER, 0, 0, + STEP_OUT, STEP_OUT, 0, STEP_OVER, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -// opcode params -enum e_params -{ - ep_S, ep_E, ep_I, ep_R0, ep_R2, ep_R4, ep_Q, - ep_cC, ep_cNC, ep_cZ, ep_cNZ, - ep_A, ep_B, ep_X, ep_Y, ep_MX, ep_MY, ep_XP, ep_XH, ep_XL, ep_YP, ep_YH, ep_YL, - ep_P, ep_F, ep_MN, ep_SP, ep_SPH, ep_SPL -}; - // 0-digit is number of bits per opcode parameter, 0 bits is literal, // 0x10-digit is for shift-right, 0x100-digit is special flag for r/q param -static const u16 ep_bits[] = +const u16 e0c6200_disassembler::ep_bits[] = { 8, 8, 4, 0x102, 0x122, 0x142, 0x102, 0, 0, 0, 0, @@ -65,10 +41,10 @@ static const u16 ep_bits[] = }; // redirect for r/q param -static const u8 ep_redirect_r[4] = { ep_A, ep_B, ep_MX, ep_MY }; +const u8 e0c6200_disassembler::ep_redirect_r[4] = { ep_A, ep_B, ep_MX, ep_MY }; // literal opcode parameter -static const char *const ep_name[] = +const char *const e0c6200_disassembler::ep_name[] = { " ", " ", " ", " ", " ", " ", " ", "C", "NC", "Z", "NZ", @@ -77,7 +53,7 @@ static const char *const ep_name[] = }; -static char* decode_param(u16 opcode, int param, char* buffer) +std::string e0c6200_disassembler::decode_param(u16 opcode, int param) { int bits = ep_bits[param] & 0xf; int shift = ep_bits[param] >> 4 & 0xf; @@ -89,30 +65,22 @@ static char* decode_param(u16 opcode, int param, char* buffer) // literal param if (ep_bits[param] == 0) - { - strcpy(buffer, ep_name[param]); - return buffer; - } + return ep_name[param]; // print value like how it's documented in the manual - char val[10]; - if (bits > 4 || opmask > 9) - sprintf(val, "%02XH", opmask); - else - sprintf(val, "%d", opmask); + std::string val = (bits > 4 || opmask > 9) ? + util::string_format("%02XH", opmask) : + util::string_format("%d", opmask); if (param == ep_MN) - sprintf(buffer, "M%s", val); + return 'M' + val; else - strcpy(buffer, val); - - return buffer; + return val; } - -CPU_DISASSEMBLE(e0c6200) +offs_t e0c6200_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u16 op = (oprom[1] | oprom[0] << 8) & 0xfff; + u16 op = opcodes.r16(pc) & 0xfff; int m; int p1 = -1; @@ -693,15 +661,34 @@ CPU_DISASSEMBLE(e0c6200) util::stream_format(stream, "%-6s", em_name[m]); // fetch param(s) - char pbuffer[10]; if (p1 != -1) { - util::stream_format(stream, "%s", decode_param(op, p1, pbuffer)); + util::stream_format(stream, "%s", decode_param(op, p1)); if (p2 != -1) { - util::stream_format(stream, ",%s", decode_param(op, p2, pbuffer)); + util::stream_format(stream, ",%s", decode_param(op, p2)); } } - return 1 | em_flags[m] | DASMFLAG_SUPPORTED; + return 1 | em_flags[m] | SUPPORTED; +} + +u32 e0c6200_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 e0c6200_disassembler::interface_flags() const +{ + return PAGED2LEVEL; +} + +u32 e0c6200_disassembler::page_address_bits() const +{ + return 8; +} + +u32 e0c6200_disassembler::page2_address_bits() const +{ + return 4; } diff --git a/src/devices/cpu/e0c6200/e0c6200d.h b/src/devices/cpu/e0c6200/e0c6200d.h new file mode 100644 index 00000000000..d2555c4ead8 --- /dev/null +++ b/src/devices/cpu/e0c6200/e0c6200d.h @@ -0,0 +1,55 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Seiko Epson E0C6200 disassembler + +*/ + +#ifndef MAME_CPU_E0C6200_E0C6200D_H +#define MAME_CPU_E0C6200_E0C6200D_H + +#pragma once + +class e0c6200_disassembler : public util::disasm_interface +{ +public: + e0c6200_disassembler() = default; + virtual ~e0c6200_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual u32 page2_address_bits() const override; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + em_JP, em_RETD, em_CALL, em_CALZ, + em_LD, em_LBPX, em_ADC, em_CP, em_ADD, em_SUB, em_SBC, em_AND, em_OR, em_XOR, + em_RLC, em_FAN, em_PSET, em_LDPX, em_LDPY, em_SET, em_RST, em_INC, em_DEC, + em_RRC, em_ACPX, em_ACPY, em_SCPX, em_SCPY, em_PUSH, em_POP, + em_RETS, em_RET, em_JPBA, em_HALT, em_SLP, em_NOP5, em_NOP7, + em_NOT, em_SCF, em_SZF, em_SDF, em_EI, em_DI, em_RDF, em_RZF, em_RCF, em_ILL + }; + + enum e_params + { + ep_S, ep_E, ep_I, ep_R0, ep_R2, ep_R4, ep_Q, + ep_cC, ep_cNC, ep_cZ, ep_cNZ, + ep_A, ep_B, ep_X, ep_Y, ep_MX, ep_MY, ep_XP, ep_XH, ep_XL, ep_YP, ep_YH, ep_YL, + ep_P, ep_F, ep_MN, ep_SP, ep_SPH, ep_SPL + }; + + static const char *const em_name[]; + static const u32 em_flags[]; + static const u16 ep_bits[]; + static const u8 ep_redirect_r[4]; + static const char *const ep_name[]; + + std::string decode_param(u16 opcode, int param); +}; + +#endif diff --git a/src/devices/cpu/e132xs/32xsdasm.cpp b/src/devices/cpu/e132xs/32xsdasm.cpp index ec853983346..339c7b9c0b0 100644 --- a/src/devices/cpu/e132xs/32xsdasm.cpp +++ b/src/devices/cpu/e132xs/32xsdasm.cpp @@ -8,13 +8,11 @@ */ #include "emu.h" -#include "e132xs.h" -#include "debugger.h" - +#include "32xsdasm.h" #include "32xsdefs.h" -static const char *const L_REG[] = +const char *const hyperstone_disassembler::L_REG[] = { "L0", "L1", "L2", "L3", "L4", "L5", "L6", "L7", "L8", "L9", "L10", "L11", "L12", "L13", "L14", "L15", "L16", "L17", "L18", "L19", @@ -25,7 +23,7 @@ static const char *const L_REG[] = "L60", "L61", "L62", "L63" }; -static const char *const G_REG[] = +const char *const hyperstone_disassembler::G_REG[] = { "PC", "SR", "FER", "G03", "G04", "G05", "G06", "G07", "G08", "G09", "G10", "G11", "G12", "G13", "G14", "G15", "G16", "G17", "SP", "UB", @@ -33,7 +31,7 @@ static const char *const G_REG[] = "G30", "G31" }; -static const char *const SETxx[] = +const char *const hyperstone_disassembler::SETxx[] = { "SETADR", "Reserved", "SET1", "SET0", "SETLE", "SETGT", "SETLT", "SETGE", "SETSE", "SETHT", "SETST", "SETHE", "SETE", "SETNE", "SETV", "SETNV", @@ -49,20 +47,13 @@ static const char *const SETxx[] = #define N_VALUE(op) ((((op & 0x100) >> 8) << 4 ) | (op & 0x0f)) -static int size, global_fp; - -static offs_t base_pc; -static const uint8_t *base_oprom; -#define READ_OP_DASM(p) ((base_oprom[(p) - base_pc] << 8) | base_oprom[(p) + 1 - base_pc]) - - -static void LL_format(char *source, char *dest, uint16_t op) +void hyperstone_disassembler::LL_format(char *source, char *dest, uint16_t op) { strcpy(source, L_REG[(SOURCECODE(op)+global_fp)%64]); strcpy(dest, L_REG[(DESTCODE(op)+global_fp)%64]); } -static void LR_format(char *source, char *dest, uint16_t op) +void hyperstone_disassembler::LR_format(char *source, char *dest, uint16_t op) { if( SOURCEBIT(op) ) { @@ -76,7 +67,7 @@ static void LR_format(char *source, char *dest, uint16_t op) strcpy(dest, L_REG[(DESTCODE(op)+global_fp)%64]); } -static void RR_format(char *source, char *dest, uint16_t op, unsigned h_flag) +void hyperstone_disassembler::RR_format(char *source, char *dest, uint16_t op, unsigned h_flag) { if( SOURCEBIT(op) ) { @@ -97,7 +88,7 @@ static void RR_format(char *source, char *dest, uint16_t op, unsigned h_flag) } } -static uint32_t LRconst_format(char *source, char *dest, uint16_t op, unsigned *pc) +uint32_t hyperstone_disassembler::LRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes) { uint16_t next_op; uint32_t const_val; @@ -115,8 +106,8 @@ static uint32_t LRconst_format(char *source, char *dest, uint16_t op, unsigned * size = 4; - *pc += 2; - next_op = READ_OP_DASM(*pc); + pc += 2; + next_op = opcodes.r16(pc); if( E_BIT(next_op) ) { @@ -124,8 +115,8 @@ static uint32_t LRconst_format(char *source, char *dest, uint16_t op, unsigned * size = 6; - *pc += 2; - next_op2 = READ_OP_DASM(*pc); + pc += 2; + next_op2 = opcodes.r16(pc); const_val = next_op2; const_val |= ((next_op & 0x3fff) << 16 ); @@ -147,7 +138,7 @@ static uint32_t LRconst_format(char *source, char *dest, uint16_t op, unsigned * return const_val; } -static uint32_t RRconst_format(char *source, char *dest, uint16_t op, unsigned *pc) +uint32_t hyperstone_disassembler::RRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes) { uint16_t next_op; uint32_t const_val; @@ -172,8 +163,8 @@ static uint32_t RRconst_format(char *source, char *dest, uint16_t op, unsigned * size = 4; - *pc += 2; - next_op = READ_OP_DASM(*pc); + pc += 2; + next_op = opcodes.r16(pc); if( E_BIT(next_op) ) { @@ -181,8 +172,8 @@ static uint32_t RRconst_format(char *source, char *dest, uint16_t op, unsigned * size = 6; - *pc += 2; - next_op2 = READ_OP_DASM(*pc); + pc += 2; + next_op2 = opcodes.r16(pc); const_val = next_op2; const_val |= ((next_op & 0x3fff) << 16 ); @@ -204,7 +195,7 @@ static uint32_t RRconst_format(char *source, char *dest, uint16_t op, unsigned * return const_val; } -static int32_t Rimm_format(char *dest, uint16_t op, unsigned *pc, unsigned h_flag) +int32_t hyperstone_disassembler::Rimm_format(char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes, unsigned h_flag) { uint16_t imm1, imm2; int32_t ret; @@ -227,10 +218,10 @@ static int32_t Rimm_format(char *dest, uint16_t op, unsigned *pc, unsigned h_fla return n; case 17: - *pc += 2; - imm1 = READ_OP_DASM(*pc); - *pc += 2; - imm2 = READ_OP_DASM(*pc); + pc += 2; + imm1 = opcodes.r16(pc); + pc += 2; + imm2 = opcodes.r16(pc); ret = (imm1 << 16) | imm2; size = 6; @@ -238,15 +229,15 @@ static int32_t Rimm_format(char *dest, uint16_t op, unsigned *pc, unsigned h_fla case 18: - *pc += 2; - ret = READ_OP_DASM(*pc); + pc += 2; + ret = opcodes.r16(pc); size = 4; return ret; case 19: - *pc += 2; - ret = (int32_t) (0xffff0000 | READ_OP_DASM(*pc)); + pc += 2; + ret = (int32_t) (0xffff0000 | opcodes.r16(pc)); size = 4; return ret; @@ -292,14 +283,14 @@ static int32_t Rimm_format(char *dest, uint16_t op, unsigned *pc, unsigned h_fla } } -static uint8_t Ln_format(char *dest, uint16_t op) +uint8_t hyperstone_disassembler::Ln_format(char *dest, uint16_t op) { strcpy(dest, L_REG[(DESTCODE(op)+global_fp)%64]); return N_VALUE(op); } -static uint8_t Rn_format(char *dest, uint16_t op) +uint8_t hyperstone_disassembler::Rn_format(char *dest, uint16_t op) { if( DESTBIT(op) ) { @@ -313,7 +304,7 @@ static uint8_t Rn_format(char *dest, uint16_t op) return N_VALUE(op); } -static int32_t PCrel_format(uint16_t op, unsigned pc) +int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes) { int32_t ret; @@ -325,7 +316,7 @@ static int32_t PCrel_format(uint16_t op, unsigned pc) pc += 2; - next = READ_OP_DASM(pc); + next = opcodes.r16(pc); ret = (op & 0x7f) << 16; @@ -345,7 +336,7 @@ static int32_t PCrel_format(uint16_t op, unsigned pc) return (pc + ret); } -static uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, unsigned pc) +uint32_t hyperstone_disassembler::RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes) { uint32_t ret; @@ -373,7 +364,7 @@ static uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t nex size = 6; - next = READ_OP_DASM(pc + 4); + next = opcodes.r16(pc + 4); ret = next; ret |= ( ( next_op & 0xfff ) << 16 ); @@ -395,31 +386,36 @@ static uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t nex return ret; } -unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom, unsigned h_flag, int private_fp) +u32 hyperstone_disassembler::opcode_alignment() const { - uint16_t op; - uint8_t op_num; + return 2; +} - uint8_t source_code, dest_code, source_bit, dest_bit; +hyperstone_disassembler::hyperstone_disassembler(config *conf) : m_config(conf) +{ +} +/*****************************/ +/* Main disassembly function */ +/*****************************/ +offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ char source[5] = "\0", dest[5] = "\0"; uint32_t flags = 0; - base_pc = pc; - base_oprom = oprom; - - op = READ_OP_DASM(pc); + uint16_t op = opcodes.r16(pc); size = 2; - source_code = SOURCECODE(op); - dest_code = DESTCODE(op); - source_bit = SOURCEBIT(op); - dest_bit = DESTBIT(op); + uint8_t source_code = SOURCECODE(op); + uint8_t dest_code = DESTCODE(op); + uint8_t source_bit = SOURCEBIT(op); + uint8_t dest_bit = DESTBIT(op); - global_fp = private_fp; + global_fp = m_config->get_fp(); + int h_flag = m_config->get_h(); - op_num = (op & 0xff00) >> 8; + uint8_t op_num = (op & 0xff00) >> 8; switch( op_num ) { @@ -456,7 +452,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom global_fp = 0; RR_format(source, dest, op, 0); util::stream_format(stream, "RET PC, %s", source); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } else if( source_code == SR_REGISTER && !source_bit ) { @@ -495,7 +491,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom size = 4; pc += 2; - op = READ_OP_DASM(pc); + op = opcodes.r16(pc); xcode = X_CODE(op); @@ -510,7 +506,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom size = 6; pc += 2; - next_op = READ_OP_DASM(pc); + next_op = opcodes.r16(pc); lim = ((op & 0xfff) << 16) | next_op; } @@ -533,7 +529,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // MASK case 0x14: case 0x15: case 0x16: case 0x17: { - uint32_t const_val = RRconst_format(source, dest, op, &pc); + uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); util::stream_format(stream, "MASK %s, %s, $%x", dest, source, const_val); @@ -543,7 +539,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // SUM case 0x18: case 0x19: case 0x1a: case 0x1b: { - uint32_t const_val = RRconst_format(source, dest, op, &pc); + uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); if( source_code == SR_REGISTER && !source_bit ) { @@ -560,7 +556,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // SUMS case 0x1c: case 0x1d: case 0x1e: case 0x1f: { - uint32_t const_val = RRconst_format(source, dest, op, &pc); + uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes); if( source_code == SR_REGISTER && !source_bit ) { @@ -778,7 +774,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // CMPI case 0x60: case 0x61: case 0x62: case 0x63: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); util::stream_format(stream, "CMPI %s, $%x", dest, imm); @@ -788,7 +784,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // MOVI case 0x64: case 0x65: case 0x66: case 0x67: { - uint32_t imm = Rimm_format(dest, op, &pc, h_flag); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, h_flag); util::stream_format(stream, "MOVI %s, $%x", dest, imm); @@ -798,7 +794,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // ADDI case 0x68: case 0x69: case 0x6a: case 0x6b: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); if( !N_VALUE(op) ) { @@ -815,7 +811,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // ADDSI case 0x6c: case 0x6d: case 0x6e: case 0x6f: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); if( !N_VALUE(op) ) { @@ -832,7 +828,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // CMPBI case 0x70: case 0x71: case 0x72: case 0x73: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); if( !N_VALUE(op) ) { @@ -852,7 +848,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // ANDNI case 0x74: case 0x75: case 0x76: case 0x77: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); if( N_VALUE(op) == 31 ) imm = 0x7fffffff; //bit 31 = 0, others = 1 @@ -865,7 +861,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // ORI case 0x78: case 0x79: case 0x7a: case 0x7b: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); util::stream_format(stream, "ORI %s, $%x", dest, imm); @@ -875,7 +871,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // XORI case 0x7c: case 0x7d: case 0x7e: case 0x7f: { - uint32_t imm = Rimm_format(dest, op, &pc, 0); + uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0); util::stream_format(stream, "XORI %s, $%x", dest, imm); @@ -995,8 +991,8 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // LDxx.D/A/IOD/IOA case 0x90: case 0x91: case 0x92: case 0x93: { - uint16_t next_op = READ_OP_DASM(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc); + uint16_t next_op = opcodes.r16(pc + 2); + uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); if( size == 2 ) size = 4; @@ -1113,8 +1109,8 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // LDxx.N/S case 0x94: case 0x95: case 0x96: case 0x97: { - uint16_t next_op = READ_OP_DASM(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc); + uint16_t next_op = opcodes.r16(pc + 2); + uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); if( size == 2 ) size = 4; @@ -1182,8 +1178,8 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // STxx.D/A/IOD/IOA case 0x98: case 0x99: case 0x9a: case 0x9b: { - uint16_t next_op = READ_OP_DASM(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc); + uint16_t next_op = opcodes.r16(pc + 2); + uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); if( size == 2 ) size = 4; @@ -1303,8 +1299,8 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // STxx.N/S case 0x9c: case 0x9d: case 0x9e: case 0x9f: { - uint16_t next_op = READ_OP_DASM(pc + 2); - uint32_t dis = RRdis_format(source, dest, op, next_op, pc); + uint16_t next_op = opcodes.r16(pc + 2); + uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes); if( size == 2 ) size = 4; @@ -1584,7 +1580,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom LL_format(source, dest, op); pc += 2; - extended_op = READ_OP_DASM(pc); + extended_op = opcodes.r16(pc); size = 4; @@ -1752,10 +1748,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBV case 0xe0: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBV $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1763,10 +1759,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBNV case 0xe1: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBNV $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1774,10 +1770,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBE case 0xe2: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBE $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1785,10 +1781,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBNE case 0xe3: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBNE $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1796,10 +1792,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBC case 0xe4: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBC $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1807,10 +1803,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBNC case 0xe5: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBNC $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1818,10 +1814,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBSE case 0xe6: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBSE $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1829,10 +1825,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBHT case 0xe7: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBHT $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1840,10 +1836,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBN case 0xe8: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBN $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1851,10 +1847,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBNN case 0xe9: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBNN $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1862,10 +1858,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBLE case 0xea: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBLE $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1873,10 +1869,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBGT case 0xeb: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBGT $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1884,10 +1880,10 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // DBR case 0xec: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "DBR $%x", rel); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } @@ -1905,17 +1901,17 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // CALL case 0xee: case 0xef: { - uint32_t const_val = LRconst_format(source, dest, op, &pc); + uint32_t const_val = LRconst_format(source, dest, op, pc, opcodes); if( source_code == SR_REGISTER && !source_bit ) { util::stream_format(stream, "CALL %s, 0, $%x", dest, const_val); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } else { util::stream_format(stream, "CALL %s, %s, $%x", dest, source, const_val); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } break; @@ -1924,7 +1920,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BV case 0xf0: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BV $%x", rel); @@ -1934,7 +1930,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BNV case 0xf1: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BNV $%x", rel); @@ -1944,7 +1940,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BE case 0xf2: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BE $%x", rel); @@ -1954,7 +1950,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BNE case 0xf3: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BNE $%x", rel); @@ -1964,7 +1960,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BC case 0xf4: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BC $%x", rel); @@ -1974,7 +1970,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BNC case 0xf5: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BNC $%x", rel); @@ -1984,7 +1980,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BSE case 0xf6: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BSE $%x", rel); @@ -1994,7 +1990,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BHT case 0xf7: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BHT $%x", rel); @@ -2004,7 +2000,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BN case 0xf8: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BN $%x", rel); @@ -2014,7 +2010,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BNN case 0xf9: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BNN $%x", rel); @@ -2024,7 +2020,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BLE case 0xfa: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BLE $%x", rel); @@ -2034,7 +2030,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BGT case 0xfb: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BGT $%x", rel); @@ -2044,7 +2040,7 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom // BR case 0xfc: { - int32_t rel = PCrel_format(op, pc) + 2; + int32_t rel = PCrel_format(op, pc, opcodes) + 2; util::stream_format(stream, "BR $%x", rel); @@ -2061,73 +2057,73 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom { case TRAPLE: util::stream_format(stream, "TRAPLE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPGT: util::stream_format(stream, "TRAPGT %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPLT: util::stream_format(stream, "TRAPLT %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPGE: util::stream_format(stream, "TRAPGE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPSE: util::stream_format(stream, "TRAPSE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPHT: util::stream_format(stream, "TRAPHT %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPST: util::stream_format(stream, "TRAPST %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPHE: util::stream_format(stream, "TRAPHE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPE: util::stream_format(stream, "TRAPE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPNE: util::stream_format(stream, "TRAPNE %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAPV: util::stream_format(stream, "TRAPV %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case TRAP: util::stream_format(stream, "TRAP %d", trapno); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } @@ -2136,10 +2132,5 @@ unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom } } - return size | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE( hyperstone_generic ) -{ - return dasm_hyperstone( stream, pc, oprom, 0, 0 ); + return size | flags | SUPPORTED; } diff --git a/src/devices/cpu/e132xs/32xsdasm.h b/src/devices/cpu/e132xs/32xsdasm.h new file mode 100644 index 00000000000..0ee99457c55 --- /dev/null +++ b/src/devices/cpu/e132xs/32xsdasm.h @@ -0,0 +1,53 @@ +// license:BSD-3-Clause +// copyright-holders:Pierpaolo Prazzoli +/* + + Hyperstone disassembler + written by Pierpaolo Prazzoli + +*/ + +#ifndef MAME_CPU_E132XS_32XSDASM_H +#define MAME_CPU_E132XS_32XSDASM_H + +#pragma once + +class hyperstone_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + + virtual u8 get_fp() const = 0; + virtual bool get_h() const = 0; + }; + + hyperstone_disassembler(config *conf); + virtual ~hyperstone_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const L_REG[]; + static const char *const G_REG[]; + static const char *const SETxx[]; + + config *m_config; + + int size; + u8 global_fp; + + void LL_format(char *source, char *dest, uint16_t op); + void LR_format(char *source, char *dest, uint16_t op); + void RR_format(char *source, char *dest, uint16_t op, unsigned h_flag); + uint32_t LRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes); + uint32_t RRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes); + int32_t Rimm_format(char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes, unsigned h_flag); + uint8_t Ln_format(char *dest, uint16_t op); + uint8_t Rn_format(char *dest, uint16_t op); + int32_t PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes); + uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes); +}; + +#endif diff --git a/src/devices/cpu/e132xs/32xsdefs.h b/src/devices/cpu/e132xs/32xsdefs.h index 164377f0060..86b0018b909 100644 --- a/src/devices/cpu/e132xs/32xsdefs.h +++ b/src/devices/cpu/e132xs/32xsdefs.h @@ -9,10 +9,13 @@ #define PC_REGISTER 0 #define SR_REGISTER 1 +#define SP_REGISTER 18 +#define UB_REGISTER 19 #define BCR_REGISTER 20 #define TPR_REGISTER 21 #define TCR_REGISTER 22 #define TR_REGISTER 23 +#define WCR_REGISTER 24 #define ISR_REGISTER 25 #define FCR_REGISTER 26 #define MCR_REGISTER 27 @@ -39,10 +42,6 @@ #define EHCFFTD 0x096 #define EHCFFTSD 0x296 -/* Delay values */ -#define NO_DELAY 0 -#define DELAY_EXECUTE 1 - /* IRQ numbers */ #define IRQ_INT1 0 #define IRQ_INT2 1 @@ -55,15 +54,15 @@ /* Trap numbers */ #define TRAPNO_IO2 48 #define TRAPNO_IO1 49 -#define TRAPNO_INT4 50 -#define TRAPNO_INT3 51 -#define TRAPNO_INT2 52 -#define TRAPNO_INT1 53 +#define TRAPNO_INT4 50 +#define TRAPNO_INT3 51 +#define TRAPNO_INT2 52 +#define TRAPNO_INT1 53 #define TRAPNO_IO3 54 #define TRAPNO_TIMER 55 #define TRAPNO_RESERVED1 56 #define TRAPNO_TRACE_EXCEPTION 57 -#define TRAPNO_PARITY_ERROR 58 +#define TRAPNO_PARITY_ERROR 58 #define TRAPNO_EXTENDED_OVERFLOW 59 #define TRAPNO_RANGE_ERROR 60 #define TRAPNO_PRIVILEGE_ERROR TRAPNO_RANGE_ERROR @@ -93,4 +92,122 @@ #define E132XS_ENTRY_IRAM 3 #define E132XS_ENTRY_MEM3 7 +/* Memory access */ +/* read byte */ +#define READ_B(addr) m_program->read_byte((addr)) +/* read half-word */ +#define READ_HW(addr) m_program->read_word((addr) & ~1) +/* read word */ +#define READ_W(addr) m_program->read_dword((addr) & ~3) + +/* write byte */ +#define WRITE_B(addr, data) m_program->write_byte(addr, data) +/* write half-word */ +#define WRITE_HW(addr, data) m_program->write_word((addr) & ~1, data) +/* write word */ +#define WRITE_W(addr, data) m_program->write_dword((addr) & ~3, data) + + +/* I/O access */ +/* read word */ +#define IO_READ_W(addr) m_io->read_dword(((addr) >> 11) & 0x7ffc) +/* write word */ +#define IO_WRITE_W(addr, data) m_io->write_dword(((addr) >> 11) & 0x7ffc, data) + + +#define READ_OP(addr) m_direct->read_word((addr), m_opcodexor) + +// set C in adds/addsi/subs/sums +#define SETCARRYS 0 +#define MISSIONCRAFT_FLAGS 1 + +/* Registers */ + +/* Internal registers */ + +#define OP m_op +#define PC m_global_regs[0] //Program Counter +#define SR m_global_regs[1] //Status Register +#define FER m_global_regs[2] //Floating-Point Exception Register +// 03 - 15 General Purpose Registers +// 16 - 17 Reserved +#define SP m_global_regs[18] //Stack Pointer +#define UB m_global_regs[19] //Upper Stack Bound +#define BCR m_global_regs[20] //Bus Control Register +#define TPR m_global_regs[21] //Timer Prescaler Register +#define TCR m_global_regs[22] //Timer Compare Register +#define TR compute_tr() //Timer Register +#define WCR m_global_regs[24] //Watchdog Compare Register +#define ISR m_global_regs[25] //Input Status Register +#define FCR m_global_regs[26] //Function Control Register +#define MCR m_global_regs[27] //Memory Control Register +// 28 - 31 Reserved + +#define C_MASK 0x00000001 +#define Z_MASK 0x00000002 +#define N_MASK 0x00000004 +#define V_MASK 0x00000008 +#define M_MASK 0x00000010 +#define H_MASK 0x00000020 +#define I_MASK 0x00000080 +#define L_MASK 0x00008000 +#define T_MASK 0x00010000 +#define P_MASK 0x00020000 +#define S_MASK 0x00040000 +#define ILC_MASK 0x00180000 + +#define S_SHIFT 18 + +/* SR flags */ +#define GET_C ( SR & C_MASK) // bit 0 //CARRY +#define GET_Z ((SR & Z_MASK)>>1) // bit 1 //ZERO +#define GET_N ((SR & N_MASK)>>2) // bit 2 //NEGATIVE +#define GET_V ((SR & V_MASK)>>3) // bit 3 //OVERFLOW +#define GET_M ((SR & M_MASK)>>4) // bit 4 //CACHE-MODE +#define GET_H ((SR & H_MASK)>>5) // bit 5 //HIGHGLOBAL +// bit 6 RESERVED (always 0) +#define GET_I ((SR & I_MASK)>>7) // bit 7 //INTERRUPT-MODE +#define GET_FTE ((SR & 0x00001f00)>>8) // bits 12 - 8 //Floating-Point Trap Enable +#define GET_FRM ((SR & 0x00006000)>>13) // bits 14 - 13 //Floating-Point Rounding Mode +#define GET_L ((SR & L_MASK)>>15) // bit 15 //INTERRUPT-LOCK +#define GET_T ((SR & T_MASK)>>16) // bit 16 //TRACE-MODE +#define GET_P ((SR & P_MASK)>>17) // bit 17 //TRACE PENDING +#define GET_S ((SR & S_MASK)>>18) // bit 18 //SUPERVISOR STATE +#define GET_ILC ((SR & 0x00180000)>>19) // bits 20 - 19 //INSTRUCTION-LENGTH +/* if FL is zero it is always interpreted as 16 */ +#define GET_FL m_fl_lut[((SR >> 21) & 0xf)] // bits 24 - 21 //FRAME LENGTH +#define GET_FP ((SR & 0xfe000000)>>25) // bits 31 - 25 //FRAME POINTER + +#define SET_C(val) (SR = (SR & ~C_MASK) | (val)) +#define SET_Z(val) (SR = (SR & ~Z_MASK) | ((val) << 1)) +#define SET_N(val) (SR = (SR & ~N_MASK) | ((val) << 2)) +#define SET_V(val) (SR = (SR & ~V_MASK) | ((val) << 3)) +#define SET_M(val) (SR = (SR & ~M_MASK) | ((val) << 4)) +#define SET_H(val) (SR = (SR & ~H_MASK) | ((val) << 5)) +#define SET_I(val) (SR = (SR & ~I_MASK) | ((val) << 7)) +#define SET_FTE(val) (SR = (SR & ~0x00001f00) | ((val) << 8)) +#define SET_FRM(val) (SR = (SR & ~0x00006000) | ((val) << 13)) +#define SET_L(val) (SR = (SR & ~L_MASK) | ((val) << 15)) +#define SET_T(val) (SR = (SR & ~T_MASK) | ((val) << 16)) +#define SET_P(val) (SR = (SR & ~P_MASK) | ((val) << 17)) +#define SET_S(val) (SR = (SR & ~S_MASK) | ((val) << 18)) +#define SET_ILC(val) (SR = (SR & 0xffe7ffff) | (val)) +#define SET_FL(val) (SR = (SR & ~0x01e00000) | ((val) << 21)) +#define SET_FP(val) (SR = (SR & ~0xfe000000) | ((val) << 25)) + +#define SET_PC(val) PC = ((val) & 0xfffffffe) //PC(0) = 0 +#define SET_SP(val) SP = ((val) & 0xfffffffc) //SP(0) = SP(1) = 0 +#define SET_UB(val) UB = ((val) & 0xfffffffc) //UB(0) = UB(1) = 0 + +#define SET_LOW_SR(val) (SR = (SR & 0xffff0000) | ((val) & 0x0000ffff)) // when SR is addressed, only low 16 bits can be changed + + +/* FER flags */ +#define GET_ACCRUED (FER & 0x0000001f) //bits 4 - 0 //Floating-Point Accrued Exceptions +#define GET_ACTUAL (FER & 0x00001f00) //bits 12 - 8 //Floating-Point Actual Exceptions +//other bits are reversed, in particular 7 - 5 for the operating system. +//the user program can only change the above 2 flags + + #endif // MAME_CPU_E132XS_XS32DEFS_H + diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp index bfd8de0fc9a..d22d84aead2 100644 --- a/src/devices/cpu/e132xs/e132xs.cpp +++ b/src/devices/cpu/e132xs/e132xs.cpp @@ -32,6 +32,7 @@ TODO: - some wrong cycle counts + - verify register wrapping with sregf/dregf on hardware CHANGELOG: @@ -101,10 +102,6 @@ Pierpaolo Prazzoli - Same fix in get_const - Ryan Holtz - 02/27/04 - - Fixed delayed branching - - const_val for CALL should always have bit 0 clear - Pierpaolo Prazzoli - 02/25/04 - Fixed some wrong addresses to address local registers instead of memory - Fixed FRAME and RET instruction @@ -133,177 +130,31 @@ (From the doc: A Call, Trap or Software instruction increments the FP and sets FL to 6, thus creating a new stack frame with the length of 6 registers). - Ryan Holtz - 10/25/03 - - Fixed CALL enough that it at least jumps to the right address, no word - yet as to whether or not it's working enough to return. - - Added get_lrconst() to get the const value for the CALL operand, since - apparently using immediate_value() was wrong. The code is ugly, but it - works properly. Vampire 1/2 now gets far enough to try to test its RAM. - - Just from looking at it, CALL apparently doesn't frame properly. I'm not - sure about FRAME, but perhaps it doesn't work properly - I'm not entirely - positive. The return address when vamphalf's memory check routine is - called at FFFFFD7E is stored in register L8, and then the RET instruction - at the end of the routine uses L1 as the return address, so that might - provide some clues as to how it works. - - I'd almost be willing to bet money that there's no framing at all since - the values in L0 - L15 as displayed by the debugger would change during a - CALL or FRAME operation. I'll look when I'm in the mood. - - The mood struck me, and I took a look at SET_L_REG and GET_L_REG. - Apparently no matter what the current frame pointer is they'll always use - local_regs[0] through local_regs[15]. - - Ryan Holtz - 08/20/03 - - Added H flag support for MOV and MOVI - - Changed init routine to set S flag on boot. Apparently the CPU defaults to - supervisor mode as opposed to user mode when it powers on, as shown by the - vamphalf power-on routines. Makes sense, too, since if the machine booted - in user mode, it would be impossible to get into supervisor mode. - Pierpaolo Prazzoli - 08/19/03 - Added check for D_BIT and S_BIT where PC or SR must or must not be denoted. (movd, divu, divs, ldxx1, ldxx2, stxx1, stxx2, mulu, muls, set, mul call, chk) - Ryan Holtz - 08/17/03 - - Working on support for H flag, nothing quite done yet - - Added trap Range Error for CHK PC, PC - - Fixed relative jumps, they have to be taken from the opcode following the - jump instead of the jump opcode itself. - Pierpaolo Prazzoli - 08/17/03 - Fixed get_pcrel() when OP & 0x80 is set. - Decremented PC by 2 also in MOV, ADD, ADDI, SUM, SUB and added the check if D_BIT is not set. (when pc is changed they are implicit branch) - Ryan Holtz - 08/17/03 - - Implemented a crude hack to set FL in the SR to 6, since according to the docs - that's supposed to happen each time a trap occurs, apparently including when - the processor starts up. The 3rd opcode executed in vamphalf checks to see if - the FL flag in SR 6, so it's apparently the "correct" behaviour despite the - docs not saying anything on it. If FL is not 6, the branch falls through and - encounters a CHK PC, L2, which at that point will always throw a range trap. - The range trap vector contains 00000000 (CHK PC, PC), which according to the - docs will always throw a range trap (which would effectively lock the system). - This revealed a bug: CHK PC, PC apparently does not throw a range trap, which - needs to be fixed. Now that the "correct" behaviour is hacked in with the FL - flags, it reveals yet another bug in that the branch is interpreted as being - +0x8700. This means that the PC then wraps around to 000082B0, give or take - a few bytes. While it does indeed branch to valid code, I highly doubt that - this is the desired effect. Check for signed/unsigned relative branch, maybe? - - Ryan Holtz - 08/16/03 - - Fixed the debugger at least somewhat so that it displays hex instead of decimal, - and so that it disassembles opcodes properly. - - Fixed hyperstone_execute() to increment PC *after* executing the opcode instead of - before. This is probably why vamphalf was booting to fffffff8, but executing at - fffffffa instead. - - Changed execute_trap to decrement PC by 2 so that the next opcode isn't skipped - after a trap - - Changed execute_br to decrement PC by 2 so that the next opcode isn't skipped - after a branch - - Changed hyperstone_movi to decrement PC by 2 when G0 (PC) is modified so that the - next opcode isn't skipped after a branch - - Changed hyperstone_movi to default to a uint32_t being moved into the register - as opposed to a uint8_t. This is wrong, the bit width is quite likely to be - dependent on the n field in the Rimm instruction type. However, vamphalf uses - MOVI G0,[FFFF]FBAC (n=$13) since there's apparently no absolute branch opcode. - What kind of CPU is this that it doesn't have an absolute jump in its branch - instructions and you have to use an immediate MOV to do an abs. jump!? - - Replaced usage of logerror() with smf's verboselog() - *********************************************************************/ #include "emu.h" #include "e132xs.h" +#include "e132xsfe.h" #include "debugger.h" #include "32xsdefs.h" -#ifdef MAME_DEBUG -#define DEBUG_PRINTF(x) do { osd_printf_debug x; } while (0) -#else -#define DEBUG_PRINTF(x) do { } while (0) -#endif - -/* Memory access */ -/* read byte */ -#define READ_B(addr) m_program->read_byte((addr)) -/* read half-word */ -#define READ_HW(addr) m_program->read_word((addr) & ~1) -/* read word */ -#define READ_W(addr) m_program->read_dword((addr) & ~3) - -/* write byte */ -#define WRITE_B(addr, data) m_program->write_byte(addr, data) -/* write half-word */ -#define WRITE_HW(addr, data) m_program->write_word((addr) & ~1, data) -/* write word */ -#define WRITE_W(addr, data) m_program->write_dword((addr) & ~3, data) - - -/* I/O access */ -/* read word */ -#define IO_READ_W(addr) m_io->read_dword(((addr) >> 11) & 0x7ffc) -/* write word */ -#define IO_WRITE_W(addr, data) m_io->write_dword(((addr) >> 11) & 0x7ffc, data) - - -#define READ_OP(addr) m_direct->read_word((addr), m_opcodexor) - -// set C in adds/addsi/subs/sums -#define SETCARRYS 0 -#define MISSIONCRAFT_FLAGS 1 - -/* Registers */ - -/* Internal registers */ - -#define SREG (decode)->src_value -#define SREGF (decode)->next_src_value -#define DREG (decode)->dst_value -#define DREGF (decode)->next_dst_value -#define EXTRA_U (decode)->extra.u -#define EXTRA_S (decode)->extra.s - -#define SET_SREG( _data_ ) ((decode)->src_is_local ? set_local_register((decode)->src, (uint32_t)_data_) : set_global_register((decode)->src, (uint32_t)_data_)) -#define SET_SREGF( _data_ ) ((decode)->src_is_local ? set_local_register((decode)->src + 1, (uint32_t)_data_) : set_global_register((decode)->src + 1, (uint32_t)_data_)) -#define SET_DREG( _data_ ) ((decode)->dst_is_local ? set_local_register((decode)->dst, (uint32_t)_data_) : set_global_register((decode)->dst, (uint32_t)_data_)) -#define SET_DREGF( _data_ ) ((decode)->dst_is_local ? set_local_register((decode)->dst + 1, (uint32_t)_data_) : set_global_register((decode)->dst + 1, (uint32_t)_data_)) - -#define SRC_IS_PC (!(decode)->src_is_local && (decode)->src == PC_REGISTER) -#define DST_IS_PC (!(decode)->dst_is_local && (decode)->dst == PC_REGISTER) -#define SRC_IS_SR (!(decode)->src_is_local && (decode)->src == SR_REGISTER) -#define DST_IS_SR (!(decode)->dst_is_local && (decode)->dst == SR_REGISTER) -#define SAME_SRC_DST (decode)->same_src_dst -#define SAME_SRC_DSTF (decode)->same_src_dstf -#define SAME_SRCF_DST (decode)->same_srcf_dst - - -/* Memory access */ -/* read byte */ -#define READ_B(addr) m_program->read_byte((addr)) -/* read half-word */ -#define READ_HW(addr) m_program->read_word((addr) & ~1) -/* read word */ -#define READ_W(addr) m_program->read_dword((addr) & ~3) - -/* write byte */ -#define WRITE_B(addr, data) m_program->write_byte(addr, data) -/* write half-word */ -#define WRITE_HW(addr, data) m_program->write_word((addr) & ~1, data) -/* write word */ -#define WRITE_W(addr, data) m_program->write_dword((addr) & ~3, data) - - -/* I/O access */ -/* read word */ -#define IO_READ_W(addr) m_io->read_dword(((addr) >> 11) & 0x7ffc) -/* write word */ -#define IO_WRITE_W(addr, data) m_io->write_dword(((addr) >> 11) & 0x7ffc, data) - +//#define VERBOSE 1 +#include "logmacro.h" -#define READ_OP(addr) m_direct->read_word((addr), m_opcodexor) +/* size of the execution code cache */ +#define CACHE_SIZE (32 * 1024 * 1024) //************************************************************************** // INTERNAL ADDRESS MAP @@ -348,14 +199,32 @@ ADDRESS_MAP_END hyperstone_device::hyperstone_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, uint32_t prg_data_width, uint32_t io_data_width, address_map_constructor internal_map) - : cpu_device(mconfig, type, tag, owner, clock), - m_program_config("program", ENDIANNESS_BIG, prg_data_width, 32, 0, internal_map), - m_io_config("io", ENDIANNESS_BIG, io_data_width, 15), - m_icount(0) + : cpu_device(mconfig, type, tag, owner, clock) + , m_program_config("program", ENDIANNESS_BIG, prg_data_width, 32, 0, internal_map) + , m_io_config("io", ENDIANNESS_BIG, io_data_width, 15) + , m_icount(0) + , m_cache(CACHE_SIZE + sizeof(hyperstone_device)) + , m_drcuml(nullptr) + , m_drcfe(nullptr) + , m_drcoptions(0) + , m_cache_dirty(0) + , m_entry(nullptr) + , m_nocode(nullptr) + , m_out_of_cycles(nullptr) + , m_drc_arg0(0) + , m_drc_arg1(0) + , m_drc_arg2(0) + , m_drc_arg3(0) + , m_mem_read8(nullptr) + , m_mem_write8(nullptr) + , m_mem_read16(nullptr) + , m_mem_write16(nullptr) + , m_mem_read32(nullptr) + , m_mem_write32(nullptr) + , m_io_read32(nullptr) + , m_io_write32(nullptr) + , m_enable_drc(false) { - // build the opcode table - for (int op = 0; op < 256; op++) - m_opcode[op] = s_opcodetable[op]; } @@ -530,130 +399,35 @@ uint32_t hyperstone_device::get_emu_code_addr(uint8_t num) /* num is OP */ return addr; } -void hyperstone_device::hyperstone_set_trap_entry(int which) -{ - switch( which ) - { - case E132XS_ENTRY_MEM0: - m_trap_entry = 0x00000000; - break; - - case E132XS_ENTRY_MEM1: - m_trap_entry = 0x40000000; - break; - - case E132XS_ENTRY_MEM2: - m_trap_entry = 0x80000000; - break; - - case E132XS_ENTRY_MEM3: - m_trap_entry = 0xffffff00; - break; - - case E132XS_ENTRY_IRAM: - m_trap_entry = 0xc0000000; - break; - - default: - DEBUG_PRINTF(("Set entry point to a reserved value: %d\n", which)); - break; - } -} +/*static*/ const uint32_t hyperstone_device::s_trap_entries[8] = { + 0x00000000, // MEM0 + 0x40000000, // MEM1 + 0x80000000, // MEM2 + 0xc0000000, // IRAM + 0, + 0, + 0, + 0xffffff00, // MEM3 +}; -#define OP m_op -#define PPC m_ppc //previous pc -#define PC m_global_regs[0] //Program Counter -#define SR m_global_regs[1] //Status Register -#define FER m_global_regs[2] //Floating-Point Exception Register -// 03 - 15 General Purpose Registers -// 16 - 17 Reserved -#define SP m_global_regs[18] //Stack Pointer -#define UB m_global_regs[19] //Upper Stack Bound -#define BCR m_global_regs[20] //Bus Control Register -#define TPR m_global_regs[21] //Timer Prescaler Register -#define TCR m_global_regs[22] //Timer Compare Register -#define TR compute_tr() //Timer Register -#define WCR m_global_regs[24] //Watchdog Compare Register -#define ISR m_global_regs[25] //Input Status Register -#define FCR m_global_regs[26] //Function Control Register -#define MCR m_global_regs[27] //Memory Control Register -// 28 - 31 Reserved - -/* SR flags */ -#define GET_C ( SR & 0x00000001) // bit 0 //CARRY -#define GET_Z ((SR & 0x00000002)>>1) // bit 1 //ZERO -#define GET_N ((SR & 0x00000004)>>2) // bit 2 //NEGATIVE -#define GET_V ((SR & 0x00000008)>>3) // bit 3 //OVERFLOW -#define GET_M ((SR & 0x00000010)>>4) // bit 4 //CACHE-MODE -#define GET_H ((SR & 0x00000020)>>5) // bit 5 //HIGHGLOBAL -// bit 6 RESERVED (always 0) -#define GET_I ((SR & 0x00000080)>>7) // bit 7 //INTERRUPT-MODE -#define GET_FTE ((SR & 0x00001f00)>>8) // bits 12 - 8 //Floating-Point Trap Enable -#define GET_FRM ((SR & 0x00006000)>>13) // bits 14 - 13 //Floating-Point Rounding Mode -#define GET_L ((SR & 0x00008000)>>15) // bit 15 //INTERRUPT-LOCK -#define GET_T ((SR & 0x00010000)>>16) // bit 16 //TRACE-MODE -#define GET_P ((SR & 0x00020000)>>17) // bit 17 //TRACE PENDING -#define GET_S ((SR & 0x00040000)>>18) // bit 18 //SUPERVISOR STATE -#define GET_ILC ((SR & 0x00180000)>>19) // bits 20 - 19 //INSTRUCTION-LENGTH -/* if FL is zero it is always interpreted as 16 */ -#define GET_FL ((SR & 0x01e00000) ? ((SR & 0x01e00000)>>21) : 16) // bits 24 - 21 //FRAME LENGTH -#define GET_FP ((SR & 0xfe000000)>>25) // bits 31 - 25 //FRAME POINTER - -#define SET_C(val) (SR = (SR & ~0x00000001) | (val)) -#define SET_Z(val) (SR = (SR & ~0x00000002) | ((val) << 1)) -#define SET_N(val) (SR = (SR & ~0x00000004) | ((val) << 2)) -#define SET_V(val) (SR = (SR & ~0x00000008) | ((val) << 3)) -#define SET_M(val) (SR = (SR & ~0x00000010) | ((val) << 4)) -#define SET_H(val) (SR = (SR & ~0x00000020) | ((val) << 5)) -#define SET_I(val) (SR = (SR & ~0x00000080) | ((val) << 7)) -#define SET_FTE(val) (SR = (SR & ~0x00001f00) | ((val) << 8)) -#define SET_FRM(val) (SR = (SR & ~0x00006000) | ((val) << 13)) -#define SET_L(val) (SR = (SR & ~0x00008000) | ((val) << 15)) -#define SET_T(val) (SR = (SR & ~0x00010000) | ((val) << 16)) -#define SET_P(val) (SR = (SR & ~0x00020000) | ((val) << 17)) -#define SET_S(val) (SR = (SR & ~0x00040000) | ((val) << 18)) -#define SET_ILC(val) (SR = (SR & ~0x00180000) | ((val) << 19)) -#define SET_FL(val) (SR = (SR & ~0x01e00000) | ((val) << 21)) -#define SET_FP(val) (SR = (SR & ~0xfe000000) | ((val) << 25)) - -#define SET_PC(val) PC = ((val) & 0xfffffffe) //PC(0) = 0 -#define SET_SP(val) SP = ((val) & 0xfffffffc) //SP(0) = SP(1) = 0 -#define SET_UB(val) UB = ((val) & 0xfffffffc) //UB(0) = UB(1) = 0 - -#define SET_LOW_SR(val) (SR = (SR & 0xffff0000) | ((val) & 0x0000ffff)) // when SR is addressed, only low 16 bits can be changed - - -#define CHECK_C(x) (SR = (SR & ~0x00000001) | (((x) & (((uint64_t)1) << 32)) ? 1 : 0 )) -#define CHECK_VADD(x,y,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & 0x80000000) ? 8: 0)) -#define CHECK_VADD3(x,y,w,z) (SR = (SR & ~0x00000008) | ((((x) ^ (z)) & ((y) ^ (z)) & ((w) ^ (z)) & 0x80000000) ? 8: 0)) -#define CHECK_VSUB(x,y,z) (SR = (SR & ~0x00000008) | ((((z) ^ (y)) & ((y) ^ (x)) & 0x80000000) ? 8: 0)) - - -/* FER flags */ -#define GET_ACCRUED (FER & 0x0000001f) //bits 4 - 0 //Floating-Point Accrued Exceptions -#define GET_ACTUAL (FER & 0x00001f00) //bits 12 - 8 //Floating-Point Actual Exceptions -//other bits are reversed, in particular 7 - 5 for the operating system. -//the user program can only changes the above 2 flags - - -uint32_t hyperstone_device::compute_tr() +void hyperstone_device::compute_tr() { uint64_t cycles_since_base = total_cycles() - m_tr_base_cycles; uint64_t clocks_since_base = cycles_since_base >> m_clck_scale; - return m_tr_base_value + (clocks_since_base / m_tr_clocks_per_tick); + m_tr_result = m_tr_base_value + (clocks_since_base / m_tr_clocks_per_tick); } void hyperstone_device::update_timer_prescale() { - uint32_t prevtr = compute_tr(); TPR &= ~0x80000000; m_clck_scale = (TPR >> 26) & m_clock_scale_mask; m_clock_cycles_1 = 1 << m_clck_scale; m_clock_cycles_2 = 2 << m_clck_scale; + m_clock_cycles_3 = 3 << m_clck_scale; m_clock_cycles_4 = 4 << m_clck_scale; m_clock_cycles_6 = 6 << m_clck_scale; m_tr_clocks_per_tick = ((TPR >> 16) & 0xff) + 2; - m_tr_base_value = prevtr; + m_tr_base_value = m_tr_result; m_tr_base_cycles = total_cycles(); } @@ -703,10 +477,13 @@ TIMER_CALLBACK_MEMBER( hyperstone_device::timer_callback ) /* update the values if necessary */ if (update) + { update_timer_prescale(); + } /* see if the timer is right for firing */ - if (!((compute_tr() - TCR) & 0x80000000)) + compute_tr(); + if (!((m_tr_result - TCR) & 0x80000000)) m_timer_int_pending = 1; /* adjust ourselves for the next time */ @@ -730,23 +507,23 @@ uint32_t hyperstone_device::get_global_register(uint8_t code) case 29: case 30: case 31: - DEBUG_PRINTF(("read _Reserved_ Global Register %d @ %08X\n",code,PC)); + LOG("read _Reserved_ Global Register %d @ %08X\n",code,PC); break; case BCR_REGISTER: - DEBUG_PRINTF(("read write-only BCR register @ %08X\n",PC)); + LOG("read write-only BCR register @ %08X\n",PC); return 0; case TPR_REGISTER: - DEBUG_PRINTF(("read write-only TPR register @ %08X\n",PC)); + LOG("read write-only TPR register @ %08X\n",PC); return 0; case FCR_REGISTER: - DEBUG_PRINTF(("read write-only FCR register @ %08X\n",PC)); + LOG("read write-only FCR register @ %08X\n",PC); return 0; case MCR_REGISTER: - DEBUG_PRINTF(("read write-only MCR register @ %08X\n",PC)); + LOG("read write-only MCR register @ %08X\n",PC); return 0; } } @@ -756,610 +533,278 @@ uint32_t hyperstone_device::get_global_register(uint8_t code) /* it is common to poll this in a loop */ if (m_icount > m_tr_clocks_per_tick / 2) m_icount -= m_tr_clocks_per_tick / 2; - return compute_tr(); + compute_tr(); + return m_tr_result; } - return m_global_regs[code]; + return m_global_regs[code & 0x1f]; } void hyperstone_device::set_local_register(uint8_t code, uint32_t val) { - uint8_t new_code = (code + GET_FP) % 64; - - m_local_regs[new_code] = val; + m_local_regs[(code + GET_FP) & 0x3f] = val; } void hyperstone_device::set_global_register(uint8_t code, uint32_t val) { //TODO: add correct FER set instruction - - if( code == PC_REGISTER ) - { - SET_PC(val); - } - else if( code == SR_REGISTER ) - { - SET_LOW_SR(val); // only a RET instruction can change the full content of SR - SR &= ~0x40; //reserved bit 6 always zero - if (m_intblock < 1) - m_intblock = 1; - } - else - { - uint32_t oldval = m_global_regs[code]; - if( code != ISR_REGISTER ) + code &= 0x1f; + switch (code) + { + case PC_REGISTER: + SET_PC(val); + return; + case SR_REGISTER: + SET_LOW_SR(val); // only a RET instruction can change the full content of SR + SR &= ~0x40; //reserved bit 6 always zero + if (m_intblock < 1) + m_intblock = 1; + return; + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + // are the below ones set only when privilege bit is set? + case 17: m_global_regs[code] = val; - else - DEBUG_PRINTF(("Written to ISR register. PC = %08X\n", PC)); - - //are these set only when privilege bit is set? - if( code >= 16 ) - { - switch( code ) + return; + case SP_REGISTER: + case UB_REGISTER: + m_global_regs[code] = val & ~3; + return; + case BCR_REGISTER: + m_global_regs[code] = val; + return; + case TPR_REGISTER: + m_global_regs[code] = val; + if (!(val & 0x80000000)) /* change immediately */ { - case 18: - SET_SP(val); - break; - - case 19: - SET_UB(val); - break; -/* - case ISR_REGISTER: - DEBUG_PRINTF(("written %08X to read-only ISR register\n",val)); - break; - - case TCR_REGISTER: -// DEBUG_PRINTF(("written %08X to TCR register\n",val)); - break; - - case 23: -// DEBUG_PRINTF(("written %08X to TR register\n",val)); - break; - - case 24: -// DEBUG_PRINTF(("written %08X to WCR register\n",val)); - break; - - case 16: - case 17: - case 28: - case 29: - case 30: - case 31: - DEBUG_PRINTF(("written %08X to _Reserved_ Global Register %d\n",val,code)); - break; - - case BCR_REGISTER: - break; -*/ - case TR_REGISTER: - m_tr_base_value = val; - m_tr_base_cycles = total_cycles(); - adjust_timer_interrupt(); - break; - - case TPR_REGISTER: - if (!(val & 0x80000000)) /* change immediately */ - update_timer_prescale(); + compute_tr(); + update_timer_prescale(); + } + adjust_timer_interrupt(); + return; + case TCR_REGISTER: + if (m_global_regs[code] != val) + { + m_global_regs[code] = val; adjust_timer_interrupt(); - break; - - case TCR_REGISTER: - if (oldval != val) - { - adjust_timer_interrupt(); - if (m_intblock < 1) - m_intblock = 1; - } - break; - - case FCR_REGISTER: - if ((oldval ^ val) & 0x00800000) - adjust_timer_interrupt(); if (m_intblock < 1) m_intblock = 1; - break; - - case MCR_REGISTER: - // bits 14..12 EntryTableMap - hyperstone_set_trap_entry((val & 0x7000) >> 12); - break; } + return; + case TR_REGISTER: + m_global_regs[code] = val; + m_tr_base_value = val; + m_tr_base_cycles = total_cycles(); + adjust_timer_interrupt(); + return; + case WCR_REGISTER: + m_global_regs[code] = val; + return; + case ISR_REGISTER: + return; + case FCR_REGISTER: + if ((m_global_regs[code] ^ val) & 0x00800000) + adjust_timer_interrupt(); + m_global_regs[code] = val; + if (m_intblock < 1) + m_intblock = 1; + return; + case MCR_REGISTER: + { + // bits 14..12 EntryTableMap + const int which = (val & 0x7000) >> 12; + assert(which < 4 || which == 7); + m_trap_entry = s_trap_entries[which]; + m_global_regs[code] = val; + return; } + case 28: + case 29: + case 30: + case 31: + m_global_regs[code] = val; + return; } } -#define GET_ABS_L_REG(code) m_local_regs[code] -#define SET_L_REG(code, val) set_local_register(code, val) -#define SET_ABS_L_REG(code, val) m_local_regs[code] = val -#define GET_G_REG(code) get_global_register(code) -#define SET_G_REG(code, val) set_global_register(code, val) - #define S_BIT ((OP & 0x100) >> 8) -#define N_BIT S_BIT #define D_BIT ((OP & 0x200) >> 9) -#define N_VALUE ((N_BIT << 4) | (OP & 0x0f)) +#define N_VALUE (((OP & 0x100) >> 4) | (OP & 0x0f)) +#define HI_N_VALUE (0x10 | (OP & 0x0f)) +#define LO_N_VALUE (OP & 0x0f) +#define N_OP_MASK (m_op & 0x10f) #define DST_CODE ((OP & 0xf0) >> 4) #define SRC_CODE (OP & 0x0f) #define SIGN_BIT(val) ((val & 0x80000000) >> 31) +#define SIGN_TO_N(val) ((val & 0x80000000) >> 29) -#define LOCAL 1 - -static const int32_t immediate_values[32] = +/*static*/ const int32_t hyperstone_device::s_immediate_values[16] = { - 0, 1, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 0, 0, 32, 64, 128, static_cast<int32_t>(0x80000000), + 16, 0, 0, 0, 32, 64, 128, int32_t(0x80000000), -8, -7, -6, -5, -4, -3, -2, -1 }; -#define WRITE_ONLY_REGMASK ((1 << BCR_REGISTER) | (1 << TPR_REGISTER) | (1 << FCR_REGISTER) | (1 << MCR_REGISTER)) - -#define decode_source(decode, local, hflag) \ -do \ -{ \ - if(local) \ - { \ - uint8_t code = (decode)->src; \ - (decode)->src_is_local = 1; \ - code = ((decode)->src + GET_FP) % 64; /* registers offset by frame pointer */\ - SREG = m_local_regs[code]; \ - code = ((decode)->src + 1 + GET_FP) % 64; \ - SREGF = m_local_regs[code]; \ - } \ - else \ - { \ - (decode)->src_is_local = 0; \ - \ - if (!hflag) \ - { \ - SREG = get_global_register((decode)->src); \ - \ - /* bound safe */ \ - if ((decode)->src != 15) \ - SREGF = get_global_register((decode)->src + 1); \ - } \ - else \ - { \ - (decode)->src += 16; \ - \ - SREG = get_global_register((decode)->src); \ - if ((WRITE_ONLY_REGMASK >> (decode)->src) & 1) \ - SREG = 0; /* write-only registers */ \ - else if ((decode)->src == ISR_REGISTER) \ - DEBUG_PRINTF(("read src ISR. PC = %08X\n",PPC)); \ - \ - /* bound safe */ \ - if ((decode)->src != 31) \ - SREGF = get_global_register((decode)->src + 1); \ - } \ - } \ -} while (0) - -#define decode_dest(decode, local, hflag) \ -do \ -{ \ - if(local) \ - { \ - uint8_t code = (decode)->dst; \ - (decode)->dst_is_local = 1; \ - code = ((decode)->dst + GET_FP) % 64; /* registers offset by frame pointer */\ - DREG = m_local_regs[code]; \ - code = ((decode)->dst + 1 + GET_FP) % 64; \ - DREGF = m_local_regs[code]; \ - } \ - else \ - { \ - (decode)->dst_is_local = 0; \ - \ - if (!hflag) \ - { \ - DREG = get_global_register((decode)->dst); \ - \ - /* bound safe */ \ - if ((decode)->dst != 15) \ - DREGF = get_global_register((decode)->dst + 1); \ - } \ - else \ - { \ - (decode)->dst += 16; \ - \ - DREG = get_global_register((decode)->dst); \ - if( (decode)->dst == ISR_REGISTER ) \ - DEBUG_PRINTF(("read dst ISR. PC = %08X\n",PPC)); \ - \ - /* bound safe */ \ - if ((decode)->dst != 31) \ - DREGF = get_global_register((decode)->dst + 1); \ - } \ - } \ -} while (0) - -#define decode_RR(decode, dlocal, slocal) \ -do \ -{ \ - (decode)->src = SRC_CODE; \ - (decode)->dst = DST_CODE; \ - decode_source(decode, slocal, 0); \ - decode_dest(decode, dlocal, 0); \ - \ - if( (slocal) == (dlocal) && SRC_CODE == DST_CODE ) \ - SAME_SRC_DST = 1; \ - \ - if( (slocal) == LOCAL && (dlocal) == LOCAL ) \ - { \ - if( SRC_CODE == ((DST_CODE + 1) % 64) ) \ - SAME_SRC_DSTF = 1; \ - \ - if( ((SRC_CODE + 1) % 64) == DST_CODE ) \ - SAME_SRCF_DST = 1; \ - } \ - else if( (slocal) == 0 && (dlocal) == 0 ) \ - { \ - if( SRC_CODE == (DST_CODE + 1) ) \ - SAME_SRC_DSTF = 1; \ - \ - if( (SRC_CODE + 1) == DST_CODE ) \ - SAME_SRCF_DST = 1; \ - } \ -} while (0) - -#define decode_LL(decode) \ -do \ -{ \ - (decode)->src = SRC_CODE; \ - (decode)->dst = DST_CODE; \ - decode_source(decode, LOCAL, 0); \ - decode_dest(decode, LOCAL, 0); \ - \ - if( SRC_CODE == DST_CODE ) \ - SAME_SRC_DST = 1; \ - \ - if( SRC_CODE == ((DST_CODE + 1) % 64) ) \ - SAME_SRC_DSTF = 1; \ -} while (0) - -#define decode_LR(decode, slocal) \ -do \ -{ \ - (decode)->src = SRC_CODE; \ - (decode)->dst = DST_CODE; \ - decode_source(decode, slocal, 0); \ - decode_dest(decode, LOCAL, 0); \ - \ - if( ((SRC_CODE + 1) % 64) == DST_CODE && slocal == LOCAL ) \ - SAME_SRCF_DST = 1; \ -} while (0) +constexpr uint32_t WRITE_ONLY_REGMASK = (1 << BCR_REGISTER) | (1 << TPR_REGISTER) | (1 << FCR_REGISTER) | (1 << MCR_REGISTER); #define check_delay_PC() \ do \ { \ /* if PC is used in a delay instruction, the delayed PC should be used */ \ - if( m_delay.delay_cmd == DELAY_EXECUTE ) \ + if (m_delay_slot) \ { \ - PC = m_delay.delay_pc; \ - m_delay.delay_cmd = NO_DELAY; \ + PC = m_delay_pc; \ + m_delay_slot = 0; \ } \ } while (0) -#define decode_immediate(decode, nbit) \ -do \ -{ \ - if (!nbit) \ - EXTRA_U = immediate_values[OP & 0x0f]; \ - else \ - switch( OP & 0x0f ) \ - { \ - default: \ - EXTRA_U = immediate_values[0x10 + (OP & 0x0f)]; \ - break; \ - \ - case 1: \ - m_instruction_length = 3; \ - EXTRA_U = (READ_OP(PC) << 16) | READ_OP(PC + 2); \ - PC += 4; \ - break; \ - \ - case 2: \ - m_instruction_length = 2; \ - EXTRA_U = READ_OP(PC); \ - PC += 2; \ - break; \ - \ - case 3: \ - m_instruction_length = 2; \ - EXTRA_U = 0xffff0000 | READ_OP(PC); \ - PC += 2; \ - break; \ - } \ -} while (0) - -#define decode_const(decode) \ -do \ -{ \ - uint16_t imm_1 = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 2; \ - \ - if( E_BIT(imm_1) ) \ - { \ - uint16_t imm_2 = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 3; \ - \ - EXTRA_S = imm_2; \ - EXTRA_S |= ((imm_1 & 0x3fff) << 16); \ - \ - if( S_BIT_CONST(imm_1) ) \ - { \ - EXTRA_S |= 0xc0000000; \ - } \ - } \ - else \ - { \ - EXTRA_S = imm_1 & 0x3fff; \ - \ - if( S_BIT_CONST(imm_1) ) \ - { \ - EXTRA_S |= 0xffffc000; \ - } \ - } \ -} while (0) - -#define decode_pcrel(decode) \ -do \ -{ \ - if( OP & 0x80 ) \ - { \ - uint16_t next = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 2; \ - \ - EXTRA_S = (OP & 0x7f) << 16; \ - EXTRA_S |= (next & 0xfffe); \ - \ - if( next & 1 ) \ - EXTRA_S |= 0xff800000; \ - } \ - else \ - { \ - EXTRA_S = OP & 0x7e; \ - \ - if( OP & 1 ) \ - EXTRA_S |= 0xffffff80; \ - } \ -} while (0) - -#define decode_dis(decode) \ -do \ -{ \ - uint16_t next_1 = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 2; \ - \ - (decode)->sub_type = DD(next_1); \ - \ - if( E_BIT(next_1) ) \ - { \ - uint16_t next_2 = READ_OP(PC); \ - \ - PC += 2; \ - m_instruction_length = 3; \ - \ - EXTRA_S = next_2; \ - EXTRA_S |= ((next_1 & 0xfff) << 16); \ - \ - if( S_BIT_CONST(next_1) ) \ - { \ - EXTRA_S |= 0xf0000000; \ - } \ - } \ - else \ - { \ - EXTRA_S = next_1 & 0xfff; \ - \ - if( S_BIT_CONST(next_1) ) \ - { \ - EXTRA_S |= 0xfffff000; \ - } \ - } \ -} while (0) - -#define decode_lim(decode) \ -do \ -{ \ - uint32_t next = READ_OP(PC); \ - PC += 2; \ - m_instruction_length = 2; \ - \ - (decode)->sub_type = X_CODE(next); \ - \ - if( E_BIT(next) ) \ - { \ - EXTRA_U = ((next & 0xfff) << 16) | READ_OP(PC); \ - PC += 2; \ - m_instruction_length = 3; \ - } \ - else \ - { \ - EXTRA_U = next & 0xfff; \ - } \ -} while (0) - -#define RRdecode(decode, dlocal, slocal) \ -do \ -{ \ - check_delay_PC(); \ - decode_RR(decode, dlocal, slocal); \ -} while (0) - -#define RRlimdecode(decode, dlocal, slocal) \ -do \ -{ \ - decode_lim(decode); \ - check_delay_PC(); \ - decode_RR(decode, dlocal, slocal); \ -} while (0) +void hyperstone_device::ignore_immediate_s() +{ + static const uint32_t lengths[16] = { 1<<19, 3<<19, 2<<19, 2<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19 }; + static const uint32_t offsets[16] = { 0, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + const uint8_t nybble = m_op & 0x0f; + m_instruction_length = lengths[nybble]; + PC += offsets[nybble]; +} -#define RRconstdecode(decode, dlocal, slocal) \ -do \ -{ \ - decode_const(decode); \ - check_delay_PC(); \ - decode_RR(decode, dlocal, slocal); \ -} while (0) +uint32_t hyperstone_device::decode_immediate_s() +{ + const uint8_t nybble = m_op & 0x0f; + switch (nybble) + { + case 0: + return 16; + case 1: + { + m_instruction_length = (3<<19); + uint32_t extra_u = (READ_OP(PC) << 16) | READ_OP(PC + 2); + PC += 4; + return extra_u; + } + case 2: + { + m_instruction_length = (2<<19); + uint32_t extra_u = READ_OP(PC); + PC += 2; + return extra_u; + } + case 3: + { + m_instruction_length = (2<<19); + uint32_t extra_u = 0xffff0000 | READ_OP(PC); + PC += 2; + return extra_u; + } + default: + return s_immediate_values[nybble]; + } +} -#define RRdisdecode(decode, dlocal, slocal) \ -do \ -{ \ - decode_dis(decode); \ - check_delay_PC(); \ - decode_RR(decode, dlocal, slocal); \ -} while (0) +uint32_t hyperstone_device::decode_const() +{ + const uint16_t imm_1 = READ_OP(PC); -#define RRdecodewithHflag(decode, dlocal, slocal) \ -do \ -{ \ - check_delay_PC(); \ - (decode)->src = SRC_CODE; \ - (decode)->dst = DST_CODE; \ - decode_source(decode, slocal, GET_H); \ - decode_dest(decode, dlocal, GET_H); \ - \ - if(GET_H) \ - if(slocal == 0 && dlocal == 0) \ - DEBUG_PRINTF(("MOV with hflag and 2 GRegs! PC = %08X\n",PPC)); \ -} while (0) + PC += 2; + m_instruction_length = (2<<19); -#define Rimmdecode(decode, dlocal, nbit) \ -do \ -{ \ - decode_immediate(decode, nbit); \ - check_delay_PC(); \ - (decode)->dst = DST_CODE; \ - decode_dest(decode, dlocal, 0); \ -} while (0) + if (imm_1 & 0x8000) + { + const uint16_t imm_2 = READ_OP(PC); -#define Rndecode(decode, dlocal) \ -do \ -{ \ - check_delay_PC(); \ - (decode)->dst = DST_CODE; \ - decode_dest(decode, dlocal, 0); \ -} while (0) + PC += 2; + m_instruction_length = (3<<19); -#define RimmdecodewithHflag(decode, dlocal, nbit) \ -do \ -{ \ - decode_immediate(decode, nbit); \ - check_delay_PC(); \ - (decode)->dst = DST_CODE; \ - decode_dest(decode, dlocal, GET_H); \ -} while (0) + uint32_t imm = imm_2; + imm |= ((imm_1 & 0x3fff) << 16); -#define Lndecode(decode) \ -do \ -{ \ - check_delay_PC(); \ - (decode)->dst = DST_CODE; \ - decode_dest(decode, LOCAL, 0); \ -} while (0) + if (imm_1 & 0x4000) + imm |= 0xc0000000; + return imm; + } + else + { + uint32_t imm = imm_1 & 0x3fff; -#define LLdecode(decode) \ -do \ -{ \ - check_delay_PC(); \ - decode_LL(decode); \ -} while (0) + if (imm_1 & 0x4000) + imm |= 0xffffc000; + return imm; + } +} -#define LLextdecode(decode) \ -do \ -{ \ - m_instruction_length = 2; \ - EXTRA_U = READ_OP(PC); \ - PC += 2; \ - check_delay_PC(); \ - decode_LL(decode); \ -} while (0) +int32_t hyperstone_device::decode_pcrel() +{ + if (OP & 0x80) + { + uint16_t next = READ_OP(PC); -#define LRdecode(decode, slocal) \ -do \ -{ \ - check_delay_PC(); \ - decode_LR(decode, slocal); \ -} while (0) + PC += 2; + m_instruction_length = (2<<19); -#define LRconstdecode(decode, slocal) \ -do \ -{ \ - decode_const(decode); \ - check_delay_PC(); \ - decode_LR(decode, slocal); \ -} while (0) + int32_t offset = (OP & 0x7f) << 16; + offset |= (next & 0xfffe); -#define PCreldecode(decode) \ -do \ -{ \ - decode_pcrel(decode); \ - check_delay_PC(); \ -} while (0) + if (next & 1) + offset |= 0xff800000; -#define PCadrdecode(decode) \ -do \ -{ \ - check_delay_PC(); \ -} while (0) + return offset; + } + else + { + int32_t offset = OP & 0x7e; -#define no_decode(decode) \ -do \ -{ \ -} while (0) + if (OP & 1) + offset |= 0xffffff80; + return offset; + } +} -void hyperstone_device::execute_br(struct hyperstone_device::regs_decode *decode) +void hyperstone_device::ignore_pcrel() { - PPC = PC; - PC += EXTRA_S; - SET_M(0); - - m_icount -= m_clock_cycles_2; + if (m_op & 0x80) + { + PC += 2; + m_instruction_length = (2<<19); + } } -void hyperstone_device::execute_dbr(struct hyperstone_device::regs_decode *decode) +void hyperstone_device::hyperstone_br() { - m_delay.delay_cmd = DELAY_EXECUTE; - m_delay.delay_pc = PC + EXTRA_S; + const int32_t offset = decode_pcrel(); + check_delay_PC(); - m_intblock = 3; -} + PC += offset; + SR &= ~M_MASK; + m_icount -= m_clock_cycles_2; +} void hyperstone_device::execute_trap(uint32_t addr) { - uint8_t reg; - uint32_t oldSR; - reg = GET_FP + GET_FL; - - SET_ILC(m_instruction_length & 3); - - oldSR = SR; + const uint8_t reg = GET_FP + GET_FL; + SET_ILC(m_instruction_length); + const uint32_t oldSR = SR; SET_FL(6); SET_FP(reg); - SET_L_REG(0, (PC & 0xfffffffe) | GET_S); - SET_L_REG(1, oldSR); + m_local_regs[(0 + reg) & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(1 + reg) & 0x3f] = oldSR; - SET_M(0); - SET_T(0); - SET_L(1); - SET_S(1); + SR &= ~(M_MASK | T_MASK); + SR |= (L_MASK | S_MASK); - PPC = PC; PC = addr; m_icount -= m_clock_cycles_2; @@ -1368,27 +813,19 @@ void hyperstone_device::execute_trap(uint32_t addr) void hyperstone_device::execute_int(uint32_t addr) { - uint8_t reg; - uint32_t oldSR; - reg = GET_FP + GET_FL; - - SET_ILC(m_instruction_length & 3); - - oldSR = SR; + const uint8_t reg = GET_FP + GET_FL; + SET_ILC(m_instruction_length); + const uint32_t oldSR = SR; SET_FL(2); SET_FP(reg); - SET_L_REG(0, (PC & 0xfffffffe) | GET_S); - SET_L_REG(1, oldSR); + m_local_regs[(0 + reg) & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(1 + reg) & 0x3f] = oldSR; - SET_M(0); - SET_T(0); - SET_L(1); - SET_S(1); - SET_I(1); + SR &= ~(M_MASK | T_MASK); + SR |= (L_MASK | S_MASK | I_MASK); - PPC = PC; PC = addr; m_icount -= m_clock_cycles_2; @@ -1397,66 +834,60 @@ void hyperstone_device::execute_int(uint32_t addr) /* TODO: mask Parity Error and Extended Overflow exceptions */ void hyperstone_device::execute_exception(uint32_t addr) { - uint8_t reg; - uint32_t oldSR; - reg = GET_FP + GET_FL; - - SET_ILC(m_instruction_length & 3); - - oldSR = SR; + const uint8_t reg = GET_FP + GET_FL; + SET_ILC(m_instruction_length); + const uint32_t oldSR = SR; - SET_FP(reg); SET_FL(2); + SET_FP(reg); - SET_L_REG(0, (PC & 0xfffffffe) | GET_S); - SET_L_REG(1, oldSR); + m_local_regs[(0 + reg) & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(1 + reg) & 0x3f] = oldSR; - SET_M(0); - SET_T(0); - SET_L(1); - SET_S(1); + SR &= ~(M_MASK | T_MASK); + SR |= (L_MASK | S_MASK); - PPC = PC; PC = addr; - DEBUG_PRINTF(("EXCEPTION! PPC = %08X PC = %08X\n",PPC-2,PC-2)); m_icount -= m_clock_cycles_2; } -void hyperstone_device::execute_software(struct hyperstone_device::regs_decode *decode) +void hyperstone_device::execute_software() { - uint8_t reg; - uint32_t oldSR; - uint32_t addr; - uint32_t stack_of_dst; + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_CODE; + const uint32_t sreg = m_local_regs[(src_code + fp) & 0x3f]; + const uint32_t sregf = m_local_regs[(src_code + 1 + fp) & 0x3f]; - SET_ILC(1); + SET_ILC(1<<19); - addr = get_emu_code_addr((OP & 0xff00) >> 8); - reg = GET_FP + GET_FL; + const uint32_t addr = get_emu_code_addr((m_op & 0xff00) >> 8); + const uint8_t reg = fp + GET_FL; //since it's sure the register is in the register part of the stack, //set the stack address to a value above the highest address //that can be set by a following frame instruction - stack_of_dst = (SP & ~0xff) + 64*4 + (((GET_FP + decode->dst) % 64) * 4); //converted to 32bits offset + const uint32_t stack_of_dst = (SP & ~0xff) + 64*4 + (((fp + DST_CODE) % 64) * 4); //converted to 32bits offset - oldSR = SR; + const uint32_t oldSR = SR; SET_FL(6); SET_FP(reg); - SET_L_REG(0, stack_of_dst); - SET_L_REG(1, SREG); - SET_L_REG(2, SREGF); - SET_L_REG(3, (PC & 0xfffffffe) | GET_S); - SET_L_REG(4, oldSR); + m_local_regs[(reg + 0) & 0x3f] = stack_of_dst; + m_local_regs[(reg + 1) & 0x3f] = sreg; + m_local_regs[(reg + 2) & 0x3f] = sregf; + m_local_regs[(reg + 3) & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(reg + 4) & 0x3f] = oldSR; - SET_M(0); - SET_T(0); - SET_L(1); + SR &= ~(M_MASK | T_MASK); + SR |= L_MASK; - PPC = PC; PC = addr; + + m_icount -= m_clock_cycles_6; } @@ -1586,9 +1017,14 @@ void hyperstone_device::device_start() void hyperstone_device::init(int scale_mask) { +#if ENABLE_E132XS_DRC + m_enable_drc = allow_drc(); +#else + m_enable_drc = false; +#endif + memset(m_global_regs, 0, sizeof(uint32_t) * 32); memset(m_local_regs, 0, sizeof(uint32_t) * 64); - m_ppc = 0; m_op = 0; m_trap_entry = 0; m_clock_scale_mask = 0; @@ -1600,6 +1036,7 @@ void hyperstone_device::init(int scale_mask) m_tr_base_cycles = 0; m_tr_base_value = 0; + m_tr_result = 0; m_tr_clocks_per_tick = 0; m_timer_int_pending = 0; @@ -1609,12 +1046,49 @@ void hyperstone_device::init(int scale_mask) m_icount = 0; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hyperstone_device::timer_callback), this)); m_clock_scale_mask = scale_mask; + for (uint8_t i = 0; i < 16; i++) + { + m_fl_lut[i] = (i ? i : 16); + } + + uint32_t umlflags = 0; + m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 1, 32, 1); + + // add UML symbols- + m_drcuml->symbol_add(&m_global_regs[0], sizeof(uint32_t), "pc"); + m_drcuml->symbol_add(&m_global_regs[1], sizeof(uint32_t), "sr"); + m_drcuml->symbol_add(&m_icount, sizeof(m_icount), "icount"); + + char buf[4]; + for (int i=0; i < 32; i++) + { + sprintf(buf, "g%d", i); + m_drcuml->symbol_add(&m_global_regs[i], sizeof(uint32_t), buf); + } + + for (int i=0; i < 64; i++) + { + sprintf(buf, "l%d", i); + m_drcuml->symbol_add(&m_local_regs[i], sizeof(uint32_t), buf); + } + + m_drcuml->symbol_add(&m_drc_arg0, sizeof(uint32_t), "arg0"); + m_drcuml->symbol_add(&m_drc_arg1, sizeof(uint32_t), "arg1"); + m_drcuml->symbol_add(&m_drc_arg2, sizeof(uint32_t), "arg2"); + m_drcuml->symbol_add(&m_drc_arg3, sizeof(uint32_t), "arg3"); + + /* initialize the front-end helper */ + m_drcfe = std::make_unique<e132xs_frontend>(this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE); + + /* mark the cache dirty so it is updated on next execute */ + m_cache_dirty = true; + // register our state for the debugger state_add(STATE_GENPC, "GENPC", m_global_regs[0]).noshow(); state_add(STATE_GENPCBASE, "CURPC", m_global_regs[0]).noshow(); @@ -1734,12 +1208,11 @@ void hyperstone_device::init(int scale_mask) save_item(NAME(m_global_regs)); save_item(NAME(m_local_regs)); - save_item(NAME(m_ppc)); save_item(NAME(m_trap_entry)); - save_item(NAME(m_delay.delay_pc)); + save_item(NAME(m_delay_pc)); save_item(NAME(m_instruction_length)); save_item(NAME(m_intblock)); - save_item(NAME(m_delay.delay_cmd)); + save_item(NAME(m_delay_slot)); save_item(NAME(m_tr_clocks_per_tick)); save_item(NAME(m_tr_base_value)); save_item(NAME(m_tr_base_cycles)); @@ -1844,12 +1317,12 @@ void hyperstone_device::device_reset() //TODO: Add different reset initializations for BCR, MCR, FCR, TPR m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_tr_clocks_per_tick = 2; - hyperstone_set_trap_entry(E132XS_ENTRY_MEM3); /* default entry point @ MEM3 */ + m_trap_entry = s_trap_entries[E132XS_ENTRY_MEM3]; // default entry point @ MEM3 set_global_register(BCR_REGISTER, ~0); set_global_register(MCR_REGISTER, ~0); @@ -1866,15 +1339,22 @@ void hyperstone_device::device_reset() SET_L(1); SET_S(1); - SET_L_REG(0, (PC & 0xfffffffe) | GET_S); - SET_L_REG(1, SR); + set_local_register(0, (PC & 0xfffffffe) | GET_S); + set_local_register(1, SR); m_icount -= m_clock_cycles_2; } void hyperstone_device::device_stop() { - // nothing to do + if (m_drcfe != nullptr) + { + m_drcfe = nullptr; + } + if (m_drcuml != nullptr) + { + m_drcuml = nullptr; + } } @@ -1926,2993 +1406,94 @@ void hyperstone_device::state_string_export(const device_state_entry &entry, std //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t hyperstone_device::disasm_min_opcode_bytes() const -{ - return 2; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t hyperstone_device::disasm_max_opcode_bytes() const -{ - return 6; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t hyperstone_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( hyperstone ); - return dasm_hyperstone(stream, pc, oprom, GET_H, GET_FP); -} - -/* Opcodes */ - -void hyperstone_device::hyperstone_chk(struct hyperstone_device::regs_decode *decode) -{ - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - - if( SRC_IS_SR ) - { - if( DREG == 0 ) - execute_exception(addr); - } - else - { - if( SRC_IS_PC ) - { - if( DREG >= SREG ) - execute_exception(addr); - } - else - { - if( DREG > SREG ) - execute_exception(addr); - } - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_movd(struct hyperstone_device::regs_decode *decode) -{ - if( DST_IS_PC ) // Rd denotes PC - { - // RET instruction - - uint8_t old_s, old_l; - int8_t difference; // really it's 7 bits - - if( SRC_IS_PC || SRC_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in RET instruction. PC = %08X\n", PC)); - } - else - { - old_s = GET_S; - old_l = GET_L; - PPC = PC; - - SET_PC(SREG); - SR = (SREGF & 0xffe00000) | ((SREG & 0x01) << 18 ) | (SREGF & 0x3ffff); - if (m_intblock < 1) - m_intblock = 1; - - m_instruction_length = 0; // undefined - - if( (!old_s && GET_S) || (!GET_S && !old_l && GET_L)) - { - uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR); - execute_exception(addr); - } - - difference = GET_FP - ((SP & 0x1fc) >> 2); - - /* convert to 8 bits */ - if(difference > 63) - difference = (int8_t)(difference|0x80); - else if( difference < -64 ) - difference = difference & 0x7f; - - if( difference < 0 ) //else it's finished - { - do - { - SP -= 4; - SET_ABS_L_REG(((SP & 0xfc) >> 2), READ_W(SP)); - difference++; - - } while(difference != 0); - } - } - - //TODO: no 1! - m_icount -= m_clock_cycles_1; - } - else if( SRC_IS_SR ) // Rd doesn't denote PC and Rs denotes SR - { - SET_DREG(0); - SET_DREGF(0); - SET_Z(1); - SET_N(0); - - m_icount -= m_clock_cycles_2; - } - else // Rd doesn't denote PC and Rs doesn't denote SR - { - uint64_t tmp; - - SET_DREG(SREG); - SET_DREGF(SREGF); - - tmp = concat_64(SREG, SREGF); - SET_Z( tmp == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(SREG) ); - - m_icount -= m_clock_cycles_2; - } -} - -void hyperstone_device::hyperstone_divu(struct hyperstone_device::regs_decode *decode) -{ - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted the same register code in hyperstone_divu instruction. PC = %08X\n", PC)); - } - else - { - if( SRC_IS_PC || SRC_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR as source register in hyperstone_divu instruction. PC = %08X\n", PC)); - } - else - { - uint64_t dividend; - - dividend = concat_64(DREG, DREGF); - - if( SREG == 0 ) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - uint32_t addr; - SET_V(1); - addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } - else - { - uint32_t quotient, remainder; - - /* TODO: add quotient overflow */ - quotient = dividend / SREG; - remainder = dividend % SREG; - - SET_DREG(remainder); - SET_DREGF(quotient); - - SET_Z( quotient == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(quotient) ); - SET_V(0); - } - } - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_divs(struct hyperstone_device::regs_decode *decode) -{ - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted the same register code in hyperstone_divs instruction. PC = %08X\n", PC)); - } - else - { - if( SRC_IS_PC || SRC_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR as source register in hyperstone_divs instruction. PC = %08X\n", PC)); - } - else - { - int64_t dividend; - - dividend = (int64_t) concat_64(DREG, DREGF); - - if( SREG == 0 || (DREG & 0x80000000) ) - { - //Rd//Rdf -> undefined - //Z -> undefined - //N -> undefined - uint32_t addr; - SET_V(1); - addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } - else - { - int32_t quotient, remainder; - - /* TODO: add quotient overflow */ - quotient = dividend / ((int32_t)(SREG)); - remainder = dividend % ((int32_t)(SREG)); - - SET_DREG(remainder); - SET_DREGF(quotient); - - SET_Z( quotient == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(quotient) ); - SET_V(0); - } - } - } - - m_icount -= 36 << m_clck_scale; -} - -void hyperstone_device::hyperstone_xm(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR || DST_IS_SR || DST_IS_PC ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_xm. PC = %08X\n", PC)); - } - else - { - switch( decode->sub_type ) // x_code - { - case 0: - case 1: - case 2: - case 3: - if( !SRC_IS_PC && (SREG > EXTRA_U) ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } - else if( SRC_IS_PC && (SREG >= EXTRA_U) ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } - else - { - SREG <<= decode->sub_type; - } - - break; - - case 4: - case 5: - case 6: - case 7: - decode->sub_type -= 4; - SREG <<= decode->sub_type; - - break; - } - - SET_DREG(SREG); - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_mask(struct hyperstone_device::regs_decode *decode) -{ - DREG = SREG & EXTRA_U; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sum(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (uint64_t)(SREG) + (uint64_t)(EXTRA_U); - CHECK_C(tmp); - CHECK_VADD(SREG,EXTRA_U,tmp); - - DREG = SREG + EXTRA_U; - - SET_DREG(DREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sums(struct hyperstone_device::regs_decode *decode) -{ - int32_t res; - int64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (int64_t)((int32_t)(SREG)) + (int64_t)(EXTRA_S); - CHECK_VADD(SREG,EXTRA_S,tmp); - -//#if SETCARRYS -// CHECK_C(tmp); -//#endif - - res = (int32_t)(SREG) + EXTRA_S; - - SET_DREG(res); - - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - m_icount -= m_clock_cycles_1; - - if( GET_V && !SRC_IS_SR ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_cmp(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - if( DREG == SREG ) - SET_Z(1); - else - SET_Z(0); - - if( (int32_t) DREG < (int32_t) SREG ) - SET_N(1); - else - SET_N(0); - - tmp = (uint64_t)(DREG) - (uint64_t)(SREG); - CHECK_VSUB(SREG,DREG,tmp); - - if( DREG < SREG ) - SET_C(1); - else - SET_C(0); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_mov(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_S && decode->dst >= 16 ) - { - uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR); - execute_exception(addr); - } - - SET_DREG(SREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( SREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(SREG) ); - - m_icount -= m_clock_cycles_1; -} - - -void hyperstone_device::hyperstone_add(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (uint64_t)(SREG) + (uint64_t)(DREG); - CHECK_C(tmp); - CHECK_VADD(SREG,DREG,tmp); - - DREG = SREG + DREG; - SET_DREG(DREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_adds(struct hyperstone_device::regs_decode *decode) -{ - int32_t res; - int64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (int64_t)((int32_t)(SREG)) + (int64_t)((int32_t)(DREG)); - - CHECK_VADD(SREG,DREG,tmp); - -//#if SETCARRYS -// CHECK_C(tmp); -//#endif - - res = (int32_t)(SREG) + (int32_t)(DREG); - - SET_DREG(res); - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - m_icount -= m_clock_cycles_1; - - if( GET_V ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_cmpb(struct hyperstone_device::regs_decode *decode) -{ - SET_Z( (DREG & SREG) == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_andn(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG & ~SREG; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_or(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG | SREG; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_xor(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG ^ SREG; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_subc(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - { - tmp = (uint64_t)(DREG) - (uint64_t)(GET_C); - CHECK_VSUB(GET_C,DREG,tmp); - } - else - { - tmp = (uint64_t)(DREG) - ((uint64_t)(SREG) + (uint64_t)(GET_C)); - //CHECK! - CHECK_VSUB(SREG + GET_C,DREG,tmp); - } - - - if( SRC_IS_SR ) - { - DREG = DREG - GET_C; - } - else - { - DREG = DREG - (SREG + GET_C); - } - - CHECK_C(tmp); - - SET_DREG(DREG); - - SET_Z( GET_Z & (DREG == 0 ? 1 : 0) ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_not(struct hyperstone_device::regs_decode *decode) -{ - SET_DREG(~SREG); - SET_Z( ~SREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sub(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (uint64_t)(DREG) - (uint64_t)(SREG); - CHECK_C(tmp); - CHECK_VSUB(SREG,DREG,tmp); - - DREG = DREG - SREG; - SET_DREG(DREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_subs(struct hyperstone_device::regs_decode *decode) -{ - int32_t res; - int64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = (int64_t)((int32_t)(DREG)) - (int64_t)((int32_t)(SREG)); - -//#ifdef SETCARRYS -// CHECK_C(tmp); -//#endif - - CHECK_VSUB(SREG,DREG,tmp); - - res = (int32_t)(DREG) - (int32_t)(SREG); - - SET_DREG(res); - - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - m_icount -= m_clock_cycles_1; - - if( GET_V ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_addc(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - { - tmp = (uint64_t)(DREG) + (uint64_t)(GET_C); - CHECK_VADD(DREG,GET_C,tmp); - } - else - { - tmp = (uint64_t)(SREG) + (uint64_t)(DREG) + (uint64_t)(GET_C); - - //CHECK! - //CHECK_VADD1: V = (DREG == 0x7FFF) && (C == 1); - //OVERFLOW = CHECK_VADD1(DREG, C, DREG+C) | CHECK_VADD(SREG, DREG+C, SREG+DREG+C) - /* check if DREG + GET_C overflows */ -// if( (DREG == 0x7FFFFFFF) && (GET_C == 1) ) -// SET_V(1); -// else -// CHECK_VADD(SREG,DREG + GET_C,tmp); - - CHECK_VADD3(SREG,DREG,GET_C,tmp); - } - - - - if( SRC_IS_SR ) - DREG = DREG + GET_C; - else - DREG = SREG + DREG + GET_C; - - CHECK_C(tmp); - - SET_DREG(DREG); - SET_Z( GET_Z & (DREG == 0 ? 1 : 0) ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_and(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG & SREG; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_neg(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = -(uint64_t)(SREG); - CHECK_C(tmp); - CHECK_VSUB(SREG,0,tmp); - - DREG = -SREG; - - SET_DREG(DREG); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_negs(struct hyperstone_device::regs_decode *decode) -{ - int32_t res; - int64_t tmp; - - if( SRC_IS_SR ) - SREG = GET_C; - - tmp = -(int64_t)((int32_t)(SREG)); - CHECK_VSUB(SREG,0,tmp); - -//#if SETCARRYS -// CHECK_C(tmp); -//#endif - - res = -(int32_t)(SREG); - - SET_DREG(res); - - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - - m_icount -= m_clock_cycles_1; - - if( GET_V && !SRC_IS_SR ) //trap doesn't occur when source is SR - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_cmpi(struct hyperstone_device::regs_decode *decode) -{ - uint64_t tmp; - - tmp = (uint64_t)(DREG) - (uint64_t)(EXTRA_U); - CHECK_VSUB(EXTRA_U,DREG,tmp); - - if( DREG == EXTRA_U ) - SET_Z(1); - else - SET_Z(0); - - if( (int32_t) DREG < (int32_t) EXTRA_U ) - SET_N(1); - else - SET_N(0); - - if( DREG < EXTRA_U ) - SET_C(1); - else - SET_C(0); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_movi(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_S && decode->dst >= 16 ) - { - uint32_t addr = get_trap_addr(TRAPNO_PRIVILEGE_ERROR); - execute_exception(addr); - } - - SET_DREG(EXTRA_U); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( EXTRA_U == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(EXTRA_U) ); - -#if MISSIONCRAFT_FLAGS - SET_V(0); // or V undefined ? -#endif - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_addi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t imm; - uint64_t tmp; - - if( N_VALUE ) - imm = EXTRA_U; - else - imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01)); - - - tmp = (uint64_t)(imm) + (uint64_t)(DREG); - CHECK_C(tmp); - CHECK_VADD(imm,DREG,tmp); - - DREG = imm + DREG; - SET_DREG(DREG); - - if( DST_IS_PC ) - SET_M(0); - - SET_Z( DREG == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(DREG) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_addsi(struct hyperstone_device::regs_decode *decode) -{ - int32_t imm, res; - int64_t tmp; - - if( N_VALUE ) - imm = EXTRA_S; - else - imm = GET_C & ((GET_Z == 0 ? 1 : 0) | (DREG & 0x01)); - - tmp = (int64_t)(imm) + (int64_t)((int32_t)(DREG)); - CHECK_VADD(imm,DREG,tmp); - -//#if SETCARRYS -// CHECK_C(tmp); -//#endif - - res = imm + (int32_t)(DREG); - - SET_DREG(res); - - SET_Z( res == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(res) ); - - m_icount -= m_clock_cycles_1; - - if( GET_V ) - { - uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR); - execute_exception(addr); - } -} - -void hyperstone_device::hyperstone_cmpbi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t imm; - - if( N_VALUE ) - { - if( N_VALUE == 31 ) - { - imm = 0x7fffffff; // bit 31 = 0, others = 1 - } - else - { - imm = EXTRA_U; - } - - SET_Z( (DREG & imm) == 0 ? 1 : 0 ); - } - else - { - if( (DREG & 0xff000000) == 0 || (DREG & 0x00ff0000) == 0 || - (DREG & 0x0000ff00) == 0 || (DREG & 0x000000ff) == 0 ) - SET_Z(1); - else - SET_Z(0); - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_andni(struct hyperstone_device::regs_decode *decode) -{ - uint32_t imm; - - if( N_VALUE == 31 ) - imm = 0x7fffffff; // bit 31 = 0, others = 1 - else - imm = EXTRA_U; - - DREG = DREG & ~imm; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_ori(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG | EXTRA_U; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_xori(struct hyperstone_device::regs_decode *decode) -{ - DREG = DREG ^ EXTRA_U; - - SET_DREG(DREG); - SET_Z( DREG == 0 ? 1 : 0 ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_shrdi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t val; - - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - - if( N_VALUE ) - SET_C((val >> (N_VALUE - 1)) & 1); - else - SET_C(0); - - val >>= N_VALUE; - - high_order = extract_64hi(val); - low_order = extract_64lo(val); - - SET_DREG(high_order); - SET_DREGF(low_order); - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_shrd(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t val; - uint8_t n = SREG & 0x1f; - - // result undefined if Ls denotes the same register as Ld or Ldf - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted same registers in hyperstone_shrd. PC = %08X\n", PC)); - } - else - { - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - - if( n ) - SET_C((val >> (n - 1)) & 1); - else - SET_C(0); - - val >>= n; - - high_order = extract_64hi(val); - low_order = extract_64lo(val); - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_shr(struct hyperstone_device::regs_decode *decode) -{ - uint32_t ret; - uint8_t n; - - n = SREG & 0x1f; - ret = DREG; - - if( n ) - SET_C((ret >> (n - 1)) & 1); - else - SET_C(0); - - ret >>= n; - - SET_DREG(ret); - SET_Z( ret == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(ret) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_sardi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t val; - uint8_t sign_bit; - - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - - if( N_VALUE ) - SET_C((val >> (N_VALUE - 1)) & 1); - else - SET_C(0); - - sign_bit = val >> 63; - val >>= N_VALUE; - - if( sign_bit ) - { - int i; - for( i = 0; i < N_VALUE; i++ ) - { - val |= (0x8000000000000000U >> i); - } - } - - high_order = val >> 32; - low_order = val & 0xffffffff; - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_sard(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t val; - uint8_t n, sign_bit; - - n = SREG & 0x1f; - - // result undefined if Ls denotes the same register as Ld or Ldf - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted same registers in hyperstone_sard. PC = %08X\n", PC)); - } - else - { - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - - if( n ) - SET_C((val >> (n - 1)) & 1); - else - SET_C(0); - - sign_bit = val >> 63; - - val >>= n; - - if( sign_bit ) - { - int i; - for( i = 0; i < n; i++ ) - { - val |= (0x8000000000000000U >> i); - } - } - - high_order = val >> 32; - low_order = val & 0xffffffff; - - SET_DREG(high_order); - SET_DREGF(low_order); - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_sar(struct hyperstone_device::regs_decode *decode) -{ - uint32_t ret; - uint8_t n, sign_bit; - - n = SREG & 0x1f; - ret = DREG; - sign_bit = (ret & 0x80000000) >> 31; - - if( n ) - SET_C((ret >> (n - 1)) & 1); - else - SET_C(0); - - ret >>= n; - - if( sign_bit ) - { - int i; - for( i = 0; i < n; i++ ) - { - ret |= (0x80000000 >> i); - } - } - - SET_DREG(ret); - SET_Z( ret == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(ret) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_shldi(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order, tmp; - uint64_t val, mask; - - high_order = DREG; - low_order = DREGF; - - val = concat_64(high_order, low_order); - SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&0x8000000000000000U)?1:0):0); - mask = ((((uint64_t)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff; - tmp = high_order << N_VALUE; - - if( ((high_order & mask) && (!(tmp & 0x80000000))) || - (((high_order & mask) ^ mask) && (tmp & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - - val <<= N_VALUE; - - high_order = extract_64hi(val); - low_order = extract_64lo(val); - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_shld(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order, tmp, n; - uint64_t val, mask; - - n = SREG & 0x1f; - - // result undefined if Ls denotes the same register as Ld or Ldf - if( SAME_SRC_DST || SAME_SRC_DSTF ) - { - DEBUG_PRINTF(("Denoted same registers in hyperstone_shld. PC = %08X\n", PC)); - } - else - { - high_order = DREG; - low_order = DREGF; - - mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; - - val = concat_64(high_order, low_order); - SET_C( (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0); - tmp = high_order << n; - - if( ((high_order & mask) && (!(tmp & 0x80000000))) || - (((high_order & mask) ^ mask) && (tmp & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - - val <<= n; - - high_order = extract_64hi(val); - low_order = extract_64lo(val); - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_shl(struct hyperstone_device::regs_decode *decode) -{ - uint32_t base, ret, n; - uint64_t mask; - - n = SREG & 0x1f; - base = DREG; - mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; - SET_C( (n)?(((base<<(n-1))&0x80000000)?1:0):0); - ret = base << n; - - if( ((base & mask) && (!(ret & 0x80000000))) || - (((base & mask) ^ mask) && (ret & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - - SET_DREG(ret); - SET_Z( ret == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(ret) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::reserved(struct hyperstone_device::regs_decode *decode) -{ - DEBUG_PRINTF(("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP)); -} - -void hyperstone_device::hyperstone_testlz(struct hyperstone_device::regs_decode *decode) -{ - uint8_t zeros = 0; - uint32_t mask; - - for( mask = 0x80000000; ; mask >>= 1 ) - { - if( SREG & mask ) - break; - else - zeros++; - - if( zeros == 32 ) - break; - } - - SET_DREG(zeros); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_rol(struct hyperstone_device::regs_decode *decode) -{ - uint32_t val, base; - uint8_t n; - uint64_t mask; - - n = SREG & 0x1f; - - val = base = DREG; - - mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; - - while( n > 0 ) - { - val = (val << 1) | ((val & 0x80000000) >> 31); - n--; - } - -#ifdef MISSIONCRAFT_FLAGS - - if( ((base & mask) && (!(val & 0x80000000))) || - (((base & mask) ^ mask) && (val & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - -#endif - - SET_DREG(val); - - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(val) ); - - m_icount -= m_clock_cycles_1; -} - -//TODO: add trap error -void hyperstone_device::hyperstone_ldxx1(struct hyperstone_device::regs_decode *decode) -{ - uint32_t load; - - if( DST_IS_SR ) - { - switch( decode->sub_type ) - { - case 0: // LDBS.A - - load = READ_B(EXTRA_S); - load |= (load & 0x80) ? 0xffffff00 : 0; - SET_SREG(load); - - break; - - case 1: // LDBU.A - - load = READ_B(EXTRA_S); - SET_SREG(load); - - break; - - case 2: - - load = READ_HW(EXTRA_S); - - if( EXTRA_S & 1 ) // LDHS.A - { - load |= (load & 0x8000) ? 0xffff0000 : 0; - } - /* - else // LDHU.A - { - // nothing more - } - */ - - SET_SREG(load); - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // LDD.IOA - { - load = IO_READ_W(EXTRA_S & ~3); - SET_SREG(load); - - load = IO_READ_W((EXTRA_S & ~3) + 4); - SET_SREGF(load); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else if( (EXTRA_S & 3) == 2 ) // LDW.IOA - { - load = IO_READ_W(EXTRA_S & ~3); - SET_SREG(load); - } - else if( (EXTRA_S & 3) == 1 ) // LDD.A - { - load = READ_W(EXTRA_S & ~1); - SET_SREG(load); - - load = READ_W((EXTRA_S & ~1) + 4); - SET_SREGF(load); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // LDW.A - { - load = READ_W(EXTRA_S & ~1); - SET_SREG(load); - } - - break; - } - } - else - { - switch( decode->sub_type ) - { - case 0: // LDBS.D - - load = READ_B(DREG + EXTRA_S); - load |= (load & 0x80) ? 0xffffff00 : 0; - SET_SREG(load); - - break; - - case 1: // LDBU.D - - load = READ_B(DREG + EXTRA_S); - SET_SREG(load); - - break; - - case 2: - - load = READ_HW(DREG + (EXTRA_S & ~1)); - - if( EXTRA_S & 1 ) // LDHS.D - { - load |= (load & 0x8000) ? 0xffff0000 : 0; - } - /* - else // LDHU.D - { - // nothing more - } - */ - - SET_SREG(load); - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // LDD.IOD - { - load = IO_READ_W(DREG + (EXTRA_S & ~3)); - SET_SREG(load); - - load = IO_READ_W(DREG + (EXTRA_S & ~3) + 4); - SET_SREGF(load); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else if( (EXTRA_S & 3) == 2 ) // LDW.IOD - { - load = IO_READ_W(DREG + (EXTRA_S & ~3)); - SET_SREG(load); - } - else if( (EXTRA_S & 3) == 1 ) // LDD.D - { - load = READ_W(DREG + (EXTRA_S & ~1)); - SET_SREG(load); - - load = READ_W(DREG + (EXTRA_S & ~1) + 4); - SET_SREGF(load); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // LDW.D - { - load = READ_W(DREG + (EXTRA_S & ~1)); - SET_SREG(load); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_ldxx2(struct hyperstone_device::regs_decode *decode) -{ - uint32_t load; - - if( DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC)); - } - else - { - switch( decode->sub_type ) - { - case 0: // LDBS.N - - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDBS.N denoted same regs @ %08X",PPC)); - - load = READ_B(DREG); - load |= (load & 0x80) ? 0xffffff00 : 0; - SET_SREG(load); - - if(!SAME_SRC_DST) - SET_DREG(DREG + EXTRA_S); - - break; - - case 1: // LDBU.N - - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDBU.N denoted same regs @ %08X",PPC)); - - load = READ_B(DREG); - SET_SREG(load); - - if(!SAME_SRC_DST) - SET_DREG(DREG + EXTRA_S); - - break; - - case 2: - - load = READ_HW(DREG); - - if( EXTRA_S & 1 ) // LDHS.N - { - load |= (load & 0x8000) ? 0xffff0000 : 0; - - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDHS.N denoted same regs @ %08X",PPC)); - } - /* - else // LDHU.N - { - // nothing more - } - */ - - SET_SREG(load); - - if(!SAME_SRC_DST) - SET_DREG(DREG + (EXTRA_S & ~1)); - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // LDW.S - { - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDW.S denoted same regs @ %08X",PPC)); - - if(DREG < SP) - SET_SREG(READ_W(DREG)); - else - SET_SREG(GET_ABS_L_REG((DREG & 0xfc) >> 2)); - - if(!SAME_SRC_DST) - SET_DREG(DREG + (EXTRA_S & ~3)); - - m_icount -= m_clock_cycles_2; // extra cycles - } - else if( (EXTRA_S & 3) == 2 ) // Reserved - { - DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_ldxx2. PC = %08X\n", PC)); - } - else if( (EXTRA_S & 3) == 1 ) // LDD.N - { - if(SAME_SRC_DST || SAME_SRCF_DST) - DEBUG_PRINTF(("LDD.N denoted same regs @ %08X",PPC)); - - load = READ_W(DREG); - SET_SREG(load); - - load = READ_W(DREG + 4); - SET_SREGF(load); - - if(!SAME_SRC_DST && !SAME_SRCF_DST) - SET_DREG(DREG + (EXTRA_S & ~1)); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // LDW.N - { - if(SAME_SRC_DST) - DEBUG_PRINTF(("LDW.N denoted same regs @ %08X",PPC)); - - load = READ_W(DREG); - SET_SREG(load); - - if(!SAME_SRC_DST) - SET_DREG(DREG + (EXTRA_S & ~1)); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; -} - -//TODO: add trap error -void hyperstone_device::hyperstone_stxx1(struct hyperstone_device::regs_decode *decode) +util::disasm_interface *hyperstone_device::create_disassembler() { - if( SRC_IS_SR ) - SREG = SREGF = 0; - - if( DST_IS_SR ) - { - switch( decode->sub_type ) - { - case 0: // STBS.A - - /* TODO: missing trap on range error */ - WRITE_B(EXTRA_S, SREG & 0xff); - - break; - - case 1: // STBU.A - - WRITE_B(EXTRA_S, SREG & 0xff); - - break; - - case 2: - - WRITE_HW(EXTRA_S, SREG & 0xffff); - - /* - if( EXTRA_S & 1 ) // STHS.A - { - // TODO: missing trap on range error - } - else // STHU.A - { - // nothing more - } - */ - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // STD.IOA - { - IO_WRITE_W(EXTRA_S & ~3, SREG); - IO_WRITE_W((EXTRA_S & ~3) + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else if( (EXTRA_S & 3) == 2 ) // STW.IOA - { - IO_WRITE_W(EXTRA_S & ~3, SREG); - } - else if( (EXTRA_S & 3) == 1 ) // STD.A - { - WRITE_W(EXTRA_S & ~1, SREG); - WRITE_W((EXTRA_S & ~1) + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // STW.A - { - WRITE_W(EXTRA_S & ~1, SREG); - } - - break; - } - } - else - { - switch( decode->sub_type ) - { - case 0: // STBS.D - - /* TODO: missing trap on range error */ - WRITE_B(DREG + EXTRA_S, SREG & 0xff); - - break; - - case 1: // STBU.D - - WRITE_B(DREG + EXTRA_S, SREG & 0xff); - - break; - - case 2: - - WRITE_HW(DREG + (EXTRA_S & ~1), SREG & 0xffff); - - /* - if( EXTRA_S & 1 ) // STHS.D - { - // TODO: missing trap on range error - } - else // STHU.D - { - // nothing more - } - */ - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // STD.IOD - { - IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG); - IO_WRITE_W(DREG + (EXTRA_S & ~3) + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else if( (EXTRA_S & 3) == 2 ) // STW.IOD - { - IO_WRITE_W(DREG + (EXTRA_S & ~3), SREG); - } - else if( (EXTRA_S & 3) == 1 ) // STD.D - { - WRITE_W(DREG + (EXTRA_S & ~1), SREG); - WRITE_W(DREG + (EXTRA_S & ~1) + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // STW.D - { - WRITE_W(DREG + (EXTRA_S & ~1), SREG); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; + return new hyperstone_disassembler(this); } -void hyperstone_device::hyperstone_stxx2(struct hyperstone_device::regs_decode *decode) +u8 hyperstone_device::get_fp() const { - if( SRC_IS_SR ) - SREG = SREGF = 0; - - if( DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_stxx2. PC = %08X\n", PC)); - } - else - { - switch( decode->sub_type ) - { - case 0: // STBS.N - - /* TODO: missing trap on range error */ - WRITE_B(DREG, SREG & 0xff); - SET_DREG(DREG + EXTRA_S); - - break; - - case 1: // STBU.N - - WRITE_B(DREG, SREG & 0xff); - SET_DREG(DREG + EXTRA_S); - - break; - - case 2: - - WRITE_HW(DREG, SREG & 0xffff); - SET_DREG(DREG + (EXTRA_S & ~1)); - - /* - if( EXTRA_S & 1 ) // STHS.N - { - // TODO: missing trap on range error - } - else // STHU.N - { - // nothing more - } - */ - - break; - - case 3: - - if( (EXTRA_S & 3) == 3 ) // STW.S - { - if(DREG < SP) - WRITE_W(DREG, SREG); - else - { - if(((DREG & 0xfc) >> 2) == ((decode->src + GET_FP) % 64) && S_BIT == LOCAL) - DEBUG_PRINTF(("STW.S denoted the same local register @ %08X\n",PPC)); - - SET_ABS_L_REG((DREG & 0xfc) >> 2,SREG); - } - - SET_DREG(DREG + (EXTRA_S & ~3)); - - m_icount -= m_clock_cycles_2; // extra cycles - - } - else if( (EXTRA_S & 3) == 2 ) // Reserved - { - DEBUG_PRINTF(("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC)); - } - else if( (EXTRA_S & 3) == 1 ) // STD.N - { - WRITE_W(DREG, SREG); - SET_DREG(DREG + (EXTRA_S & ~1)); - - if( SAME_SRCF_DST ) - WRITE_W(DREG + 4, SREGF + (EXTRA_S & ~1)); // because DREG == SREGF and DREG has been incremented - else - WRITE_W(DREG + 4, SREGF); - - m_icount -= m_clock_cycles_1; // extra cycle - } - else // STW.N - { - WRITE_W(DREG, SREG); - SET_DREG(DREG + (EXTRA_S & ~1)); - } - - break; - } - } - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_shri(struct hyperstone_device::regs_decode *decode) -{ - uint32_t val; - - val = DREG; - - if( N_VALUE ) - SET_C((val >> (N_VALUE - 1)) & 1); - else - SET_C(0); - - val >>= N_VALUE; - - SET_DREG(val); - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(val) ); - - m_icount -= m_clock_cycles_1; + return GET_FP; } -void hyperstone_device::hyperstone_sari(struct hyperstone_device::regs_decode *decode) +bool hyperstone_device::get_h() const { - uint32_t val; - uint8_t sign_bit; - - val = DREG; - sign_bit = (val & 0x80000000) >> 31; - - if( N_VALUE ) - SET_C((val >> (N_VALUE - 1)) & 1); - else - SET_C(0); - - val >>= N_VALUE; - - if( sign_bit ) - { - int i; - for( i = 0; i < N_VALUE; i++ ) - { - val |= (0x80000000 >> i); - } - } - - SET_DREG(val); - SET_Z( val == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(val) ); - - m_icount -= m_clock_cycles_1; + return GET_H; } -void hyperstone_device::hyperstone_shli(struct hyperstone_device::regs_decode *decode) -{ - uint32_t val, val2; - uint64_t mask; - - val = DREG; - SET_C( (N_VALUE)?(((val<<(N_VALUE-1))&0x80000000)?1:0):0); - mask = ((((uint64_t)1) << (32 - N_VALUE)) - 1) ^ 0xffffffff; - val2 = val << N_VALUE; - - if( ((val & mask) && (!(val2 & 0x80000000))) || - (((val & mask) ^ mask) && (val2 & 0x80000000)) ) - SET_V(1); - else - SET_V(0); - - SET_DREG(val2); - SET_Z( val2 == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(val2) ); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_mulu(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - uint64_t double_word; - - // PC or SR aren't denoted, else result is undefined - if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mulu instruction. PC = %08X\n", PC)); - } - else - { - double_word = (uint64_t)SREG *(uint64_t)DREG; - - low_order = double_word & 0xffffffff; - high_order = double_word >> 32; - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( double_word == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - if(SREG <= 0xffff && DREG <= 0xffff) - m_icount -= m_clock_cycles_4; - else - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_muls(struct hyperstone_device::regs_decode *decode) -{ - uint32_t low_order, high_order; - int64_t double_word; - - // PC or SR aren't denoted, else result is undefined - if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_muls instruction. PC = %08X\n", PC)); - } - else - { - double_word = (int64_t)(int32_t)(SREG) * (int64_t)(int32_t)(DREG); - low_order = double_word & 0xffffffff; - high_order = double_word >> 32; - - SET_DREG(high_order); - SET_DREGF(low_order); - - SET_Z( double_word == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(high_order) ); - } - - if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff)) - m_icount -= m_clock_cycles_4; - else - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_set(struct hyperstone_device::regs_decode *decode) -{ - int n = N_VALUE; - - if( DST_IS_PC ) - { - DEBUG_PRINTF(("Denoted PC in hyperstone_set. PC = %08X\n", PC)); - } - else if( DST_IS_SR ) - { - //TODO: add fetch opcode when there's the pipeline - - //TODO: no 1! - m_icount -= m_clock_cycles_1; - } - else - { - switch( n ) - { - // SETADR - case 0: - { - uint32_t val; - val = (SP & 0xfffffe00) | (GET_FP << 2); - - //plus carry into bit 9 - val += (( (SP & 0x100) && (SIGN_BIT(SR) == 0) ) ? 1 : 0); - - SET_DREG(val); - - break; - } - // Reserved - case 1: - case 16: - case 17: - case 19: - DEBUG_PRINTF(("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC)); - break; - - // SETxx - case 2: - SET_DREG(1); - break; - - case 3: - SET_DREG(0); - break; - - case 4: - if( GET_N || GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 5: - if( !GET_N && !GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 6: - if( GET_N ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 7: - if( !GET_N ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 8: - if( GET_C || GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 9: - if( !GET_C && !GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 10: - if( GET_C ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 11: - if( !GET_C ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 12: - if( GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 13: - if( !GET_Z ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 14: - if( GET_V ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 15: - if( !GET_V ) - { - SET_DREG(1); - } - else - { - SET_DREG(0); - } - - break; - - case 18: - SET_DREG(-1); - break; - - case 20: - if( GET_N || GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 21: - if( !GET_N && !GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 22: - if( GET_N ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 23: - if( !GET_N ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 24: - if( GET_C || GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 25: - if( !GET_C && !GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 26: - if( GET_C ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 27: - if( !GET_C ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 28: - if( GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 29: - if( !GET_Z ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 30: - if( GET_V ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - - case 31: - if( !GET_V ) - { - SET_DREG(-1); - } - else - { - SET_DREG(0); - } - - break; - } - - m_icount -= m_clock_cycles_1; - } -} - -void hyperstone_device::hyperstone_mul(struct hyperstone_device::regs_decode *decode) -{ - uint32_t single_word; - - // PC or SR aren't denoted, else result is undefined - if( SRC_IS_PC || SRC_IS_SR || DST_IS_PC || DST_IS_SR ) - { - DEBUG_PRINTF(("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC)); - } - else - { - single_word = (SREG * DREG);// & 0xffffffff; // only the low-order word is taken - - SET_DREG(single_word); - - SET_Z( single_word == 0 ? 1 : 0 ); - SET_N( SIGN_BIT(single_word) ); - } - - if((SREG >= 0xffff8000 && SREG <= 0x7fff) && (DREG >= 0xffff8000 && DREG <= 0x7fff)) - m_icount -= 3 << m_clck_scale; - else - m_icount -= 5 << m_clck_scale; -} - -void hyperstone_device::hyperstone_fadd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_faddd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fsub(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fsubd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fmul(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fmuld(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fdiv(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fdivd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcmp(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcmpd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcmpu(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcmpud(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcvt(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_fcvtd(struct hyperstone_device::regs_decode *decode) -{ - execute_software(decode); - m_icount -= m_clock_cycles_6; -} - -void hyperstone_device::hyperstone_extend(struct hyperstone_device::regs_decode *decode) -{ - //TODO: add locks, overflow error and other things - uint32_t vals, vald; - - vals = SREG; - vald = DREG; - - switch( EXTRA_U ) // extended opcode - { - // signed or unsigned multiplication, single word product - case EMUL: - case 0x100: // used in "N" type cpu - { - uint32_t result; - - result = vals * vald; - SET_G_REG(15, result); - - break; - } - // unsigned multiplication, double word product - case EMULU: - { - uint64_t result; - - result = (uint64_t)vals * (uint64_t)vald; - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // signed multiplication, double word product - case EMULS: - { - int64_t result; - - result = (int64_t)(int32_t)(vals) * (int64_t)(int32_t)(vald); - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // signed multiply/add, single word product sum - case EMAC: - { - int32_t result; - - result = (int32_t)GET_G_REG(15) + ((int32_t)(vals) * (int32_t)(vald)); - SET_G_REG(15, result); - - break; - } - // signed multiply/add, double word product sum - case EMACD: - { - int64_t result; - - result = (int64_t)concat_64(GET_G_REG(14), GET_G_REG(15)) + (int64_t)((int64_t)(int32_t)(vals) * (int64_t)(int32_t)(vald)); - - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // signed multiply/substract, single word product difference - case EMSUB: - { - int32_t result; - - result = (int32_t)GET_G_REG(15) - ((int32_t)(vals) * (int32_t)(vald)); - SET_G_REG(15, result); - - break; - } - // signed multiply/substract, double word product difference - case EMSUBD: - { - int64_t result; - - result = (int64_t)concat_64(GET_G_REG(14), GET_G_REG(15)) - (int64_t)((int64_t)(int32_t)(vals) * (int64_t)(int32_t)(vald)); - - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // signed half-word multiply/add, single word product sum - case EHMAC: - { - int32_t result; - - result = (int32_t)GET_G_REG(15) + ((int32_t)((vald & 0xffff0000) >> 16) * (int32_t)((vals & 0xffff0000) >> 16)) + ((int32_t)(vald & 0xffff) * (int32_t)(vals & 0xffff)); - SET_G_REG(15, result); - - break; - } - // signed half-word multiply/add, double word product sum - case EHMACD: - { - int64_t result; - - result = (int64_t)concat_64(GET_G_REG(14), GET_G_REG(15)) + (int64_t)((int64_t)(int32_t)((vald & 0xffff0000) >> 16) * (int64_t)(int32_t)((vals & 0xffff0000) >> 16)) + ((int64_t)(int32_t)(vald & 0xffff) * (int64_t)(int32_t)(vals & 0xffff)); - - vals = result >> 32; - vald = result & 0xffffffff; - SET_G_REG(14, vals); - SET_G_REG(15, vald); - - break; - } - // half-word complex multiply - case EHCMULD: - { - uint32_t result; - - result = (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); - SET_G_REG(14, result); - - result = (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); - SET_G_REG(15, result); - - break; - } - // half-word complex multiply/add - case EHCMACD: - { - uint32_t result; - - result = GET_G_REG(14) + (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); - SET_G_REG(14, result); - - result = GET_G_REG(15) + (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); - SET_G_REG(15, result); - - break; - } - // half-word (complex) add/substract - // Ls is not used and should denote the same register as Ld - case EHCSUMD: - { - uint32_t result; - - result = ((((vals & 0xffff0000) >> 16) + GET_G_REG(14)) << 16) & 0xffff0000; - result |= ((vals & 0xffff) + GET_G_REG(15)) & 0xffff; - SET_G_REG(14, result); - - result = ((((vals & 0xffff0000) >> 16) - GET_G_REG(14)) << 16) & 0xffff0000; - result |= ((vals & 0xffff) - GET_G_REG(15)) & 0xffff; - SET_G_REG(15, result); - - break; - } - // half-word (complex) add/substract with fixed point adjustment - // Ls is not used and should denote the same register as Ld - case EHCFFTD: - { - uint32_t result; - - result = ((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) << 16) & 0xffff0000; - result |= ((vals & 0xffff) + (GET_G_REG(15) >> 15)) & 0xffff; - SET_G_REG(14, result); - - result = ((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) << 16) & 0xffff0000; - result |= ((vals & 0xffff) - (GET_G_REG(15) >> 15)) & 0xffff; - SET_G_REG(15, result); - - break; - } - // half-word (complex) add/substract with fixed point adjustment and shift - // Ls is not used and should denote the same register as Ld - case EHCFFTSD: - { - uint32_t result; - - result = (((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000; - result |= ((((vals & 0xffff) + (GET_G_REG(15) >> 15)) >> 1) & 0xffff); - SET_G_REG(14, result); - - result = (((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000; - result |= ((((vals & 0xffff) - (GET_G_REG(15) >> 15)) >> 1) & 0xffff); - SET_G_REG(15, result); - - break; - } - default: - DEBUG_PRINTF(("Executed Illegal extended opcode (%X). PC = %08X\n", EXTRA_U, PC)); - break; - } - - m_icount -= m_clock_cycles_1; //TODO: with the latency it can change -} - -void hyperstone_device::hyperstone_do(struct hyperstone_device::regs_decode *decode) -{ - fatalerror("Executed hyperstone_do instruction. PC = %08X\n", PPC); -} - -void hyperstone_device::hyperstone_ldwr(struct hyperstone_device::regs_decode *decode) -{ - SET_SREG(READ_W(DREG)); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_lddr(struct hyperstone_device::regs_decode *decode) -{ - SET_SREG(READ_W(DREG)); - SET_SREGF(READ_W(DREG + 4)); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_ldwp(struct hyperstone_device::regs_decode *decode) -{ - SET_SREG(READ_W(DREG)); - - // post increment the destination register if it's different from the source one - // (needed by Hidden Catch) - if(!(decode->src == decode->dst && S_BIT == LOCAL)) - SET_DREG(DREG + 4); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_lddp(struct hyperstone_device::regs_decode *decode) -{ - SET_SREG(READ_W(DREG)); - SET_SREGF(READ_W(DREG + 4)); - - // post increment the destination register if it's different from the source one - // and from the "next source" one - if(!(decode->src == decode->dst && S_BIT == LOCAL) && !SAME_SRCF_DST ) - { - SET_DREG(DREG + 8); - } - else - { - DEBUG_PRINTF(("LDD.P denoted same regs @ %08X",PPC)); - } - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_stwr(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = 0; - - WRITE_W(DREG, SREG); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_stdr(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = SREGF = 0; - - WRITE_W(DREG, SREG); - WRITE_W(DREG + 4, SREGF); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_stwp(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = 0; - - WRITE_W(DREG, SREG); - SET_DREG(DREG + 4); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_stdp(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = SREGF = 0; - - WRITE_W(DREG, SREG); - SET_DREG(DREG + 8); - - if( SAME_SRCF_DST ) - WRITE_W(DREG + 4, SREGF + 8); // because DREG == SREGF and DREG has been incremented - else - WRITE_W(DREG + 4, SREGF); - - m_icount -= m_clock_cycles_2; -} - -void hyperstone_device::hyperstone_dbv(struct hyperstone_device::regs_decode *decode) -{ - if( GET_V ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbnv(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_V ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbe(struct hyperstone_device::regs_decode *decode) //or DBZ -{ - if( GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbne(struct hyperstone_device::regs_decode *decode) //or DBNZ -{ - if( !GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbc(struct hyperstone_device::regs_decode *decode) //or DBST -{ - if( GET_C ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbnc(struct hyperstone_device::regs_decode *decode) //or DBHE -{ - if( !GET_C ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbse(struct hyperstone_device::regs_decode *decode) -{ - if( GET_C || GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbht(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_C && !GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbn(struct hyperstone_device::regs_decode *decode) //or DBLT -{ - if( GET_N ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbnn(struct hyperstone_device::regs_decode *decode) //or DBGE -{ - if( !GET_N ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dble(struct hyperstone_device::regs_decode *decode) -{ - if( GET_N || GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbgt(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_N && !GET_Z ) - execute_dbr(decode); - - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_dbr(struct hyperstone_device::regs_decode *decode) -{ - execute_dbr(decode); -} - -void hyperstone_device::hyperstone_frame(struct hyperstone_device::regs_decode *decode) -{ - int8_t difference; // really it's 7 bits - uint8_t realfp = GET_FP - SRC_CODE; - - SET_FP(realfp); - SET_FL(DST_CODE); - SET_M(0); - - difference = ((SP & 0x1fc) >> 2) + (64 - 10) - (realfp + GET_FL); - - /* convert to 8 bits */ - if(difference > 63) - difference = (int8_t)(difference|0x80); - else if( difference < -64 ) - difference = difference & 0x7f; - - if( difference < 0 ) // else it's finished - { - uint8_t tmp_flag; - - tmp_flag = ( SP >= UB ? 1 : 0 ); - - do - { - WRITE_W(SP, GET_ABS_L_REG((SP & 0xfc) >> 2)); - SP += 4; - difference++; - - } while(difference != 0); - - if( tmp_flag ) - { - uint32_t addr = get_trap_addr(TRAPNO_FRAME_ERROR); - execute_exception(addr); - } - } - - //TODO: no 1! - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_call(struct hyperstone_device::regs_decode *decode) -{ - if( SRC_IS_SR ) - SREG = 0; - - if( !DST_CODE ) - decode->dst = 16; - - EXTRA_S = (EXTRA_S & ~1) + SREG; - - SET_ILC(m_instruction_length & 3); - - SET_DREG((PC & 0xfffffffe) | GET_S); - SET_DREGF(SR); - - SET_FP(GET_FP + decode->dst); - - SET_FL(6); //default value for call - SET_M(0); - - PPC = PC; - PC = EXTRA_S; // const value - - m_intblock = 2; - - //TODO: add interrupt locks, errors, .... - - //TODO: no 1! - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bv(struct hyperstone_device::regs_decode *decode) -{ - if( GET_V ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bnv(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_V ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_be(struct hyperstone_device::regs_decode *decode) //or BZ -{ - if( GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bne(struct hyperstone_device::regs_decode *decode) //or BNZ -{ - if( !GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bc(struct hyperstone_device::regs_decode *decode) //or BST -{ - if( GET_C ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bnc(struct hyperstone_device::regs_decode *decode) //or BHE -{ - if( !GET_C ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bse(struct hyperstone_device::regs_decode *decode) -{ - if( GET_C || GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bht(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_C && !GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bn(struct hyperstone_device::regs_decode *decode) //or BLT -{ - if( GET_N ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bnn(struct hyperstone_device::regs_decode *decode) //or BGE -{ - if( !GET_N ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_ble(struct hyperstone_device::regs_decode *decode) -{ - if( GET_N || GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_bgt(struct hyperstone_device::regs_decode *decode) -{ - if( !GET_N && !GET_Z ) - execute_br(decode); - else - m_icount -= m_clock_cycles_1; -} - -void hyperstone_device::hyperstone_br(struct hyperstone_device::regs_decode *decode) -{ - execute_br(decode); -} +/* Opcodes */ -void hyperstone_device::hyperstone_trap(struct hyperstone_device::regs_decode *decode) +void hyperstone_device::hyperstone_trap() { - uint8_t code, trapno; - uint32_t addr; - - trapno = (OP & 0xfc) >> 2; + check_delay_PC(); - addr = get_trap_addr(trapno); - code = ((OP & 0x300) >> 6) | (OP & 0x03); + const uint8_t trapno = (m_op & 0xfc) >> 2; + const uint32_t addr = get_trap_addr(trapno); + const uint8_t code = ((m_op & 0x300) >> 6) | (m_op & 0x03); - switch( code ) + switch (code) { case TRAPLE: - if( GET_N || GET_Z ) + if (SR & (N_MASK | Z_MASK)) execute_trap(addr); - break; case TRAPGT: - if( !GET_N && !GET_Z ) + if(!(SR & (N_MASK | Z_MASK))) execute_trap(addr); - break; case TRAPLT: - if( GET_N ) + if (SR & N_MASK) execute_trap(addr); - break; case TRAPGE: - if( !GET_N ) + if (!(SR & N_MASK)) execute_trap(addr); - break; case TRAPSE: - if( GET_C || GET_Z ) + if (SR & (C_MASK | Z_MASK)) execute_trap(addr); - break; case TRAPHT: - if( !GET_C && !GET_Z ) + if (!(SR & (C_MASK | Z_MASK))) execute_trap(addr); - break; case TRAPST: - if( GET_C ) + if (SR & C_MASK) execute_trap(addr); - break; case TRAPHE: - if( !GET_C ) + if (!(SR & C_MASK)) execute_trap(addr); - break; case TRAPE: - if( GET_Z ) + if (SR & Z_MASK) execute_trap(addr); - break; case TRAPNE: - if( !GET_Z ) + if (!(SR & Z_MASK)) execute_trap(addr); - break; case TRAPV: - if( GET_V ) + if (SR & V_MASK) execute_trap(addr); - break; case TRAP: execute_trap(addr); - break; } @@ -4967,6 +1548,15 @@ void hyperstone_device::execute_set_input(int inputnum, int state) ISR &= ~(1 << inputnum); } +void hyperstone_device::hyperstone_reserved() +{ + LOG("Executed Reserved opcode. PC = %08X OP = %04X\n", PC, OP); +} + +void hyperstone_device::hyperstone_do() +{ + fatalerror("Executed hyperstone_do instruction. PC = %08X\n", PC-4); +} //------------------------------------------------- // execute_run - execute a timeslice's worth of @@ -4975,6 +1565,12 @@ void hyperstone_device::execute_set_input(int inputnum, int state) void hyperstone_device::execute_run() { + if (m_enable_drc) + { + execute_run_drc(); + return; + } + if (m_intblock < 0) m_intblock = 0; @@ -4984,23 +1580,279 @@ void hyperstone_device::execute_run() { uint32_t oldh = SR & 0x00000020; - PPC = PC; /* copy PC to previous PC */ debugger_instruction_hook(this, PC); OP = READ_OP(PC); PC += 2; - m_instruction_length = 1; + m_instruction_length = (1<<19); - /* execute opcode */ - (this->*m_opcode[(OP & 0xff00) >> 8])(); + switch (m_op >> 8) + { + case 0x00: hyperstone_chk<GLOBAL, GLOBAL>(); break; + case 0x01: hyperstone_chk<GLOBAL, LOCAL>(); break; + case 0x02: hyperstone_chk<LOCAL, GLOBAL>(); break; + case 0x03: hyperstone_chk<LOCAL, LOCAL>(); break; + case 0x04: hyperstone_movd<GLOBAL, GLOBAL>(); break; + case 0x05: hyperstone_movd<GLOBAL, LOCAL>(); break; + case 0x06: hyperstone_movd<LOCAL, GLOBAL>(); break; + case 0x07: hyperstone_movd<LOCAL, LOCAL>(); break; + case 0x08: hyperstone_divsu<GLOBAL, GLOBAL, IS_UNSIGNED>(); break; + case 0x09: hyperstone_divsu<GLOBAL, LOCAL, IS_UNSIGNED>(); break; + case 0x0a: hyperstone_divsu<LOCAL, GLOBAL, IS_UNSIGNED>(); break; + case 0x0b: hyperstone_divsu<LOCAL, LOCAL, IS_UNSIGNED>(); break; + case 0x0c: hyperstone_divsu<GLOBAL, GLOBAL, IS_SIGNED>(); break; + case 0x0d: hyperstone_divsu<GLOBAL, LOCAL, IS_SIGNED>(); break; + case 0x0e: hyperstone_divsu<LOCAL, GLOBAL, IS_SIGNED>(); break; + case 0x0f: hyperstone_divsu<LOCAL, LOCAL, IS_SIGNED>(); break; + case 0x10: hyperstone_xm<GLOBAL, GLOBAL>(); break; + case 0x11: hyperstone_xm<GLOBAL, LOCAL>(); break; + case 0x12: hyperstone_xm<LOCAL, GLOBAL>(); break; + case 0x13: hyperstone_xm<LOCAL, LOCAL>(); break; + case 0x14: hyperstone_mask<GLOBAL, GLOBAL>(); break; + case 0x15: hyperstone_mask<GLOBAL, LOCAL>(); break; + case 0x16: hyperstone_mask<LOCAL, GLOBAL>(); break; + case 0x17: hyperstone_mask<LOCAL, LOCAL>(); break; + case 0x18: hyperstone_sum<GLOBAL, GLOBAL>(); break; + case 0x19: hyperstone_sum<GLOBAL, LOCAL>(); break; + case 0x1a: hyperstone_sum<LOCAL, GLOBAL>(); break; + case 0x1b: hyperstone_sum<LOCAL, LOCAL>(); break; + case 0x1c: hyperstone_sums<GLOBAL, GLOBAL>(); break; + case 0x1d: hyperstone_sums<GLOBAL, LOCAL>(); break; + case 0x1e: hyperstone_sums<LOCAL, GLOBAL>(); break; + case 0x1f: hyperstone_sums<LOCAL, LOCAL>(); break; + case 0x20: hyperstone_cmp<GLOBAL, GLOBAL>(); break; + case 0x21: hyperstone_cmp<GLOBAL, LOCAL>(); break; + case 0x22: hyperstone_cmp<LOCAL, GLOBAL>(); break; + case 0x23: hyperstone_cmp<LOCAL, LOCAL>(); break; + case 0x24: hyperstone_mov<GLOBAL, GLOBAL>(); break; + case 0x25: hyperstone_mov<GLOBAL, LOCAL>(); break; + case 0x26: hyperstone_mov<LOCAL, GLOBAL>(); break; + case 0x27: hyperstone_mov<LOCAL, LOCAL>(); break; + case 0x28: hyperstone_add<GLOBAL, GLOBAL>(); break; + case 0x29: hyperstone_add<GLOBAL, LOCAL>(); break; + case 0x2a: hyperstone_add<LOCAL, GLOBAL>(); break; + case 0x2b: hyperstone_add<LOCAL, LOCAL>(); break; + case 0x2c: hyperstone_adds<GLOBAL, GLOBAL>(); break; + case 0x2d: hyperstone_adds<GLOBAL, LOCAL>(); break; + case 0x2e: hyperstone_adds<LOCAL, GLOBAL>(); break; + case 0x2f: hyperstone_adds<LOCAL, LOCAL>(); break; + case 0x30: hyperstone_cmpb<GLOBAL, GLOBAL>(); break; + case 0x31: hyperstone_cmpb<GLOBAL, LOCAL>(); break; + case 0x32: hyperstone_cmpb<LOCAL, GLOBAL>(); break; + case 0x33: hyperstone_cmpb<LOCAL, LOCAL>(); break; + case 0x34: hyperstone_andn<GLOBAL, GLOBAL>(); break; + case 0x35: hyperstone_andn<GLOBAL, LOCAL>(); break; + case 0x36: hyperstone_andn<LOCAL, GLOBAL>(); break; + case 0x37: hyperstone_andn<LOCAL, LOCAL>(); break; + case 0x38: hyperstone_or<GLOBAL, GLOBAL>(); break; + case 0x39: hyperstone_or<GLOBAL, LOCAL>(); break; + case 0x3a: hyperstone_or<LOCAL, GLOBAL>(); break; + case 0x3b: hyperstone_or<LOCAL, LOCAL>(); break; + case 0x3c: hyperstone_xor<GLOBAL, GLOBAL>(); break; + case 0x3d: hyperstone_xor<GLOBAL, LOCAL>(); break; + case 0x3e: hyperstone_xor<LOCAL, GLOBAL>(); break; + case 0x3f: hyperstone_xor<LOCAL, LOCAL>(); break; + case 0x40: hyperstone_subc<GLOBAL, GLOBAL>(); break; + case 0x41: hyperstone_subc<GLOBAL, LOCAL>(); break; + case 0x42: hyperstone_subc<LOCAL, GLOBAL>(); break; + case 0x43: hyperstone_subc<LOCAL, LOCAL>(); break; + case 0x44: hyperstone_not<GLOBAL, GLOBAL>(); break; + case 0x45: hyperstone_not<GLOBAL, LOCAL>(); break; + case 0x46: hyperstone_not<LOCAL, GLOBAL>(); break; + case 0x47: hyperstone_not<LOCAL, LOCAL>(); break; + case 0x48: hyperstone_sub<GLOBAL, GLOBAL>(); break; + case 0x49: hyperstone_sub<GLOBAL, LOCAL>(); break; + case 0x4a: hyperstone_sub<LOCAL, GLOBAL>(); break; + case 0x4b: hyperstone_sub<LOCAL, LOCAL>(); break; + case 0x4c: hyperstone_subs<GLOBAL, GLOBAL>(); break; + case 0x4d: hyperstone_subs<GLOBAL, LOCAL>(); break; + case 0x4e: hyperstone_subs<LOCAL, GLOBAL>(); break; + case 0x4f: hyperstone_subs<LOCAL, LOCAL>(); break; + case 0x50: hyperstone_addc<GLOBAL, GLOBAL>(); break; + case 0x51: hyperstone_addc<GLOBAL, LOCAL>(); break; + case 0x52: hyperstone_addc<LOCAL, GLOBAL>(); break; + case 0x53: hyperstone_addc<LOCAL, LOCAL>(); break; + case 0x54: hyperstone_and<GLOBAL, GLOBAL>(); break; + case 0x55: hyperstone_and<GLOBAL, LOCAL>(); break; + case 0x56: hyperstone_and<LOCAL, GLOBAL>(); break; + case 0x57: hyperstone_and<LOCAL, LOCAL>(); break; + case 0x58: hyperstone_neg<GLOBAL, GLOBAL>(); break; + case 0x59: hyperstone_neg<GLOBAL, LOCAL>(); break; + case 0x5a: hyperstone_neg<LOCAL, GLOBAL>(); break; + case 0x5b: hyperstone_neg<LOCAL, LOCAL>(); break; + case 0x5c: hyperstone_negs<GLOBAL, GLOBAL>(); break; + case 0x5d: hyperstone_negs<GLOBAL, LOCAL>(); break; + case 0x5e: hyperstone_negs<LOCAL, GLOBAL>(); break; + case 0x5f: hyperstone_negs<LOCAL, LOCAL>(); break; + case 0x60: hyperstone_cmpi<GLOBAL, SIMM>(); break; + case 0x61: hyperstone_cmpi<GLOBAL, LIMM>(); break; + case 0x62: hyperstone_cmpi<LOCAL, SIMM>(); break; + case 0x63: hyperstone_cmpi<LOCAL, LIMM>(); break; + case 0x64: hyperstone_movi<GLOBAL, SIMM>(); break; + case 0x65: hyperstone_movi<GLOBAL, LIMM>(); break; + case 0x66: hyperstone_movi<LOCAL, SIMM>(); break; + case 0x67: hyperstone_movi<LOCAL, LIMM>(); break; + case 0x68: hyperstone_addi<GLOBAL, SIMM>(); break; + case 0x69: hyperstone_addi<GLOBAL, LIMM>(); break; + case 0x6a: hyperstone_addi<LOCAL, SIMM>(); break; + case 0x6b: hyperstone_addi<LOCAL, LIMM>(); break; + case 0x6c: hyperstone_addsi<GLOBAL, SIMM>(); break; + case 0x6d: hyperstone_addsi<GLOBAL, LIMM>(); break; + case 0x6e: hyperstone_addsi<LOCAL, SIMM>(); break; + case 0x6f: hyperstone_addsi<LOCAL, LIMM>(); break; + case 0x70: hyperstone_cmpbi<GLOBAL, SIMM>(); break; + case 0x71: hyperstone_cmpbi<GLOBAL, LIMM>(); break; + case 0x72: hyperstone_cmpbi<LOCAL, SIMM>(); break; + case 0x73: hyperstone_cmpbi<LOCAL, LIMM>(); break; + case 0x74: hyperstone_andni<GLOBAL, SIMM>(); break; + case 0x75: hyperstone_andni<GLOBAL, LIMM>(); break; + case 0x76: hyperstone_andni<LOCAL, SIMM>(); break; + case 0x77: hyperstone_andni<LOCAL, LIMM>(); break; + case 0x78: hyperstone_ori<GLOBAL, SIMM>(); break; + case 0x79: hyperstone_ori<GLOBAL, LIMM>(); break; + case 0x7a: hyperstone_ori<LOCAL, SIMM>(); break; + case 0x7b: hyperstone_ori<LOCAL, LIMM>(); break; + case 0x7c: hyperstone_xori<GLOBAL, SIMM>(); break; + case 0x7d: hyperstone_xori<GLOBAL, LIMM>(); break; + case 0x7e: hyperstone_xori<LOCAL, SIMM>(); break; + case 0x7f: hyperstone_xori<LOCAL, LIMM>(); break; + case 0x80: hyperstone_shrdi<N_LO>(); break; + case 0x81: hyperstone_shrdi<N_HI>(); break; + case 0x82: hyperstone_shrd(); break; + case 0x83: hyperstone_shr(); break; + case 0x84: hyperstone_sardi<N_LO>(); break; + case 0x85: hyperstone_sardi<N_HI>(); break; + case 0x86: hyperstone_sard(); break; + case 0x87: hyperstone_sar(); break; + case 0x88: hyperstone_shldi<N_LO>(); break; + case 0x89: hyperstone_shldi<N_HI>(); break; + case 0x8a: hyperstone_shld(); break; + case 0x8b: hyperstone_shl(); break; + case 0x8c: hyperstone_reserved(); break; + case 0x8d: hyperstone_reserved(); break; + case 0x8e: hyperstone_testlz(); break; + case 0x8f: hyperstone_rol(); break; + case 0x90: hyperstone_ldxx1<GLOBAL, GLOBAL>(); break; + case 0x91: hyperstone_ldxx1<GLOBAL, LOCAL>(); break; + case 0x92: hyperstone_ldxx1<LOCAL, GLOBAL>(); break; + case 0x93: hyperstone_ldxx1<LOCAL, LOCAL>(); break; + case 0x94: hyperstone_ldxx2<GLOBAL, GLOBAL>(); break; + case 0x95: hyperstone_ldxx2<GLOBAL, LOCAL>(); break; + case 0x96: hyperstone_ldxx2<LOCAL, GLOBAL>(); break; + case 0x97: hyperstone_ldxx2<LOCAL, LOCAL>(); break; + case 0x98: hyperstone_stxx1<GLOBAL, GLOBAL>(); break; + case 0x99: hyperstone_stxx1<GLOBAL, LOCAL>(); break; + case 0x9a: hyperstone_stxx1<LOCAL, GLOBAL>(); break; + case 0x9b: hyperstone_stxx1<LOCAL, LOCAL>(); break; + case 0x9c: hyperstone_stxx2<GLOBAL, GLOBAL>(); break; + case 0x9d: hyperstone_stxx2<GLOBAL, LOCAL>(); break; + case 0x9e: hyperstone_stxx2<LOCAL, GLOBAL>(); break; + case 0x9f: hyperstone_stxx2<LOCAL, LOCAL>(); break; + case 0xa0: hyperstone_shri<N_LO, GLOBAL>(); break; + case 0xa1: hyperstone_shri<N_HI, GLOBAL>(); break; + case 0xa2: hyperstone_shri<N_LO, LOCAL>(); break; + case 0xa3: hyperstone_shri<N_HI, LOCAL>(); break; + case 0xa4: hyperstone_sari<N_LO, GLOBAL>(); break; + case 0xa5: hyperstone_sari<N_HI, GLOBAL>(); break; + case 0xa6: hyperstone_sari<N_LO, LOCAL>(); break; + case 0xa7: hyperstone_sari<N_HI, LOCAL>(); break; + case 0xa8: hyperstone_shli<N_LO, GLOBAL>(); break; + case 0xa9: hyperstone_shli<N_HI, GLOBAL>(); break; + case 0xaa: hyperstone_shli<N_LO, LOCAL>(); break; + case 0xab: hyperstone_shli<N_HI, LOCAL>(); break; + case 0xac: hyperstone_reserved(); break; + case 0xad: hyperstone_reserved(); break; + case 0xae: hyperstone_reserved(); break; + case 0xaf: hyperstone_reserved(); break; + case 0xb0: hyperstone_mulsu<GLOBAL, GLOBAL, IS_UNSIGNED>(); break; + case 0xb1: hyperstone_mulsu<GLOBAL, LOCAL, IS_UNSIGNED>(); break; + case 0xb2: hyperstone_mulsu<LOCAL, GLOBAL, IS_UNSIGNED>(); break; + case 0xb3: hyperstone_mulsu<LOCAL, LOCAL, IS_UNSIGNED>(); break; + case 0xb4: hyperstone_mulsu<GLOBAL, GLOBAL, IS_SIGNED>(); break; + case 0xb5: hyperstone_mulsu<GLOBAL, LOCAL, IS_SIGNED>(); break; + case 0xb6: hyperstone_mulsu<LOCAL, GLOBAL, IS_SIGNED>(); break; + case 0xb7: hyperstone_mulsu<LOCAL, LOCAL, IS_SIGNED>(); break; + case 0xb8: hyperstone_set<N_LO, GLOBAL>(); break; + case 0xb9: hyperstone_set<N_HI, GLOBAL>(); break; + case 0xba: hyperstone_set<N_LO, LOCAL>(); break; + case 0xbb: hyperstone_set<N_HI, LOCAL>(); break; + case 0xbc: hyperstone_mul<GLOBAL, GLOBAL>(); break; + case 0xbd: hyperstone_mul<GLOBAL, LOCAL>(); break; + case 0xbe: hyperstone_mul<LOCAL, GLOBAL>(); break; + case 0xbf: hyperstone_mul<LOCAL, LOCAL>(); break; + case 0xc0: execute_software(); break; // fadd + case 0xc1: execute_software(); break; // faddd + case 0xc2: execute_software(); break; // fsub + case 0xc3: execute_software(); break; // fsubd + case 0xc4: execute_software(); break; // fmul + case 0xc5: execute_software(); break; // fmuld + case 0xc6: execute_software(); break; // fdiv + case 0xc7: execute_software(); break; // fdivd + case 0xc8: execute_software(); break; // fcmp + case 0xc9: execute_software(); break; // fcmpd + case 0xca: execute_software(); break; // fcmpu + case 0xcb: execute_software(); break; // fcmpud + case 0xcc: execute_software(); break; // fcvt + case 0xcd: execute_software(); break; // fcvtd + case 0xce: hyperstone_extend(); break; + case 0xcf: hyperstone_do(); break; + case 0xd0: hyperstone_ldwr<GLOBAL>(); break; + case 0xd1: hyperstone_ldwr<LOCAL>(); break; + case 0xd2: hyperstone_lddr<GLOBAL>(); break; + case 0xd3: hyperstone_lddr<LOCAL>(); break; + case 0xd4: hyperstone_ldwp<GLOBAL>(); break; + case 0xd5: hyperstone_ldwp<LOCAL>(); break; + case 0xd6: hyperstone_lddp<GLOBAL>(); break; + case 0xd7: hyperstone_lddp<LOCAL>(); break; + case 0xd8: hyperstone_stwr<GLOBAL>(); break; + case 0xd9: hyperstone_stwr<LOCAL>(); break; + case 0xda: hyperstone_stdr<GLOBAL>(); break; + case 0xdb: hyperstone_stdr<LOCAL>(); break; + case 0xdc: hyperstone_stwp<GLOBAL>(); break; + case 0xdd: hyperstone_stwp<LOCAL>(); break; + case 0xde: hyperstone_stdp<GLOBAL>(); break; + case 0xdf: hyperstone_stdp<LOCAL>(); break; + case 0xe0: hyperstone_db<COND_V, IS_SET>(); break; + case 0xe1: hyperstone_db<COND_V, IS_CLEAR>(); break; + case 0xe2: hyperstone_db<COND_Z, IS_SET>(); break; + case 0xe3: hyperstone_db<COND_Z, IS_CLEAR>(); break; + case 0xe4: hyperstone_db<COND_C, IS_SET>(); break; + case 0xe5: hyperstone_db<COND_C, IS_CLEAR>(); break; + case 0xe6: hyperstone_db<COND_CZ, IS_SET>(); break; + case 0xe7: hyperstone_db<COND_CZ, IS_CLEAR>(); break; + case 0xe8: hyperstone_db<COND_N, IS_SET>(); break; + case 0xe9: hyperstone_db<COND_N, IS_CLEAR>(); break; + case 0xea: hyperstone_db<COND_NZ, IS_SET>(); break; + case 0xeb: hyperstone_db<COND_NZ, IS_CLEAR>(); break; + case 0xec: hyperstone_dbr(); break; + case 0xed: hyperstone_frame(); break; + case 0xee: hyperstone_call<GLOBAL>(); break; + case 0xef: hyperstone_call<LOCAL>(); break; + case 0xf0: hyperstone_b<COND_V, IS_SET>(); break; + case 0xf1: hyperstone_b<COND_V, IS_CLEAR>(); break; + case 0xf2: hyperstone_b<COND_Z, IS_SET>(); break; + case 0xf3: hyperstone_b<COND_Z, IS_CLEAR>(); break; + case 0xf4: hyperstone_b<COND_C, IS_SET>(); break; + case 0xf5: hyperstone_b<COND_C, IS_CLEAR>(); break; + case 0xf6: hyperstone_b<COND_CZ, IS_SET>(); break; + case 0xf7: hyperstone_b<COND_CZ, IS_CLEAR>(); break; + case 0xf8: hyperstone_b<COND_N, IS_SET>(); break; + case 0xf9: hyperstone_b<COND_N, IS_CLEAR>(); break; + case 0xfa: hyperstone_b<COND_NZ, IS_SET>(); break; + case 0xfb: hyperstone_b<COND_NZ, IS_CLEAR>(); break; + case 0xfc: hyperstone_br(); break; + case 0xfd: hyperstone_trap(); break; + case 0xfe: hyperstone_trap(); break; + case 0xff: hyperstone_trap(); break; + } /* clear the H state if it was previously set */ SR ^= oldh; - SET_ILC(m_instruction_length & 3); + SET_ILC(m_instruction_length); - if( GET_T && GET_P && m_delay.delay_cmd == NO_DELAY ) /* Not in a Delayed Branch instructions */ + if (GET_T && GET_P && !m_delay_slot) /* Not in a Delayed Branch instructions */ { uint32_t addr = get_trap_addr(TRAPNO_TRACE_EXCEPTION); execute_exception(addr); diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h index fd168d9eb75..acfeea49159 100644 --- a/src/devices/cpu/e132xs/e132xs.h +++ b/src/devices/cpu/e132xs/e132xs.h @@ -5,6 +5,10 @@ #pragma once +#include "cpu/drcfe.h" +#include "cpu/drcuml.h" +#include "cpu/drcumlsh.h" +#include "32xsdasm.h" /* A note about clock multipliers and dividers: @@ -22,23 +26,53 @@ -/* Functions */ - /*************************************************************************** - REGISTER ENUMERATION + CONSTANTS ***************************************************************************/ -extern unsigned dasm_hyperstone(std::ostream &stream, unsigned pc, const uint8_t *oprom, unsigned h_flag, int private_fp); +/* map variables */ +#define MAPVAR_PC M0 +#define MAPVAR_CYCLES M1 + +/* compilation boundaries -- how far back/forward does the analysis extend? */ +#define COMPILE_BACKWARDS_BYTES 128 +#define COMPILE_FORWARDS_BYTES 512 +#define COMPILE_MAX_INSTRUCTIONS ((COMPILE_BACKWARDS_BYTES/4) + (COMPILE_FORWARDS_BYTES/4)) +#define COMPILE_MAX_SEQUENCE 64 + +/* exit codes */ +#define EXECUTE_OUT_OF_CYCLES 0 +#define EXECUTE_MISSING_CODE 1 +#define EXECUTE_UNMAPPED_CODE 2 +#define EXECUTE_RESET_CACHE 3 + +#define E132XS_STRICT_VERIFY 0x0001 /* verify all instructions */ + +#define SINGLE_INSTRUCTION_MODE (1) + +#define ENABLE_E132XS_DRC (0) //************************************************************************** // TYPE DEFINITIONS //************************************************************************** +class e132xs_frontend; + // ======================> hyperstone_device // Used by core CPU interface -class hyperstone_device : public cpu_device +class hyperstone_device : public cpu_device, public hyperstone_disassembler::config { + friend class e132xs_frontend; + +public: + inline void ccfunc_unimplemented(); + inline void ccfunc_print(); + inline void ccfunc_total_cycles(); + void update_timer_prescale(); + void compute_tr(); + void adjust_timer_interrupt(); + protected: enum { @@ -96,6 +130,69 @@ protected: E132XS_L60, E132XS_L61, E132XS_L62, E132XS_L63 }; + enum reg_bank + { + LOCAL = 0, + GLOBAL = 1 + }; + + enum imm_size + { + SIMM = 0, + LIMM = 1 + }; + + enum shift_type + { + N_LO = 0, + N_HI = 1 + }; + + enum sign_mode + { + IS_UNSIGNED = 0, + IS_SIGNED = 1 + }; + + enum branch_condition + { + COND_V = 0, + COND_Z = 1, + COND_C = 2, + COND_CZ = 3, + COND_N = 4, + COND_NZ = 5 + }; + + enum condition_set + { + IS_CLEAR = 0, + IS_SET = 1 + }; + + enum + { + EXCEPTION_IO2 = 48, + EXCEPTION_IO1 = 49, + EXCEPTION_INT4 = 50, + EXCEPTION_INT3 = 51, + EXCEPTION_INT2 = 52, + EXCEPTION_INT1 = 53, + EXCEPTION_IO3 = 54, + EXCEPTION_TIMER = 55, + EXCEPTION_RESERVED1 = 56, + EXCEPTION_TRACE = 57, + EXCEPTION_PARITY_ERROR = 58, + EXCEPTION_EXTENDED_OVERFLOW = 59, + EXCEPTION_RANGE_ERROR = 60, + EXCEPTION_PRIVILEGE_ERROR = EXCEPTION_RANGE_ERROR, + EXCEPTION_FRAME_ERROR = EXCEPTION_RANGE_ERROR, + EXCEPTION_RESERVED2 = 61, + EXCEPTION_RESET = 62, // reserved if not mapped @ MEM3 + EXCEPTION_ERROR_ENTRY = 63, // for instruction code of all ones + EXCEPTION_COUNT + }; + // construction/destruction hyperstone_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, const device_type type, uint32_t prg_data_width, uint32_t io_data_width, address_map_constructor internal_map); @@ -118,9 +215,9 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual u8 get_fp() const override; + virtual bool get_h() const override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -129,22 +226,14 @@ protected: const address_space_config m_program_config; const address_space_config m_io_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; - /* Delay information */ - struct delay_info - { - int32_t delay_cmd; - uint32_t delay_pc; - }; - // CPU registers uint32_t m_global_regs[32]; uint32_t m_local_regs[64]; /* internal stuff */ - uint32_t m_ppc; // previous pc uint16_t m_op; // opcode uint32_t m_trap_entry; // entry point to get trap address @@ -152,16 +241,21 @@ protected: uint8_t m_clck_scale; uint8_t m_clock_cycles_1; uint8_t m_clock_cycles_2; + uint8_t m_clock_cycles_3; uint8_t m_clock_cycles_4; uint8_t m_clock_cycles_6; uint64_t m_tr_base_cycles; uint32_t m_tr_base_value; + uint32_t m_tr_result; uint32_t m_tr_clocks_per_tick; uint8_t m_timer_int_pending; emu_timer *m_timer; - delay_info m_delay; + uint64_t m_numcycles; + + uint32_t m_delay_pc; + uint32_t m_delay_slot; uint32_t m_opcodexor; @@ -171,33 +265,13 @@ protected: // other internal state int m_icount; - typedef void (hyperstone_device::*ophandler)(); - - ophandler m_opcode[256]; + uint8_t m_fl_lut[16]; + static const uint32_t s_trap_entries[8]; + static const int32_t s_immediate_values[16]; - static const ophandler s_opcodetable[256]; + uint32_t get_trap_addr(uint8_t trapno); private: - struct regs_decode - { - uint8_t src, dst; // destination and source register code - uint32_t src_value; // current source register value - uint32_t next_src_value; // current next source register value - uint32_t dst_value; // current destination register value - uint32_t next_dst_value; // current next destination register value - uint8_t sub_type; // sub type opcode (for DD and X_CODE bits) - union - { - uint32_t u; - int32_t s; - } extra; // extra value such as immediate value, const, pcrel, ... - uint8_t src_is_local; - uint8_t dst_is_local; - uint8_t same_src_dst; - uint8_t same_src_dstf; - uint8_t same_srcf_dst; - }; - // internal functions void check_interrupts(); @@ -206,174 +280,249 @@ private: uint32_t get_global_register(uint8_t code); - uint32_t get_trap_addr(uint8_t trapno); uint32_t get_emu_code_addr(uint8_t num); - void hyperstone_set_trap_entry(int which); - uint32_t compute_tr(); - void update_timer_prescale(); - void adjust_timer_interrupt(); TIMER_CALLBACK_MEMBER(timer_callback); - void execute_br(struct regs_decode *decode); - void execute_dbr(struct regs_decode *decode); + uint32_t decode_const(); + uint32_t decode_immediate_s(); + void ignore_immediate_s(); + int32_t decode_pcrel(); + void ignore_pcrel(); + + void hyperstone_br(); void execute_trap(uint32_t addr); void execute_int(uint32_t addr); void execute_exception(uint32_t addr); - void execute_software(struct regs_decode *decode); - - void hyperstone_chk(struct regs_decode *decode); - void hyperstone_movd(struct regs_decode *decode); - void hyperstone_divu(struct regs_decode *decode); - void hyperstone_divs(struct regs_decode *decode); - void hyperstone_xm(struct regs_decode *decode); - void hyperstone_mask(struct regs_decode *decode); - void hyperstone_sum(struct regs_decode *decode); - void hyperstone_sums(struct regs_decode *decode); - void hyperstone_cmp(struct regs_decode *decode); - void hyperstone_mov(struct regs_decode *decode); - void hyperstone_add(struct regs_decode *decode); - void hyperstone_adds(struct regs_decode *decode); - void hyperstone_cmpb(struct regs_decode *decode); - void hyperstone_andn(struct regs_decode *decode); - void hyperstone_or(struct regs_decode *decode); - void hyperstone_xor(struct regs_decode *decode); - void hyperstone_subc(struct regs_decode *decode); - void hyperstone_not(struct regs_decode *decode); - void hyperstone_sub(struct regs_decode *decode); - void hyperstone_subs(struct regs_decode *decode); - void hyperstone_addc(struct regs_decode *decode); - void hyperstone_and(struct regs_decode *decode); - void hyperstone_neg(struct regs_decode *decode); - void hyperstone_negs(struct regs_decode *decode); - void hyperstone_cmpi(struct regs_decode *decode); - void hyperstone_movi(struct regs_decode *decode); - void hyperstone_addi(struct regs_decode *decode); - void hyperstone_addsi(struct regs_decode *decode); - void hyperstone_cmpbi(struct regs_decode *decode); - void hyperstone_andni(struct regs_decode *decode); - void hyperstone_ori(struct regs_decode *decode); - void hyperstone_xori(struct regs_decode *decode); - void hyperstone_shrdi(struct regs_decode *decode); - void hyperstone_shrd(struct regs_decode *decode); - void hyperstone_shr(struct regs_decode *decode); - void hyperstone_shri(struct regs_decode *decode); - void hyperstone_sardi(struct regs_decode *decode); - void hyperstone_sard(struct regs_decode *decode); - void hyperstone_sar(struct regs_decode *decode); - void hyperstone_sari(struct regs_decode *decode); - void hyperstone_shldi(struct regs_decode *decode); - void hyperstone_shld(struct regs_decode *decode); - void hyperstone_shl(struct regs_decode *decode); - void hyperstone_shli(struct regs_decode *decode); - void hyperstone_testlz(struct regs_decode *decode); - void hyperstone_rol(struct regs_decode *decode); - void hyperstone_ldxx1(struct regs_decode *decode); - void hyperstone_ldxx2(struct regs_decode *decode); - void hyperstone_stxx1(struct regs_decode *decode); - void hyperstone_stxx2(struct regs_decode *decode); - void hyperstone_mulu(struct regs_decode *decode); - void hyperstone_muls(struct regs_decode *decode); - void hyperstone_mul(struct regs_decode *decode); - void hyperstone_set(struct regs_decode *decode); - - void hyperstone_fadd(struct regs_decode *decode); - void hyperstone_faddd(struct regs_decode *decode); - void hyperstone_fsub(struct regs_decode *decode); - void hyperstone_fsubd(struct regs_decode *decode); - void hyperstone_fmul(struct regs_decode *decode); - void hyperstone_fmuld(struct regs_decode *decode); - void hyperstone_fdiv(struct regs_decode *decode); - void hyperstone_fdivd(struct regs_decode *decode); - - void hyperstone_fcmp(struct regs_decode *decode); - void hyperstone_fcmpd(struct regs_decode *decode); - void hyperstone_fcmpu(struct regs_decode *decode); - void hyperstone_fcmpud(struct regs_decode *decode); - - void hyperstone_fcvt(struct regs_decode *decode); - void hyperstone_fcvtd(struct regs_decode *decode); - - void hyperstone_extend(struct regs_decode *decode); - - void hyperstone_ldwr(struct regs_decode *decode); - void hyperstone_lddr(struct regs_decode *decode); - void hyperstone_ldwp(struct regs_decode *decode); - void hyperstone_lddp(struct regs_decode *decode); - - void hyperstone_stwr(struct regs_decode *decode); - void hyperstone_stdr(struct regs_decode *decode); - void hyperstone_stwp(struct regs_decode *decode); - void hyperstone_stdp(struct regs_decode *decode); - - void hyperstone_dbv(struct regs_decode *decode); - void hyperstone_dbnv(struct regs_decode *decode); - void hyperstone_dbe(struct regs_decode *decode); - void hyperstone_dbne(struct regs_decode *decode); - void hyperstone_dbc(struct regs_decode *decode); - void hyperstone_dbnc(struct regs_decode *decode); - void hyperstone_dbse(struct regs_decode *decode); - void hyperstone_dbht(struct regs_decode *decode); - void hyperstone_dbn(struct regs_decode *decode); - void hyperstone_dbnn(struct regs_decode *decode); - void hyperstone_dble(struct regs_decode *decode); - void hyperstone_dbgt(struct regs_decode *decode); - void hyperstone_dbr(struct regs_decode *decode); - - void hyperstone_frame(struct regs_decode *decode); - void hyperstone_call(struct regs_decode *decode); - - void hyperstone_bv(struct regs_decode *decode); - void hyperstone_bnv(struct regs_decode *decode); - void hyperstone_be(struct regs_decode *decode); - void hyperstone_bne(struct regs_decode *decode); - void hyperstone_bc(struct regs_decode *decode); - void hyperstone_bnc(struct regs_decode *decode); - void hyperstone_bse(struct regs_decode *decode); - void hyperstone_bht(struct regs_decode *decode); - void hyperstone_bn(struct regs_decode *decode); - void hyperstone_bnn(struct regs_decode *decode); - void hyperstone_ble(struct regs_decode *decode); - void hyperstone_bgt(struct regs_decode *decode); - void hyperstone_br(struct regs_decode *decode); - - void hyperstone_trap(struct regs_decode *decode); - void hyperstone_do(struct regs_decode *decode); - - void reserved(struct regs_decode *decode); - - void op00(); void op01(); void op02(); void op03(); void op04(); void op05(); void op06(); void op07(); - void op08(); void op09(); void op0a(); void op0b(); void op0c(); void op0d(); void op0e(); void op0f(); - void op10(); void op11(); void op12(); void op13(); void op14(); void op15(); void op16(); void op17(); - void op18(); void op19(); void op1a(); void op1b(); void op1c(); void op1d(); void op1e(); void op1f(); - void op20(); void op21(); void op22(); void op23(); void op24(); void op25(); void op26(); void op27(); - void op28(); void op29(); void op2a(); void op2b(); void op2c(); void op2d(); void op2e(); void op2f(); - void op30(); void op31(); void op32(); void op33(); void op34(); void op35(); void op36(); void op37(); - void op38(); void op39(); void op3a(); void op3b(); void op3c(); void op3d(); void op3e(); void op3f(); - void op40(); void op41(); void op42(); void op43(); void op44(); void op45(); void op46(); void op47(); - void op48(); void op49(); void op4a(); void op4b(); void op4c(); void op4d(); void op4e(); void op4f(); - void op50(); void op51(); void op52(); void op53(); void op54(); void op55(); void op56(); void op57(); - void op58(); void op59(); void op5a(); void op5b(); void op5c(); void op5d(); void op5e(); void op5f(); - void op60(); void op61(); void op62(); void op63(); void op64(); void op65(); void op66(); void op67(); - void op68(); void op69(); void op6a(); void op6b(); void op6c(); void op6d(); void op6e(); void op6f(); - void op70(); void op71(); void op72(); void op73(); void op74(); void op75(); void op76(); void op77(); - void op78(); void op79(); void op7a(); void op7b(); void op7c(); void op7d(); void op7e(); void op7f(); - void op80(); void op81(); void op82(); void op83(); void op84(); void op85(); void op86(); void op87(); - void op88(); void op89(); void op8a(); void op8b(); void op8c(); void op8d(); void op8e(); void op8f(); - void op90(); void op91(); void op92(); void op93(); void op94(); void op95(); void op96(); void op97(); - void op98(); void op99(); void op9a(); void op9b(); void op9c(); void op9d(); void op9e(); void op9f(); - void opa0(); void opa1(); void opa2(); void opa3(); void opa4(); void opa5(); void opa6(); void opa7(); - void opa8(); void opa9(); void opaa(); void opab(); void opac(); void opad(); void opae(); void opaf(); - void opb0(); void opb1(); void opb2(); void opb3(); void opb4(); void opb5(); void opb6(); void opb7(); - void opb8(); void opb9(); void opba(); void opbb(); void opbc(); void opbd(); void opbe(); void opbf(); - void opc0(); void opc1(); void opc2(); void opc3(); void opc4(); void opc5(); void opc6(); void opc7(); - void opc8(); void opc9(); void opca(); void opcb(); void opcc(); void opcd(); void opce(); void opcf(); - void opd0(); void opd1(); void opd2(); void opd3(); void opd4(); void opd5(); void opd6(); void opd7(); - void opd8(); void opd9(); void opda(); void opdb(); void opdc(); void opdd(); void opde(); void opdf(); - void ope0(); void ope1(); void ope2(); void ope3(); void ope4(); void ope5(); void ope6(); void ope7(); - void ope8(); void ope9(); void opea(); void opeb(); void opec(); void oped(); void opee(); void opef(); - void opf0(); void opf1(); void opf2(); void opf3(); void opf4(); void opf5(); void opf6(); void opf7(); - void opf8(); void opf9(); void opfa(); void opfb(); void opfc(); void opfd(); void opfe(); void opff(); + void execute_software(); + + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_chk(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_movd(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void hyperstone_divsu(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_xm(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mask(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_sum(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_sums(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_cmp(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mov(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_add(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_adds(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_cmpb(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_subc(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_sub(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_subs(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_addc(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_neg(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_negs(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_and(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_andn(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_or(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_xor(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_not(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_cmpi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_movi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_addi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_addsi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_cmpbi(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_andni(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_ori(); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void hyperstone_xori(); + template <shift_type HI_N> void hyperstone_shrdi(); + void hyperstone_shrd(); + void hyperstone_shr(); + template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_shri(); + template <shift_type HI_N> void hyperstone_sardi(); + void hyperstone_sard(); + void hyperstone_sar(); + template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_sari(); + template <shift_type HI_N> void hyperstone_shldi(); + void hyperstone_shld(); + void hyperstone_shl(); + template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_shli(); + void hyperstone_testlz(); + void hyperstone_rol(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_ldxx1(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_ldxx2(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_stxx1(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_stxx2(); + + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void hyperstone_mulsu(); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void hyperstone_mul(); + + template <shift_type HI_N, reg_bank DST_GLOBAL> void hyperstone_set(); + + template <reg_bank SRC_GLOBAL> void hyperstone_ldwr(); + template <reg_bank SRC_GLOBAL> void hyperstone_lddr(); + template <reg_bank SRC_GLOBAL> void hyperstone_ldwp(); + template <reg_bank SRC_GLOBAL> void hyperstone_lddp(); + + template <reg_bank SRC_GLOBAL> void hyperstone_stwr(); + template <reg_bank SRC_GLOBAL> void hyperstone_stdr(); + template <reg_bank SRC_GLOBAL> void hyperstone_stwp(); + template <reg_bank SRC_GLOBAL> void hyperstone_stdp(); + + template <branch_condition CONDITION, condition_set COND_SET> void hyperstone_b(); + template <branch_condition CONDITION, condition_set COND_SET> void hyperstone_db(); + void hyperstone_dbr(); + + void hyperstone_frame(); + template <hyperstone_device::reg_bank SRC_GLOBAL> void hyperstone_call(); + + void hyperstone_trap(); + void hyperstone_extend(); + + void hyperstone_reserved(); + void hyperstone_do(); + + drc_cache m_cache; + std::unique_ptr<drcuml_state> m_drcuml; + std::unique_ptr<e132xs_frontend> m_drcfe; + uint32_t m_drcoptions; + uint8_t m_cache_dirty; + + uml::parameter m_regmap[16]; + + uml::code_handle *m_entry; + uml::code_handle *m_nocode; + uml::code_handle *m_out_of_cycles; + + uint32_t m_drc_arg0; + uint32_t m_drc_arg1; + uint32_t m_drc_arg2; + uint32_t m_drc_arg3; + uint32_t m_branch_dest; + + uml::code_handle *m_mem_read8; + uml::code_handle *m_mem_write8; + uml::code_handle *m_mem_read16; + uml::code_handle *m_mem_write16; + uml::code_handle *m_mem_read32; + uml::code_handle *m_mem_write32; + uml::code_handle *m_io_read32; + uml::code_handle *m_io_write32; + uml::code_handle *m_exception[EXCEPTION_COUNT]; + + bool m_enable_drc; + + /* internal compiler state */ + struct compiler_state + { + uint32_t m_cycles; /* accumulated cycles */ + uint8_t m_checkints; /* need to check interrupts before next instruction */ + uml::code_label m_labelnum; /* index for local labels */ + }; + + void execute_run_drc(); + void flush_drc_cache(); + void code_flush_cache(); + void code_compile_block(offs_t pc); + //void load_fast_iregs(drcuml_block *block); + //void save_fast_iregs(drcuml_block *block); + void static_generate_entry_point(); + void static_generate_nocode_handler(); + void static_generate_out_of_cycles(); + void static_generate_exception(uint32_t exception, const char *name); + void static_generate_memory_accessor(int size, int iswrite, bool isio, const char *name, uml::code_handle *&handleptr); + void generate_delay_slot_and_branch(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param); + 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 log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op); + bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + void generate_get_trap_addr(drcuml_block *block, uml::code_label &label, uint32_t trapno); + void generate_check_delay_pc(drcuml_block *block); + void generate_decode_const(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_decode_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_ignore_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_decode_pcrel(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_ignore_pcrel(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + void generate_set_global_register(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + void generate_trap(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr); + void generate_int(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr); + void generate_exception(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr); + void generate_software(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_chk(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_movd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void generate_divsu(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_xm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_mask(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_sum(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_sums(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_cmp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_mov(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_add(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_adds(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_cmpb(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_subc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_sub(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_subs(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_addc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_neg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_negs(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_and(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_andn(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_or(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_xor(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_not(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_cmpi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_addi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_addsi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_cmpbi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_andni(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_ori(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, imm_size IMM_LONG> void generate_xori(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <shift_type HI_N> void generate_shrdi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_shrd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_shr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_shri(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <shift_type HI_N> void generate_sardi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_sard(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_sar(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_sari(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <shift_type HI_N> void generate_shldi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_shld(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_shl(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_shli(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_testlz(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_rol(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_ldxx1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_ldxx2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_stxx1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_stxx2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL, sign_mode SIGNED> void generate_mulsu(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank DST_GLOBAL, reg_bank SRC_GLOBAL> void generate_mul(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + template <shift_type HI_N, reg_bank DST_GLOBAL> void generate_set(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + template <reg_bank SRC_GLOBAL> void generate_ldwr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank SRC_GLOBAL> void generate_lddr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank SRC_GLOBAL> void generate_ldwp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank SRC_GLOBAL> void generate_lddp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + template <reg_bank SRC_GLOBAL> void generate_stwr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank SRC_GLOBAL> void generate_stdr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank SRC_GLOBAL> void generate_stwp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <reg_bank SRC_GLOBAL> void generate_stdp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + template <branch_condition CONDITION, condition_set COND_SET> void generate_b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_br(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <branch_condition CONDITION, condition_set COND_SET> void generate_db(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_dbr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + void generate_frame(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + template <hyperstone_device::reg_bank SRC_GLOBAL> void generate_call(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + void generate_trap_op(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_extend(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + + void generate_reserved(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); + void generate_do(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); }; // device type definition @@ -574,4 +723,5 @@ protected: virtual void device_start() override; }; + #endif // MAME_CPU_E132XS_E132XS_H diff --git a/src/devices/cpu/e132xs/e132xsdrc.cpp b/src/devices/cpu/e132xs/e132xsdrc.cpp new file mode 100644 index 00000000000..d6c2bed25b1 --- /dev/null +++ b/src/devices/cpu/e132xs/e132xsdrc.cpp @@ -0,0 +1,973 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz + +#include "e132xs.h" +#include "e132xsfe.h" +#include "32xsdefs.h" + +using namespace uml; + +#define DRC_PC mem(m_global_regs) +#define DRC_SR mem(&m_global_regs[1]) + +void hyperstone_device::execute_run_drc() +{ + drcuml_state *drcuml = m_drcuml.get(); + int execute_result; + + /* reset the cache if dirty */ + if (m_cache_dirty) + { + code_flush_cache(); + m_cache_dirty = false; + } + + + /* execute */ + do + { + /* run as much as we can */ + execute_result = drcuml->execute(*m_entry); + + /* if we need to recompile, do it */ + if (execute_result == EXECUTE_MISSING_CODE) + { + code_compile_block(m_global_regs[0]); + } + else if (execute_result == EXECUTE_UNMAPPED_CODE) + { + fatalerror("Attempted to execute unmapped code at PC=%08X\n", m_global_regs[0]); + } + else if (execute_result == EXECUTE_RESET_CACHE) + { + code_flush_cache(); + } + } while (execute_result != EXECUTE_OUT_OF_CYCLES); +} + + +/*************************************************************************** + C FUNCTION CALLBACKS +***************************************************************************/ + +/*------------------------------------------------- + cfunc_unimplemented - handler for + unimplemented opcdes +-------------------------------------------------*/ + +inline void hyperstone_device::ccfunc_unimplemented() +{ + fatalerror("PC=%08X: Unimplemented op %08X\n", PC, m_drc_arg0); +} + +inline void hyperstone_device::ccfunc_print() +{ + printf("%c: %08X\n", (char)m_drc_arg0, m_drc_arg1); +} + +static void cfunc_unimplemented(void *param) +{ + ((hyperstone_device *)param)->ccfunc_unimplemented(); +} + +static void cfunc_adjust_timer_interrupt(void *param) +{ + ((hyperstone_device *)param)->adjust_timer_interrupt(); +} + +static void cfunc_compute_tr(void *param) +{ + ((hyperstone_device *)param)->compute_tr(); +} + +static void cfunc_update_timer_prescale(void *param) +{ + ((hyperstone_device *)param)->update_timer_prescale(); +} + +/* +static void cfunc_print(void *param) +{ + ((hyperstone_device *)param)->ccfunc_print(); +} +*/ + +/*------------------------------------------------- + ccfunc_total_cycles - compute the total number + of cycles executed so far +-------------------------------------------------*/ + +void hyperstone_device::ccfunc_total_cycles() +{ + m_numcycles = total_cycles(); +} + +static void cfunc_total_cycles(void *param) +{ + ((hyperstone_device *)param)->ccfunc_total_cycles(); +} + +/*************************************************************************** + CACHE MANAGEMENT +***************************************************************************/ + +/*------------------------------------------------- + flush_drc_cache - outward-facing accessor to + code_flush_cache +-------------------------------------------------*/ + +void hyperstone_device::flush_drc_cache() +{ + if (!m_enable_drc) + return; + m_cache_dirty = true; +} + +/*------------------------------------------------- + code_flush_cache - flush the cache and + regenerate static code +-------------------------------------------------*/ + +void hyperstone_device::code_flush_cache() +{ + /* empty the transient cache contents */ + m_drcuml->reset(); + + try + { + /* generate the entry point and out-of-cycles handlers */ + static_generate_entry_point(); + static_generate_nocode_handler(); + static_generate_out_of_cycles(); + + static_generate_exception(EXCEPTION_IO2, "io2"); + static_generate_exception(EXCEPTION_IO1, "io1"); + static_generate_exception(EXCEPTION_INT4, "int4"); + static_generate_exception(EXCEPTION_INT3, "int3"); + static_generate_exception(EXCEPTION_INT2, "int2"); + static_generate_exception(EXCEPTION_INT1, "int1"); + static_generate_exception(EXCEPTION_IO3, "io3"); + static_generate_exception(EXCEPTION_TIMER, "timer"); + static_generate_exception(EXCEPTION_RESERVED1, "reserved1"); + static_generate_exception(EXCEPTION_TRACE, "trace"); + static_generate_exception(EXCEPTION_PARITY_ERROR, "parity_error"); + static_generate_exception(EXCEPTION_EXTENDED_OVERFLOW, "extended_overflow"); + static_generate_exception(EXCEPTION_RANGE_ERROR, "range_error"); + static_generate_exception(EXCEPTION_RESERVED2, "reserved2"); + static_generate_exception(EXCEPTION_RESET, "reset"); + static_generate_exception(EXCEPTION_ERROR_ENTRY, "error_entry"); + + /* add subroutines for memory accesses */ + static_generate_memory_accessor(1, false, false, "read8", m_mem_read8); + static_generate_memory_accessor(1, true, false, "write8", m_mem_write8); + static_generate_memory_accessor(2, false, false, "read16", m_mem_read16); + static_generate_memory_accessor(2, true, false, "write16", m_mem_write16); + static_generate_memory_accessor(4, false, false, "read32", m_mem_read32); + static_generate_memory_accessor(4, true, false, "write32", m_mem_write32); + static_generate_memory_accessor(4, false, true, "ioread32", m_io_read32); + static_generate_memory_accessor(4, true, true, "iowrite32", m_io_write32); + } + + catch (drcuml_block::abort_compilation &) + { + fatalerror("Unable to generate static E132XS code\n"); fflush(stdout); + } +} + +/* Return the entry point for a determinated trap */ +void hyperstone_device::generate_get_trap_addr(drcuml_block *block, uml::code_label &label, uint32_t trapno) +{ + int no_mem3; + UML_MOV(block, I0, trapno); + UML_CMP(block, mem(&m_trap_entry), 0xffffff00); + UML_JMPc(block, uml::COND_NE, no_mem3 = label++); + UML_SUB(block, I0, 63, I0); + + UML_LABEL(block, no_mem3); + UML_SHL(block, I0, I0, 2); + UML_OR(block, I0, I0, mem(&m_trap_entry)); +} + +/*------------------------------------------------- + code_compile_block - compile a block of the + given mode at the specified pc +-------------------------------------------------*/ + +void hyperstone_device::code_compile_block(offs_t pc) +{ + drcuml_state *drcuml = m_drcuml.get(); + compiler_state compiler = { 0 }; + const opcode_desc *seqhead, *seqlast; + const opcode_desc *desclist; + int override = false; + drcuml_block *block; + + g_profiler.start(PROFILER_DRC_COMPILE); + + /* get a description of this sequence */ + desclist = m_drcfe->describe_code(pc); + + bool succeeded = false; + while (!succeeded) + { + try + { + /* start the block */ + block = drcuml->begin_block(4096); + + /* loop until we get through all instruction sequences */ + for (seqhead = desclist; seqhead != nullptr; seqhead = seqlast->next()) + { + const opcode_desc *curdesc; + uint32_t nextpc; + + /* add a code log entry */ + if (drcuml->logging()) + block->append_comment("-------------------------"); + + /* determine the last instruction in this sequence */ + for (seqlast = seqhead; seqlast != nullptr; seqlast = seqlast->next()) + if (seqlast->flags & OPFLAG_END_SEQUENCE) + break; + assert(seqlast != nullptr); + + /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ + if (override || !drcuml->hash_exists(0, seqhead->pc)) + UML_HASH(block, 0, seqhead->pc); + + /* if we already have a hash, and this is the first sequence, assume that we */ + /* are recompiling due to being out of sync and allow future overrides */ + else if (seqhead == desclist) + { + override = true; + UML_HASH(block, 0, seqhead->pc); + } + + /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ + else + { + UML_LABEL(block, seqhead->pc | 0x80000000); + UML_HASHJMP(block, 0, seqhead->pc, *m_nocode); + continue; + } + + /* validate this code block if we're not pointing into ROM */ + if (m_program->get_write_ptr(seqhead->physpc) != nullptr) + generate_checksum_block(block, &compiler, seqhead, seqlast); + + /* label this instruction, if it may be jumped to locally */ + if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) + UML_LABEL(block, seqhead->pc | 0x80000000); + + /* iterate over instructions in the sequence and compile them */ + for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) + { + generate_sequence_instruction(block, &compiler, curdesc); + } + + /* if we need to return to the start, do it */ + if (seqlast->flags & OPFLAG_RETURN_TO_START) + nextpc = pc; + + /* otherwise we just go to the next instruction */ + else + { + nextpc = seqlast->pc + seqlast->length; + } + + /* count off cycles and go there */ + generate_update_cycles(block, &compiler, nextpc); // <subtract cycles> + + /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ + if (seqlast->next() == nullptr || seqlast->next()->pc != nextpc) + { + UML_HASHJMP(block, 0, nextpc, *m_nocode); // hashjmp <mode>,nextpc,nocode + } + } + + /* end the sequence */ + block->end(); + g_profiler.stop(); + succeeded = true; + } + catch (drcuml_block::abort_compilation &) + { + code_flush_cache(); + } + } +} + +/*************************************************************************** + STATIC CODEGEN +***************************************************************************/ + +/*------------------------------------------------- + epc - compute the exception PC from a + descriptor +-------------------------------------------------*/ + +static inline uint32_t epc(const opcode_desc *desc) +{ + return (desc->flags & OPFLAG_IN_DELAY_SLOT) ? (desc->pc - 3) : desc->pc; +} + + +/*------------------------------------------------- + alloc_handle - allocate a handle if not + already allocated +-------------------------------------------------*/ + +static inline void alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name) +{ + if (*handleptr == nullptr) + *handleptr = drcuml->handle_alloc(name); +} + + + +/*------------------------------------------------- + static_generate_exception - generate an + exception handler +-------------------------------------------------*/ + +void hyperstone_device::static_generate_exception(uint32_t exception, const char *name) +{ + code_handle *&exception_handle = m_exception[exception]; + drcuml_state *drcuml = m_drcuml.get(); + drcuml_block *block = drcuml->begin_block(1024); + + /* add a global entry for this */ + alloc_handle(drcuml, &exception_handle, name); + UML_HANDLE(block, *exception_handle); + + uml::code_label label = 1; + generate_get_trap_addr(block, label, exception); + UML_ROLAND(block, I1, DRC_SR, 7, 0x7f); + UML_ROLAND(block, I2, DRC_SR, 11, 0xf); + UML_TEST(block, I2, 0xf); + UML_MOVc(block, uml::COND_Z, I2, 16); + UML_ADD(block, I1, I1, I2); + + UML_AND(block, DRC_SR, DRC_SR, 0xffe7ffff); + UML_OR(block, DRC_SR, DRC_SR, mem(&m_instruction_length)); + + UML_MOV(block, I4, DRC_SR); + UML_ROLINS(block, DRC_SR, 2, 21, 0x01e00000); + UML_ROLINS(block, DRC_SR, I1, 25, 0xfe000000); + + UML_AND(block, I3, I1, 0x3f); + UML_AND(block, I1, DRC_PC, ~1); + UML_ROLAND(block, I2, DRC_SR, 14, 1); + UML_OR(block, I1, I1, I2); + UML_STORE(block, (void *)m_local_regs, I3, I1, SIZE_DWORD, SCALE_x4); + UML_ADD(block, I3, I3, 1); + UML_AND(block, I3, I3, 0x3f); + UML_STORE(block, (void *)m_local_regs, I3, I4, SIZE_DWORD, SCALE_x4); + + UML_AND(block, DRC_SR, DRC_SR, ~(M_MASK | T_MASK)); + UML_OR(block, DRC_SR, DRC_SR, (L_MASK | S_MASK)); + + UML_MOV(block, DRC_PC, I0); + UML_SUB(block, mem(&m_icount), mem(&m_icount), 2); + UML_EXHc(block, COND_S, *m_out_of_cycles, 0); + + UML_HASHJMP(block, 0, I0, *m_nocode);// hashjmp <mode>,i0,nocode + + block->end(); +} + + + +/*------------------------------------------------- + generate_entry_point - generate a + static entry point +-------------------------------------------------*/ + +void hyperstone_device::static_generate_entry_point() +{ + drcuml_state *drcuml = m_drcuml.get(); + drcuml_block *block; + + /* begin generating */ + block = drcuml->begin_block(20); + + /* forward references */ + alloc_handle(drcuml, &m_nocode, "nocode"); + + alloc_handle(drcuml, &m_entry, "entry"); + UML_HANDLE(block, *m_entry); + + /* load fast integer registers */ + //load_fast_iregs(block); + + /* generate a hash jump via the current mode and PC */ + UML_HASHJMP(block, 0, mem(&m_global_regs[0]), *m_nocode); + block->end(); +} + + +/*------------------------------------------------- + static_generate_nocode_handler - generate an + exception handler for "out of code" +-------------------------------------------------*/ + +void hyperstone_device::static_generate_nocode_handler() +{ + drcuml_state *drcuml = m_drcuml.get(); + drcuml_block *block; + + /* begin generating */ + block = drcuml->begin_block(10); + + /* generate a hash jump via the current mode and PC */ + alloc_handle(drcuml, &m_nocode, "nocode"); + UML_HANDLE(block, *m_nocode); + UML_GETEXP(block, I0); + UML_MOV(block, mem(&PC), I0); + //save_fast_iregs(block); + UML_EXIT(block, EXECUTE_MISSING_CODE); + + block->end(); +} + + +/*------------------------------------------------- + static_generate_out_of_cycles - generate an + out of cycles exception handler +-------------------------------------------------*/ + +void hyperstone_device::static_generate_out_of_cycles() +{ + drcuml_state *drcuml = m_drcuml.get(); + drcuml_block *block; + + /* begin generating */ + block = drcuml->begin_block(10); + + /* generate a hash jump via the current mode and PC */ + alloc_handle(drcuml, &m_out_of_cycles, "out_of_cycles"); + UML_HANDLE(block, *m_out_of_cycles); + UML_GETEXP(block, I0); + UML_MOV(block, mem(&m_global_regs[0]), I0); + //save_fast_iregs(block); + UML_EXIT(block, EXECUTE_OUT_OF_CYCLES); + + block->end(); +} + +/*------------------------------------------------------------------ + static_generate_memory_accessor +------------------------------------------------------------------*/ + +void hyperstone_device::static_generate_memory_accessor(int size, int iswrite, bool isio, const char *name, code_handle *&handleptr) +{ + /* on entry, address is in I0; data for writes is in I1 */ + /* on exit, read result is in I1 */ + /* routine trashes I0-I1 */ + drcuml_state *drcuml = m_drcuml.get(); + drcuml_block *block; + + /* begin generating */ + block = drcuml->begin_block(1024); + + /* add a global entry for this */ + alloc_handle(drcuml, &handleptr, name); + UML_HANDLE(block, *handleptr); + + // write: + switch (size) + { + case 1: + if (iswrite) + UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM); + else + UML_READ(block, I1, I0, SIZE_BYTE, SPACE_PROGRAM); + break; + + case 2: + if (iswrite) + UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); + else + UML_READ(block, I1, I0, SIZE_WORD, SPACE_PROGRAM); + break; + + case 4: + if (iswrite) + UML_WRITE(block, I0, I1, SIZE_DWORD, isio ? SPACE_IO : SPACE_PROGRAM); + else + UML_READ(block, I1, I0, SIZE_DWORD, isio ? SPACE_IO : SPACE_PROGRAM); + break; + } + UML_RET(block); + + block->end(); +} + + + +/*************************************************************************** + CODE GENERATION +***************************************************************************/ + +/*------------------------------------------------- + generate_update_cycles - generate code to + subtract cycles from the icount and generate + an exception if out +-------------------------------------------------*/ + +void hyperstone_device::generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param) +{ + /* account for cycles */ + if (compiler->m_cycles > 0) + { + UML_SUB(block, mem(&m_icount), mem(&m_icount), MAPVAR_CYCLES); + UML_MAPVAR(block, MAPVAR_CYCLES, 0); + UML_EXHc(block, COND_S, *m_out_of_cycles, param); + } + compiler->m_cycles = 0; +} + +/*------------------------------------------------- + generate_checksum_block - generate code to + validate a sequence of opcodes +-------------------------------------------------*/ + +void hyperstone_device::generate_checksum_block(drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast) +{ + const opcode_desc *curdesc; + if (m_drcuml->logging()) + { + block->append_comment("[Validation for %08X]", seqhead->pc); + } + /* loose verify or single instruction: just compare and fail */ + if (!(m_drcoptions & E132XS_STRICT_VERIFY) || seqhead->next() == nullptr) + { + if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) + { + uint32_t sum = seqhead->opptr.w[0]; + void *base = m_direct->read_ptr(seqhead->physpc); + UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); + + if (seqhead->delay.first() != nullptr && seqhead->physpc != seqhead->delay.first()->physpc) + { + base = m_direct->read_ptr(seqhead->delay.first()->physpc); + assert(base != nullptr); + UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2); + UML_ADD(block, I0, I0, I1); + + sum += seqhead->delay.first()->opptr.w[0]; + } + + UML_CMP(block, I0, sum); + UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); + } + } + else /* full verification; sum up everything */ + { + void *base = m_direct->read_ptr(seqhead->physpc); + UML_LOAD(block, I0, base, 0, SIZE_WORD, SCALE_x2); + uint32_t sum = seqhead->opptr.w[0]; + for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) + if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) + { + base = m_direct->read_ptr(curdesc->physpc); + assert(base != nullptr); + UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2); + UML_ADD(block, I0, I0, I1); + sum += curdesc->opptr.w[0]; + + if (curdesc->delay.first() != nullptr && (curdesc == seqlast || (curdesc->next() != nullptr && curdesc->next()->physpc != curdesc->delay.first()->physpc))) + { + base = m_direct->read_ptr(curdesc->delay.first()->physpc); + assert(base != nullptr); + UML_LOAD(block, I1, base, 0, SIZE_WORD, SCALE_x2); + UML_ADD(block, I0, I0, I1); + + sum += curdesc->delay.first()->opptr.w[0]; + } + } + UML_CMP(block, I0, sum); + UML_EXHc(block, COND_NE, *m_nocode, epc(seqhead)); + } +} + + +/*------------------------------------------------- + log_add_disasm_comment - add a comment + including disassembly of a MIPS instruction +-------------------------------------------------*/ + +void hyperstone_device::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32_t op) +{ + if (m_drcuml->logging()) + { + block->append_comment("%08X: %08x", pc, op); + } +} + + +/*------------------------------------------------------------------ + generate_delay_slot_and_branch +------------------------------------------------------------------*/ + +void hyperstone_device::generate_delay_slot_and_branch(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + compiler_state compiler_temp = *compiler; + + /* fetch the target register if dynamic, in case it is modified by the delay slot */ + if (desc->targetpc == BRANCH_TARGET_DYNAMIC) + { + UML_MOV(block, mem(&m_branch_dest), I0); + } + + /* update the cycles and jump through the hash table to the target */ + if (desc->targetpc != BRANCH_TARGET_DYNAMIC) + { + generate_update_cycles(block, &compiler_temp, desc->targetpc); + if (desc->flags & OPFLAG_INTRABLOCK_BRANCH) + UML_JMP(block, desc->targetpc | 0x80000000); + else + UML_HASHJMP(block, 0, desc->targetpc, *m_nocode); + } + else + { + generate_update_cycles(block, &compiler_temp, mem(&m_branch_dest)); + UML_HASHJMP(block, 0, mem(&m_branch_dest), *m_nocode); + } + + /* update the label */ + compiler->m_labelnum = compiler_temp.m_labelnum; + + /* reset the mapvar to the current cycles */ + UML_MAPVAR(block, MAPVAR_CYCLES, compiler->m_cycles); +} + + +/*------------------------------------------------- + generate_sequence_instruction - generate code + for a single instruction in a sequence +-------------------------------------------------*/ + +void hyperstone_device::generate_sequence_instruction(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + offs_t expc; + + /* add an entry for the log */ + if (m_drcuml->logging() && !(desc->flags & OPFLAG_VIRTUAL_NOOP)) + log_add_disasm_comment(block, desc->pc, desc->opptr.w[0]); + + /* set the PC map variable */ + expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 3 : desc->pc; + UML_MAPVAR(block, MAPVAR_PC, expc); + + /* accumulate total cycles */ + compiler->m_cycles += desc->cycles; + + /* update the icount map variable */ + UML_MAPVAR(block, MAPVAR_CYCLES, compiler->m_cycles); + + /* if we are debugging, call the debugger */ + if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) + { + UML_MOV(block, DRC_PC, desc->pc); + //save_fast_iregs(block); + UML_DEBUG(block, desc->pc); + } + + if (!(desc->flags & OPFLAG_VIRTUAL_NOOP)) + { + /* compile the instruction */ + if (!generate_opcode(block, compiler, desc)) + { + UML_MOV(block, DRC_PC, desc->pc); + UML_MOV(block, mem(&m_drc_arg0), desc->opptr.w[0]); + UML_CALLC(block, cfunc_unimplemented, this); + } + } +} + +#include "e132xsdrc_ops.hxx" + +bool hyperstone_device::generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + uint32_t op = (uint32_t)desc->opptr.w[0]; + + UML_MOV(block, I0, op); + UML_AND(block, I7, DRC_SR, H_MASK); + UML_ADD(block, DRC_PC, DRC_PC, 2); + UML_MOV(block, mem(&m_instruction_length), (1 << 19)); + + switch (op >> 8) + { + case 0x00: generate_chk<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x01: generate_chk<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x02: generate_chk<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x03: generate_chk<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x04: generate_movd<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x05: generate_movd<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x06: generate_movd<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x07: generate_movd<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x08: generate_divsu<GLOBAL, GLOBAL, IS_UNSIGNED>(block, compiler, desc); break; + case 0x09: generate_divsu<GLOBAL, LOCAL, IS_UNSIGNED>(block, compiler, desc); break; + case 0x0a: generate_divsu<LOCAL, GLOBAL, IS_UNSIGNED>(block, compiler, desc); break; + case 0x0b: generate_divsu<LOCAL, LOCAL, IS_UNSIGNED>(block, compiler, desc); break; + case 0x0c: generate_divsu<GLOBAL, GLOBAL, IS_SIGNED>(block, compiler, desc); break; + case 0x0d: generate_divsu<GLOBAL, LOCAL, IS_SIGNED>(block, compiler, desc); break; + case 0x0e: generate_divsu<LOCAL, GLOBAL, IS_SIGNED>(block, compiler, desc); break; + case 0x0f: generate_divsu<LOCAL, LOCAL, IS_SIGNED>(block, compiler, desc); break; + case 0x10: generate_xm<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x11: generate_xm<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x12: generate_xm<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x13: generate_xm<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x14: generate_mask<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x15: generate_mask<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x16: generate_mask<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x17: generate_mask<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x18: generate_sum<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x19: generate_sum<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x1a: generate_sum<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x1b: generate_sum<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x1c: generate_sums<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x1d: generate_sums<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x1e: generate_sums<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x1f: generate_sums<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x20: generate_cmp<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x21: generate_cmp<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x22: generate_cmp<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x23: generate_cmp<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x24: generate_mov<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x25: generate_mov<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x26: generate_mov<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x27: generate_mov<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x28: generate_add<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x29: generate_add<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x2a: generate_add<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x2b: generate_add<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x2c: generate_adds<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x2d: generate_adds<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x2e: generate_adds<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x2f: generate_adds<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x30: generate_cmpb<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x31: generate_cmpb<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x32: generate_cmpb<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x33: generate_cmpb<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x34: generate_andn<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x35: generate_andn<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x36: generate_andn<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x37: generate_andn<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x38: generate_or<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x39: generate_or<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x3a: generate_or<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x3b: generate_or<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x3c: generate_xor<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x3d: generate_xor<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x3e: generate_xor<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x3f: generate_xor<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x40: generate_subc<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x41: generate_subc<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x42: generate_subc<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x43: generate_subc<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x44: generate_not<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x45: generate_not<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x46: generate_not<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x47: generate_not<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x48: generate_sub<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x49: generate_sub<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x4a: generate_sub<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x4b: generate_sub<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x4c: generate_subs<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x4d: generate_subs<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x4e: generate_subs<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x4f: generate_subs<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x50: generate_addc<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x51: generate_addc<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x52: generate_addc<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x53: generate_addc<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x54: generate_and<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x55: generate_and<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x56: generate_and<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x57: generate_and<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x58: generate_neg<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x59: generate_neg<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x5a: generate_neg<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x5b: generate_neg<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x5c: generate_negs<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x5d: generate_negs<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x5e: generate_negs<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x5f: generate_negs<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x60: generate_cmpi<GLOBAL, SIMM>(block, compiler, desc); break; + case 0x61: generate_cmpi<GLOBAL, LIMM>(block, compiler, desc); break; + case 0x62: generate_cmpi<LOCAL, SIMM>(block, compiler, desc); break; + case 0x63: generate_cmpi<LOCAL, LIMM>(block, compiler, desc); break; + case 0x64: generate_movi<GLOBAL, SIMM>(block, compiler, desc); break; + case 0x65: generate_movi<GLOBAL, LIMM>(block, compiler, desc); break; + case 0x66: generate_movi<LOCAL, SIMM>(block, compiler, desc); break; + case 0x67: generate_movi<LOCAL, LIMM>(block, compiler, desc); break; + case 0x68: generate_addi<GLOBAL, SIMM>(block, compiler, desc); break; + case 0x69: generate_addi<GLOBAL, LIMM>(block, compiler, desc); break; + case 0x6a: generate_addi<LOCAL, SIMM>(block, compiler, desc); break; + case 0x6b: generate_addi<LOCAL, LIMM>(block, compiler, desc); break; + case 0x6c: generate_addsi<GLOBAL, SIMM>(block, compiler, desc); break; + case 0x6d: generate_addsi<GLOBAL, LIMM>(block, compiler, desc); break; + case 0x6e: generate_addsi<LOCAL, SIMM>(block, compiler, desc); break; + case 0x6f: generate_addsi<LOCAL, LIMM>(block, compiler, desc); break; + case 0x70: generate_cmpbi<GLOBAL, SIMM>(block, compiler, desc); break; + case 0x71: generate_cmpbi<GLOBAL, LIMM>(block, compiler, desc); break; + case 0x72: generate_cmpbi<LOCAL, SIMM>(block, compiler, desc); break; + case 0x73: generate_cmpbi<LOCAL, LIMM>(block, compiler, desc); break; + case 0x74: generate_andni<GLOBAL, SIMM>(block, compiler, desc); break; + case 0x75: generate_andni<GLOBAL, LIMM>(block, compiler, desc); break; + case 0x76: generate_andni<LOCAL, SIMM>(block, compiler, desc); break; + case 0x77: generate_andni<LOCAL, LIMM>(block, compiler, desc); break; + case 0x78: generate_ori<GLOBAL, SIMM>(block, compiler, desc); break; + case 0x79: generate_ori<GLOBAL, LIMM>(block, compiler, desc); break; + case 0x7a: generate_ori<LOCAL, SIMM>(block, compiler, desc); break; + case 0x7b: generate_ori<LOCAL, LIMM>(block, compiler, desc); break; + case 0x7c: generate_xori<GLOBAL, SIMM>(block, compiler, desc); break; + case 0x7d: generate_xori<GLOBAL, LIMM>(block, compiler, desc); break; + case 0x7e: generate_xori<LOCAL, SIMM>(block, compiler, desc); break; + case 0x7f: generate_xori<LOCAL, LIMM>(block, compiler, desc); break; + case 0x80: generate_shrdi<N_LO>(block, compiler, desc); break; + case 0x81: generate_shrdi<N_HI>(block, compiler, desc); break; + case 0x82: generate_shrd(block, compiler, desc); break; + case 0x83: generate_shr(block, compiler, desc); break; + case 0x84: generate_sardi<N_LO>(block, compiler, desc); break; + case 0x85: generate_sardi<N_HI>(block, compiler, desc); break; + case 0x86: generate_sard(block, compiler, desc); break; + case 0x87: generate_sar(block, compiler, desc); break; + case 0x88: generate_shldi<N_LO>(block, compiler, desc); break; + case 0x89: generate_shldi<N_HI>(block, compiler, desc); break; + case 0x8a: generate_shld(block, compiler, desc); break; + case 0x8b: generate_shl(block, compiler, desc); break; + case 0x8c: generate_reserved(block, compiler, desc); break; + case 0x8d: generate_reserved(block, compiler, desc); break; + case 0x8e: generate_testlz(block, compiler, desc); break; + case 0x8f: generate_rol(block, compiler, desc); break; + case 0x90: generate_ldxx1<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x91: generate_ldxx1<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x92: generate_ldxx1<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x93: generate_ldxx1<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x94: generate_ldxx2<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x95: generate_ldxx2<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x96: generate_ldxx2<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x97: generate_ldxx2<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x98: generate_stxx1<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x99: generate_stxx1<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x9a: generate_stxx1<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x9b: generate_stxx1<LOCAL, LOCAL>(block, compiler, desc); break; + case 0x9c: generate_stxx2<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0x9d: generate_stxx2<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0x9e: generate_stxx2<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0x9f: generate_stxx2<LOCAL, LOCAL>(block, compiler, desc); break; + case 0xa0: generate_shri<N_LO, GLOBAL>(block, compiler, desc); break; + case 0xa1: generate_shri<N_HI, GLOBAL>(block, compiler, desc); break; + case 0xa2: generate_shri<N_LO, LOCAL>(block, compiler, desc); break; + case 0xa3: generate_shri<N_HI, LOCAL>(block, compiler, desc); break; + case 0xa4: generate_sari<N_LO, GLOBAL>(block, compiler, desc); break; + case 0xa5: generate_sari<N_HI, GLOBAL>(block, compiler, desc); break; + case 0xa6: generate_sari<N_LO, LOCAL>(block, compiler, desc); break; + case 0xa7: generate_sari<N_HI, LOCAL>(block, compiler, desc); break; + case 0xa8: generate_shli<N_LO, GLOBAL>(block, compiler, desc); break; + case 0xa9: generate_shli<N_HI, GLOBAL>(block, compiler, desc); break; + case 0xaa: generate_shli<N_LO, LOCAL>(block, compiler, desc); break; + case 0xab: generate_shli<N_HI, LOCAL>(block, compiler, desc); break; + case 0xac: generate_reserved(block, compiler, desc); break; + case 0xad: generate_reserved(block, compiler, desc); break; + case 0xae: generate_reserved(block, compiler, desc); break; + case 0xaf: generate_reserved(block, compiler, desc); break; + case 0xb0: generate_mulsu<GLOBAL, GLOBAL, IS_UNSIGNED>(block, compiler, desc); break; + case 0xb1: generate_mulsu<GLOBAL, LOCAL, IS_UNSIGNED>(block, compiler, desc); break; + case 0xb2: generate_mulsu<LOCAL, GLOBAL, IS_UNSIGNED>(block, compiler, desc); break; + case 0xb3: generate_mulsu<LOCAL, LOCAL, IS_UNSIGNED>(block, compiler, desc); break; + case 0xb4: generate_mulsu<GLOBAL, GLOBAL, IS_SIGNED>(block, compiler, desc); break; + case 0xb5: generate_mulsu<GLOBAL, LOCAL, IS_SIGNED>(block, compiler, desc); break; + case 0xb6: generate_mulsu<LOCAL, GLOBAL, IS_SIGNED>(block, compiler, desc); break; + case 0xb7: generate_mulsu<LOCAL, LOCAL, IS_SIGNED>(block, compiler, desc); break; + case 0xb8: generate_set<N_LO, GLOBAL>(block, compiler, desc); break; + case 0xb9: generate_set<N_HI, GLOBAL>(block, compiler, desc); break; + case 0xba: generate_set<N_LO, LOCAL>(block, compiler, desc); break; + case 0xbb: generate_set<N_HI, LOCAL>(block, compiler, desc); break; + case 0xbc: generate_mul<GLOBAL, GLOBAL>(block, compiler, desc); break; + case 0xbd: generate_mul<GLOBAL, LOCAL>(block, compiler, desc); break; + case 0xbe: generate_mul<LOCAL, GLOBAL>(block, compiler, desc); break; + case 0xbf: generate_mul<LOCAL, LOCAL>(block, compiler, desc); break; + case 0xc0: generate_software(block, compiler, desc); break; // fadd + case 0xc1: generate_software(block, compiler, desc); break; // faddd + case 0xc2: generate_software(block, compiler, desc); break; // fsub + case 0xc3: generate_software(block, compiler, desc); break; // fsubd + case 0xc4: generate_software(block, compiler, desc); break; // fmul + case 0xc5: generate_software(block, compiler, desc); break; // fmuld + case 0xc6: generate_software(block, compiler, desc); break; // fdiv + case 0xc7: generate_software(block, compiler, desc); break; // fdivd + case 0xc8: generate_software(block, compiler, desc); break; // fcmp + case 0xc9: generate_software(block, compiler, desc); break; // fcmpd + case 0xca: generate_software(block, compiler, desc); break; // fcmpu + case 0xcb: generate_software(block, compiler, desc); break; // fcmpud + case 0xcc: generate_software(block, compiler, desc); break; // fcvt + case 0xcd: generate_software(block, compiler, desc); break; // fcvtd + case 0xce: generate_extend(block, compiler, desc); break; + case 0xcf: generate_do(block, compiler, desc); break; + case 0xd0: generate_ldwr<GLOBAL>(block, compiler, desc); break; + case 0xd1: generate_ldwr<LOCAL>(block, compiler, desc); break; + case 0xd2: generate_lddr<GLOBAL>(block, compiler, desc); break; + case 0xd3: generate_lddr<LOCAL>(block, compiler, desc); break; + case 0xd4: generate_ldwp<GLOBAL>(block, compiler, desc); break; + case 0xd5: generate_ldwp<LOCAL>(block, compiler, desc); break; + case 0xd6: generate_lddp<GLOBAL>(block, compiler, desc); break; + case 0xd7: generate_lddp<LOCAL>(block, compiler, desc); break; + case 0xd8: generate_stwr<GLOBAL>(block, compiler, desc); break; + case 0xd9: generate_stwr<LOCAL>(block, compiler, desc); break; + case 0xda: generate_stdr<GLOBAL>(block, compiler, desc); break; + case 0xdb: generate_stdr<LOCAL>(block, compiler, desc); break; + case 0xdc: generate_stwp<GLOBAL>(block, compiler, desc); break; + case 0xdd: generate_stwp<LOCAL>(block, compiler, desc); break; + case 0xde: generate_stdp<GLOBAL>(block, compiler, desc); break; + case 0xdf: generate_stdp<LOCAL>(block, compiler, desc); break; + case 0xe0: generate_db<COND_V, IS_SET>(block, compiler, desc); break; + case 0xe1: generate_db<COND_V, IS_CLEAR>(block, compiler, desc); break; + case 0xe2: generate_db<COND_Z, IS_SET>(block, compiler, desc); break; + case 0xe3: generate_db<COND_Z, IS_CLEAR>(block, compiler, desc); break; + case 0xe4: generate_db<COND_C, IS_SET>(block, compiler, desc); break; + case 0xe5: generate_db<COND_C, IS_CLEAR>(block, compiler, desc); break; + case 0xe6: generate_db<COND_CZ, IS_SET>(block, compiler, desc); break; + case 0xe7: generate_db<COND_CZ, IS_CLEAR>(block, compiler, desc); break; + case 0xe8: generate_db<COND_N, IS_SET>(block, compiler, desc); break; + case 0xe9: generate_db<COND_N, IS_CLEAR>(block, compiler, desc); break; + case 0xea: generate_db<COND_NZ, IS_SET>(block, compiler, desc); break; + case 0xeb: generate_db<COND_NZ, IS_CLEAR>(block, compiler, desc); break; + case 0xec: generate_dbr(block, compiler, desc); break; + case 0xed: generate_frame(block, compiler, desc); break; + case 0xee: generate_call<GLOBAL>(block, compiler, desc); break; + case 0xef: generate_call<LOCAL>(block, compiler, desc); break; + case 0xf0: generate_b<COND_V, IS_SET>(block, compiler, desc); break; + case 0xf1: generate_b<COND_V, IS_CLEAR>(block, compiler, desc); break; + case 0xf2: generate_b<COND_Z, IS_SET>(block, compiler, desc); break; + case 0xf3: generate_b<COND_Z, IS_CLEAR>(block, compiler, desc); break; + case 0xf4: generate_b<COND_C, IS_SET>(block, compiler, desc); break; + case 0xf5: generate_b<COND_C, IS_CLEAR>(block, compiler, desc); break; + case 0xf6: generate_b<COND_CZ, IS_SET>(block, compiler, desc); break; + case 0xf7: generate_b<COND_CZ, IS_CLEAR>(block, compiler, desc); break; + case 0xf8: generate_b<COND_N, IS_SET>(block, compiler, desc); break; + case 0xf9: generate_b<COND_N, IS_CLEAR>(block, compiler, desc); break; + case 0xfa: generate_b<COND_NZ, IS_SET>(block, compiler, desc); break; + case 0xfb: generate_b<COND_NZ, IS_CLEAR>(block, compiler, desc); break; + case 0xfc: generate_br(block, compiler, desc); break; + case 0xfd: generate_trap_op(block, compiler, desc); break; + case 0xfe: generate_trap_op(block, compiler, desc); break; + case 0xff: generate_trap_op(block, compiler, desc); break; + } + + UML_AND(block, DRC_SR, DRC_SR, ~ILC_MASK); + UML_OR(block, DRC_SR, DRC_SR, mem(&m_instruction_length)); + + int done; + UML_AND(block, I0, DRC_SR, (T_MASK | P_MASK)); + UML_CMP(block, I0, (T_MASK | P_MASK)); + UML_JMPc(block, uml::COND_NE, done = compiler->m_labelnum++); + UML_TEST(block, mem(&m_delay_slot), 1); + UML_EXHc(block, uml::COND_E, *m_exception[EXCEPTION_TRACE], 0); + + UML_LABEL(block, done); + UML_XOR(block, DRC_SR, DRC_SR, I7); + return true; +}
\ No newline at end of file diff --git a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx new file mode 100644 index 00000000000..e829cf070a1 --- /dev/null +++ b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx @@ -0,0 +1,1466 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz + +#include "e132xs.h" + +constexpr uint32_t WRITE_ONLY_REGMASK = (1 << BCR_REGISTER) | (1 << TPR_REGISTER) | (1 << FCR_REGISTER) | (1 << MCR_REGISTER); + +void hyperstone_device::generate_check_delay_pc(drcuml_block *block) +{ + /* if PC is used in a delay instruction, the delayed PC should be used */ + UML_TEST(block, mem(&m_delay_slot), 1); + UML_MOVc(block, uml::COND_NZ, DRC_PC, mem(&m_delay_pc)); + UML_MOVc(block, uml::COND_NZ, mem(&m_delay_slot), 0); +} + +void hyperstone_device::generate_decode_const(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + const uint16_t imm_1 = READ_OP(desc->pc + 2); + + if (imm_1 & 0x8000) + { + const uint16_t imm_2 = READ_OP(desc->pc + 4); + + uint32_t imm = imm_2; + imm |= ((imm_1 & 0x3fff) << 16); + + if (imm_1 & 0x4000) + imm |= 0xc0000000; + + UML_MOV(block, mem(&m_instruction_length), (3<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 4); + UML_MOV(block, I1, imm); + } + else + { + uint32_t imm = imm_1 & 0x3fff; + + if (imm_1 & 0x4000) + imm |= 0xffffc000; + + UML_MOV(block, mem(&m_instruction_length), (2<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 2); + UML_MOV(block, I1, imm); + } +} + +void hyperstone_device::generate_decode_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + uint16_t op = desc->opptr.w[0]; + + switch (op & 0xf) + { + case 0: + UML_MOV(block, I1, 16); + return; + case 1: + { + uint32_t extra_u = (READ_OP(desc->pc + 2) << 16) | READ_OP(desc->pc + 4); + UML_MOV(block, mem(&m_instruction_length), (3<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 4); + UML_MOV(block, I1, extra_u); + return; + } + case 2: + { + uint32_t extra_u = READ_OP(desc->pc + 2); + UML_MOV(block, mem(&m_instruction_length), (2<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 2); + UML_MOV(block, I1, extra_u); + return; + } + case 3: + { + uint32_t extra_u = 0xffff0000 | READ_OP(desc->pc + 2); + UML_MOV(block, mem(&m_instruction_length), (2<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 2); + UML_MOV(block, I1, extra_u); + return; + } + default: + UML_MOV(block, I1, s_immediate_values[op & 0xf]); + return; + } +} + +void hyperstone_device::generate_ignore_immediate_s(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + +void hyperstone_device::generate_decode_pcrel(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + +void hyperstone_device::generate_ignore_pcrel(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + +void hyperstone_device::generate_set_global_register(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + // Expects register index in I4, value in I5, clobbers I6 + int extended; + UML_CMP(block, I4, 16); + UML_JMPc(block, uml::COND_AE, extended = compiler->m_labelnum++); + + int generic_store, set_sr, done; + UML_CMP(block, I4, 1); + UML_JMPc(block, uml::COND_A, generic_store = compiler->m_labelnum++); + UML_JMPc(block, uml::COND_E, set_sr = compiler->m_labelnum++); + UML_AND(block, DRC_PC, I5, ~1); + generate_delay_slot_and_branch(block, compiler, desc); + UML_JMP(block, done = compiler->m_labelnum++); + + UML_LABEL(block, set_sr); + UML_ROLINS(block, DRC_SR, I5, 0, 0x0000ffff); + UML_AND(block, DRC_SR, DRC_SR, ~0x40); + UML_TEST(block, mem(&m_intblock), ~0); + UML_MOVc(block, uml::COND_Z, mem(&m_intblock), 1); + UML_JMP(block, done); + + UML_LABEL(block, generic_store); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_JMP(block, done); + + int above_bcr; + UML_LABEL(block, extended); + UML_CMP(block, I4, 17); + UML_JMPc(block, uml::COND_BE, generic_store); + UML_CMP(block, I4, BCR_REGISTER); + UML_JMPc(block, uml::COND_A, above_bcr = compiler->m_labelnum++); + UML_JMPc(block, uml::COND_E, generic_store); + + // SP or UB + UML_AND(block, I5, I5, ~3); + UML_JMP(block, generic_store); + + int set_tpr, set_tcr, set_tr, set_fcr; + UML_LABEL(block, above_bcr); + UML_CMP(block, I4, TCR_REGISTER); + UML_JMPc(block, uml::COND_B, set_tpr = compiler->m_labelnum++); + UML_JMPc(block, uml::COND_E, set_tcr = compiler->m_labelnum++); + // Above TCR + UML_CMP(block, I4, WCR_REGISTER); + UML_JMPc(block, uml::COND_B, set_tr = compiler->m_labelnum++); + UML_JMPc(block, uml::COND_E, generic_store); // WCR + // Above WCR + UML_CMP(block, I4, FCR_REGISTER); + UML_JMPc(block, uml::COND_B, done); // ISR - read only + UML_JMPc(block, uml::COND_E, set_fcr = compiler->m_labelnum++); + UML_CMP(block, I4, MCR_REGISTER); + UML_JMPc(block, uml::COND_A, generic_store); // regs 28..31 + // Set MCR + UML_ROLAND(block, I6, I5, 20, 0x7); + UML_LOAD(block, I6, (void *)s_trap_entries, I6, SIZE_DWORD, SCALE_x4); + UML_MOV(block, mem(&m_trap_entry), I6); + UML_JMP(block, generic_store); + + int skip_compute_tr; + UML_LABEL(block, set_tpr); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_TEST(block, I5, 0x80000000); + UML_JMPc(block, uml::COND_NZ, skip_compute_tr = compiler->m_labelnum++); + UML_CALLC(block, cfunc_compute_tr, this); + UML_CALLC(block, cfunc_update_timer_prescale, this); + UML_LABEL(block, skip_compute_tr); + UML_CALLC(block, cfunc_adjust_timer_interrupt, this); + UML_JMP(block, done); + + UML_LABEL(block, set_tcr); + UML_LOAD(block, I6, (void *)m_global_regs, I4, SIZE_DWORD, SCALE_x4); + UML_CMP(block, I6, I5); + UML_JMPc(block, uml::COND_E, done); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_CALLC(block, cfunc_adjust_timer_interrupt, this); + UML_CMP(block, mem(&m_intblock), 1); + UML_MOVc(block, uml::COND_L, mem(&m_intblock), 1); + UML_JMP(block, done); + + UML_LABEL(block, set_tr); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_MOV(block, mem(&m_tr_base_value), I5); + UML_CALLC(block, cfunc_total_cycles, this); + UML_DMOV(block, mem(&m_tr_base_cycles), mem(&m_numcycles)); + UML_CALLC(block, cfunc_adjust_timer_interrupt, this); + UML_JMP(block, done); + + int skip_adjust_timer; + UML_LABEL(block, set_fcr); + UML_LOAD(block, I6, (void *)m_global_regs, I4, SIZE_DWORD, SCALE_x4); + UML_XOR(block, I6, I6, I5); + UML_TEST(block, I6, 0x80000000); + UML_JMPc(block, uml::COND_Z, skip_adjust_timer = compiler->m_labelnum++); + UML_CALLC(block, cfunc_adjust_timer_interrupt, this); + UML_LABEL(block, skip_adjust_timer); + UML_STORE(block, (void *)m_global_regs, I4, I5, SIZE_DWORD, SCALE_x4); + UML_CMP(block, mem(&m_intblock), 1); + UML_MOVc(block, uml::COND_L, mem(&m_intblock), 1); + // Fall through to done + + UML_LABEL(block, done); +} + +void hyperstone_device::generate_trap(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr) +{ +} + +void hyperstone_device::generate_int(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr) +{ +} + +void hyperstone_device::generate_exception(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint32_t addr) +{ +} + +void hyperstone_device::generate_software(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_chk(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_movd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + generate_check_delay_pc(block); + + uint16_t op = desc->opptr.w[0]; + const uint32_t src_code = op & 0xf; + const uint32_t srcf_code = src_code + 1; + const uint32_t dst_code = (op & 0xf0) >> 4; + const uint32_t dstf_code = dst_code + 1; + + int done = compiler->m_labelnum++; + if (DST_GLOBAL && (dst_code == PC_REGISTER)) + { + if (SRC_GLOBAL && src_code < 2) + { + printf("Denoted PC or SR in RET instruction. PC = %08X\n", desc->pc); + return; + } + + UML_AND(block, I1, DRC_SR, (S_MASK | L_MASK)); + UML_LOAD(block, I2, (void *)m_global_regs, src_code, SIZE_DWORD, SCALE_x4); + UML_LOAD(block, I3, (void *)m_global_regs, srcf_code, SIZE_DWORD, SCALE_x4); + UML_AND(block, DRC_PC, I2, ~1); + UML_AND(block, DRC_SR, I3, 0xffe3ffff); + UML_ROLINS(block, DRC_SR, I2, S_SHIFT, S_MASK); + + UML_TEST(block, mem(&m_intblock), ~0); + UML_MOVc(block, uml::COND_Z, mem(&m_intblock), 1); + + UML_MOV(block, mem(&m_instruction_length), 0); + + int no_exception; + UML_AND(block, I2, DRC_SR, (S_MASK | L_MASK)); + UML_AND(block, I3, I1, I2); + UML_TEST(block, I3, S_MASK); + UML_JMPc(block, uml::COND_NZ, no_exception = compiler->m_labelnum++); // If S is set and unchanged, there won't be an exception. + + UML_XOR(block, I3, I1, I2); + UML_AND(block, I4, I3, I2); + UML_TEST(block, I4, S_MASK); + UML_EXHc(block, uml::COND_NZ, *m_exception[EXCEPTION_PRIVILEGE_ERROR], 0); // If S is newly set, it's a privilege error. + + UML_TEST(block, I3, L_MASK); + UML_JMPc(block, uml::COND_Z, no_exception); // If L is unchanged, there won't be an exception. + UML_TEST(block, I1, L_MASK); + UML_JMPc(block, uml::COND_NZ, no_exception); // If L was previously set, there won't be an exception. + UML_TEST(block, I2, S_MASK); + UML_EXHc(block, uml::COND_Z, *m_exception[EXCEPTION_PRIVILEGE_ERROR], 0); // If L is newly set and we are not in Supervisor mode, it's a privilege error. + + int diff_in_range; + UML_LABEL(block, no_exception); + UML_MOV(block, I0, mem(&SP)); + UML_ROLAND(block, I1, I0, 30, 0x7f); + UML_ROLAND(block, I2, DRC_SR, 7, 0x7f); + UML_SUB(block, I3, I2, I1); + UML_CMP(block, I3, -64); + UML_JMPc(block, uml::COND_L, done); + UML_CMP(block, I3, 64); + UML_JMPc(block, uml::COND_L, diff_in_range = compiler->m_labelnum++); + UML_OR(block, I3, I3, 0x80); + UML_SEXT(block, I3, I3, SIZE_BYTE); + UML_LABEL(block, diff_in_range); + + int pop_next; + UML_LABEL(block, pop_next = compiler->m_labelnum++); + UML_CMP(block, I3, 0); + UML_JMPc(block, uml::COND_GE, done); + UML_SUB(block, I0, I0, 4); + UML_CALLH(block, *m_mem_read32); + UML_ROLAND(block, I2, I0, 30, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + UML_ADD(block, I3, I3, 1); + UML_TEST(block, I3, ~0); + UML_JMP(block, pop_next); + } + else if (SRC_GLOBAL && (src_code == SR_REGISTER)) // Rd doesn't denote PC and Rs denotes SR + { + UML_OR(block, DRC_SR, DRC_SR, Z_MASK); + UML_AND(block, DRC_SR, DRC_SR, ~N_MASK); + if (DST_GLOBAL) + { + UML_MOV(block, I4, dst_code); + UML_MOV(block, I5, 0); + generate_set_global_register(block, compiler, desc); + UML_MOV(block, I4, dstf_code); + UML_MOV(block, I5, 0); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I0, DRC_SR, 7, 0x7f); + UML_ADD(block, I0, I0, dst_code); + UML_AND(block, I0, I0, 0x3f); + UML_STORE(block, (void *)m_local_regs, I0, 0, SIZE_DWORD, SCALE_x4); + UML_ADD(block, I0, I0, 1); + UML_AND(block, I0, I0, 0x3f); + UML_STORE(block, (void *)m_local_regs, I0, 0, SIZE_DWORD, SCALE_x4); + } + } + else // Rd doesn't denote PC and Rs doesn't denote SR + { + if (!SRC_GLOBAL || !DST_GLOBAL) + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + } + + if (SRC_GLOBAL) + { + UML_LOAD(block, I0, (void *)m_global_regs, src_code, SIZE_DWORD, SCALE_x4); + UML_LOAD(block, I1, (void *)m_global_regs, srcf_code, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ADD(block, I0, I3, src_code); + UML_AND(block, I0, I0, 0x3f); + UML_LOAD(block, I0, (void *)m_local_regs, I0, SIZE_DWORD, SCALE_x4); + UML_ADD(block, I1, I3, srcf_code); + UML_AND(block, I1, I1, 0x3f); + UML_LOAD(block, I1, (void *)m_local_regs, I0, SIZE_DWORD, SCALE_x4); + } + + UML_AND(block, DRC_SR, DRC_SR, ~(Z_MASK | N_MASK)); + + UML_OR(block, I2, I0, I1); + UML_TEST(block, I2, ~0); + UML_SETc(block, uml::COND_Z, I2); + UML_ROLINS(block, DRC_SR, I2, 0, Z_MASK); + + UML_TEST(block, I0, 0x80000000); + UML_SETc(block, uml::COND_NZ, I2); + UML_ROLINS(block, DRC_SR, I2, 0, N_MASK); + + if (DST_GLOBAL) + { + UML_MOV(block, I4, dst_code); + UML_MOV(block, I5, I0); + generate_set_global_register(block, compiler, desc); + UML_MOV(block, I4, dstf_code); + UML_MOV(block, I5, I1); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ADD(block, I2, I3, dst_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I0, SIZE_DWORD, SCALE_x4); + UML_ADD(block, I2, I3, dstf_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + } + + UML_LABEL(block, done); +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED> +void hyperstone_device::generate_divsu(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_xm(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_mask(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + uint16_t op = desc->opptr.w[0]; + const uint32_t src_code = op & 0xf; + const uint32_t dst_code = (op & 0xf0) >> 4; + + generate_decode_const(block, compiler, desc); + generate_check_delay_pc(block); + + if (!SRC_GLOBAL || !DST_GLOBAL) + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + } + + if (SRC_GLOBAL) + { + UML_LOAD(block, I2, (void *)m_global_regs, src_code, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ADD(block, I2, I3, src_code); + UML_AND(block, I2, I2, 0x3f); + UML_LOAD(block, I2, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + } + + UML_AND(block, I1, I2, I1); + + int skip_mask; + UML_AND(block, DRC_SR, DRC_SR, ~Z_MASK); + UML_TEST(block, I1, ~0); + UML_JMPc(block, uml::COND_NZ, skip_mask = compiler->m_labelnum++); + UML_OR(block, DRC_SR, DRC_SR, Z_MASK); + UML_LABEL(block, skip_mask); + + if (DST_GLOBAL) + { + UML_MOV(block, I4, dst_code); + UML_MOV(block, I5, I2); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ADD(block, I0, I3, dst_code); + UML_AND(block, I0, I0, 0x3f); + UML_STORE(block, (void *)m_local_regs, I0, I1, SIZE_DWORD, SCALE_x4); + } +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_sum(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + uint16_t op = desc->opptr.w[0]; + const uint32_t src_code = op & 0xf; + const uint32_t dst_code = (op & 0xf0) >> 4; + + generate_decode_const(block, compiler, desc); + generate_check_delay_pc(block); + + if (!SRC_GLOBAL || !DST_GLOBAL) + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + } + + if (SRC_GLOBAL) + { + UML_LOAD(block, I2, (void *)m_global_regs, src_code, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ADD(block, I2, I3, src_code); + UML_AND(block, I2, I2, 0x3f); + UML_LOAD(block, I2, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + } + + UML_DADD(block, I5, I1, I2); + + UML_AND(block, DRC_SR, DRC_SR, ~(C_MASK | V_MASK | Z_MASK | N_MASK)); + UML_DTEST(block, I5, 0x100000000U); + UML_SETc(block, uml::COND_NZ, I6); + UML_ROLINS(block, DRC_SR, I6, 0, C_MASK); + + UML_XOR(block, I1, I5, I2); + UML_XOR(block, I6, I5, I1); + UML_AND(block, I1, I1, I6); + UML_TEST(block, I1, 0x80000000); + UML_SETc(block, uml::COND_NZ, I6); + UML_ROLINS(block, DRC_SR, I6, 0, V_MASK); + + UML_TEST(block, I5, ~0); + UML_SETc(block, uml::COND_Z, I6); + UML_ROLINS(block, DRC_SR, I6, 0, Z_MASK); + + UML_TEST(block, I5, 0x80000000); + UML_SETc(block, uml::COND_NZ, I6); + UML_ROLINS(block, DRC_SR, I6, 0, N_MASK); + + if (DST_GLOBAL) + { + UML_MOV(block, I4, dst_code); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ADD(block, I0, I3, dst_code); + UML_AND(block, I2, I0, 0x3f); + UML_STORE(block, (void *)m_local_regs, I0, I1, SIZE_DWORD, SCALE_x4); + } +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_sums(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_cmp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_mov(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + uint16_t op = desc->opptr.w[0]; + const uint32_t src_code = op & 0xf; + const uint32_t dst_code = (op & 0xf0) >> 4; + + generate_check_delay_pc(block); + + if (DST_GLOBAL) + { + int no_exception; + UML_TEST(block, DRC_SR, H_MASK); + UML_JMPc(block, uml::COND_Z, no_exception = compiler->m_labelnum++); + UML_TEST(block, DRC_SR, S_MASK); + UML_JMPc(block, uml::COND_NZ, no_exception); + UML_EXH(block, *m_exception[EXCEPTION_PRIVILEGE_ERROR], 0); + UML_LABEL(block, no_exception); + } + + if (!SRC_GLOBAL || !DST_GLOBAL) + UML_ROLAND(block, I1, DRC_SR, 7, 0x7f); + + if (SRC_GLOBAL) + { + UML_TEST(block, DRC_SR, H_MASK); + UML_MOVc(block, uml::COND_NZ, I1, 16 + src_code); + UML_MOVc(block, uml::COND_Z, I1, src_code); + UML_LOAD(block, I5, (void *)m_global_regs, I1, SIZE_DWORD, SCALE_x4); + UML_SHL(block, I2, 1, I1); + UML_TEST(block, I2, WRITE_ONLY_REGMASK); + UML_MOVc(block, uml::COND_NZ, I5, 0); + } + else + { + UML_ADD(block, I2, I1, src_code); + UML_AND(block, I2, I2, 0x3f); + UML_LOAD(block, I5, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + } + + UML_AND(block, DRC_SR, DRC_SR, ~(Z_MASK | N_MASK)); + UML_TEST(block, I3, ~0); + UML_SETc(block, uml::COND_Z, I2); + UML_ROLINS(block, DRC_SR, I2, 0, Z_MASK); + UML_ROLINS(block, DRC_SR, I3, 3, N_MASK); + + if (DST_GLOBAL) + { + UML_TEST(block, DRC_SR, H_MASK); + UML_MOVc(block, uml::COND_NZ, I4, 16 + dst_code); + UML_MOVc(block, uml::COND_Z, I4, dst_code); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ADD(block, I2, I1, dst_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I5, SIZE_DWORD, SCALE_x4); + } +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_add(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_adds(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_cmpb(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_subc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_sub(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_subs(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_addc(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_neg(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_negs(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_and(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_andn(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_or(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_xor(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_not(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::generate_cmpi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + uint16_t op = desc->opptr.w[0]; + const uint32_t dst_code = (op & 0xf0) >> 4; + + if (IMM_LONG) + { + generate_decode_immediate_s(block, compiler, desc); // I1 <-- imm32 + } + else + { + UML_AND(block, I1, I0, 0xf); + } + + generate_check_delay_pc(block); + + if (DST_GLOBAL) + { + UML_LOAD(block, I2, (void *)m_global_regs, dst_code, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I3, dst_code); + UML_LOAD(block, I2, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + } + + UML_AND(block, DRC_SR, DRC_SR, ~(V_MASK | Z_MASK | N_MASK | C_MASK)); + UML_DSUB(block, I0, I2, I1); + + int no_v; + UML_XOR(block, I0, I0, I2); + UML_XOR(block, I3, I1, I2); + UML_AND(block, I0, I0, I3); + UML_TEST(block, I0, 0x80000000); + UML_JMPc(block, uml::COND_Z, no_v = compiler->m_labelnum++); + UML_OR(block, DRC_SR, DRC_SR, V_MASK); + UML_LABEL(block, no_v); + + int no_n; + UML_MOV(block, I3, 0); + UML_CMP(block, I2, I1); + UML_MOVc(block, uml::COND_E, I3, Z_MASK); + UML_MOVc(block, uml::COND_B, I3, C_MASK); + UML_JMPc(block, uml::COND_L, no_n = compiler->m_labelnum++); + UML_OR(block, I3, I3, N_MASK); + UML_LABEL(block, no_n); + UML_OR(block, DRC_SR, DRC_SR, I3); + + UML_CMP(block, I2, I1); + +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::generate_movi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + uint16_t op = desc->opptr.w[0]; + const uint32_t dst_code = (op & 0xf0) >> 4; + + if (IMM_LONG) + { + generate_decode_immediate_s(block, compiler, desc); // I1 <-- imm32 + } + else + { + UML_AND(block, I1, I0, 0xf); + } + + generate_check_delay_pc(block); + + int done, no_exception; + if (DST_GLOBAL) + { + UML_TEST(block, DRC_SR, H_MASK); + UML_JMPc(block, uml::COND_Z, no_exception = compiler->m_labelnum++); + UML_TEST(block, DRC_SR, S_MASK); + UML_JMPc(block, uml::COND_NZ, no_exception); + UML_EXH(block, *m_exception[EXCEPTION_PRIVILEGE_ERROR], 0); + UML_JMP(block, done = compiler->m_labelnum++); + UML_LABEL(block, no_exception); + } + + UML_AND(block, DRC_SR, DRC_SR, ~(Z_MASK | N_MASK)); + + int no_z; + UML_TEST(block, I1, ~0); + UML_JMPc(block, uml::COND_NZ, no_z = compiler->m_labelnum++); + UML_OR(block, DRC_SR, DRC_SR, Z_MASK); + UML_LABEL(block, no_z); + + int no_n; + UML_TEST(block, I1, 0x80000000); + UML_JMPc(block, uml::COND_Z, no_n = compiler->m_labelnum++); + UML_OR(block, DRC_SR, DRC_SR, N_MASK); + UML_LABEL(block, no_n); + +#if MISSIONCRAFT_FLAGS + UML_AND(block, DRC_SR, DRC_SR, ~V_MASK); +#endif + + if (DST_GLOBAL) + { + UML_TEST(block, DRC_SR, H_MASK); + UML_MOVc(block, uml::COND_NZ, I4, dst_code + 16); + UML_MOVc(block, uml::COND_Z, I4, dst_code); + UML_MOV(block, I5, I1); + generate_set_global_register(block, compiler, desc); + + UML_TEST(block, I0, 0xf0); + UML_JMPc(block, uml::COND_NZ, done); + UML_AND(block, DRC_SR, DRC_SR, ~M_MASK); + generate_delay_slot_and_branch(block, compiler, desc); + + UML_LABEL(block, done); + } + else + { + UML_ROLAND(block, I2, DRC_SR, 7, 0x7f); + UML_ADD(block, I0, I2, dst_code); + UML_AND(block, I0, I0, 0x3f); + UML_STORE(block, (void *)m_local_regs, I0, I1, SIZE_DWORD, SCALE_x4); + } +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::generate_addi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::generate_addsi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::generate_cmpbi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::generate_andni(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::generate_ori(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + uint16_t op = desc->opptr.w[0]; + const uint32_t dst_code = (op & 0xf0) >> 4; + + if (IMM_LONG) + { + generate_decode_immediate_s(block, compiler, desc); // I1 <-- imm32 + } + else + { + UML_AND(block, I1, I0, 0xf); + } + + generate_check_delay_pc(block); + + if (DST_GLOBAL) + { + UML_LOAD(block, I2, (void *)m_global_regs, dst_code, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I3, dst_code); + UML_LOAD(block, I2, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + } + + UML_AND(block, DRC_SR, DRC_SR, ~Z_MASK); + UML_OR(block, I5, I2, I1); + + if (DST_GLOBAL) + { + UML_MOV(block, I4, dst_code); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ADD(block, I4, I2, dst_code); + UML_AND(block, I4, I4, 0x3f); + UML_STORE(block, (void *)m_local_regs, I4, I5, SIZE_DWORD, SCALE_x4); + } +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::generate_xori(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::shift_type HI_N> +void hyperstone_device::generate_shrdi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_shrd(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_shr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::generate_shri(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::shift_type HI_N> +void hyperstone_device::generate_sardi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_sard(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_sar(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::generate_sari(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::shift_type HI_N> +void hyperstone_device::generate_shldi(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_shld(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_shl(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::generate_shli(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_testlz(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_rol(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_ldxx1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + const uint16_t op = desc->opptr.w[0]; + uint16_t next_1 = READ_OP(desc->pc + 2); + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(desc->pc + 4); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + + UML_MOV(block, mem(&m_instruction_length), (3<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 4); + } + else + { + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + + UML_MOV(block, mem(&m_instruction_length), (2<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 2); + } + + generate_check_delay_pc(block); + + const uint32_t src_code = op & 0xf; + const uint32_t srcf_code = src_code + 1; + const uint32_t dst_code = (op & 0xf0) >> 4; + + if (!DST_GLOBAL || dst_code != SR_REGISTER) + { + if (DST_GLOBAL) + UML_LOAD(block, I4, (void *)m_global_regs, dst_code, SIZE_DWORD, SCALE_x4); + else + UML_LOAD(block, I4, (void *)m_local_regs, dst_code, SIZE_DWORD, SCALE_x4); + UML_ADD(block, I6, I4, extra_s); + } + else + { + UML_MOV(block, I6, extra_s); + } + + switch (sub_type) + { + case 0: // LDBS.A + UML_MOV(block, I0, I6); + UML_CALLH(block, *m_mem_read8); + + if (SRC_GLOBAL) + { + UML_MOV(block, I4, src_code); + UML_SEXT(block, I5, I1, SIZE_BYTE); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I0, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I0, src_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + break; + + case 1: // LDBU.A + UML_MOV(block, I0, I6); + UML_CALLH(block, *m_mem_read8); + + if (SRC_GLOBAL) + { + UML_MOV(block, I4, src_code); + UML_MOV(block, I5, I1); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I0, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I0, src_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + break; + + case 2: + UML_AND(block, I6, I6, ~1); + UML_MOV(block, I0, I6); + UML_CALLH(block, *m_mem_read16); + + if (SRC_GLOBAL) + { + UML_MOV(block, I4, src_code); + if (extra_s & 1) // LDHS.A + UML_SEXT(block, I5, I1, SIZE_WORD); + else // LDHU.A + UML_MOV(block, I5, I1); + + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I0, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I0, src_code); + UML_AND(block, I2, I2, 0x3f); + if (extra_s & 1) + { + UML_SEXT(block, I5, I1, SIZE_WORD); + UML_STORE(block, (void *)m_local_regs, I2, I5, SIZE_DWORD, SCALE_x4); + } + else + { + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + } + break; + + case 3: + { + uint32_t switch_val = extra_s & 3; + UML_AND(block, I6, I6, ~3); + switch (switch_val) + { + case 0: // LDW.A + UML_MOV(block, I0, I6); + UML_CALLH(block, *m_mem_read32); + + if (SRC_GLOBAL) + { + UML_MOV(block, I5, I1); + UML_MOV(block, I4, src_code); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I0, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I0, src_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + break; + case 1: // LDD.A + UML_MOV(block, I0, I6); + UML_CALLH(block, *m_mem_read32); + + if (SRC_GLOBAL) + { + UML_MOV(block, I5, I1); + UML_MOV(block, I4, src_code); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I3, src_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + + UML_ADD(block, I0, I6, 4); + UML_CALLH(block, *m_mem_read32); + + if (SRC_GLOBAL) + { + UML_MOV(block, I5, I1); + UML_MOV(block, I4, srcf_code); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ADD(block, I2, I3, srcf_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + break; + case 2: // LDW.IOA + UML_MOV(block, I0, I6); + UML_CALLH(block, *m_io_read32); + + if (SRC_GLOBAL) + { + UML_MOV(block, I5, I1); + UML_MOV(block, I4, src_code); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I0, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I0, src_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + break; + + case 3: // LDD.IOA + UML_MOV(block, I0, I6); + UML_CALLH(block, *m_io_read32); + + if (SRC_GLOBAL) + { + UML_MOV(block, I5, I1); + UML_MOV(block, I4, src_code); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + UML_ADD(block, I2, I3, src_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + + UML_ADD(block, I0, I6, 4); + UML_CALLH(block, *m_io_read32); + + if (SRC_GLOBAL) + { + UML_MOV(block, I5, I1); + UML_MOV(block, I4, srcf_code); + generate_set_global_register(block, compiler, desc); + } + else + { + UML_ADD(block, I2, I3, srcf_code); + UML_AND(block, I2, I2, 0x3f); + UML_STORE(block, (void *)m_local_regs, I2, I1, SIZE_DWORD, SCALE_x4); + } + break; + } + break; + } + } +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_ldxx2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_stxx1(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +/* + const uint16_t op = desc->opptr.w[0]; + uint16_t next_1 = READ_OP(desc->pc + 2); + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(desc->pc + 4); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + + UML_MOV(block, mem(&m_instruction_length), (3<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 4); + } + else + { + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + + UML_MOV(block, mem(&m_instruction_length), (2<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 2); + } + + generate_check_delay_pc(block); +*/ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_stxx2(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED> +void hyperstone_device::generate_mulsu(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_mul(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::generate_set(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_ldwr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_lddr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_ldwp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_lddp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_stwr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_stdr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_stwp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_stdp(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::branch_condition CONDITION, hyperstone_device::condition_set COND_SET> +void hyperstone_device::generate_b(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_br(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +template <hyperstone_device::branch_condition CONDITION, hyperstone_device::condition_set COND_SET> +void hyperstone_device::generate_db(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_dbr(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_frame(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + const uint16_t op = desc->opptr.w[0]; + + generate_check_delay_pc(block); + + UML_ROLAND(block, I1, DRC_SR, 7, 0x7f); + UML_SUB(block, I1, I1, op & 0xf); + UML_ROLINS(block, DRC_SR, I1, 25, 0xfe000000); // SET_FP(GET_FP - SRC_CODE) + UML_ROLINS(block, DRC_SR, op, 17, 0x01e00000); // SET_FL(DST_CODE) + UML_AND(block, DRC_SR, DRC_SR, ~M_MASK); // SET_M(0) + + UML_MOV(block, I0, mem(&SP)); + UML_ADD(block, I1, I1, (op & 0xf0) >> 4); + UML_ROLAND(block, I2, I0, 30, 0x7f); + UML_ADD(block, I2, I2, (64 - 10)); + UML_SUB(block, I3, I2, I1); + UML_SEXT(block, I3, I3, SIZE_BYTE); // difference = ((SP & 0x1fc) >> 2) + (64 - 10) - ((GET_FP - SRC_CODE) + GET_FL) + + int diff_in_range, done; + UML_CMP(block, I3, -64); + UML_JMPc(block, uml::COND_L, done = compiler->m_labelnum++); + UML_CMP(block, I3, 64); + UML_JMPc(block, uml::COND_L, diff_in_range = compiler->m_labelnum++); + UML_OR(block, I3, I3, 0xffffff80); + UML_LABEL(block, diff_in_range); + + UML_CMP(block, I0, mem(&UB)); + UML_SETc(block, uml::COND_GE, I4); + UML_CMP(block, I3, 0); + UML_JMPc(block, uml::COND_GE, done); + + int push_next; + UML_LABEL(block, push_next = compiler->m_labelnum++); + UML_ROLAND(block, I2, I0, 30, 0x3f); + UML_LOAD(block, I1, (void *)m_local_regs, I2, SIZE_DWORD, SCALE_x4); + UML_CALLH(block, *m_mem_write32); + UML_ADD(block, I0, I0, 4); + UML_ADD(block, I3, I3, 1); + UML_TEST(block, I3, ~0); + UML_JMPc(block, uml::COND_NZ, push_next); + + UML_TEST(block, I4, ~0); + UML_EXHc(block, uml::COND_NZ, *m_exception[EXCEPTION_FRAME_ERROR], 0); + + UML_LABEL(block, done); +} + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::generate_call(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ + uint16_t op = desc->opptr.w[0]; + uint16_t imm_1 = READ_OP(desc->pc + 2); + + int32_t extra_s = 0; + + if (imm_1 & 0x8000) + { + uint16_t imm_2 = READ_OP(desc->pc + 4); + + extra_s = imm_2; + extra_s |= ((imm_1 & 0x3fff) << 16); + + if (imm_1 & 0x4000) + extra_s |= 0xc0000000; + + UML_MOV(block, mem(&m_instruction_length), (3<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 4); + } + else + { + extra_s = imm_1 & 0x3fff; + + if (imm_1 & 0x4000) + extra_s |= 0xffffc000; + + UML_MOV(block, mem(&m_instruction_length), (2<<19)); + UML_ADD(block, DRC_PC, DRC_PC, 2); + } + + UML_MOV(block, I1, extra_s); + + generate_check_delay_pc(block); + + const uint32_t src_code = op & 0xf; + uint32_t dst_code = (op & 0xf0) >> 4; + + if (!dst_code) + dst_code = 16; + + UML_ROLAND(block, I3, DRC_SR, 7, 0x7f); + + if (SRC_GLOBAL) + { + if (src_code == SR_REGISTER) + UML_MOV(block, I2, 0); + else + UML_LOAD(block, I2, (void *)m_global_regs, src_code, SIZE_DWORD, SCALE_x4); + } + else + { + UML_ADD(block, I4, I3, src_code); + UML_AND(block, I5, I4, 0x3f); + UML_LOAD(block, I2, (void *)m_local_regs, I5, SIZE_DWORD, SCALE_x4); + } + + UML_AND(block, I4, DRC_PC, ~1); + UML_ROLINS(block, I4, DRC_SR, 32-S_SHIFT, 1); + + UML_ADD(block, I1, I3, dst_code); + UML_AND(block, I6, I1, 0x3f); + UML_STORE(block, (void *)m_local_regs, I6, I4, SIZE_DWORD, SCALE_x4); + + UML_ADD(block, I4, I6, 1); + UML_AND(block, I5, I4, 0x3f); + UML_STORE(block, (void *)m_local_regs, I5, DRC_SR, SIZE_DWORD, SCALE_x4); + + UML_ROLINS(block, DRC_SR, I1, 25, 0xfe000000); + UML_ROLINS(block, DRC_SR, 6, 21, 0x01e00000); + UML_AND(block, DRC_SR, DRC_SR, ~M_MASK); + + UML_ADD(block, DRC_PC, I2, extra_s & ~1); + UML_MOV(block, mem(&m_intblock), 2); + + //TODO: add interrupt locks, errors, .... +} + + + +void hyperstone_device::generate_trap_op(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + +void hyperstone_device::generate_extend(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + + +void hyperstone_device::generate_reserved(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + +void hyperstone_device::generate_do(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) +{ +} + diff --git a/src/devices/cpu/e132xs/e132xsfe.cpp b/src/devices/cpu/e132xs/e132xsfe.cpp new file mode 100644 index 00000000000..be54f9342d3 --- /dev/null +++ b/src/devices/cpu/e132xs/e132xsfe.cpp @@ -0,0 +1,1302 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/*************************************************************************** + + e132xsfe.cpp + + Front end for Hyperstone recompiler + +***************************************************************************/ + +#include "emu.h" +#include "e132xsfe.h" +#include "32xsdefs.h" + +#define FE_FP ((m_cpu->m_global_regs[1] & 0xfe000000) >> 25) +#define FE_FL (m_cpu->m_fl_lut[((m_cpu->m_global_regs[1] >> 21) & 0xf)]) +#define DST_CODE ((op & 0xf0) >> 4) +#define SRC_CODE (op & 0x0f) +#define SR_CODE (1 << 1) + +/*************************************************************************** + INSTRUCTION PARSERS +***************************************************************************/ + +e132xs_frontend::e132xs_frontend(hyperstone_device *e132xs, uint32_t window_start, uint32_t window_end, uint32_t max_sequence) + : drc_frontend(*e132xs, window_start, window_end, max_sequence) + , m_cpu(e132xs) +{ +} + +inline uint32_t e132xs_frontend::imm_length(opcode_desc &desc, uint16_t op) +{ + uint8_t nybble = op & 0x0f; + switch (nybble) + { + case 0: + default: + return 2; + case 1: + return 6; + case 2: + case 3: + return 4; + } +} + +inline uint16_t e132xs_frontend::read_word(opcode_desc &desc) +{ + return m_cpu->m_direct->read_word(desc.physpc, m_cpu->m_opcodexor); +} + +inline uint16_t e132xs_frontend::read_imm1(opcode_desc &desc) +{ + return m_cpu->m_direct->read_word(desc.physpc + 2, m_cpu->m_opcodexor); +} + +inline uint16_t e132xs_frontend::read_imm2(opcode_desc &desc) +{ + return m_cpu->m_direct->read_word(desc.physpc + 4, m_cpu->m_opcodexor); +} + +inline uint32_t e132xs_frontend::read_ldstxx_imm(opcode_desc &desc) +{ + const uint16_t imm1 = read_imm1(desc); + uint32_t extra_s; + if (imm1 & 0x8000) + { + extra_s = read_imm2(desc); + extra_s |= ((imm1 & 0xfff) << 16); + + if (imm1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + extra_s = imm1 & 0xfff; + + if (imm1 & 0x4000) + extra_s |= 0xfffff000; + } + return extra_s; +} + +inline uint32_t e132xs_frontend::read_limm(opcode_desc &desc, uint16_t op) +{ + static const int32_t immediate_values[16] = + { + 16, 0, 0, 0, 32, 64, 128, int32_t(0x80000000), + -8, -7, -6, -5, -4, -3, -2, -1 + }; + + uint8_t nybble = op & 0xf; + switch (nybble) + { + case 0: + return 16; + case 1: + return (read_imm1(desc) << 16) | read_imm2(desc); + case 2: + return read_imm1(desc); + case 3: + return 0xffff0000 | read_imm1(desc); + default: + return immediate_values[nybble]; + } +} + +inline int32_t e132xs_frontend::decode_pcrel(opcode_desc &desc, uint16_t op) +{ + if (op & 0x80) + { + uint16_t next = read_imm1(desc); + + desc.length = 4; + + int32_t offset = (op & 0x7f) << 16; + offset |= (next & 0xfffe); + + if (next & 1) + offset |= 0xff800000; + + return offset; + } + else + { + int32_t offset = op & 0x7e; + if (op & 1) + offset |= 0xffffff80; + return offset; + } +} + +inline int32_t e132xs_frontend::decode_call(opcode_desc &desc) +{ + const uint16_t imm_1 = read_imm1(desc); + int32_t extra_s = 0; + if (imm_1 & 0x8000) + { + desc.length = 6; + extra_s = read_imm2(desc); + extra_s |= ((imm_1 & 0x3fff) << 16); + + if (imm_1 & 0x4000) + extra_s |= 0xc0000000; + } + else + { + desc.length = 4; + extra_s = imm_1 & 0x3fff; + if (imm_1 & 0x4000) + extra_s |= 0xffffc000; + } + return extra_s; +} + + +/*------------------------------------------------- + describe - build a description of a single + instruction +-------------------------------------------------*/ + +bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev) +{ + uint16_t op = desc.opptr.w[0] = read_word(desc); + + /* most instructions are 2 bytes and a single cycle */ + desc.length = 2; + desc.cycles = m_cpu->m_clock_cycles_1; + + const uint32_t fp = FE_FP; + const uint32_t gdst_code = DST_CODE; + const uint32_t gdstf_code = gdst_code + 1; + const uint32_t gsrc_code = SRC_CODE; + const uint32_t gsrcf_code = gsrc_code + 1; + const uint32_t ldst_code = (gdst_code + fp) & 0x1f; + const uint32_t ldstf_code = (gdstf_code + fp) & 0x1f; + const uint32_t lsrc_code = (gsrc_code + fp) & 0x1f; + const uint32_t lsrcf_code = (gsrcf_code + fp) & 0x1f; + const uint32_t ldst_group = 1 + (((DST_CODE + fp) & 0x20) >> 5); + const uint32_t ldstf_group = 1 + (((DST_CODE + fp + 1) & 0x20) >> 5); + const uint32_t lsrc_group = 1 + (((SRC_CODE + fp) & 0x20) >> 5); + const uint32_t lsrcf_group = 1 + ((SRC_CODE + fp + 1) >> 5); + + switch (op >> 8) + { + case 0x00: // chk global,global + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gsrc_code; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x01: // chk global,local + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x02: // chk local,global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x03: // chk local,local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x04: // movd global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gsrcf_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + if (gdst_code == 0) + { + desc.regout[1] = 0xffffffff; + desc.regout[2] = 0xffffffff; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + } + else + { + desc.cycles = m_cpu->m_clock_cycles_2; + } + desc.regout[0] |= SR_CODE; + break; + case 0x05: // movd global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[lsrcf_group] |= 1 << lsrcf_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + if (gdst_code == 0) + { + desc.regout[1] = 0xffffffff; + desc.regout[2] = 0xffffffff; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + } + else + { + desc.cycles = m_cpu->m_clock_cycles_2; + } + desc.regout[0] |= SR_CODE; + break; + case 0x06: // movd local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gsrcf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_2; + break; + case 0x07: // movd local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[lsrcf_group] |= 1 << lsrcf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_2; + break; + case 0x08: // divu global,global + case 0x0c: // divs global,global + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gdstf_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 36 << m_cpu->m_clck_scale; + break; + case 0x09: // divu global,local + case 0x0d: // divs global,local + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gdstf_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 36 << m_cpu->m_clck_scale; + break; + case 0x0a: // divu local,global + case 0x0e: // divs local,global + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[ldstf_group] |= 1 << ldstf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 36 << m_cpu->m_clck_scale; + break; + case 0x0b: // divu local,local + case 0x0f: // divs local,local + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[ldstf_group] |= 1 << ldstf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 36 << m_cpu->m_clck_scale; + break; + case 0x10: // xm global,global + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x11: // xm global,local + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x12: // xm local,global + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x13: // xm local,local + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x14: // mask global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x15: // mask global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x16: // mask local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x17: // mask local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + break; + case 0x18: // sum global,global + case 0x1c: // sums global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + if (op & 0x4 && gsrc_code != SR_REGISTER) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x19: // sum global,local + case 0x1d: // sums global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + if (op & 0x4) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x1a: // sum local,global + case 0x1e: // sums local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + if (op & 0x4 && gsrc_code != SR_REGISTER) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x1b: // sum local,local + case 0x1f: // sums local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = (read_imm1(desc) & 0x8000) ? 6 : 4; + if (op & 0x4) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x20: // cmp global,global + case 0x30: // cmpb global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x21: // cmp global,local + case 0x31: // cmpb global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x22: // cmp local,global + case 0x32: // cmpb local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x23: // cmp local,local + case 0x33: // cmpb local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x24: // mov global,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << (gsrc_code + 16); + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x25: // mov global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x26: // mov local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << (gsrc_code + 16); + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x27: // mov local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x28: // add global,global + case 0x2c: // adds global,global + case 0x48: // sub global,global + case 0x4c: // subs global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs + break; + case 0x29: // add global,local + case 0x2d: // adds global,local + case 0x49: // sub global,local + case 0x4d: // subs global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs + break; + case 0x2a: // add local,global + case 0x2e: // adds local,global + case 0x4a: // sub local,global + case 0x4e: // subs local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs + break; + case 0x2b: // add local,local + case 0x2f: // adds local,local + case 0x4b: // sub local,local + case 0x4f: // subs local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // adds, subs + break; + case 0x34: // andn global,global + case 0x38: // or global,global + case 0x3c: // xor global,global + case 0x54: // and global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x35: // andn global,local + case 0x39: // or global,local + case 0x3d: // xor global,local + case 0x55: // and global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x36: // andn local,global + case 0x3a: // or local,global + case 0x3e: // xor local,global + case 0x56: // and local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x37: // andn local,local + case 0x3b: // or local,local + case 0x3f: // xor local,local + case 0x57: // and local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x40: // subc global,global + case 0x50: // addc global,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x41: // subc global,local + case 0x51: // addc global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x42: // subc local,global + case 0x52: // addc local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x43: // subc local,local + case 0x53: // addc local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x44: // not global,global + case 0x58: // neg global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x45: // not global,local + case 0x59: // neg global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x46: // not local,global + case 0x5a: // neg local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x47: // not local,local + case 0x5b: // neg local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x5c: // negs global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x5d: // negs global,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x5e: // negs local,global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x5f: // negs local,local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + break; + case 0x60: // cmpi global,simm + case 0x70: // cmpbi global,simm + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x61: // cmpi global,limm + case 0x71: // cmpbi global,limm + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + break; + case 0x62: // cmpi local,simm + case 0x72: // cmpbi local,simm + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x63: // cmpi local,limm + case 0x73: // cmpbi local,limm + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + break; + case 0x64: // movi global,simm + desc.regin[0] |= SR_CODE; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << (gdst_code + 16); + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = op & 0xf; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x65: // movi global,limm + desc.regin[0] |= SR_CODE; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << (gdst_code + 16); + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = read_limm(desc, op); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x66: // movi local,simm + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x67: // movi local,limm + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + break; + case 0x68: // addi global,simm + case 0x6c: // addsi global,simm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x69: // addi global,limm + case 0x6d: // addsi global,limm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x6a: // addi local,simm + case 0x6e: // addsi local,simm + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + break; + case 0x6b: // addi local,limm + case 0x6f: // addsi local,limm + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + if (op & 0x04) desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION; // addsi + break; + case 0x74: // andni global,simm + case 0x78: // ori global,simm + case 0x7c: // xori global,simm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x75: // andni global,limm + case 0x79: // ori global,limm + case 0x7d: // xori global,limm + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + case 0x76: // andni local,simm + case 0x7a: // ori local,simm + case 0x7e: // xori local,simm + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x77: // andni local,limm + case 0x7b: // ori local,limm + case 0x7f: // xori local,limm + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.length = imm_length(desc, op); + break; + case 0x80: case 0x81: // shrdi + case 0x84: case 0x85: // sardi + case 0x88: case 0x89: // shldi + desc.regin[0] |= SR_CODE; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_2; + break; + case 0x82: // shrd + case 0x86: // sard + case 0x8a: // shld + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_2; + break; + case 0x83: // shr + case 0x87: // sar + case 0x8b: // shl + case 0x8f: // rol + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0x8c: case 0x8d: // reserved + return false; + case 0x8e: // testlz + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + break; + case 0x90: // ldxx1 global,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + } + case 0x91: // ldxx1 global,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + } + case 0x92: // ldxx1 local,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + break; + } + case 0x93: // ldxx1 local,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + break; + } + case 0x94: // ldxx2 global,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + } + case 0x95: // ldxx2 global,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + if (gdst_code == PC_REGISTER) + { + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + } + break; + } + case 0x96: // ldxx2 local,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + break; + } + case 0x97: // ldxx2 local,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regout[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_READS_MEMORY; + break; + } + case 0x98: // stxx1 global,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x99: // stxx1 global,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9a: // stxx1 local,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9b: // stxx1 local,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9c: // stxx2 global,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= 1 << gdst_code; + desc.regin[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; + desc.regout[0] |= 1 << gdst_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9d: // stxx2 global,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gdst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; + desc.regout[0] |= 1 << gdst_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9e: // stxx2 local,global + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[0] |= 1 << gsrcf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0x9f: // stxx2 local,local + { + const uint16_t imm1 = read_imm1(desc); + const uint32_t extra_s = read_ldstxx_imm(desc); + + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if ((imm1 & 0x3000) == 3 && (extra_s & 2)) desc.regin[lsrcf_group] |= 1 << lsrcf_code; + desc.regout[ldst_group] |= 1 << ldst_code; + + desc.length = (imm1 & 0x8000) ? 6 : 4; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + } + case 0xa0: // shri global (lo n) + case 0xa1: // shri global (hi n) + case 0xa4: // sari global (lo n) + case 0xa5: // sari global (hi n) + case 0xa8: // shli global (lo n) + case 0xa9: // shli global (hi n) + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + break; + case 0xa2: // shri local (lo n) + case 0xa3: // shri local (hi n) + case 0xa6: // sari local (lo n) + case 0xa7: // sari local (hi n) + case 0xaa: // shli local (lo n) + case 0xab: // shli local (hi n) + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + break; + case 0xac: case 0xad: case 0xae: case 0xaf: // reserved + return false; + case 0xb0: // mulu global,global + case 0xb4: // muls global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_4; + break; + case 0xb1: // mulu global,local + case 0xb5: // muls global,local + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_4; + break; + case 0xb2: // mulu local,global + case 0xb6: // muls local,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_4; + break; + case 0xb3: // mulu local,local + case 0xb7: // muls local,local + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.regout[0] |= SR_CODE; + desc.cycles = m_cpu->m_clock_cycles_4; + break; + case 0xb8: // set global (lo n) + case 0xb9: // set global (hi n) + desc.regin[0] |= SR_CODE; + desc.regout[0] |= 1 << gdst_code; + break; + case 0xba: // set local (lo n) + case 0xbb: // set local (hi n) + desc.regout[ldst_group] |= 1 << ldst_code; + break; + case 0xbc: // mul global,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 3 << m_cpu->m_clck_scale; + break; + case 0xbd: // muls global,local + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[0] |= 1 << gdst_code; + desc.regout[0] |= 1 << gdst_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 3 << m_cpu->m_clck_scale; + break; + case 0xbe: // muls local,global + desc.regin[0] |= 1 << gsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 3 << m_cpu->m_clck_scale; + break; + case 0xbf: // mulu local,local + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= SR_CODE; + desc.cycles = 3 << m_cpu->m_clck_scale; + break; + case 0xc0: case 0xc1: case 0xc2: case 0xc3: // software + case 0xc4: case 0xc5: case 0xc6: case 0xc7: // software + case 0xc8: case 0xc9: case 0xca: case 0xcb: // software + case 0xcc: case 0xcd: // software + { + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[lsrcf_group] |= 1 << lsrcf_code; + + const uint32_t reg = FE_FP + FE_FL; + desc.regout[1 + (((reg + 0) & 0x20) >> 5)] |= 1 << ((reg + 0) & 0x1f); + desc.regout[1 + (((reg + 1) & 0x20) >> 5)] |= 1 << ((reg + 1) & 0x1f); + desc.regout[1 + (((reg + 2) & 0x20) >> 5)] |= 1 << ((reg + 2) & 0x1f); + desc.regout[1 + (((reg + 3) & 0x20) >> 5)] |= 1 << ((reg + 3) & 0x1f); + desc.regout[1 + (((reg + 4) & 0x20) >> 5)] |= 1 << ((reg + 4) & 0x1f); + + desc.regout[0] |= SR_CODE; + + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + break; + } + case 0xce: // extend - 4 bytes + desc.regin[0] |= SR_CODE; + desc.regin[0] |= (3 << 14); // global regs 14, 15 + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= (3 << 14); // global regs 14, 15 + break; + case 0xcf: // do + return false; + case 0xd0: // ldwr global + case 0xd4: // ldwp global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= 1 << gsrc_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_READS_MEMORY; + break; + case 0xd1: // ldwr local + case 0xd5: // ldwp local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_READS_MEMORY; + break; + case 0xd2: // lddr global + case 0xd6: // lddp global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[0] |= 1 << gsrc_code; + desc.regout[0] |= 1 << gsrcf_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_READS_MEMORY; + break; + case 0xd3: // lddr local + case 0xd7: // lddp local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regout[lsrc_group] |= 1 << lsrc_code; + desc.regout[lsrcf_group] |= 1 << lsrcf_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_READS_MEMORY; + break; + case 0xd8: // stwr global + case 0xdc: // stwp global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + case 0xd9: // stwr local + case 0xdd: // stwp local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + case 0xda: // stdr global + case 0xde: // stdp global + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[0] |= 1 << gsrc_code; + desc.regin[0] |= 1 << gsrcf_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + case 0xdb: // stdr local + case 0xdf: // stdp local + desc.regin[0] |= SR_CODE; + desc.regin[ldst_group] |= 1 << ldst_code; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regin[lsrcf_group] |= 1 << lsrcf_code; + if (op & 0x04) desc.regout[ldst_group] |= 1 << ldst_code; + desc.flags |= OPFLAG_WRITES_MEMORY; + break; + case 0xe0: case 0xe1: case 0xe2: case 0xe3: // dbv, dbnv, dbe, dbne - could be 4 bytes (pcrel) + case 0xe4: case 0xe5: case 0xe6: case 0xe7: // dbc, dbnc, dbse, dbht - could be 4 bytes (pcrel) + case 0xe8: case 0xe9: case 0xea: case 0xeb: // dbn, dbnn, dblt, dbgt - could be 4 bytes (pcrel) + desc.regin[0] |= SR_CODE; + desc.targetpc = desc.pc + decode_pcrel(desc, op); + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; + desc.delayslots = 1; + break; + case 0xec: // dbr - could be 4 bytes (pcrel) + desc.targetpc = desc.pc + decode_pcrel(desc, op); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + desc.delayslots = 1; + break; + case 0xed: // frame + desc.regin[0] |= SR_CODE; + desc.regin[1] = 0xffffffff; + desc.regin[2] = 0xffffffff; + desc.regout[0] |= SR_CODE; + desc.flags |= OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_END_SEQUENCE; + break; + case 0xee: // call global + desc.regin[0] |= SR_CODE; + desc.regin[0] |= 1 << gsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.targetpc = desc.pc + decode_call(desc); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + break; + case 0xef: // call local + desc.regin[0] |= SR_CODE; + desc.regin[lsrc_group] |= 1 << lsrc_code; + desc.regout[ldst_group] |= 1 << ldst_code; + desc.regout[ldstf_group] |= 1 << ldstf_code; + desc.targetpc = desc.pc + decode_call(desc); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + break; + case 0xf0: case 0xf1: case 0xf2: case 0xf3: // bv, bnv, be, bne + case 0xf4: case 0xf5: case 0xf6: case 0xf7: // bc, bnc, bse, bht + case 0xf8: case 0xf9: case 0xfa: case 0xfb: // bn, bnn, blt, bgt + desc.regin[0] |= SR_CODE; + desc.targetpc = desc.pc + decode_pcrel(desc, op); + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH; + break; + case 0xfc: // br + desc.targetpc = desc.pc + decode_pcrel(desc, op); + desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE; + break; + case 0xfd: case 0xfe: case 0xff: // trap + desc.regin[0] |= SR_CODE; + desc.targetpc = BRANCH_TARGET_DYNAMIC; + desc.flags |= OPFLAG_IS_CONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION; + break; + } + return true; +} diff --git a/src/devices/cpu/e132xs/e132xsfe.h b/src/devices/cpu/e132xs/e132xsfe.h new file mode 100644 index 00000000000..7463fd964d0 --- /dev/null +++ b/src/devices/cpu/e132xs/e132xsfe.h @@ -0,0 +1,34 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +#ifndef MAME_CPU_E132XS_E132XSFE_H +#define MAME_CPU_E132XS_E132XSFE_H + +#pragma once + +#include "e132xs.h" +#include "cpu/drcfe.h" + +class e132xs_frontend : public drc_frontend +{ +public: + e132xs_frontend(hyperstone_device *e132xs, uint32_t window_start, uint32_t window_end, uint32_t max_sequence); + void flush(); + +protected: + // required overrides + virtual bool describe(opcode_desc &desc, const opcode_desc *prev) override; + +private: + inline uint32_t imm_length(opcode_desc &desc, uint16_t op); + inline uint16_t read_word(opcode_desc &desc); + inline uint16_t read_imm1(opcode_desc &desc); + inline uint16_t read_imm2(opcode_desc &desc); + inline uint32_t read_ldstxx_imm(opcode_desc &desc); + inline uint32_t read_limm(opcode_desc &desc, uint16_t op); + inline int32_t decode_pcrel(opcode_desc &desc, uint16_t op); + inline int32_t decode_call(opcode_desc &desc); + + hyperstone_device *m_cpu; +}; + +#endif /* MAME_CPU_E132XS_E132XSFE_H */ diff --git a/src/devices/cpu/e132xs/e132xsop.hxx b/src/devices/cpu/e132xs/e132xsop.hxx index e37ef914246..9d55b78d233 100644 --- a/src/devices/cpu/e132xs/e132xsop.hxx +++ b/src/devices/cpu/e132xs/e132xsop.hxx @@ -1,1925 +1,2712 @@ // license:BSD-3-Clause // copyright-holders:Pierpaolo Prazzoli -#define LOCAL_DECODE_INIT \ - struct regs_decode decode_state; \ - struct regs_decode *decode = &decode_state; \ -\ - /* clear 'current regs / flags' */ \ - decode->src = 0; \ - decode->dst = 0; \ - decode->src_value = 0; \ - decode->next_src_value = 0; \ - decode->dst_value = 0; \ - decode->next_dst_value = 0; \ - decode->sub_type = 0; \ - decode->extra.u = 0; \ - decode->src_is_local = 0; \ - decode->dst_is_local = 0; \ - decode->same_src_dst = 0; \ - decode->same_src_dstf = 0; \ - decode->same_srcf_dst = 0; +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_chk() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dreg = DST_GLOBAL ? m_global_regs[DST_CODE] : m_local_regs[(DST_CODE + fp) & 0x3f]; + + if (SRC_GLOBAL && (src_code == SR_REGISTER)) + { + if (dreg == 0) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + } + else + { + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + if ((SRC_GLOBAL && (src_code == PC_REGISTER)) ? (dreg >= sreg) : (dreg > sreg)) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_movd() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f); + + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t sregf = (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]; + + if (DST_GLOBAL && (dst_code == PC_REGISTER)) + { + // RET instruction + if (SRC_GLOBAL && src_code < 2) + { + LOG("Denoted PC or SR in RET instruction. PC = %08X\n", PC); + m_icount -= m_clock_cycles_1; + return; + } + + const uint32_t old_s = SR & S_MASK; + const uint32_t old_l = SR & L_MASK; + PC = sreg & ~1; + SR = (sregf & 0xffe3ffff) | ((sreg & 0x01) << 18); + if (m_intblock < 1) + m_intblock = 1; + + m_instruction_length = 0; // undefined + + const uint32_t new_s = SR & S_MASK; + const uint32_t new_l = SR & L_MASK; + if( (!old_s && new_s) || (!new_s && !old_l && new_l)) + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + + int8_t difference = GET_FP - ((SP & 0x1fc) >> 2); + + /* convert to 8 bits */ + if(difference > 63) + difference = (int8_t)(difference|0x80); + else if( difference < -64 ) + difference = difference & 0x7f; + + for (; difference < 0; difference++) + { + SP -= 4; + m_local_regs[(SP & 0xfc) >> 2] = READ_W(SP); + } + + //TODO: no 1! + m_icount -= m_clock_cycles_1; + } + else if (SRC_GLOBAL && (src_code == SR_REGISTER)) // Rd doesn't denote PC and Rs denotes SR + { + SR |= Z_MASK; + SR &= ~N_MASK; + if (DST_GLOBAL) + { + set_global_register(dst_code, 0); + set_global_register(dstf_code, 0); + } + else + { + m_local_regs[dst_code] = 0; + m_local_regs[dstf_code] = 0; + } + + m_icount -= m_clock_cycles_2; + } + else // Rd doesn't denote PC and Rs doesn't denote SR + { + SR &= ~(Z_MASK | N_MASK); + if (concat_64(sreg, sregf) == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(sreg); + + if (DST_GLOBAL) + { + set_global_register(dst_code, sreg); + set_global_register(dstf_code, sregf); + } + else + { + m_local_regs[dst_code] = sreg; + m_local_regs[dstf_code] = sregf; + } + + m_icount -= m_clock_cycles_2; + } +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED> +void hyperstone_device::hyperstone_divsu() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f); + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + + if ((SRC_GLOBAL == DST_GLOBAL && (src_code == dst_code || src_code == dstf_code)) || (SRC_GLOBAL && src_code < 2)) + { + LOG("Denoted the same register code or PC/SR as source in hyperstone_divu instruction. PC = %08X\n", PC); + m_icount -= 36 << m_clck_scale; + return; + } + + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t dregf = (DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code]; + const uint64_t dividend = concat_64(dreg, dregf); + + if (sreg == 0 || (SIGNED && (dividend & 0x8000000000000000U))) + { + //Rd//Rdf -> undefined + //Z -> undefined + //N -> undefined + SR |= V_MASK; + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + } + else + { + /* TODO: add quotient overflow */ + const uint32_t quotient = SIGNED ? (uint32_t)((int64_t)dividend / (int32_t)sreg) : (dividend / sreg); + SR &= ~(V_MASK | Z_MASK | N_MASK); + if (quotient == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(quotient); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = SIGNED ? (uint32_t)((int64_t)dividend % (int32_t)sreg) : (dividend % sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code] = (uint32_t)quotient; + } + + m_icount -= 36 << m_clck_scale; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_xm() +{ + const uint32_t next = READ_OP(PC); + PC += 2; + + const uint8_t sub_type = (next & 0x7000) >> 12; + + uint32_t extra_u = next & 0xfff; + if (next & 0x8000) + { + extra_u = ((extra_u & 0xfff) << 16) | READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + } + else + { + m_instruction_length = (2<<19); + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + + if ((SRC_GLOBAL && (src_code == SR_REGISTER)) || (DST_GLOBAL && (dst_code < 2))) + { + LOG("Denoted PC or SR in hyperstone_xm. PC = %08X\n", PC); + m_icount -= m_clock_cycles_1; + return; + } -void hyperstone_device::op00() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_chk(decode); -} + uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; -void hyperstone_device::op01() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_chk(decode); -} + if (sub_type < 4) + { + if ((SRC_GLOBAL && (src_code == PC_REGISTER)) ? (sreg >= extra_u) : (sreg > extra_u)) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); + else + sreg <<= sub_type; + } + else + { + sreg <<= (sub_type - 4); + } -void hyperstone_device::op02() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_chk(decode); -} + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = sreg; -void hyperstone_device::op03() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_chk(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op04() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_mask() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_movd(decode); -} + const uint32_t extra_u = decode_const(); + check_delay_PC(); + const uint32_t dreg = (SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]) & extra_u; -void hyperstone_device::op05() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_movd(decode); -} + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op06() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_movd(decode); -} + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[(DST_CODE + GET_FP) & 0x3f] = dreg; -void hyperstone_device::op07() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_movd(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op08() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_sum() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_divu(decode); -} + const uint32_t extra_u = decode_const(); + check_delay_PC(); + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; -void hyperstone_device::op09() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_divu(decode); -} + const uint64_t tmp = uint64_t(sreg) + uint64_t(extra_u); -void hyperstone_device::op0a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_divu(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + SR |= (tmp & 0x100000000) >> 32; + SR |= ((sreg ^ tmp) & (extra_u ^ tmp) & 0x80000000) >> 28; -void hyperstone_device::op0b() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_divu(decode); -} + const uint32_t dreg = sreg + extra_u; -void hyperstone_device::op0c() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_divs(decode); -} + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op0d() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_divs(decode); -} + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[(DST_CODE + fp) & 0x3f] = dreg; -void hyperstone_device::op0e() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_divs(decode); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op0f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_sums() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_divs(decode); -} + const int32_t extra_s = decode_const(); + check_delay_PC(); + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]); -void hyperstone_device::op10() -{ - LOCAL_DECODE_INIT; - RRlimdecode(decode, 0, 0); - hyperstone_xm(decode); -} + const int64_t tmp = int64_t(sreg) + int64_t(extra_s); -void hyperstone_device::op11() -{ - LOCAL_DECODE_INIT; - RRlimdecode(decode, 0, 1); - hyperstone_xm(decode); -} + SR &= ~(Z_MASK | N_MASK | V_MASK); + SR |= ((sreg ^ tmp) & (extra_s ^ tmp) & 0x80000000) >> 28; -void hyperstone_device::op12() -{ - LOCAL_DECODE_INIT; - RRlimdecode(decode, 1, 0); - hyperstone_xm(decode); -} +//#if SETCARRYS +// SR |= (tmp & 0x100000000) >> 32; +//#endif -void hyperstone_device::op13() -{ - LOCAL_DECODE_INIT; - RRlimdecode(decode, 1, 1); - hyperstone_xm(decode); -} + const int32_t res = sreg + extra_s; -void hyperstone_device::op14() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 0); - hyperstone_mask(decode); -} + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); -void hyperstone_device::op15() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 1); - hyperstone_mask(decode); -} + if (DST_GLOBAL) + set_global_register(DST_CODE, res); + else + m_local_regs[(DST_CODE + fp) & 0x3f] = res; -void hyperstone_device::op16() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 0); - hyperstone_mask(decode); -} + m_icount -= m_clock_cycles_1; -void hyperstone_device::op17() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 1); - hyperstone_mask(decode); + if ((SR & V_MASK) && src_code != SR_REGISTER) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op18() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 0); - hyperstone_sum(decode); -} -void hyperstone_device::op19() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_cmp() { - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 1); - hyperstone_sum(decode); -} + check_delay_PC(); -void hyperstone_device::op1a() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 0); - hyperstone_sum(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op1b() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 1); - hyperstone_sum(decode); -} + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op1c() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 0); - hyperstone_sums(decode); -} + const uint64_t tmp = uint64_t(dreg) - uint64_t(sreg); -void hyperstone_device::op1d() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 0, 1); - hyperstone_sums(decode); -} + SR &= ~(Z_MASK | N_MASK | V_MASK | C_MASK); + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; -void hyperstone_device::op1e() -{ - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 0); - hyperstone_sums(decode); + if (dreg < sreg) + SR |= C_MASK; + else if (dreg == sreg) + SR |= Z_MASK; + + if (int32_t(dreg) < int32_t(sreg)) + SR |= N_MASK; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op1f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_mov() { - LOCAL_DECODE_INIT; - RRconstdecode(decode, 1, 1); - hyperstone_sums(decode); -} + check_delay_PC(); + const bool h = (SR & H_MASK) != 0; + if (DST_GLOBAL && h && !(SR & S_MASK)) + { + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + } + else + { + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? (SRC_CODE + (h ? 16 : 0)) : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? ((WRITE_ONLY_REGMASK & (1 << src_code)) ? 0 : get_global_register(src_code)) : m_local_regs[src_code]; + SR &= ~(Z_MASK | N_MASK); + if (sreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(sreg); -void hyperstone_device::op20() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_cmp(decode); -} + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE + (h ? 16 : 0); + set_global_register(dst_code, sreg); -void hyperstone_device::op21() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_cmp(decode); -} + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + } + else + { + m_local_regs[(DST_CODE + fp) & 0x3f] = sreg; + } + } -void hyperstone_device::op22() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_cmp(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op23() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_add() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_cmp(decode); -} + check_delay_PC(); -void hyperstone_device::op24() -{ - LOCAL_DECODE_INIT; - RRdecodewithHflag(decode, 0, 0); - hyperstone_mov(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op25() -{ - LOCAL_DECODE_INIT; - RRdecodewithHflag(decode, 0, 1); - hyperstone_mov(decode); -} + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op26() -{ - LOCAL_DECODE_INIT; - RRdecodewithHflag(decode, 1, 0); - hyperstone_mov(decode); -} + const uint64_t tmp = uint64_t(sreg) + uint64_t(dreg); -void hyperstone_device::op27() -{ - LOCAL_DECODE_INIT; - RRdecodewithHflag(decode, 1, 1); - hyperstone_mov(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op28() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_add(decode); -} + SR |= (tmp & 0x100000000) >> 32; + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; -void hyperstone_device::op29() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_add(decode); -} + dreg += sreg; -void hyperstone_device::op2a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_add(decode); -} + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op2b() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_add(decode); -} + if (DST_GLOBAL) + { + set_global_register(dst_code, dreg); -void hyperstone_device::op2c() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_adds(decode); -} + if (dst_code == 0) + SR &= ~M_MASK; + } + else + { + m_local_regs[dst_code] = dreg; + } -void hyperstone_device::op2d() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_adds(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op2e() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_adds() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_adds(decode); -} + check_delay_PC(); -void hyperstone_device::op2f() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_adds(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]); + int32_t dreg = int32_t((DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]); + const int64_t tmp = int64_t(sreg) + int64_t(dreg); + SR &= ~(V_MASK | Z_MASK | N_MASK); + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; -void hyperstone_device::op30() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_cmpb(decode); -} +//#if SETCARRYS +// SR |= (tmp & 0x100000000) >> 32; +//#endif -void hyperstone_device::op31() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_cmpb(decode); -} + const int32_t res = sreg + dreg; -void hyperstone_device::op32() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_cmpb(decode); -} + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); -void hyperstone_device::op33() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_cmpb(decode); -} + if (DST_GLOBAL) + set_global_register(dst_code, res); + else + m_local_regs[dst_code] = res; -void hyperstone_device::op34() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_andn(decode); -} + m_icount -= m_clock_cycles_1; -void hyperstone_device::op35() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_andn(decode); + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op36() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_andn(decode); -} -void hyperstone_device::op37() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_andn(decode); -} -void hyperstone_device::op38() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_cmpb() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_or(decode); -} + check_delay_PC(); -void hyperstone_device::op39() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_or(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op3a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_or(decode); -} + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op3b() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_or(decode); -} + if (dreg & sreg) + SR &= ~Z_MASK; + else + SR |= Z_MASK; -void hyperstone_device::op3c() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_xor(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3d() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_andn() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_xor(decode); -} + check_delay_PC(); -void hyperstone_device::op3e() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_xor(decode); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] & ~sreg; + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op3f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_or() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_xor(decode); -} + check_delay_PC(); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] | sreg; + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op40() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_subc(decode); -} + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; -void hyperstone_device::op41() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_subc(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op42() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_xor() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_subc(decode); -} + check_delay_PC(); -void hyperstone_device::op43() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_subc(decode); -} + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] ^ sreg; -void hyperstone_device::op44() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_not(decode); -} + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op45() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_not(decode); -} + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; -void hyperstone_device::op46() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_not(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op47() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_not(decode); -} -void hyperstone_device::op48() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_sub(decode); -} -void hyperstone_device::op49() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_subc() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_sub(decode); -} + check_delay_PC(); -void hyperstone_device::op4a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_sub(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op4b() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_sub(decode); -} + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t c = GET_C; -void hyperstone_device::op4c() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_subs(decode); -} + uint32_t old_z = SR & Z_MASK; + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op4d() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_subs(decode); -} + if (SRC_GLOBAL && (src_code == SR_REGISTER)) + { + const uint64_t tmp = uint64_t(dreg) - uint64_t(c); + SR |= ((tmp ^ dreg) & dreg & 0x80000000) >> 28; + SR |= (tmp & 0x100000000) >> 32; + dreg -= c; + } + else + { + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint64_t tmp = uint64_t(dreg) - (uint64_t(sreg) + uint64_t(c)); + //CHECK! + const uint32_t sreg_c = sreg + c; + SR |= ((tmp ^ dreg) & (dreg ^ sreg_c) & 0x80000000) >> 28; + SR |= (tmp & 0x100000000) >> 32; + dreg -= sreg_c; + } -void hyperstone_device::op4e() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_subs(decode); + if (old_z && dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[dst_code] = dreg; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op4f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_not() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_subs(decode); -} + check_delay_PC(); + const uint32_t dreg = ~(SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]); + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op50() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_addc(decode); -} + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[(DST_CODE + GET_FP) & 0x3f] = dreg; -void hyperstone_device::op51() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_addc(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op52() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_sub() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_addc(decode); -} + check_delay_PC(); -void hyperstone_device::op53() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_addc(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op54() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_and(decode); -} + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op55() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_and(decode); -} + const uint64_t tmp = uint64_t(dreg) - uint64_t(sreg); -void hyperstone_device::op56() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_and(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + SR |= (tmp & 0x100000000) >> 32; + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; -void hyperstone_device::op57() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_and(decode); -} + dreg -= sreg; -void hyperstone_device::op58() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_neg(decode); -} + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op59() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_neg(decode); -} + if (DST_GLOBAL) + { + set_global_register(dst_code, dreg); -void hyperstone_device::op5a() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_neg(decode); -} + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + } + else + { + m_local_regs[dst_code] = dreg; + } -void hyperstone_device::op5b() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_neg(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op5c() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_subs() { - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_negs(decode); -} + check_delay_PC(); -void hyperstone_device::op5d() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_negs(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op5e() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_negs(decode); -} + const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]); + int32_t dreg = int32_t((DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]); + const int64_t tmp = int64_t(dreg) - int64_t(sreg); -void hyperstone_device::op5f() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_negs(decode); -} + SR &= ~(V_MASK | Z_MASK | N_MASK); +//#ifdef SETCARRYS +// SR |= (tmp & 0x100000000) >> 32; +//#endif + SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28; -void hyperstone_device::op60() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_cmpi(decode); -} + const int32_t res = dreg - sreg; -void hyperstone_device::op61() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_cmpi(decode); -} + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); -void hyperstone_device::op62() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_cmpi(decode); -} + if (DST_GLOBAL) + set_global_register(dst_code, res); + else + m_local_regs[dst_code] = res; -void hyperstone_device::op63() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_cmpi(decode); -} + m_icount -= m_clock_cycles_1; -void hyperstone_device::op64() -{ - LOCAL_DECODE_INIT; - RimmdecodewithHflag(decode, 0, 0); - hyperstone_movi(decode); + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op65() -{ - LOCAL_DECODE_INIT; - RimmdecodewithHflag(decode, 0, 1); - hyperstone_movi(decode); -} -void hyperstone_device::op66() -{ - LOCAL_DECODE_INIT; - RimmdecodewithHflag(decode, 1, 0); - hyperstone_movi(decode); -} -void hyperstone_device::op67() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_addc() { - LOCAL_DECODE_INIT; - RimmdecodewithHflag(decode, 1, 1); - hyperstone_movi(decode); -} + check_delay_PC(); -void hyperstone_device::op68() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_addi(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); -void hyperstone_device::op69() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_addi(decode); -} + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op6a() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_addi(decode); -} + const bool old_z = (SR & Z_MASK) != 0; + const uint32_t c = GET_C; -void hyperstone_device::op6b() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_addi(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op6c() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_addsi(decode); -} + uint64_t tmp; + if (SRC_GLOBAL && (src_code == SR_REGISTER)) + { + tmp = uint64_t(dreg) + uint64_t(c); + SR |= ((dreg ^ tmp) & tmp & 0x80000000) >> 28; + dreg += c; + } + else + { + tmp = uint64_t(sreg) + uint64_t(dreg) + uint64_t(c); + SR |= ((sreg ^ tmp) & (dreg ^ tmp) & tmp & 0x80000000) >> 28; + dreg += sreg + c; + } -void hyperstone_device::op6d() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_addsi(decode); -} + SR |= (tmp & 0x100000000) >> 32; -void hyperstone_device::op6e() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_addsi(decode); + if (dreg == 0 && old_z) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); + + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op6f() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_and() { - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_addsi(decode); -} + check_delay_PC(); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t sreg = SRC_GLOBAL ? m_global_regs[SRC_CODE] : m_local_regs[(SRC_CODE + GET_FP) & 0x3f]; + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] & sreg; + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; -void hyperstone_device::op70() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_cmpbi(decode); -} + if (DST_GLOBAL) + set_global_register(dst_code, dreg); + else + m_local_regs[dst_code] = dreg; -void hyperstone_device::op71() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_cmpbi(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op72() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_neg() { - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_cmpbi(decode); -} + check_delay_PC(); -void hyperstone_device::op73() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_cmpbi(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); -void hyperstone_device::op74() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_andni(decode); -} + const uint32_t sreg = SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]; + const uint64_t tmp = -uint64_t(sreg); -void hyperstone_device::op75() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_andni(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + SR |= (tmp & 0x100000000) >> 32; + SR |= (tmp & sreg & 0x80000000) >> 28; -void hyperstone_device::op76() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_andni(decode); -} + const uint32_t dreg = -sreg; -void hyperstone_device::op77() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_andni(decode); -} + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op78() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_ori(decode); -} + if (DST_GLOBAL) + set_global_register(DST_CODE, dreg); + else + m_local_regs[(DST_CODE + fp) & 0x3f] = dreg; -void hyperstone_device::op79() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_ori(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op7a() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_negs() { - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_ori(decode); -} + check_delay_PC(); -void hyperstone_device::op7b() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_ori(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); -void hyperstone_device::op7c() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 0); - hyperstone_xori(decode); -} + const int32_t sreg = int32_t(SRC_GLOBAL ? ((src_code == SR_REGISTER) ? GET_C : m_global_regs[src_code]) : m_local_regs[src_code]); + const int64_t tmp = -int64_t(sreg); -void hyperstone_device::op7d() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 0, 1); - hyperstone_xori(decode); -} + SR &= ~(V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op7e() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 0); - hyperstone_xori(decode); -} + if (tmp & sreg & 0x80000000) + SR |= V_MASK; -void hyperstone_device::op7f() -{ - LOCAL_DECODE_INIT; - Rimmdecode(decode, 1, 1); - hyperstone_xori(decode); -} +//#if SETCARRYS +// SR |= (tmp & 0x100000000) >> 32; +//#endif + const int32_t res = -sreg; + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); -void hyperstone_device::op80() -{ - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_shrdi(decode); -} + if (DST_GLOBAL) + set_global_register(DST_CODE, res); + else + m_local_regs[(DST_CODE + fp) & 0x3f] = res; -void hyperstone_device::op81() -{ - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_shrdi(decode); -} + m_icount -= m_clock_cycles_1; -void hyperstone_device::op82() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_shrd(decode); + if (GET_V) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); } -void hyperstone_device::op83() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_shr(decode); -} -void hyperstone_device::op84() -{ - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_sardi(decode); -} -void hyperstone_device::op85() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_cmpi() { - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_sardi(decode); -} + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); -void hyperstone_device::op86() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_sard(decode); -} + check_delay_PC(); -void hyperstone_device::op87() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_sar(decode); -} + if (!IMM_LONG) + imm = m_op & 0x0f; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op88() -{ - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_shldi(decode); -} + SR &= ~(V_MASK | Z_MASK | N_MASK | C_MASK); -void hyperstone_device::op89() -{ - LOCAL_DECODE_INIT; - Lndecode(decode); - hyperstone_shldi(decode); -} + uint64_t tmp = (uint64_t)dreg - (uint64_t)imm; + SR |= ((tmp ^ dreg) & (dreg ^ imm) & 0x80000000) >> 28; -void hyperstone_device::op8a() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_shld(decode); -} + if (dreg < imm) + SR |= C_MASK; + else if (dreg == imm) + SR |= Z_MASK; -void hyperstone_device::op8b() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_shl(decode); -} + if ((int32_t)dreg < (int32_t)imm) + SR |= N_MASK; -void hyperstone_device::op8c() -{ - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op8d() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_movi() { - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); -} + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); + check_delay_PC(); -void hyperstone_device::op8e() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_testlz(decode); -} + if (!IMM_LONG) + imm = m_op & 0x0f; -void hyperstone_device::op8f() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_rol(decode); -} + const bool h = (SR & H_MASK) != 0; + if (DST_GLOBAL && h && !(SR & S_MASK)) + { + execute_exception(get_trap_addr(TRAPNO_PRIVILEGE_ERROR)); + } + else + { + SR &= ~(Z_MASK | N_MASK); + if (imm == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(imm); +#if MISSIONCRAFT_FLAGS + SR &= ~V_MASK; // or V undefined ? +#endif + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE + (h ? 16 : 0); + set_global_register(dst_code, imm); -void hyperstone_device::op90() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 0); - hyperstone_ldxx1(decode); -} + if (dst_code == PC_REGISTER) + SR &= ~M_MASK; + } + else + { + m_local_regs[(DST_CODE + GET_FP) & 0x3f] = imm; + } + } -void hyperstone_device::op91() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 1); - hyperstone_ldxx1(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op92() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_addi() { - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 0); - hyperstone_ldxx1(decode); -} + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); + check_delay_PC(); -void hyperstone_device::op93() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 1); - hyperstone_ldxx1(decode); -} + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; -void hyperstone_device::op94() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 0); - hyperstone_ldxx2(decode); -} + if (!N_OP_MASK) + imm = GET_C & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); + else if (!IMM_LONG) + imm = m_op & 0x0f; -void hyperstone_device::op95() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 1); - hyperstone_ldxx2(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::op96() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 0); - hyperstone_ldxx2(decode); -} + const uint64_t tmp = (uint64_t)imm + (uint64_t)dreg; -void hyperstone_device::op97() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 1); - hyperstone_ldxx2(decode); -} + SR |= (tmp & 0x100000000) >> 32; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; -void hyperstone_device::op98() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 0); - hyperstone_stxx1(decode); -} + dreg += imm; -void hyperstone_device::op99() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 1); - hyperstone_stxx1(decode); -} + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::op9a() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 0); - hyperstone_stxx1(decode); -} + if (DST_GLOBAL) + { + set_global_register(dst_code, dreg); + + if (dst_code == 0) + SR &= ~M_MASK; + } + else + { + m_local_regs[dst_code] = dreg; + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_addsi() +{ + if (!IMM_LONG) + check_delay_PC(); + + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const int32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + int32_t imm; + if (N_OP_MASK) + { + if (IMM_LONG) + { + imm = decode_immediate_s(); + check_delay_PC(); + } + else + { + imm = m_op & 0x0f; + } + } + else + { + if (IMM_LONG) + { + ignore_immediate_s(); + check_delay_PC(); + } + imm = SR & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01)); + } + + SR &= ~(V_MASK | Z_MASK | N_MASK); + + const int64_t tmp = (int64_t)imm + (int64_t)(int32_t)dreg; + SR |= ((imm ^ tmp) & (dreg ^ tmp) & 0x80000000) >> 28; + +//#if SETCARRYS +// SR |= (tmp & 0x100000000) >> 32; +//#endif + + const int32_t res = imm + (int32_t)dreg; + + if (res == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(res); + + if (DST_GLOBAL) + set_global_register(dst_code, res); + else + m_local_regs[dst_code] = res; + + m_icount -= m_clock_cycles_1; + + if (SR & V_MASK) + execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR)); +} + + + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_cmpbi() +{ + if (!IMM_LONG) + check_delay_PC(); + + const uint32_t dreg = DST_GLOBAL ? m_global_regs[DST_CODE] : m_local_regs[(DST_CODE + GET_FP) & 0x3f]; + + const uint32_t n = N_VALUE; + if (n) + { + uint32_t imm; + if (n == 31) + { + if (IMM_LONG) + { + ignore_immediate_s(); + check_delay_PC(); + } + imm = 0x7fffffff; // bit 31 = 0, others = 1 + } + else + { + if (IMM_LONG) + { + imm = decode_immediate_s(); + check_delay_PC(); + } + else + { + imm = m_op & 0x0f; + } + } + + if (dreg & imm) + SR &= ~Z_MASK; + else + SR |= Z_MASK; + } + else + { + if (IMM_LONG) + { + ignore_immediate_s(); + check_delay_PC(); + } + if ((dreg & 0xff000000) == 0 || (dreg & 0x00ff0000) == 0 || (dreg & 0x0000ff00) == 0 || (dreg & 0x000000ff) == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_andni() +{ + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); + + check_delay_PC(); + + if (N_OP_MASK == 0x10f) + imm = 0x7fffffff; // bit 31 = 0, others = 1 + else if (!IMM_LONG) + imm = m_op & 0x0f; + + uint32_t dreg; + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE; + dreg = m_global_regs[dst_code] & ~imm; + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + + set_global_register(dst_code, dreg); + } + else + { + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + dreg = m_local_regs[dst_code] & ~imm; + m_local_regs[dst_code] = dreg; + + if (dreg == 0) + SR |= Z_MASK; + else + SR &= ~Z_MASK; + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_ori() +{ + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); + + check_delay_PC(); + + if (!IMM_LONG) + imm = m_op & 0x0f; + + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE; + const uint32_t dreg = m_global_regs[dst_code] | imm; + + if (dreg) + SR &= ~Z_MASK; + else + SR |= Z_MASK; + + set_global_register(dst_code, dreg); + } + else + { + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code] |= imm; -void hyperstone_device::op9b() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 1); - hyperstone_stxx1(decode); -} + if (dreg) + SR &= ~Z_MASK; + else + SR |= Z_MASK; + } -void hyperstone_device::op9c() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 0); - hyperstone_stxx2(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::op9d() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::imm_size IMM_LONG> +void hyperstone_device::hyperstone_xori() { - LOCAL_DECODE_INIT; - RRdisdecode(decode, 0, 1); - hyperstone_stxx2(decode); -} + uint32_t imm; + if (IMM_LONG) + imm = decode_immediate_s(); -void hyperstone_device::op9e() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 0); - hyperstone_stxx2(decode); -} + check_delay_PC(); -void hyperstone_device::op9f() -{ - LOCAL_DECODE_INIT; - RRdisdecode(decode, 1, 1); - hyperstone_stxx2(decode); -} + if (!IMM_LONG) + imm = m_op & 0x0f; + uint32_t dreg; + if (DST_GLOBAL) + { + const uint32_t dst_code = DST_CODE; + dreg = m_global_regs[dst_code] ^ imm; + if (dreg) + SR &= ~Z_MASK; + else + SR |= Z_MASK; + set_global_register(dst_code, dreg); + } + else + { + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + dreg = m_local_regs[dst_code] ^= imm; -void hyperstone_device::opa0() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_shri(decode); -} + if (dreg) + SR &= ~Z_MASK; + else + SR |= Z_MASK; + } -void hyperstone_device::opa1() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_shri(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opa2() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_shri(decode); -} -void hyperstone_device::opa3() +template <hyperstone_device::shift_type HI_N> +void hyperstone_device::hyperstone_shrdi() { - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_shri(decode); -} + check_delay_PC(); -void hyperstone_device::opa4() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_sari(decode); -} + const uint32_t fp = GET_FP; + const uint32_t code = DST_CODE; + const uint32_t dst_code = (code + fp) & 0x3f; + const uint32_t dstf_code = (code + 1 + fp) & 0x3f; + uint32_t high_order = m_local_regs[dst_code]; + const uint32_t low_order = m_local_regs[dstf_code]; -void hyperstone_device::opa5() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_sari(decode); -} + uint64_t val = concat_64(high_order, low_order); -void hyperstone_device::opa6() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_sari(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::opa7() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_sari(decode); -} + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + if (HI_N || n) + { + SR |= (val >> (n - 1)) & 1; -void hyperstone_device::opa8() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_shli(decode); -} + val >>= n; + } -void hyperstone_device::opa9() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_shli(decode); -} + high_order = extract_64hi(val); -void hyperstone_device::opaa() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_shli(decode); -} + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); -void hyperstone_device::opab() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_shli(decode); -} + m_local_regs[dst_code] = high_order; + m_local_regs[dstf_code] = extract_64lo(val); -void hyperstone_device::opac() -{ - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opad() -{ - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); -} -void hyperstone_device::opae() +void hyperstone_device::hyperstone_shrd() { - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); -} + check_delay_PC(); -void hyperstone_device::opaf() -{ - LOCAL_DECODE_INIT; - no_decode(decode); - reserved(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = (SRC_CODE + fp) & 0x3f; + const uint32_t d_code = DST_CODE; + const uint32_t dst_code = (d_code + fp) & 0x3f; + const uint32_t dstf_code = (d_code + 1 + fp) & 0x3f; + if (src_code == dst_code || src_code == dstf_code) + { + m_icount -= m_clock_cycles_2; + return; + } + uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); -void hyperstone_device::opb0() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_mulu(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::opb1() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_mulu(decode); -} + const uint32_t n = m_local_regs[src_code] & 0x1f; -void hyperstone_device::opb2() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_mulu(decode); -} + if (n) + { + SR |= (val >> (n - 1)) & 1; + val >>= n; + } -void hyperstone_device::opb3() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_mulu(decode); -} + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(m_local_regs[dst_code]); -void hyperstone_device::opb4() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_muls(decode); -} + m_local_regs[dst_code] = (uint32_t)(val >> 32); + m_local_regs[dstf_code] = (uint32_t)val; -void hyperstone_device::opb5() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_muls(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opb6() +void hyperstone_device::hyperstone_shr() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_muls(decode); -} + check_delay_PC(); -void hyperstone_device::opb7() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_muls(decode); -} + const uint32_t fp = GET_FP; + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t n = m_local_regs[(SRC_CODE + fp) & 0x3f] & 0x1f; + uint32_t dreg = m_local_regs[dst_code]; -void hyperstone_device::opb8() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_set(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::opb9() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 0); - hyperstone_set(decode); -} + if (n && (dreg & (1 << (n - 1)))) + SR |= C_MASK; -void hyperstone_device::opba() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_set(decode); -} + dreg >>= n; -void hyperstone_device::opbb() -{ - LOCAL_DECODE_INIT; - Rndecode(decode, 1); - hyperstone_set(decode); -} + if (dreg == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(dreg); -void hyperstone_device::opbc() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 0); - hyperstone_mul(decode); -} + m_local_regs[dst_code] = dreg; -void hyperstone_device::opbd() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 0, 1); - hyperstone_mul(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opbe() +template <hyperstone_device::shift_type HI_N> +void hyperstone_device::hyperstone_sardi() { - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 0); - hyperstone_mul(decode); -} + check_delay_PC(); -void hyperstone_device::opbf() -{ - LOCAL_DECODE_INIT; - RRdecode(decode, 1, 1); - hyperstone_mul(decode); -} + const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f; + const uint32_t dstf_code = (dst_code + 1) & 0x3f; + uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::opc0() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fadd(decode); -} + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + if (HI_N || n) + { + SR |= (val >> (n - 1)) & 1; -void hyperstone_device::opc1() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_faddd(decode); -} + const uint64_t sign_bit = val >> 63; + val >>= n; -void hyperstone_device::opc2() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fsub(decode); -} + if (sign_bit) + val |= 0xffffffff00000000U << (32 - n); + } -void hyperstone_device::opc3() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fsubd(decode); -} + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(m_local_regs[dst_code]); -void hyperstone_device::opc4() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fmul(decode); -} + m_local_regs[dst_code] = (uint32_t)(val >> 32); + m_local_regs[dstf_code] = (uint32_t)val; -void hyperstone_device::opc5() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fmuld(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opc6() +void hyperstone_device::hyperstone_sard() { - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fdiv(decode); -} + check_delay_PC(); -void hyperstone_device::opc7() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fdivd(decode); -} + const uint32_t fp = GET_FP; + const uint32_t src_code = (SRC_CODE + fp) & 0x3f; + const uint32_t d_code = DST_CODE; + const uint32_t dst_code = (d_code + fp) & 0x3f; + const uint32_t dstf_code = (d_code + 1 + fp) & 0x3f; -void hyperstone_device::opc8() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcmp(decode); -} + if (src_code == dst_code || src_code == dstf_code) + { + m_icount -= m_clock_cycles_2; + return; + } -void hyperstone_device::opc9() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcmpd(decode); -} + uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]); -void hyperstone_device::opca() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcmpu(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::opcb() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcmpud(decode); -} + const uint32_t n = m_local_regs[src_code] & 0x1f; + if (n) + { + SR |= (val >> (n - 1)) & 1; -void hyperstone_device::opcc() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcvt(decode); -} + uint32_t sign_bit = val >> 63; -void hyperstone_device::opcd() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_fcvtd(decode); -} + val >>= n; -void hyperstone_device::opce() -{ - LOCAL_DECODE_INIT; - LLextdecode(decode); - hyperstone_extend(decode); + if (sign_bit) + { + val |= 0xffffffff00000000L << (32 - n); + } + } + + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(m_local_regs[dst_code]); + + m_local_regs[dst_code] = (uint32_t)(val >> 32); + m_local_regs[dstf_code] = (uint32_t)val; + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opcf() +void hyperstone_device::hyperstone_sar() { - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_do(decode); -} + check_delay_PC(); + const uint32_t fp = GET_FP; + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t n = m_local_regs[(SRC_CODE + fp) & 0x3f] & 0x1f; + uint32_t ret = m_local_regs[dst_code]; -void hyperstone_device::opd0() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_ldwr(decode); -} + SR &= ~(C_MASK | Z_MASK | N_MASK); -void hyperstone_device::opd1() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_ldwr(decode); -} + if (n) + { + const uint32_t sign_bit = ret & 0x80000000; -void hyperstone_device::opd2() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_lddr(decode); -} + SR |= (ret >> (n - 1)) & 1; -void hyperstone_device::opd3() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_lddr(decode); -} + ret >>= n; -void hyperstone_device::opd4() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_ldwp(decode); -} + if (sign_bit) + ret |= 0xffffffff << (32 - n); + } -void hyperstone_device::opd5() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_ldwp(decode); -} + if (ret == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(ret); -void hyperstone_device::opd6() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_lddp(decode); -} + m_local_regs[dst_code] = ret; -void hyperstone_device::opd7() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_lddp(decode); + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opd8() +template <hyperstone_device::shift_type HI_N> +void hyperstone_device::hyperstone_shldi() { - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_stwr(decode); -} + check_delay_PC(); -void hyperstone_device::opd9() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_stwr(decode); -} + const uint32_t fp = GET_FP; + const uint32_t code = DST_CODE; + const uint32_t dst_code = (code + fp) & 0x3f; + const uint32_t dstf_code = (code + 1 + fp) & 0x3f; + uint32_t high_order = m_local_regs[dst_code]; + uint32_t low_order = m_local_regs[dstf_code]; -void hyperstone_device::opda() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_stdr(decode); -} + uint64_t val = concat_64(high_order, low_order); -void hyperstone_device::opdb() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_stdr(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::opdc() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_stwp(decode); -} + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + if ((HI_N || n) && ((val << (n - 1)) & 0x8000000000000000U)) + SR |= C_MASK; -void hyperstone_device::opdd() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_stwp(decode); -} + const uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff; + const uint32_t tmp = high_order << n; -void hyperstone_device::opde() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 0); - hyperstone_stdp(decode); -} + if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000))) + SR |= V_MASK; -void hyperstone_device::opdf() -{ - LOCAL_DECODE_INIT; - LRdecode(decode, 1); - hyperstone_stdp(decode); -} + val <<= n; + high_order = extract_64hi(val); + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); -void hyperstone_device::ope0() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbv(decode); -} + m_local_regs[dst_code] = high_order; + m_local_regs[dstf_code] = extract_64lo(val); -void hyperstone_device::ope1() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbnv(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::ope2() +void hyperstone_device::hyperstone_shld() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbe(decode); -} + check_delay_PC(); -void hyperstone_device::ope3() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbne(decode); -} + const uint32_t fp = GET_FP; + const uint32_t d_code = DST_CODE; + uint32_t src_code = (SRC_CODE + fp) & 0x3f; + uint32_t dst_code = (d_code + fp) & 0x3f; + uint32_t dstf_code = (d_code + fp + 1) & 0x3f; -void hyperstone_device::ope4() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbc(decode); -} + // result undefined if Ls denotes the same register as Ld or Ldf + if (src_code == dst_code || src_code == dstf_code) + { + LOG("Denoted same registers in hyperstone_shld. PC = %08X\n", PC); + m_icount -= m_clock_cycles_2; + return; + } -void hyperstone_device::ope5() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbnc(decode); -} + uint32_t n = m_local_regs[src_code & 0x3f] & 0x1f; + uint32_t high_order = m_local_regs[dst_code]; /* registers offset by frame pointer */ + uint32_t low_order = m_local_regs[dstf_code]; -void hyperstone_device::ope6() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbse(decode); -} + uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; -void hyperstone_device::ope7() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbht(decode); -} + uint64_t val = concat_64(high_order, low_order); -void hyperstone_device::ope8() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbn(decode); -} + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + SR |= (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0; -void hyperstone_device::ope9() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbnn(decode); -} + uint32_t tmp = high_order << n; + if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000))) + SR |= V_MASK; -void hyperstone_device::opea() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dble(decode); -} + val <<= n; -void hyperstone_device::opeb() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbgt(decode); -} + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(m_local_regs[dst_code]); -void hyperstone_device::opec() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_dbr(decode); -} + m_local_regs[dst_code] = extract_64hi(val); + m_local_regs[dstf_code] = extract_64lo(val); -void hyperstone_device::oped() -{ - LOCAL_DECODE_INIT; - LLdecode(decode); - hyperstone_frame(decode); + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opee() +void hyperstone_device::hyperstone_shl() { - LOCAL_DECODE_INIT; - LRconstdecode(decode, 0); - hyperstone_call(decode); -} + check_delay_PC(); -void hyperstone_device::opef() -{ - LOCAL_DECODE_INIT; - LRconstdecode(decode, 1); - hyperstone_call(decode); -} + const uint32_t fp = GET_FP; + uint32_t src_code = SRC_CODE + fp; + uint32_t dst_code = DST_CODE + fp; + uint32_t n = m_local_regs[src_code & 0x3f] & 0x1f; + uint32_t base = m_local_regs[dst_code & 0x3f]; /* registers offset by frame pointer */ + uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff; + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); -void hyperstone_device::opf0() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bv(decode); -} + SR |= (n)?(((base<<(n-1))&0x80000000)?1:0):0; + uint32_t ret = base << n; -void hyperstone_device::opf1() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bnv(decode); + if (((base & mask) && (!(ret & 0x80000000))) || (((base & mask) ^ mask) && (ret & 0x80000000))) + SR |= V_MASK; + + if (ret == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(ret); + + m_local_regs[dst_code & 0x3f] = ret; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf2() +void hyperstone_device::hyperstone_testlz() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_be(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t sreg = m_local_regs[(SRC_CODE + fp) & 0x3f]; + uint32_t zeros = 0; + for (uint32_t mask = 0x80000000; mask != 0; mask >>= 1 ) + { + if (sreg & mask) + break; + else + zeros++; + } + + m_local_regs[(DST_CODE + fp) & 0x3f] = zeros; + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opf3() +void hyperstone_device::hyperstone_rol() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bne(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + + uint32_t n = m_local_regs[(SRC_CODE + fp) & 0x3f] & 0x1f; + uint32_t val = m_local_regs[dst_code]; + +#ifdef MISSIONCRAFT_FLAGS + const uint32_t base = val; + const uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff; +#endif + + if (n) + val = (val << n) | (val >> (32 - n)); + +#ifdef MISSIONCRAFT_FLAGS + SR &= ~(V_MASK | Z_MASK | C_MASK); + if (((base & mask) && (!(val & 0x80000000))) || (((base & mask) ^ mask) && (val & 0x80000000))) + SR |= V_MASK; +#else + SR &= ~(Z_MASK | C_MASK | N_MASK); +#endif + + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val); + + m_local_regs[dst_code] = val; + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_ldxx1() +{ + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + m_instruction_length = (2<<19); + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dreg = ((DST_GLOBAL && dst_code == SR_REGISTER) ? 0 : (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]); + + switch (sub_type) + { + case 0: // LDBS.D + if (SRC_GLOBAL) + set_global_register(src_code, (int32_t)(int8_t)READ_B(dreg + extra_s)); + else + m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg + extra_s); + break; + + case 1: // LDBU.D + if (SRC_GLOBAL) + set_global_register(src_code, READ_B(dreg + extra_s)); + else + m_local_regs[src_code] = READ_B(dreg + extra_s); + break; + + case 2: + if (SRC_GLOBAL) + { + if (extra_s & 1) + set_global_register(src_code, (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1))); + else + set_global_register(src_code, READ_HW(dreg + (extra_s & ~1))); + } + else + { + if (extra_s & 1) + m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg + (extra_s & ~1)); + else + m_local_regs[src_code] = READ_HW(dreg + (extra_s & ~1)); + } + break; + + case 3: + switch (extra_s & 3) + { + case 0: // LDW.D + if (SRC_GLOBAL) + set_global_register(src_code, READ_W(dreg + extra_s)); + else + m_local_regs[src_code] = READ_W(dreg + extra_s); + break; + case 1: // LDD.D + if (SRC_GLOBAL) + { + set_global_register(src_code, READ_W(dreg + (extra_s & ~1))); + set_global_register(srcf_code, READ_W(dreg + (extra_s & ~1) + 4)); + } + else + { + m_local_regs[src_code] = READ_W(dreg + (extra_s & ~1)); + m_local_regs[srcf_code] = READ_W(dreg + (extra_s & ~1) + 4); + } + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // LDW.IOD + if (SRC_GLOBAL) + set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3))); + else + m_local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3)); + break; + case 3: // LDD.IOD + if (SRC_GLOBAL) + { + set_global_register(src_code, IO_READ_W(dreg + (extra_s & ~3))); + set_global_register(srcf_code, IO_READ_W(dreg + (extra_s & ~3) + 4)); + } + else + { + m_local_regs[src_code] = IO_READ_W(dreg + (extra_s & ~3)); + m_local_regs[srcf_code] = IO_READ_W(dreg + (extra_s & ~3) + 4); + } + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + break; + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_ldxx2() +{ + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + m_instruction_length = (2<<19); + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : (DST_CODE + fp) & 0x3f; + + if (DST_GLOBAL && dst_code < 2) + { + m_icount -= m_clock_cycles_1; + LOG("Denoted PC or SR in hyperstone_ldxx2. PC = %08X\n", PC); + return; + } + + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : (SRC_CODE + fp) & 0x3f; + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + switch (sub_type) + { + case 0: // LDBS.N + if (SRC_GLOBAL) + set_global_register(src_code, (int32_t)(int8_t)READ_B(dreg)); + else + m_local_regs[src_code] = (int32_t)(int8_t)READ_B(dreg); + if (DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + + case 1: // LDBU.N + if (SRC_GLOBAL) + set_global_register(src_code, READ_B(dreg)); + else + m_local_regs[src_code] = READ_B(dreg); + if(DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + + case 2: + if (SRC_GLOBAL) + { + if (extra_s & 1) // LDHS.N + set_global_register(src_code, (int32_t)(int16_t)READ_HW(dreg)); + else // LDHU.N + set_global_register(src_code, READ_HW(dreg)); + } + else + { + if (extra_s & 1) // LDHS.N + m_local_regs[src_code] = (int32_t)(int16_t)READ_HW(dreg); + else // LDHU.N + m_local_regs[src_code] = READ_HW(dreg); + } + + if(DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += (extra_s & ~1); + break; + + case 3: + switch (extra_s & 3) + { + case 0: // LDW.N + if (SRC_GLOBAL) + set_global_register(src_code, READ_W(dreg)); + else + m_local_regs[src_code] = READ_W(dreg); + if(DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + case 1: // LDD.N + if (SRC_GLOBAL) + { + set_global_register(src_code, READ_W(dreg)); + set_global_register(srcf_code, READ_W(dreg + 4)); + } + else + { + m_local_regs[src_code] = READ_W(dreg); + m_local_regs[srcf_code] = READ_W(dreg + 4); + } + + if (DST_GLOBAL != SRC_GLOBAL || (src_code != dst_code && srcf_code != dst_code)) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s & ~1; + + m_icount -= m_clock_cycles_1; // extra cycle + break; + case 2: // Reserved + LOG("Executed Reserved instruction in hyperstone_ldxx2. PC = %08X\n", PC); + break; + case 3: // LDW.S + if (SRC_GLOBAL) + { + if (dreg < SP) + set_global_register(src_code, READ_W(dreg)); + else + set_global_register(src_code, m_local_regs[(dreg & 0xfc) >> 2]); + } + else + { + if (dreg < SP) + m_local_regs[src_code] = READ_W(dreg); + else + m_local_regs[src_code] = m_local_regs[(dreg & 0xfc) >> 2]; + } + + if (DST_GLOBAL != SRC_GLOBAL || src_code != dst_code) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s & ~3; + + m_icount -= m_clock_cycles_2; // extra cycles + break; + } + break; + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stxx1() +{ + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + m_instruction_length = (2<<19); + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dreg = ((DST_GLOBAL && dst_code == SR_REGISTER) ? 0 : (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]); + const uint32_t sreg = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]); + + switch (sub_type) + { + case 0: // STBS.D + // TODO: missing trap on range error + WRITE_B(dreg + extra_s, (uint8_t)sreg); + break; + + case 1: // STBU.D + WRITE_B(dreg + extra_s, (uint8_t)sreg); + break; + + case 2: // STHS.D, STHU.D + WRITE_HW(dreg + (extra_s & ~1), (uint16_t)sreg); + // TODO: missing trap on range error with STHS.D + break; + + case 3: + switch (extra_s & 3) + { + case 0: // STW.D + WRITE_W(dreg + (extra_s & ~1), sreg); + break; + case 1: // STD.D + { + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]); + extra_s &= ~1; + WRITE_W(dreg + extra_s, sreg); + WRITE_W(dreg + extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + case 2: // STW.IOD + IO_WRITE_W(dreg + (extra_s & ~3), sreg); + break; + case 3: // STD.IOD + { + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sregf = ((SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]); + extra_s &= ~3; + IO_WRITE_W(dreg + extra_s, sreg); + IO_WRITE_W(dreg + extra_s + 4, sregf); + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + } + break; + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stxx2() +{ + uint16_t next_1 = READ_OP(PC); + PC += 2; + + const uint16_t sub_type = (next_1 & 0x3000) >> 12; + + uint32_t extra_s; + if (next_1 & 0x8000) + { + const uint16_t next_2 = READ_OP(PC); + PC += 2; + m_instruction_length = (3<<19); + + extra_s = next_2; + extra_s |= ((next_1 & 0xfff) << 16); + + if (next_1 & 0x4000) + extra_s |= 0xf0000000; + } + else + { + m_instruction_length = (2<<19); + extra_s = next_1 & 0xfff; + + if (next_1 & 0x4000) + extra_s |= 0xfffff000; + } + + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + if (DST_GLOBAL && dst_code < 2) + { + m_icount -= m_clock_cycles_1; + return; + } + + switch (sub_type) + { + case 0: // STBS.N + // TODO: missing trap on range error + WRITE_B(dreg, (uint8_t)sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + + case 1: // STBU.N + WRITE_B(dreg, (uint8_t)sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + + case 2: // STHS.N, STHU.N + WRITE_HW(dreg, (uint16_t)sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s & ~1; + // TODO: missing trap on range error with STHS.N + break; + + case 3: + switch (extra_s & 3) + { + case 0: // STW.N + WRITE_W(dreg, sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s; + break; + case 1: // STD.N + { + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sregf = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]; + WRITE_W(dreg, sreg); + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += extra_s & ~1; + + if(DST_GLOBAL == SRC_GLOBAL && (src_code + 1) == dst_code) + WRITE_W(dreg + 4, sregf + (extra_s & ~1)); // because DREG == SREGF and DREG has been incremented + else + WRITE_W(dreg + 4, sregf); + + m_icount -= m_clock_cycles_1; // extra cycle + break; + } + case 2: // Reserved + LOG("Executed Reserved instruction in hyperstone_stxx2. PC = %08X\n", PC); + break; + case 3: // STW.S + if(dreg < SP) + WRITE_W(dreg, sreg); + else + m_local_regs[(dreg & 0xfc) >> 2] = sreg; + + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] += (extra_s & ~3); + + m_icount -= m_clock_cycles_2; // extra cycles + break; + } + break; + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf4() +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::hyperstone_shri() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bc(decode); + check_delay_PC(); + + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + uint32_t val = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + SR &= ~(C_MASK | Z_MASK | N_MASK); + + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + if (HI_N || n) + SR |= (val >> (n - 1)) & 1; + + val >>= n; + + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val); + + if (DST_GLOBAL) + set_global_register(dst_code, val); + else + m_local_regs[dst_code] = val; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf5() +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::hyperstone_sari() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bnc(decode); + check_delay_PC(); + + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + uint32_t val = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + SR &= ~(C_MASK | Z_MASK | N_MASK); + + if (HI_N || n) + { + SR |= (val >> (n - 1)) & 1; + + uint32_t sign_bit = val & 0x80000000; + val >>= n; + + if (sign_bit) + val |= 0xffffffff << (32 - n); + } + + if (val == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val); + + if (DST_GLOBAL) + set_global_register(dst_code, val); + else + m_local_regs[dst_code] = val; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf6() +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::hyperstone_shli() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bse(decode); + check_delay_PC(); + + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + uint32_t val = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + + const uint32_t n = HI_N ? HI_N_VALUE : LO_N_VALUE; + SR &= ~(C_MASK | V_MASK | Z_MASK | N_MASK); + SR |= (HI_N || n) ? (((val << (n - 1)) & 0x80000000) ? 1 : 0) : 0; + uint64_t mask = ((1U << (32 - n)) - 1) ^ 0xffffffff; + uint32_t val2 = val << n; + + if (((val & mask) && (!(val2 & 0x80000000))) || (((val & mask) ^ mask) && (val2 & 0x80000000))) + SR |= V_MASK; + + if (val2 == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(val2); + + if (DST_GLOBAL) + set_global_register(dst_code, val2); + else + m_local_regs[dst_code] = val2; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf7() +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL, hyperstone_device::sign_mode SIGNED> +void hyperstone_device::hyperstone_mulsu() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bht(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + const uint32_t dstf_code = DST_GLOBAL ? (dst_code + 1) : ((dst_code + 1) & 0x3f); + + if ((SRC_GLOBAL && src_code < 2) || (DST_GLOBAL && dst_code < 2)) + { + LOG("Denoted PC or SR in hyperstone_muls/u instruction. PC = %08X\n", PC); + return; + } + + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint64_t double_word = SIGNED ? (uint64_t)((int64_t)(int32_t)sreg * (int64_t)(int32_t)dreg) : ((uint64_t)sreg *(uint64_t)dreg); + + const uint32_t high_order = (uint32_t)(double_word >> 32); + + SR &= ~(Z_MASK | N_MASK); + if (double_word == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(high_order); + + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = high_order; + (DST_GLOBAL ? m_global_regs : m_local_regs)[dstf_code] = (uint32_t)double_word; + + if(SIGNED == IS_SIGNED && (sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= m_clock_cycles_4; + else if(SIGNED == IS_UNSIGNED && sreg <= 0xffff && dreg <= 0xffff) + m_icount -= m_clock_cycles_4; + else + m_icount -= m_clock_cycles_6; } -void hyperstone_device::opf8() -{ - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bn(decode); +template <hyperstone_device::shift_type HI_N, hyperstone_device::reg_bank DST_GLOBAL> +void hyperstone_device::hyperstone_set() +{ + check_delay_PC(); + + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f); + const uint32_t n = LO_N_VALUE; + + if (DST_GLOBAL && dst_code < 2) + { + m_icount -= m_clock_cycles_1; + return; + } + + if (HI_N) + { + if (n >= 4 || n == 2) + { + static const uint32_t set_result[16] = { 0, 0, 0, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0 }; + static const uint32_t unset_result[16] = { 0, 0, 0xffffffff, 0, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff, 0, 0xffffffff }; + static const uint32_t mask[16] = { 0, 0, 0, 0, (N_MASK | Z_MASK), (N_MASK | Z_MASK), N_MASK, N_MASK, + (C_MASK | Z_MASK), (C_MASK | Z_MASK), C_MASK, C_MASK, Z_MASK, Z_MASK, V_MASK, V_MASK }; + + if (SR & mask[n]) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = set_result[n]; + else + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = unset_result[n]; + } + else + { + LOG("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC); + } + } + else + { + if (n == 0) + { + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = (SP & 0xfffffe00) | (GET_FP << 2) | (((SP & 0x100) && (SIGN_BIT(SR) == 0)) ? 1 : 0); + } + else if (n >= 2) + { + static const uint32_t set_result[16] = { 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 }; + static const uint32_t unset_result[16] = { 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 }; + static const uint32_t mask[16] = { 0, 0, 0, 0, (N_MASK | Z_MASK), (N_MASK | Z_MASK), N_MASK, N_MASK, + (C_MASK | Z_MASK), (C_MASK | Z_MASK), C_MASK, C_MASK, Z_MASK, Z_MASK, V_MASK, V_MASK }; + + if (SR & mask[n]) + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = set_result[n]; + else + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = unset_result[n]; + } + else + { + LOG("Used reserved N value (%d) in hyperstone_set. PC = %08X\n", n, PC); + } + } + + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank DST_GLOBAL, hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_mul() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = DST_GLOBAL ? DST_CODE : ((DST_CODE + fp) & 0x3f); + + if ((SRC_GLOBAL && src_code < 2) || (DST_GLOBAL && dst_code < 2)) + { + LOG("Denoted PC or SR in hyperstone_mul instruction. PC = %08X\n", PC); + return; + } + + const uint32_t dreg = (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code]; + const uint32_t sreg = (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t result = sreg * dreg; + + SR &= ~(Z_MASK | N_MASK); + if (result == 0) + SR |= Z_MASK; + SR |= SIGN_TO_N(result); + + (DST_GLOBAL ? m_global_regs : m_local_regs)[dst_code] = result; + + if ((sreg >= 0xffff8000 && sreg <= 0x7fff) && (dreg >= 0xffff8000 && dreg <= 0x7fff)) + m_icount -= 3 << m_clck_scale; + else + m_icount -= 5 << m_clck_scale; +} + +void hyperstone_device::hyperstone_extend() +{ + m_instruction_length = (2<<19); + const uint32_t func = READ_OP(PC); + PC += 2; + check_delay_PC(); + + //TODO: add locks, overflow error and other things + const uint32_t fp = GET_FP; + const uint32_t vals = m_local_regs[(SRC_CODE + fp) & 0x3f]; + const uint32_t vald = m_local_regs[(DST_CODE + fp) & 0x3f]; + + switch (func) // extended opcode + { + // signed or unsigned multiplication, single word product + case EMUL: + case 0x100: // used in "N" type cpu + m_global_regs[15] = (uint32_t)(vals * vald); + break; + + // unsigned multiplication, double word product + case EMULU: + { + const uint64_t result = (uint64_t)vals * (uint64_t)vald; + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + break; + } + // signed multiplication, double word product + case EMULS: + { + const int64_t result = (int64_t)(int32_t)vals * (int64_t)(int32_t)vald; + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + + break; + } + + // signed multiply/add, single word product sum + case EMAC: + m_global_regs[15] += (int32_t)vals * (int32_t)vald; + break; + + // signed multiply/add, double word product sum + case EMACD: + { + int64_t result = (int64_t)concat_64(m_global_regs[14], m_global_regs[15]) + (int64_t)((int64_t)(int32_t)vals * (int64_t)(int32_t)vald); + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + break; + } + // signed multiply/substract, single word product difference + case EMSUB: + m_global_regs[15] = (int32_t)m_global_regs[15] - ((int32_t)vals * (int32_t)vald); + break; + + // signed multiply/substract, double word product difference + case EMSUBD: + { + int64_t result = (int64_t)concat_64(m_global_regs[14], m_global_regs[15]) - (int64_t)((int64_t)(int32_t)vals * (int64_t)(int32_t)vald); + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + + break; + } + + // signed half-word multiply/add, single word product sum + case EHMAC: + m_global_regs[15] = (int32_t)m_global_regs[15] + ((int32_t)((vald & 0xffff0000) >> 16) * (int32_t)((vals & 0xffff0000) >> 16)) + ((int32_t)(vald & 0xffff) * (int32_t)(vals & 0xffff)); + break; + + // signed half-word multiply/add, double word product sum + case EHMACD: + { + int64_t result = (int64_t)concat_64(m_global_regs[14], m_global_regs[15]) + (int64_t)((int64_t)(int32_t)((vald & 0xffff0000) >> 16) * (int64_t)(int32_t)((vals & 0xffff0000) >> 16)) + ((int64_t)(int32_t)(vald & 0xffff) * (int64_t)(int32_t)(vals & 0xffff)); + m_global_regs[14] = (uint32_t)(result >> 32); + m_global_regs[15] = (uint32_t)result; + break; + } + + // half-word complex multiply + case EHCMULD: + m_global_regs[14] = (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); + m_global_regs[15] = (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); + break; + + // half-word complex multiply/add + case EHCMACD: + m_global_regs[14] += (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff)); + m_global_regs[15] += (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16)); + break; + + // half-word (complex) add/substract + // Ls is not used and should denote the same register as Ld + case EHCSUMD: + { + const uint32_t r14 = m_global_regs[14]; + const uint32_t r15 = m_global_regs[15]; + m_global_regs[14] = (((((vals & 0xffff0000) >> 16) + r14) << 16) & 0xffff0000) | (((vals & 0xffff) + r15) & 0xffff); + m_global_regs[15] = (((((vals & 0xffff0000) >> 16) - r14) << 16) & 0xffff0000) | (((vals & 0xffff) - r15) & 0xffff); + break; + } + + // half-word (complex) add/substract with fixed point adjustment + // Ls is not used and should denote the same register as Ld + case EHCFFTD: + { + const uint32_t r14 = m_global_regs[14]; + const uint32_t r15 = m_global_regs[15]; + m_global_regs[14] = (((((vals & 0xffff0000) >> 16) + (r14 >> 15)) << 16) & 0xffff0000) | (((vals & 0xffff) + (r15 >> 15)) & 0xffff); + m_global_regs[15] = (((((vals & 0xffff0000) >> 16) - (r14 >> 15)) << 16) & 0xffff0000) | (((vals & 0xffff) - (r15 >> 15)) & 0xffff); + break; + } + + // half-word (complex) add/substract with fixed point adjustment and shift + // Ls is not used and should denote the same register as Ld + case EHCFFTSD: + { + const uint32_t r14 = m_global_regs[14]; + const uint32_t r15 = m_global_regs[15]; + m_global_regs[14] = ((((((vals & 0xffff0000) >> 16) + (r14 >> 15)) >> 1) << 16) & 0xffff0000) | (((((vals & 0xffff) + (r15 >> 15)) >> 1) & 0xffff)); + m_global_regs[15] = ((((((vals & 0xffff0000) >> 16) - (r14 >> 15)) >> 1) << 16) & 0xffff0000) | (((((vals & 0xffff) - (r15 >> 15)) >> 1) & 0xffff)); + break; + } + + default: + LOG("Executed Illegal extended opcode (%X). PC = %08X\n", func, PC); + break; + } + + m_icount -= m_clock_cycles_1; //TODO: with the latency it can change +} + + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_ldwr() +{ + check_delay_PC(); + const uint32_t fp = GET_FP; + if (SRC_GLOBAL) + set_global_register(SRC_CODE, READ_W(m_local_regs[(DST_CODE + fp) & 0x3f])); + else + m_local_regs[(SRC_CODE + fp) & 0x3f] = READ_W(m_local_regs[(DST_CODE + fp) & 0x3f]); + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_lddr() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dreg = m_local_regs[(DST_CODE + fp) & 0x3f]; + + if (SRC_GLOBAL) + { + set_global_register(src_code, READ_W(dreg)); + set_global_register(src_code + 1, READ_W(dreg + 4)); + } + else + { + m_local_regs[src_code] = READ_W(dreg); + m_local_regs[(src_code + 1) & 0x3f] = READ_W(dreg + 4); + } + + m_icount -= m_clock_cycles_2; +} + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_ldwp() +{ + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + + if (SRC_GLOBAL) + { + set_global_register(SRC_CODE, READ_W(m_local_regs[dst_code])); + m_local_regs[dst_code] += 4; + } + else + { + const uint32_t src_code = (SRC_CODE + fp) & 0x3f; + m_local_regs[src_code] = READ_W(m_local_regs[dst_code]); + // post increment the destination register if it's different from the source one + // (needed by Hidden Catch) + if (src_code != dst_code) + m_local_regs[dst_code] += 4; + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opf9() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_lddp() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bnn(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code]; + + if (SRC_GLOBAL) + { + set_global_register(src_code, READ_W(dreg)); + set_global_register(src_code + 1, READ_W(dreg + 4)); + m_local_regs[dst_code] += 8; + } + else + { + const uint32_t srcf_code = (src_code + 1) & 0x3f; + m_local_regs[src_code] = READ_W(dreg); + m_local_regs[srcf_code] = READ_W(dreg + 4); + + // post increment the destination register if it's different from the source one + // and from the "next source" one + if (src_code != dst_code && srcf_code != dst_code) + m_local_regs[dst_code] += 8; + } + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opfa() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stwr() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_ble(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + WRITE_W(m_local_regs[(DST_CODE + fp) & 0x3f], sreg); + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opfb() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stdr() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_bgt(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t srcf_code = SRC_GLOBAL ? (SRC_CODE + 1) : ((src_code + 1) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t sregf = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]; + + const uint32_t dreg = m_local_regs[(DST_CODE + GET_FP) & 0x3f]; + + WRITE_W(dreg, sreg); + WRITE_W(dreg + 4, sregf); + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opfc() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stwp() { - LOCAL_DECODE_INIT; - PCreldecode(decode); - hyperstone_br(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code]; + + WRITE_W(dreg, sreg); + m_local_regs[dst_code] += 4; + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opfd() +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_stdp() { - LOCAL_DECODE_INIT; - PCadrdecode(decode); - hyperstone_trap(decode); + check_delay_PC(); + + const uint32_t fp = GET_FP; + const uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + const uint32_t srcf_code = SRC_GLOBAL ? (src_code + 1) : ((src_code + 1) & 0x3f); + const uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; + const uint32_t sregf = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[srcf_code]; + + const uint32_t dst_code = (DST_CODE + fp) & 0x3f; + const uint32_t dreg = m_local_regs[dst_code]; + + WRITE_W(dreg, sreg); + + m_local_regs[dst_code] += 8; + + if (SRC_GLOBAL || srcf_code != dst_code) + WRITE_W(dreg + 4, sregf); + else + WRITE_W(dreg + 4, sregf + 8); // because DREG == SREGF and DREG has been incremented + + m_icount -= m_clock_cycles_2; } -void hyperstone_device::opfe() +template <hyperstone_device::branch_condition CONDITION, hyperstone_device::condition_set COND_SET> +void hyperstone_device::hyperstone_db() { - LOCAL_DECODE_INIT; - PCadrdecode(decode); - hyperstone_trap(decode); + static const uint32_t condition_masks[6] = { V_MASK, Z_MASK, C_MASK, C_MASK | Z_MASK, N_MASK, N_MASK | Z_MASK }; + if (COND_SET) + { + if (SR & condition_masks[CONDITION]) + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = 1; + m_delay_pc = PC + offset; + m_intblock = 3; + } + else + { + ignore_pcrel(); + check_delay_PC(); + } + } + else + { + if (SR & condition_masks[CONDITION]) + { + ignore_pcrel(); + check_delay_PC(); + } + else + { + const int32_t offset = decode_pcrel(); + check_delay_PC(); + m_delay_slot = 1; + m_delay_pc = PC + offset; + m_intblock = 3; + } + } + + m_icount -= m_clock_cycles_1; } -void hyperstone_device::opff() +void hyperstone_device::hyperstone_dbr() { - LOCAL_DECODE_INIT; - PCadrdecode(decode); - hyperstone_trap(decode); + const int32_t offset = decode_pcrel(); + check_delay_PC(); + + m_delay_slot = 1; + m_delay_pc = PC + offset; + m_intblock = 3; } -const hyperstone_device::ophandler hyperstone_device::s_opcodetable[256] = +void hyperstone_device::hyperstone_frame() { - &hyperstone_device::op00, &hyperstone_device::op01, &hyperstone_device::op02, &hyperstone_device::op03, - &hyperstone_device::op04, &hyperstone_device::op05, &hyperstone_device::op06, &hyperstone_device::op07, - &hyperstone_device::op08, &hyperstone_device::op09, &hyperstone_device::op0a, &hyperstone_device::op0b, - &hyperstone_device::op0c, &hyperstone_device::op0d, &hyperstone_device::op0e, &hyperstone_device::op0f, + check_delay_PC(); - &hyperstone_device::op10, &hyperstone_device::op11, &hyperstone_device::op12, &hyperstone_device::op13, - &hyperstone_device::op14, &hyperstone_device::op15, &hyperstone_device::op16, &hyperstone_device::op17, - &hyperstone_device::op18, &hyperstone_device::op19, &hyperstone_device::op1a, &hyperstone_device::op1b, - &hyperstone_device::op1c, &hyperstone_device::op1d, &hyperstone_device::op1e, &hyperstone_device::op1f, + uint8_t realfp = GET_FP - SRC_CODE; + uint8_t dst_code = DST_CODE; - &hyperstone_device::op20, &hyperstone_device::op21, &hyperstone_device::op22, &hyperstone_device::op23, - &hyperstone_device::op24, &hyperstone_device::op25, &hyperstone_device::op26, &hyperstone_device::op27, - &hyperstone_device::op28, &hyperstone_device::op29, &hyperstone_device::op2a, &hyperstone_device::op2b, - &hyperstone_device::op2c, &hyperstone_device::op2d, &hyperstone_device::op2e, &hyperstone_device::op2f, + SET_FP(realfp); + SET_FL(dst_code); + SR &= ~M_MASK; - &hyperstone_device::op30, &hyperstone_device::op31, &hyperstone_device::op32, &hyperstone_device::op33, - &hyperstone_device::op34, &hyperstone_device::op35, &hyperstone_device::op36, &hyperstone_device::op37, - &hyperstone_device::op38, &hyperstone_device::op39, &hyperstone_device::op3a, &hyperstone_device::op3b, - &hyperstone_device::op3c, &hyperstone_device::op3d, &hyperstone_device::op3e, &hyperstone_device::op3f, + int8_t difference = ((SP & 0x1fc) >> 2) + (64 - 10) - (realfp + GET_FL); // really it's 7 bits - &hyperstone_device::op40, &hyperstone_device::op41, &hyperstone_device::op42, &hyperstone_device::op43, - &hyperstone_device::op44, &hyperstone_device::op45, &hyperstone_device::op46, &hyperstone_device::op47, - &hyperstone_device::op48, &hyperstone_device::op49, &hyperstone_device::op4a, &hyperstone_device::op4b, - &hyperstone_device::op4c, &hyperstone_device::op4d, &hyperstone_device::op4e, &hyperstone_device::op4f, + /* convert to 8 bits */ + if(difference > 63) + difference = (int8_t)(difference|0x80); + else if( difference < -64 ) + difference = difference & 0x7f; - &hyperstone_device::op50, &hyperstone_device::op51, &hyperstone_device::op52, &hyperstone_device::op53, - &hyperstone_device::op54, &hyperstone_device::op55, &hyperstone_device::op56, &hyperstone_device::op57, - &hyperstone_device::op58, &hyperstone_device::op59, &hyperstone_device::op5a, &hyperstone_device::op5b, - &hyperstone_device::op5c, &hyperstone_device::op5d, &hyperstone_device::op5e, &hyperstone_device::op5f, + if (difference < 0) // else it's finished + { + bool tmp_flag = SP >= UB; - &hyperstone_device::op60, &hyperstone_device::op61, &hyperstone_device::op62, &hyperstone_device::op63, - &hyperstone_device::op64, &hyperstone_device::op65, &hyperstone_device::op66, &hyperstone_device::op67, - &hyperstone_device::op68, &hyperstone_device::op69, &hyperstone_device::op6a, &hyperstone_device::op6b, - &hyperstone_device::op6c, &hyperstone_device::op6d, &hyperstone_device::op6e, &hyperstone_device::op6f, + for (; difference < 0; difference++) + { + WRITE_W(SP, m_local_regs[(SP & 0xfc) >> 2]); + SP += 4; + } + + if (tmp_flag) + { + execute_exception(get_trap_addr(TRAPNO_FRAME_ERROR)); + } + } + + //TODO: no 1! + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::reg_bank SRC_GLOBAL> +void hyperstone_device::hyperstone_call() +{ + uint16_t imm_1 = READ_OP(PC); + PC += 2; + + int32_t extra_s = 0; + + if (imm_1 & 0x8000) + { + uint16_t imm_2 = READ_OP(PC); + + PC += 2; + SET_ILC(3<<19); + + extra_s = imm_2; + extra_s |= ((imm_1 & 0x3fff) << 16); + + if (imm_1 & 0x4000) + extra_s |= 0xc0000000; + } + else + { + extra_s = imm_1 & 0x3fff; + + SET_ILC(2<<19); + + if (imm_1 & 0x4000) + extra_s |= 0xffffc000; + } - &hyperstone_device::op70, &hyperstone_device::op71, &hyperstone_device::op72, &hyperstone_device::op73, - &hyperstone_device::op74, &hyperstone_device::op75, &hyperstone_device::op76, &hyperstone_device::op77, - &hyperstone_device::op78, &hyperstone_device::op79, &hyperstone_device::op7a, &hyperstone_device::op7b, - &hyperstone_device::op7c, &hyperstone_device::op7d, &hyperstone_device::op7e, &hyperstone_device::op7f, + check_delay_PC(); - &hyperstone_device::op80, &hyperstone_device::op81, &hyperstone_device::op82, &hyperstone_device::op83, - &hyperstone_device::op84, &hyperstone_device::op85, &hyperstone_device::op86, &hyperstone_device::op87, - &hyperstone_device::op88, &hyperstone_device::op89, &hyperstone_device::op8a, &hyperstone_device::op8b, - &hyperstone_device::op8c, &hyperstone_device::op8d, &hyperstone_device::op8e, &hyperstone_device::op8f, + uint32_t fp = GET_FP; + uint32_t src_code = SRC_GLOBAL ? SRC_CODE : ((SRC_CODE + fp) & 0x3f); + uint32_t dst_code = DST_CODE; - &hyperstone_device::op90, &hyperstone_device::op91, &hyperstone_device::op92, &hyperstone_device::op93, - &hyperstone_device::op94, &hyperstone_device::op95, &hyperstone_device::op96, &hyperstone_device::op97, - &hyperstone_device::op98, &hyperstone_device::op99, &hyperstone_device::op9a, &hyperstone_device::op9b, - &hyperstone_device::op9c, &hyperstone_device::op9d, &hyperstone_device::op9e, &hyperstone_device::op9f, + uint32_t sreg = (SRC_GLOBAL && src_code == SR_REGISTER) ? 0 : (SRC_GLOBAL ? m_global_regs : m_local_regs)[src_code]; - &hyperstone_device::opa0, &hyperstone_device::opa1, &hyperstone_device::opa2, &hyperstone_device::opa3, - &hyperstone_device::opa4, &hyperstone_device::opa5, &hyperstone_device::opa6, &hyperstone_device::opa7, - &hyperstone_device::opa8, &hyperstone_device::opa9, &hyperstone_device::opaa, &hyperstone_device::opab, - &hyperstone_device::opac, &hyperstone_device::opad, &hyperstone_device::opae, &hyperstone_device::opaf, + if (!DST_CODE) + dst_code = 16; - &hyperstone_device::opb0, &hyperstone_device::opb1, &hyperstone_device::opb2, &hyperstone_device::opb3, - &hyperstone_device::opb4, &hyperstone_device::opb5, &hyperstone_device::opb6, &hyperstone_device::opb7, - &hyperstone_device::opb8, &hyperstone_device::opb9, &hyperstone_device::opba, &hyperstone_device::opbb, - &hyperstone_device::opbc, &hyperstone_device::opbd, &hyperstone_device::opbe, &hyperstone_device::opbf, + uint32_t dreg_index = dst_code + fp; + m_local_regs[dreg_index & 0x3f] = (PC & ~1) | GET_S; + m_local_regs[(dreg_index + 1) & 0x3f] = SR; - &hyperstone_device::opc0, &hyperstone_device::opc1, &hyperstone_device::opc2, &hyperstone_device::opc3, - &hyperstone_device::opc4, &hyperstone_device::opc5, &hyperstone_device::opc6, &hyperstone_device::opc7, - &hyperstone_device::opc8, &hyperstone_device::opc9, &hyperstone_device::opca, &hyperstone_device::opcb, - &hyperstone_device::opcc, &hyperstone_device::opcd, &hyperstone_device::opce, &hyperstone_device::opcf, + SET_FP(fp + dst_code); + SET_FL(6); //default value for call + SR &= ~M_MASK; - &hyperstone_device::opd0, &hyperstone_device::opd1, &hyperstone_device::opd2, &hyperstone_device::opd3, - &hyperstone_device::opd4, &hyperstone_device::opd5, &hyperstone_device::opd6, &hyperstone_device::opd7, - &hyperstone_device::opd8, &hyperstone_device::opd9, &hyperstone_device::opda, &hyperstone_device::opdb, - &hyperstone_device::opdc, &hyperstone_device::opdd, &hyperstone_device::opde, &hyperstone_device::opdf, + PC = (extra_s & ~1) + sreg; - &hyperstone_device::ope0, &hyperstone_device::ope1, &hyperstone_device::ope2, &hyperstone_device::ope3, - &hyperstone_device::ope4, &hyperstone_device::ope5, &hyperstone_device::ope6, &hyperstone_device::ope7, - &hyperstone_device::ope8, &hyperstone_device::ope9, &hyperstone_device::opea, &hyperstone_device::opeb, - &hyperstone_device::opec, &hyperstone_device::oped, &hyperstone_device::opee, &hyperstone_device::opef, + m_intblock = 2; - &hyperstone_device::opf0, &hyperstone_device::opf1, &hyperstone_device::opf2, &hyperstone_device::opf3, - &hyperstone_device::opf4, &hyperstone_device::opf5, &hyperstone_device::opf6, &hyperstone_device::opf7, - &hyperstone_device::opf8, &hyperstone_device::opf9, &hyperstone_device::opfa, &hyperstone_device::opfb, - &hyperstone_device::opfc, &hyperstone_device::opfd, &hyperstone_device::opfe, &hyperstone_device::opff -}; + //TODO: add interrupt locks, errors, .... + + //TODO: no 1! + m_icount -= m_clock_cycles_1; +} + +template <hyperstone_device::branch_condition CONDITION, hyperstone_device::condition_set COND_SET> +void hyperstone_device::hyperstone_b() +{ + static const uint32_t condition_masks[6] = { V_MASK, Z_MASK, C_MASK, C_MASK | Z_MASK, N_MASK, N_MASK | Z_MASK }; + if (COND_SET) + { + if (SR & condition_masks[CONDITION]) + { + hyperstone_br(); + } + else + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } + } + else + { + if (SR & condition_masks[CONDITION]) + { + ignore_pcrel(); + check_delay_PC(); + m_icount -= m_clock_cycles_1; + } + else + { + hyperstone_br(); + } + } +} diff --git a/src/devices/cpu/es5510/es5510.cpp b/src/devices/cpu/es5510/es5510.cpp index 5848ccc05e2..61a94d8316f 100644 --- a/src/devices/cpu/es5510/es5510.cpp +++ b/src/devices/cpu/es5510/es5510.cpp @@ -9,6 +9,7 @@ #include "emu.h" #include "es5510.h" +#include "es5510d.h" #include "cpu/m68000/m68000.h" #include "debugger.h" @@ -924,19 +925,9 @@ void es5510_device::execute_run() { } } -uint32_t es5510_device::disasm_min_opcode_bytes() const +util::disasm_interface *es5510_device::create_disassembler() { - return 6; -} - -uint32_t es5510_device::disasm_max_opcode_bytes() const -{ - return 6; -} - -offs_t es5510_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - return pc; + return new es5510_disassembler; } #if VERBOSE_EXEC diff --git a/src/devices/cpu/es5510/es5510.h b/src/devices/cpu/es5510/es5510.h index 56045a4e769..0fd41807684 100644 --- a/src/devices/cpu/es5510/es5510.h +++ b/src/devices/cpu/es5510/es5510.h @@ -131,10 +131,8 @@ protected: virtual uint32_t execute_max_cycles() const override; virtual uint32_t execute_input_lines() const override; virtual void execute_run() override; - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void execute_set_input(int linenum, int state) override; + virtual util::disasm_interface *create_disassembler() override; int32_t alu_operation(uint8_t op, int32_t aValue, int32_t bValue, uint8_t &flags); void alu_operation_end(); diff --git a/src/devices/cpu/es5510/es5510d.cpp b/src/devices/cpu/es5510/es5510d.cpp new file mode 100644 index 00000000000..d563019f486 --- /dev/null +++ b/src/devices/cpu/es5510/es5510d.cpp @@ -0,0 +1,21 @@ +// license:BSD-3-Clause +// copyright-holders:Christian Brunschen +/*************************************************************************** + * + * es5510.c - Ensoniq ES5510 (ESP) emulation + * by Christian Brunschen + * + ***************************************************************************/ + +#include "emu.h" +#include "es5510d.h" + +u32 es5510_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t es5510_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + return 1; +} diff --git a/src/devices/cpu/es5510/es5510d.h b/src/devices/cpu/es5510/es5510d.h new file mode 100644 index 00000000000..e80b4a3fe36 --- /dev/null +++ b/src/devices/cpu/es5510/es5510d.h @@ -0,0 +1,25 @@ +// license:BSD-3-Clause +// copyright-holders:Christian Brunschen +/*************************************************************************** + * + * es5510.c - Ensoniq ES5510 (ESP) emulation + * by Christian Brunschen + * + ***************************************************************************/ + +#ifndef MAME_CPU_ES5510_ES5510DASM_H +#define MAME_CPU_ES5510_ES5510DASM_H + +#pragma once + +class es5510_disassembler : public util::disasm_interface +{ +public: + es5510_disassembler() = default; + virtual ~es5510_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/esrip/esrip.cpp b/src/devices/cpu/esrip/esrip.cpp index ee8416304c7..e87fd1821d6 100644 --- a/src/devices/cpu/esrip/esrip.cpp +++ b/src/devices/cpu/esrip/esrip.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "esrip.h" +#include "esripdsm.h" #include "debugger.h" #include "screen.h" @@ -192,7 +193,7 @@ void esrip_device::device_start() m_ipt_ram.resize(IPT_RAM_SIZE/2); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); // register our state for the debugger state_add(STATE_GENPC, "GENPC", m_rip_pc).noshow(); @@ -372,39 +373,15 @@ void esrip_device::state_string_export(const device_state_entry &entry, std::str //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t esrip_device::disasm_min_opcode_bytes() const -{ - return 8; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t esrip_device::disasm_max_opcode_bytes() const -{ - return 8; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t esrip_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *esrip_device::create_disassembler() { - extern CPU_DISASSEMBLE( esrip ); - return CPU_DISASSEMBLE_NAME(esrip)(this, stream, pc, oprom, opram, options); + return new esrip_disassembler; } - /*************************************************************************** PRIVATE FUNCTIONS ***************************************************************************/ @@ -1901,7 +1878,7 @@ void esrip_device::execute_run() m_pl7 = m_l7; /* Latch instruction */ - inst = m_direct->read_qword(RIP_PC << 3); + inst = m_direct->read_qword(RIP_PC); in_h = inst >> 32; in_l = inst & 0xffffffff; diff --git a/src/devices/cpu/esrip/esrip.h b/src/devices/cpu/esrip/esrip.h index 8aaa0f1d071..ed2fadd98e9 100644 --- a/src/devices/cpu/esrip/esrip.h +++ b/src/devices/cpu/esrip/esrip.h @@ -136,9 +136,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -195,7 +193,7 @@ protected: uint8_t *m_lbrm; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; int m_icount; @@ -266,7 +264,4 @@ private: void am29116_execute(uint16_t inst, int _sre); }; - -CPU_DISASSEMBLE( esrip ); - #endif // MAME_CPU_ESRIP_ESRIP_H diff --git a/src/devices/cpu/esrip/esripdsm.cpp b/src/devices/cpu/esrip/esripdsm.cpp index 04890fba2e4..43ecd616539 100644 --- a/src/devices/cpu/esrip/esripdsm.cpp +++ b/src/devices/cpu/esrip/esripdsm.cpp @@ -10,14 +10,18 @@ ***************************************************************************/ #include "emu.h" -#include "debugger.h" +#include "esripdsm.h" +u32 esrip_disassembler::opcode_alignment() const +{ + return 1; +} /*************************************************************************** DISASSEMBLY HOOK (TODO: FINISH) ***************************************************************************/ -CPU_DISASSEMBLE(esrip) +offs_t esrip_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { #if 0 static const char* const jmp_types[] = @@ -45,7 +49,7 @@ CPU_DISASSEMBLE(esrip) }; #endif - uint64_t inst = big_endianize_int64(*(uint64_t *)oprom); + uint64_t inst = opcodes.r64(pc); uint32_t inst_hi = inst >> 32; uint32_t inst_lo = inst & 0xffffffff; @@ -91,5 +95,5 @@ CPU_DISASSEMBLE(esrip) ctrl3 & 0x80 ? ' ' : '7' ); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } diff --git a/src/devices/cpu/esrip/esripdsm.h b/src/devices/cpu/esrip/esripdsm.h new file mode 100644 index 00000000000..0491a02bf29 --- /dev/null +++ b/src/devices/cpu/esrip/esripdsm.h @@ -0,0 +1,27 @@ +// license:BSD-3-Clause +// copyright-holders:Philip Bennett +/*************************************************************************** + + esripdsm.c + + Implementation of the Entertainment Sciences + AM29116-based Real Time Image Processor + +***************************************************************************/ + +#ifndef MAME_CPU_ESRIP_ESRIPDSM_H +#define MAME_CPU_ESRIP_ESRIPDSM_H + +#pragma once + +class esrip_disassembler : public util::disasm_interface +{ +public: + esrip_disassembler() = default; + virtual ~esrip_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/f8/f8.cpp b/src/devices/cpu/f8/f8.cpp index 4d5f420fe62..ba386a1af13 100644 --- a/src/devices/cpu/f8/f8.cpp +++ b/src/devices/cpu/f8/f8.cpp @@ -16,6 +16,7 @@ #include "emu.h" #include "f8.h" +#include "f8dasm.h" #include "debugger.h" #define S 0x01 @@ -1958,7 +1959,7 @@ void f8_cpu_device::device_start() { // TODO register debug state m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_iospace = &space(AS_IO); save_item(NAME(m_pc0)); @@ -2070,10 +2071,9 @@ void f8_cpu_device::state_string_export(const device_state_entry &entry, std::st } -offs_t f8_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *f8_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( f8 ); - return CPU_DISASSEMBLE_NAME(f8)(this, stream, pc, oprom, opram, options); + return new f8_disassembler; } diff --git a/src/devices/cpu/f8/f8.h b/src/devices/cpu/f8/f8.h index 5be9090ec2b..287f7a9fbf3 100644 --- a/src/devices/cpu/f8/f8.h +++ b/src/devices/cpu/f8/f8.h @@ -54,9 +54,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -73,7 +71,7 @@ private: uint16_t m_io; /* last I/O address */ uint16_t m_irq_vector; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_iospace; int m_icount; uint8_t m_r[64]; /* scratchpad RAM */ diff --git a/src/devices/cpu/f8/f8dasm.cpp b/src/devices/cpu/f8/f8dasm.cpp index 4c44aa2c424..49827760cd7 100644 --- a/src/devices/cpu/f8/f8dasm.cpp +++ b/src/devices/cpu/f8/f8dasm.cpp @@ -1,18 +1,22 @@ // license:BSD-3-Clause // copyright-holders:Juergen Buchmueller #include "emu.h" -#include "debugger.h" -#include "f8.h" +#include "f8dasm.h" -static const char *const rname[16] = { +const char *const f8_disassembler::rname[16] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "J", "HU", "HL", "KU", "KL", "QU", "QL" }; -CPU_DISASSEMBLE(f8) +u32 f8_disassembler::opcode_alignment() const { - unsigned size = 0; - uint8_t op = oprom[size++]; + return 1; +} + +offs_t f8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + offs_t base_pc = pc; + uint8_t op = opcodes.r8(pc++); switch( op ) { @@ -116,40 +120,40 @@ CPU_DISASSEMBLE(f8) util::stream_format(stream, "INC"); break; case 0x20: /* 0010 0000 */ - util::stream_format(stream, "LI $%02X", oprom[size++]); + util::stream_format(stream, "LI $%02X", opcodes.r8(pc++)); break; case 0x21: /* 0010 0001 */ - util::stream_format(stream, "NI $%02X", oprom[size++]); + util::stream_format(stream, "NI $%02X", opcodes.r8(pc++)); break; case 0x22: /* 0010 0010 */ - util::stream_format(stream, "OI $%02X", oprom[size++]); + util::stream_format(stream, "OI $%02X", opcodes.r8(pc++)); break; case 0x23: /* 0010 0011 */ - util::stream_format(stream, "XI $%02X", oprom[size++]); + util::stream_format(stream, "XI $%02X", opcodes.r8(pc++)); break; case 0x24: /* 0010 0100 */ - util::stream_format(stream, "AI $%02X", oprom[size++]); + util::stream_format(stream, "AI $%02X", opcodes.r8(pc++)); break; case 0x25: /* 0010 0101 */ - util::stream_format(stream, "CI $%02X", oprom[size++]); + util::stream_format(stream, "CI $%02X", opcodes.r8(pc++)); break; case 0x26: /* 0010 0110 */ - util::stream_format(stream, "IN $%02X", oprom[size++]); + util::stream_format(stream, "IN $%02X", opcodes.r8(pc++)); break; case 0x27: /* 0010 0111 */ - util::stream_format(stream, "OUT $%02X", oprom[size++]); + util::stream_format(stream, "OUT $%02X", opcodes.r8(pc++)); break; case 0x28: /* 0010 1000 */ - util::stream_format(stream, "PI $%02X%02X", oprom[size + 0], oprom[size + 1]); - size += 2; + util::stream_format(stream, "PI $%02X%02X", opcodes.r16(pc)); + pc += 2; break; case 0x29: /* 0010 1001 */ - util::stream_format(stream, "JMP $%02X%02X", oprom[size + 0], oprom[size + 1]); - size += 2; + util::stream_format(stream, "JMP $%02X%02X", opcodes.r16(pc)); + pc += 2; break; case 0x2a: /* 0010 1010 */ - util::stream_format(stream, "DCI $%02X%02X", oprom[size + 0], oprom[size + 1]); - size += 2; + util::stream_format(stream, "DCI $%02X%02X", opcodes.r16(pc)); + pc += 2; break; case 0x2b: /* 0010 1011 */ util::stream_format(stream, "NOP"); @@ -286,22 +290,22 @@ CPU_DISASSEMBLE(f8) case 0x81: /* 1000 0001 */ case 0x85: /* 1000 0101 */ - util::stream_format(stream, "BP $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BP $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x82: /* 1000 0010 */ - util::stream_format(stream, "BC $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BC $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x84: /* 1000 0100 */ - util::stream_format(stream, "BZ $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BZ $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x80: /* 1000 0000 */ case 0x83: /* 1000 0011 */ case 0x86: /* 1000 0110 */ case 0x87: /* 1000 0111 */ - util::stream_format(stream, "BT $%02X,$%04X", op & 0x07, pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BT $%02X,$%04X", op & 0x07, base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x88: /* 1000 1000 */ @@ -333,28 +337,28 @@ CPU_DISASSEMBLE(f8) break; case 0x8f: /* 1000 1111 */ - util::stream_format(stream, "BR7 $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BR7 $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x90: /* 1001 0000 */ - util::stream_format(stream, "BR $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BR $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x91: /* 1001 0001 */ case 0x95: /* 1001 0101 */ - util::stream_format(stream, "BM $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BM $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x92: /* 1001 0010 */ - util::stream_format(stream, "BNC $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BNC $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x94: /* 1001 0100 */ - util::stream_format(stream, "BNZ $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BNZ $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x98: /* 1001 1000 */ - util::stream_format(stream, "BNO $%04X", pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BNO $%04X", base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0x93: /* 1001 0011 */ @@ -367,7 +371,7 @@ CPU_DISASSEMBLE(f8) case 0x9d: /* 1001 1101 */ case 0x9e: /* 1001 1110 */ case 0x9f: /* 1001 1111 */ - util::stream_format(stream, "BF $%02X,$%04X", op & 0x0f, pc + (int8_t)oprom[size++] + 1); + util::stream_format(stream, "BF $%02X,$%04X", op & 0x0f, base_pc + (int8_t)opcodes.r8(pc++) + 1); break; case 0xa0: /* 1010 0000 */ @@ -530,5 +534,5 @@ CPU_DISASSEMBLE(f8) break; } - return size; + return pc - base_pc; } diff --git a/src/devices/cpu/f8/f8dasm.h b/src/devices/cpu/f8/f8dasm.h new file mode 100644 index 00000000000..112cf35dc0f --- /dev/null +++ b/src/devices/cpu/f8/f8dasm.h @@ -0,0 +1,21 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller + +#ifndef MAME_CPU_F8_F8DASM_H +#define MAME_CPU_F8_F8DASM_H + +#pragma once + +class f8_disassembler : public util::disasm_interface +{ +public: + f8_disassembler() = default; + virtual ~f8_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +private: + static const char *const rname[16]; +}; + +#endif diff --git a/src/devices/cpu/g65816/g65816.cpp b/src/devices/cpu/g65816/g65816.cpp index b121fba081a..6514f113b05 100644 --- a/src/devices/cpu/g65816/g65816.cpp +++ b/src/devices/cpu/g65816/g65816.cpp @@ -767,18 +767,19 @@ void g65816_device::execute_set_input(int line, int state) (this->*FTABLE_SET_LINE)(line, state); } -/* Disassemble an instruction */ -#include "g65816ds.h" - +util::disasm_interface *g65816_device::create_disassembler() +{ + return new g65816_disassembler(this); +} -offs_t g65816_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +bool g65816_device::get_m_flag() const { - return g65816_disassemble(stream, (pc & 0x00ffff), (pc & 0xff0000) >> 16, oprom, FLAG_M, FLAG_X); + return FLAG_M; } -CPU_DISASSEMBLE( g65816 ) +bool g65816_device::get_x_flag() const { - return g65816_disassemble(stream, (pc & 0x00ffff), (pc & 0xff0000) >> 16, oprom, 0/*FLAG_M*/, 0/*FLAG_X*/); + return FLAG_X; } void g65816_device::g65816_restore_state() diff --git a/src/devices/cpu/g65816/g65816.h b/src/devices/cpu/g65816/g65816.h index 67f21b780bc..cfacba32927 100644 --- a/src/devices/cpu/g65816/g65816.h +++ b/src/devices/cpu/g65816/g65816.h @@ -5,6 +5,7 @@ #pragma once +#include "g65816ds.h" #include "g65816cm.h" /* ======================================================================== */ @@ -45,7 +46,7 @@ enum #define G65816_INT_NMI G65816_LINE_NMI -class g65816_device : public cpu_device +class g65816_device : public cpu_device, public g65816_disassembler::config { public: // construction/destruction @@ -85,9 +86,9 @@ protected: 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 1; } - 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; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_m_flag() const override; + virtual bool get_x_flag() const override; address_space_config m_program_config; diff --git a/src/devices/cpu/g65816/g65816ds.cpp b/src/devices/cpu/g65816/g65816ds.cpp index aad24ceb545..5fde19e4218 100644 --- a/src/devices/cpu/g65816/g65816ds.cpp +++ b/src/devices/cpu/g65816/g65816ds.cpp @@ -12,102 +12,55 @@ All rights reserved. */ - #include "emu.h" #include "g65816ds.h" -#ifdef SEC -#undef SEC -#endif - -#define ADDRESS_65816(A) ((A)&0xffffff) - - -namespace { - -class g65816_opcode_struct +g65816_disassembler::g65816_disassembler(config *conf) : m_config(conf) { -public: - const char *name() const - { - return s_opnames[unsigned(m_name)]; - } +} - bool is_call() const - { - switch (m_name) - { - case op::JSR: - case op::JSL: - return true; - default: - return false; - } - } +u32 g65816_disassembler::opcode_alignment() const +{ + return 1; +} - bool is_return() const - { - switch (m_name) - { - case op::RTI: - case op::RTL: - case op::RTS: - return true; - default: - return false; - } - } +const char *g65816_disassembler::opcode_struct::name() const +{ + return g65816_disassembler::s_opnames[unsigned(m_name)]; +} - static const g65816_opcode_struct &get(unsigned char ins) +bool g65816_disassembler::opcode_struct::is_call() const +{ + switch (m_name) { - return s_opcodes[ins]; + case op::JSR: + case op::JSL: + return true; + default: + return false; } +} - unsigned char flag; - unsigned char ea; - -protected: - enum class op : unsigned - { - ADC , AND , ASL , BCC , BCS , BEQ , BIT , BMI , BNE , BPL , BRA , - BRK , BRL , BVC , BVS , CLC , CLD , CLI , CLV , CMP , COP , CPX , - CPY , DEA , DEC , DEX , DEY , EOR , INA , INC , INX , INY , JML , - JMP , JSL , JSR , LDA , LDX , LDY , LSR , MVN , MVP , NOP , ORA , - PEA , PEI , PER , PHA , PHB , PHD , PHK , PHP , PHX , PHY , PLA , - PLB , PLD , PLP , PLX , PLY , REP , ROL , ROR , RTI , RTL , RTS , - SBC , SEC , SED , SEI , SEP , STA , STP , STX , STY , STZ , TAX , - TAY , TCS , TCD , TDC , TRB , TSB , TSC , TSX , TXA , TXS , TXY , - TYA , TYX , WAI , WDM , XBA , XCE - }; - - g65816_opcode_struct(op n, unsigned char f, unsigned char e) - : flag(f) - , ea(e) - , m_name(n) +bool g65816_disassembler::opcode_struct::is_return() const +{ + switch (m_name) { + case op::RTI: + case op::RTL: + case op::RTS: + return true; + default: + return false; } +} - op m_name; - - static const char *const s_opnames[]; - static const g65816_opcode_struct s_opcodes[256]; -}; - -enum +g65816_disassembler::opcode_struct::opcode_struct(op n, u8 f, u8 e) : m_name(n), flag(f), ea(e) { - IMP , ACC , RELB, RELW, IMM , A , AI , AL , ALX , AX , AXI , - AY , D , DI , DIY , DLI , DLIY, DX , DXI , DY , S , SIY , - SIG , MVN , MVP , PEA , PEI , PER -}; +} + -enum -{ - I, /* ignore */ - M, /* check m bit */ - X /* check x bit */ -}; -const char *const g65816_opcode_struct::s_opnames[] = +const char *const g65816_disassembler::s_opnames[] = { "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL", "BRA", "BRK", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", "CMP", "COP", "CPX", @@ -120,7 +73,7 @@ const char *const g65816_opcode_struct::s_opnames[] = "TYA", "TYX", "WAI", "WDM", "XBA", "XCE" }; -const g65816_opcode_struct g65816_opcode_struct::s_opcodes[256] = +const g65816_disassembler::opcode_struct g65816_disassembler::s_opcodes[256] = { {op::BRK, I, SIG }, {op::ORA, M, DXI }, {op::COP, I, SIG }, {op::ORA, M, S }, {op::TSB, M, D }, {op::ORA, M, D }, {op::ASL, M, D }, {op::ORA, M, DLI }, @@ -188,83 +141,38 @@ const g65816_opcode_struct g65816_opcode_struct::s_opcodes[256] = {op::JSR, I, AXI }, {op::SBC, M, AX }, {op::INC, M, AX }, {op::SBC, M, ALX } }; -} // anonymous namespace - -static const uint8_t *base_oprom; -static uint32_t base_pc; - -static inline unsigned int read_8(unsigned int address) -{ - address = ADDRESS_65816(address); - return base_oprom[address - base_pc]; -} - -static inline unsigned int read_16(unsigned int address) -{ - unsigned int val = read_8(address); - return val | (read_8(address+1)<<8); -} - -static inline unsigned int read_24(unsigned int address) -{ - unsigned int val = read_8(address); - val |= (read_8(address+1)<<8); - return val | (read_8(address+2)<<16); -} - -static inline char* int_8_str(unsigned int val) +std::string g65816_disassembler::int_8_str(u8 val) { - static char str[20]; - - val &= 0xff; - if(val & 0x80) - sprintf(str, "-$%x", (0-val) & 0x7f); + return util::string_format("-$%x", (0-val) & 0x7f); else - sprintf(str, "$%x", val & 0x7f); - - return str; + return util::string_format("$%x", val & 0x7f); } -static inline char* int_16_str(unsigned int val) +std::string g65816_disassembler::int_16_str(u16 val) { - static char str[20]; - - val &= 0xffff; - if(val & 0x8000) - sprintf(str, "-$%x", (0-val) & 0x7fff); + return util::string_format("-$%x", (0-val) & 0x7fff); else - sprintf(str, "$%x", val & 0x7fff); - - return str; + return util::string_format("$%x", val & 0x7fff); } -unsigned g65816_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, const uint8_t *oprom, int m_flag, int x_flag) +offs_t g65816_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned int instruction; - const g65816_opcode_struct* opcode; int var; int length = 1; - unsigned int address; - unsigned dasm_flags; - - pb <<= 16; - address = pc | pb; - - base_oprom = oprom; - base_pc = address; + offs_t dasm_flags; - instruction = read_8(address); - opcode = &g65816_opcode_struct::get(instruction); + u8 instruction = opcodes.r8(pc & 0xffffff); + const opcode_struct *opcode = &s_opcodes[instruction]; stream << opcode->name(); if (opcode->is_call()) - dasm_flags = DASMFLAG_STEP_OVER; + dasm_flags = STEP_OVER; else if (opcode->is_return()) - dasm_flags = DASMFLAG_STEP_OUT; + dasm_flags = STEP_OUT; else dasm_flags = 0; @@ -276,113 +184,108 @@ unsigned g65816_disassemble(std::ostream &stream, unsigned int pc, unsigned int util::stream_format(stream, "A"); break; case RELB: - var = (int8_t) read_8(address+1); + var = (int8_t) opcodes.r8((pc+1) & 0xffffff); length++; - util::stream_format(stream, " %06x (%s)", pb | ((pc + length + var)&0xffff), int_8_str(var)); + util::stream_format(stream, " %06x (%s)", (pc & 0xff0000) | ((pc + length + var)&0xffff), int_8_str(var)); break; case RELW: case PER : - var = read_16(address+1); + var = opcodes.r16((pc+1) & 0xffffff); length += 2; - util::stream_format(stream, " %06x (%s)", pb | ((pc + length + var)&0xffff), int_16_str(var)); + util::stream_format(stream, " %06x (%s)", (pc & 0xff0000) | ((pc + length + var)&0xffff), int_16_str(var)); break; case IMM : - if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) + if((opcode->flag == M && !m_config->get_m_flag()) || (opcode->flag == X && !m_config->get_x_flag())) { - util::stream_format(stream, " #$%04x", read_16(address+1)); + util::stream_format(stream, " #$%04x", opcodes.r16((pc+1) & 0xffffff)); length += 2; } else { - util::stream_format(stream, " #$%02x", read_8(address+1)); + util::stream_format(stream, " #$%02x", opcodes.r8((pc+1) & 0xffffff)); length++; } break; case A : case PEA : - util::stream_format(stream, " $%04x", read_16(address+1)); + util::stream_format(stream, " $%04x", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case AI : - util::stream_format(stream, " ($%04x)", read_16(address+1)); + util::stream_format(stream, " ($%04x)", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case AL : - util::stream_format(stream, " $%06x", read_24(address+1)); + util::stream_format(stream, " $%06x", opcodes.r32((pc+1) & 0xffffff) & 0xffffff); length += 3; break; case ALX : - util::stream_format(stream, " $%06x,X", read_24(address+1)); + util::stream_format(stream, " $%06x,X", opcodes.r32((pc+1) & 0xffffff) & 0xffffff); length += 3; break; case AX : - util::stream_format(stream, " $%04x,X", read_16(address+1)); + util::stream_format(stream, " $%04x,X", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case AXI : - util::stream_format(stream, " ($%04x,X)", read_16(address+1)); + util::stream_format(stream, " ($%04x,X)", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case AY : - util::stream_format(stream, " $%04x,Y", read_16(address+1)); + util::stream_format(stream, " $%04x,Y", opcodes.r16((pc+1) & 0xffffff)); length += 2; break; case D : - util::stream_format(stream, " $%02x", read_8(address+1)); + util::stream_format(stream, " $%02x", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DI : case PEI : - util::stream_format(stream, " ($%02x)", read_8(address+1)); + util::stream_format(stream, " ($%02x)", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DIY : - util::stream_format(stream, " ($%02x),Y", read_8(address+1)); + util::stream_format(stream, " ($%02x),Y", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DLI : - util::stream_format(stream, " [$%02x]", read_8(address+1)); + util::stream_format(stream, " [$%02x]", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DLIY: - util::stream_format(stream, " [$%02x],Y", read_8(address+1)); + util::stream_format(stream, " [$%02x],Y", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DX : - util::stream_format(stream, " $%02x,X", read_8(address+1)); + util::stream_format(stream, " $%02x,X", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DXI : - util::stream_format(stream, " ($%02x,X)", read_8(address+1)); + util::stream_format(stream, " ($%02x,X)", opcodes.r8((pc+1) & 0xffffff)); length++; break; case DY : - util::stream_format(stream, " $%02x,Y", read_8(address+1)); + util::stream_format(stream, " $%02x,Y", opcodes.r8((pc+1) & 0xffffff)); length++; break; case S : - util::stream_format(stream, " %s,S", int_8_str(read_8(address+1))); + util::stream_format(stream, " %s,S", int_8_str(opcodes.r8((pc+1) & 0xffffff))); length++; break; case SIY : - util::stream_format(stream, " (%s,S),Y", int_8_str(read_8(address+1))); + util::stream_format(stream, " (%s,S),Y", int_8_str(opcodes.r8((pc+1) & 0xffffff))); length++; break; case SIG : - util::stream_format(stream, " #$%02x", read_8(address+1)); + util::stream_format(stream, " #$%02x", opcodes.r8((pc+1) & 0xffffff)); length++; break; case MVN : case MVP : - util::stream_format(stream, " $%02x, $%02x", read_8(address+2), read_8(address+1)); + util::stream_format(stream, " $%02x, $%02x", opcodes.r8((pc+2) & 0xffffff), opcodes.r8((pc+1) & 0xffffff)); length += 2; break; } - return length | DASMFLAG_SUPPORTED | dasm_flags; -} - -CPU_DISASSEMBLE( g65816_generic ) -{ - return g65816_disassemble(stream, (pc & 0x00ffff), (pc & 0xff0000) >> 16, oprom, 0, 0); + return length | SUPPORTED | dasm_flags; } diff --git a/src/devices/cpu/g65816/g65816ds.h b/src/devices/cpu/g65816/g65816ds.h index 892dd065a10..832754de4cd 100644 --- a/src/devices/cpu/g65816/g65816ds.h +++ b/src/devices/cpu/g65816/g65816ds.h @@ -16,7 +16,68 @@ All rights reserved. */ -unsigned g65816_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, const uint8_t *oprom, int m_flag, int x_flag); +class g65816_disassembler : public util::disasm_interface +{ +public: + class config { + public: + virtual ~config() = default; + virtual bool get_m_flag() const = 0; + virtual bool get_x_flag() const = 0; + }; + g65816_disassembler(config *conf); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum class op : unsigned + { + ADC , AND , ASL , BCC , BCS , BEQ , BIT , BMI , BNE , BPL , BRA , + BRK , BRL , BVC , BVS , CLC , CLD , CLI , CLV , CMP , COP , CPX , + CPY , DEA , DEC , DEX , DEY , EOR , INA , INC , INX , INY , JML , + JMP , JSL , JSR , LDA , LDX , LDY , LSR , MVN , MVP , NOP , ORA , + PEA , PEI , PER , PHA , PHB , PHD , PHK , PHP , PHX , PHY , PLA , + PLB , PLD , PLP , PLX , PLY , REP , ROL , ROR , RTI , RTL , RTS , + SBC , SEC , SED , SEI , SEP , STA , STP , STX , STY , STZ , TAX , + TAY , TCS , TCD , TDC , TRB , TSB , TSC , TSX , TXA , TXS , TXY , + TYA , TYX , WAI , WDM , XBA , XCE + }; + + enum + { + IMP , ACC , RELB, RELW, IMM , A , AI , AL , ALX , AX , AXI , + AY , D , DI , DIY , DLI , DLIY, DX , DXI , DY , S , SIY , + SIG , MVN , MVP , PEA , PEI , PER + }; + + enum + { + I, /* ignore */ + M, /* check m bit */ + X /* check x bit */ + }; + + class opcode_struct { + public: + op m_name; + u8 flag; + u8 ea; + + opcode_struct(op n, u8 f, u8 e); + const char *name() const; + bool is_call() const; + bool is_return() const; + }; + + static const char *const s_opnames[]; + static const opcode_struct s_opcodes[256]; + + config *m_config; + + std::string int_8_str(u8 val); + std::string int_16_str(u16 val); +}; #endif /* __G65816DS_H__ */ diff --git a/src/devices/cpu/h6280/6280dasm.cpp b/src/devices/cpu/h6280/6280dasm.cpp index c214a058c52..35b1b60c165 100644 --- a/src/devices/cpu/h6280/6280dasm.cpp +++ b/src/devices/cpu/h6280/6280dasm.cpp @@ -18,69 +18,10 @@ ******************************************************************************/ -#ifdef __OS2__ -/* To avoid name clash of _brk */ -#define __STRICT_ANSI__ -#endif - #include "emu.h" +#include "6280dasm.h" -#define RDOP(addr) (oprom[addr - pc]) -#define RDBYTE(addr) (opram[addr - pc]) -#define RDWORD(addr) (opram[addr - pc] | ( oprom[(addr) + 1 - pc] << 8 )) - -enum addr_mode { - _non=0, /* no additional arguments */ - _acc, /* accumulator */ - _imp, /* implicit */ - _imm, /* immediate */ - _abs, /* absolute */ - _zpg, /* zero page */ - _zpx, /* zero page + X */ - _zpy, /* zero page + Y */ - _zpi, /* zero page indirect */ - _abx, /* absolute + X */ - _aby, /* absolute + Y */ - _rel, /* relative */ - _idx, /* zero page pre indexed */ - _idy, /* zero page post indexed */ - _ind, /* indirect */ - _iax, /* indirect + X */ - _blk, /* block */ - _zrl, /* zero page relative */ - _imz, /* immediate, zero page */ - _izx, /* immediate, zero page + X */ - _ima, /* immediate, absolute */ - _imx /* immediate, absolute + X */ -}; - -enum opcodes { - /* 6502 opcodes */ - _adc=0,_and, _asl, _bcc, _bcs, _beq, _bit, _bmi, - _bne, _bpl, _brk, _bvc, _bvs, _clc, _cld, _cli, - _clv, _cmp, _cpx, _cpy, _dec, _dex, _dey, _eor, - _inc, _inx, _iny, _jmp, _jsr, _lda, _ldx, _ldy, - _lsr, _nop, _ora, _pha, _php, _pla, _plp, _rol, - _ror, _rti, _rts, _sbc, _sec, _sed, _sei, _sta, - _stx, _sty, _tax, _tay, _tsx, _txa, _txs, _tya, - _ill, - - /* Hu6280 extensions */ - _bra, _stz, _trb, _tsb, _dea, _ina, _sax, _bsr, - _phx, _phy, _plx, _ply, _csh, _csl, _tam, _tma, - _cla, _cly, _clx, _st0, _st1, _st2, _tst, _set, - _tdd, _tia, _tii, _tin, _tai, _say, _sxy, - - _sm0, _sm1, _sm2, _sm3, _sm4, _sm5, _sm6, _sm7, - _rm0, _rm1, _rm2, _rm3, _rm4, _rm5, _rm6, _rm7, - - _bs0, _bs1, _bs2, _bs3, _bs4, _bs5, _bs6, _bs7, - _br0, _br1, _br2, _br3, _br4, _br5, _br6, _br7 - -}; - - -static const char *const token[]= +const char *const h6280_disassembler::token[]= { /* 6502 opcodes */ "adc", "and", "asl", "bcc", "bcs", "beq", "bit", "bmi", @@ -105,7 +46,7 @@ static const char *const token[]= "bbr0", "bbr1", "bbr2", "bbr3", "bbr4", "bbr5", "bbr6", "bbr7" }; -static const unsigned char op6280[512]= +const unsigned char h6280_disassembler::op6280[512]= { _brk,_imp, _ora,_idx, _sxy,_imp, _st0,_imm, _tsb,_zpg, _ora,_zpg, _asl,_zpg, _rm0,_zpg, /* 00 */ _php,_imp, _ora,_imm, _asl,_acc, _ill,_non, _tsb,_abs, _ora,_abs, _asl,_abs, _br0,_zrl, @@ -141,16 +82,22 @@ static const unsigned char op6280[512]= _sed,_imp, _sbc,_aby, _plx,_imp, _ill,_non, _ill,_non, _sbc,_abx, _inc,_abx, _bs7,_zrl }; +u32 h6280_disassembler::opcode_alignment() const +{ + return 1; +} + /***************************************************************************** * Disassemble a single command and return the number of bytes it uses. *****************************************************************************/ -CPU_DISASSEMBLE(h6280) +offs_t h6280_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; - int PC, OP, opc, arg; + offs_t PC; + int OP, opc, arg; PC = pc; - OP = RDOP(PC); + OP = opcodes.r8(PC); OP = OP << 1; PC++; @@ -158,9 +105,9 @@ CPU_DISASSEMBLE(h6280) arg = op6280[OP+1]; if (opc == _jsr || opc == _bsr) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (opc == _rts) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; switch(arg) { @@ -171,84 +118,84 @@ CPU_DISASSEMBLE(h6280) util::stream_format(stream, "%s", token[opc]); break; case _rel: - util::stream_format(stream, "%-5s$%04X", token[opc], (PC + 1 + (signed char)RDBYTE(PC)) & 0xffff); + util::stream_format(stream, "%-5s$%04X", token[opc], (PC + 1 + (signed char)params.r8(PC)) & 0xffff); PC+=1; break; case _imm: - util::stream_format(stream, "%-5s#$%02X", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s#$%02X", token[opc], params.r8(PC)); PC+=1; break; case _zpg: - util::stream_format(stream, "%-5s$%02X", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s$%02X", token[opc], params.r8(PC)); PC+=1; break; case _zpx: - util::stream_format(stream, "%-5s$%02X,x", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s$%02X,x", token[opc], params.r8(PC)); PC+=1; break; case _zpy: - util::stream_format(stream, "%-5s$%02X,y", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s$%02X,y", token[opc], params.r8(PC)); PC+=1; break; case _idx: - util::stream_format(stream, "%-5s($%02X,x)", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s($%02X,x)", token[opc], params.r8(PC)); PC+=1; break; case _idy: - util::stream_format(stream, "%-5s($%02X),y", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s($%02X),y", token[opc], params.r8(PC)); PC+=1; break; case _zpi: - util::stream_format(stream, "%-5s($%02X)", token[opc], RDBYTE(PC)); + util::stream_format(stream, "%-5s($%02X)", token[opc], params.r8(PC)); PC+=1; break; case _abs: - util::stream_format(stream, "%-5s$%04X", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s$%04X", token[opc], params.r16(PC)); PC+=2; break; case _abx: - util::stream_format(stream, "%-5s$%04X,x", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s$%04X,x", token[opc], params.r16(PC)); PC+=2; break; case _aby: - util::stream_format(stream, "%-5s$%04X,y", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s$%04X,y", token[opc], params.r16(PC)); PC+=2; break; case _ind: - util::stream_format(stream, "%-5s($%04X)", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s($%04X)", token[opc], params.r16(PC)); PC+=2; break; case _iax: - util::stream_format(stream, "%-5s($%04X),X", token[opc], RDWORD(PC)); + util::stream_format(stream, "%-5s($%04X),X", token[opc], params.r16(PC)); PC+=2; break; case _blk: - util::stream_format(stream, "%-5s$%04X $%04X $%04X", token[opc], RDWORD(PC), RDWORD(PC+2), RDWORD(PC+4)); + util::stream_format(stream, "%-5s$%04X $%04X $%04X", token[opc], params.r16(PC), params.r16(PC+2), params.r16(PC+4)); PC+=6; break; case _zrl: - util::stream_format(stream, "%-5s$%02X $%04X", token[opc], RDBYTE(PC), (PC + 2 + (signed char)RDBYTE(PC+1)) & 0xffff); + util::stream_format(stream, "%-5s$%02X $%04X", token[opc], params.r8(PC), (PC + 2 + (signed char)params.r8(PC+1)) & 0xffff); PC+=2; break; case _imz: - util::stream_format(stream, "%-5s#$%02X $%02X", token[opc], RDBYTE(PC), RDBYTE(PC+1)); + util::stream_format(stream, "%-5s#$%02X $%02X", token[opc], params.r8(PC), params.r8(PC+1)); PC+=2; break; case _izx: - util::stream_format(stream, "%-5s#$%02X $%02X,x", token[opc], RDBYTE(PC), RDBYTE(PC+1)); + util::stream_format(stream, "%-5s#$%02X $%02X,x", token[opc], params.r8(PC), params.r8(PC+1)); PC+=2; break; case _ima: - util::stream_format(stream, "%-5s#$%02X $%04X", token[opc], RDBYTE(PC), RDWORD(PC+1)); + util::stream_format(stream, "%-5s#$%02X $%04X", token[opc], params.r8(PC), params.r16(PC+1)); PC+=3; break; case _imx: - util::stream_format(stream, "%-5s#$%02X $%04X,x", token[opc], RDBYTE(PC), RDWORD(PC+1)); + util::stream_format(stream, "%-5s#$%02X $%04X,x", token[opc], params.r8(PC), params.r16(PC+1)); PC+=3; break; default: util::stream_format(stream, "%-5s$%02X", token[opc], OP >> 1); } - return (PC - pc) | flags | DASMFLAG_SUPPORTED; + return (PC - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/h6280/6280dasm.h b/src/devices/cpu/h6280/6280dasm.h new file mode 100644 index 00000000000..5186720dfa8 --- /dev/null +++ b/src/devices/cpu/h6280/6280dasm.h @@ -0,0 +1,90 @@ +// license:BSD-3-Clause +// copyright-holders:Bryan McPhail +/***************************************************************************** + + 6280dasm.c Hudsonsoft Hu6280 (HuC6280/Hu6280a) disassembler + + Copyright Bryan McPhail, mish@tendril.co.uk + + This source code is based (with permission!) on the 6502 emulator by + Juergen Buchmueller. It is released as part of the Mame emulator project. + Let me know if you intend to use this code in any other project. + + + Notes relating to Mame: + + The dasm window shows 'real' memory, as executed by the cpu + The data windows show 'physical' memory, as defined in the memory map + +******************************************************************************/ + +#ifndef MAME_CPU_H6280_6280DASM_H +#define MAME_CPU_H6280_6280DASM_H + +#pragma once + +class h6280_disassembler : public util::disasm_interface +{ +public: + h6280_disassembler() = default; + virtual ~h6280_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum addr_mode { + _non=0, /* no additional arguments */ + _acc, /* accumulator */ + _imp, /* implicit */ + _imm, /* immediate */ + _abs, /* absolute */ + _zpg, /* zero page */ + _zpx, /* zero page + X */ + _zpy, /* zero page + Y */ + _zpi, /* zero page indirect */ + _abx, /* absolute + X */ + _aby, /* absolute + Y */ + _rel, /* relative */ + _idx, /* zero page pre indexed */ + _idy, /* zero page post indexed */ + _ind, /* indirect */ + _iax, /* indirect + X */ + _blk, /* block */ + _zrl, /* zero page relative */ + _imz, /* immediate, zero page */ + _izx, /* immediate, zero page + X */ + _ima, /* immediate, absolute */ + _imx /* immediate, absolute + X */ + }; + + enum opcodes { + /* 6502 opcodes */ + _adc=0,_and, _asl, _bcc, _bcs, _beq, _bit, _bmi, + _bne, _bpl, _brk, _bvc, _bvs, _clc, _cld, _cli, + _clv, _cmp, _cpx, _cpy, _dec, _dex, _dey, _eor, + _inc, _inx, _iny, _jmp, _jsr, _lda, _ldx, _ldy, + _lsr, _nop, _ora, _pha, _php, _pla, _plp, _rol, + _ror, _rti, _rts, _sbc, _sec, _sed, _sei, _sta, + _stx, _sty, _tax, _tay, _tsx, _txa, _txs, _tya, + _ill, + + /* Hu6280 extensions */ + _bra, _stz, _trb, _tsb, _dea, _ina, _sax, _bsr, + _phx, _phy, _plx, _ply, _csh, _csl, _tam, _tma, + _cla, _cly, _clx, _st0, _st1, _st2, _tst, _set, + _tdd, _tia, _tii, _tin, _tai, _say, _sxy, + + _sm0, _sm1, _sm2, _sm3, _sm4, _sm5, _sm6, _sm7, + _rm0, _rm1, _rm2, _rm3, _rm4, _rm5, _rm6, _rm7, + + _bs0, _bs1, _bs2, _bs3, _bs4, _bs5, _bs6, _bs7, + _br0, _br1, _br2, _br3, _br4, _br5, _br6, _br7 + }; + + static const char *const token[]; + static const unsigned char op6280[512]; + +}; + +#endif diff --git a/src/devices/cpu/h6280/h6280.cpp b/src/devices/cpu/h6280/h6280.cpp index 4c5091b502e..c47ed31a70f 100644 --- a/src/devices/cpu/h6280/h6280.cpp +++ b/src/devices/cpu/h6280/h6280.cpp @@ -112,6 +112,7 @@ #include "emu.h" #include "h6280.h" +#include "6280dasm.h" #include "debugger.h" /* 6280 flags */ @@ -300,7 +301,7 @@ void h6280_device::device_reset() m_io_buffer = 0; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); /* set I and B flags */ @@ -2220,36 +2221,13 @@ void h6280_device::state_string_export(const device_state_entry &entry, std::str //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t h6280_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t h6280_device::disasm_max_opcode_bytes() const -{ - return 7; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t h6280_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *h6280_device::create_disassembler() { - extern CPU_DISASSEMBLE( h6280 ); - return CPU_DISASSEMBLE_NAME(h6280)(this, stream, pc, oprom, opram, options); + return new h6280_disassembler; } diff --git a/src/devices/cpu/h6280/h6280.h b/src/devices/cpu/h6280/h6280.h index dc6a3ddb47f..e744247e8cb 100644 --- a/src/devices/cpu/h6280/h6280.h +++ b/src/devices/cpu/h6280/h6280.h @@ -89,9 +89,7 @@ protected: virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -359,7 +357,7 @@ protected: // address spaces address_space *m_program; address_space *m_io; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; typedef void (h6280_device::*ophandler)(); diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp index 516c2253496..e54155b120d 100644 --- a/src/devices/cpu/h8/h8.cpp +++ b/src/devices/cpu/h8/h8.cpp @@ -14,6 +14,7 @@ #include "h8.h" #include "h8_dma.h" #include "h8_dtc.h" +#include "h8d.h" h8_device::h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool mode_a16, address_map_delegate map_delegate) : cpu_device(mconfig, type, tag, owner, clock), @@ -31,7 +32,7 @@ h8_device::h8_device(const machine_config &mconfig, device_type type, const char void h8_device::device_start() { program = &space(AS_PROGRAM); - direct = &program->direct(); + direct = program->direct<0>(); io = &space(AS_IO); state_add(STATE_GENPC, "GENPC", NPC).noshow(); @@ -324,256 +325,6 @@ void h8_device::state_string_export(const device_state_entry &entry, std::string } } - -uint32_t h8_device::disasm_min_opcode_bytes() const -{ - return 2; -} - -uint32_t h8_device::disasm_max_opcode_bytes() const -{ - return 10; -} - -void h8_device::disassemble_am(std::ostream &stream, int am, offs_t pc, const uint8_t *oprom, uint32_t opcode, int slot, int offset) -{ - static const char *const r8_names[16] = { - "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h", - "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l" - }; - - static const char *const r16_names[16] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", - }; - - static const char *const r32_names[8] = { - "er0", "er1", "er2", "er3", "er4", "er5", "er6", "sp", - }; - - switch(am) { - case DASM_r8l: - util::stream_format(stream, "%s", r8_names[opcode & 15]); - break; - - case DASM_r8h: - util::stream_format(stream, "%s", r8_names[(opcode >> 4) & 15]); - break; - - case DASM_r8u: - util::stream_format(stream, "%s", r8_names[(opcode >> 8) & 15]); - break; - - case DASM_r16l: - util::stream_format(stream, "%s", r16_names[opcode & 15]); - break; - - case DASM_r16h: - util::stream_format(stream, "%s", r16_names[(opcode >> 4) & 15]); - break; - - case DASM_r32l: - util::stream_format(stream, "%s", r32_names[opcode & 7]); - break; - - case DASM_r32h: - util::stream_format(stream, "%s", r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r16ih: - util::stream_format(stream, "@%s", r16_names[(opcode >> 4) & 7]); - break; - - case DASM_r16ihh: - util::stream_format(stream, "@%s", r16_names[(opcode >> 20) & 7]); - break; - - case DASM_pr16h: - util::stream_format(stream, "@-%s", r16_names[(opcode >> 4) & 7]); - break; - - case DASM_r16ph: - util::stream_format(stream, "@%s+", r16_names[(opcode >> 4) & 7]); - break; - - case DASM_r16d16h: - util::stream_format(stream, "@(%x, %s)", (oprom[offset-2] << 8) | oprom[offset-1], r16_names[(opcode >> 4) & 7]); - break; - - case DASM_r32ih: - util::stream_format(stream, "@%s", r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r32ihh: - util::stream_format(stream, "@%s", r32_names[(opcode >> 20) & 7]); - break; - - case DASM_pr32h: - util::stream_format(stream, "@-%s", r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r32pl: - util::stream_format(stream, "@%s+", r32_names[opcode & 7]); - break; - - case DASM_r32ph: - util::stream_format(stream, "@%s+", r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r32d16h: - util::stream_format(stream, "@(%x, %s)", (oprom[offset-2] << 8) | oprom[offset-1], r32_names[(opcode >> 4) & 7]); - break; - - case DASM_r32d32hh: - util::stream_format(stream, "@(%x, %s)", (oprom[offset-4] << 24) | (oprom[offset-3] << 16) | (oprom[offset-2] << 8) | oprom[offset-1], r32_names[(opcode >> 20) & 7]); - break; - - case DASM_psp: - util::stream_format(stream, "@-sp"); - break; - - case DASM_spp: - util::stream_format(stream, "@sp+"); - break; - - case DASM_r32n2l: - util::stream_format(stream, "%s-%s", r32_names[opcode & 6], r32_names[(opcode & 6) + 1]); - break; - - case DASM_r32n3l: - util::stream_format(stream, "%s-%s", r32_names[opcode & 4], r32_names[(opcode & 4) + 2]); - break; - - case DASM_r32n4l: - util::stream_format(stream, "%s-%s", r32_names[opcode & 4], r32_names[(opcode & 4) + 3]); - break; - - case DASM_abs8: - util::stream_format(stream, "@%08x", 0xffffff00 | oprom[1]); - break; - - case DASM_abs16: - if(offset >= 6) - util::stream_format(stream, "@%08x", int16_t((oprom[offset-4] << 8) | oprom[offset-3])); - else - util::stream_format(stream, "@%08x", int16_t((oprom[offset-2] << 8) | oprom[offset-1])); - break; - - case DASM_abs32: - if(slot == 3) - util::stream_format(stream, "@%08x", (oprom[offset-6] << 24) | (oprom[offset-5] << 16) | (oprom[offset-4] << 8) | oprom[offset-3]); - else - util::stream_format(stream, "@%08x", (oprom[offset-4] << 24) | (oprom[offset-3] << 16) | (oprom[offset-2] << 8) | oprom[offset-1]); - break; - - case DASM_abs8i: - util::stream_format(stream, "@%02x", oprom[1]); - break; - - case DASM_abs16e: - util::stream_format(stream, "%04x", (oprom[2] << 8) | oprom[3]); - break; - - case DASM_abs24e: - util::stream_format(stream, "%08x", (oprom[1] << 16) | (oprom[2] << 8) | oprom[3]); - break; - - case DASM_rel8: - util::stream_format(stream, "%08x", pc + 2 + int8_t(oprom[1])); - break; - - case DASM_rel16: - util::stream_format(stream, "%08x", pc + 4 + int16_t((oprom[2] << 8) | oprom[3])); - break; - - case DASM_one: - util::stream_format(stream, "#1"); - break; - - case DASM_two: - util::stream_format(stream, "#2"); - break; - - case DASM_four: - util::stream_format(stream, "#4"); - break; - - case DASM_imm2: - util::stream_format(stream, "#%x", (opcode >> 4) & 3); - break; - - case DASM_imm3: - util::stream_format(stream, "#%x", (opcode >> 4) & 7); - break; - - case DASM_imm8: - util::stream_format(stream, "#%02x", oprom[1]); - break; - - case DASM_imm16: - util::stream_format(stream, "#%04x", (oprom[2] << 8) | oprom[3]); - break; - - case DASM_imm32: - util::stream_format(stream, "#%08x", (oprom[2] << 16) | (oprom[3] << 16) | (oprom[4] << 8) | oprom[5]); - break; - - case DASM_ccr: - util::stream_format(stream, "ccr"); - break; - - case DASM_exr: - util::stream_format(stream, "exr"); - break; - - case DASM_macl: - util::stream_format(stream, "macl"); - break; - - case DASM_mach: - util::stream_format(stream, "mach"); - break; - - default: - util::stream_format(stream, "<%d>", am); - break; - } -} - -offs_t h8_device::disassemble_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *table) -{ - uint32_t slot[5]; - slot[0] = (oprom[0] << 8) | oprom[1]; - slot[1] = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[2] << 8) | oprom[3]; - slot[2] = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[4] << 8) | oprom[5]; - slot[3] = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[6] << 8) | oprom[7]; - slot[4] = (oprom[2] << 24) | (oprom[3] << 16) | (oprom[4] << 8) | oprom[5]; - - int inst; - for(inst=0;; inst++) { - const disasm_entry &e = table[inst]; - if((slot[e.slot] & e.mask) == e.val && (slot[0] & e.mask0) == e.val0) - break; - } - const disasm_entry &e = table[inst]; - stream << e.opcode; - - if(e.am1 != DASM_none) { - stream << ' '; - disassemble_am(stream, e.am1, pc, oprom, slot[e.slot], e.slot, e.flags & DASMFLAG_LENGTHMASK); - } - if(e.am2 != DASM_none) { - stream << ", "; - disassemble_am(stream, e.am2, pc, oprom, slot[e.slot], e.slot, e.flags & DASMFLAG_LENGTHMASK); - } - return e.flags | DASMFLAG_SUPPORTED; -} - -offs_t h8_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); -} - uint16_t h8_device::read16i(uint32_t adr) { icount--; @@ -1592,4 +1343,9 @@ void h8_device::set_nz32(uint32_t v) CCR |= F_N; } +util::disasm_interface *h8_device::create_disassembler() +{ + return new h8_disassembler; +} + #include "cpu/h8/h8.hxx" diff --git a/src/devices/cpu/h8/h8.h b/src/devices/cpu/h8/h8.h index 3df33f8de1b..78ce598bb84 100644 --- a/src/devices/cpu/h8/h8.h +++ b/src/devices/cpu/h8/h8.h @@ -72,15 +72,6 @@ public: bool access_is_dma() const { return inst_state == STATE_DMA || inst_state == STATE_DTC; } protected: - struct disasm_entry { - int slot; - uint32_t val, mask; - uint16_t val0, mask0; - const char *opcode; - int am1, am2; - offs_t flags; - }; - enum { F_I = 0x80, F_UI = 0x40, @@ -96,64 +87,6 @@ protected: EXR_I = 0x07 }; - enum { - DASM_none, /* no additional arguments */ - - DASM_r8l, /* 8-bits register in bits 0-3 */ - DASM_r8h, /* 8-bits register in bits 4-7 */ - DASM_r8u, /* 8-bits register in bits 8-15 */ - DASM_r16l, /* 16-bits register in bits 0-3 */ - DASM_r16h, /* 16-bits register in bits 4-7 */ - DASM_r32l, /* 32-bits register in bits 0-3 */ - DASM_r32h, /* 32-bits register in bits 4-7 */ - - DASM_r16ih, /* indexed through 16-bits register in bits 4-6 */ - DASM_r16ihh, /* indexed through 16-bits register in bits 4-6 in 4-bytes instruction */ - DASM_pr16h, /* indexed through predecremented 16-bits register in bits 4-6 */ - DASM_r16ph, /* indexed through postincremented 16-bits register in bits 4-6 */ - DASM_r16d16h, /* indexed through 16-bits register in bits 4-6 with 16-bits displacement at end of instruction */ - - DASM_r32ih, /* indexed through 32-bits register in bits 4-6 */ - DASM_r32ihh, /* indexed through 32-bits register in bits 4-6 in 4-bytes instruction */ - DASM_pr32h, /* indexed through predecremented 32-bits register in bits 4-6 */ - DASM_r32pl, /* indexed through postincremented 32-bits register in bits 0-2 */ - DASM_r32ph, /* indexed through postincremented 32-bits register in bits 4-6 */ - DASM_r32d16h, /* indexed through 32-bits register in bits 4-6 with 16-bits displacement at end of instruction */ - DASM_r32d32hh, /* indexed through 32-bits register in bits 20-22 with 32-bits displacement at end of instruction */ - - DASM_psp, /* indexed through predecremented stack pointer */ - DASM_spp, /* indexed through postincremented stack pointer */ - - DASM_r32n2l, /* Block of 2 registers */ - DASM_r32n3l, /* Block of 3 registers */ - DASM_r32n4l, /* Block of 4 registers */ - - DASM_abs8, /* 8-bit address present at +1 */ - DASM_abs16, /* 16-bit address present at end of instruction */ - DASM_abs32, /* 32-bit address present at end of instruction */ - DASM_abs8i, /* 8-bit indirect jump address present at +1 */ - DASM_abs16e, /* 16-bit jump address present at +2 */ - DASM_abs24e, /* 24-bit jump address present at +1 */ - - DASM_rel8, /* 8-bit pc-relative jump address at +1, offset=2 */ - DASM_rel16, /* 16-bit pc-relative jump address at +2, offset=4 */ - - DASM_one, /* immediate value 1 */ - DASM_two, /* immediate value 2 */ - DASM_four, /* immediate value 4 */ - - DASM_imm2, /* 2-bit immediate in bits 4-5 (trapa) */ - DASM_imm3, /* 3-bit immediate in bits 4-6 (bit selection */ - DASM_imm8, /* 8-bit immediate at +1 */ - DASM_imm16, /* 16-bit immediate at +2 */ - DASM_imm32, /* 32-bit immediate at +2 */ - - DASM_ccr, /* internal register ccr */ - DASM_exr, /* internal register exr */ - DASM_macl, /* internal register macl */ - DASM_mach /* internal register mach */ - }; - h8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool mode_a16, address_map_delegate map_delegate); // device-level overrides @@ -175,13 +108,11 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config program_config, io_config; address_space *program, *io; - direct_read_data *direct; + direct_read_data<0> *direct; h8_dma_device *dma_device; h8_dtc_device *dtc_device; h8_dma_state *current_dma; @@ -208,11 +139,6 @@ protected: int irq_level, taken_irq_level; bool irq_required, irq_nmi; - static const disasm_entry disasm_entries[]; - - offs_t disassemble_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *table); - void disassemble_am(std::ostream &stream, int am, offs_t pc, const uint8_t *oprom, uint32_t opcode, int slot, int offset); - virtual void do_exec_full(); virtual void do_exec_partial(); static void add_event(uint64_t &event_time, uint64_t new_event); diff --git a/src/devices/cpu/h8/h8_adc.cpp b/src/devices/cpu/h8/h8_adc.cpp index 979b13fe631..76b03584e6d 100644 --- a/src/devices/cpu/h8/h8_adc.cpp +++ b/src/devices/cpu/h8/h8_adc.cpp @@ -168,7 +168,7 @@ void h8_adc_device::conversion_wait(bool first, bool poweron, uint64_t current_t void h8_adc_device::buffer_value(int port, int buffer) { - buf[buffer] = io->read_word(2*(h8_device::ADC_0 + port)); + buf[buffer] = io->read_word(h8_device::ADC_0 + port); if(V>=1) logerror("adc buffer %d -> %d:%03x\n", port, buffer, buf[buffer]); } diff --git a/src/devices/cpu/h8/h8_port.cpp b/src/devices/cpu/h8/h8_port.cpp index ae63eedad51..bc21c99d6df 100644 --- a/src/devices/cpu/h8/h8_port.cpp +++ b/src/devices/cpu/h8/h8_port.cpp @@ -13,7 +13,7 @@ h8_port_device::h8_port_device(const machine_config &mconfig, const char *tag, d void h8_port_device::set_info(int _address, uint8_t _default_ddr, uint8_t _mask) { - address = 2*_address; + address = _address; default_ddr = _default_ddr; mask = _mask; } diff --git a/src/devices/cpu/h8/h8d.cpp b/src/devices/cpu/h8/h8d.cpp new file mode 100644 index 00000000000..b157aedd3c7 --- /dev/null +++ b/src/devices/cpu/h8/h8d.cpp @@ -0,0 +1,262 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8-300 base cpu emulation, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "h8d.h" +#include "cpu/h8/h8d.hxx" + +h8_disassembler::h8_disassembler(const disasm_entry *_table) : table(_table) +{ +} + +h8_disassembler::h8_disassembler() : h8_disassembler(disasm_entries) +{ +} + +u32 h8_disassembler::opcode_alignment() const +{ + return 2; +} + +void h8_disassembler::disassemble_am(std::ostream &stream, int am, offs_t pc, const data_buffer &opcodes, u32 opcode, int slot, int offset) +{ + static const char *const r8_names[16] = { + "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h", + "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l" + }; + + static const char *const r16_names[16] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", + }; + + static const char *const r32_names[8] = { + "er0", "er1", "er2", "er3", "er4", "er5", "er6", "sp", + }; + + offs_t epc = pc + offset; + + switch(am) { + case DASM_r8l: + util::stream_format(stream, "%s", r8_names[opcode & 15]); + break; + + case DASM_r8h: + util::stream_format(stream, "%s", r8_names[(opcode >> 4) & 15]); + break; + + case DASM_r8u: + util::stream_format(stream, "%s", r8_names[(opcode >> 8) & 15]); + break; + + case DASM_r16l: + util::stream_format(stream, "%s", r16_names[opcode & 15]); + break; + + case DASM_r16h: + util::stream_format(stream, "%s", r16_names[(opcode >> 4) & 15]); + break; + + case DASM_r32l: + util::stream_format(stream, "%s", r32_names[opcode & 7]); + break; + + case DASM_r32h: + util::stream_format(stream, "%s", r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r16ih: + util::stream_format(stream, "@%s", r16_names[(opcode >> 4) & 7]); + break; + + case DASM_r16ihh: + util::stream_format(stream, "@%s", r16_names[(opcode >> 20) & 7]); + break; + + case DASM_pr16h: + util::stream_format(stream, "@-%s", r16_names[(opcode >> 4) & 7]); + break; + + case DASM_r16ph: + util::stream_format(stream, "@%s+", r16_names[(opcode >> 4) & 7]); + break; + + case DASM_r16d16h: + util::stream_format(stream, "@(%x, %s)", opcodes.r16(epc-2), r16_names[(opcode >> 4) & 7]); + break; + + case DASM_r32ih: + util::stream_format(stream, "@%s", r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r32ihh: + util::stream_format(stream, "@%s", r32_names[(opcode >> 20) & 7]); + break; + + case DASM_pr32h: + util::stream_format(stream, "@-%s", r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r32pl: + util::stream_format(stream, "@%s+", r32_names[opcode & 7]); + break; + + case DASM_r32ph: + util::stream_format(stream, "@%s+", r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r32d16h: + util::stream_format(stream, "@(%x, %s)", opcodes.r16(epc-2), r32_names[(opcode >> 4) & 7]); + break; + + case DASM_r32d32hh: + util::stream_format(stream, "@(%x, %s)", opcodes.r32(epc-4), r32_names[(opcode >> 20) & 7]); + break; + + case DASM_psp: + util::stream_format(stream, "@-sp"); + break; + + case DASM_spp: + util::stream_format(stream, "@sp+"); + break; + + case DASM_r32n2l: + util::stream_format(stream, "%s-%s", r32_names[opcode & 6], r32_names[(opcode & 6) + 1]); + break; + + case DASM_r32n3l: + util::stream_format(stream, "%s-%s", r32_names[opcode & 4], r32_names[(opcode & 4) + 2]); + break; + + case DASM_r32n4l: + util::stream_format(stream, "%s-%s", r32_names[opcode & 4], r32_names[(opcode & 4) + 3]); + break; + + case DASM_abs8: + util::stream_format(stream, "@%08x", 0xffffff00 | opcodes.r8(pc+1)); + break; + + case DASM_abs16: + if(offset >= 6) + util::stream_format(stream, "@%08x", s16(opcodes.r16(epc-4))); + else + util::stream_format(stream, "@%08x", s16(opcodes.r16(epc-2))); + break; + + case DASM_abs32: + if(slot == 3) + util::stream_format(stream, "@%08x", opcodes.r32(epc-6)); + else + util::stream_format(stream, "@%08x", opcodes.r32(epc-4)); + break; + + case DASM_abs8i: + util::stream_format(stream, "@%02x", opcodes.r8(pc+1)); + break; + + case DASM_abs16e: + util::stream_format(stream, "%04x", opcodes.r16(pc+2)); + break; + + case DASM_abs24e: + util::stream_format(stream, "%08x", opcodes.r32(pc) & 0xffffff); + break; + + case DASM_rel8: + util::stream_format(stream, "%08x", pc + 2 + s8(opcodes.r8(pc+1))); + break; + + case DASM_rel16: + util::stream_format(stream, "%08x", pc + 4 + s16(opcodes.r16(pc+2))); + break; + + case DASM_one: + util::stream_format(stream, "#1"); + break; + + case DASM_two: + util::stream_format(stream, "#2"); + break; + + case DASM_four: + util::stream_format(stream, "#4"); + break; + + case DASM_imm2: + util::stream_format(stream, "#%x", (opcode >> 4) & 3); + break; + + case DASM_imm3: + util::stream_format(stream, "#%x", (opcode >> 4) & 7); + break; + + case DASM_imm8: + util::stream_format(stream, "#%02x", opcodes.r8(pc+1)); + break; + + case DASM_imm16: + util::stream_format(stream, "#%04x", opcodes.r16(pc+2)); + break; + + case DASM_imm32: + util::stream_format(stream, "#%08x", opcodes.r32(pc+2)); + break; + + case DASM_ccr: + util::stream_format(stream, "ccr"); + break; + + case DASM_exr: + util::stream_format(stream, "exr"); + break; + + case DASM_macl: + util::stream_format(stream, "macl"); + break; + + case DASM_mach: + util::stream_format(stream, "mach"); + break; + + default: + util::stream_format(stream, "<%d>", am); + break; + } +} + +offs_t h8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + u32 slot[5]; + slot[0] = opcodes.r16(pc); + slot[1] = opcodes.r32(pc); + slot[2] = (opcodes.r16(pc) << 16) | opcodes.r16(pc+4); + slot[3] = (opcodes.r16(pc) << 16) | opcodes.r16(pc+6); + slot[4] = opcodes.r32(pc+2); + + int inst; + for(inst=0;; inst++) { + const disasm_entry &e = table[inst]; + if((slot[e.slot] & e.mask) == e.val && (slot[0] & e.mask0) == e.val0) + break; + } + const disasm_entry &e = table[inst]; + stream << e.opcode; + + if(e.am1 != DASM_none) { + stream << ' '; + disassemble_am(stream, e.am1, pc, opcodes, slot[e.slot], e.slot, e.flags & LENGTHMASK); + } + if(e.am2 != DASM_none) { + stream << ", "; + disassemble_am(stream, e.am2, pc, opcodes, slot[e.slot], e.slot, e.flags & LENGTHMASK); + } + return e.flags | SUPPORTED; +} diff --git a/src/devices/cpu/h8/h8d.h b/src/devices/cpu/h8/h8d.h new file mode 100644 index 00000000000..65ba1d7fd97 --- /dev/null +++ b/src/devices/cpu/h8/h8d.h @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8-300 base cpu emulation, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_H8_H8D_H +#define MAME_CPU_H8_H8D_H + +#pragma once + +class h8_disassembler : public util::disasm_interface +{ +protected: + struct disasm_entry { + int slot; + u32 val, mask; + u16 val0, mask0; + const char *opcode; + int am1, am2; + offs_t flags; + }; + +public: + h8_disassembler(const disasm_entry *_table); + h8_disassembler(); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum { + DASM_none, /* no additional arguments */ + + DASM_r8l, /* 8-bits register in bits 0-3 */ + DASM_r8h, /* 8-bits register in bits 4-7 */ + DASM_r8u, /* 8-bits register in bits 8-15 */ + DASM_r16l, /* 16-bits register in bits 0-3 */ + DASM_r16h, /* 16-bits register in bits 4-7 */ + DASM_r32l, /* 32-bits register in bits 0-3 */ + DASM_r32h, /* 32-bits register in bits 4-7 */ + + DASM_r16ih, /* indexed through 16-bits register in bits 4-6 */ + DASM_r16ihh, /* indexed through 16-bits register in bits 4-6 in 4-bytes instruction */ + DASM_pr16h, /* indexed through predecremented 16-bits register in bits 4-6 */ + DASM_r16ph, /* indexed through postincremented 16-bits register in bits 4-6 */ + DASM_r16d16h, /* indexed through 16-bits register in bits 4-6 with 16-bits displacement at end of instruction */ + + DASM_r32ih, /* indexed through 32-bits register in bits 4-6 */ + DASM_r32ihh, /* indexed through 32-bits register in bits 4-6 in 4-bytes instruction */ + DASM_pr32h, /* indexed through predecremented 32-bits register in bits 4-6 */ + DASM_r32pl, /* indexed through postincremented 32-bits register in bits 0-2 */ + DASM_r32ph, /* indexed through postincremented 32-bits register in bits 4-6 */ + DASM_r32d16h, /* indexed through 32-bits register in bits 4-6 with 16-bits displacement at end of instruction */ + DASM_r32d32hh, /* indexed through 32-bits register in bits 20-22 with 32-bits displacement at end of instruction */ + + DASM_psp, /* indexed through predecremented stack pointer */ + DASM_spp, /* indexed through postincremented stack pointer */ + + DASM_r32n2l, /* Block of 2 registers */ + DASM_r32n3l, /* Block of 3 registers */ + DASM_r32n4l, /* Block of 4 registers */ + + DASM_abs8, /* 8-bit address present at +1 */ + DASM_abs16, /* 16-bit address present at end of instruction */ + DASM_abs32, /* 32-bit address present at end of instruction */ + DASM_abs8i, /* 8-bit indirect jump address present at +1 */ + DASM_abs16e, /* 16-bit jump address present at +2 */ + DASM_abs24e, /* 24-bit jump address present at +1 */ + + DASM_rel8, /* 8-bit pc-relative jump address at +1, offset=2 */ + DASM_rel16, /* 16-bit pc-relative jump address at +2, offset=4 */ + + DASM_one, /* immediate value 1 */ + DASM_two, /* immediate value 2 */ + DASM_four, /* immediate value 4 */ + + DASM_imm2, /* 2-bit immediate in bits 4-5 (trapa) */ + DASM_imm3, /* 3-bit immediate in bits 4-6 (bit selection */ + DASM_imm8, /* 8-bit immediate at +1 */ + DASM_imm16, /* 16-bit immediate at +2 */ + DASM_imm32, /* 32-bit immediate at +2 */ + + DASM_ccr, /* internal register ccr */ + DASM_exr, /* internal register exr */ + DASM_macl, /* internal register macl */ + DASM_mach /* internal register mach */ + }; + + void disassemble_am(std::ostream &stream, int am, offs_t pc, const data_buffer &opcodes, u32 opcode, int slot, int offset); + + const disasm_entry *table; + + static const disasm_entry disasm_entries[]; +}; + +#endif diff --git a/src/devices/cpu/h8/h8h.cpp b/src/devices/cpu/h8/h8h.cpp index 37756da3d12..97b945d8166 100644 --- a/src/devices/cpu/h8/h8h.cpp +++ b/src/devices/cpu/h8/h8h.cpp @@ -2,6 +2,7 @@ // copyright-holders:Olivier Galibert #include "emu.h" #include "h8h.h" +#include "h8hd.h" h8h_device::h8h_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate) : h8_device(mconfig, type, tag, owner, clock, false, map_delegate) @@ -10,9 +11,9 @@ h8h_device::h8h_device(const machine_config &mconfig, device_type type, const ch mode_advanced = true; } -offs_t h8h_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *h8h_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new h8h_disassembler; } #include "cpu/h8/h8h.hxx" diff --git a/src/devices/cpu/h8/h8h.h b/src/devices/cpu/h8/h8h.h index 460ddcefc3a..4c8c226a516 100644 --- a/src/devices/cpu/h8/h8h.h +++ b/src/devices/cpu/h8/h8h.h @@ -20,11 +20,9 @@ class h8h_device : public h8_device { protected: - static const disasm_entry disasm_entries[]; - h8h_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/h8/h8hd.cpp b/src/devices/cpu/h8/h8hd.cpp new file mode 100644 index 00000000000..c6cb3238784 --- /dev/null +++ b/src/devices/cpu/h8/h8hd.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8-300H base cpu emulation, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "h8hd.h" +#include "cpu/h8/h8hd.hxx" + +h8h_disassembler::h8h_disassembler() : h8_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/h8/h8hd.h b/src/devices/cpu/h8/h8hd.h new file mode 100644 index 00000000000..5123ee32563 --- /dev/null +++ b/src/devices/cpu/h8/h8hd.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8hd.h + + H8-300H base cpu emulation, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_H8_H8HD_H +#define MAME_CPU_H8_H8HD_H + +#pragma once + +#include "h8d.h" + +class h8h_disassembler : public h8_disassembler +{ +public: + h8h_disassembler(); + virtual ~h8h_disassembler() = default; + +protected: + static const disasm_entry disasm_entries[]; +}; + +#endif diff --git a/src/devices/cpu/h8/h8make.py b/src/devices/cpu/h8/h8make.py index e5aee1dbb96..99883e92c2a 100644 --- a/src/devices/cpu/h8/h8make.py +++ b/src/devices/cpu/h8/h8make.py @@ -5,7 +5,7 @@ from __future__ import print_function USAGE = """ Usage: -%s h8.lst <type> h8.inc (type = o/h/s20/s26) +%s h8.lst <mode> <type> h8.inc (mode = s/d, type = o/h/s20/s26) """ import sys @@ -21,14 +21,23 @@ def name_to_type(name): sys.stderr.write("Unknown chip type name %s\n" % name) sys.exit(1) -def type_to_device(dtype): - if dtype == 0: - return "h8_device" - if dtype == 1: - return "h8h_device" - if dtype == 2: - return "h8s2000_device" - return "h8s2600_device" +def type_to_device(dtype, mode): + if mode == 's': + if dtype == 0: + return "h8_device" + if dtype == 1: + return "h8h_device" + if dtype == 2: + return "h8s2000_device" + return "h8s2600_device" + else: + if dtype == 0: + return "h8_disassembler" + if dtype == 1: + return "h8h_disassembler" + if dtype == 2: + return "h8s2000_disassembler" + return "h8s2600_disassembler" def hexsplit(str): res = [] @@ -182,9 +191,9 @@ class Opcode: size = len(self.val) + 2*self.skip + 2*self.extra_words if self.name == "jsr" or self.name == "bsr": - flags = "%d | DASMFLAG_STEP_OVER" % size + flags = "%d | STEP_OVER" % size elif self.name == "rts" or self.name == "rte": - flags = "%d | DASMFLAG_STEP_OUT" % size + flags = "%d | STEP_OUT" % size else: flags = "%d" % size @@ -445,28 +454,31 @@ class OpcodeList: print("}", file=f) def main(argv): - if len(argv) != 4: + if len(argv) != 5: print(USAGE % argv[0]) return 1 - dtype = name_to_type(argv[2]) - dname = type_to_device(dtype) + mode = argv[2] + dtype = name_to_type(argv[3]) + dname = type_to_device(dtype, mode) opcodes = OpcodeList(argv[1], dtype) try: - f = open(argv[3], "w") + f = open(argv[4], "w") except Exception: err = sys.exc_info()[1] - sys.stderr.write("cannot write file %s [%s]\n" % (argv[3], err)) + sys.stderr.write("cannot write file %s [%s]\n" % (argv[4], err)) sys.exit(1) - opcodes.build_dispatch() - opcodes.save_dasm(f, dname) - opcodes.save_opcodes(f, dname) - if dtype == 0: - opcodes.save_dispatch(f, dname) - opcodes.save_exec(f, dname, dtype, "full") - opcodes.save_exec(f, dname, dtype, "partial") + if mode == 's': + opcodes.build_dispatch() + opcodes.save_opcodes(f, dname) + if dtype == 0: + opcodes.save_dispatch(f, dname) + opcodes.save_exec(f, dname, dtype, "full") + opcodes.save_exec(f, dname, dtype, "partial") + else: + opcodes.save_dasm(f, dname) f.close() # ====================================================================== diff --git a/src/devices/cpu/h8/h8s2000.cpp b/src/devices/cpu/h8/h8s2000.cpp index 2af090f5867..95e10cc2c50 100644 --- a/src/devices/cpu/h8/h8s2000.cpp +++ b/src/devices/cpu/h8/h8s2000.cpp @@ -2,6 +2,7 @@ // copyright-holders:Olivier Galibert #include "emu.h" #include "h8s2000.h" +#include "h8s2000d.h" h8s2000_device::h8s2000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate) : h8h_device(mconfig, type, tag, owner, clock, map_delegate) @@ -9,9 +10,9 @@ h8s2000_device::h8s2000_device(const machine_config &mconfig, device_type type, has_exr = true; } -offs_t h8s2000_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *h8s2000_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new h8s2000_disassembler; } #include "cpu/h8/h8s2000.hxx" diff --git a/src/devices/cpu/h8/h8s2000.h b/src/devices/cpu/h8/h8s2000.h index e28e640baec..8aa195df7ad 100644 --- a/src/devices/cpu/h8/h8s2000.h +++ b/src/devices/cpu/h8/h8s2000.h @@ -24,9 +24,7 @@ class h8s2000_device : public h8h_device { protected: h8s2000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate); - static const disasm_entry disasm_entries[]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/h8/h8s2000d.cpp b/src/devices/cpu/h8/h8s2000d.cpp new file mode 100644 index 00000000000..1e0b3830f53 --- /dev/null +++ b/src/devices/cpu/h8/h8s2000d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8S-2000 base cpu emulation, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "h8s2000d.h" +#include "cpu/h8/h8s2000d.hxx" + +h8s2000_disassembler::h8s2000_disassembler() : h8_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/h8/h8s2000d.h b/src/devices/cpu/h8/h8s2000d.h new file mode 100644 index 00000000000..cf6bc5bfa9e --- /dev/null +++ b/src/devices/cpu/h8/h8s2000d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8s2000d.h + + H8S-2000 base cpu emulation, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_H8_H8S2000D_H +#define MAME_CPU_H8_H8S2000D_H + +#pragma once + +#include "h8d.h" + +class h8s2000_disassembler : public h8_disassembler +{ +public: + h8s2000_disassembler(); + virtual ~h8s2000_disassembler() = default; + +protected: + static const disasm_entry disasm_entries[]; +}; + +#endif diff --git a/src/devices/cpu/h8/h8s2600.cpp b/src/devices/cpu/h8/h8s2600.cpp index 188f879279d..171dfef2d9b 100644 --- a/src/devices/cpu/h8/h8s2600.cpp +++ b/src/devices/cpu/h8/h8s2600.cpp @@ -2,15 +2,16 @@ // copyright-holders:Olivier Galibert #include "emu.h" #include "h8s2600.h" +#include "h8s2600d.h" h8s2600_device::h8s2600_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate) : h8s2000_device(mconfig, type, tag, owner, clock, map_delegate) { } -offs_t h8s2600_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *h8s2600_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new h8s2600_disassembler; } #include "cpu/h8/h8s2600.hxx" diff --git a/src/devices/cpu/h8/h8s2600.h b/src/devices/cpu/h8/h8s2600.h index 45b84bb2f8c..e3b4b7e44a9 100644 --- a/src/devices/cpu/h8/h8s2600.h +++ b/src/devices/cpu/h8/h8s2600.h @@ -20,11 +20,9 @@ class h8s2600_device : public h8s2000_device { protected: - static const disasm_entry disasm_entries[]; - h8s2600_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_delegate map_delegate); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/h8/h8s2600d.cpp b/src/devices/cpu/h8/h8s2600d.cpp new file mode 100644 index 00000000000..7e55784bed0 --- /dev/null +++ b/src/devices/cpu/h8/h8s2600d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8d.h + + H8S-2600 base cpu emulation, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "h8s2600d.h" +#include "cpu/h8/h8s2600d.hxx" + +h8s2600_disassembler::h8s2600_disassembler() : h8_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/h8/h8s2600d.h b/src/devices/cpu/h8/h8s2600d.h new file mode 100644 index 00000000000..3ee3fbfe133 --- /dev/null +++ b/src/devices/cpu/h8/h8s2600d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + h8s2600d.h + + H8S-2600 base cpu emulation, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_H8_H8S2600D_H +#define MAME_CPU_H8_H8S2600D_H + +#pragma once + +#include "h8d.h" + +class h8s2600_disassembler : public h8_disassembler +{ +public: + h8s2600_disassembler(); + virtual ~h8s2600_disassembler() = default; + +protected: + static const disasm_entry disasm_entries[]; +}; + +#endif diff --git a/src/devices/cpu/hcd62121/hcd62121.cpp b/src/devices/cpu/hcd62121/hcd62121.cpp index 92f3deaac88..efdb53ba2cd 100644 --- a/src/devices/cpu/hcd62121/hcd62121.cpp +++ b/src/devices/cpu/hcd62121/hcd62121.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Wilbert Pol +// copyright-holders:Wilbert Pol, Ricardo Barreira /********************************************************************** Hitachi hcd62121 cpu core emulation. @@ -7,9 +7,12 @@ The Hitachi hcd62121 is the custom cpu which was used in the Casio CFX-9850 (and maybe some other things too). -This CPU core is based on the information provided by Martin Poupe. +This CPU core is mainly based on the information provided by Martin Poupe. Martin Poupe's site can be found at http://martin.poupe.org/casio/ +Other contributors to reverse-engineering this CPU include Petr Pfeifer +who hacked the hardware, Uwe Ryssel, Brad O'Dell and Ricardo Barreira. + TODO: - instruction timings - unknown instructions @@ -18,6 +21,7 @@ TODO: #include "emu.h" #include "hcd62121.h" +#include "hcd62121d.h" #include "debugger.h" @@ -38,11 +42,11 @@ enum }; +constexpr u8 FLAG_CL = 0x10; constexpr u8 FLAG_Z = 0x08; -constexpr u8 FLAG_C = 0x02; -constexpr u8 FLAG_ZL = 0x04; -constexpr u8 FLAG_CL = 0x01; -constexpr u8 FLAG_ZH = 0x10; +constexpr u8 FLAG_C = 0x04; +constexpr u8 FLAG_ZL = 0x02; +constexpr u8 FLAG_ZH = 0x01; DEFINE_DEVICE_TYPE(HCD62121, hcd62121_cpu_device, "hcd62121_cpu_device", "Hitachi HCD62121") @@ -110,12 +114,12 @@ void hcd62121_cpu_device::read_reg(int size, u8 op1) if (op1 & 0x80) { for (int i = 0; i < size; i++) - m_temp1[i] = m_reg[(op1 - i) & 0x7f]; + m_temp1[i] = m_reg[(op1 - i) & 0x7f]; // TODO - is this really how wrap-around for registers works? } else { for (int i = 0; i < size; i++) - m_temp1[i] = m_reg[(op1 + i) & 0x7f]; + m_temp1[i] = m_reg[(op1 + i) & 0x7f]; // TODO - is this really how wrap-around for registers works? } } @@ -134,8 +138,7 @@ void hcd62121_cpu_device::write_reg(int size, u8 op1) } } - -void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logical) +void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool copy_extend_immediate) { for (int i = 0; i < size; i++) m_temp1[i] = m_reg[(op1 + i) & 0x7f]; @@ -145,7 +148,7 @@ void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logic /* Second operand is an immediate value */ m_temp2[0] = op2; for (int i = 1; i < size; i++) - m_temp2[i] = op_is_logical ? op2 : 0; + m_temp2[i] = copy_extend_immediate ? op2 : 0; } else { @@ -154,7 +157,7 @@ void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logic m_temp2[i] = m_reg[(op2 + i) & 0x7f]; } - if (!(op1 & 0x80) && !(op2 & 0x80)) + if (!(op1 & 0x80)) { /* We need to swap parameters */ for (int i = 0; i < size; i++) @@ -167,24 +170,24 @@ void hcd62121_cpu_device::read_regreg(int size, u8 op1, u8 op2, bool op_is_logic } -void hcd62121_cpu_device::write_regreg(int size, u8 op1, u8 op2) +void hcd62121_cpu_device::write_regreg(int size, u8 arg1, u8 arg2) { - if ((op1 & 0x80) || (op2 & 0x80)) + if ((arg1 & 0x80)) { - /* store in reg1 */ + /* store in arg1 */ for (int i = 0; i < size; i++) - m_reg[(op1 + i) & 0x7f] = m_temp1[i]; + m_reg[(arg1 + i) & 0x7f] = m_temp1[i]; } else { - /* store in reg2 */ + /* store in arg2 */ for (int i = 0; i < size; i++) - m_reg[(op2 + i) & 0x7f] = m_temp1[i]; + m_reg[(arg2 + i) & 0x7f] = m_temp1[i]; } } -void hcd62121_cpu_device::read_iregreg(int size, u8 op1, u8 op2) +void hcd62121_cpu_device::read_iregreg(int size, u8 op1, u8 op2, bool copy_extend_immediate) { u16 ad = m_reg[(0x40 | op1) & 0x7f ] | (m_reg[(0x40 | (op1 + 1)) & 0x7f] << 8); @@ -197,12 +200,14 @@ void hcd62121_cpu_device::read_iregreg(int size, u8 op1, u8 op2) if (op1 & 0x80) { + /* Second operand is an immediate value */ m_temp2[0] = op2; for (int i = 1; i < size; i++) - m_temp2[i] = 0; + m_temp2[i] = copy_extend_immediate ? op2 : 0; } else { + /* Second operand is a register */ for (int i = 0; i < size; i++) m_temp2[i] = m_reg[(op2 + i) & 0x7f]; } @@ -282,11 +287,11 @@ bool hcd62121_cpu_device::check_cond(u8 op) case 0x03: /* Z set */ return (m_f & FLAG_Z); - case 0x04: /* Z or C set */ - return (m_f & (FLAG_Z | FLAG_C)); + case 0x04: /* ZH not set */ + return (!(m_f & FLAG_ZH)); - case 0x05: /* CL set */ - return (m_f & FLAG_CL); + case 0x05: /* ZL not set */ + return (!(m_f & FLAG_ZL)); case 0x06: /* C clear */ return (!(m_f & FLAG_C)); @@ -575,169 +580,217 @@ inline void hcd62121_cpu_device::set_cl_flag(bool is_cl) inline void hcd62121_cpu_device::op_msk(int size) { - bool mskres = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { - if ((m_temp1[i] & m_temp2[i]) != m_temp2[i]) - mskres = false; + if ((m_temp1[i] & m_temp2[i] & 0xf0) != (m_temp2[i] & 0xf0)) + zero_high = false; + if ((m_temp1[i] & m_temp2[i] & 0x0f) != (m_temp2[i] & 0x0f)) + zero_low = false; } - set_zero_flag(!mskres); -} - - -inline void hcd62121_cpu_device::op_imsk(int size) -{ - bool mskres = true; - bool set_zero = false; + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); - for (int i = 0; i < size; i++) - { - if ((m_temp1[i] & ~m_temp2[i]) != ~m_temp2[i]) - mskres = false; - if (m_temp1[i] | m_temp2[i]) - set_zero = true; - } - - set_zero_flag(set_zero); - set_carry_flag(!mskres); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_and(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { m_temp1[i] = m_temp1[i] & m_temp2[i]; - if (m_temp1[i]) - is_zero = false; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_or(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { m_temp1[i] = m_temp1[i] | m_temp2[i]; - if (m_temp1[i]) - is_zero = false; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_xor(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; for (int i = 0; i < size; i++) { m_temp1[i] = m_temp1[i] ^ m_temp2[i]; - if (m_temp1[i]) - is_zero = false; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_cl_flag(false); + set_carry_flag(false); } inline void hcd62121_cpu_device::op_add(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; u8 carry = 0; - set_cl_flag((m_temp1[0] & 0x0f) + (m_temp2[0] & 0x0f) > 15); - for (int i = 0; i < size; i++) { - u16 res = m_temp1[i] + m_temp2[i] + carry; + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry > 0x0f); + } + u16 res = m_temp1[i] + m_temp2[i] + carry; m_temp1[i] = res & 0xff; - if (m_temp1[i]) - is_zero = false; - carry = (res & 0xff00) ? 1 : 0; + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); set_carry_flag(carry); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); } // BCD ADD inline void hcd62121_cpu_device::op_addb(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; u8 carry = 0; - set_cl_flag((m_temp1[0] & 0x0f) + (m_temp2[0] & 0x0f) > 9); - for (int i = 0; i < size; i++) { - u16 res = (m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry; - - if (res > 9) - { - res += 6; + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) + (m_temp2[i] & 0x0f) + carry > 9); } - res += (m_temp1[i] & 0xf0) + (m_temp2[i] & 0xf0); - if (res > 0x9f) - { - res += 0x60; + + int num1 = (m_temp1[i] & 0x0f) + ((m_temp1[i] & 0xf0) >> 4) * 10; + int num2 = (m_temp2[i] & 0x0f) + ((m_temp2[i] & 0xf0) >> 4) * 10; + + int result = num1 + num2 + carry; + carry = (result > 99); + if (result > 99) + result -= 100; + m_temp1[i] = (result % 10) | ((result / 10) << 4); + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; + } + + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_carry_flag(carry); +} + + +// BCD SUBTRACT +inline void hcd62121_cpu_device::op_subb(int size) +{ + bool zero_high = true; + bool zero_low = true; + u8 carry = 0; + + for (int i = 0; i < size; i++) + { + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) - (m_temp2[i] & 0x0f) - carry < 0); } - m_temp1[i] = res & 0xff; - if (m_temp1[i]) - is_zero = false; - carry = (res & 0xff00) ? 1 : 0; + int num1 = (m_temp1[i] & 0x0f) + ((m_temp1[i] & 0xf0) >> 4) * 10; + int num2 = (m_temp2[i] & 0x0f) + ((m_temp2[i] & 0xf0) >> 4) * 10; + + int result = num1 - num2 - carry; + carry = (result < 0); + if (result < 0) + result += 100; + m_temp1[i] = (result % 10) | ((result / 10) << 4); + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); set_carry_flag(carry); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); } inline void hcd62121_cpu_device::op_sub(int size) { - bool is_zero = true; + bool zero_high = true; + bool zero_low = true; u8 carry = 0; - set_cl_flag((m_temp1[0] & 0x0f) < (m_temp2[0] & 0x0f)); - for (int i = 0; i < size; i++) { - u16 res = m_temp1[i] - m_temp2[i] - carry; + if (i == size - 1) { + set_cl_flag((m_temp1[i] & 0x0f) - (m_temp2[i] & 0x0f) - carry < 0); + } + u16 res = m_temp1[i] - m_temp2[i] - carry; m_temp1[i] = res & 0xff; - if (m_temp1[i]) - is_zero = false; - carry = ( res & 0xff00 ) ? 1 : 0; + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } - set_zero_flag(is_zero); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); set_carry_flag(carry); - set_zl_flag((m_temp1[0] & 0x0f) == 0); - set_zh_flag((m_temp1[0] & 0xf0) == 0); } @@ -774,48 +827,36 @@ void hcd62121_cpu_device::execute_run() // actual instruction timings unknown m_icount -= 4; - switch (op) { - case 0x00: /* rorb/rolb r1,4 */ - case 0x01: /* rorw/rolw r1,4 */ - case 0x02: /* rorq/rolq r1,4 */ - case 0x03: /* rort/rolt r1,4 */ - /* Nibble rotate */ + case 0x00: /* shrb/shlb r1,8 */ // Yes, this just sets a register to 0! + case 0x01: /* shrw/shlw r1,8 */ + case 0x02: /* shrq/shlq r1,8 */ + case 0x03: /* shrt/shlt r1,8 */ { int size = datasize(op); u8 reg1 = read_op(); - u8 d1 = 0, d2 = 0; - read_reg(size, reg1); - - if (reg1 & 0x80) - { - // rotate right - d2 = (m_temp1[size-1] & 0x0f) << 4; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x0f) << 4; - m_temp1[i] = (m_temp1[i] >> 4) | d2; - d2 = d1; + // TODO - read_reg should support reading this + if (reg1 & 0x80) { + read_reg(size, (reg1 & 0x7f) - size + 1); + for (int i=0; i < size - 1; i++) { + m_temp1[i] = m_temp1[i + 1]; } + m_temp1[size-1] = 0; + write_reg(size, (reg1 & 0x7f) - size + 1); } else { - // rotate left - d2 = (m_temp1[size-1] & 0xf0) >> 4; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0xf0) >> 4; - m_temp1[i] = (m_temp1[i] << 4) | d2; - d2 = d1; + read_reg(size, reg1); + for (int i = size-1; i > 0; i--) { + m_temp1[i] = m_temp1[i - 1]; } + m_temp1[0] = 0; + write_reg(size, reg1); } - - write_reg(size, reg1); } break; - case 0x04: /* mskb r1,r2 */ case 0x05: /* mskw r1,r2 */ case 0x06: /* mskq r1,r2 */ @@ -825,7 +866,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_msk(size); } @@ -877,7 +918,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_and(size); } @@ -892,7 +933,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_xor(size); @@ -933,10 +974,10 @@ void hcd62121_cpu_device::execute_run() } break; - case 0x1C: /* imskb r1,r2 */ - case 0x1D: /* imskw r1,r2 */ - case 0x1E: /* imskq r1,r2 */ - case 0x1F: /* imskt r1,r2 */ + case 0x1C: /* cmpaddb r1,r2 */ + case 0x1D: /* cmpaddw r1,r2 */ + case 0x1E: /* cmpaddq r1,r2 */ + case 0x1F: /* cmpaddt r1,r2 */ { int size = datasize(op); u8 reg1 = read_op(); @@ -944,46 +985,42 @@ void hcd62121_cpu_device::execute_run() read_regreg(size, reg1, reg2, false); - op_imsk(size); + op_add(size); } break; - case 0x20: /* rorb/rolb r1 */ - case 0x21: /* rorw/rolw r1 */ - case 0x22: /* rorq/rolq r1 */ - case 0x23: /* rort/rolt r1 */ - /* Single bit rotate */ + case 0x20: /* shrb r1,1 */ + case 0x21: /* shrw r1,1 */ + case 0x22: /* shrq r1,1 */ + case 0x23: /* shrt r1,1 */ { int size = datasize(op); u8 reg1 = read_op(); u8 d1 = 0, d2 = 0; + bool zero_high = true; + bool zero_low = true; read_reg(size, reg1); - if (reg1 & 0x80) - { - // rotate right - d2 = (m_temp1[size-1] & 0x01) << 7; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x01) << 7; - m_temp1[i] = (m_temp1[i] >> 1) | d2; - d2 = d1; - } - } - else + d2 = 0; + set_cl_flag ((m_temp1[0] & (1U<<4)) != 0U); + for (int i = 0; i < size; i++) { - // rotate left - d2 = (m_temp1[size-1] & 0x80) >> 7; - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x80) >> 7; - m_temp1[i] = (m_temp1[i] << 1) | d2; - d2 = d1; - } + d1 = (m_temp1[i] & 0x01) << 7; + m_temp1[i] = (m_temp1[i] >> 1) | d2; + d2 = d1; + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } write_reg(size, reg1); + + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_carry_flag (d2 != 0); } break; @@ -996,7 +1033,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_regreg(size, reg1, reg2, false); + read_regreg(size, reg1, reg2, true); op_or(size); @@ -1004,40 +1041,37 @@ void hcd62121_cpu_device::execute_run() } break; - case 0x28: /* shrb/shlb r1 */ - case 0x29: /* shrw/shlw r1 */ - case 0x2A: /* shrq/shlq r1 */ - case 0x2B: /* shrt/shlt r1 */ - /* Single bit shift */ + case 0x28: /* shlb r1,1 */ + case 0x29: /* shlw r1,1 */ + case 0x2A: /* shlq r1,1 */ + case 0x2B: /* shlt r1,1 */ { int size = datasize(op); u8 reg1 = read_op(); u8 d1 = 0, d2 = 0; + bool zero_high = true; + bool zero_low = true; read_reg(size, reg1); - if (reg1 & 0x80) - { - // shift right - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x01) << 7; - m_temp1[i] = (m_temp1[i] >> 1) | d2; - d2 = d1; - } - } - else + set_cl_flag ((m_temp1[0] & (1U<<3)) != 0U); + for (int i = 0; i < size; i++) { - // shift left - for (int i = 0; i < size; i++) - { - d1 = (m_temp1[i] & 0x80) >> 7; - m_temp1[i] = (m_temp1[i] << 1) | d2; - d2 = d1; - } + d1 = (m_temp1[i] & 0x80) >> 7; + m_temp1[i] = (m_temp1[i] << 1) | d2; + d2 = d1; + + if (m_temp1[i] & 0xf0) + zero_high = false; + if (m_temp1[i] & 0x0f) + zero_low = false; } write_reg(size, reg1); + set_zero_flag(zero_high && zero_low); + set_zh_flag(zero_high); + set_zl_flag(zero_low); + set_carry_flag (d2 != 0); } break; @@ -1058,6 +1092,23 @@ void hcd62121_cpu_device::execute_run() } break; + case 0x30: /* subbb r1,r2 */ + case 0x31: /* subbw r1,r2 */ + case 0x32: /* subbq r1,r2 */ + case 0x33: /* subbt r1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_regreg(size, reg1, reg2, false); + + op_subb(size); + + write_regreg(size, reg1, reg2); + } + break; + case 0x34: /* subb r1,r2 */ case 0x35: /* subw r1,r2 */ case 0x36: /* subq r1,r2 */ @@ -1118,7 +1169,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, true); op_and(size); } @@ -1133,7 +1184,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, false); op_sub(size); } @@ -1148,7 +1199,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, false); for (int i = 0; i < size; i++) m_temp1[i] = m_temp2[i]; @@ -1157,6 +1208,21 @@ void hcd62121_cpu_device::execute_run() } break; + case 0x5C: /* cmpaddb ir1,r2 */ + case 0x5D: /* cmpaddw ir1,r2 */ + case 0x5E: /* cmpaddq ir1,r2 */ + case 0x5F: /* cmpaddt ir1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_iregreg(size, reg1, reg2, false); + + op_add(size); + } + break; + case 0x64: /* orb ir1,r2 */ case 0x65: /* orb ir1,r2 */ case 0x66: /* orb ir1,r2 */ @@ -1166,7 +1232,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, true); op_or(size); @@ -1183,7 +1249,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, true); op_and(size); @@ -1191,6 +1257,40 @@ void hcd62121_cpu_device::execute_run() } break; + case 0x74: /* subb ir1,r2 */ + case 0x75: /* subw ir1,r2 */ + case 0x76: /* subq ir1,r2 */ + case 0x77: /* subt ir1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_iregreg(size, reg1, reg2, false); + + op_sub(size); + + write_iregreg(size, reg1, reg2); + } + break; + + case 0x78: /* adbb ir1,r2 */ + case 0x79: /* adbw ir1,r2 */ + case 0x7A: /* adbq ir1,r2 */ + case 0x7B: /* adbt ir1,r2 */ + { + int size = datasize(op); + u8 reg1 = read_op(); + u8 reg2 = read_op(); + + read_iregreg(size, reg1, reg2, false); + + op_addb(size); + + write_iregreg(size, reg1, reg2); + } + break; + case 0x7C: /* addb ir1,r2 */ case 0x7D: /* addw ir1,r2 */ case 0x7E: /* addq ir1,r2 */ @@ -1200,7 +1300,7 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + read_iregreg(size, reg1, reg2, false); op_add(size); @@ -1209,7 +1309,11 @@ void hcd62121_cpu_device::execute_run() break; case 0x88: /* jump _a16 */ - m_ip = (read_op() << 8) | read_op(); + { + u8 a1 = read_op(); + u8 a2 = read_op(); + m_ip = (a1 << 8) | a2; + } break; case 0x89: /* jumpf cs:a16 */ @@ -1234,8 +1338,30 @@ void hcd62121_cpu_device::execute_run() } break; - case 0x8C: /* unk_8C */ - case 0x8D: /* unk_8D */ + case 0x8C: /* bstack_to_dmem */ + { + int size = m_dsize + 1; + for (int i=0; i < size; i++) { + u8 byte = m_program->read_byte((m_sseg << 16) | m_sp); + m_program->write_byte((m_dseg << 16) | m_lar, byte); + m_sp--; + m_lar--; + } + } + break; + + case 0x8D: /* fstack_to_dmem */ + { + int size = m_dsize + 1; + for (int i=0; i < size; i++) { + u8 byte = m_program->read_byte((m_sseg << 16) | m_sp); + m_program->write_byte((m_dseg << 16) | m_lar, byte); + m_sp++; + m_lar++; + } + } + break; + case 0x8E: /* unk_8E */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); break; @@ -1244,8 +1370,8 @@ void hcd62121_cpu_device::execute_run() case 0x91: /* retzl */ case 0x92: /* retc */ case 0x93: /* retz */ - case 0x94: /* retzc */ - case 0x95: /* retcl */ + case 0x94: /* retnzh */ + case 0x95: /* retnzl */ case 0x96: /* retnc */ case 0x97: /* retnz */ if (check_cond(op)) @@ -1274,8 +1400,8 @@ void hcd62121_cpu_device::execute_run() case 0xA1: /* jmpzl a16 */ case 0xA2: /* jmpc a16 */ case 0xA3: /* jmpz a16 */ - case 0xA4: /* jmpzc a16 */ - case 0xA5: /* jmpcl a16 */ + case 0xA4: /* jmpnzh a16 */ + case 0xA5: /* jmpnzl a16 */ case 0xA6: /* jmpnc a16 */ case 0xA7: /* jmpnz a16 */ { @@ -1291,8 +1417,8 @@ void hcd62121_cpu_device::execute_run() case 0xA9: /* callzl a16 */ case 0xAA: /* callc a16 */ case 0xAB: /* callz a16 */ - case 0xAC: /* callzc a16 */ - case 0xAD: /* callcl a16 */ + case 0xAC: /* callnzh a16 */ + case 0xAD: /* callnzl a16 */ case 0xAE: /* callnc a16 */ case 0xAF: /* callnz a16 */ { @@ -1335,7 +1461,7 @@ void hcd62121_cpu_device::execute_run() read_op(); break; - case 0xBB: /* jmpcl? a16 */ + case 0xBB: /* jmpcl a16 */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); { u8 a1 = read_op(); @@ -1346,12 +1472,7 @@ void hcd62121_cpu_device::execute_run() } break; - case 0xBC: /* unk_BC reg/i8 */ - logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); - read_op(); - break; - - case 0xBF: /* jmpncl? a16 */ + case 0xBF: /* jmpncl a16 */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); { u8 a1 = read_op(); @@ -1362,14 +1483,17 @@ void hcd62121_cpu_device::execute_run() } break; - case 0xC0: /* movb reg,i8 */ + //case 0xC0: /* movb reg,i8 */ // TODO - test case 0xC1: /* movw reg,i16 */ - case 0xC2: /* movw reg,i64 */ - case 0xC3: /* movw reg,i80 */ + //case 0xC2: /* movw reg,i64 */ // TODO - test + //case 0xC3: /* movw reg,i80 */ // TODO - test { int size = datasize(op); u8 reg = read_op(); + if (reg & 0x80) + fatalerror("%02x:%04x: unimplemented instruction %02x encountered with (arg & 0x80) != 0\n", m_cseg, m_ip-1, op); + for (int i = 0; i < size; i++) { m_reg[(reg + i) & 0x7f] = read_op(); @@ -1383,12 +1507,12 @@ void hcd62121_cpu_device::execute_run() case 0xC7: /* movt (lar),r1 / r1,(lar) */ { int size = datasize(op); - u8 reg1 = read_op(); - u8 reg2 = read_op(); + u8 arg1 = read_op(); + u8 arg2 = read_op(); int pre_inc = 0; int post_inc = 1; - switch (reg1 & 0x60) + switch (arg1 & 0x60) { case 0x00: pre_inc = 0; @@ -1408,23 +1532,29 @@ void hcd62121_cpu_device::execute_run() break; } - if ((reg1 & 0x80) || (reg2 & 0x80)) + if ((arg1 & 0x80) || (arg2 & 0x80)) { - /* (lar) <- r1 */ + /* (lar) <- r2 (immediate or register) */ for (int i = 0; i < size; i++) { m_lar += pre_inc; - m_program->write_byte((m_dseg << 16) | m_lar, m_reg[(reg2 + i) & 0x7f]); + if (arg1 & 0x80) { + m_program->write_byte((m_dseg << 16) | m_lar, arg2); + } + else + { + m_program->write_byte((m_dseg << 16) | m_lar, m_reg[(arg2 + i) & 0x7f]); + } m_lar += post_inc; } } else { - /* r1 <- (lar) */ + /* r2 <- (lar) */ for (int i = 0; i < size; i++) { m_lar += pre_inc; - m_reg[(reg2 + i) & 0x7f] = m_program->read_byte((m_dseg << 16) | m_lar); + m_reg[(arg2 + i) & 0x7f] = m_program->read_byte((m_dseg << 16) | m_lar); m_lar += post_inc; } } @@ -1440,7 +1570,11 @@ void hcd62121_cpu_device::execute_run() u8 reg1 = read_op(); u8 reg2 = read_op(); - read_iregreg(size, reg1, reg2); + if (reg1 & 0x80) { + fatalerror("%02x:%04x: unimplemented swap with immediate encountered\n", m_cseg, m_ip-1); + } + + read_iregreg(size, reg1, reg2, false); for (int i = 0; i < size; i++) { @@ -1451,6 +1585,7 @@ void hcd62121_cpu_device::execute_run() write_iregreg(size, reg1, reg2); write_iregreg2(size, reg1, reg2); + // TODO - are flags affected? } break; @@ -1492,11 +1627,11 @@ void hcd62121_cpu_device::execute_run() break; case 0xD8: /* movb f,reg */ - m_f = m_reg[read_op() & 0x7f]; + m_f = m_reg[read_op() & 0x7f] & 0x3f; break; case 0xD9: /* movb f,i8 */ - m_f = read_op(); + m_f = read_op() & 0x3f; break; case 0xDC: /* movb ds,reg */ @@ -1515,6 +1650,10 @@ void hcd62121_cpu_device::execute_run() } break; + case 0xDF: /* movw lar,i8 */ + m_lar = read_op(); + break; + case 0xE0: /* in0 reg */ { logerror("%06x: in0 read\n", (m_cseg << 16) | m_ip); @@ -1532,16 +1671,26 @@ void hcd62121_cpu_device::execute_run() m_reg[read_op() & 0x7f] = m_ki_cb(); break; - case 0xE6: /* movb reg,PORT */ - m_reg[read_op() & 0x7f] = m_port; + case 0xE3: /* movb reg,dsize */ + { + u8 reg = read_op(); + if (reg & 0x80) + fatalerror("%02x:%04x: unimplemented instruction %02x encountered with (arg & 0x80) != 0\n", m_cseg, m_ip-1, op); + m_reg[reg & 0x7f] = m_dsize; + } break; - case 0xE3: /* unk_e3 reg/i8 (in?) */ - case 0xE4: /* unk_e4 reg/i8 (in?) */ - case 0xE5: /* unk_e5 reg/i8 (in?) */ - case 0xE7: /* unk_e7 reg/i8 (in?) */ - logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); - read_op(); + case 0xE4: /* movb reg,f */ + { + u8 reg = read_op(); + if (reg & 0x80) + fatalerror("%02x:%04x: unimplemented instruction %02x encountered with (arg & 0x80) != 0\n", m_cseg, m_ip-1, op); + m_reg[reg & 0x7f] = m_f; + } + break; + + case 0xE6: /* movb reg,PORT */ + m_reg[read_op() & 0x7f] = m_port; break; case 0xE8: /* movw r1,lar */ @@ -1553,7 +1702,7 @@ void hcd62121_cpu_device::execute_run() } break; - case 0xEB: /* movw reg,ss */ + case 0xEB: /* movw reg,sp */ { u8 reg1 = read_op(); @@ -1578,9 +1727,7 @@ void hcd62121_cpu_device::execute_run() case 0xF1: /* unk_F1 reg/i8 (out?) */ case 0xF3: /* unk_F3 reg/i8 (out?) */ - case 0xF4: /* unk_F4 reg/i8 (out?) */ case 0xF5: /* unk_F5 reg/i8 (out?) */ - case 0xF6: /* unk_F6 reg/i8 (out?) */ case 0xF7: /* unk_F7 reg/i8 (out?) */ logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); read_op(); @@ -1589,6 +1736,9 @@ void hcd62121_cpu_device::execute_run() case 0xFC: /* unk_FC - disable interrupts/stop timer?? */ case 0xFD: /* unk_FD */ case 0xFE: /* unk_FE - wait for/start timer */ + if (op == 0xFE) + m_icount -= 75000; // TODO: temporary value that makes emulation speed acceptable + logerror("%02x:%04x: unimplemented instruction %02x encountered\n", m_cseg, m_ip-1, op); break; @@ -1602,9 +1752,7 @@ void hcd62121_cpu_device::execute_run() } while (m_icount > 0); } - -offs_t hcd62121_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, uint32_t options) +util::disasm_interface *hcd62121_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(hcd62121); - return CPU_DISASSEMBLE_NAME(hcd62121)(this, stream, pc, oprom, opram, options); + return new hcd62121_disassembler; } diff --git a/src/devices/cpu/hcd62121/hcd62121.h b/src/devices/cpu/hcd62121/hcd62121.h index ff43a2ac1dc..1b7fb74feba 100644 --- a/src/devices/cpu/hcd62121/hcd62121.h +++ b/src/devices/cpu/hcd62121/hcd62121.h @@ -61,18 +61,16 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 18; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; private: u8 read_op(); u8 datasize(u8 op); void read_reg(int size, u8 op1); void write_reg(int size, u8 op1); - void read_regreg(int size, u8 op1, u8 op2, bool op_is_logical); + void read_regreg(int size, u8 op1, u8 op2, bool copy_extend_immediate); void write_regreg(int size, u8 op1, u8 op2); - void read_iregreg(int size, u8 op1, u8 op2); + void read_iregreg(int size, u8 op1, u8 op2, bool copy_extend_immediate); void write_iregreg(int size, u8 op1, u8 op2); void write_iregreg2(int size, u8 op1, u8 op2); bool check_cond(u8 op); @@ -82,12 +80,12 @@ private: void set_zh_flag(bool is_zh); void set_cl_flag(bool is_cl); void op_msk(int size); - void op_imsk(int size); void op_and(int size); void op_or(int size); void op_xor(int size); void op_add(int size); void op_addb(int size); + void op_subb(int size); void op_sub(int size); void op_pushw(u16 source); u16 op_popw(); diff --git a/src/devices/cpu/hcd62121/hcd62121d.cpp b/src/devices/cpu/hcd62121/hcd62121d.cpp index b6598127a55..2b7ea7b1150 100644 --- a/src/devices/cpu/hcd62121/hcd62121d.cpp +++ b/src/devices/cpu/hcd62121/hcd62121d.cpp @@ -2,56 +2,17 @@ // copyright-holders:Wilbert Pol #include "emu.h" +#include "hcd62121d.h" -enum -{ - ARG_NONE=0, /* no argument or unknown */ - ARG_REG, /* register */ - ARG_REGREG, /* register1, register2, or register2, register1 or register1, imm byte */ - ARG_IRG, /* register indirect */ - ARG_IRGREG, /* 2 register indirect */ - ARG_A16, /* 16bit address */ - ARG_A24, /* seg:address */ - ARG_F, /* flag register */ - ARG_CS, /* cs register */ - ARG_DS, /* ds register */ - ARG_SS, /* ss register */ - ARG_PC, /* program counter */ - ARG_SP, /* stack pointer */ - ARG_I8, /* immediate 8 bit value */ - ARG_I16, /* immediate 16 bit value */ - ARG_I64, /* immediate 64 bit value */ - ARG_I80, /* immediate 80 bit value */ - ARG_ILR, /* indirect last address register access */ - ARG_LAR, /* last address register */ - ARG_DSZ, /* dsize register? */ - ARG_OPT, /* OPTx (output) pins */ - ARG_PORT, /* PORTx (output) pins */ - ARG_TIM, /* timing related register? */ - ARG_KLO, /* KO1 - KO8 output lines */ - ARG_KHI, /* KO9 - KO14(?) output lines */ - ARG_KI, /* K input lines */ - ARG_RS, /* rotate/shift */ - ARG_RS4 /* nibble rotate/shift */ -}; - -struct hcd62121_dasm -{ - const char *str; - u8 arg1; - u8 arg2; -}; - - -static const hcd62121_dasm hcd62121_ops[256] = +const hcd62121_disassembler::dasm hcd62121_disassembler::ops[256] = { /* 0x00 */ - { "ro?b", ARG_REG, ARG_RS4 }, { "ro?w", ARG_REG, ARG_RS4 }, - { "ro?q", ARG_REG, ARG_RS4 }, { "ro?t", ARG_REG, ARG_RS4 }, + { "sh?b", ARG_REG, ARG_S8 }, { "sh?w", ARG_REG, ARG_S8 }, + { "sh?q", ARG_REG, ARG_S8 }, { "sh?t", ARG_REG, ARG_S8 }, { "mskb", ARG_REGREG, ARG_NONE }, { "mskw", ARG_REGREG, ARG_NONE }, { "mskq", ARG_REGREG, ARG_NONE }, { "mskt", ARG_REGREG, ARG_NONE }, - { "sh?b", ARG_REG, ARG_RS4 }, { "sh?w", ARG_REG, ARG_RS4 }, - { "sh?q", ARG_REG, ARG_RS4 }, { "sh?t", ARG_REG, ARG_RS4 }, + { "sh?b", ARG_REG, ARG_S4 }, { "sh?w", ARG_REG, ARG_S4 }, + { "sh?q", ARG_REG, ARG_S4 }, { "sh?t", ARG_REG, ARG_S4 }, { "tstb", ARG_REGREG, ARG_NONE }, { "tstw", ARG_REGREG, ARG_NONE }, { "tstq", ARG_REGREG, ARG_NONE }, { "tstt", ARG_REGREG, ARG_NONE }, @@ -62,16 +23,16 @@ static const hcd62121_dasm hcd62121_ops[256] = { "cmpq", ARG_REGREG, ARG_NONE }, { "cmpt", ARG_REGREG, ARG_NONE }, { "movb", ARG_REGREG, ARG_NONE }, { "movw", ARG_REGREG, ARG_NONE }, { "movq", ARG_REGREG, ARG_NONE }, { "movt", ARG_REGREG, ARG_NONE }, - { "imskb", ARG_REGREG, ARG_NONE }, { "imskw", ARG_REGREG, ARG_NONE }, - { "imskq", ARG_REGREG, ARG_NONE }, { "imskt", ARG_REGREG, ARG_NONE }, + { "cmpaddb", ARG_REGREG, ARG_NONE }, { "cmpaddw", ARG_REGREG, ARG_NONE }, + { "cmpaddq", ARG_REGREG, ARG_NONE }, { "cmpaddt", ARG_REGREG, ARG_NONE }, /* 0x20 */ - { "ro?b", ARG_REG, ARG_RS }, { "ro?w", ARG_REG, ARG_RS }, - { "ro?q", ARG_REG, ARG_RS }, { "ro?t", ARG_REG, ARG_RS }, + { "shrb", ARG_REG, ARG_S1 }, { "shrw", ARG_REG, ARG_S1 }, + { "shrq", ARG_REG, ARG_S1 }, { "shrt", ARG_REG, ARG_S1 }, { "orb", ARG_REGREG, ARG_NONE }, { "orw", ARG_REGREG, ARG_NONE }, { "orq", ARG_REGREG, ARG_NONE }, { "ort", ARG_REGREG, ARG_NONE }, - { "sh?b", ARG_REG, ARG_RS }, { "sh?w", ARG_REG, ARG_RS }, - { "sh?q", ARG_REG, ARG_RS }, { "sh?t", ARG_REG, ARG_RS }, + { "shlb", ARG_REG, ARG_S1 }, { "shlw", ARG_REG, ARG_S1 }, + { "shlq", ARG_REG, ARG_S1 }, { "shlt", ARG_REG, ARG_S1 }, { "andb", ARG_REGREG, ARG_NONE }, { "andw", ARG_REGREG, ARG_NONE }, { "andq", ARG_REGREG, ARG_NONE }, { "andt", ARG_REGREG, ARG_NONE }, @@ -86,12 +47,12 @@ static const hcd62121_dasm hcd62121_ops[256] = { "addq", ARG_REGREG, ARG_NONE }, { "addt", ARG_REGREG, ARG_NONE }, /* 0x40 */ - { "ro?b", ARG_IRG, ARG_RS4 }, { "ro?w", ARG_IRG, ARG_RS4 }, - { "ro?q", ARG_IRG, ARG_RS4 }, { "ro?t", ARG_IRG, ARG_RS4 }, + { "sh?b", ARG_IRG, ARG_S8 }, { "sh?w", ARG_IRG, ARG_S8 }, + { "sh?q", ARG_IRG, ARG_S8 }, { "sh?t", ARG_IRG, ARG_S8 }, { "mskb", ARG_IRGREG, ARG_NONE }, { "mskw", ARG_IRGREG, ARG_NONE }, { "mskq", ARG_IRGREG, ARG_NONE }, { "mskt", ARG_IRGREG, ARG_NONE }, - { "sh?b", ARG_IRG, ARG_RS4 }, { "sh?w", ARG_IRG, ARG_RS4 }, - { "sh?q", ARG_IRG, ARG_RS4 }, { "sh?t", ARG_IRG, ARG_RS4 }, + { "sh?b", ARG_IRG, ARG_S4 }, { "sh?w", ARG_IRG, ARG_S4 }, + { "sh?q", ARG_IRG, ARG_S4 }, { "sh?t", ARG_IRG, ARG_S4 }, { "tstb", ARG_IRGREG, ARG_NONE }, { "tstw", ARG_IRGREG, ARG_NONE }, { "tstq", ARG_IRGREG, ARG_NONE }, { "tstt", ARG_IRGREG, ARG_NONE }, @@ -102,16 +63,16 @@ static const hcd62121_dasm hcd62121_ops[256] = { "cmpq", ARG_IRGREG, ARG_NONE }, { "cmpt", ARG_IRGREG, ARG_NONE }, { "movb", ARG_IRGREG, ARG_NONE }, { "movw", ARG_IRGREG, ARG_NONE }, { "movq", ARG_IRGREG, ARG_NONE }, { "movt", ARG_IRGREG, ARG_NONE }, - { "imskb", ARG_IRGREG, ARG_NONE }, { "imskw", ARG_IRGREG, ARG_NONE }, - { "imskq", ARG_IRGREG, ARG_NONE }, { "imskt", ARG_IRGREG, ARG_NONE }, + { "cmpaddb", ARG_IRGREG, ARG_NONE }, { "cmpaddw", ARG_IRGREG, ARG_NONE }, + { "cmpaddq", ARG_IRGREG, ARG_NONE }, { "cmpaddt", ARG_IRGREG, ARG_NONE }, /* 0x60 */ - { "ro?b", ARG_IRG, ARG_RS }, { "ro?w", ARG_IRG, ARG_RS }, - { "ro?q", ARG_IRG, ARG_RS }, { "ro?t", ARG_IRG, ARG_RS }, + { "shrb", ARG_IRG, ARG_S1 }, { "shrw", ARG_IRG, ARG_S1 }, + { "shrq", ARG_IRG, ARG_S1 }, { "shrt", ARG_IRG, ARG_S1 }, { "orb", ARG_IRGREG, ARG_NONE }, { "orw", ARG_IRGREG, ARG_NONE }, { "orq", ARG_IRGREG, ARG_NONE }, { "ort", ARG_IRGREG, ARG_NONE }, - { "sh?b", ARG_IRG, ARG_RS }, { "sh?w", ARG_IRG, ARG_RS }, - { "sh?q", ARG_IRG, ARG_RS }, { "sh?t", ARG_IRG, ARG_RS }, + { "shlb", ARG_IRG, ARG_S1 }, { "shlw", ARG_IRG, ARG_S1 }, + { "shlq", ARG_IRG, ARG_S1 }, { "shlt", ARG_IRG, ARG_S1 }, { "andb", ARG_IRGREG, ARG_NONE }, { "andw", ARG_IRGREG, ARG_NONE }, { "andq", ARG_IRGREG, ARG_NONE }, { "andt", ARG_IRGREG, ARG_NONE }, @@ -132,13 +93,13 @@ static const hcd62121_dasm hcd62121_ops[256] = { "un86?", ARG_NONE, ARG_NONE }, { "un87?", ARG_NONE, ARG_NONE }, { "jump", ARG_A16, ARG_NONE }, { "jump", ARG_A24, ARG_NONE }, { "call", ARG_A16, ARG_NONE }, { "un8b?", ARG_NONE, ARG_NONE }, - { "un8C?", ARG_NONE, ARG_NONE }, { "un8D?", ARG_NONE, ARG_NONE }, + { "bstack_to_dmem", ARG_NONE, ARG_NONE }, { "fstack_to_dmem", ARG_NONE, ARG_NONE }, { "un8E?", ARG_NONE, ARG_NONE }, { "un8F?", ARG_NONE, ARG_NONE }, /* 0x90 */ { "retzh", ARG_NONE, ARG_NONE }, { "retzl", ARG_NONE, ARG_NONE }, { "retc", ARG_NONE, ARG_NONE }, { "retz", ARG_NONE, ARG_NONE }, - { "retzc", ARG_NONE, ARG_NONE }, { "retcl", ARG_NONE, ARG_NONE }, + { "retnzh", ARG_NONE, ARG_NONE }, { "retnzl", ARG_NONE, ARG_NONE }, { "retnc", ARG_NONE, ARG_NONE }, { "retnz", ARG_NONE, ARG_NONE }, { "jump", ARG_IRG, ARG_NONE }, { "un99?", ARG_NONE, ARG_NONE }, { "un9A?", ARG_NONE, ARG_NONE }, { "un9b?", ARG_NONE, ARG_NONE }, @@ -148,11 +109,11 @@ static const hcd62121_dasm hcd62121_ops[256] = /* 0xa0 */ { "jmpzh", ARG_A16, ARG_NONE }, { "jmpzl", ARG_A16, ARG_NONE }, { "jmpc", ARG_A16, ARG_NONE }, { "jmpz", ARG_A16, ARG_NONE }, - { "jmpzc", ARG_A16, ARG_NONE }, { "jmpcl", ARG_A16, ARG_NONE }, + { "jmpnzh", ARG_A16, ARG_NONE }, { "jmpnzl", ARG_A16, ARG_NONE }, { "jmpnc", ARG_A16, ARG_NONE }, { "jmpnz", ARG_A16, ARG_NONE }, { "callzh", ARG_A16, ARG_NONE }, { "callzl", ARG_A16, ARG_NONE }, { "callc", ARG_A16, ARG_NONE }, { "callz", ARG_A16, ARG_NONE }, - { "callzc", ARG_A16, ARG_NONE }, { "callcl", ARG_A16, ARG_NONE }, + { "callnzh", ARG_A16, ARG_NONE }, { "callnzl", ARG_A16, ARG_NONE }, { "callnc", ARG_A16, ARG_NONE }, { "callnz", ARG_A16, ARG_NONE }, /* 0xb0 */ @@ -161,9 +122,9 @@ static const hcd62121_dasm hcd62121_ops[256] = { "out", ARG_KHI, ARG_REG }, { "out", ARG_KHI, ARG_I8 }, { "out", ARG_KLO, ARG_REG }, { "out", ARG_KLO, ARG_I8 }, { "unB8?", ARG_NONE, ARG_NONE }, { "unB9?", ARG_I8, ARG_NONE }, - { "unBA?", ARG_NONE, ARG_NONE }, { "jmpcl?", ARG_A16, ARG_NONE }, + { "unBA?", ARG_NONE, ARG_NONE }, { "jmpcl", ARG_A16, ARG_NONE }, { "unBC?", ARG_I8, ARG_NONE }, { "unBD?", ARG_NONE, ARG_NONE }, - { "unBE?", ARG_NONE, ARG_NONE }, { "jmpncl?", ARG_A16, ARG_NONE }, + { "unBE?", ARG_NONE, ARG_NONE }, { "jmpncl", ARG_A16, ARG_NONE }, /* 0xc0 */ { "movb", ARG_REG, ARG_I8 }, { "movw", ARG_REG, ARG_I16 }, @@ -183,7 +144,7 @@ static const hcd62121_dasm hcd62121_ops[256] = { "movb", ARG_F, ARG_REG }, { "movb", ARG_F, ARG_I8 }, { "unDA?", ARG_NONE, ARG_NONE }, { "unDb?", ARG_NONE, ARG_NONE }, { "movb", ARG_DS, ARG_REG }, { "movb", ARG_DS, ARG_I8 }, - { "movw", ARG_LAR, ARG_REG }, { "movw?", ARG_LAR, ARG_I8 }, + { "movw", ARG_LAR, ARG_REG }, { "movb", ARG_LAR, ARG_I8 }, /* 0xe0 */ { "in0", ARG_REG, ARG_NONE }, { "movb", ARG_REG, ARG_OPT }, @@ -206,30 +167,34 @@ static const hcd62121_dasm hcd62121_ops[256] = { "unFE?", ARG_NONE, ARG_NONE }, { "nop", ARG_NONE, ARG_NONE } }; +u32 hcd62121_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(hcd62121) +offs_t hcd62121_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { u8 op; u8 op1; u8 op2; - u32 pos = 0; - const hcd62121_dasm *inst; + offs_t base_pc = pc; + const dasm *inst; - op = oprom[pos++]; + op = opcodes.r8(pc++); - inst = &hcd62121_ops[op]; + inst = &ops[op]; /* Special cases for shift and rotate instructions */ - if (inst->arg2 == ARG_RS || inst->arg2 == ARG_RS4) - util::stream_format(stream, "%c%c%c%c ", inst->str[0], inst->str[1], (oprom[pos] & 0x80) ? 'r' : 'l', inst->str[3]); + if (inst->arg2 == ARG_S4 || inst->arg2 == ARG_S8) + util::stream_format(stream, "%c%c%c%c ", inst->str[0], inst->str[1], (opcodes.r8(pc) & 0x80) ? 'r' : 'l', inst->str[3]); else util::stream_format(stream, "%-8s", inst->str); switch(inst->arg1) { case ARG_REGREG: - op1 = oprom[pos++]; - op2 = oprom[pos++]; + op1 = opcodes.r8(pc++); + op2 = opcodes.r8(pc++); if (op1 & 0x80) { util::stream_format(stream, "r%02x,0x%02x", op1 & 0x7f, op2); @@ -243,12 +208,12 @@ CPU_DISASSEMBLE(hcd62121) } break; case ARG_REG: - util::stream_format(stream, "r%02x", oprom[pos++] & 0x7f); + util::stream_format(stream, "r%02x", opcodes.r8(pc++) & 0x7f); break; case ARG_IRGREG: /* bit 6 = direction. 0 - regular, 1 - reverse */ - op1 = oprom[pos++]; - op2 = oprom[pos++]; + op1 = opcodes.r8(pc++); + op2 = opcodes.r8(pc++); if (op1 & 0x80) { util::stream_format(stream, "(r%02x),0x%02x", 0x40 | (op1 & 0x3f), op2); @@ -263,7 +228,7 @@ CPU_DISASSEMBLE(hcd62121) break; case ARG_IRG: /* bit 6 = direction. 0 - regular, 1 - reverse */ - op1 = oprom[pos++]; + op1 = opcodes.r8(pc++); util::stream_format(stream, "(r%02x%s)", 0x40 | (op1 & 0x3f), (op1 & 0x40) ? ".r" : ""); break; case ARG_F: @@ -285,47 +250,55 @@ CPU_DISASSEMBLE(hcd62121) util::stream_format(stream, "SP"); break; case ARG_I8: - util::stream_format(stream, "0x%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); break; case ARG_I16: case ARG_A16: - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_I64: - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_I80: - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_A24: - util::stream_format(stream, "0x%02x:", oprom[pos++]); - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, "0x%02x:", opcodes.r8(pc++)); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_ILR: - op1 = oprom[pos++]; - op2 = oprom[pos++]; + op1 = opcodes.r8(pc++); + op2 = opcodes.r8(pc++); if ((op1 & 0x80) || (op2 & 0x80)) { - /* (lar),reg */ - util::stream_format(stream, "(%slar%s),r%02x", (op1 & 0x20) ? ((op1 & 0x40) ? "--" : "++") : "", (op1 & 0x20) ? "" : ((op1 & 0x40) ? "--" : "++"), op2 & 0x7f); + if (op1 & 0x80) + { + /* (lar),imm */ + util::stream_format(stream, "(%slar%s), %02x", (op1 & 0x20) ? ((op1 & 0x40) ? "--" : "++") : "", (op1 & 0x20) ? "" : ((op1 & 0x40) ? "--" : "++"), op2); + } + else + { + /* (lar),reg */ + util::stream_format(stream, "(%slar%s),r%02x", (op1 & 0x20) ? ((op1 & 0x40) ? "--" : "++") : "", (op1 & 0x20) ? "" : ((op1 & 0x40) ? "--" : "++"), op2 & 0x7f); + } } else { @@ -361,7 +334,7 @@ CPU_DISASSEMBLE(hcd62121) switch(inst->arg2) { case ARG_REG: - util::stream_format(stream, ",r%02x", oprom[pos++] & 0x7f); + util::stream_format(stream, ",r%02x", opcodes.r8(pc++) & 0x7f); break; case ARG_F: util::stream_format(stream, ",F"); @@ -382,43 +355,43 @@ CPU_DISASSEMBLE(hcd62121) util::stream_format(stream, ",SP"); break; case ARG_I8: - util::stream_format(stream, ",0x%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x", opcodes.r8(pc++)); break; case ARG_I16: - util::stream_format(stream, ",0x%02x", oprom[pos+1]); - util::stream_format(stream, "%02x", oprom[pos]); - pos += 2; + util::stream_format(stream, ",0x%02x", opcodes.r8(pc+1)); + util::stream_format(stream, "%02x", opcodes.r8(pc)); + pc += 2; break; case ARG_A16: - util::stream_format(stream, ",0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_I64: - util::stream_format(stream, ",0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_I80: - util::stream_format(stream, ",0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_A24: - util::stream_format(stream, ",0x%02x:", oprom[pos++]); - util::stream_format(stream, "0x%02x", oprom[pos++]); - util::stream_format(stream, "%02x", oprom[pos++]); + util::stream_format(stream, ",0x%02x:", opcodes.r8(pc++)); + util::stream_format(stream, "0x%02x", opcodes.r8(pc++)); + util::stream_format(stream, "%02x", opcodes.r8(pc++)); break; case ARG_ILR: /* Implemented by ARG_ILR section for arg1 */ @@ -441,13 +414,16 @@ CPU_DISASSEMBLE(hcd62121) case ARG_KI: util::stream_format(stream, ",KI"); break; - case ARG_RS4: + case ARG_S4: util::stream_format(stream, ",4"); break; + case ARG_S8: + util::stream_format(stream, ",8"); + break; default: break; } - return pos | DASMFLAG_SUPPORTED; + return (pc - base_pc) | SUPPORTED; } diff --git a/src/devices/cpu/hcd62121/hcd62121d.h b/src/devices/cpu/hcd62121/hcd62121d.h new file mode 100644 index 00000000000..c03d10dd410 --- /dev/null +++ b/src/devices/cpu/hcd62121/hcd62121d.h @@ -0,0 +1,62 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol + +#ifndef MAME_CPU_HCD62121_HCD62121D_H +#define MAME_CPU_HCD62121_HCD62121D_H + +#pragma once + +class hcd62121_disassembler : public util::disasm_interface +{ +public: + hcd62121_disassembler() = default; + virtual ~hcd62121_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct dasm + { + const char *str; + u8 arg1; + u8 arg2; + }; + + enum + { + ARG_NONE=0, /* no argument or unknown */ + ARG_REG, /* register */ + ARG_REGREG, /* register1, register2, or register2, register1 or register1, imm byte */ + ARG_IRG, /* register indirect */ + ARG_IRGREG, /* 2 register indirect */ + ARG_A16, /* 16bit address */ + ARG_A24, /* seg:address */ + ARG_F, /* flag register */ + ARG_CS, /* cs register */ + ARG_DS, /* ds register */ + ARG_SS, /* ss register */ + ARG_PC, /* program counter */ + ARG_SP, /* stack pointer */ + ARG_I8, /* immediate 8 bit value */ + ARG_I16, /* immediate 16 bit value */ + ARG_I64, /* immediate 64 bit value */ + ARG_I80, /* immediate 80 bit value */ + ARG_ILR, /* indirect last address register access */ + ARG_LAR, /* last address register */ + ARG_DSZ, /* dsize register? */ + ARG_OPT, /* OPTx (output) pins */ + ARG_PORT, /* PORTx (output) pins */ + ARG_TIM, /* timing related register? */ + ARG_KLO, /* KO1 - KO8 output lines */ + ARG_KHI, /* KO9 - KO14(?) output lines */ + ARG_KI, /* K input lines */ + ARG_S1, /* shift by 1 */ + ARG_S4, /* shift by 4 */ + ARG_S8, /* shift by 8 */ + }; + + static const dasm ops[256]; +}; + +#endif diff --git a/src/devices/cpu/hd61700/hd61700.cpp b/src/devices/cpu/hd61700/hd61700.cpp index cc27d85850f..1c6225a9d79 100644 --- a/src/devices/cpu/hd61700/hd61700.cpp +++ b/src/devices/cpu/hd61700/hd61700.cpp @@ -24,6 +24,7 @@ #include "emu.h" #include "hd61700.h" +#include "hd61700d.h" #include "debugger.h" @@ -296,18 +297,15 @@ void hd61700_cpu_device::state_string_export(const device_state_entry &entry, st //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t hd61700_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hd61700_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( hd61700 ); - return CPU_DISASSEMBLE_NAME(hd61700)(this, stream, pc, oprom, opram, options); + return new hd61700_disassembler; } - - //------------------------------------------------- // check_irqs - check if need interrupts //------------------------------------------------- @@ -2756,7 +2754,7 @@ inline uint8_t hd61700_cpu_device::read_op() if (m_pc <= INT_ROM) { - data = m_program->read_word(addr18<<1); + data = m_program->read_word(addr18); if (!(m_fetch_addr&1)) data = (data>>8) ; @@ -2764,9 +2762,9 @@ inline uint8_t hd61700_cpu_device::read_op() else { if (m_fetch_addr&1) - data = m_program->read_word((addr18+1)<<1); + data = m_program->read_word(addr18 + 1); else - data = m_program->read_word((addr18+0)<<1); + data = m_program->read_word(addr18 + 0); } m_fetch_addr += ((m_pc > INT_ROM) ? 2 : 1); @@ -2782,12 +2780,12 @@ inline uint8_t hd61700_cpu_device::read_op() inline uint8_t hd61700_cpu_device::mem_readbyte(uint8_t segment, uint16_t offset) { - return m_program->read_word(make_18bit_addr(segment, offset)<<1) & 0xff; + return m_program->read_word(make_18bit_addr(segment, offset)) & 0xff; } inline void hd61700_cpu_device::mem_writebyte(uint8_t segment, uint16_t offset, uint8_t data) { - m_program->write_word(make_18bit_addr(segment, offset)<<1, data); + m_program->write_word(make_18bit_addr(segment, offset), data); } inline uint32_t hd61700_cpu_device::make_18bit_addr(uint8_t segment, uint16_t offset) diff --git a/src/devices/cpu/hd61700/hd61700.h b/src/devices/cpu/hd61700/hd61700.h index dba81ba0205..12da10dece3 100644 --- a/src/devices/cpu/hd61700/hd61700.h +++ b/src/devices/cpu/hd61700/hd61700.h @@ -90,9 +90,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 16; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // interrupts bool check_irqs(); diff --git a/src/devices/cpu/hd61700/hd61700d.cpp b/src/devices/cpu/hd61700/hd61700d.cpp index 53a98be2145..44bbcd5b1a5 100644 --- a/src/devices/cpu/hd61700/hd61700d.cpp +++ b/src/devices/cpu/hd61700/hd61700d.cpp @@ -1,55 +1,15 @@ // license:BSD-3-Clause // copyright-holders:Sandro Ronco -#include "emu.h" -#include "debugger.h" -#include "hd61700.h" - -#define EXT_ROM (pc > 0x0c00) -#define INC_POS pos += (type+1) -#define POS (pos + type) -static const char *const reg_5b[4] = {"sx", "sy", "sz", "sz"}; -static const char *const reg_8b[8] = {"pe", "pd", "ib", "ua", "ia", "ie", "tm", "tm"}; -static const char *const reg_16b[8] = {"ix", "iy", "iz", "us", "ss", "ky", "ky", "ky"}; -static const char *const jp_cond[8] = {"z", "nc", "lz", "uz", "nz", "c", "nlz"}; - -enum -{ - OP_NULL=0, - OP_IM16, - OP_IM16A, - OP_IM3, - OP_IM5, - OP_IM7, - OP_IM8, - OP_IM8I, - OP_IM8_, - OP_IR_IM3, - OP_IR_IM8, - OP_IR_IM8_, - OP_JX_COND, - OP_MREG, - OP_MREG2, - OP_MR_SIR, - OP_MR_SIRI, - OP_REG16, - OP_REG16_, - OP_REG8, - OP_REG8_, - OP_REGIM8, - OP_RMSIM3, - OP_RSIR -}; +#include "emu.h" +#include "hd61700d.h" -struct hd61700_dasm -{ - const char *str; - uint8_t arg1; - uint8_t arg2; - bool optjr; -}; +const char *const hd61700_disassembler::reg_5b[4] = {"sx", "sy", "sz", "sz"}; +const char *const hd61700_disassembler::reg_8b[8] = {"pe", "pd", "ib", "ua", "ia", "ie", "tm", "tm"}; +const char *const hd61700_disassembler::reg_16b[8] = {"ix", "iy", "iz", "us", "ss", "ky", "ky", "ky"}; +const char *const hd61700_disassembler::jp_cond[8] = {"z", "nc", "lz", "uz", "nz", "c", "nlz"}; -static const hd61700_dasm hd61700_ops[256] = +const hd61700_disassembler::dasm hd61700_disassembler::ops[256] = { // 0x00 { "adc", OP_MREG, OP_MR_SIR, 1 }, { "sbc", OP_MREG, OP_MR_SIR, 1 }, @@ -212,13 +172,20 @@ static const hd61700_dasm hd61700_ops[256] = { "off", OP_NULL, OP_NULL, 0 }, { "trp", OP_NULL, OP_NULL, 0 }, }; +u8 hd61700_disassembler::opread(offs_t pc, offs_t pos, const data_buffer &opcodes) +{ + if(pc >= 0x0c00) + return opcodes.r16(pc + pos) & 0xff; + else + return pos & 1 ? opcodes.r16(pc + (pos >> 1)) & 0xff : opcodes.r16(pc + (pos >> 1)) >> 8; +} -static void dasm_im8(std::ostream &stream, uint16_t pc, int arg, const uint8_t *oprom, int &pos, int type) +void hd61700_disassembler::dasm_im8(std::ostream &stream, offs_t pc, int arg, offs_t &pos, const data_buffer &opcodes) { if (((arg>>5) & 0x03) == 0x03) { - INC_POS; - util::stream_format(stream, "0x%02x", oprom[POS] & 0x1f); + pos ++; + util::stream_format(stream, "0x%02x", opread(pc, pos, opcodes) & 0x1f); } else { @@ -227,7 +194,7 @@ static void dasm_im8(std::ostream &stream, uint16_t pc, int arg, const uint8_t * } -static void dasm_im8(std::ostream &stream, uint16_t pc, int arg, int arg1, const uint8_t *oprom, int &pos) +void hd61700_disassembler::dasm_im8(std::ostream &stream, offs_t pc, int arg, int arg1, offs_t &pos, const data_buffer &opcodes) { if (((arg>>5) & 0x03) == 0x03) { @@ -240,57 +207,55 @@ static void dasm_im8(std::ostream &stream, uint16_t pc, int arg, int arg1, const } -static void dasm_arg(std::ostream &stream, uint8_t op, uint16_t pc, int arg, const uint8_t *oprom, int &pos) +void hd61700_disassembler::dasm_arg(std::ostream &stream, uint8_t op, offs_t pc, int arg, offs_t &pos, const data_buffer &opcodes) { - int type = EXT_ROM; - switch( arg ) { case OP_MREG: case OP_MREG2: - util::stream_format( stream, "$%02u", oprom[POS] & 0x1f ); - if (arg == OP_MREG2) INC_POS; + util::stream_format( stream, "$%02u", opread(pc, pos, opcodes) & 0x1f ); + if (arg == OP_MREG2) pos ++; break; case OP_RSIR: - util::stream_format( stream, "%s", reg_5b[(oprom[POS]>>5) & 0x03] ); + util::stream_format( stream, "%s", reg_5b[(opread(pc, pos, opcodes)>>5) & 0x03] ); break; case OP_REG8: case OP_REG8_: - util::stream_format( stream, "%s", reg_8b[(BIT(op,0)<<2) + ((oprom[POS]>>5&3))]); - if (arg == OP_REG8_) INC_POS; + util::stream_format( stream, "%s", reg_8b[(BIT(op,0)<<2) + ((opread(pc, pos, opcodes)>>5&3))]); + if (arg == OP_REG8_) pos ++; break; case OP_MR_SIR: - dasm_im8(stream, pc, oprom[POS], oprom, pos, type); - INC_POS; + dasm_im8(stream, pc, opread(pc, pos, opcodes), pos, opcodes); + pos ++; break; case OP_IR_IM8: case OP_IR_IM8_: - util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (oprom[POS]&0x80) ? "-": "+"); - dasm_im8(stream, pc, oprom[POS], oprom, pos, type); + util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (opread(pc, pos, opcodes)&0x80) ? "-": "+"); + dasm_im8(stream, pc, opread(pc, pos, opcodes), pos, opcodes); util::stream_format( stream, ")"); - if (arg == OP_IR_IM8_) INC_POS; + if (arg == OP_IR_IM8_) pos ++; break; case OP_IM8_: - INC_POS; + pos ++; case OP_IM8: - util::stream_format( stream, "0x%02x", oprom[POS] ); - INC_POS; + util::stream_format( stream, "0x%02x", opread(pc, pos, opcodes) ); + pos ++; break; case OP_IM8I: - util::stream_format( stream, "(0x%02x)", oprom[POS] ); - INC_POS; + util::stream_format( stream, "(0x%02x)", opread(pc, pos, opcodes) ); + pos ++; break; case OP_REGIM8: - util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (oprom[POS]&0x80) ? "-": "+"); - util::stream_format( stream, "%x)", oprom[POS] & 0x1f); - INC_POS; + util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (opread(pc, pos, opcodes)&0x80) ? "-": "+"); + util::stream_format( stream, "%x)", opread(pc, pos, opcodes) & 0x1f); + pos ++; break; case OP_JX_COND: @@ -300,67 +265,67 @@ static void dasm_arg(std::ostream &stream, uint8_t op, uint16_t pc, int arg, con case OP_RMSIM3: { - uint8_t tmp = oprom[POS]; - INC_POS; - dasm_im8(stream, pc, tmp, oprom[POS], oprom, pos); + uint8_t tmp = opread(pc, pos, opcodes); + pos ++; + dasm_im8(stream, pc, tmp, opread(pc, pos, opcodes), pos, opcodes); util::stream_format( stream, ", 0x%02x", ((tmp>>5)&7)+1); - INC_POS; + pos ++; } break; case OP_IR_IM3: { - uint8_t tmp = oprom[POS]; - INC_POS; + uint8_t tmp = opread(pc, pos, opcodes); + pos ++; util::stream_format( stream, "(%s%s", (op&1) ? "iz": "ix", (tmp&0x80) ? "-": "+"); - dasm_im8(stream, pc, tmp, oprom[POS], oprom, pos); - util::stream_format( stream, "), 0x%02x", ((oprom[POS]>>5)&7)+1 ); - INC_POS; + dasm_im8(stream, pc, tmp, opread(pc, pos, opcodes), pos, opcodes); + util::stream_format( stream, "), 0x%02x", ((opread(pc, pos, opcodes)>>5)&7)+1 ); + pos ++; } break; case OP_IM3: - util::stream_format( stream, "0x%02x", ((oprom[POS]>>5)&7)+1 ); - INC_POS; + util::stream_format( stream, "0x%02x", ((opread(pc, pos, opcodes)>>5)&7)+1 ); + pos ++; break; case OP_MR_SIRI: util::stream_format( stream, "("); - dasm_im8(stream, pc, oprom[POS], oprom, pos, type); + dasm_im8(stream, pc, opread(pc, pos, opcodes), pos, opcodes); util::stream_format( stream, ")"); - INC_POS; + pos ++; break; case OP_IM7: { - int tmp = oprom[POS]; + int tmp = opread(pc, pos, opcodes); if (tmp&0x80) tmp = 0x80 - tmp; - util::stream_format( stream, "0x%04x", (pc + tmp + EXT_ROM) & 0xffff ); - INC_POS; + util::stream_format( stream, "0x%04x", (pc + tmp + (pc >= 0x0c00)) & 0xffff ); + pos ++; } break; case OP_IM5: - util::stream_format( stream, "0x%02x", oprom[POS]&0x1f ); - INC_POS; + util::stream_format( stream, "0x%02x", opread(pc, pos, opcodes)&0x1f ); + pos ++; break; case OP_REG16: case OP_REG16_: - util::stream_format(stream, "%s", reg_16b[(BIT(op,0)<<2) + ((oprom[POS]>>5&3))]); - if (arg == OP_REG16_) INC_POS; + util::stream_format(stream, "%s", reg_16b[(BIT(op,0)<<2) + ((opread(pc, pos, opcodes)>>5&3))]); + if (arg == OP_REG16_) pos ++; break; case OP_IM16: case OP_IM16A: { - uint8_t tmp1 = oprom[POS]; - INC_POS; - if (!EXT_ROM && arg == OP_IM16A) INC_POS; - uint8_t tmp2 = oprom[POS]; + uint8_t tmp1 = opread(pc, pos, opcodes); + pos ++; + if (pc < 0x0c00 && arg == OP_IM16A) pos ++; + uint8_t tmp2 = opread(pc, pos, opcodes); util::stream_format(stream, "0x%04x", ((tmp2<<8) | tmp1)); - INC_POS; + pos ++; } break; @@ -369,7 +334,7 @@ static void dasm_arg(std::ostream &stream, uint8_t op, uint16_t pc, int arg, con } } -uint32_t get_dasmflags(uint8_t op) +uint32_t hd61700_disassembler::get_dasmflags(uint8_t op) { switch (op) { @@ -381,55 +346,61 @@ uint32_t get_dasmflags(uint8_t op) case 0xb4: case 0xb5: case 0xb6: case 0xb7: //jr case 0xde: //jp case 0xdf: //jp - return DASMFLAG_STEP_OVER; + return STEP_OVER; case 0xf0: case 0xf1: case 0xf2: case 0xf3: //rtn case 0xf4: case 0xf5: case 0xf6: case 0xf7: //rtn case 0xfd: //rtni - return DASMFLAG_STEP_OUT; + return STEP_OUT; } return 0; } +u32 hd61700_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(hd61700) +offs_t hd61700_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const hd61700_dasm *inst; + const dasm *inst; uint32_t dasmflags; uint8_t op, op1; - int pos = 0, type = EXT_ROM; + offs_t pos = 0; + int type = pc >= 0x0c00; - op = oprom[POS]; - INC_POS; + op = opread(pc, pos, opcodes); + pos++; dasmflags = get_dasmflags(op); - op1 = oprom[POS]; + op1 = opread(pc, pos, opcodes); + pos++; - inst = &hd61700_ops[op]; + inst = &ops[op]; util::stream_format(stream, "%-8s", inst->str); //dasm first arg - dasm_arg(stream, op, pc, inst->arg1, oprom, pos); + dasm_arg(stream, op, pc, inst->arg1, pos, opcodes); //if present dasm second arg if (inst->arg2 != OP_NULL) { util::stream_format(stream, ", "); - dasm_arg(stream, op, pc, inst->arg2, oprom, pos); + dasm_arg(stream, op, pc, inst->arg2, pos, opcodes); } //if required add the optional jr if (inst->optjr == true && BIT(op1, 7)) { util::stream_format(stream, ", jr "); - dasm_arg(stream, op, pc+1, OP_IM7, oprom, pos); + dasm_arg(stream, op, pc+1, OP_IM7, pos, opcodes); - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; } - if (pos&1) INC_POS; + if (pos&1) pos += type+1; - return (pos>>1) | dasmflags | DASMFLAG_SUPPORTED; + return (pos>>1) | dasmflags | SUPPORTED; } diff --git a/src/devices/cpu/hd61700/hd61700d.h b/src/devices/cpu/hd61700/hd61700d.h new file mode 100644 index 00000000000..f951bf540c8 --- /dev/null +++ b/src/devices/cpu/hd61700/hd61700d.h @@ -0,0 +1,70 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco + + +#ifndef MAME_CPU_HD61700_HD61700D_H +#define MAME_CPU_HD61700_HD61700D_H + +#pragma once + +class hd61700_disassembler : public util::disasm_interface +{ +public: + hd61700_disassembler() = default; + virtual ~hd61700_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct dasm + { + const char *str; + uint8_t arg1; + uint8_t arg2; + bool optjr; + }; + + enum + { + OP_NULL=0, + OP_IM16, + OP_IM16A, + OP_IM3, + OP_IM5, + OP_IM7, + OP_IM8, + OP_IM8I, + OP_IM8_, + OP_IR_IM3, + OP_IR_IM8, + OP_IR_IM8_, + OP_JX_COND, + OP_MREG, + OP_MREG2, + OP_MR_SIR, + OP_MR_SIRI, + OP_REG16, + OP_REG16_, + OP_REG8, + OP_REG8_, + OP_REGIM8, + OP_RMSIM3, + OP_RSIR + }; + + static const char *const reg_5b[4]; + static const char *const reg_8b[8]; + static const char *const reg_16b[8]; + static const char *const jp_cond[8]; + + static const dasm ops[256]; + + u8 opread(offs_t pc, offs_t pos, const data_buffer &opcodes); + void dasm_im8(std::ostream &stream, offs_t pc, int arg, offs_t &pos, const data_buffer &opcodes); + void dasm_im8(std::ostream &stream, offs_t pc, int arg, int arg1, offs_t &pos, const data_buffer &opcodes); + void dasm_arg(std::ostream &stream, uint8_t op, offs_t pc, int arg, offs_t &pos, const data_buffer &opcodes); + uint32_t get_dasmflags(uint8_t op); +}; + +#endif diff --git a/src/devices/cpu/hmcs40/hmcs40.cpp b/src/devices/cpu/hmcs40/hmcs40.cpp index 2bc1860917c..a80c067aaeb 100644 --- a/src/devices/cpu/hmcs40/hmcs40.cpp +++ b/src/devices/cpu/hmcs40/hmcs40.cpp @@ -14,6 +14,7 @@ #include "emu.h" #include "hmcs40.h" #include "debugger.h" +#include "hmcs40d.h" #define IS_PMOS 0 #define IS_CMOS ~0 @@ -173,14 +174,12 @@ void hmcs40_cpu_device::state_string_export(const device_state_entry &entry, std } } -offs_t hmcs40_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *hmcs40_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(hmcs40); - return CPU_DISASSEMBLE_NAME(hmcs40)(this, stream, pc, oprom, opram, options); + return new hmcs40_disassembler; } - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- @@ -620,7 +619,7 @@ void hmcs40_cpu_device::execute_run() // fetch next opcode debugger_instruction_hook(this, m_pc); m_icount--; - m_op = m_program->read_word(m_pc << 1) & 0x3ff; + m_op = m_program->read_word(m_pc) & 0x3ff; m_i = BITSWAP8(m_op,7,6,5,4,0,1,2,3) & 0xf; // reversed bit-order for 4-bit immediate param (except for XAMR) increment_pc(); diff --git a/src/devices/cpu/hmcs40/hmcs40.h b/src/devices/cpu/hmcs40/hmcs40.h index 33e439fc1f5..ca5f238ad9a 100644 --- a/src/devices/cpu/hmcs40/hmcs40.h +++ b/src/devices/cpu/hmcs40/hmcs40.h @@ -158,9 +158,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 2; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; address_space_config m_program_config; diff --git a/src/devices/cpu/hmcs40/hmcs40d.cpp b/src/devices/cpu/hmcs40/hmcs40d.cpp index 7074bf5283a..48ae33ccfaa 100644 --- a/src/devices/cpu/hmcs40/hmcs40d.cpp +++ b/src/devices/cpu/hmcs40/hmcs40d.cpp @@ -9,27 +9,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "hmcs40.h" +#include "hmcs40d.h" - -enum e_mnemonics -{ - mILL, - mLAB, mLBA, mLAY, mLASPX, mLASPY, mXAMR, - mLXA, mLYA, mLXI, mLYI, mIY, mDY, mAYY, mSYY, mXSP, - mLAM, mLBM, mXMA, mXMB, mLMAIY, mLMADY, - mLMIIY, mLAI, mLBI, - mAI, mIB, mDB, mAMC, mSMC, mAM, mDAA, mDAS, mNEGA, mCOMB, mSEC, mREC, mTC, mROTL, mROTR, mOR, - mMNEI, mYNEI, mANEM, mBNEM, mALEI, mALEM, mBLEM, - mSEM, mREM, mTM, - mBR, mCAL, mLPU, mTBR, mRTN, - mSEIE, mSEIF0, mSEIF1, mSETF, mSECF, mREIE, mREIF0, mREIF1, mRETF, mRECF, mTI0, mTI1, mTIF0, mTIF1, mTTF, mLTI, mLTA, mLAT, mRTNI, - mSED, mRED, mTD, mSEDD, mREDD, mLAR, mLBR, mLRA, mLRB, mP, - mNOP -}; - -static const char *const s_mnemonics[] = +const char *const hmcs40_disassembler::s_mnemonics[] = { "?", "LAB", "LBA", "LAY", "LASPX", "LASPY", "XAMR", @@ -46,7 +28,7 @@ static const char *const s_mnemonics[] = }; // number of bits per opcode parameter, 99 means (XY) parameter, negative means reversed bit-order -static const s8 s_bits[] = +const s8 hmcs40_disassembler::s_bits[] = { 0, 0, 0, 0, 0, 0, 4, @@ -62,10 +44,7 @@ static const s8 s_bits[] = 0 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 hmcs40_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, @@ -75,14 +54,13 @@ static const u32 s_flags[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, _OVER, 0, 0, _OUT, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _OUT, + 0, STEP_OVER, 0, 0, STEP_OUT, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -static const u8 hmcs40_mnemonic[0x400] = +const u8 hmcs40_disassembler::hmcs40_mnemonic[0x400] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0x000 */ @@ -175,9 +153,9 @@ static const u8 hmcs40_mnemonic[0x400] = -CPU_DISASSEMBLE(hmcs40) +offs_t hmcs40_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u16 op = (oprom[0] | oprom[1] << 8) & 0x3ff; + u16 op = opcodes.r16(pc) & 0x3ff; u8 instr = hmcs40_mnemonic[op]; s8 bits = s_bits[instr]; @@ -217,5 +195,43 @@ CPU_DISASSEMBLE(hmcs40) } } - return 1 | s_flags[instr] | DASMFLAG_SUPPORTED; + return 1 | s_flags[instr] | SUPPORTED; +} + +u32 hmcs40_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 hmcs40_disassembler::interface_flags() const +{ + return NONLINEAR_PC | PAGED; +} + +u32 hmcs40_disassembler::page_address_bits() const +{ + return 6; } + +offs_t hmcs40_disassembler::pc_linear_to_real(offs_t pc) const +{ + static const u8 l2r[64] = { + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x3e, 0x3d, 0x3b, 0x37, 0x2f, 0x1e, 0x3c, 0x39, 0x33, + 0x27, 0x0e, 0x1d, 0x3a, 0x35, 0x2b, 0x16, 0x2c, 0x18, 0x30, 0x21, 0x02, 0x05, 0x0b, 0x17, 0x2e, + 0x1c, 0x38, 0x31, 0x23, 0x06, 0x0d, 0x1b, 0x36, 0x2d, 0x1a, 0x34, 0x29, 0x12, 0x24, 0x08, 0x11, + 0x22, 0x04, 0x09, 0x13, 0x26, 0x0c, 0x19, 0x32, 0x25, 0x0a, 0x15, 0x2a, 0x14, 0x28, 0x10, 0x20, + }; + return (pc & ~0x3f) | l2r[pc & 0x3f]; +} + +offs_t hmcs40_disassembler::pc_real_to_linear(offs_t pc) const +{ + static const u8 r2l[64] = { + 0x00, 0x01, 0x1b, 0x02, 0x31, 0x1c, 0x24, 0x03, 0x2e, 0x32, 0x39, 0x1d, 0x35, 0x25, 0x11, 0x04, + 0x3e, 0x2f, 0x2c, 0x33, 0x3c, 0x3a, 0x16, 0x1e, 0x18, 0x36, 0x29, 0x26, 0x20, 0x12, 0x0c, 0x05, + 0x3f, 0x1a, 0x30, 0x23, 0x2d, 0x38, 0x34, 0x10, 0x3d, 0x2b, 0x3b, 0x15, 0x17, 0x28, 0x1f, 0x0b, + 0x19, 0x22, 0x37, 0x0f, 0x2a, 0x14, 0x27, 0x0a, 0x21, 0x0e, 0x13, 0x09, 0x0d, 0x08, 0x07, 0x06, + }; + return (pc & ~0x3f) | r2l[pc & 0x3f]; +} + diff --git a/src/devices/cpu/hmcs40/hmcs40d.h b/src/devices/cpu/hmcs40/hmcs40d.h new file mode 100644 index 00000000000..04f534bdc4c --- /dev/null +++ b/src/devices/cpu/hmcs40/hmcs40d.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Hitachi HMCS40 MCU family disassembler + +*/ + +#ifndef MAME_CPU_HMCS40_HMCS40D_H +#define MAME_CPU_HMCS40_HMCS40D_H + +#pragma once + +class hmcs40_disassembler : public util::disasm_interface +{ +public: + hmcs40_disassembler() = default; + virtual ~hmcs40_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual offs_t pc_linear_to_real(offs_t pc) const override; + virtual offs_t pc_real_to_linear(offs_t pc) const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + mILL, + mLAB, mLBA, mLAY, mLASPX, mLASPY, mXAMR, + mLXA, mLYA, mLXI, mLYI, mIY, mDY, mAYY, mSYY, mXSP, + mLAM, mLBM, mXMA, mXMB, mLMAIY, mLMADY, + mLMIIY, mLAI, mLBI, + mAI, mIB, mDB, mAMC, mSMC, mAM, mDAA, mDAS, mNEGA, mCOMB, mSEC, mREC, mTC, mROTL, mROTR, mOR, + mMNEI, mYNEI, mANEM, mBNEM, mALEI, mALEM, mBLEM, + mSEM, mREM, mTM, + mBR, mCAL, mLPU, mTBR, mRTN, + mSEIE, mSEIF0, mSEIF1, mSETF, mSECF, mREIE, mREIF0, mREIF1, mRETF, mRECF, mTI0, mTI1, mTIF0, mTIF1, mTTF, mLTI, mLTA, mLAT, mRTNI, + mSED, mRED, mTD, mSEDD, mREDD, mLAR, mLBR, mLRA, mLRB, mP, + mNOP + }; + + static const char *const s_mnemonics[]; + static const s8 s_bits[]; + static const u32 s_flags[]; + static const u8 hmcs40_mnemonic[0x400]; +}; + +#endif diff --git a/src/devices/cpu/hmcs40/hmcs40op.cpp b/src/devices/cpu/hmcs40/hmcs40op.cpp index 2c28d4cb54e..2078d5e765b 100644 --- a/src/devices/cpu/hmcs40/hmcs40op.cpp +++ b/src/devices/cpu/hmcs40/hmcs40op.cpp @@ -663,7 +663,7 @@ void hmcs40_cpu_device::op_p() // P p: Pattern Generation m_icount--; u16 address = m_a | m_b << 4 | m_c << 8 | (m_op & 7) << 9 | (m_pc & ~0x3f); - u16 o = m_program->read_word((address & m_prgmask) << 1); + u16 o = m_program->read_word(address & m_prgmask); // destination is determined by the 2 highest bits if (o & 0x100) diff --git a/src/devices/cpu/hphybrid/hphybrid.cpp b/src/devices/cpu/hphybrid/hphybrid.cpp index 6eb3f4b83d6..9e8457b255d 100644 --- a/src/devices/cpu/hphybrid/hphybrid.cpp +++ b/src/devices/cpu/hphybrid/hphybrid.cpp @@ -33,6 +33,7 @@ #include "emu.h" #include "hphybrid.h" +#include "hphybrid_dasm.h" #include "debugger.h" #include "hphybrid_defs.h" @@ -201,7 +202,7 @@ void hp_hybrid_cpu_device::device_start() } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_io = &space(AS_IO); save_item(NAME(m_reg_A)); @@ -296,808 +297,809 @@ uint16_t hp_hybrid_cpu_device::execute_one(uint16_t opcode) */ uint16_t hp_hybrid_cpu_device::execute_one_sub(uint16_t opcode) { - uint32_t ea; - uint16_t tmp; - - switch (opcode & 0x7800) { - case 0x0000: - // LDA - m_icount -= 13; - m_reg_A = RM(get_ea(opcode)); - break; - - case 0x0800: - // LDB - m_icount -= 13; - m_reg_B = RM(get_ea(opcode)); - break; - - case 0x1000: - // CPA - m_icount -= 16; - if (m_reg_A != RM(get_ea(opcode))) { - // Skip next instruction - return m_reg_P + 2; - } - break; - - case 0x1800: - // CPB - m_icount -= 16; - if (m_reg_B != RM(get_ea(opcode))) { - // Skip next instruction - return m_reg_P + 2; - } - break; - - case 0x2000: - // ADA - m_icount -= 13; - do_add(m_reg_A , RM(get_ea(opcode))); - break; - - case 0x2800: - // ADB - m_icount -= 13; - do_add(m_reg_B , RM(get_ea(opcode))); - break; - - case 0x3000: - // STA - m_icount -= 13; - WM(get_ea(opcode) , m_reg_A); - break; - - case 0x3800: - // STB - m_icount -= 13; - WM(get_ea(opcode) , m_reg_B); - break; - - case 0x4000: - // JSM - m_icount -= 17; - WM(AEC_CASE_C , ++m_reg_R , m_reg_P); - return remove_mae(get_ea(opcode)); - - case 0x4800: - // ISZ - m_icount -= 19; - ea = get_ea(opcode); - tmp = RM(ea) + 1; - WM(ea , tmp); - if (tmp == 0) { - // Skip next instruction - return m_reg_P + 2; - } - break; - - case 0x5000: - // AND - m_icount -= 13; - m_reg_A &= RM(get_ea(opcode)); - break; - - case 0x5800: - // DSZ - m_icount -= 19; - ea = get_ea(opcode); - tmp = RM(ea) - 1; - WM(ea , tmp); - if (tmp == 0) { - // Skip next instruction - return m_reg_P + 2; - } - break; - - case 0x6000: - // IOR - m_icount -= 13; - m_reg_A |= RM(get_ea(opcode)); - break; - - case 0x6800: - // JMP - m_icount -= 8; - return remove_mae(get_ea(opcode)); + uint32_t ea; + uint16_t tmp; + + switch (opcode & 0x7800) { + case 0x0000: + // LDA + m_icount -= 13; + m_reg_A = RM(get_ea(opcode)); + break; + + case 0x0800: + // LDB + m_icount -= 13; + m_reg_B = RM(get_ea(opcode)); + break; + + case 0x1000: + // CPA + m_icount -= 16; + if (m_reg_A != RM(get_ea(opcode))) { + // Skip next instruction + return m_reg_P + 2; + } + break; + + case 0x1800: + // CPB + m_icount -= 16; + if (m_reg_B != RM(get_ea(opcode))) { + // Skip next instruction + return m_reg_P + 2; + } + break; + + case 0x2000: + // ADA + m_icount -= 13; + do_add(m_reg_A , RM(get_ea(opcode))); + break; + + case 0x2800: + // ADB + m_icount -= 13; + do_add(m_reg_B , RM(get_ea(opcode))); + break; + + case 0x3000: + // STA + m_icount -= 13; + WM(get_ea(opcode) , m_reg_A); + break; + + case 0x3800: + // STB + m_icount -= 13; + WM(get_ea(opcode) , m_reg_B); + break; + + case 0x4000: + // JSM + m_icount -= 17; + WM(AEC_CASE_C , ++m_reg_R , m_reg_P); + return remove_mae(get_ea(opcode)); + + case 0x4800: + // ISZ + m_icount -= 19; + ea = get_ea(opcode); + tmp = RM(ea) + 1; + WM(ea , tmp); + if (tmp == 0) { + // Skip next instruction + return m_reg_P + 2; + } + break; + + case 0x5000: + // AND + m_icount -= 13; + m_reg_A &= RM(get_ea(opcode)); + break; + + case 0x5800: + // DSZ + m_icount -= 19; + ea = get_ea(opcode); + tmp = RM(ea) - 1; + WM(ea , tmp); + if (tmp == 0) { + // Skip next instruction + return m_reg_P + 2; + } + break; + + case 0x6000: + // IOR + m_icount -= 13; + m_reg_A |= RM(get_ea(opcode)); + break; + + case 0x6800: + // JMP + m_icount -= 8; + return remove_mae(get_ea(opcode)); + + default: + switch (opcode & 0xfec0) { + case 0x7400: + // RZA + // SZA + m_icount -= 14; + return get_skip_addr(opcode , m_reg_A == 0); + + case 0x7440: + // RIA + // SIA + m_icount -= 14; + return get_skip_addr(opcode , m_reg_A++ == 0); + + case 0x7480: + // SFS + // SFC + m_icount -= 14; + return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_FLG_BIT)); + + case 0x7C00: + // RZB + // SZB + m_icount -= 14; + return get_skip_addr(opcode , m_reg_B == 0); + + case 0x7C40: + // RIB + // SIB + m_icount -= 14; + return get_skip_addr(opcode , m_reg_B++ == 0); + + case 0x7c80: + // SSS + // SSC + m_icount -= 14; + return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_STS_BIT)); + + case 0x7cc0: + // SHS + // SHC + m_icount -= 14; + return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_HALT_BIT)); + + default: + switch (opcode & 0xfe00) { + case 0x7600: + // SLA + // RLA + m_icount -= 14; + return get_skip_addr_sc(opcode , m_reg_A , 0); + + case 0x7e00: + // SLB + // RLB + m_icount -= 14; + return get_skip_addr_sc(opcode , m_reg_B , 0); + + case 0xf400: + // SAP + // SAM + m_icount -= 14; + return get_skip_addr_sc(opcode , m_reg_A , 15); + + case 0xf600: + // SOC + // SOS + m_icount -= 14; + return get_skip_addr_sc(opcode , m_flags , HPHYBRID_O_BIT); + + case 0xfc00: + // SBP + // SBM + m_icount -= 14; + return get_skip_addr_sc(opcode , m_reg_B , 15); + + case 0xfe00: + // SEC + // SES + m_icount -= 14; + return get_skip_addr_sc(opcode , m_flags , HPHYBRID_C_BIT); + + default: + switch (opcode & 0xfff0) { + case 0xf100: + // AAR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + // A shift by 16 positions is equivalent to a shift by 15 + tmp = tmp > 15 ? 15 : tmp; + m_reg_A = ((m_reg_A ^ 0x8000) >> tmp) - (0x8000 >> tmp); + break; + + case 0xf900: + // ABR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + tmp = tmp > 15 ? 15 : tmp; + m_reg_B = ((m_reg_B ^ 0x8000) >> tmp) - (0x8000 >> tmp); + break; + + case 0xf140: + // SAR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_A >>= tmp; + break; + + case 0xf940: + // SBR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_B >>= tmp; + break; + + case 0xf180: + // SAL + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_A <<= tmp; + break; + + case 0xf980: + // SBL + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_B <<= tmp; + break; + + case 0xf1c0: + // RAR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_A = (m_reg_A >> tmp) | (m_reg_A << (16 - tmp)); + break; + + case 0xf9c0: + // RBR + tmp = (opcode & 0xf) + 1; + m_icount -= (9 + tmp); + m_reg_B = (m_reg_B >> tmp) | (m_reg_B << (16 - tmp)); + break; default: - switch (opcode & 0xfec0) { - case 0x7400: - // RZA - // SZA - m_icount -= 14; - return get_skip_addr(opcode , m_reg_A == 0); - - case 0x7440: - // RIA - // SIA - m_icount -= 14; - return get_skip_addr(opcode , m_reg_A++ == 0); - - case 0x7480: - // SFS - // SFC - m_icount -= 14; - return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_FLG_BIT)); - - case 0x7C00: - // RZB - // SZB - m_icount -= 14; - return get_skip_addr(opcode , m_reg_B == 0); - - case 0x7C40: - // RIB - // SIB - m_icount -= 14; - return get_skip_addr(opcode , m_reg_B++ == 0); - - case 0x7c80: - // SSS - // SSC - m_icount -= 14; - return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_STS_BIT)); - - case 0x7cc0: - // SHS - // SHC - m_icount -= 14; - return get_skip_addr(opcode , !BIT(m_flags , HPHYBRID_HALT_BIT)); - - default: - switch (opcode & 0xfe00) { - case 0x7600: - // SLA - // RLA - m_icount -= 14; - return get_skip_addr_sc(opcode , m_reg_A , 0); - - case 0x7e00: - // SLB - // RLB - m_icount -= 14; - return get_skip_addr_sc(opcode , m_reg_B , 0); - - case 0xf400: - // SAP - // SAM - m_icount -= 14; - return get_skip_addr_sc(opcode , m_reg_A , 15); - - case 0xf600: - // SOC - // SOS - m_icount -= 14; - return get_skip_addr_sc(opcode , m_flags , HPHYBRID_O_BIT); - - case 0xfc00: - // SBP - // SBM - m_icount -= 14; - return get_skip_addr_sc(opcode , m_reg_B , 15); - - case 0xfe00: - // SEC - // SES - m_icount -= 14; - return get_skip_addr_sc(opcode , m_flags , HPHYBRID_C_BIT); - - default: - switch (opcode & 0xfff0) { - case 0xf100: - // AAR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - // A shift by 16 positions is equivalent to a shift by 15 - tmp = tmp > 15 ? 15 : tmp; - m_reg_A = ((m_reg_A ^ 0x8000) >> tmp) - (0x8000 >> tmp); - break; - - case 0xf900: - // ABR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - tmp = tmp > 15 ? 15 : tmp; - m_reg_B = ((m_reg_B ^ 0x8000) >> tmp) - (0x8000 >> tmp); - break; - - case 0xf140: - // SAR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_A >>= tmp; - break; - - case 0xf940: - // SBR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_B >>= tmp; - break; - - case 0xf180: - // SAL - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_A <<= tmp; - break; - - case 0xf980: - // SBL - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_B <<= tmp; - break; - - case 0xf1c0: - // RAR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_A = (m_reg_A >> tmp) | (m_reg_A << (16 - tmp)); - break; - - case 0xf9c0: - // RBR - tmp = (opcode & 0xf) + 1; - m_icount -= (9 + tmp); - m_reg_B = (m_reg_B >> tmp) | (m_reg_B << (16 - tmp)); - break; - - default: - if ((opcode & 0xf760) == 0x7160) { - // Place/withdraw instructions - m_icount -= 23; - do_pw(opcode); - } else if ((opcode & 0xff80) == 0xf080) { - // RET - m_icount -= 16; - if (BIT(opcode , 6)) { - // Pop PA stack - if (BIT(m_flags , HPHYBRID_IRH_SVC_BIT)) { - BIT_CLR(m_flags , HPHYBRID_IRH_SVC_BIT); - memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); - m_pa_changed_func((uint8_t)CURRENT_PA); - } else if (BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { - BIT_CLR(m_flags , HPHYBRID_IRL_SVC_BIT); - memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); - m_pa_changed_func((uint8_t)CURRENT_PA); - } - tmp = RM(AEC_CASE_C , m_reg_R--) + (opcode & 0x1f); - BIT_CLR(m_flags, HPHYBRID_IM_BIT); - } else { - tmp = RM(AEC_CASE_C , m_reg_R--) + (opcode & 0x1f); - } - return BIT(opcode , 5) ? tmp - 0x20 : tmp; - } else { - switch (opcode) { - case 0x7100: - // SDO - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_DMADIR_BIT); - break; - - case 0x7108: - // SDI - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_DMADIR_BIT); - break; - - case 0x7110: - // EIR - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_INTEN_BIT); - break; - - case 0x7118: - // DIR - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_INTEN_BIT); - break; - - case 0x7120: - // DMA - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_DMAEN_BIT); - break; - - case 0x7138: - // DDR - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_DMAEN_BIT); - break; - - case 0x7140: - // DBL - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_DB_BIT); - break; - - case 0x7148: - // CBL - m_icount -= 12; - BIT_CLR(m_flags , HPHYBRID_CB_BIT); - break; - - case 0x7150: - // DBU - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_DB_BIT); - break; - - case 0x7158: - // CBU - m_icount -= 12; - BIT_SET(m_flags , HPHYBRID_CB_BIT); - break; - - case 0xf020: - // TCA - m_icount -= 9; - m_reg_A = ~m_reg_A; - do_add(m_reg_A , 1); - break; - - case 0xf060: - // CMA - m_icount -= 9; - m_reg_A = ~m_reg_A; - break; - - case 0xf820: - // TCB - m_icount -= 9; - m_reg_B = ~m_reg_B; - do_add(m_reg_B , 1); - break; - - case 0xf860: - // CMB - m_icount -= 9; - m_reg_B = ~m_reg_B; - break; - - default: - // Unrecognized instruction: pass it on for further processing (by EMC if present) - return execute_no_bpc_ioc(opcode); - } - } - } - } - } - } - - return m_reg_P + 1; + if ((opcode & 0xf760) == 0x7160) { + // Place/withdraw instructions + m_icount -= 23; + do_pw(opcode); + } else if ((opcode & 0xff80) == 0xf080) { + // RET + m_icount -= 16; + if (BIT(opcode , 6)) { + // Pop PA stack + if (BIT(m_flags , HPHYBRID_IRH_SVC_BIT)) { + BIT_CLR(m_flags , HPHYBRID_IRH_SVC_BIT); + memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); + m_pa_changed_func((uint8_t)CURRENT_PA); + } else if (BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { + BIT_CLR(m_flags , HPHYBRID_IRL_SVC_BIT); + memmove(&m_reg_PA[ 0 ] , &m_reg_PA[ 1 ] , HPHYBRID_INT_LVLS); + m_pa_changed_func((uint8_t)CURRENT_PA); + } + tmp = RM(AEC_CASE_C , m_reg_R--) + (opcode & 0x1f); + BIT_CLR(m_flags, HPHYBRID_IM_BIT); + } else { + tmp = RM(AEC_CASE_C , m_reg_R--) + (opcode & 0x1f); + } + return BIT(opcode , 5) ? tmp - 0x20 : tmp; + } else { + switch (opcode) { + case 0x7100: + // SDO + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_DMADIR_BIT); + break; + + case 0x7108: + // SDI + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_DMADIR_BIT); + break; + + case 0x7110: + // EIR + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_INTEN_BIT); + break; + + case 0x7118: + // DIR + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_INTEN_BIT); + break; + + case 0x7120: + // DMA + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_DMAEN_BIT); + break; + + case 0x7138: + // DDR + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_DMAEN_BIT); + break; + + case 0x7140: + // DBL + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_DB_BIT); + break; + + case 0x7148: + // CBL + m_icount -= 12; + BIT_CLR(m_flags , HPHYBRID_CB_BIT); + break; + + case 0x7150: + // DBU + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_DB_BIT); + break; + + case 0x7158: + // CBU + m_icount -= 12; + BIT_SET(m_flags , HPHYBRID_CB_BIT); + break; + + case 0xf020: + // TCA + m_icount -= 9; + m_reg_A = ~m_reg_A; + do_add(m_reg_A , 1); + break; + + case 0xf060: + // CMA + m_icount -= 9; + m_reg_A = ~m_reg_A; + break; + + case 0xf820: + // TCB + m_icount -= 9; + m_reg_B = ~m_reg_B; + do_add(m_reg_B , 1); + break; + + case 0xf860: + // CMB + m_icount -= 9; + m_reg_B = ~m_reg_B; + break; + + default: + // Unrecognized instruction: pass it on for further processing (by EMC if present) + return execute_no_bpc_ioc(opcode); + } + } + } + } + } + } + + return m_reg_P + 1; } void hp_hybrid_cpu_device::state_string_export(const device_state_entry &entry, std::string &str) const { if (entry.index() == STATE_GENFLAGS) { str = string_format("%s %s %c %c", - BIT(m_flags , HPHYBRID_DB_BIT) ? "Db":"..", - BIT(m_flags , HPHYBRID_CB_BIT) ? "Cb":"..", - BIT(m_flags , HPHYBRID_O_BIT) ? 'O':'.', - BIT(m_flags , HPHYBRID_C_BIT) ? 'E':'.'); + BIT(m_flags , HPHYBRID_DB_BIT) ? "Db":"..", + BIT(m_flags , HPHYBRID_CB_BIT) ? "Cb":"..", + BIT(m_flags , HPHYBRID_O_BIT) ? 'O':'.', + BIT(m_flags , HPHYBRID_C_BIT) ? 'E':'.'); } } -offs_t hp_hybrid_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hp_hybrid_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(hp_hybrid); - return CPU_DISASSEMBLE_NAME(hp_hybrid)(this, stream, pc, oprom, opram, options); + return new hp_hybrid_disassembler; } uint16_t hp_hybrid_cpu_device::remove_mae(uint32_t addr) { - return (uint16_t)(addr & 0xffff); + return (uint16_t)(addr & 0xffff); } uint16_t hp_hybrid_cpu_device::RM(aec_cases_t aec_case , uint16_t addr) { - return RM(add_mae(aec_case , addr)); + return RM(add_mae(aec_case , addr)); } uint16_t hp_hybrid_cpu_device::RM(uint32_t addr) { - uint16_t tmp; - uint16_t addr_wo_bsc = remove_mae(addr); + uint16_t tmp; + uint16_t addr_wo_bsc = remove_mae(addr); - if (addr_wo_bsc <= HP_REG_LAST_ADDR) { - // Any access to internal registers removes forcing of BSC 2x - m_forced_bsc_25 = false; + if (addr_wo_bsc <= HP_REG_LAST_ADDR) { + // Any access to internal registers removes forcing of BSC 2x + m_forced_bsc_25 = false; - // Memory mapped registers that are present in both 3001 & 3011 - switch (addr_wo_bsc) { - case HP_REG_A_ADDR: - return m_reg_A; + // Memory mapped registers that are present in both 3001 & 3011 + switch (addr_wo_bsc) { + case HP_REG_A_ADDR: + return m_reg_A; - case HP_REG_B_ADDR: - return m_reg_B; + case HP_REG_B_ADDR: + return m_reg_B; - case HP_REG_P_ADDR: - return m_reg_P; + case HP_REG_P_ADDR: + return m_reg_P; - case HP_REG_R_ADDR: - return m_reg_R; + case HP_REG_R_ADDR: + return m_reg_R; - case HP_REG_R4_ADDR: - case HP_REG_R5_ADDR: - case HP_REG_R6_ADDR: - case HP_REG_R7_ADDR: - return RIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR); + case HP_REG_R4_ADDR: + case HP_REG_R5_ADDR: + case HP_REG_R6_ADDR: + case HP_REG_R7_ADDR: + return RIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR); - case HP_REG_IV_ADDR: - return m_reg_IV; + case HP_REG_IV_ADDR: + return m_reg_IV; - case HP_REG_PA_ADDR: - return CURRENT_PA; + case HP_REG_PA_ADDR: + return CURRENT_PA; - case HP_REG_W_ADDR: - return m_reg_W; + case HP_REG_W_ADDR: + return m_reg_W; - case HP_REG_DMAPA_ADDR: - tmp = m_dmapa & HP_REG_PA_MASK; - if (BIT(m_flags , HPHYBRID_CB_BIT)) { - BIT_SET(tmp , 15); - } - if (BIT(m_flags , HPHYBRID_DB_BIT)) { - BIT_SET(tmp , 14); - } - return tmp; + case HP_REG_DMAPA_ADDR: + tmp = m_dmapa & HP_REG_PA_MASK; + if (BIT(m_flags , HPHYBRID_CB_BIT)) { + BIT_SET(tmp , 15); + } + if (BIT(m_flags , HPHYBRID_DB_BIT)) { + BIT_SET(tmp , 14); + } + return tmp; - case HP_REG_DMAMA_ADDR: - return m_dmama; + case HP_REG_DMAMA_ADDR: + return m_dmama; - case HP_REG_DMAC_ADDR: - return m_dmac; + case HP_REG_DMAC_ADDR: + return m_dmac; - case HP_REG_C_ADDR: - return m_reg_C; + case HP_REG_C_ADDR: + return m_reg_C; - case HP_REG_D_ADDR: - return m_reg_D; + case HP_REG_D_ADDR: + return m_reg_D; - default: - return read_non_common_reg(addr_wo_bsc); - } - } else { - return m_direct->read_word(addr << 1); + default: + return read_non_common_reg(addr_wo_bsc); } + } else { + return m_direct->read_word(addr << 1); + } } void hp_hybrid_cpu_device::WM(aec_cases_t aec_case , uint16_t addr , uint16_t v) { - WM(add_mae(aec_case , addr) , v); + WM(add_mae(aec_case , addr) , v); } void hp_hybrid_cpu_device::WM(uint32_t addr , uint16_t v) { - uint16_t addr_wo_bsc = remove_mae(addr); - - if (addr_wo_bsc <= HP_REG_LAST_ADDR) { - // Any access to internal registers removes forcing of BSC 2x - m_forced_bsc_25 = false; - - // Memory mapped registers - switch (addr_wo_bsc) { - case HP_REG_A_ADDR: - m_reg_A = v; - break; - - case HP_REG_B_ADDR: - m_reg_B = v; - break; - - case HP_REG_P_ADDR: - m_reg_P = v; - break; - - case HP_REG_R_ADDR: - m_reg_R = v; - break; - - case HP_REG_R4_ADDR: - case HP_REG_R5_ADDR: - case HP_REG_R6_ADDR: - case HP_REG_R7_ADDR: - WIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR , v); - break; - - case HP_REG_IV_ADDR: - m_reg_IV = v & HP_REG_IV_MASK; - break; - - case HP_REG_PA_ADDR: - CURRENT_PA = v & HP_REG_PA_MASK; - m_pa_changed_func((uint8_t)CURRENT_PA); - break; - - case HP_REG_W_ADDR: - m_reg_W = v; - break; - - case HP_REG_DMAPA_ADDR: - m_dmapa = v & HP_REG_PA_MASK; - break; - - case HP_REG_DMAMA_ADDR: - m_dmama = v; - break; - - case HP_REG_DMAC_ADDR: - m_dmac = v; - break; - - case HP_REG_C_ADDR: - m_reg_C = v; - break; - - case HP_REG_D_ADDR: - m_reg_D = v; - break; + uint16_t addr_wo_bsc = remove_mae(addr); - default: - write_non_common_reg(addr_wo_bsc , v); - break; - } - } else { - m_program->write_word(addr << 1 , v); + if (addr_wo_bsc <= HP_REG_LAST_ADDR) { + // Any access to internal registers removes forcing of BSC 2x + m_forced_bsc_25 = false; + + // Memory mapped registers + switch (addr_wo_bsc) { + case HP_REG_A_ADDR: + m_reg_A = v; + break; + + case HP_REG_B_ADDR: + m_reg_B = v; + break; + + case HP_REG_P_ADDR: + m_reg_P = v; + break; + + case HP_REG_R_ADDR: + m_reg_R = v; + break; + + case HP_REG_R4_ADDR: + case HP_REG_R5_ADDR: + case HP_REG_R6_ADDR: + case HP_REG_R7_ADDR: + WIO(CURRENT_PA , addr_wo_bsc - HP_REG_R4_ADDR , v); + break; + + case HP_REG_IV_ADDR: + m_reg_IV = v & HP_REG_IV_MASK; + break; + + case HP_REG_PA_ADDR: + CURRENT_PA = v & HP_REG_PA_MASK; + m_pa_changed_func((uint8_t)CURRENT_PA); + break; + + case HP_REG_W_ADDR: + m_reg_W = v; + break; + + case HP_REG_DMAPA_ADDR: + m_dmapa = v & HP_REG_PA_MASK; + break; + + case HP_REG_DMAMA_ADDR: + m_dmama = v; + break; + + case HP_REG_DMAC_ADDR: + m_dmac = v; + break; + + case HP_REG_C_ADDR: + m_reg_C = v; + break; + + case HP_REG_D_ADDR: + m_reg_D = v; + break; + + default: + write_non_common_reg(addr_wo_bsc , v); + break; } + } else { + m_program->write_word(addr , v); + } } uint16_t hp_hybrid_cpu_device::fetch(void) { - m_genpc = add_mae(AEC_CASE_A , m_reg_P); - return RM(m_genpc); + m_genpc = add_mae(AEC_CASE_A , m_reg_P); + return RM(m_genpc); } uint32_t hp_hybrid_cpu_device::get_ea(uint16_t opcode) { - uint16_t base; - uint16_t off; - aec_cases_t aec; - - if (BIT(opcode , 10)) { - // Current page - base = m_reg_P; - aec = AEC_CASE_A; - } else { - // Base page - base = 0; - aec = AEC_CASE_B; - } + uint16_t base; + uint16_t off; + aec_cases_t aec; + + if (BIT(opcode , 10)) { + // Current page + base = m_reg_P; + aec = AEC_CASE_A; + } else { + // Base page + base = 0; + aec = AEC_CASE_B; + } - off = opcode & 0x3ff; - if (off & 0x200) { - off -= 0x400; - } + off = opcode & 0x3ff; + if (off & 0x200) { + off -= 0x400; + } - base += off; + base += off; - if (BIT(opcode , 15)) { - // Indirect addressing - m_icount -= 6; - return add_mae(AEC_CASE_C , RM(aec , base)); - } else { - // Direct addressing - return add_mae(aec , base); - } + if (BIT(opcode , 15)) { + // Indirect addressing + m_icount -= 6; + return add_mae(AEC_CASE_C , RM(aec , base)); + } else { + // Direct addressing + return add_mae(aec , base); + } } void hp_hybrid_cpu_device::do_add(uint16_t& addend1 , uint16_t addend2) { - uint32_t tmp = addend1 + addend2; + uint32_t tmp = addend1 + addend2; - if (BIT(tmp , 16)) { - // Carry - BIT_SET(m_flags , HPHYBRID_C_BIT); - } + if (BIT(tmp , 16)) { + // Carry + BIT_SET(m_flags , HPHYBRID_C_BIT); + } - if (BIT((tmp ^ addend1) & (tmp ^ addend2) , 15)) { - // Overflow - BIT_SET(m_flags , HPHYBRID_O_BIT); - } + if (BIT((tmp ^ addend1) & (tmp ^ addend2) , 15)) { + // Overflow + BIT_SET(m_flags , HPHYBRID_O_BIT); + } - addend1 = (uint16_t)tmp; + addend1 = (uint16_t)tmp; } uint16_t hp_hybrid_cpu_device::get_skip_addr(uint16_t opcode , bool condition) const { - bool skip_val = BIT(opcode , 8) != 0; + bool skip_val = BIT(opcode , 8) != 0; - if (condition == skip_val) { - uint16_t off = opcode & 0x1f; + if (condition == skip_val) { + uint16_t off = opcode & 0x1f; - if (BIT(opcode , 5)) { - off -= 0x20; - } - return m_reg_P + off; - } else { - return m_reg_P + 1; - } + if (BIT(opcode , 5)) { + off -= 0x20; + } + return m_reg_P + off; + } else { + return m_reg_P + 1; + } } uint16_t hp_hybrid_cpu_device::get_skip_addr_sc(uint16_t opcode , uint16_t& v , unsigned n) { - bool val = BIT(v , n); - - if (BIT(opcode , 7)) { - if (BIT(opcode , 6)) { - BIT_SET(v , n); - } else { - BIT_CLR(v , n); - } - } + bool val = BIT(v , n); - return get_skip_addr(opcode , val); + if (BIT(opcode , 7)) { + if (BIT(opcode , 6)) { + BIT_SET(v , n); + } else { + BIT_CLR(v , n); + } + } + + return get_skip_addr(opcode , val); } uint16_t hp_hybrid_cpu_device::get_skip_addr_sc(uint16_t opcode , uint32_t& v , unsigned n) { - bool val = BIT(v , n); + bool val = BIT(v , n); - if (BIT(opcode , 7)) { - if (BIT(opcode , 6)) { - BIT_SET(v , n); - } else { - BIT_CLR(v , n); - } + if (BIT(opcode , 7)) { + if (BIT(opcode , 6)) { + BIT_SET(v , n); + } else { + BIT_CLR(v , n); } + } - return get_skip_addr(opcode , val); + return get_skip_addr(opcode , val); } void hp_hybrid_cpu_device::do_pw(uint16_t opcode) { - uint16_t tmp; - uint16_t reg_addr = opcode & 7; - uint16_t *ptr_reg; - uint16_t b_mask; - - if (BIT(opcode , 3)) { - ptr_reg = &m_reg_D; - b_mask = BIT_MASK(HPHYBRID_DB_BIT); - } else { - ptr_reg = &m_reg_C; - b_mask = BIT_MASK(HPHYBRID_CB_BIT); - } + uint16_t tmp; + uint16_t reg_addr = opcode & 7; + uint16_t *ptr_reg; + uint16_t b_mask; - if (BIT(opcode , 4)) { - // Withdraw - if (BIT(opcode , 11)) { - // Byte - uint32_t tmp_addr = (uint32_t)(*ptr_reg); - if (m_flags & b_mask) { - tmp_addr |= 0x10000; - } - tmp = RM(AEC_CASE_C , (uint16_t)(tmp_addr >> 1)); - if (BIT(tmp_addr , 0)) { - tmp &= 0xff; - } else { - tmp >>= 8; - } - } else { - // Word - tmp = RM(AEC_CASE_C , *ptr_reg); - } - WM(reg_addr , tmp); - - if (BIT(opcode , 7)) { - // Post-decrement - if ((*ptr_reg)-- == 0) { - m_flags ^= b_mask; - } - } else { - // Post-increment - if (++(*ptr_reg) == 0) { - m_flags ^= b_mask; - } - } + if (BIT(opcode , 3)) { + ptr_reg = &m_reg_D; + b_mask = BIT_MASK(HPHYBRID_DB_BIT); + } else { + ptr_reg = &m_reg_C; + b_mask = BIT_MASK(HPHYBRID_CB_BIT); + } + + if (BIT(opcode , 4)) { + // Withdraw + if (BIT(opcode , 11)) { + // Byte + uint32_t tmp_addr = (uint32_t)(*ptr_reg); + if (m_flags & b_mask) { + tmp_addr |= 0x10000; + } + tmp = RM(AEC_CASE_C , (uint16_t)(tmp_addr >> 1)); + if (BIT(tmp_addr , 0)) { + tmp &= 0xff; + } else { + tmp >>= 8; + } + } else { + // Word + tmp = RM(AEC_CASE_C , *ptr_reg); + } + WM(reg_addr , tmp); + + if (BIT(opcode , 7)) { + // Post-decrement + if ((*ptr_reg)-- == 0) { + m_flags ^= b_mask; + } + } else { + // Post-increment + if (++(*ptr_reg) == 0) { + m_flags ^= b_mask; + } + } + } else { + // Place + if (BIT(opcode , 7)) { + // Pre-decrement + if ((*ptr_reg)-- == 0) { + m_flags ^= b_mask; + } + } else { + // Pre-increment + if (++(*ptr_reg) == 0) { + m_flags ^= b_mask; + } + } + tmp = RM(reg_addr); + if (BIT(opcode , 11)) { + // Byte + uint32_t tmp_addr = (uint32_t)(*ptr_reg); + if (m_flags & b_mask) { + tmp_addr |= 0x10000; + } + if (tmp_addr <= (HP_REG_LAST_ADDR * 2 + 1)) { + // Single bytes can be written to registers. + // The addressed register gets the written byte in the proper position + // and a 0 in the other byte because access to registers is always done in + // 16 bits units. + if (BIT(tmp_addr , 0)) { + tmp &= 0xff; } else { - // Place - if (BIT(opcode , 7)) { - // Pre-decrement - if ((*ptr_reg)-- == 0) { - m_flags ^= b_mask; - } - } else { - // Pre-increment - if (++(*ptr_reg) == 0) { - m_flags ^= b_mask; - } - } - tmp = RM(reg_addr); - if (BIT(opcode , 11)) { - // Byte - uint32_t tmp_addr = (uint32_t)(*ptr_reg); - if (m_flags & b_mask) { - tmp_addr |= 0x10000; - } - if (tmp_addr <= (HP_REG_LAST_ADDR * 2 + 1)) { - // Single bytes can be written to registers. - // The addressed register gets the written byte in the proper position - // and a 0 in the other byte because access to registers is always done in - // 16 bits units. - if (BIT(tmp_addr , 0)) { - tmp &= 0xff; - } else { - tmp <<= 8; - } - WM(tmp_addr >> 1 , tmp); - } else { - // Extend address, preserve LSB & form byte address - tmp_addr = (add_mae(AEC_CASE_C , tmp_addr >> 1) << 1) | (tmp_addr & 1); - m_program->write_byte(tmp_addr , (uint8_t)tmp); - } - } else { - // Word - WM(AEC_CASE_C , *ptr_reg , tmp); - } + tmp <<= 8; } + WM(tmp_addr >> 1 , tmp); + } else { + // Extend address, form byte address + uint16_t val = (tmp_addr & 1) ? uint8_t(tmp) << 8 : uint8_t(tmp); + uint16_t mask = (tmp_addr & 1) ? 0xff00 : 0x00ff; + tmp_addr = add_mae(AEC_CASE_C , tmp_addr >> 1); + m_program->write_word(tmp_addr , val, mask); + } + } else { + // Word + WM(AEC_CASE_C , *ptr_reg , tmp); + } + } } void hp_hybrid_cpu_device::check_for_interrupts(void) { - if (!BIT(m_flags , HPHYBRID_INTEN_BIT) || BIT(m_flags , HPHYBRID_IRH_SVC_BIT) || BIT(m_flags , HPHYBRID_IM_BIT)) { - return; - } + if (!BIT(m_flags , HPHYBRID_INTEN_BIT) || BIT(m_flags , HPHYBRID_IRH_SVC_BIT) || BIT(m_flags , HPHYBRID_IM_BIT)) { + return; + } - int irqline; - - if (BIT(m_flags , HPHYBRID_IRH_BIT)) { - // Service high-level interrupt - BIT_SET(m_flags , HPHYBRID_IRH_SVC_BIT); - irqline = HPHYBRID_IRH; - if (BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { - logerror("H pre-empted L @ %06x\n" , m_genpc); - } - } else if (BIT(m_flags , HPHYBRID_IRL_BIT) && !BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { - // Service low-level interrupt - BIT_SET(m_flags , HPHYBRID_IRL_SVC_BIT); - irqline = HPHYBRID_IRL; - } else { - return; - } + int irqline; - // Get interrupt vector in low byte - uint8_t vector = (uint8_t)standard_irq_callback(irqline); - uint8_t new_PA; + if (BIT(m_flags , HPHYBRID_IRH_BIT)) { + // Service high-level interrupt + BIT_SET(m_flags , HPHYBRID_IRH_SVC_BIT); + irqline = HPHYBRID_IRH; + if (BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { + logerror("H pre-empted L @ %06x\n" , m_genpc); + } + } else if (BIT(m_flags , HPHYBRID_IRL_BIT) && !BIT(m_flags , HPHYBRID_IRL_SVC_BIT)) { + // Service low-level interrupt + BIT_SET(m_flags , HPHYBRID_IRL_SVC_BIT); + irqline = HPHYBRID_IRL; + } else { + return; + } - // Get highest numbered 1 - // Don't know what happens if vector is 0, here we assume bit 7 = 1 - if (vector == 0) { - new_PA = 7; - } else { - for (new_PA = 7; new_PA && !BIT(vector , 7); new_PA--, vector <<= 1) { - } - } - if (irqline == HPHYBRID_IRH) { - BIT_SET(new_PA , 3); - } + // Get interrupt vector in low byte + uint8_t vector = (uint8_t)standard_irq_callback(irqline); + uint8_t new_PA; - // Push PA stack - memmove(&m_reg_PA[ 1 ] , &m_reg_PA[ 0 ] , HPHYBRID_INT_LVLS); + // Get highest numbered 1 + // Don't know what happens if vector is 0, here we assume bit 7 = 1 + if (vector == 0) { + new_PA = 7; + } else { + for (new_PA = 7; new_PA && !BIT(vector , 7); new_PA--, vector <<= 1) { + } + } + if (irqline == HPHYBRID_IRH) { + BIT_SET(new_PA , 3); + } - CURRENT_PA = new_PA; + // Push PA stack + memmove(&m_reg_PA[ 1 ] , &m_reg_PA[ 0 ] , HPHYBRID_INT_LVLS); - m_pa_changed_func((uint8_t)CURRENT_PA); + CURRENT_PA = new_PA; + + m_pa_changed_func((uint8_t)CURRENT_PA); - // Is this correct? Patent @ pg 210 suggests that the whole interrupt recognition sequence - // lasts for 32 cycles - m_icount -= 32; + // Is this correct? Patent @ pg 210 suggests that the whole interrupt recognition sequence + // lasts for 32 cycles + m_icount -= 32; - // Allow special processing in 5061-3001 - enter_isr(); + // Allow special processing in 5061-3001 + enter_isr(); - // Do a double-indirect JSM IV,I instruction - WM(AEC_CASE_C , ++m_reg_R , m_reg_P); - m_reg_P = RM(AEC_CASE_C , m_reg_IV + CURRENT_PA); - m_reg_I = fetch(); + // Do a double-indirect JSM IV,I instruction + WM(AEC_CASE_C , ++m_reg_R , m_reg_P); + m_reg_P = RM(AEC_CASE_C , m_reg_IV + CURRENT_PA); + m_reg_I = fetch(); } void hp_hybrid_cpu_device::enter_isr(void) { - // Do nothing special + // Do nothing special } void hp_hybrid_cpu_device::handle_dma(void) @@ -1108,7 +1110,7 @@ void hp_hybrid_cpu_device::handle_dma(void) if (BIT(m_flags , HPHYBRID_DMADIR_BIT)) { // "Outward" DMA: memory -> peripheral - tmp = RM(AEC_CASE_D , m_dmama++); + tmp = RM(AEC_CASE_D , m_dmama++); WIO(m_dmapa , tc ? 2 : 0 , tmp); m_icount -= 10; } else { @@ -1397,16 +1399,16 @@ uint16_t hp_5061_3001_cpu_device::execute_no_bpc_ioc(uint16_t opcode) break; case 0x7280: - // FXA - m_icount -= 40; - tmp_ar2 = get_ar2(); - carry = do_dec_add(BIT(m_flags , HPHYBRID_DC_BIT) , tmp_ar2 , get_ar1()); - set_ar2(tmp_ar2); - if (carry) - BIT_SET(m_flags, HPHYBRID_DC_BIT); - else - BIT_CLR(m_flags, HPHYBRID_DC_BIT); - break; + // FXA + m_icount -= 40; + tmp_ar2 = get_ar2(); + carry = do_dec_add(BIT(m_flags , HPHYBRID_DC_BIT) , tmp_ar2 , get_ar1()); + set_ar2(tmp_ar2); + if (carry) + BIT_SET(m_flags, HPHYBRID_DC_BIT); + else + BIT_CLR(m_flags, HPHYBRID_DC_BIT); + break; case 0x7340: // NRM @@ -1539,10 +1541,9 @@ uint16_t hp_5061_3001_cpu_device::execute_no_bpc_ioc(uint16_t opcode) return m_reg_P + 1; } -offs_t hp_5061_3001_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hp_5061_3001_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(hp_5061_3001); - return CPU_DISASSEMBLE_NAME(hp_5061_3001)(this, stream, pc, oprom, opram, options); + return new hp_5061_3001_disassembler; } uint32_t hp_5061_3001_cpu_device::add_mae(aec_cases_t aec_case , uint16_t addr) @@ -1599,7 +1600,7 @@ uint32_t hp_5061_3001_cpu_device::add_mae(aec_cases_t aec_case , uint16_t addr) case AEC_CASE_D: bsc_reg = top_half ? m_reg_aec[ HP_REG_R32_ADDR - HP_REG_R32_ADDR ] : m_reg_aec[ HP_REG_R37_ADDR - HP_REG_R32_ADDR ]; - break; + break; default: logerror("hphybrid: aec_case=%d\n" , aec_case); diff --git a/src/devices/cpu/hphybrid/hphybrid.h b/src/devices/cpu/hphybrid/hphybrid.h index 5962942b64c..bd362d710ee 100644 --- a/src/devices/cpu/hphybrid/hphybrid.h +++ b/src/devices/cpu/hphybrid/hphybrid.h @@ -85,9 +85,7 @@ protected: 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // Different cases of memory access // See patent @ pg 361 @@ -142,7 +140,7 @@ private: address_space_config m_io_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_io; uint32_t get_ea(uint16_t opcode); @@ -181,7 +179,7 @@ protected: void do_mpy(); virtual uint16_t execute_no_bpc_ioc(uint16_t opcode) override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t add_mae(aec_cases_t aec_case, uint16_t addr) override; virtual uint16_t read_non_common_reg(uint16_t addr) override; virtual void write_non_common_reg(uint16_t addr , uint16_t v) override; diff --git a/src/devices/cpu/hphybrid/hphybrid_dasm.cpp b/src/devices/cpu/hphybrid/hphybrid_dasm.cpp index 58d800a3722..74d833803c0 100644 --- a/src/devices/cpu/hphybrid/hphybrid_dasm.cpp +++ b/src/devices/cpu/hphybrid/hphybrid_dasm.cpp @@ -5,23 +5,10 @@ // ******************************************************************************** #include "emu.h" -#include "hphybrid.h" -#include "debugger.h" - +#include "hphybrid_dasm.h" #include "hphybrid_defs.h" - -typedef void (*fn_dis_param)(std::ostream &stream , offs_t pc , uint16_t opcode , bool is_3001); - -typedef struct { - uint16_t m_op_mask; - uint16_t m_opcode; - const char *m_mnemonic; - fn_dis_param m_param_fn; - uint32_t m_dasm_flags; -} dis_entry_t; - -static void addr_2_str(std::ostream &stream, uint16_t addr , bool indirect , bool is_3001) +void hp_hybrid_disassembler::addr_2_str(std::ostream &stream, uint16_t addr , bool indirect , bool is_3001) { util::stream_format(stream, "$%04x" , addr); @@ -168,11 +155,11 @@ static void addr_2_str(std::ostream &stream, uint16_t addr , bool indirect , boo } } -static void param_none(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_none(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { } -static void param_loc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_loc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { uint16_t base; uint16_t off; @@ -193,12 +180,12 @@ static void param_loc(std::ostream &stream, offs_t pc , uint16_t opcode , bool i addr_2_str(stream, base + off , (opcode & 0x8000) != 0 , is_3001); } -static void param_addr32(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_addr32(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { addr_2_str(stream, opcode & 0x1f , (opcode & 0x8000) != 0 , is_3001); } -static void param_skip(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_skip(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { uint16_t off = opcode & 0x3f; if (off & 0x20) { @@ -207,7 +194,7 @@ static void param_skip(std::ostream &stream, offs_t pc , uint16_t opcode , bool addr_2_str(stream , pc + off , false , is_3001); } -static void param_skip_sc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_skip_sc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { param_skip(stream, pc, opcode , is_3001); @@ -220,7 +207,7 @@ static void param_skip_sc(std::ostream &stream, offs_t pc , uint16_t opcode , bo } } -static void param_ret(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_ret(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { int off = opcode & 0x3f; @@ -234,12 +221,12 @@ static void param_ret(std::ostream &stream, offs_t pc , uint16_t opcode , bool i } } -static void param_n16(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_n16(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { util::stream_format(stream , "%u" , (opcode & 0xf) + 1); } -static void param_reg_id(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) +void hp_hybrid_disassembler::param_reg_id(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001) { addr_2_str(stream, opcode & 7, false , is_3001); @@ -250,133 +237,133 @@ static void param_reg_id(std::ostream &stream, offs_t pc , uint16_t opcode , boo } } -static const dis_entry_t dis_table[] = { +const hp_hybrid_disassembler::dis_entry_t hp_hybrid_disassembler::dis_table[] = { // *** BPC Instructions *** - {0xffff , 0x0000 , "NOP" , param_none , 0 }, - {0x7800 , 0x0000 , "LDA" , param_loc , 0 }, - {0x7800 , 0x0800 , "LDB" , param_loc , 0 }, - {0x7800 , 0x1000 , "CPA" , param_loc , 0 }, - {0x7800 , 0x1800 , "CPB" , param_loc , 0 }, - {0x7800 , 0x2000 , "ADA" , param_loc , 0 }, - {0x7800 , 0x2800 , "ADB" , param_loc , 0 }, - {0x7800 , 0x3000 , "STA" , param_loc , 0 }, - {0x7800 , 0x3800 , "STB" , param_loc , 0 }, - {0x7800 , 0x4000 , "JSM" , param_loc , DASMFLAG_STEP_OVER }, - {0x7800 , 0x4800 , "ISZ" , param_loc , 0 }, - {0x7800 , 0x5000 , "AND" , param_loc , 0 }, - {0x7800 , 0x5800 , "DSZ" , param_loc , 0 }, - {0x7800 , 0x6000 , "IOR" , param_loc , 0 }, - {0x7800 , 0x6800 , "JMP" , param_loc , 0 }, - {0x7fe0 , 0x7000 , "EXE" , param_addr32 , 0 }, - {0xffc0 , 0x7400 , "RZA" , param_skip , 0 }, - {0xffc0 , 0x7C00 , "RZB" , param_skip , 0 }, - {0xffc0 , 0x7440 , "RIA" , param_skip , 0 }, - {0xffc0 , 0x7C40 , "RIB" , param_skip , 0 }, - {0xffc0 , 0x7500 , "SZA" , param_skip , 0 }, - {0xffc0 , 0x7D00 , "SZB" , param_skip , 0 }, - {0xffc0 , 0x7540 , "SIA" , param_skip , 0 }, - {0xffc0 , 0x7D40 , "SIB" , param_skip , 0 }, - {0xffc0 , 0x7480 , "SFS" , param_skip , 0 }, - {0xffc0 , 0x7580 , "SFC" , param_skip , 0 }, - {0xffc0 , 0x7c80 , "SSS" , param_skip , 0 }, - {0xffc0 , 0x7d80 , "SSC" , param_skip , 0 }, - {0xffc0 , 0x7cc0 , "SHS" , param_skip , 0 }, - {0xffc0 , 0x7dc0 , "SHC" , param_skip , 0 }, - {0xff00 , 0x7600 , "SLA" , param_skip_sc , 0 }, - {0xff00 , 0x7e00 , "SLB" , param_skip_sc , 0 }, - {0xff00 , 0x7700 , "RLA" , param_skip_sc , 0 }, - {0xff00 , 0x7f00 , "RLB" , param_skip_sc , 0 }, - {0xff00 , 0xf400 , "SAP" , param_skip_sc , 0 }, - {0xff00 , 0xfc00 , "SBP" , param_skip_sc , 0 }, - {0xff00 , 0xf500 , "SAM" , param_skip_sc , 0 }, - {0xff00 , 0xfd00 , "SBM" , param_skip_sc , 0 }, - {0xff00 , 0xf600 , "SOC" , param_skip_sc , 0 }, - {0xff00 , 0xf700 , "SOS" , param_skip_sc , 0 }, - {0xff00 , 0xfe00 , "SEC" , param_skip_sc , 0 }, - {0xff00 , 0xff00 , "SES" , param_skip_sc , 0 }, - {0xffff , 0xf020 , "TCA" , param_none , 0 }, - {0xffff , 0xf820 , "TCB" , param_none , 0 }, - {0xffff , 0xf060 , "CMA" , param_none , 0 }, - {0xffff , 0xf860 , "CMB" , param_none , 0 }, - {0xff80 , 0xf080 , "RET" , param_ret , DASMFLAG_STEP_OUT }, - {0xfff0 , 0xf100 , "AAR" , param_n16 , 0 }, - {0xfff0 , 0xf900 , "ABR" , param_n16 , 0 }, - {0xffff , 0xf14f , "CLA" , param_none , 0 }, - {0xfff0 , 0xf140 , "SAR" , param_n16 , 0 }, - {0xffff , 0xf94f , "CLB" , param_none , 0 }, - {0xfff0 , 0xf940 , "SBR" , param_n16 , 0 }, - {0xfff0 , 0xf180 , "SAL" , param_n16 , 0 }, - {0xfff0 , 0xf980 , "SBL" , param_n16 , 0 }, - {0xfff0 , 0xf1c0 , "RAR" , param_n16 , 0 }, - {0xfff0 , 0xf9c0 , "RBR" , param_n16 , 0 }, + {0xffff , 0x0000 , "NOP" , &hp_hybrid_disassembler::param_none , 0 }, + {0x7800 , 0x0000 , "LDA" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x0800 , "LDB" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x1000 , "CPA" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x1800 , "CPB" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x2000 , "ADA" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x2800 , "ADB" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x3000 , "STA" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x3800 , "STB" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x4000 , "JSM" , &hp_hybrid_disassembler::param_loc , STEP_OVER }, + {0x7800 , 0x4800 , "ISZ" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x5000 , "AND" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x5800 , "DSZ" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x6000 , "IOR" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7800 , 0x6800 , "JMP" , &hp_hybrid_disassembler::param_loc , 0 }, + {0x7fe0 , 0x7000 , "EXE" , &hp_hybrid_disassembler::param_addr32 , 0 }, + {0xffc0 , 0x7400 , "RZA" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7C00 , "RZB" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7440 , "RIA" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7C40 , "RIB" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7500 , "SZA" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7D00 , "SZB" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7540 , "SIA" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7D40 , "SIB" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7480 , "SFS" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7580 , "SFC" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7c80 , "SSS" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7d80 , "SSC" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7cc0 , "SHS" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xffc0 , 0x7dc0 , "SHC" , &hp_hybrid_disassembler::param_skip , 0 }, + {0xff00 , 0x7600 , "SLA" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0x7e00 , "SLB" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0x7700 , "RLA" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0x7f00 , "RLB" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xf400 , "SAP" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xfc00 , "SBP" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xf500 , "SAM" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xfd00 , "SBM" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xf600 , "SOC" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xf700 , "SOS" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xfe00 , "SEC" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xff00 , 0xff00 , "SES" , &hp_hybrid_disassembler::param_skip_sc , 0 }, + {0xffff , 0xf020 , "TCA" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0xf820 , "TCB" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0xf060 , "CMA" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0xf860 , "CMB" , &hp_hybrid_disassembler::param_none , 0 }, + {0xff80 , 0xf080 , "RET" , &hp_hybrid_disassembler::param_ret , STEP_OUT }, + {0xfff0 , 0xf100 , "AAR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf900 , "ABR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xffff , 0xf14f , "CLA" , &hp_hybrid_disassembler::param_none , 0 }, + {0xfff0 , 0xf140 , "SAR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xffff , 0xf94f , "CLB" , &hp_hybrid_disassembler::param_none , 0 }, + {0xfff0 , 0xf940 , "SBR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf180 , "SAL" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf980 , "SBL" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf1c0 , "RAR" , &hp_hybrid_disassembler::param_n16 , 0 }, + {0xfff0 , 0xf9c0 , "RBR" , &hp_hybrid_disassembler::param_n16 , 0 }, // *** IOC Instructions *** - {0xffff , 0x7100 , "SDO" , param_none , 0 }, - {0xffff , 0x7108 , "SDI" , param_none , 0 }, - {0xffff , 0x7110 , "EIR" , param_none , 0 }, - {0xffff , 0x7118 , "DIR" , param_none , 0 }, - {0xffff , 0x7120 , "DMA" , param_none , 0 }, - {0xffff , 0x7128 , "PCM" , param_none , 0 }, - {0xffff , 0x7138 , "DDR" , param_none , 0 }, - {0xffff , 0x7140 , "DBL" , param_none , 0 }, - {0xffff , 0x7148 , "CBL" , param_none , 0 }, - {0xffff , 0x7150 , "DBU" , param_none , 0 }, - {0xffff , 0x7158 , "CBU" , param_none , 0 }, - {0xff78 , 0x7160 , "PWC" , param_reg_id , 0 }, - {0xff78 , 0x7168 , "PWD" , param_reg_id , 0 }, - {0xff78 , 0x7960 , "PBC" , param_reg_id , 0 }, - {0xff78 , 0x7968 , "PBD" , param_reg_id , 0 }, - {0xff78 , 0x7170 , "WWC" , param_reg_id , 0 }, - {0xff78 , 0x7178 , "WWD" , param_reg_id , 0 }, - {0xff78 , 0x7970 , "WBC" , param_reg_id , 0 }, - {0xff78 , 0x7978 , "WBD" , param_reg_id , 0 }, + {0xffff , 0x7100 , "SDO" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7108 , "SDI" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7110 , "EIR" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7118 , "DIR" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7120 , "DMA" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7128 , "PCM" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7138 , "DDR" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7140 , "DBL" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7148 , "CBL" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7150 , "DBU" , &hp_hybrid_disassembler::param_none , 0 }, + {0xffff , 0x7158 , "CBU" , &hp_hybrid_disassembler::param_none , 0 }, + {0xff78 , 0x7160 , "PWC" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7168 , "PWD" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7960 , "PBC" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7968 , "PBD" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7170 , "WWC" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7178 , "WWD" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7970 , "WBC" , &hp_hybrid_disassembler::param_reg_id , 0 }, + {0xff78 , 0x7978 , "WBD" , &hp_hybrid_disassembler::param_reg_id , 0 }, // *** END *** {0 , 0 , nullptr , nullptr , 0 } }; -static const dis_entry_t dis_table_emc[] = { +const hp_hybrid_disassembler::dis_entry_t hp_5061_3001_disassembler::dis_table_emc[] = { // *** EMC Instructions *** - {0xffff , 0x7200 , "MWA" , param_none , 0 }, - {0xffff , 0x7220 , "CMY" , param_none , 0 }, - {0xffff , 0x7260 , "CMX" , param_none , 0 }, - {0xffff , 0x7280 , "FXA" , param_none , 0 }, - {0xfff0 , 0x7300 , "XFR" , param_n16 , 0 }, - {0xffff , 0x7340 , "NRM" , param_none , 0 }, - {0xfff0 , 0x7380 , "CLR" , param_n16 , 0 }, - {0xffff , 0x73c0 , "CDC" , param_none , 0 }, - {0xffc0 , 0x74c0 , "SDS" , param_skip , 0 }, - {0xffc0 , 0x75c0 , "SDC" , param_skip , 0 }, - {0xffff , 0x7a00 , "FMP" , param_none , 0 }, - {0xffff , 0x7a21 , "FDV" , param_none , 0 }, - {0xffff , 0x7b00 , "MRX" , param_none , 0 }, - {0xffff , 0x7b21 , "DRS" , param_none , 0 }, - {0xffff , 0x7b40 , "MRY" , param_none , 0 }, - {0xffff , 0x7b61 , "MLY" , param_none , 0 }, - {0xffff , 0x7b8f , "MPY" , param_none , 0 }, + {0xffff , 0x7200 , "MWA" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7220 , "CMY" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7260 , "CMX" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7280 , "FXA" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xfff0 , 0x7300 , "XFR" , &hp_5061_3001_disassembler::param_n16 , 0 }, + {0xffff , 0x7340 , "NRM" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xfff0 , 0x7380 , "CLR" , &hp_5061_3001_disassembler::param_n16 , 0 }, + {0xffff , 0x73c0 , "CDC" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffc0 , 0x74c0 , "SDS" , &hp_5061_3001_disassembler::param_skip , 0 }, + {0xffc0 , 0x75c0 , "SDC" , &hp_5061_3001_disassembler::param_skip , 0 }, + {0xffff , 0x7a00 , "FMP" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7a21 , "FDV" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b00 , "MRX" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b21 , "DRS" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b40 , "MRY" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b61 , "MLY" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7b8f , "MPY" , &hp_5061_3001_disassembler::param_none , 0 }, // *** Undocumented instructions of 5061-3001 *** - {0xffff , 0x7026 , "CIM" , param_none , 0 }, - {0xffff , 0x7027 , "SIM" , param_none , 0 }, + {0xffff , 0x7026 , "CIM" , &hp_5061_3001_disassembler::param_none , 0 }, + {0xffff , 0x7027 , "SIM" , &hp_5061_3001_disassembler::param_none , 0 }, // *** END *** {0 , 0 , nullptr , nullptr , 0 } }; -static offs_t disassemble_table(uint16_t opcode , offs_t pc , const dis_entry_t *table , bool is_3001 , std::ostream &stream) +offs_t hp_hybrid_disassembler::disassemble_table(uint16_t opcode , offs_t pc , const dis_entry_t *table , bool is_3001 , std::ostream &stream) { const dis_entry_t *p; for (p = table; p->m_op_mask; p++) { if ((opcode & p->m_op_mask) == p->m_opcode) { stream << p->m_mnemonic << " "; - p->m_param_fn(stream , pc , opcode , is_3001); - return 1 | p->m_dasm_flags | DASMFLAG_SUPPORTED; + (this->*(p->m_param_fn))(stream , pc , opcode , is_3001); + return 1 | p->m_dasm_flags | SUPPORTED; } } return 0; } -CPU_DISASSEMBLE(hp_hybrid) +offs_t hp_hybrid_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint16_t opcode = ((uint16_t)oprom[ 0 ] << 8) | oprom[ 1 ]; + uint16_t opcode = opcodes.r16(pc); offs_t res; res = disassemble_table(opcode, pc, dis_table, false, stream); @@ -385,15 +372,15 @@ CPU_DISASSEMBLE(hp_hybrid) { // Unknown opcode stream << "???"; - res = 1 | DASMFLAG_SUPPORTED; + res = 1 | SUPPORTED; } return res; } -CPU_DISASSEMBLE(hp_5061_3001) +offs_t hp_5061_3001_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint16_t opcode = ((uint16_t)oprom[ 0 ] << 8) | oprom[ 1 ]; + uint16_t opcode = opcodes.r16(pc); offs_t res; res = disassemble_table(opcode, pc, dis_table_emc, true, stream); @@ -407,8 +394,13 @@ CPU_DISASSEMBLE(hp_5061_3001) { // Unknown opcode stream << "???"; - res = 1 | DASMFLAG_SUPPORTED; + res = 1 | SUPPORTED; } return res; } + +u32 hp_hybrid_disassembler::opcode_alignment() const +{ + return 1; +} diff --git a/src/devices/cpu/hphybrid/hphybrid_dasm.h b/src/devices/cpu/hphybrid/hphybrid_dasm.h new file mode 100644 index 00000000000..96994ae0632 --- /dev/null +++ b/src/devices/cpu/hphybrid/hphybrid_dasm.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:F. Ulivi +// ******************************************************************************** +// * HP "hybrid" processor disassembler +// ******************************************************************************** + +#ifndef MAME_CPU_HPHYBRID_HPHYBRID_DASM_H +#define MAME_CPU_HPHYBRID_HPHYBRID_DASM_H + +#pragma once + +class hp_hybrid_disassembler : public util::disasm_interface +{ +public: + hp_hybrid_disassembler() = default; + virtual ~hp_hybrid_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + typedef void (hp_hybrid_disassembler::*fn_dis_param)(std::ostream &stream , offs_t pc , uint16_t opcode , bool is_3001); + + typedef struct { + uint16_t m_op_mask; + uint16_t m_opcode; + const char *m_mnemonic; + fn_dis_param m_param_fn; + uint32_t m_dasm_flags; + } dis_entry_t; + + static const dis_entry_t dis_table[]; + + void addr_2_str(std::ostream &stream, uint16_t addr , bool indirect , bool is_3001); + void param_none(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_loc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_addr32(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_skip(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_skip_sc(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_ret(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_n16(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + void param_reg_id(std::ostream &stream, offs_t pc , uint16_t opcode , bool is_3001); + + offs_t disassemble_table(uint16_t opcode , offs_t pc , const dis_entry_t *table , bool is_3001 , std::ostream &stream); +}; + +class hp_5061_3001_disassembler : public hp_hybrid_disassembler +{ +public: + hp_5061_3001_disassembler() = default; + virtual ~hp_5061_3001_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + static const dis_entry_t dis_table_emc[]; +}; + +#endif diff --git a/src/devices/cpu/i386/i386.cpp b/src/devices/cpu/i386/i386.cpp index 5c403dc1163..15379c18d7b 100644 --- a/src/devices/cpu/i386/i386.cpp +++ b/src/devices/cpu/i386/i386.cpp @@ -3171,36 +3171,13 @@ uint64_t i386_device::debug_virttophys(symbol_table &table, int params, const ui return result; } -uint64_t i386_debug_segbase(symbol_table &table, void *ref, int params, const uint64_t *param) -{ - i386_device *i386 = (i386_device *)(ref); - return i386->debug_segbase(table, params, param); -} - -uint64_t i386_debug_seglimit(symbol_table &table, void *ref, int params, const uint64_t *param) -{ - i386_device *i386 = (i386_device *)(ref); - return i386->debug_seglimit(table, params, param); -} - -uint64_t i386_debug_segofftovirt(symbol_table &table, void *ref, int params, const uint64_t *param) -{ - i386_device *i386 = (i386_device *)(ref); - return i386->debug_segofftovirt(table, params, param); -} - -static uint64_t i386_debug_virttophys(symbol_table &table, void *ref, int params, const uint64_t *param) -{ - i386_device *i386 = (i386_device *)(ref); - return i386->debug_virttophys(table, params, param); -} - void i386_device::device_debug_setup() { - debug()->symtable().add("segbase", (void *)this, 1, 1, i386_debug_segbase); - debug()->symtable().add("seglimit", (void *)this, 1, 1, i386_debug_seglimit); - debug()->symtable().add("segofftovirt", (void *)this, 2, 2, i386_debug_segofftovirt); - debug()->symtable().add("virttophys", (void *)this, 1, 1, i386_debug_virttophys); + using namespace std::placeholders; + debug()->symtable().add("segbase", 1, 1, std::bind(&i386_device::debug_segbase, this, _1, _2, _3)); + debug()->symtable().add("seglimit", 1, 1, std::bind(&i386_device::debug_seglimit, this, _1, _2, _3)); + debug()->symtable().add("segofftovirt", 2, 2, std::bind(&i386_device::debug_segofftovirt, this, _1, _2, _3)); + debug()->symtable().add("virttophys", 1, 1, std::bind(&i386_device::debug_virttophys, this, _1, _2, _3)); } /*************************************************************************/ @@ -3244,7 +3221,7 @@ void i386_device::i386_common_init() } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_smi = false; m_debugger_temp = 0; @@ -4021,11 +3998,15 @@ bool i386_device::memory_translate(int spacenum, int intention, offs_t &address) return ret; } -offs_t i386_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +int i386_device::get_mode() const { - return i386_dasm_one(stream, pc, oprom, m_sreg[CS].d ? 32 : 16); + return m_sreg[CS].d ? 32 : 16; } +util::disasm_interface *i386_device::create_disassembler() +{ + return new i386_disassembler(this); +} /*****************************************************************************/ /* Intel 486 */ diff --git a/src/devices/cpu/i386/i386.h b/src/devices/cpu/i386/i386.h index 3701f6c6704..93c5df1c122 100644 --- a/src/devices/cpu/i386/i386.h +++ b/src/devices/cpu/i386/i386.h @@ -15,6 +15,7 @@ #include "debug/debugcpu.h" #include "divtlb.h" +#include "i386dasm.h" #define INPUT_LINE_A20 1 #define INPUT_LINE_SMI 2 @@ -29,7 +30,7 @@ #define X86_NUM_CPUS 4 -class i386_device : public cpu_device, public device_vtlb_interface +class i386_device : public cpu_device, public device_vtlb_interface, public i386_disassembler::config { public: // construction/destruction @@ -68,9 +69,8 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 15; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual int get_mode() const override; address_space_config m_program_config; address_space_config m_io_config; @@ -212,7 +212,7 @@ protected: uint8_t m_irq_state; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint32_t m_a20_mask; diff --git a/src/devices/cpu/i386/i386dasm.cpp b/src/devices/cpu/i386/i386dasm.cpp index 3c815612ffa..e201c4c02a4 100644 --- a/src/devices/cpu/i386/i386dasm.cpp +++ b/src/devices/cpu/i386/i386dasm.cpp @@ -7,117 +7,9 @@ */ #include "emu.h" +#include "i386dasm.h" -enum -{ - PARAM_REG = 1, /* 16 or 32-bit register */ - PARAM_REG8, /* 8-bit register */ - PARAM_REG16, /* 16-bit register */ - PARAM_REG32, /* 32-bit register */ - PARAM_REG3264, /* 32-bit or 64-bit register */ - PARAM_REG2_32, /* 32-bit register */ - PARAM_MMX, /* MMX register */ - PARAM_MMX2, /* MMX register in modrm */ - PARAM_XMM, /* XMM register */ - PARAM_RM, /* 16 or 32-bit memory or register */ - PARAM_RM8, /* 8-bit memory or register */ - PARAM_RM16, /* 16-bit memory or register */ - PARAM_RM32, /* 32-bit memory or register */ - PARAM_RMPTR, /* 16 or 32-bit memory or register */ - PARAM_RMPTR8, /* 8-bit memory or register */ - PARAM_RMPTR16, /* 16-bit memory or register */ - PARAM_RMPTR32, /* 32-bit memory or register */ - PARAM_RMXMM, /* 32 or 64-bit memory or register */ - PARAM_REGORXMM, /* 32 or 64-bit register or XMM register */ - PARAM_M64, /* 64-bit memory */ - PARAM_M64PTR, /* 64-bit memory */ - PARAM_MMXM, /* 64-bit memory or MMX register */ - PARAM_XMMM, /* 128-bit memory or XMM register */ - PARAM_I4, /* 4-bit signed immediate */ - PARAM_I8, /* 8-bit signed immediate */ - PARAM_I16, /* 16-bit signed immediate */ - PARAM_UI8, /* 8-bit unsigned immediate */ - PARAM_UI16, /* 16-bit unsigned immediate */ - PARAM_IMM, /* 16 or 32-bit immediate */ - PARAM_IMM64, /* 16, 32 or 64-bit immediate */ - PARAM_ADDR, /* 16:16 or 16:32 address */ - PARAM_REL, /* 16 or 32-bit PC-relative displacement */ - PARAM_REL8, /* 8-bit PC-relative displacement */ - PARAM_MEM_OFFS, /* 16 or 32-bit mem offset */ - PARAM_PREIMP, /* prefix with implicit register */ - PARAM_SREG, /* segment register */ - PARAM_CREG, /* control register */ - PARAM_DREG, /* debug register */ - PARAM_TREG, /* test register */ - PARAM_1, /* used by shift/rotate instructions */ - PARAM_AL, - PARAM_CL, - PARAM_DL, - PARAM_BL, - PARAM_AH, - PARAM_CH, - PARAM_DH, - PARAM_BH, - PARAM_DX, - PARAM_EAX, /* EAX or AX */ - PARAM_ECX, /* ECX or CX */ - PARAM_EDX, /* EDX or DX */ - PARAM_EBX, /* EBX or BX */ - PARAM_ESP, /* ESP or SP */ - PARAM_EBP, /* EBP or BP */ - PARAM_ESI, /* ESI or SI */ - PARAM_EDI, /* EDI or DI */ - PARAM_XMM0, - PARAM_XMM64, /* 64-bit memory or XMM register */ - PARAM_XMM32, /* 32-bit memory or XMM register */ - PARAM_XMM16 /* 16-bit memory or XMM register */ -}; - -enum -{ - MODRM = 1, - GROUP, - FPU, - OP_SIZE, - ADDR_SIZE, - TWO_BYTE, - PREFIX, - SEG_CS, - SEG_DS, - SEG_ES, - SEG_FS, - SEG_GS, - SEG_SS, - ISREX, - THREE_BYTE /* [prefix] 0f op1 op2 and then mod/rm */ -}; - -#define FLAGS_MASK 0x0ff -#define VAR_NAME 0x100 -#define VAR_NAME4 0x200 -#define ALWAYS64 0x400 -#define SPECIAL64 0x800 -#define SPECIAL64_ENT(x) (SPECIAL64 | ((x) << 24)) -#define GROUP_MOD 0x1000 - -struct I386_OPCODE { - const char *mnemonic; - uint32_t flags; - uint32_t param1; - uint32_t param2; - uint32_t param3; - offs_t dasm_flags; -}; - -struct GROUP_OP { - char mnemonic[32]; - const I386_OPCODE *opcode; -}; - -static const uint8_t *opcode_ptr; -static const uint8_t *opcode_ptr_base; - -static const I386_OPCODE i386_opcode_table1[256] = +const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table1[256] = { // 0x00 {"add", MODRM, PARAM_RM8, PARAM_REG8, 0 }, @@ -283,7 +175,7 @@ static const I386_OPCODE i386_opcode_table1[256] = {"xchg", 0, PARAM_EAX, PARAM_EDI, 0 }, {"cbw\0cwde\0cdqe", VAR_NAME, 0, 0, 0 }, {"cwd\0cdq\0cqo", VAR_NAME, 0, 0, 0 }, - {"call", ALWAYS64, PARAM_ADDR, 0, 0, DASMFLAG_STEP_OVER}, + {"call", ALWAYS64, PARAM_ADDR, 0, 0, STEP_OVER}, {"wait", 0, 0, 0, 0 }, {"pushf\0pushfd\0pushfq",VAR_NAME, 0, 0, 0 }, {"popf\0popfd\0popfq",VAR_NAME, 0, 0, 0 }, @@ -326,20 +218,20 @@ static const I386_OPCODE i386_opcode_table1[256] = // 0xc0 {"groupC0", GROUP, 0, 0, 0 }, {"groupC1", GROUP, 0, 0, 0 }, - {"ret", 0, PARAM_UI16, 0, 0, DASMFLAG_STEP_OUT}, - {"ret", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, + {"ret", 0, PARAM_UI16, 0, 0, STEP_OUT}, + {"ret", 0, 0, 0, 0, STEP_OUT}, {"les", MODRM, PARAM_REG, PARAM_RM, 0 }, {"lds", MODRM, PARAM_REG, PARAM_RM, 0 }, {"mov", MODRM, PARAM_RMPTR8, PARAM_UI8, 0 }, {"mov", MODRM, PARAM_RMPTR, PARAM_IMM, 0 }, {"enter", 0, PARAM_UI16, PARAM_UI8, 0 }, {"leave", 0, 0, 0, 0 }, - {"retf", 0, PARAM_UI16, 0, 0, DASMFLAG_STEP_OUT}, - {"retf", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, - {"int 3", 0, 0, 0, 0, DASMFLAG_STEP_OVER}, - {"int", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, + {"retf", 0, PARAM_UI16, 0, 0, STEP_OUT}, + {"retf", 0, 0, 0, 0, STEP_OUT}, + {"int 3", 0, 0, 0, 0, STEP_OVER}, + {"int", 0, PARAM_UI8, 0, 0, STEP_OVER}, {"into", 0, 0, 0, 0 }, - {"iret", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, + {"iret", 0, 0, 0, 0, STEP_OUT}, // 0xd0 {"groupD0", GROUP, 0, 0, 0 }, {"groupD1", GROUP, 0, 0, 0 }, @@ -358,15 +250,15 @@ static const I386_OPCODE i386_opcode_table1[256] = {"escape", FPU, 0, 0, 0 }, {"escape", FPU, 0, 0, 0 }, // 0xe0 - {"loopne", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, - {"loopz", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, - {"loop", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, + {"loopne", 0, PARAM_REL8, 0, 0, STEP_OVER}, + {"loopz", 0, PARAM_REL8, 0, 0, STEP_OVER}, + {"loop", 0, PARAM_REL8, 0, 0, STEP_OVER}, {"jcxz\0jecxz\0jrcxz",VAR_NAME, PARAM_REL8, 0, 0 }, {"in", 0, PARAM_AL, PARAM_UI8, 0 }, {"in", 0, PARAM_EAX, PARAM_UI8, 0 }, {"out", 0, PARAM_UI8, PARAM_AL, 0 }, {"out", 0, PARAM_UI8, PARAM_EAX, 0 }, - {"call", 0, PARAM_REL, 0, 0, DASMFLAG_STEP_OVER}, + {"call", 0, PARAM_REL, 0, 0, STEP_OVER}, {"jmp", 0, PARAM_REL, 0, 0 }, {"jmp", 0, PARAM_ADDR, 0, 0 }, {"jmp", 0, PARAM_REL8, 0, 0 }, @@ -393,12 +285,12 @@ static const I386_OPCODE i386_opcode_table1[256] = {"groupFF", GROUP, 0, 0, 0 } }; -static const I386_OPCODE x64_opcode_alt[] = +const i386_disassembler::I386_OPCODE i386_disassembler::x64_opcode_alt[] = { {"movsxd", MODRM | ALWAYS64,PARAM_REG, PARAM_RMPTR32, 0 }, }; -static const I386_OPCODE i386_opcode_table2[256] = +const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table2[256] = { // 0x00 {"group0F00", GROUP, 0, 0, 0 }, @@ -724,7 +616,7 @@ static const I386_OPCODE i386_opcode_table2[256] = {"bsr\0" "???\0" "???\0" - "lzcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0, DASMFLAG_STEP_OVER}, + "lzcnt", MODRM|VAR_NAME4, PARAM_REG, PARAM_RM, 0, STEP_OVER}, {"movsx", MODRM, PARAM_REG, PARAM_RMPTR8, 0 }, {"movsx", MODRM, PARAM_REG, PARAM_RMPTR16, 0 }, // 0xc0 @@ -821,7 +713,7 @@ static const I386_OPCODE i386_opcode_table2[256] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE i386_opcode_table0F38[256] = +const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table0F38[256] = { // 0x00 {"pshufb\0" @@ -1265,7 +1157,7 @@ static const I386_OPCODE i386_opcode_table0F38[256] = {"???", 0, 0, 0, 0 }, }; -static const I386_OPCODE i386_opcode_table0F3A[256] = +const i386_disassembler::I386_OPCODE i386_disassembler::i386_opcode_table0F3A[256] = { // 0x00 {"???", 0, 0, 0, 0 }, @@ -1613,7 +1505,7 @@ static const I386_OPCODE i386_opcode_table0F3A[256] = {"???", 0, 0, 0, 0 }, }; -static const I386_OPCODE group80_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group80_table[8] = { {"add", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"or", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, @@ -1625,7 +1517,7 @@ static const I386_OPCODE group80_table[8] = {"cmp", 0, PARAM_RMPTR8, PARAM_UI8, 0 } }; -static const I386_OPCODE group81_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group81_table[8] = { {"add", 0, PARAM_RMPTR, PARAM_IMM, 0 }, {"or", 0, PARAM_RMPTR, PARAM_IMM, 0 }, @@ -1637,7 +1529,7 @@ static const I386_OPCODE group81_table[8] = {"cmp", 0, PARAM_RMPTR, PARAM_IMM, 0 } }; -static const I386_OPCODE group83_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group83_table[8] = { {"add", 0, PARAM_RMPTR, PARAM_I8, 0 }, {"or", 0, PARAM_RMPTR, PARAM_I8, 0 }, @@ -1649,7 +1541,7 @@ static const I386_OPCODE group83_table[8] = {"cmp", 0, PARAM_RMPTR, PARAM_I8, 0 } }; -static const I386_OPCODE groupC0_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupC0_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, @@ -1661,7 +1553,7 @@ static const I386_OPCODE groupC0_table[8] = {"sar", 0, PARAM_RMPTR8, PARAM_UI8, 0 } }; -static const I386_OPCODE groupC1_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupC1_table[8] = { {"rol", 0, PARAM_RMPTR, PARAM_UI8, 0 }, {"ror", 0, PARAM_RMPTR, PARAM_UI8, 0 }, @@ -1673,7 +1565,7 @@ static const I386_OPCODE groupC1_table[8] = {"sar", 0, PARAM_RMPTR, PARAM_UI8, 0 } }; -static const I386_OPCODE groupD0_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupD0_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_1, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_1, 0 }, @@ -1685,7 +1577,7 @@ static const I386_OPCODE groupD0_table[8] = {"sar", 0, PARAM_RMPTR8, PARAM_1, 0 } }; -static const I386_OPCODE groupD1_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupD1_table[8] = { {"rol", 0, PARAM_RMPTR, PARAM_1, 0 }, {"ror", 0, PARAM_RMPTR, PARAM_1, 0 }, @@ -1697,7 +1589,7 @@ static const I386_OPCODE groupD1_table[8] = {"sar", 0, PARAM_RMPTR, PARAM_1, 0 } }; -static const I386_OPCODE groupD2_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupD2_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_CL, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_CL, 0 }, @@ -1709,7 +1601,7 @@ static const I386_OPCODE groupD2_table[8] = {"sar", 0, PARAM_RMPTR8, PARAM_CL, 0 } }; -static const I386_OPCODE groupD3_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupD3_table[8] = { {"rol", 0, PARAM_RMPTR, PARAM_CL, 0 }, {"ror", 0, PARAM_RMPTR, PARAM_CL, 0 }, @@ -1721,7 +1613,7 @@ static const I386_OPCODE groupD3_table[8] = {"sar", 0, PARAM_RMPTR, PARAM_CL, 0 } }; -static const I386_OPCODE groupF6_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupF6_table[8] = { {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, @@ -1733,7 +1625,7 @@ static const I386_OPCODE groupF6_table[8] = {"idiv", 0, PARAM_RMPTR8, 0, 0 } }; -static const I386_OPCODE groupF7_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupF7_table[8] = { {"test", 0, PARAM_RMPTR, PARAM_IMM, 0 }, {"test", 0, PARAM_RMPTR, PARAM_IMM, 0 }, @@ -1745,7 +1637,7 @@ static const I386_OPCODE groupF7_table[8] = {"idiv", 0, PARAM_RMPTR, 0, 0 } }; -static const I386_OPCODE groupFE_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupFE_table[8] = { {"inc", 0, PARAM_RMPTR8, 0, 0 }, {"dec", 0, PARAM_RMPTR8, 0, 0 }, @@ -1757,19 +1649,19 @@ static const I386_OPCODE groupFE_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE groupFF_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::groupFF_table[8] = { {"inc", 0, PARAM_RMPTR, 0, 0 }, {"dec", 0, PARAM_RMPTR, 0, 0 }, - {"call", ALWAYS64, PARAM_RMPTR, 0, 0, DASMFLAG_STEP_OVER}, - {"call far ptr ",0, PARAM_RM, 0, 0, DASMFLAG_STEP_OVER}, + {"call", ALWAYS64, PARAM_RMPTR, 0, 0, STEP_OVER}, + {"call far ptr ",0, PARAM_RM, 0, 0, STEP_OVER}, {"jmp", ALWAYS64, PARAM_RMPTR, 0, 0 }, {"jmp far ptr ",0, PARAM_RM, 0, 0 }, {"push", 0, PARAM_RMPTR, 0, 0 }, {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F00_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F00_table[8] = { {"sldt", 0, PARAM_RM, 0, 0 }, {"str", 0, PARAM_RM, 0, 0 }, @@ -1781,7 +1673,7 @@ static const I386_OPCODE group0F00_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F01_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F01_table[8] = { {"sgdt", 0, PARAM_RM, 0, 0 }, {"sidt", 0, PARAM_RM, 0, 0 }, @@ -1793,7 +1685,7 @@ static const I386_OPCODE group0F01_table[8] = {"invlpg", 0, PARAM_RM, 0, 0 } }; -static const I386_OPCODE group0F0D_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F0D_table[8] = { {"prefetch", 0, PARAM_RM8, 0, 0 }, {"prefetchw", 0, PARAM_RM8, 0, 0 }, @@ -1805,7 +1697,7 @@ static const I386_OPCODE group0F0D_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F12_table[4] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F12_table[4] = { { "movlps\0" "movlpd\0" @@ -1825,7 +1717,7 @@ static const I386_OPCODE group0F12_table[4] = "movsldup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 } }; -static const I386_OPCODE group0F16_table[4] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F16_table[4] = { { "movhps\0" "movhpd\0" @@ -1845,7 +1737,7 @@ static const I386_OPCODE group0F16_table[4] = "movshdup", VAR_NAME4,PARAM_XMM, PARAM_XMMM, 0 } }; -static const I386_OPCODE group0F18_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F18_table[8] = { {"prefetchnta", 0, PARAM_RM8, 0, 0 }, {"prefetch0", 0, PARAM_RM8, 0, 0 }, @@ -1857,7 +1749,7 @@ static const I386_OPCODE group0F18_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F71_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F71_table[8] = { {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, @@ -1869,7 +1761,7 @@ static const I386_OPCODE group0F71_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F72_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F72_table[8] = { {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, @@ -1881,7 +1773,7 @@ static const I386_OPCODE group0F72_table[8] = {"???", 0, 0, 0, 0 } }; -static const I386_OPCODE group0F73_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0F73_table[8] = { {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, @@ -1893,7 +1785,7 @@ static const I386_OPCODE group0F73_table[8] = {"pslldq", 0, PARAM_MMX2, PARAM_UI8, 0 }, }; -static const I386_OPCODE group0FAE_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0FAE_table[8] = { {"fxsave", 0, PARAM_RM, 0, 0 }, {"fxrstor", 0, PARAM_RM, 0, 0 }, @@ -1906,7 +1798,7 @@ static const I386_OPCODE group0FAE_table[8] = }; -static const I386_OPCODE group0FBA_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0FBA_table[8] = { {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, @@ -1918,7 +1810,7 @@ static const I386_OPCODE group0FBA_table[8] = {"btc", 0, PARAM_RM, PARAM_UI8, 0 } }; -static const I386_OPCODE group0FC7_table[8] = +const i386_disassembler::I386_OPCODE i386_disassembler::group0FC7_table[8] = { {"???", 0, 0, 0, 0 }, {"cmpxchg8b", MODRM, PARAM_M64PTR, 0, 0 }, @@ -1933,7 +1825,7 @@ static const I386_OPCODE group0FC7_table[8] = {"vmptrtst", MODRM, PARAM_M64PTR, 0, 0 } }; -static const GROUP_OP group_op_table[] = +const i386_disassembler::GROUP_OP i386_disassembler::group_op_table[] = { { "group80", group80_table }, { "group81", group81_table }, @@ -1964,98 +1856,60 @@ static const GROUP_OP group_op_table[] = -static const char *const i386_reg[3][16] = +const char *const i386_disassembler::i386_reg[3][16] = { {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w","r11w","r12w","r13w","r14w","r15w"}, {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d","r11d","r12d","r13d","r14d","r15d"}, {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"} }; -static const char *const i386_reg8[8] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}; -static const char *const i386_reg8rex[16] = {"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"}; -static const char *const i386_sreg[8] = {"es", "cs", "ss", "ds", "fs", "gs", "???", "???"}; - -static int address_size; -static int operand_size; -static int address_prefix; -static int operand_prefix; -static int max_length; -static uint64_t pc; -static uint8_t modrm; -static uint32_t segment; -static offs_t dasm_flags; -static std::string modrm_string; -static uint8_t rex, regex, sibex, rmex; -static uint8_t pre0f; -static uint8_t curmode; - -#define MODRM_REG1 ((modrm >> 3) & 0x7) -#define MODRM_REG2 (modrm & 0x7) -#define MODRM_MOD ((modrm >> 6) & 0x3) - -static inline uint8_t FETCH(void) +const char *const i386_disassembler::i386_reg8[8] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"}; +const char *const i386_disassembler::i386_reg8rex[16] = {"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"}; +const char *const i386_disassembler::i386_sreg[8] = {"es", "cs", "ss", "ds", "fs", "gs", "???", "???"}; + +inline uint8_t i386_disassembler::FETCH(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - if ((opcode_ptr - opcode_ptr_base) + 1 > max_length) + if ((pc - base_pc) + 1 > max_length) return 0xff; + uint8_t d = opcodes.r8(pc); pc++; - return *opcode_ptr++; + return d; } -#if 0 -static inline uint16_t FETCH16(void) +inline uint16_t i386_disassembler::FETCH16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - uint16_t d; - if ((opcode_ptr - opcode_ptr_base) + 2 > max_length) + if ((pc - base_pc) + 2 > max_length) return 0xffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8); - opcode_ptr += 2; + uint16_t d = opcodes.r16(pc); pc += 2; return d; } -#endif -static inline uint32_t FETCH32(void) +inline uint32_t i386_disassembler::FETCH32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - uint32_t d; - if ((opcode_ptr - opcode_ptr_base) + 4 > max_length) + if ((pc - base_pc) + 4 > max_length) return 0xffffffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8) | (opcode_ptr[2] << 16) | (opcode_ptr[3] << 24); - opcode_ptr += 4; + uint32_t d = opcodes.r32(pc); pc += 4; return d; } -static inline uint8_t FETCHD(void) +inline uint8_t i386_disassembler::FETCHD(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - if ((opcode_ptr - opcode_ptr_base) + 1 > max_length) - return 0xff; - pc++; - return *opcode_ptr++; + return FETCH(base_pc, pc, opcodes); } -static inline uint16_t FETCHD16(void) +inline uint16_t i386_disassembler::FETCHD16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - uint16_t d; - if ((opcode_ptr - opcode_ptr_base) + 2 > max_length) - return 0xffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8); - opcode_ptr += 2; - pc += 2; - return d; + return FETCH16(base_pc, pc, opcodes); } -static inline uint32_t FETCHD32(void) +inline uint32_t i386_disassembler::FETCHD32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { - uint32_t d; - if ((opcode_ptr - opcode_ptr_base) + 4 > max_length) - return 0xffffffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8) | (opcode_ptr[2] << 16) | (opcode_ptr[3] << 24); - opcode_ptr += 4; - pc += 4; - return d; + return FETCH32(base_pc, pc, opcodes); } -static char *hexstring(uint32_t value, int digits) +char *i386_disassembler::hexstring(uint32_t value, int digits) { static char buffer[20]; buffer[0] = '0'; @@ -2066,7 +1920,7 @@ static char *hexstring(uint32_t value, int digits) return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0]; } -static char *hexstring64(uint32_t lo, uint32_t hi) +char *i386_disassembler::hexstring64(uint32_t lo, uint32_t hi) { static char buffer[40]; buffer[0] = '0'; @@ -2077,15 +1931,15 @@ static char *hexstring64(uint32_t lo, uint32_t hi) return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0]; } -static char *hexstringpc(uint64_t pc) +char *i386_disassembler::hexstringpc(uint64_t pc) { - if (curmode == 64) + if (m_config->get_mode() == 64) return hexstring64((uint32_t)pc, (uint32_t)(pc >> 32)); else return hexstring((uint32_t)pc, 0); } -static char *shexstring(uint32_t value, int digits, bool always) +char *i386_disassembler::shexstring(uint32_t value, int digits, bool always) { static char buffer[20]; if (value >= 0x80000000) @@ -2097,18 +1951,18 @@ static char *shexstring(uint32_t value, int digits, bool always) return buffer; } -static void handle_sib_byte(std::ostream &stream, uint8_t mod) +void i386_disassembler::handle_sib_byte(std::ostream &stream, uint8_t mod, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { uint32_t i32; uint8_t scale, i, base; - uint8_t sib = FETCHD(); + uint8_t sib = FETCHD(base_pc, pc, opcodes); scale = (sib >> 6) & 0x3; i = ((sib >> 3) & 0x7) | sibex; base = (sib & 0x7) | rmex; if (base == 5 && mod == 0) { - i32 = FETCH32(); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i32, 0)); } else if (base != 5 || mod != 3) util::stream_format(stream, "%s", i386_reg[address_size][base]); @@ -2120,14 +1974,14 @@ static void handle_sib_byte(std::ostream &stream, uint8_t mod) } } -static void handle_modrm(std::ostream &stream) +void i386_disassembler::handle_modrm(std::ostream &stream, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { int8_t disp8; int16_t disp16; int32_t disp32; uint8_t mod, rm; - modrm = FETCHD(); + modrm = FETCHD(base_pc, pc, opcodes); mod = (modrm >> 6) & 0x3; rm = (modrm & 0x7) | rmex; @@ -2147,38 +2001,38 @@ static void handle_modrm(std::ostream &stream) util::stream_format(stream, "[" ); if( address_size == 2 ) { if ((rm & 7) == 4) - handle_sib_byte(stream, mod ); + handle_sib_byte(stream, mod, base_pc, pc, opcodes); else if ((rm & 7) == 5 && mod == 0) { - disp32 = FETCHD32(); + disp32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "rip%s", shexstring(disp32, 0, true)); } else util::stream_format(stream, "%s", i386_reg[2][rm]); if( mod == 1 ) { - disp8 = FETCHD(); + disp8 = FETCHD(base_pc, pc, opcodes); if (disp8 != 0) util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) ); } else if( mod == 2 ) { - disp32 = FETCHD32(); + disp32 = FETCHD32(base_pc, pc, opcodes); if (disp32 != 0) util::stream_format(stream, "%s", shexstring(disp32, 0, true) ); } } else if (address_size == 1) { if ((rm & 7) == 4) - handle_sib_byte(stream, mod ); + handle_sib_byte(stream, mod, base_pc, pc, opcodes); else if ((rm & 7) == 5 && mod == 0) { - disp32 = FETCHD32(); - if (curmode == 64) + disp32 = FETCHD32(base_pc, pc, opcodes); + if (m_config->get_mode() == 64) util::stream_format(stream, "eip%s", shexstring(disp32, 0, true) ); else util::stream_format(stream, "%s", hexstring(disp32, 0) ); } else util::stream_format(stream, "%s", i386_reg[1][rm]); if( mod == 1 ) { - disp8 = FETCHD(); + disp8 = FETCHD(base_pc, pc, opcodes); if (disp8 != 0) util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) ); } else if( mod == 2 ) { - disp32 = FETCHD32(); + disp32 = FETCHD32(base_pc, pc, opcodes); if (disp32 != 0) util::stream_format(stream, "%s", shexstring(disp32, 0, true) ); } @@ -2193,7 +2047,7 @@ static void handle_modrm(std::ostream &stream) case 5: util::stream_format(stream, "di" ); break; case 6: if( mod == 0 ) { - disp16 = FETCHD16(); + disp16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring((unsigned) (uint16_t) disp16, 0) ); } else { util::stream_format(stream, "bp" ); @@ -2202,11 +2056,11 @@ static void handle_modrm(std::ostream &stream) case 7: util::stream_format(stream, "bx" ); break; } if( mod == 1 ) { - disp8 = FETCHD(); + disp8 = FETCHD(base_pc, pc, opcodes); if (disp8 != 0) util::stream_format(stream, "%s", shexstring((int32_t)disp8, 0, true) ); } else if( mod == 2 ) { - disp16 = FETCHD16(); + disp16 = FETCHD16(base_pc, pc, opcodes); if (disp16 != 0) util::stream_format(stream, "%s", shexstring((int32_t)disp16, 0, true) ); } @@ -2214,14 +2068,14 @@ static void handle_modrm(std::ostream &stream) util::stream_format(stream, "]" ); } -static void handle_modrm(std::string &buffer) +void i386_disassembler::handle_modrm(std::string &buffer, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { std::stringstream stream; - handle_modrm(stream); + handle_modrm(stream, base_pc, pc, opcodes); buffer = stream.str(); } -static void handle_param(std::ostream &stream, uint32_t param) +void i386_disassembler::handle_param(std::ostream &stream, uint32_t param, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { uint8_t i8; uint16_t i16; @@ -2235,58 +2089,58 @@ static void handle_param(std::ostream &stream, uint32_t param) switch(param) { case PARAM_REG: - util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG1() | regex] ); break; case PARAM_REG8: - util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG1() | regex] ); break; case PARAM_REG16: - util::stream_format(stream, "%s", i386_reg[0][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[0][MODRM_REG1() | regex] ); break; case PARAM_REG32: - util::stream_format(stream, "%s", i386_reg[1][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[1][MODRM_REG1() | regex] ); break; case PARAM_REG3264: - util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] ); break; case PARAM_MMX: if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG1 | regex ); + util::stream_format(stream, "xmm%d", MODRM_REG1() | regex ); else - util::stream_format(stream, "mm%d", MODRM_REG1 | regex ); + util::stream_format(stream, "mm%d", MODRM_REG1() | regex ); break; case PARAM_MMX2: if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG2 | regex ); + util::stream_format(stream, "xmm%d", MODRM_REG2() | regex ); else - util::stream_format(stream, "mm%d", MODRM_REG2 | regex ); + util::stream_format(stream, "mm%d", MODRM_REG2() | regex ); break; case PARAM_XMM: - util::stream_format(stream, "xmm%d", MODRM_REG1 | regex ); + util::stream_format(stream, "xmm%d", MODRM_REG1() | regex ); break; case PARAM_REGORXMM: if (pre0f != 0xf2 && pre0f != 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG1 | regex ); + util::stream_format(stream, "xmm%d", MODRM_REG1() | regex ); else - util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1 | regex] ); + util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG1() | regex] ); break; case PARAM_REG2_32: - util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2() | rmex] ); break; case PARAM_RM: case PARAM_RMPTR: if( modrm >= 0xc0 ) { - util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[operand_size][MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR) { @@ -2304,7 +2158,7 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RM8: case PARAM_RMPTR8: if( modrm >= 0xc0 ) { - util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", (rex ? i386_reg8rex : i386_reg8)[MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR8) util::stream_format(stream, "byte ptr " ); @@ -2315,7 +2169,7 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RM16: case PARAM_RMPTR16: if( modrm >= 0xc0 ) { - util::stream_format(stream, "%s", i386_reg[0][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[0][MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR16) util::stream_format(stream, "word ptr " ); @@ -2326,7 +2180,7 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RM32: case PARAM_RMPTR32: if( modrm >= 0xc0 ) { - util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[1][MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR32) util::stream_format(stream, "dword ptr " ); @@ -2337,9 +2191,9 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RMXMM: if( modrm >= 0xc0 ) { if (pre0f != 0xf2 && pre0f != 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG2 | rmex ); + util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex ); else - util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG2 | rmex] ); + util::stream_format(stream, "%s", i386_reg[(operand_size == 2) ? 2 : 1][MODRM_REG2() | rmex] ); } else { if (param == PARAM_RMPTR32) util::stream_format(stream, "dword ptr " ); @@ -2361,9 +2215,9 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_MMXM: if( modrm >= 0xc0 ) { if (pre0f == 0x66 || pre0f == 0xf2 || pre0f == 0xf3) - util::stream_format(stream, "xmm%d", MODRM_REG2 | rmex ); + util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex ); else - util::stream_format(stream, "mm%d", MODRM_REG2 | rmex ); + util::stream_format(stream, "mm%d", MODRM_REG2() | rmex ); } else { util::stream_format(stream, "%s", modrm_string ); } @@ -2371,70 +2225,70 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_XMMM: if( modrm >= 0xc0 ) { - util::stream_format(stream, "xmm%d", MODRM_REG2 | rmex ); + util::stream_format(stream, "xmm%d", MODRM_REG2() | rmex ); } else { util::stream_format(stream, "%s", modrm_string ); } break; case PARAM_I4: - i8 = FETCHD(); + i8 = FETCHD(base_pc, pc, opcodes); util::stream_format(stream, "%d", i8 & 0x0f ); break; case PARAM_I8: - i8 = FETCHD(); + i8 = FETCHD(base_pc, pc, opcodes); util::stream_format(stream, "%s", shexstring((int8_t)i8, 0, false) ); break; case PARAM_I16: - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", shexstring((int16_t)i16, 0, false) ); break; case PARAM_UI8: - i8 = FETCHD(); + i8 = FETCHD(base_pc, pc, opcodes); util::stream_format(stream, "%s", shexstring((uint8_t)i8, 0, false) ); break; case PARAM_UI16: - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", shexstring((uint16_t)i16, 0, false) ); break; case PARAM_IMM64: if (operand_size == 2) { - uint32_t lo32 = FETCHD32(); - i32 = FETCHD32(); + uint32_t lo32 = FETCHD32(base_pc, pc, opcodes); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring64(lo32, i32) ); } else if( operand_size ) { - i32 = FETCHD32(); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i32, 0) ); } else { - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i16, 0) ); } break; case PARAM_IMM: if( operand_size ) { - i32 = FETCHD32(); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i32, 0) ); } else { - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstring(i16, 0) ); } break; case PARAM_ADDR: if( operand_size ) { - addr = FETCHD32(); - ptr = FETCHD16(); + addr = FETCHD32(base_pc, pc, opcodes); + ptr = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s:", hexstring(ptr, 4) ); util::stream_format(stream, "%s", hexstring(addr, 0) ); } else { - addr = FETCHD16(); - ptr = FETCHD16(); + addr = FETCHD16(base_pc, pc, opcodes); + ptr = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s:", hexstring(ptr, 4) ); util::stream_format(stream, "%s", hexstring(addr, 0) ); } @@ -2442,17 +2296,17 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_REL: if( operand_size ) { - d32 = FETCHD32(); + d32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstringpc(pc + d32) ); } else { /* make sure to keep the relative offset within the segment */ - d16 = FETCHD16(); + d16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstringpc((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF)) ); } break; case PARAM_REL8: - d8 = FETCHD(); + d8 = FETCHD(base_pc, pc, opcodes); util::stream_format(stream, "%s", hexstringpc(pc + d8) ); break; @@ -2468,10 +2322,10 @@ static void handle_param(std::ostream &stream, uint32_t param) } if( address_size ) { - i32 = FETCHD32(); + i32 = FETCHD32(base_pc, pc, opcodes); util::stream_format(stream, "[%s]", hexstring(i32, 0) ); } else { - i16 = FETCHD16(); + i16 = FETCHD16(base_pc, pc, opcodes); util::stream_format(stream, "[%s]", hexstring(i16, 0) ); } break; @@ -2489,19 +2343,19 @@ static void handle_param(std::ostream &stream, uint32_t param) break; case PARAM_SREG: - util::stream_format(stream, "%s", i386_sreg[MODRM_REG1] ); + util::stream_format(stream, "%s", i386_sreg[MODRM_REG1()] ); break; case PARAM_CREG: - util::stream_format(stream, "cr%d", MODRM_REG1 | regex ); + util::stream_format(stream, "cr%d", MODRM_REG1() | regex ); break; case PARAM_TREG: - util::stream_format(stream, "tr%d", MODRM_REG1 | regex ); + util::stream_format(stream, "tr%d", MODRM_REG1() | regex ); break; case PARAM_DREG: - util::stream_format(stream, "dr%d", MODRM_REG1 | regex ); + util::stream_format(stream, "dr%d", MODRM_REG1() | regex ); break; case PARAM_1: @@ -2536,7 +2390,7 @@ static void handle_param(std::ostream &stream, uint32_t param) } } -static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) +void i386_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { switch (op1 & 0x7) { @@ -2545,8 +2399,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fadd dword ptr %s", modrm_string); break; @@ -2581,8 +2434,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fld dword ptr %s", modrm_string); break; @@ -2645,8 +2497,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fiadd dword ptr %s", modrm_string); break; @@ -2689,8 +2540,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fild dword ptr %s", modrm_string); break; @@ -2739,8 +2589,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fadd qword ptr %s", modrm_string); break; @@ -2786,8 +2635,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fld qword ptr %s", modrm_string); break; @@ -2830,8 +2678,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fiadd word ptr %s", modrm_string); break; @@ -2879,8 +2726,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); switch ((op2 >> 3) & 0x7) { case 0: util::stream_format(stream, "fild word ptr %s", modrm_string); break; @@ -2913,7 +2759,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) } } -static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t op1) +void i386_disassembler::decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t op1, offs_t base_pc, offs_t &pc, const data_buffer &opcodes) { int i; uint8_t op2; @@ -2924,15 +2770,15 @@ static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t o switch( op->flags & FLAGS_MASK ) { case ISREX: - if (curmode == 64) + if (m_config->get_mode() == 64) { rex = op1; operand_size = (op1 & 8) ? 2 : 1; regex = (op1 << 1) & 8; sibex = (op1 << 2) & 8; rmex = (op1 << 3) & 8; - op2 = FETCH(); - decode_opcode(stream, &i386_opcode_table1[op2], op1 ); + op2 = FETCH(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table1[op2], op1, base_pc, pc, opcodes); return; } break; @@ -2944,37 +2790,37 @@ static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t o operand_size ^= 1; operand_prefix = 1; } - op2 = FETCH(); - decode_opcode(stream, &i386_opcode_table1[op2], op2 ); + op2 = FETCH(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes); return; case ADDR_SIZE: rex = regex = sibex = rmex = 0; if(address_prefix == 0) { - if (curmode != 64) + if (m_config->get_mode() != 64) address_size ^= 1; else address_size ^= 3; address_prefix = 1; } - op2 = FETCH(); - decode_opcode(stream, &i386_opcode_table1[op2], op2 ); + op2 = FETCH(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes); return; case TWO_BYTE: - if (&opcode_ptr[-2] >= opcode_ptr_base) - pre0f = opcode_ptr[-2]; - op2 = FETCHD(); - decode_opcode(stream, &i386_opcode_table2[op2], op1 ); + if (pc - 2 >= base_pc) + pre0f = opcodes.r8(pc-2); + op2 = FETCHD(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table2[op2], op1, base_pc, pc, opcodes); return; case THREE_BYTE: - op2 = FETCHD(); - if (opcode_ptr[-2] == 0x38) - decode_opcode(stream, &i386_opcode_table0F38[op2], op1 ); + op2 = FETCHD(base_pc, pc, opcodes); + if (opcodes.r8(pc-2) == 0x38) + decode_opcode(stream, &i386_opcode_table0F38[op2], op1, base_pc, pc, opcodes); else - decode_opcode(stream, &i386_opcode_table0F3A[op2], op1 ); + decode_opcode(stream, &i386_opcode_table0F3A[op2], op1, base_pc, pc, opcodes); return; case SEG_CS: @@ -2985,43 +2831,43 @@ static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t o case SEG_SS: rex = regex = sibex = rmex = 0; segment = op->flags; - op2 = FETCH(); - decode_opcode(stream, &i386_opcode_table1[op2], op2 ); + op2 = FETCH(base_pc, pc, opcodes); + decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes); return; case PREFIX: - op2 = FETCH(); + op2 = FETCH(base_pc, pc, opcodes); if ((op2 != 0x0f) && (op2 != 0x90)) util::stream_format(stream, "%-7s ", op->mnemonic ); if ((op2 == 0x90) && !pre0f) pre0f = op1; - decode_opcode(stream, &i386_opcode_table1[op2], op2 ); + decode_opcode(stream, &i386_opcode_table1[op2], op2, base_pc, pc, opcodes); return; case GROUP: - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) { if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 ) { if (op->flags & GROUP_MOD) - decode_opcode(stream, &group_op_table[i].opcode[MODRM_MOD], op1 ); + decode_opcode(stream, &group_op_table[i].opcode[MODRM_MOD()], op1, base_pc, pc, opcodes); else - decode_opcode(stream, &group_op_table[i].opcode[MODRM_REG1], op1 ); + decode_opcode(stream, &group_op_table[i].opcode[MODRM_REG1()], op1, base_pc, pc, opcodes); return; } } goto handle_unknown; case FPU: - op2 = FETCHD(); - handle_fpu(stream, op1, op2); + op2 = FETCHD(base_pc, pc, opcodes); + handle_fpu(stream, op1, op2, base_pc, pc, opcodes); return; case MODRM: - handle_modrm( modrm_string ); + handle_modrm(modrm_string, base_pc, pc, opcodes); break; } - if ((op->flags & ALWAYS64) && curmode == 64) + if ((op->flags & ALWAYS64) && m_config->get_mode() == 64) operand_size = 2; if ((op->flags & VAR_NAME) && operand_size > 0) @@ -3044,17 +2890,17 @@ static void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t o dasm_flags = op->dasm_flags; if( op->param1 != 0 ) { - handle_param(stream, op->param1 ); + handle_param(stream, op->param1, base_pc, pc, opcodes); } if( op->param2 != 0 ) { util::stream_format(stream, "," ); - handle_param(stream, op->param2 ); + handle_param(stream, op->param2, base_pc, pc, opcodes); } if( op->param3 != 0 ) { util::stream_format(stream, "," ); - handle_param(stream, op->param3 ); + handle_param(stream, op->param3, base_pc, pc, opcodes); } return; @@ -3062,12 +2908,12 @@ handle_unknown: util::stream_format(stream, "???"); } -int i386_dasm_one_ex(std::ostream &stream, uint64_t eip, const uint8_t *oprom, int mode) +offs_t i386_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { + offs_t base_pc = pc; uint8_t op; - opcode_ptr = opcode_ptr_base = oprom; - switch(mode) + switch(m_config->get_mode()) { case 1: /* 8086/8088/80186/80188 */ address_size = 0; @@ -3095,37 +2941,24 @@ int i386_dasm_one_ex(std::ostream &stream, uint64_t eip, const uint8_t *oprom, i max_length = 15; break; } - pc = eip; dasm_flags = 0; segment = 0; - curmode = mode; pre0f = 0; rex = regex = sibex = rmex = 0; address_prefix = 0; operand_prefix = 0; - op = FETCH(); + op = FETCH(base_pc, pc, opcodes); - decode_opcode( stream, &i386_opcode_table1[op], op ); - return (pc-eip) | dasm_flags | DASMFLAG_SUPPORTED; -} - -int i386_dasm_one(std::ostream &stream, offs_t eip, const uint8_t *oprom, int mode) -{ - return i386_dasm_one_ex(stream, eip, oprom, mode); -} - -CPU_DISASSEMBLE( x86_16 ) -{ - return i386_dasm_one_ex(stream, pc, oprom, 16); + decode_opcode( stream, &i386_opcode_table1[op], op, base_pc, pc, opcodes); + return (pc-base_pc) | dasm_flags | SUPPORTED; } -CPU_DISASSEMBLE( x86_32 ) +i386_disassembler::i386_disassembler(config *conf) : m_config(conf) { - return i386_dasm_one_ex(stream, pc, oprom, 32); } -CPU_DISASSEMBLE( x86_64 ) +u32 i386_disassembler::opcode_alignment() const { - return i386_dasm_one_ex(stream, pc, oprom, 64); + return 1; } diff --git a/src/devices/cpu/i386/i386dasm.h b/src/devices/cpu/i386/i386dasm.h index 42142bee675..25f5ec0d4d6 100644 --- a/src/devices/cpu/i386/i386dasm.h +++ b/src/devices/cpu/i386/i386dasm.h @@ -1,5 +1,216 @@ // license:BSD-3-Clause // copyright-holders:Ville Linde, Peter Ferrie -extern int i386_dasm_one(std::ostream &stream, uint32_t pc, const uint8_t *oprom, int mode); -extern int i386_dasm_one_ex(std::ostream &stream, uint64_t eip, const uint8_t *oprom, int mode); +#ifndef MAME_CPU_I386_I386DASM_H +#define MAME_CPU_I386_I386DASM_H + +#pragma once + +class i386_disassembler : public util::disasm_interface +{ +public: + class config { + public: + virtual ~config() = default; + virtual int get_mode() const = 0; + }; + + i386_disassembler(config *conf); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum + { + PARAM_REG = 1, /* 16 or 32-bit register */ + PARAM_REG8, /* 8-bit register */ + PARAM_REG16, /* 16-bit register */ + PARAM_REG32, /* 32-bit register */ + PARAM_REG3264, /* 32-bit or 64-bit register */ + PARAM_REG2_32, /* 32-bit register */ + PARAM_MMX, /* MMX register */ + PARAM_MMX2, /* MMX register in modrm */ + PARAM_XMM, /* XMM register */ + PARAM_RM, /* 16 or 32-bit memory or register */ + PARAM_RM8, /* 8-bit memory or register */ + PARAM_RM16, /* 16-bit memory or register */ + PARAM_RM32, /* 32-bit memory or register */ + PARAM_RMPTR, /* 16 or 32-bit memory or register */ + PARAM_RMPTR8, /* 8-bit memory or register */ + PARAM_RMPTR16, /* 16-bit memory or register */ + PARAM_RMPTR32, /* 32-bit memory or register */ + PARAM_RMXMM, /* 32 or 64-bit memory or register */ + PARAM_REGORXMM, /* 32 or 64-bit register or XMM register */ + PARAM_M64, /* 64-bit memory */ + PARAM_M64PTR, /* 64-bit memory */ + PARAM_MMXM, /* 64-bit memory or MMX register */ + PARAM_XMMM, /* 128-bit memory or XMM register */ + PARAM_I4, /* 4-bit signed immediate */ + PARAM_I8, /* 8-bit signed immediate */ + PARAM_I16, /* 16-bit signed immediate */ + PARAM_UI8, /* 8-bit unsigned immediate */ + PARAM_UI16, /* 16-bit unsigned immediate */ + PARAM_IMM, /* 16 or 32-bit immediate */ + PARAM_IMM64, /* 16, 32 or 64-bit immediate */ + PARAM_ADDR, /* 16:16 or 16:32 address */ + PARAM_REL, /* 16 or 32-bit PC-relative displacement */ + PARAM_REL8, /* 8-bit PC-relative displacement */ + PARAM_MEM_OFFS, /* 16 or 32-bit mem offset */ + PARAM_PREIMP, /* prefix with implicit register */ + PARAM_SREG, /* segment register */ + PARAM_CREG, /* control register */ + PARAM_DREG, /* debug register */ + PARAM_TREG, /* test register */ + PARAM_1, /* used by shift/rotate instructions */ + PARAM_AL, + PARAM_CL, + PARAM_DL, + PARAM_BL, + PARAM_AH, + PARAM_CH, + PARAM_DH, + PARAM_BH, + PARAM_DX, + PARAM_EAX, /* EAX or AX */ + PARAM_ECX, /* ECX or CX */ + PARAM_EDX, /* EDX or DX */ + PARAM_EBX, /* EBX or BX */ + PARAM_ESP, /* ESP or SP */ + PARAM_EBP, /* EBP or BP */ + PARAM_ESI, /* ESI or SI */ + PARAM_EDI, /* EDI or DI */ + PARAM_XMM0, + PARAM_XMM64, /* 64-bit memory or XMM register */ + PARAM_XMM32, /* 32-bit memory or XMM register */ + PARAM_XMM16 /* 16-bit memory or XMM register */ + }; + + enum + { + MODRM = 1, + GROUP, + FPU, + OP_SIZE, + ADDR_SIZE, + TWO_BYTE, + PREFIX, + SEG_CS, + SEG_DS, + SEG_ES, + SEG_FS, + SEG_GS, + SEG_SS, + ISREX, + THREE_BYTE /* [prefix] 0f op1 op2 and then mod/rm */ + }; + + enum { + FLAGS_MASK = 0x0ff, + VAR_NAME = 0x100, + VAR_NAME4 = 0x200, + ALWAYS64 = 0x400, + SPECIAL64 = 0x800, + GROUP_MOD = 0x1000 + }; + + struct I386_OPCODE { + const char *mnemonic; + u32 flags; + u32 param1; + u32 param2; + u32 param3; + offs_t dasm_flags; + }; + + struct GROUP_OP { + char mnemonic[32]; + const I386_OPCODE *opcode; + }; + + static constexpr u32 SPECIAL64_ENT(u32 x) { + return SPECIAL64 | (x << 24); + } + + static const I386_OPCODE i386_opcode_table1[256]; + static const I386_OPCODE x64_opcode_alt[]; + static const I386_OPCODE i386_opcode_table2[256]; + static const I386_OPCODE i386_opcode_table0F38[256]; + static const I386_OPCODE i386_opcode_table0F3A[256]; + static const I386_OPCODE group80_table[8]; + static const I386_OPCODE group81_table[8]; + static const I386_OPCODE group83_table[8]; + static const I386_OPCODE groupC0_table[8]; + static const I386_OPCODE groupC1_table[8]; + static const I386_OPCODE groupD0_table[8]; + static const I386_OPCODE groupD1_table[8]; + static const I386_OPCODE groupD2_table[8]; + static const I386_OPCODE groupD3_table[8]; + static const I386_OPCODE groupF6_table[8]; + static const I386_OPCODE groupF7_table[8]; + static const I386_OPCODE groupFE_table[8]; + static const I386_OPCODE groupFF_table[8]; + static const I386_OPCODE group0F00_table[8]; + static const I386_OPCODE group0F01_table[8]; + static const I386_OPCODE group0F0D_table[8]; + static const I386_OPCODE group0F12_table[4]; + static const I386_OPCODE group0F16_table[4]; + static const I386_OPCODE group0F18_table[8]; + static const I386_OPCODE group0F71_table[8]; + static const I386_OPCODE group0F72_table[8]; + static const I386_OPCODE group0F73_table[8]; + static const I386_OPCODE group0FAE_table[8]; + static const I386_OPCODE group0FBA_table[8]; + static const I386_OPCODE group0FC7_table[8]; + static const GROUP_OP group_op_table[]; + static const char *const i386_reg[3][16]; + static const char *const i386_reg8[8]; + static const char *const i386_reg8rex[16]; + static const char *const i386_sreg[8]; + + config *m_config; + + int address_size; + int operand_size; + int address_prefix; + int operand_prefix; + int max_length; + uint8_t modrm; + uint32_t segment; + offs_t dasm_flags; + std::string modrm_string; + uint8_t rex, regex, sibex, rmex; + uint8_t pre0f; + + inline u8 MODRM_REG1() const { + return (modrm >> 3) & 0x7; + } + + inline u8 MODRM_REG2() const { + return modrm & 0x7; + } + + inline u8 MODRM_MOD() const { + return (modrm >> 6) & 0x7; + } + + inline uint8_t FETCH(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint16_t FETCH16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint32_t FETCH32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint8_t FETCHD(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint16_t FETCHD16(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + inline uint32_t FETCHD32(offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + + char *hexstring(uint32_t value, int digits); + char *hexstring64(uint32_t lo, uint32_t hi); + char *hexstringpc(uint64_t pc); + char *shexstring(uint32_t value, int digits, bool always); + void handle_sib_byte(std::ostream &stream, uint8_t mod, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void handle_modrm(std::ostream &stream, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void handle_modrm(std::string &buffer, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void handle_param(std::ostream &stream, uint32_t param, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); + void decode_opcode(std::ostream &stream, const I386_OPCODE *op, uint8_t op1, offs_t base_pc, offs_t &pc, const data_buffer &opcodes); +}; + +#endif diff --git a/src/devices/cpu/i8008/8008dasm.cpp b/src/devices/cpu/i8008/8008dasm.cpp index 66be08a40b7..88d2cacf88b 100644 --- a/src/devices/cpu/i8008/8008dasm.cpp +++ b/src/devices/cpu/i8008/8008dasm.cpp @@ -9,18 +9,21 @@ *****************************************************************************/ #include "emu.h" +#include "8008dasm.h" -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] +const char i8008_disassembler::reg[] = { 'a', 'b', 'c', 'd', 'e', 'h', 'l', 'm' }; +const char i8008_disassembler::flag_names[] = { 'c', 'z', 's', 'p' }; -static const char reg[] = { 'a', 'b', 'c', 'd', 'e', 'h', 'l', 'm' }; -static const char flag_names[] = { 'c', 'z', 's', 'p' }; +u32 i8008_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(i8008) +offs_t i8008_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; unsigned PC = pc; - uint8_t op = OP(pc++); + uint8_t op = opcodes.r8(pc++); switch (op >> 6) { case 0x03: // starting with 11 @@ -65,28 +68,28 @@ CPU_DISASSEMBLE(i8008) case 3 : util::stream_format(stream, "r%c%c",(BIT(op,5) ? 't' : 'f'),flag_names[(op>>3)&3]); break; case 4 : { switch((op >> 3) & 7) { - case 0 : util::stream_format(stream, "adi %02x",ARG(pc)); pc++; break; - case 1 : util::stream_format(stream, "aci %02x",ARG(pc)); pc++; break; - case 2 : util::stream_format(stream, "sui %02x",ARG(pc)); pc++; break; - case 3 : util::stream_format(stream, "sbi %02x",ARG(pc)); pc++; break; - case 4 : util::stream_format(stream, "ndi %02x",ARG(pc)); pc++; break; - case 5 : util::stream_format(stream, "xri %02x",ARG(pc)); pc++; break; - case 6 : util::stream_format(stream, "ori %02x",ARG(pc)); pc++; break; - case 7 : util::stream_format(stream, "cpi %02x",ARG(pc)); pc++; break; + case 0 : util::stream_format(stream, "adi %02x",params.r8(pc)); pc++; break; + case 1 : util::stream_format(stream, "aci %02x",params.r8(pc)); pc++; break; + case 2 : util::stream_format(stream, "sui %02x",params.r8(pc)); pc++; break; + case 3 : util::stream_format(stream, "sbi %02x",params.r8(pc)); pc++; break; + case 4 : util::stream_format(stream, "ndi %02x",params.r8(pc)); pc++; break; + case 5 : util::stream_format(stream, "xri %02x",params.r8(pc)); pc++; break; + case 6 : util::stream_format(stream, "ori %02x",params.r8(pc)); pc++; break; + case 7 : util::stream_format(stream, "cpi %02x",params.r8(pc)); pc++; break; } } break; case 5 : util::stream_format(stream, "rst %02x",(op>>3) & 7); break; - case 6 : util::stream_format(stream, "l%ci %02x",reg[(op >> 3) & 7],ARG(pc)); pc++; break; + case 6 : util::stream_format(stream, "l%ci %02x",reg[(op >> 3) & 7],params.r8(pc)); pc++; break; case 7 : util::stream_format(stream, "ret"); break; } break; case 0x01: // starting with 01 switch(op & 7) { - case 0 : util::stream_format(stream, "j%c%c %02x%02x",(BIT(op,5)? 't' : 'f'),flag_names[(op>>3)&3], ARG(pc+1) & 0x3f,ARG(pc)); pc+=2; break; - case 2 : util::stream_format(stream, "c%c%c %02x%02x",(BIT(op,5)? 't' : 'f'),flag_names[(op>>3)&3], ARG(pc+1) & 0x3f,ARG(pc)); pc+=2; break; - case 4 : util::stream_format(stream, "jmp %02x%02x",ARG(pc+1) & 0x3f,ARG(pc)); pc+=2; break; - case 6 : util::stream_format(stream, "cal %02x%02x",ARG(pc+1) & 0x3f,ARG(pc)); pc+=2; break; + case 0 : util::stream_format(stream, "j%c%c %02x%02x",(BIT(op,5)? 't' : 'f'),flag_names[(op>>3)&3], params.r8(pc+1) & 0x3f,params.r8(pc)); pc+=2; break; + case 2 : util::stream_format(stream, "c%c%c %02x%02x",(BIT(op,5)? 't' : 'f'),flag_names[(op>>3)&3], params.r8(pc+1) & 0x3f,params.r8(pc)); pc+=2; break; + case 4 : util::stream_format(stream, "jmp %02x%02x",params.r8(pc+1) & 0x3f,params.r8(pc)); pc+=2; break; + case 6 : util::stream_format(stream, "cal %02x%02x",params.r8(pc+1) & 0x3f,params.r8(pc)); pc+=2; break; case 1 : case 3 : case 5 : @@ -111,5 +114,5 @@ CPU_DISASSEMBLE(i8008) } break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; } diff --git a/src/devices/cpu/i8008/8008dasm.h b/src/devices/cpu/i8008/8008dasm.h new file mode 100644 index 00000000000..a5cb209dda6 --- /dev/null +++ b/src/devices/cpu/i8008/8008dasm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Miodrag Milanovic +/***************************************************************************** + * + * 8008dasm.c + * + * Intel 8008 CPU Disassembly + * + *****************************************************************************/ + +#ifndef MAME_CPU_I8008_8008DASM_H +#define MAME_CPU_I8008_8008DASM_H + +#pragma once + +class i8008_disassembler : public util::disasm_interface +{ +public: + i8008_disassembler() = default; + virtual ~i8008_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char reg[]; + static const char flag_names[]; + +}; + +#endif diff --git a/src/devices/cpu/i8008/i8008.cpp b/src/devices/cpu/i8008/i8008.cpp index 6baa28a766b..9b687eec92a 100644 --- a/src/devices/cpu/i8008/i8008.cpp +++ b/src/devices/cpu/i8008/i8008.cpp @@ -9,6 +9,7 @@ *****************************************************************************/ #include "emu.h" #include "i8008.h" +#include "8008dasm.h" #include "debugger.h" //************************************************************************** @@ -52,7 +53,7 @@ void i8008_device::device_start() { // find address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); // save state @@ -203,34 +204,13 @@ void i8008_device::state_string_export(const device_state_entry &entry, std::str } //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t i8008_device::disasm_min_opcode_bytes() const -{ - return 1; -} - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t i8008_device::disasm_max_opcode_bytes() const -{ - return 3; -} - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t i8008_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8008_device::create_disassembler() { - extern CPU_DISASSEMBLE( i8008 ); - return CPU_DISASSEMBLE_NAME(i8008)(this, stream, pc, oprom, opram, options); + return new i8008_disassembler; } //************************************************************************** diff --git a/src/devices/cpu/i8008/i8008.h b/src/devices/cpu/i8008/i8008.h index b6450fcf5e5..ea473df22af 100644 --- a/src/devices/cpu/i8008/i8008.h +++ b/src/devices/cpu/i8008/i8008.h @@ -42,11 +42,8 @@ protected: virtual void state_export(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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one(int opcode); @@ -86,7 +83,7 @@ protected: address_space *m_program; address_space *m_io; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; }; // device type definition diff --git a/src/devices/cpu/i8085/8085dasm.cpp b/src/devices/cpu/i8085/8085dasm.cpp index 5f898c86464..36d4640afb5 100644 --- a/src/devices/cpu/i8085/8085dasm.cpp +++ b/src/devices/cpu/i8085/8085dasm.cpp @@ -2,544 +2,284 @@ // copyright-holders:Juergen Buchmueller /***************************************************************************** * - * 8085dasm.c * Portable I8085A disassembler * + * TODO: + * - add I8080? + * *****************************************************************************/ #include "emu.h" +#include "8085dasm.h" -/* 8080/8085A mnemonics were more irritation than information - What would you guess "CP $3456" to mean? It's not compare, - but call if plus ... therefore: */ -//#define Z80_MNEMONICS - -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] -#define ARGW(A) (opram[(A) - PC] | (opram[(A) + 1 - PC] << 8)) +u32 i8085_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(i8085) +offs_t i8085_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t flags = 0; + offs_t flags = 0; uint8_t op; - unsigned PC = pc; - switch (op = OP(pc++)) + unsigned prevpc = pc; + switch (op = opcodes.r8(pc++)) { -#ifdef Z80_MNEMONICS - case 0x00: util::stream_format(stream, "nop"); break; - case 0x01: util::stream_format(stream, "ld bc,$%04x", ARGW(pc)); pc+=2; break; - case 0x02: util::stream_format(stream, "ld (bc),a"); break; - case 0x03: util::stream_format(stream, "inc bc"); break; - case 0x04: util::stream_format(stream, "inc b"); break; - case 0x05: util::stream_format(stream, "dec b"); break; - case 0x06: util::stream_format(stream, "ld b,$%02x", ARG(pc)); pc++; break; - case 0x07: util::stream_format(stream, "rlca"); break; - case 0x08: util::stream_format(stream, "sub hl,bc (*)"); break; - case 0x09: util::stream_format(stream, "add hl,bc"); break; - case 0x0a: util::stream_format(stream, "ld a,(bc)"); break; - case 0x0b: util::stream_format(stream, "dec bc"); break; - case 0x0c: util::stream_format(stream, "inc c"); break; - case 0x0d: util::stream_format(stream, "dec c"); break; - case 0x0e: util::stream_format(stream, "ld c,$%02x", ARG(pc)); pc++; break; - case 0x0f: util::stream_format(stream, "rrca"); break; - case 0x10: util::stream_format(stream, "sra hl (*)"); break; - case 0x11: util::stream_format(stream, "ld de,$%04x", ARGW(pc)); pc+=2; break; - case 0x12: util::stream_format(stream, "ld (de),a"); break; - case 0x13: util::stream_format(stream, "inc de"); break; - case 0x14: util::stream_format(stream, "inc d"); break; - case 0x15: util::stream_format(stream, "dec d"); break; - case 0x16: util::stream_format(stream, "ld d,$%02x", ARG(pc)); pc++; break; - case 0x17: util::stream_format(stream, "rla"); break; - case 0x18: util::stream_format(stream, "rl de (*)"); break; - case 0x19: util::stream_format(stream, "add hl,de"); break; - case 0x1a: util::stream_format(stream, "ld a,(de)"); break; - case 0x1b: util::stream_format(stream, "dec de"); break; - case 0x1c: util::stream_format(stream, "inc e"); break; - case 0x1d: util::stream_format(stream, "dec e"); break; - case 0x1e: util::stream_format(stream, "ld e,$%02x", ARG(pc)); pc++; break; - case 0x1f: util::stream_format(stream, "rra"); break; - case 0x20: util::stream_format(stream, "rim"); break; - case 0x21: util::stream_format(stream, "ld hl,$%04x", ARGW(pc)); pc+=2; break; - case 0x22: util::stream_format(stream, "ld ($%04x),hl", ARGW(pc)); pc+=2;break; - case 0x23: util::stream_format(stream, "inc hl"); break; - case 0x24: util::stream_format(stream, "inc h"); break; - case 0x25: util::stream_format(stream, "dec h"); break; - case 0x26: util::stream_format(stream, "ld h,$%02x", ARG(pc)); pc++; break; - case 0x27: util::stream_format(stream, "daa"); break; - case 0x28: util::stream_format(stream, "ld de,hl+$%02x (*)",ARG(pc));pc++;break; - case 0x29: util::stream_format(stream, "add hl,hl"); break; - case 0x2a: util::stream_format(stream, "ld hl,($%04x)", ARGW(pc)); pc+=2;break; - case 0x2b: util::stream_format(stream, "dec hl"); break; - case 0x2c: util::stream_format(stream, "inc l"); break; - case 0x2d: util::stream_format(stream, "dec l"); break; - case 0x2e: util::stream_format(stream, "ld l,$%02x", ARG(pc)); pc++; break; - case 0x2f: util::stream_format(stream, "cpl"); break; - case 0x30: util::stream_format(stream, "sim"); break; - case 0x31: util::stream_format(stream, "ld sp,$%04x", ARGW(pc)); pc+=2; break; - case 0x32: util::stream_format(stream, "ld ($%04x),a", ARGW(pc)); pc+=2; break; - case 0x33: util::stream_format(stream, "inc sp"); break; - case 0x34: util::stream_format(stream, "inc (hl)"); break; - case 0x35: util::stream_format(stream, "dec (hl)"); break; - case 0x36: util::stream_format(stream, "ld (hl),$%02x", ARG(pc)); pc++; break; - case 0x37: util::stream_format(stream, "scf"); break; - case 0x38: util::stream_format(stream, "ld de,sp+$%02x (*)",ARG(pc));pc++;break; - case 0x39: util::stream_format(stream, "add hl,sp"); break; - case 0x3a: util::stream_format(stream, "ld a,($%04x)", ARGW(pc)); pc+=2; break; - case 0x3b: util::stream_format(stream, "dec sp"); break; - case 0x3c: util::stream_format(stream, "inc a"); break; - case 0x3d: util::stream_format(stream, "dec a"); break; - case 0x3e: util::stream_format(stream, "ld a,$%02x", ARG(pc)); pc++; break; - case 0x3f: util::stream_format(stream, "ccf"); break; - case 0x40: util::stream_format(stream, "ld b,b"); break; - case 0x41: util::stream_format(stream, "ld b,c"); break; - case 0x42: util::stream_format(stream, "ld b,d"); break; - case 0x43: util::stream_format(stream, "ld b,e"); break; - case 0x44: util::stream_format(stream, "ld b,h"); break; - case 0x45: util::stream_format(stream, "ld b,l"); break; - case 0x46: util::stream_format(stream, "ld b,(hl)"); break; - case 0x47: util::stream_format(stream, "ld b,a"); break; - case 0x48: util::stream_format(stream, "ld c,b"); break; - case 0x49: util::stream_format(stream, "ld c,c"); break; - case 0x4a: util::stream_format(stream, "ld c,d"); break; - case 0x4b: util::stream_format(stream, "ld c,e"); break; - case 0x4c: util::stream_format(stream, "ld c,h"); break; - case 0x4d: util::stream_format(stream, "ld c,l"); break; - case 0x4e: util::stream_format(stream, "ld c,(hl)"); break; - case 0x4f: util::stream_format(stream, "ld c,a"); break; - case 0x50: util::stream_format(stream, "ld d,b"); break; - case 0x51: util::stream_format(stream, "ld d,c"); break; - case 0x52: util::stream_format(stream, "ld d,d"); break; - case 0x53: util::stream_format(stream, "ld d,e"); break; - case 0x54: util::stream_format(stream, "ld d,h"); break; - case 0x55: util::stream_format(stream, "ld d,l"); break; - case 0x56: util::stream_format(stream, "ld d,(hl)"); break; - case 0x57: util::stream_format(stream, "ld d,a"); break; - case 0x58: util::stream_format(stream, "ld e,b"); break; - case 0x59: util::stream_format(stream, "ld e,c"); break; - case 0x5a: util::stream_format(stream, "ld e,d"); break; - case 0x5b: util::stream_format(stream, "ld e,e"); break; - case 0x5c: util::stream_format(stream, "ld e,h"); break; - case 0x5d: util::stream_format(stream, "ld e,l"); break; - case 0x5e: util::stream_format(stream, "ld e,(hl)"); break; - case 0x5f: util::stream_format(stream, "ld e,a"); break; - case 0x60: util::stream_format(stream, "ld h,b"); break; - case 0x61: util::stream_format(stream, "ld h,c"); break; - case 0x62: util::stream_format(stream, "ld h,d"); break; - case 0x63: util::stream_format(stream, "ld h,e"); break; - case 0x64: util::stream_format(stream, "ld h,h"); break; - case 0x65: util::stream_format(stream, "ld h,l"); break; - case 0x66: util::stream_format(stream, "ld h,(hl)"); break; - case 0x67: util::stream_format(stream, "ld h,a"); break; - case 0x68: util::stream_format(stream, "ld l,b"); break; - case 0x69: util::stream_format(stream, "ld l,c"); break; - case 0x6a: util::stream_format(stream, "ld l,d"); break; - case 0x6b: util::stream_format(stream, "ld l,e"); break; - case 0x6c: util::stream_format(stream, "ld l,h"); break; - case 0x6d: util::stream_format(stream, "ld l,l"); break; - case 0x6e: util::stream_format(stream, "ld l,(hl)"); break; - case 0x6f: util::stream_format(stream, "ld l,a"); break; - case 0x70: util::stream_format(stream, "ld (hl),b"); break; - case 0x71: util::stream_format(stream, "ld (hl),c"); break; - case 0x72: util::stream_format(stream, "ld (hl),d"); break; - case 0x73: util::stream_format(stream, "ld (hl),e"); break; - case 0x74: util::stream_format(stream, "ld (hl),h"); break; - case 0x75: util::stream_format(stream, "ld (hl),l"); break; - case 0x76: util::stream_format(stream, "halt"); break; - case 0x77: util::stream_format(stream, "ld (hl),a"); break; - case 0x78: util::stream_format(stream, "ld a,b"); break; - case 0x79: util::stream_format(stream, "ld a,c"); break; - case 0x7a: util::stream_format(stream, "ld a,d"); break; - case 0x7b: util::stream_format(stream, "ld a,e"); break; - case 0x7c: util::stream_format(stream, "ld a,h"); break; - case 0x7d: util::stream_format(stream, "ld a,l"); break; - case 0x7e: util::stream_format(stream, "ld a,(hl)"); break; - case 0x7f: util::stream_format(stream, "ld a,a"); break; - case 0x80: util::stream_format(stream, "add a,b"); break; - case 0x81: util::stream_format(stream, "add a,c"); break; - case 0x82: util::stream_format(stream, "add a,d"); break; - case 0x83: util::stream_format(stream, "add a,e"); break; - case 0x84: util::stream_format(stream, "add a,h"); break; - case 0x85: util::stream_format(stream, "add a,l"); break; - case 0x86: util::stream_format(stream, "add a,(hl)"); break; - case 0x87: util::stream_format(stream, "add a,a"); break; - case 0x88: util::stream_format(stream, "adc a,b"); break; - case 0x89: util::stream_format(stream, "adc a,c"); break; - case 0x8a: util::stream_format(stream, "adc a,d"); break; - case 0x8b: util::stream_format(stream, "adc a,e"); break; - case 0x8c: util::stream_format(stream, "adc a,h"); break; - case 0x8d: util::stream_format(stream, "adc a,l"); break; - case 0x8e: util::stream_format(stream, "adc a,(hl)"); break; - case 0x8f: util::stream_format(stream, "adc a,a"); break; - case 0x90: util::stream_format(stream, "sub b"); break; - case 0x91: util::stream_format(stream, "sub c"); break; - case 0x92: util::stream_format(stream, "sub d"); break; - case 0x93: util::stream_format(stream, "sub e"); break; - case 0x94: util::stream_format(stream, "sub h"); break; - case 0x95: util::stream_format(stream, "sub l"); break; - case 0x96: util::stream_format(stream, "sub (hl)"); break; - case 0x97: util::stream_format(stream, "sub a"); break; - case 0x98: util::stream_format(stream, "sbc a,b"); break; - case 0x99: util::stream_format(stream, "sbc a,c"); break; - case 0x9a: util::stream_format(stream, "sbc a,d"); break; - case 0x9b: util::stream_format(stream, "sbc a,e"); break; - case 0x9c: util::stream_format(stream, "sbc a,h"); break; - case 0x9d: util::stream_format(stream, "sbc a,l"); break; - case 0x9e: util::stream_format(stream, "sbc a,(hl)"); break; - case 0x9f: util::stream_format(stream, "sbc a,a"); break; - case 0xa0: util::stream_format(stream, "and b"); break; - case 0xa1: util::stream_format(stream, "and c"); break; - case 0xa2: util::stream_format(stream, "and d"); break; - case 0xa3: util::stream_format(stream, "and e"); break; - case 0xa4: util::stream_format(stream, "and h"); break; - case 0xa5: util::stream_format(stream, "and l"); break; - case 0xa6: util::stream_format(stream, "and (hl)"); break; - case 0xa7: util::stream_format(stream, "and a"); break; - case 0xa8: util::stream_format(stream, "xor b"); break; - case 0xa9: util::stream_format(stream, "xor c"); break; - case 0xaa: util::stream_format(stream, "xor d"); break; - case 0xab: util::stream_format(stream, "xor e"); break; - case 0xac: util::stream_format(stream, "xor h"); break; - case 0xad: util::stream_format(stream, "xor l"); break; - case 0xae: util::stream_format(stream, "xor (hl)"); break; - case 0xaf: util::stream_format(stream, "xor a"); break; - case 0xb0: util::stream_format(stream, "or b"); break; - case 0xb1: util::stream_format(stream, "or c"); break; - case 0xb2: util::stream_format(stream, "or d"); break; - case 0xb3: util::stream_format(stream, "or e"); break; - case 0xb4: util::stream_format(stream, "or h"); break; - case 0xb5: util::stream_format(stream, "or l"); break; - case 0xb6: util::stream_format(stream, "or (hl)"); break; - case 0xb7: util::stream_format(stream, "or a"); break; - case 0xb8: util::stream_format(stream, "cp b"); break; - case 0xb9: util::stream_format(stream, "cp c"); break; - case 0xba: util::stream_format(stream, "cp d"); break; - case 0xbb: util::stream_format(stream, "cp e"); break; - case 0xbc: util::stream_format(stream, "cp h"); break; - case 0xbd: util::stream_format(stream, "cp l"); break; - case 0xbe: util::stream_format(stream, "cp (hl)"); break; - case 0xbf: util::stream_format(stream, "cp a"); break; - case 0xc0: util::stream_format(stream, "ret nz"); flags = DASMFLAG_STEP_OUT; break; - case 0xc1: util::stream_format(stream, "pop bc"); break; - case 0xc2: util::stream_format(stream, "jp nz,$%04x", ARGW(pc)); pc+=2; break; - case 0xc3: util::stream_format(stream, "jp $%04x", ARGW(pc)); pc+=2; break; - case 0xc4: util::stream_format(stream, "call nz,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xc5: util::stream_format(stream, "push bc"); break; - case 0xc6: util::stream_format(stream, "add a,$%02x", ARG(pc)); pc++; break; - case 0xc7: util::stream_format(stream, "rst $00"); flags = DASMFLAG_STEP_OVER; break; - case 0xc8: util::stream_format(stream, "ret z"); flags = DASMFLAG_STEP_OUT; break; - case 0xc9: util::stream_format(stream, "ret"); flags = DASMFLAG_STEP_OUT; break; - case 0xca: util::stream_format(stream, "jp z,$%04x", ARGW(pc)); pc+=2; break; - case 0xcb: util::stream_format(stream, "rst v,$40 (*)"); flags = DASMFLAG_STEP_OVER; break; - case 0xcc: util::stream_format(stream, "call z,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xcd: util::stream_format(stream, "call $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xce: util::stream_format(stream, "adc a,$%02x", ARG(pc)); pc++; break; - case 0xcf: util::stream_format(stream, "rst $08"); flags = DASMFLAG_STEP_OVER; break; - case 0xd0: util::stream_format(stream, "ret nc"); flags = DASMFLAG_STEP_OUT; break; - case 0xd1: util::stream_format(stream, "pop de"); break; - case 0xd2: util::stream_format(stream, "jp nc,$%04x", ARGW(pc)); pc+=2; break; - case 0xd3: util::stream_format(stream, "out ($%02x),a", ARG(pc)); pc++; break; - case 0xd4: util::stream_format(stream, "call nc,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xd5: util::stream_format(stream, "push de"); break; - case 0xd6: util::stream_format(stream, "sub $%02x", ARG(pc)); pc++; break; - case 0xd7: util::stream_format(stream, "rst $10"); flags = DASMFLAG_STEP_OVER; break; - case 0xd8: util::stream_format(stream, "ret c"); break; - case 0xd9: util::stream_format(stream, "ld (de),hl (*)"); break; - case 0xda: util::stream_format(stream, "jp c,$%04x", ARGW(pc)); pc+=2; break; - case 0xdb: util::stream_format(stream, "in a,($%02x)", ARG(pc)); pc++; break; - case 0xdc: util::stream_format(stream, "call c,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xdd: util::stream_format(stream, "jp nx,$%04x (*)",ARGW(pc));pc+=2;break; - case 0xde: util::stream_format(stream, "sub $%02x", ARG(pc)); pc++; break; - case 0xdf: util::stream_format(stream, "rst $18"); flags = DASMFLAG_STEP_OVER; break; - case 0xe0: util::stream_format(stream, "ret pe"); break; - case 0xe1: util::stream_format(stream, "pop hl"); break; - case 0xe2: util::stream_format(stream, "jp pe,$%04x", ARGW(pc)); pc+=2; break; - case 0xe3: util::stream_format(stream, "ex (sp),hl"); break; - case 0xe4: util::stream_format(stream, "call pe,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xe5: util::stream_format(stream, "push hl"); break; - case 0xe6: util::stream_format(stream, "and $%02x", ARG(pc)); pc++; break; - case 0xe7: util::stream_format(stream, "rst $20"); flags = DASMFLAG_STEP_OVER; break; - case 0xe8: util::stream_format(stream, "ret po"); break; - case 0xe9: util::stream_format(stream, "jp (hl)"); break; - case 0xea: util::stream_format(stream, "jp po,$%04x", ARGW(pc)); pc+=2; break; - case 0xeb: util::stream_format(stream, "ex de,hl"); break; - case 0xec: util::stream_format(stream, "call po,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xed: util::stream_format(stream, "ld hl,(de) (*)"); break; - case 0xee: util::stream_format(stream, "xor $%02x", ARG(pc)); pc++; break; - case 0xef: util::stream_format(stream, "rst $28"); flags = DASMFLAG_STEP_OVER; break; - case 0xf0: util::stream_format(stream, "ret p"); break; - case 0xf1: util::stream_format(stream, "pop af"); break; - case 0xf2: util::stream_format(stream, "jp p,$%04x", ARGW(pc)); pc+=2; break; - case 0xf3: util::stream_format(stream, "di"); break; - case 0xf4: util::stream_format(stream, "cp $%04x", ARGW(pc)); pc+=2; break; - case 0xf5: util::stream_format(stream, "push af"); break; - case 0xf6: util::stream_format(stream, "or $%02x", ARG(pc)); pc++; break; - case 0xf7: util::stream_format(stream, "rst $30"); flags = DASMFLAG_STEP_OVER; break; - case 0xf8: util::stream_format(stream, "ret m"); break; - case 0xf9: util::stream_format(stream, "ld sp,hl"); break; - case 0xfa: util::stream_format(stream, "jp m,$%04x", ARGW(pc)); pc+=2; break; - case 0xfb: util::stream_format(stream, "ei"); break; - case 0xfc: util::stream_format(stream, "call m,$%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xfd: util::stream_format(stream, "jp x,$%04x (*)",ARGW(pc));pc+=2; break; - case 0xfe: util::stream_format(stream, "cp $%02x", ARG(pc)); pc++; break; - case 0xff: util::stream_format(stream, "rst $38"); flags = DASMFLAG_STEP_OVER; break; -#else - case 0x00: util::stream_format(stream, "nop"); break; - case 0x01: util::stream_format(stream, "lxi b,$%04x", ARGW(pc)); pc+=2; break; - case 0x02: util::stream_format(stream, "stax b"); break; - case 0x03: util::stream_format(stream, "inx b"); break; - case 0x04: util::stream_format(stream, "inr b"); break; - case 0x05: util::stream_format(stream, "dcr b"); break; - case 0x06: util::stream_format(stream, "mvi b,$%02x", ARG(pc)); pc++; break; - case 0x07: util::stream_format(stream, "rlc"); break; - case 0x08: util::stream_format(stream, "dsub (*)"); break; - case 0x09: util::stream_format(stream, "dad b"); break; - case 0x0a: util::stream_format(stream, "ldax b"); break; - case 0x0b: util::stream_format(stream, "dcx b"); break; - case 0x0c: util::stream_format(stream, "inr c"); break; - case 0x0d: util::stream_format(stream, "dcr c"); break; - case 0x0e: util::stream_format(stream, "mvi c,$%02x", ARG(pc)); pc++; break; - case 0x0f: util::stream_format(stream, "rrc"); break; - case 0x10: util::stream_format(stream, "asrh (*)"); break; - case 0x11: util::stream_format(stream, "lxi d,$%04x", ARGW(pc)); pc+=2; break; - case 0x12: util::stream_format(stream, "stax d"); break; - case 0x13: util::stream_format(stream, "inx d"); break; - case 0x14: util::stream_format(stream, "inr d"); break; - case 0x15: util::stream_format(stream, "dcr d"); break; - case 0x16: util::stream_format(stream, "mvi d,$%02x", ARG(pc)); pc++; break; - case 0x17: util::stream_format(stream, "ral"); break; - case 0x18: util::stream_format(stream, "rlde (*)"); break; - case 0x19: util::stream_format(stream, "dad d"); break; - case 0x1a: util::stream_format(stream, "ldax d"); break; - case 0x1b: util::stream_format(stream, "dcx d"); break; - case 0x1c: util::stream_format(stream, "inr e"); break; - case 0x1d: util::stream_format(stream, "dcr e"); break; - case 0x1e: util::stream_format(stream, "mvi e,$%02x", ARG(pc)); pc++; break; - case 0x1f: util::stream_format(stream, "rar"); break; - case 0x20: util::stream_format(stream, "rim"); break; - case 0x21: util::stream_format(stream, "lxi h,$%04x", ARGW(pc)); pc+=2; break; - case 0x22: util::stream_format(stream, "shld $%04x", ARGW(pc)); pc+=2; break; - case 0x23: util::stream_format(stream, "inx h"); break; - case 0x24: util::stream_format(stream, "inr h"); break; - case 0x25: util::stream_format(stream, "dcr h"); break; - case 0x26: util::stream_format(stream, "mvi h,$%02x", ARG(pc)); pc++; break; - case 0x27: util::stream_format(stream, "daa"); break; - case 0x28: util::stream_format(stream, "ldeh $%02x (*)", ARG(pc)); pc++; break; - case 0x29: util::stream_format(stream, "dad h"); break; - case 0x2a: util::stream_format(stream, "lhld $%04x", ARGW(pc)); pc+=2; break; - case 0x2b: util::stream_format(stream, "dcx h"); break; - case 0x2c: util::stream_format(stream, "inr l"); break; - case 0x2d: util::stream_format(stream, "dcr l"); break; - case 0x2e: util::stream_format(stream, "mvi l,$%02x", ARG(pc)); pc++; break; - case 0x2f: util::stream_format(stream, "cma"); break; - case 0x30: util::stream_format(stream, "sim"); break; - case 0x31: util::stream_format(stream, "lxi sp,$%04x", ARGW(pc)); pc+=2; break; - case 0x32: util::stream_format(stream, "stax $%04x", ARGW(pc)); pc+=2; break; - case 0x33: util::stream_format(stream, "inx sp"); break; - case 0x34: util::stream_format(stream, "inr m"); break; - case 0x35: util::stream_format(stream, "dcr m"); break; - case 0x36: util::stream_format(stream, "mvi m,$%02x", ARG(pc)); pc++; break; - case 0x37: util::stream_format(stream, "stc"); break; - case 0x38: util::stream_format(stream, "ldes $%02x (*)", ARG(pc)); pc++; break; - case 0x39: util::stream_format(stream, "dad sp"); break; - case 0x3a: util::stream_format(stream, "ldax $%04x", ARGW(pc)); pc+=2; break; - case 0x3b: util::stream_format(stream, "dcx sp"); break; - case 0x3c: util::stream_format(stream, "inr a"); break; - case 0x3d: util::stream_format(stream, "dcr a"); break; - case 0x3e: util::stream_format(stream, "mvi a,$%02x", ARG(pc)); pc++; break; - case 0x3f: util::stream_format(stream, "cmc"); break; - case 0x40: util::stream_format(stream, "mov b,b"); break; - case 0x41: util::stream_format(stream, "mov b,c"); break; - case 0x42: util::stream_format(stream, "mov b,d"); break; - case 0x43: util::stream_format(stream, "mov b,e"); break; - case 0x44: util::stream_format(stream, "mov b,h"); break; - case 0x45: util::stream_format(stream, "mov b,l"); break; - case 0x46: util::stream_format(stream, "mov b,m"); break; - case 0x47: util::stream_format(stream, "mov b,a"); break; - case 0x48: util::stream_format(stream, "mov c,b"); break; - case 0x49: util::stream_format(stream, "mov c,c"); break; - case 0x4a: util::stream_format(stream, "mov c,d"); break; - case 0x4b: util::stream_format(stream, "mov c,e"); break; - case 0x4c: util::stream_format(stream, "mov c,h"); break; - case 0x4d: util::stream_format(stream, "mov c,l"); break; - case 0x4e: util::stream_format(stream, "mov c,m"); break; - case 0x4f: util::stream_format(stream, "mov c,a"); break; - case 0x50: util::stream_format(stream, "mov d,b"); break; - case 0x51: util::stream_format(stream, "mov d,c"); break; - case 0x52: util::stream_format(stream, "mov d,d"); break; - case 0x53: util::stream_format(stream, "mov d,e"); break; - case 0x54: util::stream_format(stream, "mov d,h"); break; - case 0x55: util::stream_format(stream, "mov d,l"); break; - case 0x56: util::stream_format(stream, "mov d,m"); break; - case 0x57: util::stream_format(stream, "mov d,a"); break; - case 0x58: util::stream_format(stream, "mov e,b"); break; - case 0x59: util::stream_format(stream, "mov e,c"); break; - case 0x5a: util::stream_format(stream, "mov e,d"); break; - case 0x5b: util::stream_format(stream, "mov e,e"); break; - case 0x5c: util::stream_format(stream, "mov e,h"); break; - case 0x5d: util::stream_format(stream, "mov e,l"); break; - case 0x5e: util::stream_format(stream, "mov e,m"); break; - case 0x5f: util::stream_format(stream, "mov e,a"); break; - case 0x60: util::stream_format(stream, "mov h,b"); break; - case 0x61: util::stream_format(stream, "mov h,c"); break; - case 0x62: util::stream_format(stream, "mov h,d"); break; - case 0x63: util::stream_format(stream, "mov h,e"); break; - case 0x64: util::stream_format(stream, "mov h,h"); break; - case 0x65: util::stream_format(stream, "mov h,l"); break; - case 0x66: util::stream_format(stream, "mov h,m"); break; - case 0x67: util::stream_format(stream, "mov h,a"); break; - case 0x68: util::stream_format(stream, "mov l,b"); break; - case 0x69: util::stream_format(stream, "mov l,c"); break; - case 0x6a: util::stream_format(stream, "mov l,d"); break; - case 0x6b: util::stream_format(stream, "mov l,e"); break; - case 0x6c: util::stream_format(stream, "mov l,h"); break; - case 0x6d: util::stream_format(stream, "mov l,l"); break; - case 0x6e: util::stream_format(stream, "mov l,m"); break; - case 0x6f: util::stream_format(stream, "mov l,a"); break; - case 0x70: util::stream_format(stream, "mov m,b"); break; - case 0x71: util::stream_format(stream, "mov m,c"); break; - case 0x72: util::stream_format(stream, "mov m,d"); break; - case 0x73: util::stream_format(stream, "mov m,e"); break; - case 0x74: util::stream_format(stream, "mov m,h"); break; - case 0x75: util::stream_format(stream, "mov m,l"); break; - case 0x76: util::stream_format(stream, "hlt"); break; - case 0x77: util::stream_format(stream, "mov m,a"); break; - case 0x78: util::stream_format(stream, "mov a,b"); break; - case 0x79: util::stream_format(stream, "mov a,c"); break; - case 0x7a: util::stream_format(stream, "mov a,d"); break; - case 0x7b: util::stream_format(stream, "mov a,e"); break; - case 0x7c: util::stream_format(stream, "mov a,h"); break; - case 0x7d: util::stream_format(stream, "mov a,l"); break; - case 0x7e: util::stream_format(stream, "mov a,m"); break; - case 0x7f: util::stream_format(stream, "mov a,a"); break; - case 0x80: util::stream_format(stream, "add b"); break; - case 0x81: util::stream_format(stream, "add c"); break; - case 0x82: util::stream_format(stream, "add d"); break; - case 0x83: util::stream_format(stream, "add e"); break; - case 0x84: util::stream_format(stream, "add h"); break; - case 0x85: util::stream_format(stream, "add l"); break; - case 0x86: util::stream_format(stream, "add m"); break; - case 0x87: util::stream_format(stream, "add a"); break; - case 0x88: util::stream_format(stream, "adc b"); break; - case 0x89: util::stream_format(stream, "adc c"); break; - case 0x8a: util::stream_format(stream, "adc d"); break; - case 0x8b: util::stream_format(stream, "adc e"); break; - case 0x8c: util::stream_format(stream, "adc h"); break; - case 0x8d: util::stream_format(stream, "adc l"); break; - case 0x8e: util::stream_format(stream, "adc m"); break; - case 0x8f: util::stream_format(stream, "adc a"); break; - case 0x90: util::stream_format(stream, "sub b"); break; - case 0x91: util::stream_format(stream, "sub c"); break; - case 0x92: util::stream_format(stream, "sub d"); break; - case 0x93: util::stream_format(stream, "sub e"); break; - case 0x94: util::stream_format(stream, "sub h"); break; - case 0x95: util::stream_format(stream, "sub l"); break; - case 0x96: util::stream_format(stream, "sub m"); break; - case 0x97: util::stream_format(stream, "sub a"); break; - case 0x98: util::stream_format(stream, "sbb b"); break; - case 0x99: util::stream_format(stream, "sbb c"); break; - case 0x9a: util::stream_format(stream, "sbb d"); break; - case 0x9b: util::stream_format(stream, "sbb e"); break; - case 0x9c: util::stream_format(stream, "sbb h"); break; - case 0x9d: util::stream_format(stream, "sbb l"); break; - case 0x9e: util::stream_format(stream, "sbb m"); break; - case 0x9f: util::stream_format(stream, "sbb a"); break; - case 0xa0: util::stream_format(stream, "ana b"); break; - case 0xa1: util::stream_format(stream, "ana c"); break; - case 0xa2: util::stream_format(stream, "ana d"); break; - case 0xa3: util::stream_format(stream, "ana e"); break; - case 0xa4: util::stream_format(stream, "ana h"); break; - case 0xa5: util::stream_format(stream, "ana l"); break; - case 0xa6: util::stream_format(stream, "ana m"); break; - case 0xa7: util::stream_format(stream, "ana a"); break; - case 0xa8: util::stream_format(stream, "xra b"); break; - case 0xa9: util::stream_format(stream, "xra c"); break; - case 0xaa: util::stream_format(stream, "xra d"); break; - case 0xab: util::stream_format(stream, "xra e"); break; - case 0xac: util::stream_format(stream, "xra h"); break; - case 0xad: util::stream_format(stream, "xra l"); break; - case 0xae: util::stream_format(stream, "xra m"); break; - case 0xaf: util::stream_format(stream, "xra a"); break; - case 0xb0: util::stream_format(stream, "ora b"); break; - case 0xb1: util::stream_format(stream, "ora c"); break; - case 0xb2: util::stream_format(stream, "ora d"); break; - case 0xb3: util::stream_format(stream, "ora e"); break; - case 0xb4: util::stream_format(stream, "ora h"); break; - case 0xb5: util::stream_format(stream, "ora l"); break; - case 0xb6: util::stream_format(stream, "ora m"); break; - case 0xb7: util::stream_format(stream, "ora a"); break; - case 0xb8: util::stream_format(stream, "cmp b"); break; - case 0xb9: util::stream_format(stream, "cmp c"); break; - case 0xba: util::stream_format(stream, "cmp d"); break; - case 0xbb: util::stream_format(stream, "cmp e"); break; - case 0xbc: util::stream_format(stream, "cmp h"); break; - case 0xbd: util::stream_format(stream, "cmp l"); break; - case 0xbe: util::stream_format(stream, "cmp m"); break; - case 0xbf: util::stream_format(stream, "cmp a"); break; - case 0xc0: util::stream_format(stream, "rnz"); flags = DASMFLAG_STEP_OUT; break; - case 0xc1: util::stream_format(stream, "pop b"); break; - case 0xc2: util::stream_format(stream, "jnz $%04x", ARGW(pc)); pc+=2; break; - case 0xc3: util::stream_format(stream, "jmp $%04x", ARGW(pc)); pc+=2; break; - case 0xc4: util::stream_format(stream, "cnz $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xc5: util::stream_format(stream, "push b"); break; - case 0xc6: util::stream_format(stream, "adi $%02x", ARG(pc)); pc++; break; - case 0xc7: util::stream_format(stream, "rst 0"); flags = DASMFLAG_STEP_OVER; break; - case 0xc8: util::stream_format(stream, "rz"); flags = DASMFLAG_STEP_OUT; break; - case 0xc9: util::stream_format(stream, "ret"); flags = DASMFLAG_STEP_OUT; break; - case 0xca: util::stream_format(stream, "jz $%04x", ARGW(pc)); pc+=2; break; - case 0xcb: util::stream_format(stream, "rstv 8 (*)"); flags = DASMFLAG_STEP_OVER; break; - case 0xcc: util::stream_format(stream, "cz $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xcd: util::stream_format(stream, "call $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xce: util::stream_format(stream, "aci $%02x", ARG(pc)); pc++; break; - case 0xcf: util::stream_format(stream, "rst 1"); flags = DASMFLAG_STEP_OVER; break; - case 0xd0: util::stream_format(stream, "rnc"); flags = DASMFLAG_STEP_OUT; break; - case 0xd1: util::stream_format(stream, "pop d"); break; - case 0xd2: util::stream_format(stream, "jnc $%04x", ARGW(pc)); pc+=2; break; - case 0xd3: util::stream_format(stream, "out $%02x", ARG(pc)); pc++; break; - case 0xd4: util::stream_format(stream, "cnc $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xd5: util::stream_format(stream, "push d"); break; - case 0xd6: util::stream_format(stream, "sui $%02x", ARG(pc)); pc++; break; - case 0xd7: util::stream_format(stream, "rst 2"); flags = DASMFLAG_STEP_OVER; break; - case 0xd8: util::stream_format(stream, "rc"); flags = DASMFLAG_STEP_OUT; break; - case 0xd9: util::stream_format(stream, "shlx d (*)"); break; - case 0xda: util::stream_format(stream, "jc $%04x", ARGW(pc)); pc+=2; break; - case 0xdb: util::stream_format(stream, "in $%02x", ARG(pc)); pc++; break; - case 0xdc: util::stream_format(stream, "cc $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xdd: util::stream_format(stream, "jnx $%04x (*)", ARGW(pc)); pc+=2; break; - case 0xde: util::stream_format(stream, "sbi $%02x", ARG(pc)); pc++; break; - case 0xdf: util::stream_format(stream, "rst 3"); flags = DASMFLAG_STEP_OVER; break; - case 0xe0: util::stream_format(stream, "rpo"); flags = DASMFLAG_STEP_OUT; break; - case 0xe1: util::stream_format(stream, "pop h"); break; - case 0xe2: util::stream_format(stream, "jpo $%04x", ARGW(pc)); pc+=2; break; - case 0xe3: util::stream_format(stream, "xthl"); break; - case 0xe4: util::stream_format(stream, "cpo $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xe5: util::stream_format(stream, "push h"); break; - case 0xe6: util::stream_format(stream, "ani $%02x", ARG(pc)); pc++; break; - case 0xe7: util::stream_format(stream, "rst 4"); flags = DASMFLAG_STEP_OVER; break; - case 0xe8: util::stream_format(stream, "rpe"); flags = DASMFLAG_STEP_OUT; break; - case 0xe9: util::stream_format(stream, "pchl"); break; - case 0xea: util::stream_format(stream, "jpe $%04x", ARGW(pc)); pc+=2; break; - case 0xeb: util::stream_format(stream, "xchg"); break; - case 0xec: util::stream_format(stream, "cpe $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xed: util::stream_format(stream, "lhlx d (*)"); break; - case 0xee: util::stream_format(stream, "xri $%02x", ARG(pc)); pc++; break; - case 0xef: util::stream_format(stream, "rst 5"); flags = DASMFLAG_STEP_OVER; break; - case 0xf0: util::stream_format(stream, "rp"); flags = DASMFLAG_STEP_OUT; break; - case 0xf1: util::stream_format(stream, "pop psw"); break; - case 0xf2: util::stream_format(stream, "jp $%04x", ARGW(pc)); pc+=2; break; - case 0xf3: util::stream_format(stream, "di"); break; - case 0xf4: util::stream_format(stream, "cp $%04x", ARGW(pc)); pc+=2; break; - case 0xf5: util::stream_format(stream, "push psw"); break; - case 0xf6: util::stream_format(stream, "ori $%02x", ARG(pc)); pc++; break; - case 0xf7: util::stream_format(stream, "rst 6"); flags = DASMFLAG_STEP_OVER; break; - case 0xf8: util::stream_format(stream, "rm"); flags = DASMFLAG_STEP_OUT; break; - case 0xf9: util::stream_format(stream, "sphl"); break; - case 0xfa: util::stream_format(stream, "jm $%04x", ARGW(pc)); pc+=2; break; - case 0xfb: util::stream_format(stream, "ei"); break; - case 0xfc: util::stream_format(stream, "cm $%04x", ARGW(pc)); pc+=2; flags = DASMFLAG_STEP_OVER; break; - case 0xfd: util::stream_format(stream, "jx $%04x (*)", ARGW(pc)); pc+=2; break; - case 0xfe: util::stream_format(stream, "cpi $%02x", ARG(pc)); pc++; break; - case 0xff: util::stream_format(stream, "rst 7"); flags = DASMFLAG_STEP_OVER; break; -#endif + case 0x00: util::stream_format(stream, "nop"); break; + case 0x01: util::stream_format(stream, "lxi b,$%04x", params.r16(pc)); pc+=2; break; + case 0x02: util::stream_format(stream, "stax b"); break; + case 0x03: util::stream_format(stream, "inx b"); break; + case 0x04: util::stream_format(stream, "inr b"); break; + case 0x05: util::stream_format(stream, "dcr b"); break; + case 0x06: util::stream_format(stream, "mvi b,$%02x", params.r8(pc)); pc++; break; + case 0x07: util::stream_format(stream, "rlc"); break; + case 0x08: util::stream_format(stream, "dsub (*)"); break; + case 0x09: util::stream_format(stream, "dad b"); break; + case 0x0a: util::stream_format(stream, "ldax b"); break; + case 0x0b: util::stream_format(stream, "dcx b"); break; + case 0x0c: util::stream_format(stream, "inr c"); break; + case 0x0d: util::stream_format(stream, "dcr c"); break; + case 0x0e: util::stream_format(stream, "mvi c,$%02x", params.r8(pc)); pc++; break; + case 0x0f: util::stream_format(stream, "rrc"); break; + case 0x10: util::stream_format(stream, "asrh (*)"); break; + case 0x11: util::stream_format(stream, "lxi d,$%04x", params.r16(pc)); pc+=2; break; + case 0x12: util::stream_format(stream, "stax d"); break; + case 0x13: util::stream_format(stream, "inx d"); break; + case 0x14: util::stream_format(stream, "inr d"); break; + case 0x15: util::stream_format(stream, "dcr d"); break; + case 0x16: util::stream_format(stream, "mvi d,$%02x", params.r8(pc)); pc++; break; + case 0x17: util::stream_format(stream, "ral"); break; + case 0x18: util::stream_format(stream, "rlde (*)"); break; + case 0x19: util::stream_format(stream, "dad d"); break; + case 0x1a: util::stream_format(stream, "ldax d"); break; + case 0x1b: util::stream_format(stream, "dcx d"); break; + case 0x1c: util::stream_format(stream, "inr e"); break; + case 0x1d: util::stream_format(stream, "dcr e"); break; + case 0x1e: util::stream_format(stream, "mvi e,$%02x", params.r8(pc)); pc++; break; + case 0x1f: util::stream_format(stream, "rar"); break; + case 0x20: util::stream_format(stream, "rim"); break; + case 0x21: util::stream_format(stream, "lxi h,$%04x", params.r16(pc)); pc+=2; break; + case 0x22: util::stream_format(stream, "shld $%04x", params.r16(pc)); pc+=2; break; + case 0x23: util::stream_format(stream, "inx h"); break; + case 0x24: util::stream_format(stream, "inr h"); break; + case 0x25: util::stream_format(stream, "dcr h"); break; + case 0x26: util::stream_format(stream, "mvi h,$%02x", params.r8(pc)); pc++; break; + case 0x27: util::stream_format(stream, "daa"); break; + case 0x28: util::stream_format(stream, "ldeh $%02x (*)", params.r8(pc)); pc++; break; + case 0x29: util::stream_format(stream, "dad h"); break; + case 0x2a: util::stream_format(stream, "lhld $%04x", params.r16(pc)); pc+=2; break; + case 0x2b: util::stream_format(stream, "dcx h"); break; + case 0x2c: util::stream_format(stream, "inr l"); break; + case 0x2d: util::stream_format(stream, "dcr l"); break; + case 0x2e: util::stream_format(stream, "mvi l,$%02x", params.r8(pc)); pc++; break; + case 0x2f: util::stream_format(stream, "cma"); break; + case 0x30: util::stream_format(stream, "sim"); break; + case 0x31: util::stream_format(stream, "lxi sp,$%04x", params.r16(pc)); pc+=2; break; + case 0x32: util::stream_format(stream, "stax $%04x", params.r16(pc)); pc+=2; break; + case 0x33: util::stream_format(stream, "inx sp"); break; + case 0x34: util::stream_format(stream, "inr m"); break; + case 0x35: util::stream_format(stream, "dcr m"); break; + case 0x36: util::stream_format(stream, "mvi m,$%02x", params.r8(pc)); pc++; break; + case 0x37: util::stream_format(stream, "stc"); break; + case 0x38: util::stream_format(stream, "ldes $%02x (*)", params.r8(pc)); pc++; break; + case 0x39: util::stream_format(stream, "dad sp"); break; + case 0x3a: util::stream_format(stream, "ldax $%04x", params.r16(pc)); pc+=2; break; + case 0x3b: util::stream_format(stream, "dcx sp"); break; + case 0x3c: util::stream_format(stream, "inr a"); break; + case 0x3d: util::stream_format(stream, "dcr a"); break; + case 0x3e: util::stream_format(stream, "mvi a,$%02x", params.r8(pc)); pc++; break; + case 0x3f: util::stream_format(stream, "cmc"); break; + case 0x40: util::stream_format(stream, "mov b,b"); break; + case 0x41: util::stream_format(stream, "mov b,c"); break; + case 0x42: util::stream_format(stream, "mov b,d"); break; + case 0x43: util::stream_format(stream, "mov b,e"); break; + case 0x44: util::stream_format(stream, "mov b,h"); break; + case 0x45: util::stream_format(stream, "mov b,l"); break; + case 0x46: util::stream_format(stream, "mov b,m"); break; + case 0x47: util::stream_format(stream, "mov b,a"); break; + case 0x48: util::stream_format(stream, "mov c,b"); break; + case 0x49: util::stream_format(stream, "mov c,c"); break; + case 0x4a: util::stream_format(stream, "mov c,d"); break; + case 0x4b: util::stream_format(stream, "mov c,e"); break; + case 0x4c: util::stream_format(stream, "mov c,h"); break; + case 0x4d: util::stream_format(stream, "mov c,l"); break; + case 0x4e: util::stream_format(stream, "mov c,m"); break; + case 0x4f: util::stream_format(stream, "mov c,a"); break; + case 0x50: util::stream_format(stream, "mov d,b"); break; + case 0x51: util::stream_format(stream, "mov d,c"); break; + case 0x52: util::stream_format(stream, "mov d,d"); break; + case 0x53: util::stream_format(stream, "mov d,e"); break; + case 0x54: util::stream_format(stream, "mov d,h"); break; + case 0x55: util::stream_format(stream, "mov d,l"); break; + case 0x56: util::stream_format(stream, "mov d,m"); break; + case 0x57: util::stream_format(stream, "mov d,a"); break; + case 0x58: util::stream_format(stream, "mov e,b"); break; + case 0x59: util::stream_format(stream, "mov e,c"); break; + case 0x5a: util::stream_format(stream, "mov e,d"); break; + case 0x5b: util::stream_format(stream, "mov e,e"); break; + case 0x5c: util::stream_format(stream, "mov e,h"); break; + case 0x5d: util::stream_format(stream, "mov e,l"); break; + case 0x5e: util::stream_format(stream, "mov e,m"); break; + case 0x5f: util::stream_format(stream, "mov e,a"); break; + case 0x60: util::stream_format(stream, "mov h,b"); break; + case 0x61: util::stream_format(stream, "mov h,c"); break; + case 0x62: util::stream_format(stream, "mov h,d"); break; + case 0x63: util::stream_format(stream, "mov h,e"); break; + case 0x64: util::stream_format(stream, "mov h,h"); break; + case 0x65: util::stream_format(stream, "mov h,l"); break; + case 0x66: util::stream_format(stream, "mov h,m"); break; + case 0x67: util::stream_format(stream, "mov h,a"); break; + case 0x68: util::stream_format(stream, "mov l,b"); break; + case 0x69: util::stream_format(stream, "mov l,c"); break; + case 0x6a: util::stream_format(stream, "mov l,d"); break; + case 0x6b: util::stream_format(stream, "mov l,e"); break; + case 0x6c: util::stream_format(stream, "mov l,h"); break; + case 0x6d: util::stream_format(stream, "mov l,l"); break; + case 0x6e: util::stream_format(stream, "mov l,m"); break; + case 0x6f: util::stream_format(stream, "mov l,a"); break; + case 0x70: util::stream_format(stream, "mov m,b"); break; + case 0x71: util::stream_format(stream, "mov m,c"); break; + case 0x72: util::stream_format(stream, "mov m,d"); break; + case 0x73: util::stream_format(stream, "mov m,e"); break; + case 0x74: util::stream_format(stream, "mov m,h"); break; + case 0x75: util::stream_format(stream, "mov m,l"); break; + case 0x76: util::stream_format(stream, "hlt"); break; + case 0x77: util::stream_format(stream, "mov m,a"); break; + case 0x78: util::stream_format(stream, "mov a,b"); break; + case 0x79: util::stream_format(stream, "mov a,c"); break; + case 0x7a: util::stream_format(stream, "mov a,d"); break; + case 0x7b: util::stream_format(stream, "mov a,e"); break; + case 0x7c: util::stream_format(stream, "mov a,h"); break; + case 0x7d: util::stream_format(stream, "mov a,l"); break; + case 0x7e: util::stream_format(stream, "mov a,m"); break; + case 0x7f: util::stream_format(stream, "mov a,a"); break; + case 0x80: util::stream_format(stream, "add b"); break; + case 0x81: util::stream_format(stream, "add c"); break; + case 0x82: util::stream_format(stream, "add d"); break; + case 0x83: util::stream_format(stream, "add e"); break; + case 0x84: util::stream_format(stream, "add h"); break; + case 0x85: util::stream_format(stream, "add l"); break; + case 0x86: util::stream_format(stream, "add m"); break; + case 0x87: util::stream_format(stream, "add a"); break; + case 0x88: util::stream_format(stream, "adc b"); break; + case 0x89: util::stream_format(stream, "adc c"); break; + case 0x8a: util::stream_format(stream, "adc d"); break; + case 0x8b: util::stream_format(stream, "adc e"); break; + case 0x8c: util::stream_format(stream, "adc h"); break; + case 0x8d: util::stream_format(stream, "adc l"); break; + case 0x8e: util::stream_format(stream, "adc m"); break; + case 0x8f: util::stream_format(stream, "adc a"); break; + case 0x90: util::stream_format(stream, "sub b"); break; + case 0x91: util::stream_format(stream, "sub c"); break; + case 0x92: util::stream_format(stream, "sub d"); break; + case 0x93: util::stream_format(stream, "sub e"); break; + case 0x94: util::stream_format(stream, "sub h"); break; + case 0x95: util::stream_format(stream, "sub l"); break; + case 0x96: util::stream_format(stream, "sub m"); break; + case 0x97: util::stream_format(stream, "sub a"); break; + case 0x98: util::stream_format(stream, "sbb b"); break; + case 0x99: util::stream_format(stream, "sbb c"); break; + case 0x9a: util::stream_format(stream, "sbb d"); break; + case 0x9b: util::stream_format(stream, "sbb e"); break; + case 0x9c: util::stream_format(stream, "sbb h"); break; + case 0x9d: util::stream_format(stream, "sbb l"); break; + case 0x9e: util::stream_format(stream, "sbb m"); break; + case 0x9f: util::stream_format(stream, "sbb a"); break; + case 0xa0: util::stream_format(stream, "ana b"); break; + case 0xa1: util::stream_format(stream, "ana c"); break; + case 0xa2: util::stream_format(stream, "ana d"); break; + case 0xa3: util::stream_format(stream, "ana e"); break; + case 0xa4: util::stream_format(stream, "ana h"); break; + case 0xa5: util::stream_format(stream, "ana l"); break; + case 0xa6: util::stream_format(stream, "ana m"); break; + case 0xa7: util::stream_format(stream, "ana a"); break; + case 0xa8: util::stream_format(stream, "xra b"); break; + case 0xa9: util::stream_format(stream, "xra c"); break; + case 0xaa: util::stream_format(stream, "xra d"); break; + case 0xab: util::stream_format(stream, "xra e"); break; + case 0xac: util::stream_format(stream, "xra h"); break; + case 0xad: util::stream_format(stream, "xra l"); break; + case 0xae: util::stream_format(stream, "xra m"); break; + case 0xaf: util::stream_format(stream, "xra a"); break; + case 0xb0: util::stream_format(stream, "ora b"); break; + case 0xb1: util::stream_format(stream, "ora c"); break; + case 0xb2: util::stream_format(stream, "ora d"); break; + case 0xb3: util::stream_format(stream, "ora e"); break; + case 0xb4: util::stream_format(stream, "ora h"); break; + case 0xb5: util::stream_format(stream, "ora l"); break; + case 0xb6: util::stream_format(stream, "ora m"); break; + case 0xb7: util::stream_format(stream, "ora a"); break; + case 0xb8: util::stream_format(stream, "cmp b"); break; + case 0xb9: util::stream_format(stream, "cmp c"); break; + case 0xba: util::stream_format(stream, "cmp d"); break; + case 0xbb: util::stream_format(stream, "cmp e"); break; + case 0xbc: util::stream_format(stream, "cmp h"); break; + case 0xbd: util::stream_format(stream, "cmp l"); break; + case 0xbe: util::stream_format(stream, "cmp m"); break; + case 0xbf: util::stream_format(stream, "cmp a"); break; + case 0xc0: util::stream_format(stream, "rnz"); flags = STEP_OUT; break; + case 0xc1: util::stream_format(stream, "pop b"); break; + case 0xc2: util::stream_format(stream, "jnz $%04x", params.r16(pc)); pc+=2; break; + case 0xc3: util::stream_format(stream, "jmp $%04x", params.r16(pc)); pc+=2; break; + case 0xc4: util::stream_format(stream, "cnz $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xc5: util::stream_format(stream, "push b"); break; + case 0xc6: util::stream_format(stream, "adi $%02x", params.r8(pc)); pc++; break; + case 0xc7: util::stream_format(stream, "rst 0"); flags = STEP_OVER; break; + case 0xc8: util::stream_format(stream, "rz"); flags = STEP_OUT; break; + case 0xc9: util::stream_format(stream, "ret"); flags = STEP_OUT; break; + case 0xca: util::stream_format(stream, "jz $%04x", params.r16(pc)); pc+=2; break; + case 0xcb: util::stream_format(stream, "rstv 8 (*)"); flags = STEP_OVER; break; + case 0xcc: util::stream_format(stream, "cz $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xcd: util::stream_format(stream, "call $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xce: util::stream_format(stream, "aci $%02x", params.r8(pc)); pc++; break; + case 0xcf: util::stream_format(stream, "rst 1"); flags = STEP_OVER; break; + case 0xd0: util::stream_format(stream, "rnc"); flags = STEP_OUT; break; + case 0xd1: util::stream_format(stream, "pop d"); break; + case 0xd2: util::stream_format(stream, "jnc $%04x", params.r16(pc)); pc+=2; break; + case 0xd3: util::stream_format(stream, "out $%02x", params.r8(pc)); pc++; break; + case 0xd4: util::stream_format(stream, "cnc $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xd5: util::stream_format(stream, "push d"); break; + case 0xd6: util::stream_format(stream, "sui $%02x", params.r8(pc)); pc++; break; + case 0xd7: util::stream_format(stream, "rst 2"); flags = STEP_OVER; break; + case 0xd8: util::stream_format(stream, "rc"); flags = STEP_OUT; break; + case 0xd9: util::stream_format(stream, "shlx d (*)"); break; + case 0xda: util::stream_format(stream, "jc $%04x", params.r16(pc)); pc+=2; break; + case 0xdb: util::stream_format(stream, "in $%02x", params.r8(pc)); pc++; break; + case 0xdc: util::stream_format(stream, "cc $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xdd: util::stream_format(stream, "jnx $%04x (*)", params.r16(pc)); pc+=2; break; + case 0xde: util::stream_format(stream, "sbi $%02x", params.r8(pc)); pc++; break; + case 0xdf: util::stream_format(stream, "rst 3"); flags = STEP_OVER; break; + case 0xe0: util::stream_format(stream, "rpo"); flags = STEP_OUT; break; + case 0xe1: util::stream_format(stream, "pop h"); break; + case 0xe2: util::stream_format(stream, "jpo $%04x", params.r16(pc)); pc+=2; break; + case 0xe3: util::stream_format(stream, "xthl"); break; + case 0xe4: util::stream_format(stream, "cpo $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xe5: util::stream_format(stream, "push h"); break; + case 0xe6: util::stream_format(stream, "ani $%02x", params.r8(pc)); pc++; break; + case 0xe7: util::stream_format(stream, "rst 4"); flags = STEP_OVER; break; + case 0xe8: util::stream_format(stream, "rpe"); flags = STEP_OUT; break; + case 0xe9: util::stream_format(stream, "pchl"); break; + case 0xea: util::stream_format(stream, "jpe $%04x", params.r16(pc)); pc+=2; break; + case 0xeb: util::stream_format(stream, "xchg"); break; + case 0xec: util::stream_format(stream, "cpe $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xed: util::stream_format(stream, "lhlx d (*)"); break; + case 0xee: util::stream_format(stream, "xri $%02x", params.r8(pc)); pc++; break; + case 0xef: util::stream_format(stream, "rst 5"); flags = STEP_OVER; break; + case 0xf0: util::stream_format(stream, "rp"); flags = STEP_OUT; break; + case 0xf1: util::stream_format(stream, "pop psw"); break; + case 0xf2: util::stream_format(stream, "jp $%04x", params.r16(pc)); pc+=2; break; + case 0xf3: util::stream_format(stream, "di"); break; + case 0xf4: util::stream_format(stream, "cp $%04x", params.r16(pc)); pc+=2; break; + case 0xf5: util::stream_format(stream, "push psw"); break; + case 0xf6: util::stream_format(stream, "ori $%02x", params.r8(pc)); pc++; break; + case 0xf7: util::stream_format(stream, "rst 6"); flags = STEP_OVER; break; + case 0xf8: util::stream_format(stream, "rm"); flags = STEP_OUT; break; + case 0xf9: util::stream_format(stream, "sphl"); break; + case 0xfa: util::stream_format(stream, "jm $%04x", params.r16(pc)); pc+=2; break; + case 0xfb: util::stream_format(stream, "ei"); break; + case 0xfc: util::stream_format(stream, "cm $%04x", params.r16(pc)); pc+=2; flags = STEP_OVER; break; + case 0xfd: util::stream_format(stream, "jx $%04x (*)", params.r16(pc)); pc+=2; break; + case 0xfe: util::stream_format(stream, "cpi $%02x", params.r8(pc)); pc++; break; + case 0xff: util::stream_format(stream, "rst 7"); flags = STEP_OVER; break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - prevpc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/i8085/8085dasm.h b/src/devices/cpu/i8085/8085dasm.h new file mode 100644 index 00000000000..1aad019848d --- /dev/null +++ b/src/devices/cpu/i8085/8085dasm.h @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * Portable I8085A disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_I8085_8085DASM_H +#define MAME_CPU_I8085_8085DASM_H + +#pragma once + +class i8085_disassembler : public util::disasm_interface +{ +public: + i8085_disassembler() = default; + virtual ~i8085_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/i8085/i8085.cpp b/src/devices/cpu/i8085/i8085.cpp index 75a2360dc63..5e984464cf3 100644 --- a/src/devices/cpu/i8085/i8085.cpp +++ b/src/devices/cpu/i8085/i8085.cpp @@ -1,13 +1,19 @@ // license:BSD-3-Clause // copyright-holders:Juergen Buchmueller, hap +// thanks-to:Marcel De Kogel /***************************************************************************** * - * i8085.c * Portable I8085A emulator V1.2 * * Copyright Juergen Buchmueller, all rights reserved. * Partially based on information out of Z80Em by Marcel De Kogel * + * TODO: + * - 8085 DAA fails on 8080/8085 CPU Exerciser + * - not sure if 8085 DSUB H flag is correct + * + * --------------------------------------------------------------------------- + * * changes in V1.3 * - Added undocumented opcodes for the 8085A, based on a german * book about microcomputers: "Mikrocomputertechnik mit dem @@ -103,23 +109,38 @@ #include "emu.h" #include "debugger.h" #include "i8085.h" -#include "i8085cpu.h" +#include "8085dasm.h" #define VERBOSE 0 #include "logmacro.h" -#define CPUTYPE_8080 0 -#define CPUTYPE_8085 1 - - /*************************************************************************** - MACROS + CONSTANTS ***************************************************************************/ -#define IS_8080() (m_cputype == CPUTYPE_8080) -#define IS_8085() (m_cputype == CPUTYPE_8085) - +constexpr u8 SF = 0x80; +constexpr u8 ZF = 0x40; +constexpr u8 X5F = 0x20; +constexpr u8 HF = 0x10; +constexpr u8 X3F = 0x08; +constexpr u8 PF = 0x04; +constexpr u8 VF = 0x02; +constexpr u8 CF = 0x01; + +constexpr u8 IM_SID = 0x80; +constexpr u8 IM_I75 = 0x40; +constexpr u8 IM_I65 = 0x20; +constexpr u8 IM_I55 = 0x10; +constexpr u8 IM_IE = 0x08; +constexpr u8 IM_M75 = 0x04; +constexpr u8 IM_M65 = 0x02; +constexpr u8 IM_M55 = 0x01; + +constexpr u16 ADDR_TRAP = 0x0024; +constexpr u16 ADDR_RST55 = 0x002c; +constexpr u16 ADDR_RST65 = 0x0034; +constexpr u16 ADDR_RST75 = 0x003c; /*************************************************************************** @@ -127,7 +148,7 @@ ***************************************************************************/ /* cycles lookup */ -const uint8_t i8085a_cpu_device::lut_cycles_8080[256]={ +const u8 i8085a_cpu_device::lut_cycles_8080[256]={ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0 */ 4, 10,7, 5, 5, 5, 7, 4, 4, 10,7, 5, 5, 5, 7, 4, /* 1 */ 4, 10,7, 5, 5, 5, 7, 4, 4, 10,7, 5, 5, 5, 7, 4, @@ -145,7 +166,7 @@ const uint8_t i8085a_cpu_device::lut_cycles_8080[256]={ /* D */ 5, 10,10,10,11,11,7, 11,5, 10,10,10,11,11,7, 11, /* E */ 5, 10,10,18,11,11,7, 11,5, 5, 10,5, 11,11,7, 11, /* F */ 5, 10,10,4, 11,11,7, 11,5, 5, 10,4, 11,11,7, 11 }; -const uint8_t i8085a_cpu_device::lut_cycles_8085[256]={ +const u8 i8085a_cpu_device::lut_cycles_8085[256]={ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ /* 0 */ 4, 10,7, 6, 4, 4, 7, 4, 10,10,7, 6, 4, 4, 7, 4, /* 1 */ 7, 10,7, 6, 4, 4, 7, 4, 10,10,7, 6, 4, 4, 7, 4, @@ -165,13 +186,13 @@ const uint8_t i8085a_cpu_device::lut_cycles_8085[256]={ /* F */ 6, 10,10,4, 11,12,7, 12,6, 6, 10,4, 11,10,7, 12 }; /* special cases (partially taken care of elsewhere): - base c taken? not taken? -M_RET 8080 5 +6(11) -0 (conditional) -M_RET 8085 6 +6(12) -0 (conditional) -M_JMP 8080 10 +0 -0 -M_JMP 8085 10 +0 -3(7) -M_CALL 8080 11 +6(17) -0 -M_CALL 8085 11 +7(18) -2(9) + base c taken? not taken? +op_ret 8080 5 +6(11) -0 (conditional) +op_ret 8085 6 +6(12) -0 (conditional) +op_jmp 8080 10 +0 -0 +op_jmp 8085 10 +0 -3(7) +op_call 8080 11 +6(17) -0 +op_call 8085 11 +7(18) -2(9) */ @@ -181,16 +202,16 @@ DEFINE_DEVICE_TYPE(I8080A, i8080a_cpu_device, "i8080a", "8080A") DEFINE_DEVICE_TYPE(I8085A, i8085a_cpu_device, "i8085a", "8085A") -i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : i8085a_cpu_device(mconfig, I8085A, tag, owner, clock, CPUTYPE_8085) +i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : i8085a_cpu_device(mconfig, I8085A, tag, owner, clock, CPUTYPE_8085A) { } - -i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cputype) +i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int cputype) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0) , m_io_config("io", ENDIANNESS_LITTLE, 8, 8, 0) + , m_opcode_config("opcodes", ENDIANNESS_LITTLE, 8, 16, 0) , m_out_status_func(*this) , m_out_inte_func(*this) , m_in_sid_func(*this) @@ -199,21 +220,23 @@ i8085a_cpu_device::i8085a_cpu_device(const machine_config &mconfig, device_type { } - -i8080_cpu_device::i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +i8080_cpu_device::i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : i8085a_cpu_device(mconfig, I8080, tag, owner, clock, CPUTYPE_8080) { } - -i8080a_cpu_device::i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : i8085a_cpu_device(mconfig, I8080A, tag, owner, clock, CPUTYPE_8080) +i8080a_cpu_device::i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : i8085a_cpu_device(mconfig, I8080A, tag, owner, clock, CPUTYPE_8080A) { } device_memory_interface::space_config_vector i8085a_cpu_device::memory_space_config() const { - return space_config_vector { + return has_configured_map(AS_OPCODES) ? space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_IO, &m_io_config), + std::make_pair(AS_OPCODES, &m_opcode_config) + } : space_config_vector { std::make_pair(AS_PROGRAM, &m_program_config), std::make_pair(AS_IO, &m_io_config) }; @@ -235,664 +258,18 @@ void i8085a_cpu_device::device_clock_changed() } -void i8085a_cpu_device::set_sod(int state) -{ - if (state != 0 && m_sod_state == 0) - { - m_sod_state = 1; - m_out_sod_func(m_sod_state); - } - else if (state == 0 && m_sod_state != 0) - { - m_sod_state = 0; - m_out_sod_func(m_sod_state); - } -} - - -void i8085a_cpu_device::set_inte(int state) -{ - if (state != 0 && (m_IM & IM_IE) == 0) - { - m_IM |= IM_IE; - m_out_inte_func(1); - } - else if (state == 0 && (m_IM & IM_IE) != 0) - { - m_IM &= ~IM_IE; - m_out_inte_func(0); - } -} - - -void i8085a_cpu_device::set_status(uint8_t status) -{ - if (status != m_STATUS) - m_out_status_func(status); - - m_STATUS = status; -} - - -uint8_t i8085a_cpu_device::get_rim_value() -{ - uint8_t result = m_IM; - int sid = m_in_sid_func(); - - /* copy live RST5.5 and RST6.5 states */ - result &= ~(IM_I65 | IM_I55); - if (m_irq_state[I8085_RST65_LINE]) result |= IM_I65; - if (m_irq_state[I8085_RST55_LINE]) result |= IM_I55; - - /* fetch the SID bit if we have a callback */ - result = (result & ~IM_SID) | (sid ? IM_SID : 0); - - return result; -} - - -void i8085a_cpu_device::break_halt_for_interrupt() -{ - /* de-halt if necessary */ - if (m_HALT) - { - m_PC.w.l++; - m_HALT = 0; - set_status(0x26); /* int ack while halt */ - } - else - set_status(0x23); /* int ack */ -} - - -uint8_t i8085a_cpu_device::ROP() -{ - set_status(0xa2); // instruction fetch - return m_direct->read_byte(m_PC.w.l++); -} - -uint8_t i8085a_cpu_device::ARG() -{ - return m_direct->read_byte(m_PC.w.l++); -} - -uint16_t i8085a_cpu_device::ARG16() -{ - uint16_t w; - w = m_direct->read_byte(m_PC.d); - m_PC.w.l++; - w += m_direct->read_byte(m_PC.d) << 8; - m_PC.w.l++; - return w; -} - -uint8_t i8085a_cpu_device::RM(uint32_t a) -{ - set_status(0x82); // memory read - return m_program->read_byte(a); -} - -void i8085a_cpu_device::WM(uint32_t a, uint8_t v) -{ - set_status(0x00); // memory write - m_program->write_byte(a, v); -} - - -void i8085a_cpu_device::check_for_interrupts() -{ - /* TRAP is the highest priority */ - if (m_trap_pending) - { - /* the first RIM after a TRAP reflects the original IE state; remember it here, - setting the high bit to indicate it is valid */ - m_trap_im_copy = m_IM | 0x80; - - /* reset the pending state */ - m_trap_pending = false; - - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(INPUT_LINE_NMI); - - /* push the PC and jump to $0024 */ - M_PUSH(PC); - set_inte(0); - m_PC.w.l = ADDR_TRAP; - m_icount -= 11; - } - - /* followed by RST7.5 */ - else if ((m_IM & IM_I75) && !(m_IM & IM_M75) && (m_IM & IM_IE)) - { - /* reset the pending state (which is CPU-visible via the RIM instruction) */ - m_IM &= ~IM_I75; - - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(I8085_RST75_LINE); - - /* push the PC and jump to $003C */ - M_PUSH(PC); - set_inte(0); - m_PC.w.l = ADDR_RST75; - m_icount -= 11; - } - - /* followed by RST6.5 */ - else if (m_irq_state[I8085_RST65_LINE] && !(m_IM & IM_M65) && (m_IM & IM_IE)) - { - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(I8085_RST65_LINE); - - /* push the PC and jump to $0034 */ - M_PUSH(PC); - set_inte(0); - m_PC.w.l = ADDR_RST65; - m_icount -= 11; - } - - /* followed by RST5.5 */ - else if (m_irq_state[I8085_RST55_LINE] && !(m_IM & IM_M55) && (m_IM & IM_IE)) - { - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - standard_irq_callback(I8085_RST55_LINE); - - /* push the PC and jump to $002C */ - M_PUSH(PC); - set_inte(0); - m_PC.w.l = ADDR_RST55; - m_icount -= 11; - } - - /* followed by classic INTR */ - else if (m_irq_state[I8085_INTR_LINE] && (m_IM & IM_IE)) - { - uint32_t vector; - - /* break out of HALT state and call the IRQ ack callback */ - break_halt_for_interrupt(); - vector = standard_irq_callback(I8085_INTR_LINE); - - /* use the resulting vector as an opcode to execute */ - set_inte(0); - switch (vector & 0xff0000) - { - case 0xcd0000: /* CALL nnnn */ - m_icount -= 7; - M_PUSH(PC); - case 0xc30000: /* JMP nnnn */ - m_icount -= 10; - m_PC.d = vector & 0xffff; - break; - - default: - LOG("i8085 take int $%02x\n", vector); - execute_one(vector & 0xff); - break; - } - } -} - - -void i8085a_cpu_device::execute_one(int opcode) -{ - m_icount -= lut_cycles[opcode]; - - switch (opcode) - { - case 0x00: break; /* NOP */ - case 0x01: m_BC.w.l = ARG16(); break; /* LXI B,nnnn */ - case 0x02: WM(m_BC.d, m_AF.b.h); break; /* STAX B */ - case 0x03: m_BC.w.l++; /* INX B */ - if (IS_8085()) { if (m_BC.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x04: M_INR(m_BC.b.h); break; /* INR B */ - case 0x05: M_DCR(m_BC.b.h); break; /* DCR B */ - case 0x06: M_MVI(m_BC.b.h); break; /* MVI B,nn */ - case 0x07: M_RLC; break; /* RLC */ - - case 0x08: if (IS_8085()) { M_DSUB(); } /* DSUB */ - /* else { ; } */ /* NOP undocumented */ - break; - case 0x09: M_DAD(BC); break; /* DAD B */ - case 0x0a: m_AF.b.h = RM(m_BC.d); break; /* LDAX B */ - case 0x0b: m_BC.w.l--; /* DCX B */ - if (IS_8085()) { if (m_BC.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x0c: M_INR(m_BC.b.l); break; /* INR C */ - case 0x0d: M_DCR(m_BC.b.l); break; /* DCR C */ - case 0x0e: M_MVI(m_BC.b.l); break; /* MVI C,nn */ - case 0x0f: M_RRC; break; /* RRC */ - - case 0x10: if (IS_8085()) { /* ASRH */ - m_AF.b.l = (m_AF.b.l & ~CF) | (m_HL.b.l & CF); - m_HL.w.l = (m_HL.w.l >> 1); - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x11: m_DE.w.l = ARG16(); break; /* LXI D,nnnn */ - case 0x12: WM(m_DE.d, m_AF.b.h); break; /* STAX D */ - case 0x13: m_DE.w.l++; /* INX D */ - if (IS_8085()) { if (m_DE.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x14: M_INR(m_DE.b.h); break; /* INR D */ - case 0x15: M_DCR(m_DE.b.h); break; /* DCR D */ - case 0x16: M_MVI(m_DE.b.h); break; /* MVI D,nn */ - case 0x17: M_RAL; break; /* RAL */ - - case 0x18: if (IS_8085()) { /* RLDE */ - m_AF.b.l = (m_AF.b.l & ~(CF | VF)) | (m_DE.b.h >> 7); - m_DE.w.l = (m_DE.w.l << 1) | (m_DE.w.l >> 15); - if (0 != (((m_DE.w.l >> 15) ^ m_AF.b.l) & CF)) m_AF.b.l |= VF; - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x19: M_DAD(DE); break; /* DAD D */ - case 0x1a: m_AF.b.h = RM(m_DE.d); break; /* LDAX D */ - case 0x1b: m_DE.w.l--; /* DCX D */ - if (IS_8085()) { if (m_DE.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x1c: M_INR(m_DE.b.l); break; /* INR E */ - case 0x1d: M_DCR(m_DE.b.l); break; /* DCR E */ - case 0x1e: M_MVI(m_DE.b.l); break; /* MVI E,nn */ - case 0x1f: M_RAR; break; /* RAR */ - - case 0x20: if (IS_8085()) { /* RIM */ - m_AF.b.h = get_rim_value(); - - /* if we have remembered state from taking a TRAP, fix up the IE flag here */ - if (m_trap_im_copy & 0x80) m_AF.b.h = (m_AF.b.h & ~IM_IE) | (m_trap_im_copy & IM_IE); - m_trap_im_copy = 0; - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x21: m_HL.w.l = ARG16(); break; /* LXI H,nnnn */ - case 0x22: m_WZ.w.l = ARG16(); /* SHLD nnnn */ - WM(m_WZ.d, m_HL.b.l); m_WZ.w.l++; - WM(m_WZ.d, m_HL.b.h); - break; - case 0x23: m_HL.w.l++; /* INX H */ - if (IS_8085()) { if (m_HL.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x24: M_INR(m_HL.b.h); break; /* INR H */ - case 0x25: M_DCR(m_HL.b.h); break; /* DCR H */ - case 0x26: M_MVI(m_HL.b.h); break; /* MVI H,nn */ - case 0x27: m_WZ.b.h = m_AF.b.h; /* DAA */ - if (IS_8085() && m_AF.b.l&VF) { - if ((m_AF.b.l&HF) | ((m_AF.b.h&0xf)>9)) m_WZ.b.h-=6; - if ((m_AF.b.l&CF) | (m_AF.b.h>0x99)) m_WZ.b.h-=0x60; - } - else { - if ((m_AF.b.l&HF) | ((m_AF.b.h&0xf)>9)) m_WZ.b.h+=6; - if ((m_AF.b.l&CF) | (m_AF.b.h>0x99)) m_WZ.b.h+=0x60; - } - - m_AF.b.l=(m_AF.b.l&3) | (m_AF.b.h&0x28) | (m_AF.b.h>0x99) | ((m_AF.b.h^m_WZ.b.h)&0x10) | ZSP[m_WZ.b.h]; - m_AF.b.h=m_WZ.b.h; - break; - - case 0x28: if (IS_8085()) { /* LDEH nn */ - m_WZ.d = ARG(); - m_DE.d = (m_HL.d + m_WZ.d) & 0xffff; - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x29: M_DAD(HL); break; /* DAD H */ - case 0x2a: m_WZ.d = ARG16(); /* LHLD nnnn */ - m_HL.b.l = RM(m_WZ.d); m_WZ.w.l++; - m_HL.b.h = RM(m_WZ.d); - break; - case 0x2b: m_HL.w.l--; /* DCX H */ - if (IS_8085()) { if (m_HL.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x2c: M_INR(m_HL.b.l); break; /* INR L */ - case 0x2d: M_DCR(m_HL.b.l); break; /* DCR L */ - case 0x2e: M_MVI(m_HL.b.l); break; /* MVI L,nn */ - case 0x2f: m_AF.b.h ^= 0xff; /* CMA */ - if (IS_8085()) m_AF.b.l |= HF | VF; - break; - - case 0x30: if (IS_8085()) { /* SIM */ - /* if bit 3 is set, bits 0-2 become the new masks */ - if (m_AF.b.h & 0x08) { - m_IM &= ~(IM_M55 | IM_M65 | IM_M75 | IM_I55 | IM_I65); - m_IM |= m_AF.b.h & (IM_M55 | IM_M65 | IM_M75); - - /* update live state based on the new masks */ - if ((m_IM & IM_M55) == 0 && m_irq_state[I8085_RST55_LINE]) m_IM |= IM_I55; - if ((m_IM & IM_M65) == 0 && m_irq_state[I8085_RST65_LINE]) m_IM |= IM_I65; - } - - /* bit if 4 is set, the 7.5 flip-flop is cleared */ - if (m_AF.b.h & 0x10) m_IM &= ~IM_I75; - - /* if bit 6 is set, then bit 7 is the new SOD state */ - if (m_AF.b.h & 0x40) set_sod(m_AF.b.h >> 7); - - /* check for revealed interrupts */ - check_for_interrupts(); - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x31: m_SP.w.l = ARG16(); break; /* LXI SP,nnnn */ - case 0x32: m_WZ.d = ARG16(); /* STAX nnnn */ - WM(m_WZ.d, m_AF.b.h); - break; - case 0x33: m_SP.w.l++; /* INX SP */ - if (IS_8085()) { if (m_SP.w.l == 0x0000) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x34: m_WZ.b.l = RM(m_HL.d); /* INR M */ - M_INR(m_WZ.b.l); - WM(m_HL.d, m_WZ.b.l); - break; - case 0x35: m_WZ.b.l = RM(m_HL.d); /* DCR M */ - M_DCR(m_WZ.b.l); - WM(m_HL.d, m_WZ.b.l); - break; - case 0x36: m_WZ.b.l = ARG(); /* MVI M,nn */ - WM(m_HL.d, m_WZ.b.l); - break; - case 0x37: m_AF.b.l = (m_AF.b.l & 0xfe) | CF; break; /* STC */ - - case 0x38: if (IS_8085()) { /* LDES nn */ - m_WZ.d = ARG(); - m_DE.d = (m_SP.d + m_WZ.d) & 0xffff; - } /* else { ; } */ /* NOP undocumented */ - break; - case 0x39: M_DAD(SP); break; /* DAD SP */ - case 0x3a: m_WZ.d = ARG16(); /* LDAX nnnn */ - m_AF.b.h = RM(m_WZ.d); - break; - case 0x3b: m_SP.w.l--; /* DCX SP */ - if (IS_8085()) { if (m_SP.w.l == 0xffff) m_AF.b.l |= X5F; else m_AF.b.l &= ~X5F; } - break; - case 0x3c: M_INR(m_AF.b.h); break; /* INR A */ - case 0x3d: M_DCR(m_AF.b.h); break; /* DCR A */ - case 0x3e: M_MVI(m_AF.b.h); break; /* MVI A,nn */ - case 0x3f: m_AF.b.l = (m_AF.b.l & 0xfe) | (~m_AF.b.l & CF); break; /* CMC */ - - case 0x40: break; /* MOV B,B */ - case 0x41: m_BC.b.h = m_BC.b.l; break; /* MOV B,C */ - case 0x42: m_BC.b.h = m_DE.b.h; break; /* MOV B,D */ - case 0x43: m_BC.b.h = m_DE.b.l; break; /* MOV B,E */ - case 0x44: m_BC.b.h = m_HL.b.h; break; /* MOV B,H */ - case 0x45: m_BC.b.h = m_HL.b.l; break; /* MOV B,L */ - case 0x46: m_BC.b.h = RM(m_HL.d); break; /* MOV B,M */ - case 0x47: m_BC.b.h = m_AF.b.h; break; /* MOV B,A */ - - case 0x48: m_BC.b.l = m_BC.b.h; break; /* MOV C,B */ - case 0x49: break; /* MOV C,C */ - case 0x4a: m_BC.b.l = m_DE.b.h; break; /* MOV C,D */ - case 0x4b: m_BC.b.l = m_DE.b.l; break; /* MOV C,E */ - case 0x4c: m_BC.b.l = m_HL.b.h; break; /* MOV C,H */ - case 0x4d: m_BC.b.l = m_HL.b.l; break; /* MOV C,L */ - case 0x4e: m_BC.b.l = RM(m_HL.d); break; /* MOV C,M */ - case 0x4f: m_BC.b.l = m_AF.b.h; break; /* MOV C,A */ - - case 0x50: m_DE.b.h = m_BC.b.h; break; /* MOV D,B */ - case 0x51: m_DE.b.h = m_BC.b.l; break; /* MOV D,C */ - case 0x52: break; /* MOV D,D */ - case 0x53: m_DE.b.h = m_DE.b.l; break; /* MOV D,E */ - case 0x54: m_DE.b.h = m_HL.b.h; break; /* MOV D,H */ - case 0x55: m_DE.b.h = m_HL.b.l; break; /* MOV D,L */ - case 0x56: m_DE.b.h = RM(m_HL.d); break; /* MOV D,M */ - case 0x57: m_DE.b.h = m_AF.b.h; break; /* MOV D,A */ - - case 0x58: m_DE.b.l = m_BC.b.h; break; /* MOV E,B */ - case 0x59: m_DE.b.l = m_BC.b.l; break; /* MOV E,C */ - case 0x5a: m_DE.b.l = m_DE.b.h; break; /* MOV E,D */ - case 0x5b: break; /* MOV E,E */ - case 0x5c: m_DE.b.l = m_HL.b.h; break; /* MOV E,H */ - case 0x5d: m_DE.b.l = m_HL.b.l; break; /* MOV E,L */ - case 0x5e: m_DE.b.l = RM(m_HL.d); break; /* MOV E,M */ - case 0x5f: m_DE.b.l = m_AF.b.h; break; /* MOV E,A */ - - case 0x60: m_HL.b.h = m_BC.b.h; break; /* MOV H,B */ - case 0x61: m_HL.b.h = m_BC.b.l; break; /* MOV H,C */ - case 0x62: m_HL.b.h = m_DE.b.h; break; /* MOV H,D */ - case 0x63: m_HL.b.h = m_DE.b.l; break; /* MOV H,E */ - case 0x64: break; /* MOV H,H */ - case 0x65: m_HL.b.h = m_HL.b.l; break; /* MOV H,L */ - case 0x66: m_HL.b.h = RM(m_HL.d); break; /* MOV H,M */ - case 0x67: m_HL.b.h = m_AF.b.h; break; /* MOV H,A */ - - case 0x68: m_HL.b.l = m_BC.b.h; break; /* MOV L,B */ - case 0x69: m_HL.b.l = m_BC.b.l; break; /* MOV L,C */ - case 0x6a: m_HL.b.l = m_DE.b.h; break; /* MOV L,D */ - case 0x6b: m_HL.b.l = m_DE.b.l; break; /* MOV L,E */ - case 0x6c: m_HL.b.l = m_HL.b.h; break; /* MOV L,H */ - case 0x6d: break; /* MOV L,L */ - case 0x6e: m_HL.b.l = RM(m_HL.d); break; /* MOV L,M */ - case 0x6f: m_HL.b.l = m_AF.b.h; break; /* MOV L,A */ - - case 0x70: WM(m_HL.d, m_BC.b.h); break; /* MOV M,B */ - case 0x71: WM(m_HL.d, m_BC.b.l); break; /* MOV M,C */ - case 0x72: WM(m_HL.d, m_DE.b.h); break; /* MOV M,D */ - case 0x73: WM(m_HL.d, m_DE.b.l); break; /* MOV M,E */ - case 0x74: WM(m_HL.d, m_HL.b.h); break; /* MOV M,H */ - case 0x75: WM(m_HL.d, m_HL.b.l); break; /* MOV M,L */ - case 0x76: m_PC.w.l--; m_HALT = 1; /* HLT */ - set_status(0x8a); // halt acknowledge - break; - case 0x77: WM(m_HL.d, m_AF.b.h); break; /* MOV M,A */ - - case 0x78: m_AF.b.h = m_BC.b.h; break; /* MOV A,B */ - case 0x79: m_AF.b.h = m_BC.b.l; break; /* MOV A,C */ - case 0x7a: m_AF.b.h = m_DE.b.h; break; /* MOV A,D */ - case 0x7b: m_AF.b.h = m_DE.b.l; break; /* MOV A,E */ - case 0x7c: m_AF.b.h = m_HL.b.h; break; /* MOV A,H */ - case 0x7d: m_AF.b.h = m_HL.b.l; break; /* MOV A,L */ - case 0x7e: m_AF.b.h = RM(m_HL.d); break; /* MOV A,M */ - case 0x7f: break; /* MOV A,A */ - - case 0x80: M_ADD(m_BC.b.h); break; /* ADD B */ - case 0x81: M_ADD(m_BC.b.l); break; /* ADD C */ - case 0x82: M_ADD(m_DE.b.h); break; /* ADD D */ - case 0x83: M_ADD(m_DE.b.l); break; /* ADD E */ - case 0x84: M_ADD(m_HL.b.h); break; /* ADD H */ - case 0x85: M_ADD(m_HL.b.l); break; /* ADD L */ - case 0x86: m_WZ.b.l = RM(m_HL.d); M_ADD(m_WZ.b.l); break; /* ADD M */ - case 0x87: M_ADD(m_AF.b.h); break; /* ADD A */ - - case 0x88: M_ADC(m_BC.b.h); break; /* ADC B */ - case 0x89: M_ADC(m_BC.b.l); break; /* ADC C */ - case 0x8a: M_ADC(m_DE.b.h); break; /* ADC D */ - case 0x8b: M_ADC(m_DE.b.l); break; /* ADC E */ - case 0x8c: M_ADC(m_HL.b.h); break; /* ADC H */ - case 0x8d: M_ADC(m_HL.b.l); break; /* ADC L */ - case 0x8e: m_WZ.b.l = RM(m_HL.d); M_ADC(m_WZ.b.l); break; /* ADC M */ - case 0x8f: M_ADC(m_AF.b.h); break; /* ADC A */ - - case 0x90: M_SUB(m_BC.b.h); break; /* SUB B */ - case 0x91: M_SUB(m_BC.b.l); break; /* SUB C */ - case 0x92: M_SUB(m_DE.b.h); break; /* SUB D */ - case 0x93: M_SUB(m_DE.b.l); break; /* SUB E */ - case 0x94: M_SUB(m_HL.b.h); break; /* SUB H */ - case 0x95: M_SUB(m_HL.b.l); break; /* SUB L */ - case 0x96: m_WZ.b.l = RM(m_HL.d); M_SUB(m_WZ.b.l); break; /* SUB M */ - case 0x97: M_SUB(m_AF.b.h); break; /* SUB A */ - - case 0x98: M_SBB(m_BC.b.h); break; /* SBB B */ - case 0x99: M_SBB(m_BC.b.l); break; /* SBB C */ - case 0x9a: M_SBB(m_DE.b.h); break; /* SBB D */ - case 0x9b: M_SBB(m_DE.b.l); break; /* SBB E */ - case 0x9c: M_SBB(m_HL.b.h); break; /* SBB H */ - case 0x9d: M_SBB(m_HL.b.l); break; /* SBB L */ - case 0x9e: m_WZ.b.l = RM(m_HL.d); M_SBB(m_WZ.b.l); break; /* SBB M */ - case 0x9f: M_SBB(m_AF.b.h); break; /* SBB A */ - - case 0xa0: M_ANA(m_BC.b.h); break; /* ANA B */ - case 0xa1: M_ANA(m_BC.b.l); break; /* ANA C */ - case 0xa2: M_ANA(m_DE.b.h); break; /* ANA D */ - case 0xa3: M_ANA(m_DE.b.l); break; /* ANA E */ - case 0xa4: M_ANA(m_HL.b.h); break; /* ANA H */ - case 0xa5: M_ANA(m_HL.b.l); break; /* ANA L */ - case 0xa6: m_WZ.b.l = RM(m_HL.d); M_ANA(m_WZ.b.l); break; /* ANA M */ - case 0xa7: M_ANA(m_AF.b.h); break; /* ANA A */ - - case 0xa8: M_XRA(m_BC.b.h); break; /* XRA B */ - case 0xa9: M_XRA(m_BC.b.l); break; /* XRA C */ - case 0xaa: M_XRA(m_DE.b.h); break; /* XRA D */ - case 0xab: M_XRA(m_DE.b.l); break; /* XRA E */ - case 0xac: M_XRA(m_HL.b.h); break; /* XRA H */ - case 0xad: M_XRA(m_HL.b.l); break; /* XRA L */ - case 0xae: m_WZ.b.l = RM(m_HL.d); M_XRA(m_WZ.b.l); break; /* XRA M */ - case 0xaf: M_XRA(m_AF.b.h); break; /* XRA A */ - - case 0xb0: M_ORA(m_BC.b.h); break; /* ORA B */ - case 0xb1: M_ORA(m_BC.b.l); break; /* ORA C */ - case 0xb2: M_ORA(m_DE.b.h); break; /* ORA D */ - case 0xb3: M_ORA(m_DE.b.l); break; /* ORA E */ - case 0xb4: M_ORA(m_HL.b.h); break; /* ORA H */ - case 0xb5: M_ORA(m_HL.b.l); break; /* ORA L */ - case 0xb6: m_WZ.b.l = RM(m_HL.d); M_ORA(m_WZ.b.l); break; /* ORA M */ - case 0xb7: M_ORA(m_AF.b.h); break; /* ORA A */ - - case 0xb8: M_CMP(m_BC.b.h); break; /* CMP B */ - case 0xb9: M_CMP(m_BC.b.l); break; /* CMP C */ - case 0xba: M_CMP(m_DE.b.h); break; /* CMP D */ - case 0xbb: M_CMP(m_DE.b.l); break; /* CMP E */ - case 0xbc: M_CMP(m_HL.b.h); break; /* CMP H */ - case 0xbd: M_CMP(m_HL.b.l); break; /* CMP L */ - case 0xbe: m_WZ.b.l = RM(m_HL.d); M_CMP(m_WZ.b.l); break; /* CMP M */ - case 0xbf: M_CMP(m_AF.b.h); break; /* CMP A */ - - case 0xc0: M_RET( !(m_AF.b.l & ZF) ); break; /* RNZ */ - case 0xc1: M_POP(BC); break; /* POP B */ - case 0xc2: M_JMP( !(m_AF.b.l & ZF) ); break; /* JNZ nnnn */ - case 0xc3: M_JMP(1); break; /* JMP nnnn */ - case 0xc4: M_CALL( !(m_AF.b.l & ZF) ); break; /* CNZ nnnn */ - case 0xc5: M_PUSH(BC); break; /* PUSH B */ - case 0xc6: m_WZ.b.l = ARG(); M_ADD(m_WZ.b.l); break; /* ADI nn */ - case 0xc7: M_RST(0); break; /* RST 0 */ - - case 0xc8: M_RET( m_AF.b.l & ZF ); break; /* RZ */ - case 0xc9: M_POP(PC); break; /* RET */ - case 0xca: M_JMP( m_AF.b.l & ZF ); break; /* JZ nnnn */ - case 0xcb: if (IS_8085()) { /* RST V */ - if (m_AF.b.l & VF) { M_RST(8); } - else m_icount += 6; // RST not taken - } else { M_JMP(1); } /* JMP nnnn undocumented */ - break; - case 0xcc: M_CALL( m_AF.b.l & ZF ); break; /* CZ nnnn */ - case 0xcd: M_CALL(1); break; /* CALL nnnn */ - case 0xce: m_WZ.b.l = ARG(); M_ADC(m_WZ.b.l); break; /* ACI nn */ - case 0xcf: M_RST(1); break; /* RST 1 */ - - case 0xd0: M_RET( !(m_AF.b.l & CF) ); break; /* RNC */ - case 0xd1: M_POP(DE); break; /* POP D */ - case 0xd2: M_JMP( !(m_AF.b.l & CF) ); break; /* JNC nnnn */ - case 0xd3: M_OUT; break; /* OUT nn */ - case 0xd4: M_CALL( !(m_AF.b.l & CF) ); break; /* CNC nnnn */ - case 0xd5: M_PUSH(DE); break; /* PUSH D */ - case 0xd6: m_WZ.b.l = ARG(); M_SUB(m_WZ.b.l); break; /* SUI nn */ - case 0xd7: M_RST(2); break; /* RST 2 */ - - case 0xd8: M_RET( m_AF.b.l & CF ); break; /* RC */ - case 0xd9: if (IS_8085()) { /* SHLX */ - m_WZ.w.l = m_DE.w.l; - WM(m_WZ.d, m_HL.b.l); m_WZ.w.l++; - WM(m_WZ.d, m_HL.b.h); - } else { M_POP(PC); } /* RET undocumented */ - break; - case 0xda: M_JMP( m_AF.b.l & CF ); break; /* JC nnnn */ - case 0xdb: M_IN; break; /* IN nn */ - case 0xdc: M_CALL( m_AF.b.l & CF ); break; /* CC nnnn */ - case 0xdd: if (IS_8085()) { M_JMP( !(m_AF.b.l & X5F) ); } /* JNX nnnn */ - else { M_CALL(1); } /* CALL nnnn undocumented */ - break; - case 0xde: m_WZ.b.l = ARG(); M_SBB(m_WZ.b.l); break; /* SBI nn */ - case 0xdf: M_RST(3); break; /* RST 3 */ - - case 0xe0: M_RET( !(m_AF.b.l & PF) ); break; /* RPO */ - case 0xe1: M_POP(HL); break; /* POP H */ - case 0xe2: M_JMP( !(m_AF.b.l & PF) ); break; /* JPO nnnn */ - case 0xe3: M_POP(WZ); M_PUSH(HL); /* XTHL */ - m_HL.d = m_WZ.d; - break; - case 0xe4: M_CALL( !(m_AF.b.l & PF) ); break; /* CPO nnnn */ - case 0xe5: M_PUSH(HL); break; /* PUSH H */ - case 0xe6: m_WZ.b.l = ARG(); M_ANA(m_WZ.b.l); break; /* ANI nn */ - case 0xe7: M_RST(4); break; /* RST 4 */ - - case 0xe8: M_RET( m_AF.b.l & PF ); break; /* RPE */ - case 0xe9: m_PC.d = m_HL.w.l; break; /* PCHL */ - case 0xea: M_JMP( m_AF.b.l & PF ); break; /* JPE nnnn */ - case 0xeb: m_WZ.d = m_DE.d; /* XCHG */ - m_DE.d = m_HL.d; - m_HL.d = m_WZ.d; - break; - case 0xec: M_CALL( m_AF.b.l & PF ); break; /* CPE nnnn */ - case 0xed: if (IS_8085()) { /* LHLX */ - m_WZ.w.l = m_DE.w.l; - m_HL.b.l = RM(m_WZ.d); m_WZ.w.l++; - m_HL.b.h = RM(m_WZ.d); - } else { M_CALL(1); } /* CALL nnnn undocumented */ - break; - case 0xee: m_WZ.b.l = ARG(); M_XRA(m_WZ.b.l); break; /* XRI nn */ - case 0xef: M_RST(5); break; /* RST 5 */ - - case 0xf0: M_RET( !(m_AF.b.l&SF) ); break; /* RP */ - case 0xf1: M_POP(AF); break; /* POP A */ - case 0xf2: M_JMP( !(m_AF.b.l & SF) ); break; /* JP nnnn */ - case 0xf3: set_inte(0); break; /* DI */ - case 0xf4: M_CALL( !(m_AF.b.l & SF) ); break; /* CP nnnn */ - case 0xf5: if (IS_8080()) m_AF.b.l = (m_AF.b.l&~(X3F|X5F))|VF; // on 8080, VF=1 and X3F=0 and X5F=0 always! (we don't have to check for it elsewhere) - M_PUSH(AF); break; /* PUSH A */ - case 0xf6: m_WZ.b.l = ARG(); M_ORA(m_WZ.b.l); break; /* ORI nn */ - case 0xf7: M_RST(6); break; /* RST 6 */ - - case 0xf8: M_RET( m_AF.b.l & SF ); break; /* RM */ - case 0xf9: m_SP.d = m_HL.d; break; /* SPHL */ - case 0xfa: M_JMP( m_AF.b.l & SF ); break; /* JM nnnn */ - case 0xfb: set_inte(1); m_after_ei = 2; break; /* EI */ - case 0xfc: M_CALL( m_AF.b.l & SF ); break; /* CM nnnn */ - case 0xfd: if (IS_8085()) { M_JMP( m_AF.b.l & X5F ); } /* JX nnnn */ - else { M_CALL(1); } /* CALL nnnn undocumented */ - break; - case 0xfe: m_WZ.b.l = ARG(); M_CMP(m_WZ.b.l); break; /* CPI nn */ - case 0xff: M_RST(7); break; /* RST 7 */ - } -} - - -/*************************************************************************** - COMMON EXECUTION -***************************************************************************/ - -void i8085a_cpu_device::execute_run() -{ - /* check for TRAPs before diving in (can't do others because of after_ei) */ - if (m_trap_pending || m_after_ei == 0) - check_for_interrupts(); - - do - { - debugger_instruction_hook(this, m_PC.d); - - /* the instruction after an EI does not take an interrupt, so - we cannot check immediately; handle post-EI behavior here */ - if (m_after_ei != 0 && --m_after_ei == 0) - check_for_interrupts(); - - /* here we go... */ - execute_one(ROP()); - - } while (m_icount > 0); -} - - - /*************************************************************************** CORE INITIALIZATION ***************************************************************************/ void i8085a_cpu_device::init_tables() { - uint8_t zs; + u8 zs; int i, p; for (i = 0; i < 256; i++) { /* cycles */ - lut_cycles[i] = m_cputype?lut_cycles_8085[i]:lut_cycles_8080[i]; + lut_cycles[i] = is_8085() ? lut_cycles_8085[i] : lut_cycles_8080[i]; /* flags */ zs = 0; @@ -907,12 +284,11 @@ void i8085a_cpu_device::init_tables() if (i&32) ++p; if (i&64) ++p; if (i&128) ++p; - ZS[i] = zs; - ZSP[i] = zs | ((p&1) ? 0 : PF); + lut_zs[i] = zs; + lut_zsp[i] = zs | ((p&1) ? 0 : PF); } } - void i8085a_cpu_device::device_start() { m_PC.d = 0; @@ -922,9 +298,9 @@ void i8085a_cpu_device::device_start() m_DE.d = 0; m_HL.d = 0; m_WZ.d = 0; - m_HALT = 0; - m_IM = 0; - m_STATUS = 0; + m_halt = 0; + m_im = 0; + m_status = 0; m_after_ei = 0; m_nmi_state = 0; m_irq_state[3] = m_irq_state[2] = m_irq_state[1] = m_irq_state[0] = 0; @@ -955,14 +331,15 @@ void i8085a_cpu_device::device_start() state_add(I8085_BC, "BC", m_BC.w.l); state_add(I8085_DE, "DE", m_DE.w.l); state_add(I8085_HL, "HL", m_HL.w.l); - state_add(I8085_STATUS, "STATUS", m_STATUS); + state_add(I8085_STATUS, "STATUS", m_status); state_add(I8085_SOD, "SOD", m_sod_state).mask(0x1); state_add(I8085_SID, "SID", m_ietemp).mask(0x1).callimport().callexport(); state_add(I8085_INTE, "INTE", m_ietemp).mask(0x1).callimport().callexport(); } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); + m_opcode_direct = has_space(AS_OPCODES) ? space(AS_OPCODES).direct<0>() : m_direct; m_io = &space(AS_IO); /* resolve callbacks */ @@ -978,9 +355,9 @@ void i8085a_cpu_device::device_start() save_item(NAME(m_BC.w.l)); save_item(NAME(m_DE.w.l)); save_item(NAME(m_HL.w.l)); - save_item(NAME(m_HALT)); - save_item(NAME(m_IM)); - save_item(NAME(m_STATUS)); + save_item(NAME(m_halt)); + save_item(NAME(m_im)); + save_item(NAME(m_status)); save_item(NAME(m_after_ei)); save_item(NAME(m_nmi_state)); save_item(NAME(m_irq_state)); @@ -999,9 +376,9 @@ void i8085a_cpu_device::device_start() void i8085a_cpu_device::device_reset() { m_PC.d = 0; - m_HALT = 0; - m_IM &= ~IM_I75; - m_IM |= IM_M55 | IM_M65 | IM_M75; + m_halt = 0; + m_im &= ~IM_I75; + m_im |= IM_M55 | IM_M65 | IM_M75; m_after_ei = false; m_trap_pending = false; m_trap_im_copy = 0; @@ -1010,7 +387,6 @@ void i8085a_cpu_device::device_reset() } - /*************************************************************************** COMMON STATE IMPORT/EXPORT ***************************************************************************/ @@ -1022,22 +398,22 @@ void i8085a_cpu_device::state_import(const device_state_entry &entry) case I8085_SID: if (m_ietemp) { - m_IM |= IM_SID; + m_im |= IM_SID; } else { - m_IM &= ~IM_SID; + m_im &= ~IM_SID; } break; case I8085_INTE: if (m_ietemp) { - m_IM |= IM_IE; + m_im |= IM_IE; } else { - m_IM &= ~IM_IE; + m_im &= ~IM_IE; } break; @@ -1046,17 +422,16 @@ void i8085a_cpu_device::state_import(const device_state_entry &entry) } } - void i8085a_cpu_device::state_export(const device_state_entry &entry) { switch (entry.index()) { case I8085_SID: - m_ietemp = ((m_IM & IM_SID) != 0) && m_in_sid_func() != 0; + m_ietemp = ((m_im & IM_SID) != 0) && m_in_sid_func() != 0; break; case I8085_INTE: - m_ietemp = ((m_IM & IM_IE) != 0); + m_ietemp = ((m_im & IM_IE) != 0); break; default: @@ -1082,6 +457,15 @@ void i8085a_cpu_device::state_string_export(const device_state_entry &entry, std } } +util::disasm_interface *i8085a_cpu_device::create_disassembler() +{ + return new i8085_disassembler; +} + + +/*************************************************************************** + INTERRUPTS +***************************************************************************/ void i8085a_cpu_device::execute_set_input(int irqline, int state) { @@ -1099,7 +483,7 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state) else if (irqline == I8085_RST75_LINE) { if (!m_irq_state[I8085_RST75_LINE] && newstate) - m_IM |= IM_I75; + m_im |= IM_I75; m_irq_state[I8085_RST75_LINE] = newstate; } @@ -1108,9 +492,1133 @@ void i8085a_cpu_device::execute_set_input(int irqline, int state) m_irq_state[irqline] = state; } +void i8085a_cpu_device::break_halt_for_interrupt() +{ + /* de-halt if necessary */ + if (m_halt) + { + m_PC.w.l++; + m_halt = 0; + set_status(0x26); /* int ack while halt */ + } + else + set_status(0x23); /* int ack */ +} + +void i8085a_cpu_device::check_for_interrupts() +{ + /* TRAP is the highest priority */ + if (m_trap_pending) + { + /* the first RIM after a TRAP reflects the original IE state; remember it here, + setting the high bit to indicate it is valid */ + m_trap_im_copy = m_im | 0x80; + + /* reset the pending state */ + m_trap_pending = false; + + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(INPUT_LINE_NMI); + + /* push the PC and jump to $0024 */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_TRAP; + m_icount -= 11; + } + + /* followed by RST7.5 */ + else if ((m_im & IM_I75) && !(m_im & IM_M75) && (m_im & IM_IE)) + { + /* reset the pending state (which is CPU-visible via the RIM instruction) */ + m_im &= ~IM_I75; + + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(I8085_RST75_LINE); + + /* push the PC and jump to $003C */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_RST75; + m_icount -= 11; + } + + /* followed by RST6.5 */ + else if (m_irq_state[I8085_RST65_LINE] && !(m_im & IM_M65) && (m_im & IM_IE)) + { + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(I8085_RST65_LINE); + + /* push the PC and jump to $0034 */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_RST65; + m_icount -= 11; + } + + /* followed by RST5.5 */ + else if (m_irq_state[I8085_RST55_LINE] && !(m_im & IM_M55) && (m_im & IM_IE)) + { + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + standard_irq_callback(I8085_RST55_LINE); + + /* push the PC and jump to $002C */ + op_push(m_PC); + set_inte(0); + m_PC.w.l = ADDR_RST55; + m_icount -= 11; + } + + /* followed by classic INTR */ + else if (m_irq_state[I8085_INTR_LINE] && (m_im & IM_IE)) + { + u32 vector; + + /* break out of HALT state and call the IRQ ack callback */ + break_halt_for_interrupt(); + vector = standard_irq_callback(I8085_INTR_LINE); + + /* use the resulting vector as an opcode to execute */ + set_inte(0); + switch (vector & 0xff0000) + { + case 0xcd0000: /* CALL nnnn */ + m_icount -= 7; + op_push(m_PC); + case 0xc30000: /* JMP nnnn */ + m_icount -= 10; + m_PC.d = vector & 0xffff; + break; + + default: + LOG("i8085 take int $%02x\n", vector); + execute_one(vector & 0xff); + break; + } + } +} + + +/*************************************************************************** + OPCODE HELPERS +***************************************************************************/ -offs_t i8085a_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +void i8085a_cpu_device::set_sod(int state) { - extern CPU_DISASSEMBLE( i8085 ); - return CPU_DISASSEMBLE_NAME(i8085)(this, stream, pc, oprom, opram, options); + if (state != 0 && m_sod_state == 0) + { + m_sod_state = 1; + m_out_sod_func(m_sod_state); + } + else if (state == 0 && m_sod_state != 0) + { + m_sod_state = 0; + m_out_sod_func(m_sod_state); + } +} + +void i8085a_cpu_device::set_inte(int state) +{ + if (state != 0 && (m_im & IM_IE) == 0) + { + m_im |= IM_IE; + m_out_inte_func(1); + } + else if (state == 0 && (m_im & IM_IE) != 0) + { + m_im &= ~IM_IE; + m_out_inte_func(0); + } +} + +void i8085a_cpu_device::set_status(u8 status) +{ + if (status != m_status) + m_out_status_func(status); + + m_status = status; +} + +u8 i8085a_cpu_device::get_rim_value() +{ + u8 result = m_im; + int sid = m_in_sid_func(); + + /* copy live RST5.5 and RST6.5 states */ + result &= ~(IM_I65 | IM_I55); + if (m_irq_state[I8085_RST65_LINE]) result |= IM_I65; + if (m_irq_state[I8085_RST55_LINE]) result |= IM_I55; + + /* fetch the SID bit if we have a callback */ + result = (result & ~IM_SID) | (sid ? IM_SID : 0); + + return result; +} + +// memory access +u8 i8085a_cpu_device::read_arg() +{ + return m_direct->read_byte(m_PC.w.l++); +} + +PAIR i8085a_cpu_device::read_arg16() +{ + PAIR p; + p.b.l = m_direct->read_byte(m_PC.w.l++); + p.b.h = m_direct->read_byte(m_PC.w.l++); + return p; +} + +u8 i8085a_cpu_device::read_op() +{ + set_status(0xa2); // instruction fetch + return m_opcode_direct->read_byte(m_PC.w.l++); +} + +u8 i8085a_cpu_device::read_mem(u32 a) +{ + set_status(0x82); // memory read + return m_program->read_byte(a); +} + +void i8085a_cpu_device::write_mem(u32 a, u8 v) +{ + set_status(0x00); // memory write + m_program->write_byte(a, v); +} + +void i8085a_cpu_device::op_push(PAIR p) +{ + set_status(0x04); // stack push + m_program->write_byte(--m_SP.w.l, p.b.h); + m_program->write_byte(--m_SP.w.l, p.b.l); +} + +PAIR i8085a_cpu_device::op_pop() +{ + PAIR p; + set_status(0x86); // stack pop + p.b.l = m_program->read_byte(m_SP.w.l++); + p.b.h = m_program->read_byte(m_SP.w.l++); + return p; +} + +// logical +void i8085a_cpu_device::op_ora(u8 v) +{ + m_AF.b.h |= v; + m_AF.b.l = lut_zsp[m_AF.b.h]; +} + +void i8085a_cpu_device::op_xra(u8 v) +{ + m_AF.b.h ^= v; + m_AF.b.l = lut_zsp[m_AF.b.h]; +} + +void i8085a_cpu_device::op_ana(u8 v) +{ + u8 hc = ((m_AF.b.h | v) << 1) & HF; + m_AF.b.h &= v; + m_AF.b.l = lut_zsp[m_AF.b.h]; + if (is_8085()) + m_AF.b.l |= HF; + else + m_AF.b.l |= hc; +} + +// increase / decrease +u8 i8085a_cpu_device::op_inr(u8 v) +{ + u8 hc = ((v & 0x0f) == 0x0f) ? HF : 0; + m_AF.b.l = (m_AF.b.l & CF) | lut_zsp[++v] | hc; + return v; +} + +u8 i8085a_cpu_device::op_dcr(u8 v) +{ + u8 hc = ((v & 0x0f) != 0x00) ? HF : 0; + m_AF.b.l = (m_AF.b.l & CF) | lut_zsp[--v] | hc | VF; + return v; +} + +// arithmetic +void i8085a_cpu_device::op_add(u8 v) +{ + int q = m_AF.b.h + v; + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | ((m_AF.b.h ^ q ^ v) & HF); + m_AF.b.h = q; +} + +void i8085a_cpu_device::op_adc(u8 v) +{ + int q = m_AF.b.h + v + (m_AF.b.l & CF); + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | ((m_AF.b.h ^ q ^ v) & HF); + m_AF.b.h = q; +} + +void i8085a_cpu_device::op_sub(u8 v) +{ + int q = m_AF.b.h - v; + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | (~(m_AF.b.h ^ q ^ v) & HF) | VF; + m_AF.b.h = q; +} + +void i8085a_cpu_device::op_sbb(u8 v) +{ + int q = m_AF.b.h - v - (m_AF.b.l & CF); + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | (~(m_AF.b.h ^ q ^ v) & HF) | VF; + m_AF.b.h = q; +} + +void i8085a_cpu_device::op_cmp(u8 v) +{ + int q = m_AF.b.h - v; + m_AF.b.l = lut_zsp[q & 0xff] | ((q >> 8) & CF) | (~(m_AF.b.h ^ q ^ v) & HF) | VF; +} + +void i8085a_cpu_device::op_dad(u16 v) +{ + int q = m_HL.w.l + v; + m_AF.b.l = (m_AF.b.l & ~CF) | (q >> 16 & CF); + m_HL.w.l = q; +} + +// jumps +void i8085a_cpu_device::op_jmp(int cond) +{ + // on 8085, jump if condition is not satisfied is shorter + if (cond) + m_PC = read_arg16(); + else + { + m_PC.w.l += 2; + m_icount += (is_8085()) ? 3 : 0; + } +} + +void i8085a_cpu_device::op_call(int cond) +{ + // on 8085, call if condition is not satisfied is 9 ticks + if (cond) + { + PAIR p = read_arg16(); + m_icount -= (is_8085()) ? 7 : 6 ; + op_push(m_PC); + m_PC = p; + } + else + { + m_PC.w.l += 2; + m_icount += (is_8085()) ? 2 : 0; + } +} + +void i8085a_cpu_device::op_ret(int cond) +{ + // conditional RET only + if (cond) + { + m_icount -= 6; + m_PC = op_pop(); + } +} + +void i8085a_cpu_device::op_rst(u8 v) +{ + op_push(m_PC); + m_PC.d = 8 * v; +} + + +/*************************************************************************** + COMMON EXECUTION +***************************************************************************/ + +void i8085a_cpu_device::execute_run() +{ + /* check for TRAPs before diving in (can't do others because of after_ei) */ + if (m_trap_pending || m_after_ei == 0) + check_for_interrupts(); + + do + { + debugger_instruction_hook(this, m_PC.d); + + /* the instruction after an EI does not take an interrupt, so + we cannot check immediately; handle post-EI behavior here */ + if (m_after_ei != 0 && --m_after_ei == 0) + check_for_interrupts(); + + /* here we go... */ + execute_one(read_op()); + + } while (m_icount > 0); +} + +void i8085a_cpu_device::execute_one(int opcode) +{ + m_icount -= lut_cycles[opcode]; + + switch (opcode) + { + case 0x00: // NOP + break; + case 0x01: // LXI B,nnnn + m_BC = read_arg16(); + break; + case 0x02: // STAX B + write_mem(m_BC.d, m_AF.b.h); + break; + case 0x03: // INX B + m_BC.w.l++; + if (is_8085()) + { + if (m_BC.w.l == 0x0000) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x04: // INR B + m_BC.b.h = op_inr(m_BC.b.h); + break; + case 0x05: // DCR B + m_BC.b.h = op_dcr(m_BC.b.h); + break; + case 0x06: // MVI B,nn + m_BC.b.h = read_arg(); + break; + case 0x07: // RLC + m_AF.b.h = (m_AF.b.h << 1) | (m_AF.b.h >> 7); + m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); + break; + + case 0x08: // 8085: DSUB, otherwise undocumented NOP + if (is_8085()) + { + int q = m_HL.b.l - m_BC.b.l; + m_AF.b.l = lut_zs[q & 0xff] | ((q >> 8) & CF) | VF | ((m_HL.b.l ^ q ^ m_BC.b.l) & HF) | (((m_BC.b.l ^ m_HL.b.l) & (m_HL.b.l ^ q) & SF) >> 5); + m_HL.b.l = q; + q = m_HL.b.h - m_BC.b.h - (m_AF.b.l & CF); + m_AF.b.l = lut_zs[q & 0xff] | ((q >> 8) & CF) | VF | ((m_HL.b.h ^ q ^ m_BC.b.h) & HF) | (((m_BC.b.h ^ m_HL.b.h) & (m_HL.b.h ^ q) & SF) >> 5); + if (m_HL.b.l != 0) + m_AF.b.l &= ~ZF; + } + break; + case 0x09: // DAD B + op_dad(m_BC.w.l); + break; + case 0x0a: // LDAX B + m_AF.b.h = read_mem(m_BC.d); + break; + case 0x0b: // DCX B + m_BC.w.l--; + if (is_8085()) + { + if (m_BC.w.l == 0xffff) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x0c: // INR C + m_BC.b.l = op_inr(m_BC.b.l); + break; + case 0x0d: // DCR C + m_BC.b.l = op_dcr(m_BC.b.l); + break; + case 0x0e: // MVI C,nn + m_BC.b.l = read_arg(); + break; + case 0x0f: // RRC + m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); + m_AF.b.h = (m_AF.b.h >> 1) | (m_AF.b.h << 7); + break; + + case 0x10: // 8085: ASRH, otherwise undocumented NOP + if (is_8085()) + { + m_AF.b.l = (m_AF.b.l & ~CF) | (m_HL.b.l & CF); + m_HL.w.l = (m_HL.w.l >> 1); + } + break; + case 0x11: // LXI D,nnnn + m_DE = read_arg16(); + break; + case 0x12: // STAX D + write_mem(m_DE.d, m_AF.b.h); + break; + case 0x13: // INX D + m_DE.w.l++; + if (is_8085()) + { + if (m_DE.w.l == 0x0000) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x14: // INR D + m_DE.b.h = op_inr(m_DE.b.h); + break; + case 0x15: // DCR D + m_DE.b.h = op_dcr(m_DE.b.h); + break; + case 0x16: // MVI D,nn + m_DE.b.h = read_arg(); + break; + case 0x17: // RAL + { + int c = m_AF.b.l & CF; + m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h >> 7); + m_AF.b.h = (m_AF.b.h << 1) | c; + break; + } + + case 0x18: // 8085: RLDE, otherwise undocumented NOP + if (is_8085()) + { + m_AF.b.l = (m_AF.b.l & ~(CF | VF)) | (m_DE.b.h >> 7); + m_DE.w.l = (m_DE.w.l << 1) | (m_DE.w.l >> 15); + if ((((m_DE.w.l >> 15) ^ m_AF.b.l) & CF) != 0) + m_AF.b.l |= VF; + } + break; + case 0x19: // DAD D + op_dad(m_DE.w.l); + break; + case 0x1a: // LDAX D + m_AF.b.h = read_mem(m_DE.d); + break; + case 0x1b: // DCX D + m_DE.w.l--; + if (is_8085()) + { + if (m_DE.w.l == 0xffff) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x1c: // INR E + m_DE.b.l = op_inr(m_DE.b.l); + break; + case 0x1d: // DCR E + m_DE.b.l = op_dcr(m_DE.b.l); + break; + case 0x1e: // MVI E,nn + m_DE.b.l = read_arg(); + break; + case 0x1f: // RAR + { + int c = (m_AF.b.l & CF) << 7; + m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); + m_AF.b.h = (m_AF.b.h >> 1) | c; + break; + } + + case 0x20: // 8085: RIM, otherwise undocumented NOP + if (is_8085()) + { + m_AF.b.h = get_rim_value(); + + // if we have remembered state from taking a TRAP, fix up the IE flag here + if (m_trap_im_copy & 0x80) + m_AF.b.h = (m_AF.b.h & ~IM_IE) | (m_trap_im_copy & IM_IE); + m_trap_im_copy = 0; + } + break; + case 0x21: // LXI H,nnnn + m_HL = read_arg16(); + break; + case 0x22: // SHLD nnnn + m_WZ = read_arg16(); + write_mem(m_WZ.d, m_HL.b.l); + m_WZ.w.l++; + write_mem(m_WZ.d, m_HL.b.h); + break; + case 0x23: // INX H + m_HL.w.l++; + if (is_8085()) + { + if (m_HL.w.l == 0x0000) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x24: // INR H + m_HL.b.h = op_inr(m_HL.b.h); + break; + case 0x25: // DCR H + m_HL.b.h = op_dcr(m_HL.b.h); + break; + case 0x26: // MVI H,nn + m_HL.b.h = read_arg(); + break; + case 0x27: // DAA + m_WZ.b.h = m_AF.b.h; + if (is_8085() && m_AF.b.l & VF) + { + if ((m_AF.b.l & HF) || ((m_AF.b.h & 0xf) > 9)) + m_WZ.b.h -= 6; + if ((m_AF.b.l & CF) || (m_AF.b.h > 0x99)) + m_WZ.b.h -= 0x60; + } + else + { + if ((m_AF.b.l & HF) || ((m_AF.b.h & 0xf) > 9)) + m_WZ.b.h += 6; + if ((m_AF.b.l & CF) || (m_AF.b.h > 0x99)) + m_WZ.b.h += 0x60; + } + + m_AF.b.l = (m_AF.b.l & 3) | (m_AF.b.h & 0x28) | ((m_AF.b.h > 0x99) ? 1 : 0) | ((m_AF.b.h ^ m_WZ.b.h) & 0x10) | lut_zsp[m_WZ.b.h]; + m_AF.b.h = m_WZ.b.h; + break; + + case 0x28: // 8085: LDEH nn, otherwise undocumented NOP + if (is_8085()) + { + m_WZ.d = read_arg(); + m_DE.d = (m_HL.d + m_WZ.d) & 0xffff; + } + break; + case 0x29: // DAD H + op_dad(m_HL.w.l); + break; + case 0x2a: // LHLD nnnn + m_WZ = read_arg16(); + m_HL.b.l = read_mem(m_WZ.d); + m_WZ.w.l++; + m_HL.b.h = read_mem(m_WZ.d); + break; + case 0x2b: // DCX H + m_HL.w.l--; + if (is_8085()) + { + if (m_HL.w.l == 0xffff) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x2c: // INR L + m_HL.b.l = op_inr(m_HL.b.l); + break; + case 0x2d: // DCR L + m_HL.b.l = op_dcr(m_HL.b.l); + break; + case 0x2e: // MVI L,nn + m_HL.b.l = read_arg(); + break; + case 0x2f: // CMA + m_AF.b.h ^= 0xff; + if (is_8085()) + m_AF.b.l |= HF | VF; + break; + + case 0x30: // 8085: SIM, otherwise undocumented NOP + if (is_8085()) + { + // if bit 3 is set, bits 0-2 become the new masks + if (m_AF.b.h & 0x08) + { + m_im &= ~(IM_M55 | IM_M65 | IM_M75 | IM_I55 | IM_I65); + m_im |= m_AF.b.h & (IM_M55 | IM_M65 | IM_M75); + + // update live state based on the new masks + if ((m_im & IM_M55) == 0 && m_irq_state[I8085_RST55_LINE]) + m_im |= IM_I55; + if ((m_im & IM_M65) == 0 && m_irq_state[I8085_RST65_LINE]) + m_im |= IM_I65; + } + + // bit if 4 is set, the 7.5 flip-flop is cleared + if (m_AF.b.h & 0x10) + m_im &= ~IM_I75; + + // if bit 6 is set, then bit 7 is the new SOD state + if (m_AF.b.h & 0x40) + set_sod(m_AF.b.h >> 7); + + // check for revealed interrupts + check_for_interrupts(); + } + break; + case 0x31: // LXI SP,nnnn + m_SP = read_arg16(); + break; + case 0x32: // STAX nnnn + m_WZ = read_arg16(); + write_mem(m_WZ.d, m_AF.b.h); + break; + case 0x33: // INX SP + m_SP.w.l++; + if (is_8085()) + { + if (m_SP.w.l == 0x0000) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x34: // INR M + m_WZ.b.l = op_inr(read_mem(m_HL.d)); + write_mem(m_HL.d, m_WZ.b.l); + break; + case 0x35: // DCR M + m_WZ.b.l = op_dcr(read_mem(m_HL.d)); + write_mem(m_HL.d, m_WZ.b.l); + break; + case 0x36: // MVI M,nn + m_WZ.b.l = read_arg(); + write_mem(m_HL.d, m_WZ.b.l); + break; + case 0x37: // STC + m_AF.b.l = (m_AF.b.l & 0xfe) | CF; + break; + + case 0x38: // 8085: LDES nn, otherwise undocumented NOP + if (is_8085()) + { + m_WZ.d = read_arg(); + m_DE.d = (m_SP.d + m_WZ.d) & 0xffff; + } + break; + case 0x39: // DAD SP + op_dad(m_SP.w.l); + break; + case 0x3a: // LDAX nnnn + m_WZ = read_arg16(); + m_AF.b.h = read_mem(m_WZ.d); + break; + case 0x3b: // DCX SP + m_SP.w.l--; + if (is_8085()) + { + if (m_SP.w.l == 0xffff) + m_AF.b.l |= X5F; + else + m_AF.b.l &= ~X5F; + } + break; + case 0x3c: // INR A + m_AF.b.h = op_inr(m_AF.b.h); + break; + case 0x3d: // DCR A + m_AF.b.h = op_dcr(m_AF.b.h); + break; + case 0x3e: // MVI A,nn + m_AF.b.h = read_arg(); + break; + case 0x3f: // CMC + m_AF.b.l = (m_AF.b.l & 0xfe) | (~m_AF.b.l & CF); + break; + + // MOV [B/C/D/E/H/L/M/A],[B/C/D/E/H/L/M/A] + case 0x40: break; // MOV B,B + case 0x41: m_BC.b.h = m_BC.b.l; break; + case 0x42: m_BC.b.h = m_DE.b.h; break; + case 0x43: m_BC.b.h = m_DE.b.l; break; + case 0x44: m_BC.b.h = m_HL.b.h; break; + case 0x45: m_BC.b.h = m_HL.b.l; break; + case 0x46: m_BC.b.h = read_mem(m_HL.d); break; + case 0x47: m_BC.b.h = m_AF.b.h; break; + + case 0x48: m_BC.b.l = m_BC.b.h; break; + case 0x49: break; // MOV C,C + case 0x4a: m_BC.b.l = m_DE.b.h; break; + case 0x4b: m_BC.b.l = m_DE.b.l; break; + case 0x4c: m_BC.b.l = m_HL.b.h; break; + case 0x4d: m_BC.b.l = m_HL.b.l; break; + case 0x4e: m_BC.b.l = read_mem(m_HL.d); break; + case 0x4f: m_BC.b.l = m_AF.b.h; break; + + case 0x50: m_DE.b.h = m_BC.b.h; break; + case 0x51: m_DE.b.h = m_BC.b.l; break; + case 0x52: break; // MOV D,D + case 0x53: m_DE.b.h = m_DE.b.l; break; + case 0x54: m_DE.b.h = m_HL.b.h; break; + case 0x55: m_DE.b.h = m_HL.b.l; break; + case 0x56: m_DE.b.h = read_mem(m_HL.d); break; + case 0x57: m_DE.b.h = m_AF.b.h; break; + + case 0x58: m_DE.b.l = m_BC.b.h; break; + case 0x59: m_DE.b.l = m_BC.b.l; break; + case 0x5a: m_DE.b.l = m_DE.b.h; break; + case 0x5b: break; // MOV E,E + case 0x5c: m_DE.b.l = m_HL.b.h; break; + case 0x5d: m_DE.b.l = m_HL.b.l; break; + case 0x5e: m_DE.b.l = read_mem(m_HL.d); break; + case 0x5f: m_DE.b.l = m_AF.b.h; break; + + case 0x60: m_HL.b.h = m_BC.b.h; break; + case 0x61: m_HL.b.h = m_BC.b.l; break; + case 0x62: m_HL.b.h = m_DE.b.h; break; + case 0x63: m_HL.b.h = m_DE.b.l; break; + case 0x64: break; // MOV H,H + case 0x65: m_HL.b.h = m_HL.b.l; break; + case 0x66: m_HL.b.h = read_mem(m_HL.d); break; + case 0x67: m_HL.b.h = m_AF.b.h; break; + + case 0x68: m_HL.b.l = m_BC.b.h; break; + case 0x69: m_HL.b.l = m_BC.b.l; break; + case 0x6a: m_HL.b.l = m_DE.b.h; break; + case 0x6b: m_HL.b.l = m_DE.b.l; break; + case 0x6c: m_HL.b.l = m_HL.b.h; break; + case 0x6d: break; // MOV L,L + case 0x6e: m_HL.b.l = read_mem(m_HL.d); break; + case 0x6f: m_HL.b.l = m_AF.b.h; break; + + case 0x70: write_mem(m_HL.d, m_BC.b.h); break; + case 0x71: write_mem(m_HL.d, m_BC.b.l); break; + case 0x72: write_mem(m_HL.d, m_DE.b.h); break; + case 0x73: write_mem(m_HL.d, m_DE.b.l); break; + case 0x74: write_mem(m_HL.d, m_HL.b.h); break; + case 0x75: write_mem(m_HL.d, m_HL.b.l); break; + case 0x76: // HLT (instead of MOV M,M) + m_PC.w.l--; + m_halt = 1; + set_status(0x8a); // halt acknowledge + break; + case 0x77: write_mem(m_HL.d, m_AF.b.h); break; + + case 0x78: m_AF.b.h = m_BC.b.h; break; + case 0x79: m_AF.b.h = m_BC.b.l; break; + case 0x7a: m_AF.b.h = m_DE.b.h; break; + case 0x7b: m_AF.b.h = m_DE.b.l; break; + case 0x7c: m_AF.b.h = m_HL.b.h; break; + case 0x7d: m_AF.b.h = m_HL.b.l; break; + case 0x7e: m_AF.b.h = read_mem(m_HL.d); break; + case 0x7f: break; // MOV A,A + + // alu op [B/C/D/E/H/L/M/A] + case 0x80: op_add(m_BC.b.h); break; + case 0x81: op_add(m_BC.b.l); break; + case 0x82: op_add(m_DE.b.h); break; + case 0x83: op_add(m_DE.b.l); break; + case 0x84: op_add(m_HL.b.h); break; + case 0x85: op_add(m_HL.b.l); break; + case 0x86: m_WZ.b.l = read_mem(m_HL.d); op_add(m_WZ.b.l); break; + case 0x87: op_add(m_AF.b.h); break; + + case 0x88: op_adc(m_BC.b.h); break; + case 0x89: op_adc(m_BC.b.l); break; + case 0x8a: op_adc(m_DE.b.h); break; + case 0x8b: op_adc(m_DE.b.l); break; + case 0x8c: op_adc(m_HL.b.h); break; + case 0x8d: op_adc(m_HL.b.l); break; + case 0x8e: m_WZ.b.l = read_mem(m_HL.d); op_adc(m_WZ.b.l); break; + case 0x8f: op_adc(m_AF.b.h); break; + + case 0x90: op_sub(m_BC.b.h); break; + case 0x91: op_sub(m_BC.b.l); break; + case 0x92: op_sub(m_DE.b.h); break; + case 0x93: op_sub(m_DE.b.l); break; + case 0x94: op_sub(m_HL.b.h); break; + case 0x95: op_sub(m_HL.b.l); break; + case 0x96: m_WZ.b.l = read_mem(m_HL.d); op_sub(m_WZ.b.l); break; + case 0x97: op_sub(m_AF.b.h); break; + + case 0x98: op_sbb(m_BC.b.h); break; + case 0x99: op_sbb(m_BC.b.l); break; + case 0x9a: op_sbb(m_DE.b.h); break; + case 0x9b: op_sbb(m_DE.b.l); break; + case 0x9c: op_sbb(m_HL.b.h); break; + case 0x9d: op_sbb(m_HL.b.l); break; + case 0x9e: m_WZ.b.l = read_mem(m_HL.d); op_sbb(m_WZ.b.l); break; + case 0x9f: op_sbb(m_AF.b.h); break; + + case 0xa0: op_ana(m_BC.b.h); break; + case 0xa1: op_ana(m_BC.b.l); break; + case 0xa2: op_ana(m_DE.b.h); break; + case 0xa3: op_ana(m_DE.b.l); break; + case 0xa4: op_ana(m_HL.b.h); break; + case 0xa5: op_ana(m_HL.b.l); break; + case 0xa6: m_WZ.b.l = read_mem(m_HL.d); op_ana(m_WZ.b.l); break; + case 0xa7: op_ana(m_AF.b.h); break; + + case 0xa8: op_xra(m_BC.b.h); break; + case 0xa9: op_xra(m_BC.b.l); break; + case 0xaa: op_xra(m_DE.b.h); break; + case 0xab: op_xra(m_DE.b.l); break; + case 0xac: op_xra(m_HL.b.h); break; + case 0xad: op_xra(m_HL.b.l); break; + case 0xae: m_WZ.b.l = read_mem(m_HL.d); op_xra(m_WZ.b.l); break; + case 0xaf: op_xra(m_AF.b.h); break; + + case 0xb0: op_ora(m_BC.b.h); break; + case 0xb1: op_ora(m_BC.b.l); break; + case 0xb2: op_ora(m_DE.b.h); break; + case 0xb3: op_ora(m_DE.b.l); break; + case 0xb4: op_ora(m_HL.b.h); break; + case 0xb5: op_ora(m_HL.b.l); break; + case 0xb6: m_WZ.b.l = read_mem(m_HL.d); op_ora(m_WZ.b.l); break; + case 0xb7: op_ora(m_AF.b.h); break; + + case 0xb8: op_cmp(m_BC.b.h); break; + case 0xb9: op_cmp(m_BC.b.l); break; + case 0xba: op_cmp(m_DE.b.h); break; + case 0xbb: op_cmp(m_DE.b.l); break; + case 0xbc: op_cmp(m_HL.b.h); break; + case 0xbd: op_cmp(m_HL.b.l); break; + case 0xbe: m_WZ.b.l = read_mem(m_HL.d); op_cmp(m_WZ.b.l); break; + case 0xbf: op_cmp(m_AF.b.h); break; + + case 0xc0: // RNZ + op_ret(!(m_AF.b.l & ZF)); + break; + case 0xc1: // POP B + m_BC = op_pop(); + break; + case 0xc2: // JNZ nnnn + op_jmp(!(m_AF.b.l & ZF)); + break; + case 0xc3: // JMP nnnn + op_jmp(1); + break; + case 0xc4: // CNZ nnnn + op_call(!(m_AF.b.l & ZF)); + break; + case 0xc5: // PUSH B + op_push(m_BC); + break; + case 0xc6: // ADI nn + m_WZ.b.l = read_arg(); + op_add(m_WZ.b.l); + break; + case 0xc7: // RST 0 + op_rst(0); + break; + + case 0xc8: // RZ + op_ret(m_AF.b.l & ZF); + break; + case 0xc9: // RET + m_PC = op_pop(); + break; + case 0xca: // JZ nnnn + op_jmp(m_AF.b.l & ZF); + break; + case 0xcb: // 8085: RST V, otherwise undocumented JMP nnnn + if (is_8085()) + { + if (m_AF.b.l & VF) + op_rst(8); + else + m_icount += 6; // RST not taken + } + else + op_jmp(1); + break; + case 0xcc: // CZ nnnn + op_call(m_AF.b.l & ZF); + break; + case 0xcd: // CALL nnnn + op_call(1); + break; + case 0xce: // ACI nn + m_WZ.b.l = read_arg(); + op_adc(m_WZ.b.l); + break; + case 0xcf: // RST 1 + op_rst(1); + break; + + case 0xd0: // RNC + op_ret(!(m_AF.b.l & CF)); + break; + case 0xd1: // POP D + m_DE = op_pop(); + break; + case 0xd2: // JNC nnnn + op_jmp(!(m_AF.b.l & CF)); + break; + case 0xd3: // OUT nn + set_status(0x10); + m_WZ.d = read_arg(); + m_io->write_byte(m_WZ.d, m_AF.b.h); + break; + case 0xd4: // CNC nnnn + op_call(!(m_AF.b.l & CF)); + break; + case 0xd5: // PUSH D + op_push(m_DE); + break; + case 0xd6: // SUI nn + m_WZ.b.l = read_arg(); + op_sub(m_WZ.b.l); + break; + case 0xd7: // RST 2 + op_rst(2); + break; + + case 0xd8: // RC + op_ret(m_AF.b.l & CF); + break; + case 0xd9: // 8085: SHLX, otherwise undocumented RET + if (is_8085()) + { + m_WZ.w.l = m_DE.w.l; + write_mem(m_WZ.d, m_HL.b.l); + m_WZ.w.l++; + write_mem(m_WZ.d, m_HL.b.h); + } + else + m_PC = op_pop(); + break; + case 0xda: // JC nnnn + op_jmp(m_AF.b.l & CF); + break; + case 0xdb: // IN nn + set_status(0x42); + m_WZ.d = read_arg(); + m_AF.b.h = m_io->read_byte(m_WZ.d); + break; + case 0xdc: // CC nnnn + op_call(m_AF.b.l & CF); + break; + case 0xdd: // 8085: JNX nnnn, otherwise undocumented CALL nnnn + if (is_8085()) + op_jmp(!(m_AF.b.l & X5F)); + else + op_call(1); + break; + case 0xde: // SBI nn + m_WZ.b.l = read_arg(); + op_sbb(m_WZ.b.l); + break; + case 0xdf: // RST 3 + op_rst(3); + break; + + case 0xe0: // RPO + op_ret(!(m_AF.b.l & PF)); + break; + case 0xe1: // POP H + m_HL = op_pop(); + break; + case 0xe2: // JPO nnnn + op_jmp(!(m_AF.b.l & PF)); + break; + case 0xe3: // XTHL + m_WZ = op_pop(); + op_push(m_HL); + m_HL.d = m_WZ.d; + break; + case 0xe4: // CPO nnnn + op_call(!(m_AF.b.l & PF)); + break; + case 0xe5: // PUSH H + op_push(m_HL); + break; + case 0xe6: // ANI nn + m_WZ.b.l = read_arg(); + op_ana(m_WZ.b.l); + break; + case 0xe7: // RST 4 + op_rst(4); + break; + + case 0xe8: // RPE + op_ret(m_AF.b.l & PF); + break; + case 0xe9: // PCHL + m_PC.d = m_HL.w.l; + break; + case 0xea: // JPE nnnn + op_jmp(m_AF.b.l & PF); + break; + case 0xeb: // XCHG + m_WZ.d = m_DE.d; + m_DE.d = m_HL.d; + m_HL.d = m_WZ.d; + break; + case 0xec: // CPE nnnn + op_call(m_AF.b.l & PF); + break; + case 0xed: // 8085: LHLX, otherwise undocumented CALL nnnn + if (is_8085()) + { + m_WZ.w.l = m_DE.w.l; + m_HL.b.l = read_mem(m_WZ.d); + m_WZ.w.l++; + m_HL.b.h = read_mem(m_WZ.d); + } + else + op_call(1); + break; + case 0xee: // XRI nn + m_WZ.b.l = read_arg(); + op_xra(m_WZ.b.l); + break; + case 0xef: // RST 5 + op_rst(5); + break; + + case 0xf0: // RP + op_ret(!(m_AF.b.l & SF)); + break; + case 0xf1: // POP A + m_AF = op_pop(); + break; + case 0xf2: // JP nnnn + op_jmp(!(m_AF.b.l & SF)); + break; + case 0xf3: // DI + set_inte(0); + break; + case 0xf4: // CP nnnn + op_call(!(m_AF.b.l & SF)); + break; + case 0xf5: // PUSH A + // on 8080, VF=1 and X3F=0 and X5F=0 always! (we don't have to check for it elsewhere) + if (is_8080()) + m_AF.b.l = (m_AF.b.l & ~(X3F | X5F)) | VF; + op_push(m_AF); + break; + case 0xf6: // ORI nn + m_WZ.b.l = read_arg(); + op_ora(m_WZ.b.l); + break; + case 0xf7: // RST 6 + op_rst(6); + break; + + case 0xf8: // RM + op_ret(m_AF.b.l & SF); + break; + case 0xf9: // SPHL + m_SP.d = m_HL.d; + break; + case 0xfa: // JM nnnn + op_jmp(m_AF.b.l & SF); + break; + case 0xfb: // EI + set_inte(1); + m_after_ei = 2; + break; + case 0xfc: // CM nnnn + op_call(m_AF.b.l & SF); + break; + case 0xfd: // 8085: JX nnnn, otherwise undocumented CALL nnnn + if (is_8085()) + op_jmp(m_AF.b.l & X5F); + else + op_call(1); + break; + case 0xfe: // CPI nn + m_WZ.b.l = read_arg(); + op_cmp(m_WZ.b.l); + break; + case 0xff: // RST 7 + op_rst(7); + break; + } // end big switch } diff --git a/src/devices/cpu/i8085/i8085.h b/src/devices/cpu/i8085/i8085.h index 41f681f8897..b4ab5901c1f 100644 --- a/src/devices/cpu/i8085/i8085.h +++ b/src/devices/cpu/i8085/i8085.h @@ -53,17 +53,17 @@ public: I8085_HALT, I8085_IM }; - static constexpr uint8_t STATUS_INTA = 0x01; - static constexpr uint8_t STATUS_WO = 0x02; - static constexpr uint8_t STATUS_STACK = 0x04; - static constexpr uint8_t STATUS_HLTA = 0x08; - static constexpr uint8_t STATUS_OUT = 0x10; - static constexpr uint8_t STATUS_M1 = 0x20; - static constexpr uint8_t STATUS_INP = 0x40; - static constexpr uint8_t STATUS_MEMR = 0x80; + static constexpr u8 STATUS_INTA = 0x01; + static constexpr u8 STATUS_WO = 0x02; + static constexpr u8 STATUS_STACK = 0x04; + static constexpr u8 STATUS_HLTA = 0x08; + static constexpr u8 STATUS_OUT = 0x10; + static constexpr u8 STATUS_M1 = 0x20; + static constexpr u8 STATUS_INP = 0x40; + static constexpr u8 STATUS_MEMR = 0x80; // construction/destruction - i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + i8085a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // static configuration helpers template <class Object> static devcb_base &set_out_status_func(device_t &device, Object &&cb) { return downcast<i8085a_cpu_device &>(device).m_out_status_func.set_callback(std::forward<Object>(cb)); } @@ -73,7 +73,7 @@ public: static void static_set_clk_out(device_t &device, clock_update_delegate &&clk_out) { downcast<i8085a_cpu_device &>(device).m_clk_out_func = std::move(clk_out); } protected: - i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int cputype); + i8085a_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int cputype); // device-level overrides virtual void device_config_complete() override; @@ -82,14 +82,14 @@ protected: virtual void device_reset() override; // device_execute_interface overrides - virtual uint32_t execute_min_cycles() const override { return 4; } - virtual uint32_t execute_max_cycles() const override { return 16; } - virtual uint32_t execute_input_lines() const override { return 4; } - virtual uint32_t execute_default_irq_vector() const override { return 0xff; } + virtual u32 execute_min_cycles() const override { return 4; } + virtual u32 execute_max_cycles() const override { return 16; } + virtual u32 execute_input_lines() const override { return 4; } + virtual u32 execute_default_irq_vector() const override { return 0xff; } virtual void execute_run() override; virtual void execute_set_input(int inputnum, int state) override; - virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 2 - 1) / 2; } - virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 2); } + virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return (clocks + 2 - 1) / 2; } + virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return (cycles * 2); } // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; @@ -100,62 +100,89 @@ protected: virtual void state_import(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + + enum + { + CPUTYPE_8080 = 0, + CPUTYPE_8080A, + CPUTYPE_8085A + }; private: address_space_config m_program_config; address_space_config m_io_config; + address_space_config m_opcode_config; - devcb_write8 m_out_status_func; - devcb_write_line m_out_inte_func; - devcb_read_line m_in_sid_func; - devcb_write_line m_out_sod_func; + devcb_write8 m_out_status_func; + devcb_write_line m_out_inte_func; + devcb_read_line m_in_sid_func; + devcb_write_line m_out_sod_func; clock_update_delegate m_clk_out_func; - int m_cputype; /* 0 8080, 1 8085A */ - PAIR m_PC,m_SP,m_AF,m_BC,m_DE,m_HL,m_WZ; - uint8_t m_HALT; - uint8_t m_IM; /* interrupt mask (8085A only) */ - uint8_t m_STATUS; /* status word */ + inline bool is_8080() { return m_cputype == CPUTYPE_8080 || m_cputype == CPUTYPE_8080A; } + inline bool is_8085() { return m_cputype == CPUTYPE_8085A; } + int m_cputype; + + PAIR m_PC,m_SP,m_AF,m_BC,m_DE,m_HL,m_WZ; + u8 m_halt; + u8 m_im; /* interrupt mask (8085A only) */ + u8 m_status; /* status word */ - uint8_t m_after_ei; /* post-EI processing; starts at 2, check for ints at 0 */ - uint8_t m_nmi_state; /* raw NMI line state */ - uint8_t m_irq_state[4]; /* raw IRQ line states */ - uint8_t m_trap_pending; /* TRAP interrupt latched? */ - uint8_t m_trap_im_copy; /* copy of IM register when TRAP was taken */ - uint8_t m_sod_state; /* state of the SOD line */ + u8 m_after_ei; /* post-EI processing; starts at 2, check for ints at 0 */ + u8 m_nmi_state; /* raw NMI line state */ + u8 m_irq_state[4]; /* raw IRQ line states */ + u8 m_trap_pending; /* TRAP interrupt latched? */ + u8 m_trap_im_copy; /* copy of IM register when TRAP was taken */ + u8 m_sod_state; /* state of the SOD line */ - bool m_ietemp; /* import/export temp space */ + bool m_ietemp; /* import/export temp space */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; + direct_read_data<0> *m_opcode_direct; address_space *m_io; - int m_icount; + int m_icount; /* cycles lookup */ - static const uint8_t lut_cycles_8080[256]; - static const uint8_t lut_cycles_8085[256]; - uint8_t lut_cycles[256]; + static const u8 lut_cycles_8080[256]; + static const u8 lut_cycles_8085[256]; + u8 lut_cycles[256]; /* flags lookup */ - uint8_t ZS[256]; - uint8_t ZSP[256]; + u8 lut_zs[256]; + u8 lut_zsp[256]; void set_sod(int state); void set_inte(int state); - void set_status(uint8_t status); - uint8_t get_rim_value(); + void set_status(u8 status); + u8 get_rim_value(); void break_halt_for_interrupt(); - uint8_t ROP(); - uint8_t ARG(); - uint16_t ARG16(); - uint8_t RM(uint32_t a); - void WM(uint32_t a, uint8_t v); + u8 read_op(); + u8 read_arg(); + PAIR read_arg16(); + u8 read_mem(u32 a); + void write_mem(u32 a, u8 v); + void op_push(PAIR p); + PAIR op_pop(); void check_for_interrupts(); void execute_one(int opcode); void init_tables(); + void op_ora(u8 v); + void op_xra(u8 v); + void op_ana(u8 v); + u8 op_inr(u8 v); + u8 op_dcr(u8 v); + void op_add(u8 v); + void op_adc(u8 v); + void op_sub(u8 v); + void op_sbb(u8 v); + void op_cmp(u8 v); + void op_dad(u16 v); + void op_jmp(int cond); + void op_call(int cond); + void op_ret(int cond); + void op_rst(u8 v); }; @@ -163,12 +190,12 @@ class i8080_cpu_device : public i8085a_cpu_device { public: // construction/destruction - i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + i8080_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: - virtual uint32_t execute_input_lines() const override { return 1; } - virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return clocks; } - virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return cycles; } + virtual u32 execute_input_lines() const override { return 1; } + virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return clocks; } + virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return cycles; } }; @@ -176,12 +203,12 @@ class i8080a_cpu_device : public i8085a_cpu_device { public: // construction/destruction - i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + i8080a_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: - virtual uint32_t execute_input_lines() const override { return 1; } - virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return clocks; } - virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return cycles; } + virtual u32 execute_input_lines() const override { return 1; } + virtual u64 execute_clocks_to_cycles(u64 clocks) const override { return clocks; } + virtual u64 execute_cycles_to_clocks(u64 cycles) const override { return cycles; } }; diff --git a/src/devices/cpu/i8085/i8085cpu.h b/src/devices/cpu/i8085/i8085cpu.h deleted file mode 100644 index a41e96f06c7..00000000000 --- a/src/devices/cpu/i8085/i8085cpu.h +++ /dev/null @@ -1,188 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Juergen Buchmueller, hap -/******************************************************* - * - * Portable (hopefully ;-) 8085A emulator - * - * Written by J. Buchmueller for use with MAME - * - * Partially based on Z80Em by Marcel De Kogel - * - * CPU related macros - * - *******************************************************/ - - -#define SF 0x80 -#define ZF 0x40 -#define X5F 0x20 -#define HF 0x10 -#define X3F 0x08 -#define PF 0x04 -#define VF 0x02 -#define CF 0x01 - -#define IM_SID 0x80 -#define IM_I75 0x40 -#define IM_I65 0x20 -#define IM_I55 0x10 -#define IM_IE 0x08 -#define IM_M75 0x04 -#define IM_M65 0x02 -#define IM_M55 0x01 - -#define ADDR_TRAP 0x0024 -#define ADDR_RST55 0x002c -#define ADDR_RST65 0x0034 -#define ADDR_RST75 0x003c -#define ADDR_INTR 0x0038 - - -#define M_MVI(R) R=ARG() - -/* rotate */ -#define M_RLC { \ - m_AF.b.h = (m_AF.b.h << 1) | (m_AF.b.h >> 7); \ - m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); \ -} - -#define M_RRC { \ - m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); \ - m_AF.b.h = (m_AF.b.h >> 1) | (m_AF.b.h << 7); \ -} - -#define M_RAL { \ - int c = m_AF.b.l&CF; \ - m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h >> 7); \ - m_AF.b.h = (m_AF.b.h << 1) | c; \ -} - -#define M_RAR { \ - int c = (m_AF.b.l&CF) << 7; \ - m_AF.b.l = (m_AF.b.l & 0xfe) | (m_AF.b.h & CF); \ - m_AF.b.h = (m_AF.b.h >> 1) | c; \ -} - -/* logical */ -#define M_ORA(R) m_AF.b.h|=R; m_AF.b.l=ZSP[m_AF.b.h] -#define M_XRA(R) m_AF.b.h^=R; m_AF.b.l=ZSP[m_AF.b.h] -#define M_ANA(R) {uint8_t hc = ((m_AF.b.h | R)<<1) & HF; m_AF.b.h&=R; m_AF.b.l=ZSP[m_AF.b.h]; if(IS_8085()) { m_AF.b.l |= HF; } else {m_AF.b.l |= hc; } } - -/* increase / decrease */ -#define M_INR(R) {uint8_t hc = ((R & 0x0f) == 0x0f) ? HF : 0; ++R; m_AF.b.l= (m_AF.b.l & CF ) | ZSP[R] | hc; } -#define M_DCR(R) {uint8_t hc = ((R & 0x0f) != 0x00) ? HF : 0; --R; m_AF.b.l= (m_AF.b.l & CF ) | ZSP[R] | hc | VF; } - -/* arithmetic */ -#define M_ADD(R) { \ - int q = m_AF.b.h+R; \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|((m_AF.b.h^q^R)&HF); \ - m_AF.b.h=q; \ -} - -#define M_ADC(R) { \ - int q = m_AF.b.h+R+(m_AF.b.l&CF); \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|((m_AF.b.h^q^R)&HF); \ - m_AF.b.h=q; \ -} - -#define M_SUB(R) { \ - int q = m_AF.b.h-R; \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|(~(m_AF.b.h^q^R)&HF)|VF; \ - m_AF.b.h=q; \ -} - -#define M_SBB(R) { \ - int q = m_AF.b.h-R-(m_AF.b.l&CF); \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|(~(m_AF.b.h^q^R)&HF)|VF; \ - m_AF.b.h=q; \ -} - -#define M_CMP(R) { \ - int q = m_AF.b.h-R; \ - m_AF.b.l=ZSP[q&255]|((q>>8)&CF)|(~(m_AF.b.h^q^R)&HF)|VF; \ -} - -#define M_DAD(R) { \ - int q = m_HL.d + m_##R.d; \ - m_AF.b.l = (m_AF.b.l & ~CF) | (q>>16 & CF ); \ - m_HL.w.l = q; \ -} - -// DSUB is 8085-only, not sure if H flag handling is correct -#define M_DSUB() { \ - int q = m_HL.b.l-m_BC.b.l; \ - m_AF.b.l=ZS[q&255]|((q>>8)&CF)|VF| \ - ((m_HL.b.l^q^m_BC.b.l)&HF)| \ - (((m_BC.b.l^m_HL.b.l)&(m_HL.b.l^q)&SF)>>5); \ - m_HL.b.l=q; \ - q = m_HL.b.h-m_BC.b.h-(m_AF.b.l&CF); \ - m_AF.b.l=ZS[q&255]|((q>>8)&CF)|VF| \ - ((m_HL.b.h^q^m_BC.b.h)&HF)| \ - (((m_BC.b.h^m_HL.b.h)&(m_HL.b.h^q)&SF)>>5); \ - if (m_HL.b.l!=0) m_AF.b.l&=~ZF; \ -} - -/* i/o */ -#define M_IN \ - set_status(0x42); \ - m_WZ.d=ARG(); \ - m_AF.b.h=m_io->read_byte(m_WZ.d); - -#define M_OUT \ - set_status(0x10); \ - m_WZ.d=ARG(); \ - m_io->write_byte(m_WZ.d,m_AF.b.h) - -/* stack */ -#define M_PUSH(R) { \ - set_status(0x04); \ - m_program->write_byte(--m_SP.w.l, m_##R.b.h); \ - m_program->write_byte(--m_SP.w.l, m_##R.b.l); \ -} - -#define M_POP(R) { \ - set_status(0x86); \ - m_##R.b.l = m_program->read_byte(m_SP.w.l++); \ - m_##R.b.h = m_program->read_byte(m_SP.w.l++); \ -} - -/* jumps */ -// On 8085 jump if condition is not satisfied is shorter -#define M_JMP(cc) { \ - if (cc) { \ - m_PC.w.l = ARG16(); \ - } else { \ - m_PC.w.l += 2; \ - m_icount += (IS_8085()) ? 3 : 0; \ - } \ -} - -// On 8085 call if condition is not satisfied is 9 ticks -#define M_CALL(cc) \ -{ \ - if (cc) \ - { \ - uint16_t a = ARG16(); \ - m_icount -= (IS_8085()) ? 7 : 6 ; \ - M_PUSH(PC); \ - m_PC.d = a; \ - } else { \ - m_PC.w.l += 2; \ - m_icount += (IS_8085()) ? 2 : 0; \ - } \ -} - -// conditional RET only -#define M_RET(cc) \ -{ \ - if (cc) \ - { \ - m_icount -= 6; \ - M_POP(PC); \ - } \ -} - -#define M_RST(nn) { \ - M_PUSH(PC); \ - m_PC.d = 8 * nn; \ -} diff --git a/src/devices/cpu/i8089/i8089.cpp b/src/devices/cpu/i8089/i8089.cpp index 93a38ceea04..d688555d26b 100644 --- a/src/devices/cpu/i8089/i8089.cpp +++ b/src/devices/cpu/i8089/i8089.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "i8089.h" +#include "i8089_dasm.h" #include "i8089_channel.h" @@ -39,7 +40,7 @@ i8089_device::i8089_device(const machine_config &mconfig, const char *tag, devic m_ch1(*this, "1"), m_ch2(*this, "2"), m_write_sintr1(*this), - m_write_sintr2(*this), m_databus_width(0), m_mem(nullptr), m_io(nullptr), + m_write_sintr2(*this), m_data_width(0), m_mem(nullptr), m_io(nullptr), m_sysbus(0), m_scb(0), m_soc(0), m_initialized(false), @@ -116,8 +117,8 @@ void i8089_device::device_start() void i8089_device::device_config_complete() { - m_program_config = address_space_config("program", ENDIANNESS_LITTLE, m_databus_width, 20); - m_io_config = address_space_config("io", ENDIANNESS_LITTLE, m_databus_width, 16); + m_program_config = address_space_config("program", ENDIANNESS_LITTLE, m_data_width, 20); + m_io_config = address_space_config("io", ENDIANNESS_LITTLE, m_data_width, 16); } //------------------------------------------------- @@ -144,13 +145,12 @@ device_memory_interface::space_config_vector i8089_device::memory_space_config() } //------------------------------------------------- -// disasm_disassemble - disassembler +// disassemble - disassembler //------------------------------------------------- -offs_t i8089_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8089_device::create_disassembler() { - extern CPU_DISASSEMBLE(i8089); - return CPU_DISASSEMBLE_NAME(i8089)(this, stream, pc, oprom, opram, options); + return new i8089_disassembler(); } //------------------------------------------------- diff --git a/src/devices/cpu/i8089/i8089.h b/src/devices/cpu/i8089/i8089.h index 3465c444e2a..1659afd54d9 100644 --- a/src/devices/cpu/i8089/i8089.h +++ b/src/devices/cpu/i8089/i8089.h @@ -22,8 +22,8 @@ // INTERFACE CONFIGURATION MACROS //************************************************************************** -#define MCFG_I8089_DATABUS_WIDTH(_databus_width) \ - i8089_device::set_databus_width(*device, _databus_width); +#define MCFG_I8089_DATA_WIDTH(_data_width) \ + i8089_device::set_data_width(*device, _data_width); #define MCFG_I8089_SINTR1(_sintr1) \ devcb = &downcast<i8089_device *>(device)->set_sintr1_callback(DEVCB_##_sintr1); @@ -54,7 +54,7 @@ public: template <class Object> devcb_base &set_sintr2_callback(Object &&sintr2) { return m_write_sintr2.set_callback(std::forward<Object>(sintr2)); } // static configuration helpers - static void set_databus_width(device_t &device, uint8_t databus_width) { downcast<i8089_device &>(device).m_databus_width = databus_width; } + static void set_data_width(device_t &device, uint8_t data_width) { downcast<i8089_device &>(device).m_data_width = data_width; } // input lines DECLARE_WRITE_LINE_MEMBER( ca_w ); @@ -82,9 +82,7 @@ protected: address_space_config m_io_config; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 7; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -114,7 +112,7 @@ private: void initialize(); - uint8_t m_databus_width; + uint8_t m_data_width; address_space *m_mem; address_space *m_io; diff --git a/src/devices/cpu/i8089/i8089_dasm.cpp b/src/devices/cpu/i8089/i8089_dasm.cpp index 1159602289b..8e45053b1ba 100644 --- a/src/devices/cpu/i8089/i8089_dasm.cpp +++ b/src/devices/cpu/i8089/i8089_dasm.cpp @@ -9,439 +9,385 @@ ***************************************************************************/ #include "emu.h" +#include "i8089_dasm.h" -class i8089_instruction +const char *const i8089_disassembler::m_reg[] = { -public: - i8089_instruction(offs_t pc, const uint8_t *oprom) : - m_oprom(oprom), m_ppc(pc), m_pc(0), m_flags(DASMFLAG_SUPPORTED) - { - // instruction - m_brp = (oprom[0] >> 5) & 0x07; - m_wb = (oprom[0] >> 3) & 0x03; - m_aa = (oprom[0] >> 1) & 0x03; - m_w = (oprom[0] >> 0) & 0x01; - m_opc = (oprom[1] >> 2) & 0x3f; - m_mm = (oprom[1] >> 0) & 0x03; - - // clear buffers - memset(m_buffer, 0, sizeof(m_buffer)); - memset(m_offset, 0, sizeof(m_offset)); - - // start working - disassemble(); - } - - char *buffer() { return m_buffer; } - int length() const { return m_pc; } - int flags() const { return m_flags; } - -private: - const uint8_t *m_oprom; + "ga", "gb", "gc", "bc", "tp", "ix", "cc", "mc" +}; - char m_buffer[256]; - char m_offset[100]; - offs_t m_ppc; - int m_pc; +// fetch 1-byte value +uint8_t i8089_disassembler::fetch_value8() +{ + uint8_t i = m_opcodes->r8(m_pc); + m_pc += 1; + return i; +} - // decoded instruction - int m_brp; - int m_wb; - int m_aa; - int m_w; - int m_opc; - int m_mm; +// fetch 2-byte value +uint16_t i8089_disassembler::fetch_value16() +{ + uint16_t i = m_opcodes->r16(m_pc); + m_pc += 2; + return i; +} - // dasm flags - int m_flags; +// fetch a 1 or 2 byte immediate value +uint16_t i8089_disassembler::fetch_immediate() +{ + return (m_wb & 1) ? fetch_value8() : fetch_value16(); +} - // register names - static const char *m_reg[]; +// print memory offset +std::string i8089_disassembler::offset() +{ + const char *mm_name[] = { "ga", "gb", "gc", "pp" }; - // register index - enum + switch (m_aa) { - GA, // 20-bit general purpose address a - GB, // 20-bit general purpose address b - GC, // 20-bit general purpose address c - BC, // byte count - TP, // 20-bit task pointer - IX, // index - CC, // mask compare - MC // channel control - }; - - // fetch 1-byte value - uint8_t fetch_value8() - { - uint8_t i = m_oprom[m_pc]; - m_pc += 1; - return i; + case 0: return util::string_format("[%s]", mm_name[m_mm]); + case 1: return util::string_format("[%s].%02x", mm_name[m_mm], m_opcodes->r8(m_pc++)); + case 2: return util::string_format("[%s+ix]", mm_name[m_mm]); + case 3: return util::string_format("[%s+ix+]", mm_name[m_mm]); } + return ""; +} - // fetch 2-byte value - uint16_t fetch_value16() - { - uint16_t i = m_oprom[m_pc] | m_oprom[m_pc + 1] << 8; - m_pc += 2; - return i; - } +// invalid instruction +std::string i8089_disassembler::invalid() +{ + return "???"; +} - // fetch a 1 or 2 byte immediate value - uint16_t fetch_immediate() - { - return (m_wb & 1) ? fetch_value8() : fetch_value16(); - } +// to register or memory from immediate +std::string i8089_disassembler::from_i(std::string instr8, std::string instr16, std::string target) +{ + if (m_w == 0 && m_wb == 1) + return util::string_format("%s %s, %02x", instr8, target, fetch_immediate()); + else if (m_w == 1 && m_wb == 2) + return util::string_format("%s %s, %04x", instr16, target, fetch_immediate()); + else + return invalid(); +} - // print memory offset - void offset() - { - const char *mm_name[] = { "ga", "gb", "gc", "pp" }; +// register, immediate +std::string i8089_disassembler::inst_ri(std::string instr8, std::string instr16) +{ + if (m_mm == 0) + return from_i(instr8, instr16, m_reg[m_brp]); + else + return invalid(); +} - switch (m_aa) - { - case 0: sprintf(m_offset, "[%s]", mm_name[m_mm]); break; - case 1: sprintf(m_offset, "[%s].%02x", mm_name[m_mm], m_oprom[m_pc]); m_pc++; break; - case 2: sprintf(m_offset, "[%s+ix]", mm_name[m_mm]); break; - case 3: sprintf(m_offset, "[%s+ix+]", mm_name[m_mm]); break; - } - } +// register +std::string i8089_disassembler::inst_r(std::string instr) +{ + if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0) + return util::string_format("%s %s", instr, m_reg[m_brp]); + else + return invalid(); +} - // to register or memory from immediate - void from_i(const char *instr8, const char *instr16, const char *target) - { - if (m_w == 0 && m_wb == 1) - sprintf(m_buffer, "%s %s, %02x", instr8, target, fetch_immediate()); - else if (m_w == 1 && m_wb == 2) - sprintf(m_buffer, "%s %s, %04x", instr16, target, fetch_immediate()); - else - invalid(); - } +// jump register +std::string i8089_disassembler::inst_jr(std::string instr8, std::string instr16) +{ + uint16_t i = fetch_immediate(); + if (m_mm == 0 && m_w == 0 && m_wb == 1) + return util::string_format("%s %s, %05x", instr8, m_reg[m_brp], m_pc + (int8_t) i); + else if (m_mm == 0 && m_w == 0 && m_wb == 2) + return util::string_format("%s %s, %05x", instr16, m_reg[m_brp], m_pc + (int16_t) i); + else + return invalid(); +} - // register, immediate - void inst_ri(const char *instr8, const char *instr16) - { - if (m_mm == 0) - from_i(instr8, instr16, m_reg[m_brp]); - else - invalid(); - } +// memory immediate +std::string i8089_disassembler::inst_mi(std::string instr8, std::string instr16) +{ + std::string off = offset(); + return from_i(instr8, instr16, off); +} - // register - void inst_r(const char *instr) - { - if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s", instr, m_reg[m_brp]); - else - invalid(); - } +// register memory +std::string i8089_disassembler::inst_rm(std::string instr8, std::string instr16) +{ + std::string off = offset(); + if (m_w == 0 && m_wb == 0) + return util::string_format("%s %s, %s", instr8, m_reg[m_brp], off); + else if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s, %s", instr16, m_reg[m_brp], off); + else + return invalid(); +} - // jump register - void inst_jr(const char *instr8, const char *instr16) - { - uint16_t i = fetch_immediate(); - if (m_mm == 0 && m_w == 0 && m_wb == 1) - sprintf(m_buffer, "%s %s, %05x", instr8, m_reg[m_brp], m_ppc + m_pc + (int8_t) i); - else if (m_mm == 0 && m_w == 0 && m_wb == 2) - sprintf(m_buffer, "%s %s, %05x", instr16, m_reg[m_brp], m_ppc + m_pc + (int16_t) i); - else - invalid(); - } +// jump memory +std::string i8089_disassembler::inst_jm(std::string jump8short, std::string jump8long) +{ + std::string off = offset(); + uint16_t i = fetch_immediate(); + if (m_w == 0 && m_wb == 1 && m_brp == 0) + return util::string_format("%s %s, %05x", jump8short, off, m_pc + (int8_t) i); + else if (m_w == 0 && m_wb == 2 && m_brp == 0) + return util::string_format("%s %s, %05x", jump8long, off, m_pc + (int16_t) i); + else + return invalid(); +} - // memory immediate - void inst_mi(const char *instr8, const char *instr16) - { - offset(); - from_i(instr8, instr16, m_offset); - } +// jump memory bit +std::string i8089_disassembler::inst_jmb(std::string jump8short, std::string jump8long) +{ + std::string off = offset(); + uint16_t i = fetch_immediate(); + if (m_w == 0 && m_wb == 1) + return util::string_format("%s %s, %d, %05x", jump8short, off, m_brp, m_pc + (int8_t) i); + else if (m_w == 0 && m_wb == 2) + return util::string_format("%s %s, %d, %05x", jump8long, off, m_brp, m_pc + (int16_t) i); + else + return invalid(); +} - // register memory - void inst_rm(const char *instr8, const char *instr16) - { - offset(); - if (m_w == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr8, m_reg[m_brp], m_offset); - else if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr16, m_reg[m_brp], m_offset); - else - invalid(); - } +// memory register +std::string i8089_disassembler::inst_mr(std::string instr8, std::string instr16) +{ + std::string off = offset(); + if (m_w == 0 && m_wb == 0) + return util::string_format("%s %s, %s", instr8, off, m_reg[m_brp]); + else if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s, %s", instr16, off, m_reg[m_brp]); + else + return invalid(); +} - // jump memory - void inst_jm(const char *jump8short, const char *jump8long) - { - offset(); - uint16_t i = fetch_immediate(); - if (m_w == 0 && m_wb == 1 && m_brp == 0) - sprintf(m_buffer, "%s %s, %05x", jump8short, m_offset, m_ppc + m_pc + (int8_t) i); - else if (m_w == 0 && m_wb == 2 && m_brp == 0) - sprintf(m_buffer, "%s %s, %05x", jump8long, m_offset, m_ppc + m_pc + (int16_t) i); - else - invalid(); - } +// pointer memory +std::string i8089_disassembler::inst_pm(std::string instr16) +{ + std::string off = offset(); + if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s, %s", instr16, m_reg[m_brp], off); + else + return invalid(); +} - // jump memory bit - void inst_jmb(const char *jump8short, const char *jump8long) - { - offset(); - uint16_t i = fetch_immediate(); - if (m_w == 0 && m_wb == 1) - sprintf(m_buffer, "%s %s, %d, %05x", jump8short, m_offset, m_brp, m_ppc + m_pc + (int8_t) i); - else if (m_w == 0 && m_wb == 2) - sprintf(m_buffer, "%s %s, %d, %05x", jump8long, m_offset, m_brp, m_ppc + m_pc + (int16_t) i); - else - invalid(); - } +// memory pointer +std::string i8089_disassembler::inst_mp(std::string instr16) +{ + std::string off = offset(); + if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s, %s", instr16, off, m_reg[m_brp]); + else + return invalid(); +} - // memory register - void inst_mr(const char *instr8, const char *instr16) - { - offset(); - if (m_w == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr8, m_offset, m_reg[m_brp]); - else if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr16, m_offset, m_reg[m_brp]); - else - invalid(); - } +// jump memory +std::string i8089_disassembler::inst_j16(std::string jump8short, std::string jump16short, std::string jump8long, std::string jump16long) +{ + std::string off = offset(); + uint16_t i = fetch_immediate(); + if (m_w == 0 && m_wb == 1) + return util::string_format("%s %s, %05x", jump8short, off, m_pc + (int8_t) i); + else if (m_w == 1 && m_wb == 1) + return util::string_format("%s %s, %05x", jump16short, off, m_pc + (int8_t) i); + else if (m_w == 0 && m_wb == 2) + return util::string_format("%s %s, %05x", jump8long, off, m_pc + (int16_t) i); + else if (m_w == 1 && m_wb == 2) + return util::string_format("%s %s, %05x", jump16long, off, m_pc + (int16_t) i); + else + return invalid(); +} - // pointer memory - void inst_pm(const char *instr16) - { - offset(); - if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr16, m_reg[m_brp], m_offset); - else - invalid(); - } +// memory +std::string i8089_disassembler::inst_m(std::string instr8, std::string instr16) +{ + std::string off = offset(); + if (m_w == 0 && m_wb == 0) + return util::string_format("%s %s", instr8, off); + else if (m_w == 1 && m_wb == 0) + return util::string_format("%s %s", instr16, off); + else + return invalid(); +} - // memory pointer - void inst_mp(const char *instr16) - { - offset(); - if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s, %s", instr16, m_offset, m_reg[m_brp]); - else - invalid(); - } +// memory bit +std::string i8089_disassembler::inst_b(std::string instr) +{ + std::string off = offset(); + if (m_w == 0 && m_wb == 0) + return util::string_format("%s %s, %d", instr, off, m_brp); + else + return invalid(); +} - // jump memory - void inst_j16(const char *jump8short, const char *jump16short, const char *jump8long, const char *jump16long) - { - offset(); - uint16_t i = fetch_immediate(); - if (m_w == 0 && m_wb == 1) - sprintf(m_buffer, "%s %s, %05x", jump8short, m_offset, m_ppc + m_pc + (int8_t) i); - else if (m_w == 1 && m_wb == 1) - sprintf(m_buffer, "%s %s, %05x", jump16short, m_offset, m_ppc + m_pc + (int8_t) i); - else if (m_w == 0 && m_wb == 2) - sprintf(m_buffer, "%s %s, %05x", jump8long, m_offset, m_ppc + m_pc + (int16_t) i); - else if (m_w == 1 && m_wb == 2) - sprintf(m_buffer, "%s %s, %05x", jump16long, m_offset, m_ppc + m_pc + (int16_t) i); - else - invalid(); - } +u32 i8089_disassembler::opcode_alignment() const +{ + return 1; +} - // memory - void inst_m(const char *instr8, const char *instr16) - { - offset(); - if (m_w == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s", instr8, m_offset); - else if (m_w == 1 && m_wb == 0) - sprintf(m_buffer, "%s %s", instr16, m_offset); - else - invalid(); - } +void i8089_disassembler::load_instruction() +{ + // instruction + m_brp = (m_opcodes->r8(m_pc) >> 5) & 0x07; + m_wb = (m_opcodes->r8(m_pc) >> 3) & 0x03; + m_aa = (m_opcodes->r8(m_pc) >> 1) & 0x03; + m_w = (m_opcodes->r8(m_pc) >> 0) & 0x01; + m_opc = (m_opcodes->r8(m_pc+1) >> 2) & 0x3f; + m_mm = (m_opcodes->r8(m_pc+1) >> 0) & 0x03; + m_pc += 2; +} - // memory bit - void inst_b(const char *instr) - { - offset(); - if (m_w == 0 && m_wb == 0) - sprintf(m_buffer, "%s %s, %d", instr, m_offset, m_brp); - else - invalid(); - } +offs_t i8089_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + m_opcodes = &opcodes; + m_pc = pc; + m_flags = SUPPORTED; - // invalid instruction - void invalid() - { - sprintf(m_buffer, "???"); - } + load_instruction(); + stream << do_disassemble(); + return (m_pc - pc) | m_flags; +} - void disassemble() +std::string i8089_disassembler::do_disassemble() +{ + switch (m_opc) { - m_pc += 2; - - switch (m_opc) + case 0x00: + if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0) { - case 0x00: - if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0) + switch (m_brp) { - switch (m_brp) - { - case 0: sprintf(m_buffer, "nop"); break; - case 1: invalid(); break; - case 2: sprintf(m_buffer, "sintr"); break; - case 3: sprintf(m_buffer, "xfer"); break; - case 4: sprintf(m_buffer, "wid 8, 8"); break; - case 5: sprintf(m_buffer, "wid 8, 16"); break; - case 6: sprintf(m_buffer, "wid 16, 8"); break; - case 7: sprintf(m_buffer, "wid 16, 16"); break; - } + case 0: return util::string_format("nop"); + case 1: return invalid(); break; + case 2: return util::string_format("sintr"); + case 3: return util::string_format("xfer"); + case 4: return util::string_format("wid 8, 8"); + case 5: return util::string_format("wid 8, 16"); + case 6: return util::string_format("wid 16, 8"); + case 7: return util::string_format("wid 16, 16"); } - else - invalid(); - break; + } + else + return invalid(); + break; - case 0x02: - if (m_w == 1 && m_aa == 0 && m_wb == 2) - { - uint16_t offs = fetch_immediate(); - uint16_t segm = fetch_immediate(); - sprintf(m_buffer, "lpdi %s, %05x", m_reg[m_brp], ((segm << 4) + offs) & 0xfffff); - } - else - invalid(); - break; + case 0x02: + if (m_w == 1 && m_aa == 0 && m_wb == 2) + { + uint16_t offs = fetch_immediate(); + uint16_t segm = fetch_immediate(); + return util::string_format("lpdi %s, %05x", m_reg[m_brp], ((segm << 4) + offs) & 0xfffff); + } + else + return invalid(); - case 0x08: - if (m_mm == 0) - { - uint16_t i = fetch_immediate(); - - if (m_w == 0 && m_aa == 0 && m_wb == 1 && m_brp == TP) - sprintf(m_buffer, "jmp %05x", m_ppc + m_pc + (int8_t) i); - else if (m_w == 1 && m_aa == 0 && m_wb == 2 && m_brp == TP) - sprintf(m_buffer, "ljmp %05x", m_ppc + m_pc + (int16_t) i); - else if (m_w == 0 && m_wb == 1) - sprintf(m_buffer, "addbi %s, %02x", m_reg[m_brp], i); - else if (m_w == 1 && m_wb == 2) - sprintf(m_buffer, "addi %s, %04x", m_reg[m_brp], i); - else - invalid(); - } - else - invalid(); - break; - - case 0x09: inst_ri("orbi", "ori"); break; - case 0x0a: inst_ri("andbi", "andi"); break; - case 0x0b: inst_r("not"); break; - case 0x0c: inst_ri("movbi", "movi"); break; - case 0x0e: inst_r("inc"); break; - case 0x0f: inst_r("dec"); break; - case 0x10: inst_jr("jnz", "ljnz"); break; - case 0x11: inst_jr("jz", "ljz"); break; - - case 0x12: - if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0 && m_brp == 1) - sprintf(m_buffer, "hlt"); + case 0x08: + if (m_mm == 0) + { + uint16_t i = fetch_immediate(); + + if (m_w == 0 && m_aa == 0 && m_wb == 1 && m_brp == TP) + return util::string_format("jmp %05x", m_pc + (int8_t) i); + else if (m_w == 1 && m_aa == 0 && m_wb == 2 && m_brp == TP) + return util::string_format("ljmp %05x", m_pc + (int16_t) i); + else if (m_w == 0 && m_wb == 1) + return util::string_format("addbi %s, %02x", m_reg[m_brp], i); + else if (m_w == 1 && m_wb == 2) + return util::string_format("addi %s, %04x", m_reg[m_brp], i); else - invalid(); - break; + return invalid(); + } + else + return invalid(); + + case 0x09: return inst_ri("orbi", "ori"); + case 0x0a: return inst_ri("andbi", "andi"); + case 0x0b: return inst_r("not"); + case 0x0c: return inst_ri("movbi", "movi"); + case 0x0e: return inst_r("inc"); + case 0x0f: return inst_r("dec"); + case 0x10: return inst_jr("jnz", "ljnz"); + case 0x11: return inst_jr("jz", "ljz"); + + case 0x12: + if (m_mm == 0 && m_w == 0 && m_aa == 0 && m_wb == 0 && m_brp == 1) + return util::string_format("hlt"); + else + return invalid(); - case 0x13: inst_mi("movbi", "movi"); break; - case 0x20: inst_rm("movb", "mov"); break; - case 0x21: inst_mr("movb", "mov"); break; - case 0x22: inst_pm("lpd"); break; - case 0x23: inst_pm("movp"); break; + case 0x13: return inst_mi("movbi", "movi"); + case 0x20: return inst_rm("movb", "mov"); + case 0x21: return inst_mr("movb", "mov"); + case 0x22: return inst_pm("lpd"); + case 0x23: return inst_pm("movp"); - case 0x24: - if (m_wb == 0) - { - offset(); + case 0x24: + if (m_wb == 0) + { + std::string off = offset(); - auto tmp = new i8089_instruction(m_pc, m_oprom + m_pc); - m_pc += tmp->length(); - std::string sub = tmp->buffer(); + load_instruction(); - if (m_w == 0) - sprintf(m_buffer, "movb %s, %s", sub.c_str(), m_offset); - else - sprintf(m_buffer, "mov %s, %s", sub.c_str(), m_offset); + if (m_opc != 0x33) + return invalid(); + std::string off2 = offset(); - delete(tmp); - } + if (m_w == 0) + return util::string_format("movb %s, %s", off2, off); else - invalid(); - break; + return util::string_format("mov %s, %s", off2, off); + } + else + return invalid(); - case 0x25: - if (m_w == 0 && m_wb == 3 && m_brp == 0) - { - offset(); - uint16_t i = fetch_immediate(); - int displacement = (int8_t) fetch_immediate(); - sprintf(m_buffer, "tsl %s, %02x, %05x", m_offset, i, m_ppc + m_pc + displacement); - } - else - invalid(); - break; + case 0x25: + if (m_w == 0 && m_wb == 3 && m_brp == 0) + { + std::string off = offset(); + uint16_t i = fetch_immediate(); + int displacement = (int8_t) fetch_immediate(); + return util::string_format("tsl %s, %02x, %05x", off, i, m_pc + displacement); + } + else + return invalid(); - case 0x26: inst_mp("movp"); break; + case 0x26: return inst_mp("movp"); - case 0x27: - if (m_w == 1 && m_brp == TP && (m_wb == 1 || m_wb == 2)) - { - offset(); - uint16_t i = fetch_immediate(); + case 0x27: + if (m_w == 1 && m_brp == TP && (m_wb == 1 || m_wb == 2)) + { + std::string off = offset(); + uint16_t i = fetch_immediate(); - if (m_wb == 1) - sprintf(m_buffer, "call %s, %05x", m_offset, m_ppc + m_pc + (int8_t) i); - else if (m_wb == 2) - sprintf(m_buffer, "lcall %s, %05x", m_offset, m_ppc + m_pc + (int16_t) i); + m_flags |= STEP_OVER; - m_flags |= DASMFLAG_STEP_OVER; - } - else - invalid(); - break; - - case 0x28: inst_rm("addb", "add"); break; - case 0x29: inst_rm("orb", "or"); break; - case 0x2a: inst_rm("andb", "and"); break; - case 0x2b: inst_rm("notb", "not"); break; - case 0x2c: inst_jm("jmce", "ljmce"); break; - case 0x2d: inst_jm("jmcne", "ljmcne"); break; - case 0x2e: inst_jmb("jnbt", "ljnbt"); break; - case 0x2f: inst_jmb("jbt", "ljbt"); break; - case 0x30: inst_mi("addbi", "addi"); break; - case 0x31: inst_mi("orbi", "ori"); break; - case 0x32: inst_mi("andbi", "andi"); break; - - case 0x33: - offset(); - sprintf(m_buffer, "%s", m_offset); - break; - - case 0x34: inst_mr("addb", "add"); break; - case 0x35: inst_mr("orb", "or"); break; - case 0x36: inst_mr("andb", "and"); break; - case 0x37: inst_mr("notb", "not"); break; - case 0x38: inst_j16("jnzb", "jnz", "ljnzb", "ljnz"); break; - case 0x39: inst_j16("jzb", "jz", "ljzb", "ljz"); break; - case 0x3a: inst_m("incb", "inc"); break; - case 0x3b: inst_m("decb", "dec"); break; - case 0x3d: inst_b("setb"); break; - case 0x3e: inst_b("clr"); break; - - default: - invalid(); + if (m_wb == 1) + return util::string_format("call %s, %05x", off, m_pc + (int8_t) i); + else if (m_wb == 2) + return util::string_format("lcall %s, %05x", off, m_pc + (int16_t) i); } + else + return invalid(); + + case 0x28: return inst_rm("addb", "add"); + case 0x29: return inst_rm("orb", "or"); + case 0x2a: return inst_rm("andb", "and"); + case 0x2b: return inst_rm("notb", "not"); + case 0x2c: return inst_jm("jmce", "ljmce"); + case 0x2d: return inst_jm("jmcne", "ljmcne"); + case 0x2e: return inst_jmb("jnbt", "ljnbt"); + case 0x2f: return inst_jmb("jbt", "ljbt"); + case 0x30: return inst_mi("addbi", "addi"); + case 0x31: return inst_mi("orbi", "ori"); + case 0x32: return inst_mi("andbi", "andi"); + + case 0x34: return inst_mr("addb", "add"); + case 0x35: return inst_mr("orb", "or"); + case 0x36: return inst_mr("andb", "and"); + case 0x37: return inst_mr("notb", "not"); + case 0x38: return inst_j16("jnzb", "jnz", "ljnzb", "ljnz"); + case 0x39: return inst_j16("jzb", "jz", "ljzb", "ljz"); + case 0x3a: return inst_m("incb", "inc"); + case 0x3b: return inst_m("decb", "dec"); + case 0x3d: return inst_b("setb"); + case 0x3e: return inst_b("clr"); } -}; -const char *i8089_instruction::m_reg[] = -{ - "ga", "gb", "gc", "bc", "tp", "ix", "cc", "mc" -}; - -CPU_DISASSEMBLE(i8089) -{ - std::unique_ptr<i8089_instruction> i = std::make_unique<i8089_instruction>(pc, oprom); - stream << i->buffer(); - offs_t result = i->length() | i->flags(); - return result; + return invalid(); } diff --git a/src/devices/cpu/i8089/i8089_dasm.h b/src/devices/cpu/i8089/i8089_dasm.h new file mode 100644 index 00000000000..cf59d4b483c --- /dev/null +++ b/src/devices/cpu/i8089/i8089_dasm.h @@ -0,0 +1,71 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + Intel 8089 I/O Processor + + Disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_I8089_I8089DASM_H +#define MAME_CPU_I8089_I8089DASM_H + +#pragma once + +class i8089_disassembler : public util::disasm_interface +{ +public: + i8089_disassembler() = default; + virtual ~i8089_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // register index + enum + { + GA, // 20-bit general purpose address a + GB, // 20-bit general purpose address b + GC, // 20-bit general purpose address c + BC, // byte count + TP, // 20-bit task pointer + IX, // index + CC, // mask compare + MC // channel control + }; + + static const char *const m_reg[]; + + uint8_t m_brp, m_wb, m_aa, m_w, m_opc, m_mm; + offs_t m_pc, m_flags; + + const data_buffer *m_opcodes; + + uint8_t fetch_value8(); + uint16_t fetch_value16(); + uint16_t fetch_immediate(); + std::string offset(); + std::string invalid(); + + std::string from_i(std::string instr8, std::string instr16, std::string target); + std::string inst_ri(std::string instr8, std::string instr16); + std::string inst_r(std::string instr); + std::string inst_jr(std::string instr8, std::string instr16); + std::string inst_mi(std::string instr8, std::string instr16); + std::string inst_rm(std::string instr8, std::string instr16); + std::string inst_jm(std::string jump8short, std::string jump8long); + std::string inst_jmb(std::string jump8short, std::string jump8long); + std::string inst_mr(std::string instr8, std::string instr16); + std::string inst_pm(std::string instr16); + std::string inst_mp(std::string instr16); + std::string inst_j16(std::string jump8short, std::string jump16short, std::string jump8long, std::string jump16long); + std::string inst_m(std::string instr8, std::string instr16); + std::string inst_b(std::string instr); + + std::string do_disassemble(); + void load_instruction(); +}; + +#endif diff --git a/src/devices/cpu/i86/i86.cpp b/src/devices/cpu/i86/i86.cpp index 4c4cd49d6ae..9ecd0ddc99f 100644 --- a/src/devices/cpu/i86/i86.cpp +++ b/src/devices/cpu/i86/i86.cpp @@ -417,8 +417,8 @@ void i8086_common_cpu_device::device_start() m_stack = m_program; m_code = m_program; m_extra = m_program; - m_direct = &m_program->direct(); - m_direct_opcodes = &m_opcodes->direct(); + m_direct = m_program->direct<0>(); + m_direct_opcodes = m_opcodes->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_regs.w)); @@ -570,9 +570,14 @@ void i8086_common_cpu_device::execute_set_input( int inptnum, int state ) } } -offs_t i8086_common_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8086_common_cpu_device::create_disassembler() { - return i386_dasm_one(stream, pc, oprom, 1); + return new i386_disassembler(this); +} + +int i8086_common_cpu_device::get_mode() const +{ + return 1; } uint8_t i8086_common_cpu_device::read_port_byte(uint16_t port) diff --git a/src/devices/cpu/i86/i86.h b/src/devices/cpu/i86/i86.h index f6e177c25d9..f1dc8bc329d 100644 --- a/src/devices/cpu/i86/i86.h +++ b/src/devices/cpu/i86/i86.h @@ -5,6 +5,7 @@ #pragma once +#include <cpu/i386/i386dasm.h> ///////////////////////////////////////////////////////////////// @@ -39,7 +40,7 @@ enum }; -class i8086_common_cpu_device : public cpu_device +class i8086_common_cpu_device : public cpu_device, public i386_disassembler::config { public: template <class Object> static devcb_base &set_lock_handler(device_t &device, Object &&cb) @@ -134,9 +135,8 @@ protected: virtual void execute_set_input(int inputnum, int state) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual int get_mode() const override; // device_state_interface overrides virtual void state_import(const device_state_entry &entry) override; @@ -314,7 +314,7 @@ protected: uint8_t m_test_state; address_space *m_program, *m_opcodes, *m_stack, *m_code, *m_extra; - direct_read_data *m_direct, *m_direct_opcodes; + direct_read_data<0> *m_direct, *m_direct_opcodes; address_space *m_io; offs_t m_fetch_xor; int m_icount; diff --git a/src/devices/cpu/i860/i860.cpp b/src/devices/cpu/i860/i860.cpp index eb22a347f2a..a9d8a3c78b9 100644 --- a/src/devices/cpu/i860/i860.cpp +++ b/src/devices/cpu/i860/i860.cpp @@ -18,6 +18,7 @@ TODO: Separate out i860XR and i860XP (make different types, etc). #include "emu.h" #include "debugger.h" #include "i860.h" +#include "i860dis.h" /* Control register numbers. */ @@ -231,11 +232,9 @@ void i860_cpu_device::device_reset() reset_i860(); } - -offs_t i860_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i860_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( i860 ); - return CPU_DISASSEMBLE_NAME(i860)(this, stream, pc, oprom, opram, options); + return new i860_disassembler; } diff --git a/src/devices/cpu/i860/i860.h b/src/devices/cpu/i860/i860.h index 3387244858e..05e81407e7c 100644 --- a/src/devices/cpu/i860/i860.h +++ b/src/devices/cpu/i860/i860.h @@ -80,9 +80,7 @@ protected: virtual void state_import(const device_state_entry &entry) 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/i860/i860dasm.cpp b/src/devices/cpu/i860/i860dasm.cpp deleted file mode 100644 index 03d24e2d2a8..00000000000 --- a/src/devices/cpu/i860/i860dasm.cpp +++ /dev/null @@ -1,378 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Jason Eckhardt -#include "i860.h" - -/* Sub-group decoders */ -static void i860_dasm_core_dasm(const uint32_t op, char* buffer); -static void i860_dasm_floating_point_dasm(const uint32_t op, char* buffer); -static void i860_dasm_CTRL_dasm(const uint32_t op, char* buffer); - -/* REG-Format Opcodes*/ -static void i860_dasm_ldx(const uint32_t op, char* buffer); -static void i860_dasm_stx(const uint32_t op, char* buffer); -static void i860_dasm_ixfr(const uint32_t op, char* buffer); -static void i860_dasm_fid_fst(const uint32_t op, char* buffer); -static void i860_dasm_flush(const uint32_t op, char* buffer); -static void i860_dasm_pstd(const uint32_t op, char* buffer); -static void i860_dasm_ldc_sdc(const uint32_t op, char* buffer); -static void i860_dasm_bri(const uint32_t op, char* buffer); -static void i860_dasm_trap(const uint32_t op, char* buffer); -static void i860_dasm_bte_btne(const uint32_t op, char* buffer); -static void i860_dasm_pfidy(const uint32_t op, char* buffer); -static void i860_dasm_addu_subu(const uint32_t op, char* buffer); -static void i860_dasm_shl_shr(const uint32_t op, char* buffer); -static void i860_dasm_shrd(const uint32_t op, char* buffer); -static void i860_dasm_bla(const uint32_t op, char* buffer); -static void i860_dasm_shra(const uint32_t op, char* buffer); -static void i860_dasm_and_andh(const uint32_t op, char* buffer); -static void i860_dasm_andnot_andnoth(const uint32_t op, char* buffer); -static void i860_dasm_or_orh(const uint32_t op, char* buffer); -static void i860_dasm_xor_xorh(const uint32_t op, char* buffer); - -/* CORE Escape Opcodes */ -static void i860_dasm_CORE_lock(const uint32_t op, char* buffer); -static void i860_dasm_CORE_calli(const uint32_t op, char* buffer); -static void i860_dasm_CORE_intovr(const uint32_t op, char* buffer); -static void i860_dasm_CORE_unlock(const uint32_t op, char* buffer); - -/* CTRL-Format Opcodes */ -static void i860_dasm_CTRL_br(const uint32_t op, char* buffer); -static void i860_dasm_CTRL_call(const uint32_t op, char* buffer); -static void i860_dasm_CTRL_bc_bct(const uint32_t op, char* buffer); -static void i860_dasm_CTRL_bnc_bnct(const uint32_t op, char* buffer); - -/* Floating-Point Instructions */ - - -CPU_DISASSEMBLE( i860 ) -{ - char tempB[1024] = ""; - - /* Little Endian */ - const uint32_t op = (oprom[3] << 24) | (oprom[2] << 16) | (oprom[1] << 8) | (oprom[0] << 0); - //const uint32_t op = (oprom[2] << 24) | (oprom[3] << 16) | (oprom[0] << 8) | (oprom[1] << 0); /* Mixed Endian */ - //const uint32_t op = (oprom[0] << 24) | (oprom[1] << 16) | (oprom[2] << 8) | (oprom[3] << 0); /* Big Endian */ - //const uint32_t op = (oprom[1] << 24) | (oprom[0] << 16) | (oprom[3] << 8) | (oprom[2] << 0); /* Mixed Endian */ - - /* The opcode is the top 6 bits */ - uint8_t opcode = (op >> 26) & 0x3f; - - /* DEBUG - print this out if you feel things are going a bit wonky */ - // sprintf(buffer, "%08x : oo %02x", op, opcode); - - /* Main decode */ - switch (opcode) - { - case 0x00: - case 0x01: - case 0x04: - case 0x05: i860_dasm_ldx(op, tempB); break; - - case 0x03: - case 0x07: i860_dasm_stx(op, tempB); break; - - case 0x02: i860_dasm_ixfr(op, tempB); break; - - case 0x06: sprintf(tempB, "(reserved)"); break; - - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: i860_dasm_fid_fst(op, tempB); break; - - case 0x0d: i860_dasm_flush(op, tempB); break; - - case 0x0f: i860_dasm_pstd(op, tempB); break; - - case 0x0c: - case 0x0e: i860_dasm_ldc_sdc(op, tempB); break; - - case 0x10: i860_dasm_bri(op, tempB); break; - - case 0x11: i860_dasm_trap(op, tempB); break; - - case 0x12: i860_dasm_floating_point_dasm(op, tempB); break; /* Floating point operation sub-group */ - - case 0x13: i860_dasm_core_dasm(op, tempB); break; /* Core operation sub-group */ - - case 0x14: - case 0x15: - case 0x16: - case 0x17: i860_dasm_bte_btne(op, tempB); break; - - case 0x18: - case 0x19: i860_dasm_pfidy(op, tempB); break; - - case 0x1a: - case 0x1b: - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f: i860_dasm_CTRL_dasm(op, tempB); break; /* CTRL operation sub-group */ - - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x26: - case 0x27: i860_dasm_addu_subu(op, tempB); break; - - case 0x28: - case 0x29: - case 0x2a: - case 0x2b: i860_dasm_shl_shr(op, tempB); break; - - case 0x2c: i860_dasm_shrd(op, tempB); break; - - case 0x2d: i860_dasm_bla(op, tempB); break; - - case 0x2e: - case 0x2f: i860_dasm_shra(op, tempB); break; - - case 0x30: - case 0x31: - case 0x32: - case 0x33: i860_dasm_and_andh(op, tempB); break; - - case 0x34: - case 0x35: - case 0x36: - case 0x37: i860_dasm_andnot_andnoth(op, tempB); break; - - case 0x38: - case 0x39: - case 0x3a: - case 0x3b: i860_dasm_or_orh(op, tempB); break; - - case 0x3c: - case 0x3d: - case 0x3e: - case 0x3f: i860_dasm_xor_xorh(op, tempB); break; - - default: sprintf(tempB, "(reserved)"); break; - } - - /* More Debug */ - //strcat(buffer, " : "); - //strcat(buffer, tempB); - sprintf(buffer, "%s", tempB); - - /* All opcodes are 32 bits */ - return (4 | DASMFLAG_SUPPORTED); -} - - -// BIT HELPER -// 31 27 23 19 15 11 7 3 -// 0000 0011 1111 1111 0000 0111 1110 0000 - - -/**********************/ -/* Sub-group decoders */ -/**********************/ -static void i860_dasm_core_dasm(const uint32_t op, char* buffer) -{ - //uint8_t src1 = (op >> 11) & 0x0000001f; - - /* Reserved bits must be set to 0 */ - if ( (op & 0x000007e0) || (op & 0x03ff0000) ) - { - //logerror("[i860] Reserved CORE bits must be set to 0."); - printf("CORE baddie\n"); - } - - switch(op & 0x0000001f) - { - case 0x01: i860_dasm_CORE_lock(op, buffer); break; - case 0x02: i860_dasm_CORE_calli(op, buffer); break; - case 0x04: i860_dasm_CORE_intovr(op, buffer); break; - case 0x07: i860_dasm_CORE_unlock(op, buffer); break; - - default: sprintf(buffer, "(reserved)"); break; - } -} - -static void i860_dasm_floating_point_dasm(const uint32_t op, char* buffer) -{ - sprintf(buffer, "[[F-P unit]]"); -} - -static void i860_dasm_CTRL_dasm(const uint32_t op, char* buffer) -{ - uint8_t opc = (op >> 26) & 0x07; - - switch(opc) - { - case 0x02: i860_dasm_CTRL_br(op, buffer); break; - case 0x03: i860_dasm_CTRL_call(op, buffer); break; - case 0x04: case 0x05: i860_dasm_CTRL_bc_bct(op, buffer); break; - case 0x06: case 0x07: i860_dasm_CTRL_bnc_bnct(op, buffer); break; - - default: sprintf(buffer, "(reserved)"); break; - } -} - - -/*********************/ -/* REG-Format Opcodes*/ -/*********************/ -static void i860_dasm_ldx(const uint32_t op, char* buffer) -{ - sprintf(buffer, "ldx"); -} - -static void i860_dasm_stx(const uint32_t op, char* buffer) -{ - sprintf(buffer, "stx"); -} - -static void i860_dasm_ixfr(const uint32_t op, char* buffer) -{ -// uint16_t val = op & 0x7ff; -// uint8_t opc = (op >> 26) & 0x3f; -// uint8_t src2 = (op >> 21) & 0x1f; -// uint8_t dest = (op >> 16) & 0x1f; -// uint8_t src1 = (op >> 11) & 0x1f; - - sprintf(buffer, "ixfr"); -} - -static void i860_dasm_fid_fst(const uint32_t op, char* buffer) -{ - sprintf(buffer, "fst"); -} - -static void i860_dasm_flush(const uint32_t op, char* buffer) -{ - sprintf(buffer, "flush"); -} - -static void i860_dasm_pstd(const uint32_t op, char* buffer) -{ - sprintf(buffer, "pstd"); -} - -static void i860_dasm_ldc_sdc(const uint32_t op, char* buffer) -{ - sprintf(buffer, "ldc, sdc"); -} - -static void i860_dasm_bri(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bri"); -} - -static void i860_dasm_trap(const uint32_t op, char* buffer) -{ - sprintf(buffer, "trap"); -} - -static void i860_dasm_bte_btne(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bte, btne"); -} - -static void i860_dasm_pfidy(const uint32_t op, char* buffer) -{ - sprintf(buffer, "pfidy"); -} - -static void i860_dasm_addu_subu(const uint32_t op, char* buffer) -{ - sprintf(buffer, "addu, subu"); -} - -static void i860_dasm_shl_shr(const uint32_t op, char* buffer) -{ - sprintf(buffer, "shl, shr"); -} - -static void i860_dasm_shrd(const uint32_t op, char* buffer) -{ - sprintf(buffer, "shrd"); -} - -static void i860_dasm_bla(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bla"); -} - -static void i860_dasm_shra(const uint32_t op, char* buffer) -{ - sprintf(buffer, "shra"); -} - -static void i860_dasm_and_andh(const uint32_t op, char* buffer) -{ - sprintf(buffer, "and, andh"); -} - -static void i860_dasm_andnot_andnoth(const uint32_t op, char* buffer) -{ - sprintf(buffer, "andnot, andnoth"); -} - -static void i860_dasm_or_orh(const uint32_t op, char* buffer) -{ - sprintf(buffer, "or, orh"); -} - -static void i860_dasm_xor_xorh(const uint32_t op, char* buffer) -{ - sprintf(buffer, "xor, xorh"); -} - - -/***********************/ -/* CORE Escape Opcodes */ -/***********************/ -static void i860_dasm_CORE_lock(const uint32_t op, char* buffer) -{ - sprintf(buffer, "lock"); -} - -static void i860_dasm_CORE_calli(const uint32_t op, char* buffer) -{ - sprintf(buffer, "calli"); -} - -static void i860_dasm_CORE_intovr(const uint32_t op, char* buffer) -{ - sprintf(buffer, "intovr"); -} - -static void i860_dasm_CORE_unlock(const uint32_t op, char* buffer) -{ - sprintf(buffer, "unlock"); -} - - -/***********************/ -/* CTRL-Format Opcodes */ -/***********************/ -static void i860_dasm_CTRL_br(const uint32_t op, char* buffer) -{ - sprintf(buffer, "br"); -} - -static void i860_dasm_CTRL_call(const uint32_t op, char* buffer) -{ - sprintf(buffer, "call"); -} - -static void i860_dasm_CTRL_bc_bct(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bct"); -} - -static void i860_dasm_CTRL_bnc_bnct(const uint32_t op, char* buffer) -{ - sprintf(buffer, "bnct"); -} - - -/*******************************/ -/* Floating-Point Instructions */ -/*******************************/ diff --git a/src/devices/cpu/i860/i860dis.cpp b/src/devices/cpu/i860/i860dis.cpp index a1230d570cc..5f9d08da411 100644 --- a/src/devices/cpu/i860/i860dis.cpp +++ b/src/devices/cpu/i860/i860dis.cpp @@ -11,7 +11,7 @@ ***************************************************************************/ #include "emu.h" -#include "i860.h" +#include "i860dis.h" /* Macros for accessing register fields in instruction word. */ #define get_isrc1(bits) (((bits) >> 11) & 0x1f) @@ -28,12 +28,12 @@ /* Control register names. */ -static const char *const cr2str[] = +const char *const i860_disassembler::cr2str[] = {"fir", "psr", "dirbase", "db", "fsr", "epsr", "!", "!"}; /* Sign extend N-bit number. */ -static int32_t sign_ext(uint32_t x, int n) +int32_t i860_disassembler::sign_ext(uint32_t x, int n) { int32_t t; t = x >> (n - 1); @@ -44,7 +44,7 @@ static int32_t sign_ext(uint32_t x, int n) /* Basic integer 3-address register format: * mnemonic %rs1,%rs2,%rd */ -static void int_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { /* Possibly prefix shrd with 'd.' */ if (((insn & 0xfc000000) == 0xb0000000) && (insn & 0x200)) @@ -58,7 +58,7 @@ static void int_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Basic integer 3-address imm16 format: * mnemonic #imm16,%rs2,%rd */ -static void int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { /* Sign extend the 16-bit immediate. Print as hex for the bitwise operations. */ @@ -73,21 +73,21 @@ static void int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Integer (mixed) 2-address isrc1ni,fdest. */ -static void int_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s\t%%r%d,%%f%d", mnemonic, get_isrc1 (insn), get_fdest (insn)); } /* Integer (mixed) 2-address csrc2,idest. */ -static void int_cd(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_cd(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s\t%%%s,%%r%d", mnemonic, cr2str[get_creg (insn)], get_idest (insn)); } /* Integer (mixed) 2-address isrc1,csrc2. */ -static void int_1c(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_1c(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s\t%%r%d,%%%s", mnemonic, get_isrc1(insn), cr2str[get_creg (insn)]); } @@ -95,7 +95,7 @@ static void int_1c(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t i /* Integer 1-address register format: * mnemonic %rs1 */ -static void int_1(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_1(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s\t%%r%d", mnemonic, get_isrc1 (insn)); } @@ -103,7 +103,7 @@ static void int_1(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t in /* Integer no-address register format: * mnemonic */ -static void int_0(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_0(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { util::stream_format(stream, "%s", mnemonic); } @@ -111,7 +111,7 @@ static void int_0(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t in /* Basic floating-point 3-address register format: * mnemonic %fs1,%fs2,%fd */ -static void flop_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::flop_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { char newname[256]; const char *const suffix[4] = { "ss", "sd", "ds", "dd" }; @@ -165,7 +165,7 @@ static void flop_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Floating-point 2-address register format: * mnemonic %fs1,%fd */ -static void flop_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::flop_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { const char *const suffix[4] = { "ss", "sd", "ds", "dd" }; const char *prefix_d, *prefix_p; @@ -179,7 +179,7 @@ static void flop_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Floating-point 2-address register format: * mnemonic %fs2,%fd */ -static void flop_2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::flop_2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { const char *const suffix[4] = { "ss", "sd", "ds", "dd" }; const char *prefix_d; @@ -192,7 +192,7 @@ static void flop_2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Floating-point (mixed) 2-address register format: * fxfr fsrc1,idest. */ -static void flop_fxfr(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::flop_fxfr(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { const char *prefix_d = (insn & 0x200) ? "d." : ""; util::stream_format(stream, "%s%s\t%%f%d,%%r%d", prefix_d, mnemonic, get_fsrc1 (insn), @@ -202,7 +202,7 @@ static void flop_fxfr(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_ /* Branch with reg,reg,sbroff format: * mnemonic %rs1,%rs2,sbroff */ -static void int_12S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_12S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { int32_t sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16); int32_t rel = (int32_t)pc + (sbroff << 2) + 4; @@ -214,7 +214,7 @@ static void int_12S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Branch with #const5,reg,sbroff format: * mnemonic #const5,%rs2,sbroff */ -static void int_i2S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_i2S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { int32_t sbroff = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16); int32_t rel = (int32_t)pc + (sbroff << 2) + 4; @@ -226,7 +226,7 @@ static void int_i2S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Branch with lbroff format: * mnemonic lbroff */ -static void int_L(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_L(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { int32_t lbroff = sign_ext ((insn & 0x03ffffff), 26); int32_t rel = (int32_t)pc + (lbroff << 2) + 4; @@ -238,7 +238,7 @@ static void int_L(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t in /* Integer load. * ld.{b,s,l} isrc1(isrc2),idest * ld.{b,s,l} #const(isrc2),idest */ -static void int_ldx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_ldx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { /* Operand size, in bytes. */ int sizes[4] = { 1, 1, 2, 4 }; @@ -265,7 +265,7 @@ static void int_ldx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t /* Integer store: st.b isrc1ni,#const(isrc2) */ -static void int_stx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_stx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { /* Operand size, in bytes. */ int sizes[4] = { 1, 1, 2, 4 }; @@ -291,7 +291,7 @@ static void int_stx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t * "fst.y fdest,isrc1(isrc2)", "fst.y fdest,isrc1(isrc2)++", * "fst.y fdest,#const(isrc2)" or "fst.y fdest,#const(isrc2)++" * Where y = {l,d,q}. Note, there is no pfld.q, though. */ -static void int_fldst(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_fldst(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { int32_t immsrc1 = sign_ext (get_imm16 (insn), 16); /* Operand size, in bytes. */ @@ -353,7 +353,7 @@ static void int_fldst(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_ /* flush #const(isrc2)[++]. */ -static void int_flush(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) +void i860_disassembler::int_flush(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn) { const char *const auto_suff[2] = { "", "++" }; int32_t immsrc = sign_ext (get_imm16 (insn), 16); @@ -363,257 +363,234 @@ static void int_flush(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_ } -/* Flags for the decode table. */ -enum -{ - DEC_MORE = 1, /* More decoding necessary. */ - DEC_DECODED = 2 /* Fully decoded, go. */ -}; - - -struct decode_tbl_t -{ - /* Disassembly function for this opcode. - Call with buffer, mnemonic, pc, insn. */ - void (*insn_dis)(std::ostream &, char *, uint32_t, uint32_t); - - /* Flags for this opcode. */ - char flags; - - /* Mnemonic of this opcode (sometimes partial when more decode is - done in disassembly routines-- e.g., loads and stores). */ - const char *mnemonic; -}; - - /* First-level decode table (i.e., for the 6 primary opcode bits). */ -static const decode_tbl_t decode_tbl[64] = +const i860_disassembler::decode_tbl_t i860_disassembler::decode_tbl[64] = { /* A slight bit of decoding for loads and stores is done in the execution routines (operand size and addressing mode), which is why their respective entries are identical. */ - { int_ldx, DEC_DECODED, "ld." }, /* ld.b isrc1(isrc2),idest. */ - { int_ldx, DEC_DECODED, "ld." }, /* ld.b #const(isrc2),idest. */ - { int_1d, DEC_DECODED, "ixfr" }, /* ixfr isrc1ni,fdest. */ - { int_stx, DEC_DECODED, "st." }, /* st.b isrc1ni,#const(isrc2). */ - { int_ldx, DEC_DECODED, "ld." }, /* ld.{s,l} isrc1(isrc2),idest. */ - { int_ldx, DEC_DECODED, "ld." }, /* ld.{s,l} #const(isrc2),idest. */ - { nullptr, 0 , nullptr }, - { int_stx, DEC_DECODED, "st." }, /* st.{s,l} isrc1ni,#const(isrc2),idest.*/ - { int_fldst, DEC_DECODED, "fld." }, /* fld.{l,d,q} isrc1(isrc2)[++],fdest. */ - { int_fldst, DEC_DECODED, "fld." }, /* fld.{l,d,q} #const(isrc2)[++],fdest. */ - { int_fldst, DEC_DECODED, "fst." }, /* fst.{l,d,q} fdest,isrc1(isrc2)[++] */ - { int_fldst, DEC_DECODED, "fst." }, /* fst.{l,d,q} fdest,#const(isrc2)[++] */ - { int_cd, DEC_DECODED, "ld.c" }, /* ld.c csrc2,idest. */ - { int_flush, DEC_DECODED, "flush" }, /* flush #const(isrc2) (or autoinc). */ - { int_1c, DEC_DECODED, "st.c" }, /* st.c isrc1,csrc2. */ - { int_fldst, DEC_DECODED, "pstd." }, /* pst.d fdest,#const(isrc2)[++]. */ - { int_1, DEC_DECODED, "bri" }, /* bri isrc1ni. */ - { int_12d, DEC_DECODED, "trap" }, /* trap isrc1ni,isrc2,idest. */ - { nullptr, DEC_MORE, nullptr }, /* FP ESCAPE FORMAT, more decode. */ - { nullptr, DEC_MORE, nullptr }, /* CORE ESCAPE FORMAT, more decode. */ - { int_12S, DEC_DECODED, "btne" }, /* btne isrc1,isrc2,sbroff. */ - { int_i2S, DEC_DECODED, "btne" }, /* btne #const,isrc2,sbroff. */ - { int_12S, DEC_DECODED, "bte" }, /* bte isrc1,isrc2,sbroff. */ - { int_i2S, DEC_DECODED, "bte" }, /* bte #const5,isrc2,idest. */ - { int_fldst, DEC_DECODED, "pfld." }, /* pfld.{l,d,q} isrc1(isrc2)[++],fdest. */ - { int_fldst, DEC_DECODED, "pfld." }, /* pfld.{l,d,q} #const(isrc2)[++],fdest.*/ - { int_L, DEC_DECODED, "br" }, /* br lbroff. */ - { int_L, DEC_DECODED, "call" }, /* call lbroff . */ - { int_L, DEC_DECODED, "bc" }, /* bc lbroff. */ - { int_L, DEC_DECODED, "bc.t" }, /* bc.t lbroff. */ - { int_L, DEC_DECODED, "bnc" }, /* bnc lbroff. */ - { int_L, DEC_DECODED, "bnc.t" }, /* bnc.t lbroff. */ - { int_12d, DEC_DECODED, "addu" }, /* addu isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "addu" }, /* addu #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "subu" }, /* subu isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "subu" }, /* subu #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "adds" }, /* adds isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "adds" }, /* adds #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "subs" }, /* subs isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "subs" }, /* subs #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "shl" }, /* shl isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "shl" }, /* shl #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "shr" }, /* shr isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "shr" }, /* shr #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "shrd" }, /* shrd isrc1ni,isrc2,idest. */ - { int_12S, DEC_DECODED, "bla" }, /* bla isrc1ni,isrc2,sbroff. */ - { int_12d, DEC_DECODED, "shra" }, /* shra isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "shra" }, /* shra #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "and" }, /* and isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "and" }, /* and #const,isrc2,idest. */ - { nullptr, 0 , nullptr }, - { int_i2d, DEC_DECODED, "andh" }, /* andh #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "andnot" }, /* andnot isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "andnot" }, /* andnot #const,isrc2,idest. */ - { nullptr, 0 , nullptr }, - { int_i2d, DEC_DECODED, "andnoth" }, /* andnoth #const,isrc2,idest.*/ - { int_12d, DEC_DECODED, "or" }, /* or isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "or" }, /* or #const,isrc2,idest. */ - { nullptr, 0 , nullptr }, - { int_i2d, DEC_DECODED, "orh" }, /* orh #const,isrc2,idest. */ - { int_12d, DEC_DECODED, "xor" }, /* xor isrc1,isrc2,idest. */ - { int_i2d, DEC_DECODED, "xor" }, /* xor #const,isrc2,idest. */ - { nullptr, 0 , nullptr }, - { int_i2d, DEC_DECODED, "xorh" }, /* xorh #const,isrc2,idest. */ + { &i860_disassembler::int_ldx, DEC_DECODED, "ld." }, /* ld.b isrc1(isrc2),idest. */ + { &i860_disassembler::int_ldx, DEC_DECODED, "ld." }, /* ld.b #const(isrc2),idest. */ + { &i860_disassembler::int_1d, DEC_DECODED, "ixfr" }, /* ixfr isrc1ni,fdest. */ + { &i860_disassembler::int_stx, DEC_DECODED, "st." }, /* st.b isrc1ni,#const(isrc2). */ + { &i860_disassembler::int_ldx, DEC_DECODED, "ld." }, /* ld.{s,l} isrc1(isrc2),idest. */ + { &i860_disassembler::int_ldx, DEC_DECODED, "ld." }, /* ld.{s,l} #const(isrc2),idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_stx, DEC_DECODED, "st." }, /* st.{s,l} isrc1ni,#const(isrc2),idest.*/ + { &i860_disassembler::int_fldst, DEC_DECODED, "fld." }, /* fld.{l,d,q} isrc1(isrc2)[++],fdest. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "fld." }, /* fld.{l,d,q} #const(isrc2)[++],fdest. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "fst." }, /* fst.{l,d,q} fdest,isrc1(isrc2)[++] */ + { &i860_disassembler::int_fldst, DEC_DECODED, "fst." }, /* fst.{l,d,q} fdest,#const(isrc2)[++] */ + { &i860_disassembler::int_cd, DEC_DECODED, "ld.c" }, /* ld.c csrc2,idest. */ + { &i860_disassembler::int_flush, DEC_DECODED, "flush" }, /* flush #const(isrc2) (or autoinc). */ + { &i860_disassembler::int_1c, DEC_DECODED, "st.c" }, /* st.c isrc1,csrc2. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "pstd." }, /* pst.d fdest,#const(isrc2)[++]. */ + { &i860_disassembler::int_1, DEC_DECODED, "bri" }, /* bri isrc1ni. */ + { &i860_disassembler::int_12d, DEC_DECODED, "trap" }, /* trap isrc1ni,isrc2,idest. */ + { nullptr, DEC_MORE, nullptr }, /* FP ESCAPE FORMAT, more decode. */ + { nullptr, DEC_MORE, nullptr }, /* CORE ESCAPE FORMAT, more decode. */ + { &i860_disassembler::int_12S, DEC_DECODED, "btne" }, /* btne isrc1,isrc2,sbroff. */ + { &i860_disassembler::int_i2S, DEC_DECODED, "btne" }, /* btne #const,isrc2,sbroff. */ + { &i860_disassembler::int_12S, DEC_DECODED, "bte" }, /* bte isrc1,isrc2,sbroff. */ + { &i860_disassembler::int_i2S, DEC_DECODED, "bte" }, /* bte #const5,isrc2,idest. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "pfld." }, /* pfld.{l,d,q} isrc1(isrc2)[++],fdest. */ + { &i860_disassembler::int_fldst, DEC_DECODED, "pfld." }, /* pfld.{l,d,q} #const(isrc2)[++],fdest.*/ + { &i860_disassembler::int_L, DEC_DECODED, "br" }, /* br lbroff. */ + { &i860_disassembler::int_L, DEC_DECODED, "call" }, /* call lbroff . */ + { &i860_disassembler::int_L, DEC_DECODED, "bc" }, /* bc lbroff. */ + { &i860_disassembler::int_L, DEC_DECODED, "bc.t" }, /* bc.t lbroff. */ + { &i860_disassembler::int_L, DEC_DECODED, "bnc" }, /* bnc lbroff. */ + { &i860_disassembler::int_L, DEC_DECODED, "bnc.t" }, /* bnc.t lbroff. */ + { &i860_disassembler::int_12d, DEC_DECODED, "addu" }, /* addu isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "addu" }, /* addu #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "subu" }, /* subu isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "subu" }, /* subu #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "adds" }, /* adds isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "adds" }, /* adds #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "subs" }, /* subs isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "subs" }, /* subs #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "shl" }, /* shl isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "shl" }, /* shl #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "shr" }, /* shr isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "shr" }, /* shr #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "shrd" }, /* shrd isrc1ni,isrc2,idest. */ + { &i860_disassembler::int_12S, DEC_DECODED, "bla" }, /* bla isrc1ni,isrc2,sbroff. */ + { &i860_disassembler::int_12d, DEC_DECODED, "shra" }, /* shra isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "shra" }, /* shra #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "and" }, /* and isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "and" }, /* and #const,isrc2,idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_i2d, DEC_DECODED, "andh" }, /* andh #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "andnot" }, /* andnot isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "andnot" }, /* andnot #const,isrc2,idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_i2d, DEC_DECODED, "andnoth" }, /* andnoth #const,isrc2,idest.*/ + { &i860_disassembler::int_12d, DEC_DECODED, "or" }, /* or isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "or" }, /* or #const,isrc2,idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_i2d, DEC_DECODED, "orh" }, /* orh #const,isrc2,idest. */ + { &i860_disassembler::int_12d, DEC_DECODED, "xor" }, /* xor isrc1,isrc2,idest. */ + { &i860_disassembler::int_i2d, DEC_DECODED, "xor" }, /* xor #const,isrc2,idest. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_i2d, DEC_DECODED, "xorh" }, /* xorh #const,isrc2,idest. */ }; /* Second-level decode table (i.e., for the 3 core escape opcode bits). */ -static const decode_tbl_t core_esc_decode_tbl[8] = +const i860_disassembler::decode_tbl_t i860_disassembler::core_esc_decode_tbl[8] = { - { nullptr, 0 , nullptr }, - { int_0, DEC_DECODED, "lock" }, /* lock. */ - { int_1, DEC_DECODED, "calli" }, /* calli isrc1ni. */ - { nullptr, 0 , nullptr }, - { int_0, DEC_DECODED, "intovr" }, /* intovr. */ - { nullptr, 0 , nullptr }, - { nullptr, 0 , nullptr }, - { int_0, DEC_DECODED, "unlock" }, /* unlock. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_0, DEC_DECODED, "lock" }, /* lock. */ + { &i860_disassembler::int_1, DEC_DECODED, "calli" }, /* calli isrc1ni. */ + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_0, DEC_DECODED, "intovr" }, /* intovr. */ + { nullptr, 0 , nullptr }, + { nullptr, 0 , nullptr }, + { &i860_disassembler::int_0, DEC_DECODED, "unlock" }, /* unlock. */ }; /* Second-level decode table (i.e., for the 7 FP extended opcode bits). */ -static const decode_tbl_t fp_decode_tbl[128] = +const i860_disassembler::decode_tbl_t i860_disassembler::fp_decode_tbl[128] = { /* Floating point instructions. The least significant 7 bits are the (extended) opcode and bits 10:7 are P,D,S,R respectively ([p]ipelined, [d]ual, [s]ource prec., [r]esult prec.). For some operations, I defer decoding the P,S,R bits to the emulation routine for them. */ - { flop_12d, DEC_DECODED, "r2p1." }, /* 0x00 pf[m]am */ - { flop_12d, DEC_DECODED, "r2pt." }, /* 0x01 pf[m]am */ - { flop_12d, DEC_DECODED, "r2ap1." }, /* 0x02 pf[m]am */ - { flop_12d, DEC_DECODED, "r2apt." }, /* 0x03 pf[m]am */ - { flop_12d, DEC_DECODED, "i2p1." }, /* 0x04 pf[m]am */ - { flop_12d, DEC_DECODED, "i2pt." }, /* 0x05 pf[m]am */ - { flop_12d, DEC_DECODED, "i2ap1." }, /* 0x06 pf[m]am */ - { flop_12d, DEC_DECODED, "i2apt." }, /* 0x07 pf[m]am */ - { flop_12d, DEC_DECODED, "rat1p2." }, /* 0x08 pf[m]am */ - { flop_12d, DEC_DECODED, "m12apm." }, /* 0x09 pf[m]am */ - { flop_12d, DEC_DECODED, "ra1p2." }, /* 0x0A pf[m]am */ - { flop_12d, DEC_DECODED, "m12ttpa." }, /* 0x0B pf[m]am */ - { flop_12d, DEC_DECODED, "iat1p2." }, /* 0x0C pf[m]am */ - { flop_12d, DEC_DECODED, "m12tpm." }, /* 0x0D pf[m]am */ - { flop_12d, DEC_DECODED, "ia1p2." }, /* 0x0E pf[m]am */ - { flop_12d, DEC_DECODED, "m12tpa." }, /* 0x0F pf[m]am */ - { flop_12d, DEC_DECODED, "r2s1." }, /* 0x10 pf[m]sm */ - { flop_12d, DEC_DECODED, "r2st." }, /* 0x11 pf[m]sm */ - { flop_12d, DEC_DECODED, "r2as1." }, /* 0x12 pf[m]sm */ - { flop_12d, DEC_DECODED, "r2ast." }, /* 0x13 pf[m]sm */ - { flop_12d, DEC_DECODED, "i2s1." }, /* 0x14 pf[m]sm */ - { flop_12d, DEC_DECODED, "i2st." }, /* 0x15 pf[m]sm */ - { flop_12d, DEC_DECODED, "i2as1." }, /* 0x16 pf[m]sm */ - { flop_12d, DEC_DECODED, "i2ast." }, /* 0x17 pf[m]sm */ - { flop_12d, DEC_DECODED, "rat1s2." }, /* 0x18 pf[m]sm */ - { flop_12d, DEC_DECODED, "m12asm." }, /* 0x19 pf[m]sm */ - { flop_12d, DEC_DECODED, "ra1s2." }, /* 0x1A pf[m]sm */ - { flop_12d, DEC_DECODED, "m12ttsa." }, /* 0x1B pf[m]sm */ - { flop_12d, DEC_DECODED, "iat1s2." }, /* 0x1C pf[m]sm */ - { flop_12d, DEC_DECODED, "m12tsm." }, /* 0x1D pf[m]sm */ - { flop_12d, DEC_DECODED, "ia1s2." }, /* 0x1E pf[m]sm */ - { flop_12d, DEC_DECODED, "m12tsa." }, /* 0x1F pf[m]sm */ - { flop_12d, DEC_DECODED, "fmul." }, /* 0x20 [p]fmul */ - { flop_12d, DEC_DECODED, "fmlow." }, /* 0x21 fmlow.dd */ - { flop_2d, DEC_DECODED, "frcp." }, /* 0x22 frcp.{ss,sd,dd} */ - { flop_2d, DEC_DECODED, "frsqr." }, /* 0x23 frsqr.{ss,sd,dd} */ - { flop_12d, DEC_DECODED, "pfmul3.dd" }, /* 0x24 pfmul3.dd */ - { nullptr, 0 , nullptr }, /* 0x25 */ - { nullptr, 0 , nullptr }, /* 0x26 */ - { nullptr, 0 , nullptr }, /* 0x27 */ - { nullptr, 0 , nullptr }, /* 0x28 */ - { nullptr, 0 , nullptr }, /* 0x29 */ - { nullptr, 0 , nullptr }, /* 0x2A */ - { nullptr, 0 , nullptr }, /* 0x2B */ - { nullptr, 0 , nullptr }, /* 0x2C */ - { nullptr, 0 , nullptr }, /* 0x2D */ - { nullptr, 0 , nullptr }, /* 0x2E */ - { nullptr, 0 , nullptr }, /* 0x2F */ - { flop_12d, DEC_DECODED, "fadd." }, /* 0x30, [p]fadd.{ss,sd,dd} */ - { flop_12d, DEC_DECODED, "fsub." }, /* 0x31, [p]fsub.{ss,sd,dd} */ - { flop_1d, DEC_DECODED, "fix." }, /* 0x32, [p]fix.{ss,sd,dd} */ - { flop_1d, DEC_DECODED, "famov." }, /* 0x33, [p]famov.{ss,sd,ds,dd} */ - { flop_12d, DEC_DECODED, "f{gt,le}" }, /* 0x34, pf{gt,le}.{ss,dd} */ - { flop_12d, DEC_DECODED, "feq." }, /* 0x35, pfeq.{ss,dd} */ - { nullptr, 0 , nullptr }, /* 0x36 */ - { nullptr, 0 , nullptr }, /* 0x37 */ - { nullptr, 0 , nullptr }, /* 0x38 */ - { nullptr, 0 , nullptr }, /* 0x39 */ - { flop_1d, DEC_DECODED, "ftrunc." }, /* 0x3A, [p]ftrunc.{ss,sd,dd} */ - { nullptr, 0 , nullptr }, /* 0x3B */ - { nullptr, 0 , nullptr }, /* 0x3C */ - { nullptr, 0 , nullptr }, /* 0x3D */ - { nullptr, 0 , nullptr }, /* 0x3E */ - { nullptr, 0 , nullptr }, /* 0x3F */ - { flop_fxfr, DEC_DECODED, "fxfr" }, /* 0x40, fxfr fsrc1,idest. */ - { nullptr, 0 , nullptr }, /* 0x41 */ - { nullptr, 0 , nullptr }, /* 0x42 */ - { nullptr, 0 , nullptr }, /* 0x43 */ - { nullptr, 0 , nullptr }, /* 0x44 */ - { nullptr, 0 , nullptr }, /* 0x45 */ - { nullptr, 0 , nullptr }, /* 0x46 */ - { nullptr, 0 , nullptr }, /* 0x47 */ - { nullptr, 0 , nullptr }, /* 0x48 */ - { flop_12d, DEC_DECODED, "fiadd." }, /* 0x49, [p]fiadd.{ss,dd} */ - { nullptr, 0 , nullptr }, /* 0x4A */ - { nullptr, 0 , nullptr }, /* 0x4B */ - { nullptr, 0 , nullptr }, /* 0x4C */ - { flop_12d, DEC_DECODED, "fisub." }, /* 0x4D, [p]fisub.{ss,dd} */ - { nullptr, 0 , nullptr }, /* 0x4E */ - { nullptr, 0 , nullptr }, /* 0x4F */ - { flop_12d, DEC_DECODED, "faddp" }, /* 0x50, [p]faddp */ - { flop_12d, DEC_DECODED, "faddz" }, /* 0x51, [p]faddz */ - { nullptr, 0 , nullptr }, /* 0x52 */ - { nullptr, 0 , nullptr }, /* 0x53 */ - { nullptr, 0 , nullptr }, /* 0x54 */ - { nullptr, 0 , nullptr }, /* 0x55 */ - { nullptr, 0 , nullptr }, /* 0x56 */ - { flop_12d, DEC_DECODED, "fzchkl" }, /* 0x57, [p]fzchkl */ - { nullptr, 0 , nullptr }, /* 0x58 */ - { nullptr, 0 , nullptr }, /* 0x59 */ - { flop_1d, DEC_DECODED, "form" }, /* 0x5A, [p]form.dd */ - { nullptr, 0 , nullptr }, /* 0x5B */ - { nullptr, 0 , nullptr }, /* 0x5C */ - { nullptr, 0 , nullptr }, /* 0x5D */ - { nullptr, 0 , nullptr }, /* 0x5E */ - { flop_12d, DEC_DECODED, "fzchks" }, /* 0x5F, [p]fzchks */ - { nullptr, 0 , nullptr }, /* 0x60 */ - { nullptr, 0 , nullptr }, /* 0x61 */ - { nullptr, 0 , nullptr }, /* 0x62 */ - { nullptr, 0 , nullptr }, /* 0x63 */ - { nullptr, 0 , nullptr }, /* 0x64 */ - { nullptr, 0 , nullptr }, /* 0x65 */ - { nullptr, 0 , nullptr }, /* 0x66 */ - { nullptr, 0 , nullptr }, /* 0x67 */ - { nullptr, 0 , nullptr }, /* 0x68 */ - { nullptr, 0 , nullptr }, /* 0x69 */ - { nullptr, 0 , nullptr }, /* 0x6A */ - { nullptr, 0 , nullptr }, /* 0x6B */ - { nullptr, 0 , nullptr }, /* 0x6C */ - { nullptr, 0 , nullptr }, /* 0x6D */ - { nullptr, 0 , nullptr }, /* 0x6E */ - { nullptr, 0 , nullptr }, /* 0x6F */ - { nullptr, 0 , nullptr }, /* 0x70 */ - { nullptr, 0 , nullptr }, /* 0x71 */ - { nullptr, 0 , nullptr }, /* 0x72 */ - { nullptr, 0 , nullptr }, /* 0x73 */ - { nullptr, 0 , nullptr }, /* 0x74 */ - { nullptr, 0 , nullptr }, /* 0x75 */ - { nullptr, 0 , nullptr }, /* 0x76 */ - { nullptr, 0 , nullptr }, /* 0x77 */ - { nullptr, 0 , nullptr }, /* 0x78 */ - { nullptr, 0 , nullptr }, /* 0x79 */ - { nullptr, 0 , nullptr }, /* 0x7A */ - { nullptr, 0 , nullptr }, /* 0x7B */ - { nullptr, 0 , nullptr }, /* 0x7C */ - { nullptr, 0 , nullptr }, /* 0x7D */ - { nullptr, 0 , nullptr }, /* 0x7E */ - { nullptr, 0 , nullptr }, /* 0x7F */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2p1." }, /* 0x00 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2pt." }, /* 0x01 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2ap1." }, /* 0x02 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2apt." }, /* 0x03 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2p1." }, /* 0x04 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2pt." }, /* 0x05 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2ap1." }, /* 0x06 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2apt." }, /* 0x07 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "rat1p2." }, /* 0x08 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12apm." }, /* 0x09 pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "ra1p2." }, /* 0x0A pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12ttpa." }, /* 0x0B pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "iat1p2." }, /* 0x0C pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12tpm." }, /* 0x0D pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "ia1p2." }, /* 0x0E pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12tpa." }, /* 0x0F pf[m]am */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2s1." }, /* 0x10 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2st." }, /* 0x11 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2as1." }, /* 0x12 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "r2ast." }, /* 0x13 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2s1." }, /* 0x14 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2st." }, /* 0x15 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2as1." }, /* 0x16 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "i2ast." }, /* 0x17 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "rat1s2." }, /* 0x18 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12asm." }, /* 0x19 pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "ra1s2." }, /* 0x1A pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12ttsa." }, /* 0x1B pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "iat1s2." }, /* 0x1C pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12tsm." }, /* 0x1D pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "ia1s2." }, /* 0x1E pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "m12tsa." }, /* 0x1F pf[m]sm */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fmul." }, /* 0x20 [p]fmul */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fmlow." }, /* 0x21 fmlow.dd */ + { &i860_disassembler::flop_2d, DEC_DECODED, "frcp." }, /* 0x22 frcp.{ss,sd,dd} */ + { &i860_disassembler::flop_2d, DEC_DECODED, "frsqr." }, /* 0x23 frsqr.{ss,sd,dd} */ + { &i860_disassembler::flop_12d, DEC_DECODED, "pfmul3.dd" }, /* 0x24 pfmul3.dd */ + { nullptr, 0 , nullptr }, /* 0x25 */ + { nullptr, 0 , nullptr }, /* 0x26 */ + { nullptr, 0 , nullptr }, /* 0x27 */ + { nullptr, 0 , nullptr }, /* 0x28 */ + { nullptr, 0 , nullptr }, /* 0x29 */ + { nullptr, 0 , nullptr }, /* 0x2A */ + { nullptr, 0 , nullptr }, /* 0x2B */ + { nullptr, 0 , nullptr }, /* 0x2C */ + { nullptr, 0 , nullptr }, /* 0x2D */ + { nullptr, 0 , nullptr }, /* 0x2E */ + { nullptr, 0 , nullptr }, /* 0x2F */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fadd." }, /* 0x30, [p]fadd.{ss,sd,dd} */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fsub." }, /* 0x31, [p]fsub.{ss,sd,dd} */ + { &i860_disassembler::flop_1d, DEC_DECODED, "fix." }, /* 0x32, [p]fix.{ss,sd,dd} */ + { &i860_disassembler::flop_1d, DEC_DECODED, "famov." }, /* 0x33, [p]famov.{ss,sd,ds,dd} */ + { &i860_disassembler::flop_12d, DEC_DECODED, "f{gt,le}" }, /* 0x34, pf{gt,le}.{ss,dd} */ + { &i860_disassembler::flop_12d, DEC_DECODED, "feq." }, /* 0x35, pfeq.{ss,dd} */ + { nullptr, 0 , nullptr }, /* 0x36 */ + { nullptr, 0 , nullptr }, /* 0x37 */ + { nullptr, 0 , nullptr }, /* 0x38 */ + { nullptr, 0 , nullptr }, /* 0x39 */ + { &i860_disassembler::flop_1d, DEC_DECODED, "ftrunc." }, /* 0x3A, [p]ftrunc.{ss,sd,dd} */ + { nullptr, 0 , nullptr }, /* 0x3B */ + { nullptr, 0 , nullptr }, /* 0x3C */ + { nullptr, 0 , nullptr }, /* 0x3D */ + { nullptr, 0 , nullptr }, /* 0x3E */ + { nullptr, 0 , nullptr }, /* 0x3F */ + { &i860_disassembler::flop_fxfr, DEC_DECODED, "fxfr" }, /* 0x40, fxfr fsrc1,idest. */ + { nullptr, 0 , nullptr }, /* 0x41 */ + { nullptr, 0 , nullptr }, /* 0x42 */ + { nullptr, 0 , nullptr }, /* 0x43 */ + { nullptr, 0 , nullptr }, /* 0x44 */ + { nullptr, 0 , nullptr }, /* 0x45 */ + { nullptr, 0 , nullptr }, /* 0x46 */ + { nullptr, 0 , nullptr }, /* 0x47 */ + { nullptr, 0 , nullptr }, /* 0x48 */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fiadd." }, /* 0x49, [p]fiadd.{ss,dd} */ + { nullptr, 0 , nullptr }, /* 0x4A */ + { nullptr, 0 , nullptr }, /* 0x4B */ + { nullptr, 0 , nullptr }, /* 0x4C */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fisub." }, /* 0x4D, [p]fisub.{ss,dd} */ + { nullptr, 0 , nullptr }, /* 0x4E */ + { nullptr, 0 , nullptr }, /* 0x4F */ + { &i860_disassembler::flop_12d, DEC_DECODED, "faddp" }, /* 0x50, [p]faddp */ + { &i860_disassembler::flop_12d, DEC_DECODED, "faddz" }, /* 0x51, [p]faddz */ + { nullptr, 0 , nullptr }, /* 0x52 */ + { nullptr, 0 , nullptr }, /* 0x53 */ + { nullptr, 0 , nullptr }, /* 0x54 */ + { nullptr, 0 , nullptr }, /* 0x55 */ + { nullptr, 0 , nullptr }, /* 0x56 */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fzchkl" }, /* 0x57, [p]fzchkl */ + { nullptr, 0 , nullptr }, /* 0x58 */ + { nullptr, 0 , nullptr }, /* 0x59 */ + { &i860_disassembler::flop_1d, DEC_DECODED, "form" }, /* 0x5A, [p]form.dd */ + { nullptr, 0 , nullptr }, /* 0x5B */ + { nullptr, 0 , nullptr }, /* 0x5C */ + { nullptr, 0 , nullptr }, /* 0x5D */ + { nullptr, 0 , nullptr }, /* 0x5E */ + { &i860_disassembler::flop_12d, DEC_DECODED, "fzchks" }, /* 0x5F, [p]fzchks */ + { nullptr, 0 , nullptr }, /* 0x60 */ + { nullptr, 0 , nullptr }, /* 0x61 */ + { nullptr, 0 , nullptr }, /* 0x62 */ + { nullptr, 0 , nullptr }, /* 0x63 */ + { nullptr, 0 , nullptr }, /* 0x64 */ + { nullptr, 0 , nullptr }, /* 0x65 */ + { nullptr, 0 , nullptr }, /* 0x66 */ + { nullptr, 0 , nullptr }, /* 0x67 */ + { nullptr, 0 , nullptr }, /* 0x68 */ + { nullptr, 0 , nullptr }, /* 0x69 */ + { nullptr, 0 , nullptr }, /* 0x6A */ + { nullptr, 0 , nullptr }, /* 0x6B */ + { nullptr, 0 , nullptr }, /* 0x6C */ + { nullptr, 0 , nullptr }, /* 0x6D */ + { nullptr, 0 , nullptr }, /* 0x6E */ + { nullptr, 0 , nullptr }, /* 0x6F */ + { nullptr, 0 , nullptr }, /* 0x70 */ + { nullptr, 0 , nullptr }, /* 0x71 */ + { nullptr, 0 , nullptr }, /* 0x72 */ + { nullptr, 0 , nullptr }, /* 0x73 */ + { nullptr, 0 , nullptr }, /* 0x74 */ + { nullptr, 0 , nullptr }, /* 0x75 */ + { nullptr, 0 , nullptr }, /* 0x76 */ + { nullptr, 0 , nullptr }, /* 0x77 */ + { nullptr, 0 , nullptr }, /* 0x78 */ + { nullptr, 0 , nullptr }, /* 0x79 */ + { nullptr, 0 , nullptr }, /* 0x7A */ + { nullptr, 0 , nullptr }, /* 0x7B */ + { nullptr, 0 , nullptr }, /* 0x7C */ + { nullptr, 0 , nullptr }, /* 0x7D */ + { nullptr, 0 , nullptr }, /* 0x7E */ + { nullptr, 0 , nullptr }, /* 0x7F */ }; /* Replaces tabs with spaces. */ -static void i860_dasm_tab_replacer(std::ostream &stream, const std::string &buf, int tab_size) +void i860_disassembler::i860_dasm_tab_replacer(std::ostream &stream, const std::string &buf, int tab_size) { int tab_count = 0; @@ -636,14 +613,11 @@ static void i860_dasm_tab_replacer(std::ostream &stream, const std::string &buf, } -static offs_t internal_disasm_i860(cpu_device *device, std::ostream &main_stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options) +offs_t i860_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - std::stringstream stream; + std::stringstream tstream; - uint32_t insn = (oprom[0] << 0) | - (oprom[1] << 8) | - (oprom[2] << 16) | - (oprom[3] << 24); + uint32_t insn = opcodes.r32(pc); int unrecognized_op = 1; int upper_6bits = (insn >> 26) & 0x3f; @@ -651,7 +625,7 @@ static offs_t internal_disasm_i860(cpu_device *device, std::ostream &main_stream if (flags & DEC_DECODED) { const char *s = decode_tbl[upper_6bits].mnemonic; - decode_tbl[upper_6bits].insn_dis (stream, (char *)s, pc, insn); + (this->*(decode_tbl[upper_6bits].insn_dis)) (tstream, (char *)s, pc, insn); unrecognized_op = 0; } else if (flags & DEC_MORE) @@ -663,7 +637,7 @@ static offs_t internal_disasm_i860(cpu_device *device, std::ostream &main_stream const char *s = fp_decode_tbl[insn & 0x7f].mnemonic; if (fp_flags & DEC_DECODED) { - fp_decode_tbl[insn & 0x7f].insn_dis (stream, (char *)s, pc, insn); + (this->*(fp_decode_tbl[insn & 0x7f].insn_dis)) (tstream, (char *)s, pc, insn); unrecognized_op = 0; } } @@ -674,25 +648,24 @@ static offs_t internal_disasm_i860(cpu_device *device, std::ostream &main_stream const char *s = core_esc_decode_tbl[insn & 0x3].mnemonic; if (esc_flags & DEC_DECODED) { - core_esc_decode_tbl[insn & 0x3].insn_dis (stream, (char *)s, pc, insn); + (this->*(core_esc_decode_tbl[insn & 0x3].insn_dis)) (tstream, (char *)s, pc, insn); unrecognized_op = 0; } } } if (unrecognized_op) - util::stream_format(stream, ".long\t%#08x", insn); + util::stream_format(tstream, ".long\t%#08x", insn); /* Replace tabs with spaces */ - i860_dasm_tab_replacer(main_stream, stream.str(), 10); + i860_dasm_tab_replacer(stream, tstream.str(), 10); /* Return number of bytes disassembled. */ /* MAME dasm flags haven't been added yet */ return (4); } - -CPU_DISASSEMBLE(i860) +u32 i860_disassembler::opcode_alignment() const { - return internal_disasm_i860(device, stream, pc, oprom, opram, options); + return 4; } diff --git a/src/devices/cpu/i860/i860dis.h b/src/devices/cpu/i860/i860dis.h new file mode 100644 index 00000000000..46847ba8648 --- /dev/null +++ b/src/devices/cpu/i860/i860dis.h @@ -0,0 +1,77 @@ +// license:BSD-3-Clause +// copyright-holders:Jason Eckhardt +/*************************************************************************** + + i860dis.c + + Disassembler for the Intel i860 emulator. + + Copyright (C) 1995-present Jason Eckhardt (jle@rice.edu) + +***************************************************************************/ + +#ifndef MAME_CPU_I860_I860DIS_H +#define MAME_CPU_I860_I860DIS_H + +#pragma once + +class i860_disassembler : public util::disasm_interface +{ +public: + i860_disassembler() = default; + virtual ~i860_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + /* Flags for the decode table. */ + enum + { + DEC_MORE = 1, /* More decoding necessary. */ + DEC_DECODED = 2 /* Fully decoded, go. */ + }; + + + struct decode_tbl_t + { + /* Disassembly function for this opcode. + Call with buffer, mnemonic, pc, insn. */ + void (i860_disassembler::*insn_dis)(std::ostream &, char *, uint32_t, uint32_t); + + /* Flags for this opcode. */ + char flags; + + /* Mnemonic of this opcode (sometimes partial when more decode is + done in disassembly routines-- e.g., loads and stores). */ + const char *mnemonic; + }; + + static const char *const cr2str[]; + static const decode_tbl_t decode_tbl[64]; + static const decode_tbl_t core_esc_decode_tbl[8]; + static const decode_tbl_t fp_decode_tbl[128]; + + int32_t sign_ext(uint32_t x, int n); + void int_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_i2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_cd(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_1c(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_1(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_0(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void flop_12d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void flop_1d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void flop_2d(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void flop_fxfr(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_12S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_i2S(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_L(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_ldx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_stx(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_fldst(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void int_flush(std::ostream &stream, char *mnemonic, uint32_t pc, uint32_t insn); + void i860_dasm_tab_replacer(std::ostream &stream, const std::string &buf, int tab_size); +}; + +#endif diff --git a/src/devices/cpu/i960/i960.cpp b/src/devices/cpu/i960/i960.cpp index dcffb837f95..148cc1a8996 100644 --- a/src/devices/cpu/i960/i960.cpp +++ b/src/devices/cpu/i960/i960.cpp @@ -2,10 +2,9 @@ // copyright-holders:Farfetch'd, R. Belmont #include "emu.h" #include "i960.h" +#include "i960dis.h" #include "debugger.h" -CPU_DISASSEMBLE( i960 ); - #ifdef _MSC_VER /* logb prototype is different for MS Visual C */ #include <float.h> @@ -2104,7 +2103,7 @@ void i960_cpu_device::execute_set_input(int irqline, int state) void i960_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_IP)); save_item(NAME(m_PIP)); @@ -2209,9 +2208,7 @@ void i960_cpu_device::device_reset() m_rcache_pos = 0; } - -offs_t i960_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i960_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( i960 ); - return CPU_DISASSEMBLE_NAME(i960)(this, stream, pc, oprom, opram, options); + return new i960_disassembler; } diff --git a/src/devices/cpu/i960/i960.h b/src/devices/cpu/i960/i960.h index 76d60109cf4..2b2b53e2729 100644 --- a/src/devices/cpu/i960/i960.h +++ b/src/devices/cpu/i960/i960.h @@ -97,9 +97,7 @@ protected: 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 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -127,7 +125,7 @@ private: int m_immediate_pri; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; diff --git a/src/devices/cpu/i960/i960dis.cpp b/src/devices/cpu/i960/i960dis.cpp index 43f81015240..5f4991fc77b 100644 --- a/src/devices/cpu/i960/i960dis.cpp +++ b/src/devices/cpu/i960/i960dis.cpp @@ -7,17 +7,10 @@ */ #include "emu.h" -#include "i960.h" #include "i960dis.h" -struct mnemonic_t -{ - const char *mnem; - unsigned short type; -}; - -static const mnemonic_t mnemonic[256] = { +const i960_disassembler::mnemonic_t i960_disassembler::mnemonic[256] = { { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, // 00 { "b", 8 }, { "call", 8 }, { "ret", 9 }, { "bal", 8 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, @@ -67,7 +60,7 @@ static const mnemonic_t mnemonic[256] = { { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 }, { "?", 0 } }; -static const mnemonic_t mnem_reg[100] = +const i960_disassembler::mnemonic_t i960_disassembler::mnem_reg[100] = { { "notbit", 0x580 }, { "and", 0x581 }, { "andnot", 0x582 }, { "setbit", 0x583 }, { "notand",0x584 }, { "xor", 0x586 }, { "or", 0x587 }, { "nor", 0x588 }, { "xnor",0x589 }, { "not",0x58a }, @@ -93,13 +86,13 @@ static const mnemonic_t mnem_reg[100] = { "ending_code",0 } }; -static const char *const constnames[32] = +const char *const i960_disassembler::constnames[32] = { "0x0", "0x1", "0x2", "0x3", "0x4", "0x5", "0x6", "0x7", "0x8", "0x9", "0xa", "0xb", "0xc", "0xd", "0xe", "0xf", "0x10", "0x11", "0x12", "0x13", "0x14", "0x15", "0x16", "0x17", "0x18", "0x19", "0x1a", "0x1b", "0x1c", "0x1d", "0x1e", "0x1f" }; -static const char *const regnames[32] = +const char *const i960_disassembler::regnames[32] = { "pfp","sp","rip","r3", "r4","r5","r6","r7", "r8","r9","r10","r11", "r12","r13","r14","r15", "g0","g1","g2","g3", "g4","g5","g6","g7", "g8","g9","g10","g11", "g12","g13","g14","fp", @@ -128,118 +121,120 @@ static const char *const regnames[32] = #define COBRSRC1 ((iCode >> 19) & 0x1f) #define COBRSRC2 ((iCode >> 14) & 0x1f) -static char *dis_decode_reg(unsigned long iCode, char* tmpStr,unsigned char cnt) +std::string i960_disassembler::dis_decode_reg(u32 iCode, unsigned char cnt) { - char src1[10]; - char src2[10]; - char dst[10]; + std::string src1, src2, dst; - if (S1) src1[0] = 0; + if (S1) + src1 = ""; else { - if(M1) sprintf(src1,"0x%lx",SRC1); - else sprintf(src1,"%s",regnames[SRC1]); + if(M1) + src1 = util::string_format("0x%lx", SRC1); + else + src1 = util::string_format("%s", regnames[SRC1]); } - if (S2) sprintf(src2,"reserved"); + + if (S2) + src2 = "reserved"; else { - if(M2) sprintf(src2,"0x%lx,",SRC2); - else sprintf(src2,"%s,",regnames[SRC2]); + if(M2) + src2 = util::string_format("0x%lx,", SRC2); + else + src2 = util::string_format("%s,", regnames[SRC2]); } - if(M3) dst[0] = 0; - else sprintf(dst,"%s,",regnames[DST]); + + if(M3) + dst = ""; + else + dst = util::string_format("%s,", regnames[DST]); + if (cnt == 1) - sprintf(tmpStr,"%s%s",dst,src1); + return util::string_format("%s%s", dst, src1); else - sprintf(tmpStr,"%s%s%s",dst,src2,src1); - return tmpStr; + return util::string_format("%s%s%s", dst, src2, src1); } -#define READ32(dis,offs) ((dis)->oprom[(offs) + 0] | ((dis)->oprom[(offs) + 1] << 8) | ((dis)->oprom[(offs) + 2] << 16) | ((dis)->oprom[(offs) + 3] << 24)) - -static void i960_disassemble(disassemble_t *diss) +offs_t i960_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned char op,op2; - unsigned char /*mode,*/ modeh, model; - unsigned char dst,abase,reg2; - unsigned short opc; - unsigned long iCode; - char tmpStr[256]; - long i; - - iCode = READ32(diss,0); - op = (unsigned char) (iCode >> 24); - op2 = (unsigned char) (iCode >> 7)&0xf; - - model = (unsigned char) (iCode >> 10) &0x3; - modeh = (unsigned char) (iCode >> 12) &0x3; + u32 IP = pc; + + u32 iCode = opcodes.r32(IP); + u8 op = (unsigned char) (iCode >> 24); + u8 op2 = (unsigned char) (iCode >> 7)&0xf; + u8 opc = 0; + u32 i = 0; + + u8 model = (unsigned char) (iCode >> 10) &0x3; + u8 modeh = (unsigned char) (iCode >> 12) &0x3; //mode = (unsigned char) (iCode >> 10) &0x7; - dst = (unsigned char) (iCode >> 19) &0x1f; - abase = (unsigned char) (iCode>>14)&0x1f; - reg2 = (unsigned char) (iCode)&0x1f; + u8 dst = (unsigned char) (iCode >> 19) &0x1f; + u8 abase = (unsigned char) (iCode>>14)&0x1f; + u8 reg2 = (unsigned char) (iCode)&0x1f; - diss->IPinc = 4; - diss->disflags = 0; + offs_t IPinc = 4; + offs_t disflags = 0; if (op == 0x09 || op == 0x0b || op == 0x66 || op == 0x85 || op == 0x86) - diss->disflags = DASMFLAG_STEP_OVER; + disflags = STEP_OVER; else if (op == 0x0a) - diss->disflags = DASMFLAG_STEP_OUT; + disflags = STEP_OUT; switch(mnemonic[op].type) { case 0: // not yet implemented - util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; case 1: // memory access switch(modeh) { case 0: - util::stream_format(diss->stream, "%-8s%s,0x%lx",NEM,REG_DST, iCode&0xfff); + util::stream_format(stream, "%-8s%s,0x%lx",NEM,REG_DST, iCode&0xfff); break; case 1: switch (model) { case 0: - util::stream_format(diss->stream, "%-8s%s,(%s)",NEM,REG_DST, REG_ABASE); + util::stream_format(stream, "%-8s%s,(%s)",NEM,REG_DST, REG_ABASE); break; case 3: - util::stream_format(diss->stream, "%-8s%s,(%s)[%s*%ld]",NEM,REG_DST, REG_ABASE,REG_REG2,(iCode>>7)&0x7); + util::stream_format(stream, "%-8s%s,(%s)[%s*%ld]",NEM,REG_DST, REG_ABASE,REG_REG2,(iCode>>7)&0x7); break; default: - util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; } break; case 2: - util::stream_format(diss->stream, "%-8s%s,0x%lx(%s)",NEM,REG_DST, iCode&0xfff,REG_ABASE); + util::stream_format(stream, "%-8s%s,0x%lx(%s)",NEM,REG_DST, iCode&0xfff,REG_ABASE); break; case 3: switch (model) { case 0: - util::stream_format(diss->stream, "%-8s%s,0x%x",NEM,REG_DST, READ32(diss,4)); - diss->IPinc = 8; + util::stream_format(stream, "%-8s%s,0x%x",NEM,REG_DST, opcodes.r32(IP + 4)); + IPinc = 8; break; case 1: - util::stream_format(diss->stream, "%-8s%s,0x%x(%s)",NEM,REG_DST, READ32(diss,4),REG_ABASE); - diss->IPinc = 8; + util::stream_format(stream, "%-8s%s,0x%x(%s)",NEM,REG_DST, opcodes.r32(IP + 4),REG_ABASE); + IPinc = 8; break; case 2: - util::stream_format(diss->stream, "%-8s%s,0x%x[%s*%ld]",NEM,REG_DST, READ32(diss,4),REG_REG2,(iCode>>7)&0x7); - diss->IPinc = 8; + util::stream_format(stream, "%-8s%s,0x%x[%s*%ld]",NEM,REG_DST, opcodes.r32(IP + 4),REG_REG2,(iCode>>7)&0x7); + IPinc = 8; break; case 3: - util::stream_format(diss->stream, "%-8s%s,0x%x(%s)[%s*%ld]",NEM,REG_DST, READ32(diss,4),REG_ABASE,REG_REG2,(iCode>>7)&0x7); - diss->IPinc = 8; + util::stream_format(stream, "%-8s%s,0x%x(%s)[%s*%ld]",NEM,REG_DST, opcodes.r32(IP + 4),REG_ABASE,REG_REG2,(iCode>>7)&0x7); + IPinc = 8; break; default: - util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; } break; default: - util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; } break; @@ -253,8 +248,8 @@ static void i960_disassemble(disassemble_t *diss) i++; } - if (mnem_reg[i].type == opc) util::stream_format(diss->stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,tmpStr,1)); - else util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + if (mnem_reg[i].type == opc) util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,1)); + else util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; case 3: i = 0; @@ -266,38 +261,34 @@ static void i960_disassemble(disassemble_t *diss) i++; } - if (mnem_reg[i].type == opc) util::stream_format(diss->stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,tmpStr,0)); - else util::stream_format(diss->stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); + if (mnem_reg[i].type == opc) util::stream_format(stream, "%-8s%s", mnem_reg[i].mnem,dis_decode_reg(iCode,0)); + else util::stream_format(stream, "%s %02x:%01x %08lx %1x %1x",mnemonic[op].mnem,op,op2,iCode, modeh, model); break; case 6: // bitpos and branch type - util::stream_format(diss->stream, "%-8s%ld,%s,0x%lx",NEM, COBRSRC1, REG_COBR_SRC2,((((long)iCode&0x00fffffc)<<19)>>19) + (diss->IP)); + util::stream_format(stream, "%-8s%ld,%s,0x%lx",NEM, COBRSRC1, REG_COBR_SRC2,((((s32)iCode&0x00fffffc)<<19)>>19) + (IP)); break; case 7: // compare and branch type - util::stream_format(diss->stream, "%-8s%s,%s,0x%lx",NEM,REG_COBR_SRC1,REG_COBR_SRC2,((((long)iCode&0x00fffffc)<<19)>>19) + (diss->IP)); + util::stream_format(stream, "%-8s%s,%s,0x%lx",NEM,REG_COBR_SRC1,REG_COBR_SRC2,((((s32)iCode&0x00fffffc)<<19)>>19) + (IP)); break; case 8: // target type - util::stream_format(diss->stream, "%-8s%08lx",NEM,((((long)iCode&0x00fffffc)<<8)>>8) + (diss->IP)); + util::stream_format(stream, "%-8s%08lx",NEM,((((s32)iCode&0x00fffffc)<<8)>>8) + (IP)); break; case 9: // no operands - util::stream_format(diss->stream, "%s",NEM); + util::stream_format(stream, "%s",NEM); break; case 10: // TEST type: register only - util::stream_format(diss->stream, "%s %s", NEM, REG_DST); + util::stream_format(stream, "%s %s", NEM, REG_DST); break; default: - diss->stream << "???"; + stream << "???"; break; } -} - + return IPinc | disflags | SUPPORTED; +} -CPU_DISASSEMBLE(i960) +u32 i960_disassembler::opcode_alignment() const { - disassemble_t dis(stream, pc, oprom); - - i960_disassemble(&dis); - - return dis.IPinc | dis.disflags | DASMFLAG_SUPPORTED; + return 4; } diff --git a/src/devices/cpu/i960/i960dis.h b/src/devices/cpu/i960/i960dis.h index 94e364fd666..2bc52697648 100644 --- a/src/devices/cpu/i960/i960dis.h +++ b/src/devices/cpu/i960/i960dis.h @@ -1,18 +1,33 @@ // license:BSD-3-Clause // copyright-holders:Farfetch'd, R. Belmont -#ifndef __I960DIS_H__ -#define __I960DIS_H__ +#ifndef MAME_CPU_I960_I960DIS_H +#define MAME_CPU_I960_I960DIS_H -struct disassemble_t +#pragma once + +class i960_disassembler : public util::disasm_interface { - disassemble_t(std::ostream &s, unsigned long ip, const uint8_t *opr) - : stream(s), IP(ip), oprom(opr) { } - - std::ostream &stream; // output stream - unsigned long IP; - unsigned long IPinc; - const uint8_t *oprom; - uint32_t disflags; +public: + i960_disassembler() = default; + virtual ~i960_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct mnemonic_t + { + const char *mnem; + unsigned short type; + }; + + static const mnemonic_t mnemonic[256]; + static const mnemonic_t mnem_reg[100]; + static const char *const constnames[32]; + static const char *const regnames[32]; + + std::string dis_decode_reg(u32 iCode, unsigned char cnt); + }; -#endif /* __I960DIS_H__ */ +#endif diff --git a/src/devices/cpu/ie15/ie15.cpp b/src/devices/cpu/ie15/ie15.cpp index e09d99c51a8..80c0fecdbe7 100644 --- a/src/devices/cpu/ie15/ie15.cpp +++ b/src/devices/cpu/ie15/ie15.cpp @@ -2,6 +2,7 @@ // copyright-holders:Sergey Svishchev #include "emu.h" #include "ie15.h" +#include "ie15dasm.h" #include "debugger.h" @@ -48,7 +49,7 @@ void ie15_cpu_device::device_start() { // find address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); // save state @@ -149,34 +150,12 @@ void ie15_cpu_device::state_string_export(const device_state_entry &entry, std:: } //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes +// create_disassembler //------------------------------------------------- -uint32_t ie15_cpu_device::disasm_min_opcode_bytes() const +util::disasm_interface *ie15_cpu_device::create_disassembler() { - return 1; -} - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t ie15_cpu_device::disasm_max_opcode_bytes() const -{ - return 2; -} - -//------------------------------------------------- -// disasm_disassemble - call the disassembly -// helper function -//------------------------------------------------- - -offs_t ie15_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( ie15 ); - return CPU_DISASSEMBLE_NAME(ie15)(nullptr, stream, pc, oprom, opram, 0); + return new ie15_disassembler; } //************************************************************************** diff --git a/src/devices/cpu/ie15/ie15.h b/src/devices/cpu/ie15/ie15.h index 2a39a663fed..f919d81c211 100644 --- a/src/devices/cpu/ie15/ie15.h +++ b/src/devices/cpu/ie15/ie15.h @@ -44,9 +44,7 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one(int opcode); @@ -76,7 +74,7 @@ protected: address_space *m_program; address_space *m_io; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; }; // device type definition diff --git a/src/devices/cpu/ie15/ie15dasm.cpp b/src/devices/cpu/ie15/ie15dasm.cpp index f13e8f52e44..1318c58d6d5 100644 --- a/src/devices/cpu/ie15/ie15dasm.cpp +++ b/src/devices/cpu/ie15/ie15dasm.cpp @@ -1,34 +1,37 @@ // license:BSD-3-Clause // copyright-holders:Sergey Svishchev #include "emu.h" +#include "ie15dasm.h" -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] +u32 ie15_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(ie15) +offs_t ie15_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; uint8_t op; unsigned PC = pc; - op = OP(pc++); + op = opcodes.r8(pc++); switch (op & 0xf0) { case 0x00: util::stream_format(stream, "add r%d", op & 0x0f); break; case 0x10: - util::stream_format(stream, "jmp $%04x", (((op & 0x0f) << 8) | ARG(pc)) + 1); + util::stream_format(stream, "jmp $%04x", (((op & 0x0f) << 8) | params.r8(pc)) + 1); pc+=1; break; case 0x20: - util::stream_format(stream, "ldc r%d, #$%02x", (op & 0x0f), ARG(pc)); + util::stream_format(stream, "ldc r%d, #$%02x", (op & 0x0f), params.r8(pc)); pc+=1; break; case 0x30: switch (op) { case 0x30: - util::stream_format(stream, "lca #$%02x", ARG(pc)); + util::stream_format(stream, "lca #$%02x", params.r8(pc)); pc+=1; break; case 0x33: @@ -123,5 +126,5 @@ CPU_DISASSEMBLE(ie15) break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; } diff --git a/src/devices/cpu/ie15/ie15dasm.h b/src/devices/cpu/ie15/ie15dasm.h new file mode 100644 index 00000000000..fb85a7a3d1c --- /dev/null +++ b/src/devices/cpu/ie15/ie15dasm.h @@ -0,0 +1,19 @@ +// license:BSD-3-Clause +// copyright-holders:Sergey Svishchev + +#ifndef MAME_CPU_IE15_IE15DASM_H +#define MAME_CPU_IE15_IE15DASM_H + +#pragma once + +class ie15_disassembler : public util::disasm_interface +{ +public: + ie15_disassembler() = default; + virtual ~ie15_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/jaguar/jagdasm.cpp b/src/devices/cpu/jaguar/jagdasm.cpp index 538f35b4b48..97c049594d6 100644 --- a/src/devices/cpu/jaguar/jagdasm.cpp +++ b/src/devices/cpu/jaguar/jagdasm.cpp @@ -9,27 +9,16 @@ ***************************************************************************/ #include "emu.h" -#include "jaguar.h" - - -/*************************************************************************** - MEMORY ACCESSORS -***************************************************************************/ - -#define ROPCODE(offs) ((oprom[offs] << 8) | oprom[(offs) + 1]) - +#include "jagdasm.h" /*************************************************************************** STATIC VARIABLES ***************************************************************************/ -static constexpr unsigned JAGUAR_VARIANT_GPU = 0; -static constexpr unsigned JAGUAR_VARIANT_DSP = 1; - -static const uint8_t convert_zero[32] = +const uint8_t jaguar_disassembler::convert_zero[32] = { 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }; -static const char *const condition[32] = +const char *const jaguar_disassembler::condition[32] = { "", "nz,", @@ -72,20 +61,18 @@ static const char *const condition[32] = CODE CODE ***************************************************************************/ -static inline char *signed_16bit(int16_t val) +std::string jaguar_disassembler::signed_16bit(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "$%x", val); - return temp; + return util::string_format("$%x", val); } -static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const uint8_t *oprom) +offs_t jaguar_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; - int op = ROPCODE(0); + int op = opcodes.r16(pc); int reg1 = (op >> 5) & 31; int reg2 = op & 31; int size = 2; @@ -126,12 +113,12 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui case 30: util::stream_format(stream, "cmp r%d,r%d", reg1, reg2); break; case 31: util::stream_format(stream, "cmpq %s,r%d", signed_16bit((int16_t)(reg1 << 11) >> 11), reg2);break; - case 32: if (variant == JAGUAR_VARIANT_GPU) + case 32: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "sat8 r%d", reg2); else util::stream_format(stream, "subqmod $%x,r%d", convert_zero[reg1], reg2); break; - case 33: if (variant == JAGUAR_VARIANT_GPU) + case 33: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "sat16 r%d", reg2); else util::stream_format(stream, "sat16s r%d", reg2); @@ -140,11 +127,11 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui case 35: util::stream_format(stream, "moveq %d,r%d", reg1, reg2); break; case 36: util::stream_format(stream, "moveta r%d,r%d", reg1, reg2); break; case 37: util::stream_format(stream, "movefa r%d,r%d", reg1, reg2); break; - case 38: util::stream_format(stream, "movei $%x,r%d", ROPCODE(2) | (ROPCODE(4)<<16), reg2); size = 6; break; + case 38: util::stream_format(stream, "movei $%x,r%d", opcodes.r32(pc+2), reg2); size = 6; break; case 39: util::stream_format(stream, "loadb (r%d),r%d", reg1, reg2); break; case 40: util::stream_format(stream, "loadw (r%d),r%d", reg1, reg2); break; case 41: util::stream_format(stream, "load (r%d),r%d", reg1, reg2); break; - case 42: if (variant == JAGUAR_VARIANT_GPU) + case 42: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "loadp (r%d),r%d", reg1, reg2); else util::stream_format(stream, "sat32s r%d", reg2); @@ -154,7 +141,7 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui case 45: util::stream_format(stream, "storeb r%d,(r%d)", reg2, reg1); break; case 46: util::stream_format(stream, "storew r%d,(r%d)", reg2, reg1); break; case 47: util::stream_format(stream, "store r%d,(r%d)", reg2, reg1); break; - case 48: if (variant == JAGUAR_VARIANT_GPU) + case 48: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "storep r%d,(r%d)", reg2, reg1); else util::stream_format(stream, "mirror r%d", reg2); @@ -172,12 +159,12 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui case 59: util::stream_format(stream, "load (r15+r%d),r%d", reg1, reg2); break; case 60: util::stream_format(stream, "store r%d,(r14+r%d)", reg2, reg1); break; case 61: util::stream_format(stream, "store r%d,(r15+r%d)", reg2, reg1); break; - case 62: if (variant == JAGUAR_VARIANT_GPU) + case 62: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, "sat24 r%d", reg2); else util::stream_format(stream, "illegal"); break; - case 63: if (variant == JAGUAR_VARIANT_GPU) + case 63: if (m_variant == JAGUAR_VARIANT_GPU) util::stream_format(stream, reg1 ? "unpack r%d" : "pack r%d", reg2); @@ -186,15 +173,14 @@ static unsigned dasmjag(int variant, std::ostream &stream, unsigned pc, const ui break; } - return size | flags | DASMFLAG_SUPPORTED; + return size | flags | SUPPORTED; } -CPU_DISASSEMBLE( jaguargpu ) +jaguar_disassembler::jaguar_disassembler(u32 variant) : m_variant(variant) { - return dasmjag(JAGUAR_VARIANT_GPU, stream, pc, oprom); } -CPU_DISASSEMBLE( jaguardsp ) +uint32_t jaguar_disassembler::opcode_alignment() const { - return dasmjag(JAGUAR_VARIANT_DSP, stream, pc, oprom); + return 2; } diff --git a/src/devices/cpu/jaguar/jagdasm.h b/src/devices/cpu/jaguar/jagdasm.h new file mode 100644 index 00000000000..232fda13b1f --- /dev/null +++ b/src/devices/cpu/jaguar/jagdasm.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + jagdasm.c + Disassembler for the portable Jaguar DSP emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_JAGUAR_JAGDASM_H +#define MAME_CPU_JAGUAR_JAGDASM_H + +#pragma once + +class jaguar_disassembler : public util::disasm_interface +{ +public: + static constexpr unsigned JAGUAR_VARIANT_GPU = 0; + static constexpr unsigned JAGUAR_VARIANT_DSP = 1; + + jaguar_disassembler(u32 variant); + virtual ~jaguar_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const uint8_t convert_zero[32]; + static const char *const condition[32]; + + u32 m_variant; + + static std::string signed_16bit(int16_t val); +}; + +#endif diff --git a/src/devices/cpu/jaguar/jaguar.cpp b/src/devices/cpu/jaguar/jaguar.cpp index 3b52ae1bfcc..b38f2c1fe97 100644 --- a/src/devices/cpu/jaguar/jaguar.cpp +++ b/src/devices/cpu/jaguar/jaguar.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "debugger.h" #include "jaguar.h" +#include "jagdasm.h" #define LOG_GPU_IO 0 @@ -337,7 +338,7 @@ void jaguar_cpu_device::device_start() init_tables(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_cpu_interrupt.resolve_safe(); save_item(NAME(m_r)); @@ -1436,16 +1437,12 @@ WRITE32_MEMBER( jaguardsp_cpu_device::ctrl_w ) } } - -offs_t jaguargpu_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *jaguargpu_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( jaguargpu ); - return CPU_DISASSEMBLE_NAME(jaguargpu)(this, stream, pc, oprom, opram, options); + return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_GPU); } - -offs_t jaguardsp_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *jaguardsp_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( jaguardsp ); - return CPU_DISASSEMBLE_NAME(jaguardsp)(this, stream, pc, oprom, opram, options); + return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_DSP); } diff --git a/src/devices/cpu/jaguar/jaguar.h b/src/devices/cpu/jaguar/jaguar.h index 1bc5ddf8d64..ac7f406621d 100644 --- a/src/devices/cpu/jaguar/jaguar.h +++ b/src/devices/cpu/jaguar/jaguar.h @@ -120,10 +120,6 @@ protected: // device_state_interface overrides 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - address_space_config m_program_config; /* core registers */ @@ -143,7 +139,7 @@ protected: int m_bankswitch_icount; devcb_write_line m_cpu_interrupt; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; uint32_t m_internal_ram_start; uint32_t m_internal_ram_end; @@ -249,7 +245,7 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -266,7 +262,7 @@ protected: virtual uint32_t execute_input_lines() const override { return 6; } virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; diff --git a/src/devices/cpu/lc8670/lc8670.cpp b/src/devices/cpu/lc8670/lc8670.cpp index c78a0acd4c8..34078ecb994 100644 --- a/src/devices/cpu/lc8670/lc8670.cpp +++ b/src/devices/cpu/lc8670/lc8670.cpp @@ -18,6 +18,7 @@ #include "emu.h" #include "debugger.h" #include "lc8670.h" +#include "lc8670dsm.h" //*************************************************************************** // DEBUGGING @@ -194,7 +195,7 @@ void lc8670_cpu_device::device_start() m_program = &space(AS_PROGRAM); m_data = &space(AS_DATA); m_io = &space(AS_IO); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // set our instruction counter m_icountptr = &m_icount; @@ -1777,3 +1778,8 @@ int lc8670_cpu_device::op_xor() return 1; } + +util::disasm_interface *lc8670_cpu_device::create_disassembler() +{ + return new lc8670_disassembler; +} diff --git a/src/devices/cpu/lc8670/lc8670.h b/src/devices/cpu/lc8670/lc8670.h index a6de4f7c98a..c0fddecb60b 100644 --- a/src/devices/cpu/lc8670/lc8670.h +++ b/src/devices/cpu/lc8670/lc8670.h @@ -115,9 +115,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - 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; + virtual util::disasm_interface *create_disassembler() override; private: // helpers @@ -142,7 +140,6 @@ private: void timer0_tick(bool ext_line = false); void timer1_tick(); void base_timer_tick(); - static void dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, const uint8_t *oprom, int &pos); // opcodes handlers int op_nop(); @@ -200,7 +197,7 @@ private: address_space * m_program; // program space (ROM or flash) address_space * m_data; // internal RAM/register address_space * m_io; // I/O ports - direct_read_data * m_direct; + direct_read_data<0> *m_direct; // timers static const device_timer_id BASE_TIMER = 1; @@ -240,33 +237,6 @@ private: // opcodes table typedef int (lc8670_cpu_device::*op_handler)(); static const op_handler s_opcode_table[80]; - - // disassembler - enum - { - OP_NULL, - OP_R8, - OP_R8RI, - OP_R16, - OP_RI, - OP_A12, - OP_A16, - OP_I8, - OP_B3, - OP_D9, - OP_D9B3, - OP_RII8 - }; - - // disasm table - struct dasm_entry - { - const char *str; - uint8_t arg1; - uint8_t arg2; - bool inv; - }; - static const dasm_entry s_dasm_table[80]; }; DECLARE_DEVICE_TYPE(LC8670, lc8670_cpu_device) diff --git a/src/devices/cpu/lc8670/lc8670dsm.cpp b/src/devices/cpu/lc8670/lc8670dsm.cpp index d1a223fc3a8..540b4d55377 100644 --- a/src/devices/cpu/lc8670/lc8670dsm.cpp +++ b/src/devices/cpu/lc8670/lc8670dsm.cpp @@ -7,10 +7,14 @@ ******************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "lc8670.h" +#include "lc8670dsm.h" -const lc8670_cpu_device::dasm_entry lc8670_cpu_device::s_dasm_table[] = +u32 lc8670_disassembler::opcode_alignment() const +{ + return 1; +} + +const lc8670_disassembler::dasm_entry lc8670_disassembler::s_dasm_table[] = { { "NOP" , OP_NULL, OP_NULL, 0 }, // 0x0* { "BR" , OP_R8 , OP_NULL, 0 }, @@ -94,7 +98,7 @@ const lc8670_cpu_device::dasm_entry lc8670_cpu_device::s_dasm_table[] = { "SET1", OP_D9B3, OP_NULL, 0 }, }; -void lc8670_cpu_device::dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, const uint8_t *oprom, int &pos) +void lc8670_disassembler::dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, const data_buffer &opcodes, offs_t &pos) { switch( arg ) { @@ -105,71 +109,88 @@ void lc8670_cpu_device::dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, c pc++; // fall through case OP_R8RI: - buffer += sprintf(buffer, "%04x", (pc + 1 + oprom[pos] - (oprom[pos]&0x80 ? 0x100 : 0)) & 0xffff); + buffer += sprintf(buffer, "%04x", (pc + 1 + opcodes.r8(pos) - (opcodes.r8(pos)&0x80 ? 0x100 : 0)) & 0xffff); pos++; break; case OP_R16: - buffer += sprintf(buffer, "%04x", (pc + 2 + ((oprom[pos+1]<<8) | oprom[pos])) & 0xffff); + buffer += sprintf(buffer, "%04x", (pc + 2 + ((opcodes.r8(pos+1)<<8) | opcodes.r8(pos))) & 0xffff); pos += 2; break; case OP_RI: buffer += sprintf(buffer, "@%x", op & 0x03); break; case OP_A12: - buffer += sprintf(buffer, "%04x", ((pc + 2) & 0xf000) | ((op & 0x10)<<7) | ((op & 0x07)<<8) | oprom[pos]); + buffer += sprintf(buffer, "%04x", ((pc + 2) & 0xf000) | ((op & 0x10)<<7) | ((op & 0x07)<<8) | opcodes.r8(pos)); pos++; break; case OP_A16: - buffer += sprintf(buffer, "%04x", (oprom[pos]<<8) | oprom[pos+1]); + buffer += sprintf(buffer, "%04x", (opcodes.r8(pos)<<8) | opcodes.r8(pos+1)); pos += 2; break; case OP_I8: - buffer += sprintf(buffer, "#$%02x", oprom[pos++]); + buffer += sprintf(buffer, "#$%02x", opcodes.r8(pos++)); break; case OP_B3: buffer += sprintf(buffer, "%x", op & 0x07); break; case OP_D9: - buffer += sprintf(buffer, "($%03x)", ((op & 0x01)<<8) | oprom[pos]); + buffer += sprintf(buffer, "($%03x)", ((op & 0x01)<<8) | opcodes.r8(pos)); pos++; break; case OP_D9B3: - buffer += sprintf(buffer, "($%03x)", ((op & 0x10)<<4) | oprom[pos]); + buffer += sprintf(buffer, "($%03x)", ((op & 0x10)<<4) | opcodes.r8(pos)); buffer += sprintf(buffer, ",%x", op & 0x07); pos++; break; case OP_RII8: buffer += sprintf(buffer, "@%x", op & 0x03); - buffer += sprintf(buffer, ",#$%02x", oprom[pos]); + buffer += sprintf(buffer, ",#$%02x", opcodes.r8(pos)); pos++; break; } } //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t lc8670_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +offs_t lc8670_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int pos = 0; + offs_t pos = pc; char arg1[16], arg2[16]; - uint8_t op = oprom[pos++]; + uint8_t op = opcodes.r8(pos); + + int idx; + switch (op & 0x0f) + { + case 0: case 1: + idx = op & 0x0f; + break; + case 2: case 3: + idx = 2; + break; + case 4: case 5: case 6: case 7: + idx = 3; + break; + default: + idx = 4; + break; + } - int op_idx = decode_op(op); + int op_idx = ((op>>4) & 0x0f) * 5 + idx; const dasm_entry *inst = &s_dasm_table[op_idx]; util::stream_format(stream, "%-8s", inst->str); - dasm_arg(op, inst->inv ? arg2 : arg1, pc+0, inst->arg1, oprom, pos); - dasm_arg(op, inst->inv ? arg1 : arg2, pc+1, inst->arg2, oprom, pos); + dasm_arg(op, inst->inv ? arg2 : arg1, pc+0, inst->arg1, opcodes, pos); + dasm_arg(op, inst->inv ? arg1 : arg2, pc+1, inst->arg2, opcodes, pos); stream << arg1; if (inst->arg2 != OP_NULL) stream << "," << arg2; - return pos; + return pos - pc; } diff --git a/src/devices/cpu/lc8670/lc8670dsm.h b/src/devices/cpu/lc8670/lc8670dsm.h new file mode 100644 index 00000000000..c59da2add6d --- /dev/null +++ b/src/devices/cpu/lc8670/lc8670dsm.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/****************************************************************************** + + Sanyo LC8670 disassembler + +******************************************************************************/ + +#ifndef MAME_CPU_LC8670_LC8670DSM_H +#define MAME_CPU_LC8670_LC8670DSM_H + +#pragma once + +class lc8670_disassembler : public util::disasm_interface +{ +public: + lc8670_disassembler() = default; + virtual ~lc8670_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // disassembler + enum + { + OP_NULL, + OP_R8, + OP_R8RI, + OP_R16, + OP_RI, + OP_A12, + OP_A16, + OP_I8, + OP_B3, + OP_D9, + OP_D9B3, + OP_RII8 + }; + + // disasm table + struct dasm_entry + { + const char *str; + uint8_t arg1; + uint8_t arg2; + bool inv; + }; + static const dasm_entry s_dasm_table[80]; + + void dasm_arg(uint8_t op, char *buffer, offs_t pc, int arg, const data_buffer &opcodes, offs_t &pos); +}; + +#endif diff --git a/src/devices/cpu/lh5801/5801dasm.cpp b/src/devices/cpu/lh5801/5801dasm.cpp index 2cf6f105b8d..f289f4760a0 100644 --- a/src/devices/cpu/lh5801/5801dasm.cpp +++ b/src/devices/cpu/lh5801/5801dasm.cpp @@ -9,104 +9,14 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" - -#include "lh5801.h" +#include "5801dasm.h" #if defined(SEC) #undef SEC #endif -namespace { - -class Entry -{ -public: - enum Ins - { - ILL, ILL2, PREFD, NOP, - - LDA, STA, LDI, LDX, STX, - LDE, SDE, LIN, SIN, - TIN, // (x++)->(y++) - ADC, ADI, ADR, SBC, SBI, - DCA, DCS, // bcd add and sub - CPA, CPI, CIN, // A compared with (x++) - AND, ANI, ORA, ORI, EOR, EAI, BIT, BII, - INC, DEC, - DRL, DRR, // digit rotates - ROL, ROR, - SHL, SHR, - AEX, // A nibble swap - - BCR, BCS, BHR, BHS, BZR, BZS, BVR, BVS, - BCH, LOP, // loop with ul - JMP, SJP, RTN, RTI, HLT, - VCR, VCS, VHR, VHS, VVS, VZR, VZS, - VMJ, VEJ, - PSH, POP, ATT, TTA, - REC, SEC, RIE, SIE, - - AM0, AM1, // load timer reg - ITA, // reads input port - ATP, // akku send to data bus - CDV, // clears internal divider - OFF, // clears bf flip flop - RDP, SDP,// reset display flip flop - RPU, SPU,// flip flop pu off - RPV, SPV // flip flop pv off - }; - - enum Adr - { - Imp, - Reg, - Vec, // imm byte (vector at 0xffxx) - Vej, - Imm, - RegImm, - Imm16, - RegImm16, - ME0, - ME0Imm, - Abs, - AbsImm, - ME1, - ME1Imm, - ME1Abs, - ME1AbsImm, - RelP, - RelM - }; - - enum Regs - { - RegNone, - A, - XL, XH, X, - YL, YH, Y, - UL, UH, U, - P, S - }; - const char *ins_name() const { return ins_names[ins]; } - const char *reg_name() const { return reg_names[reg]; } - - Ins ins; - Adr adr; - Regs reg; - - static const Entry table[0x100]; - static const Entry table_fd[0x100]; - -protected: - Entry(Ins i, Adr a = Imp, Regs r = RegNone) : ins(i), adr(a), reg(r) { } - - static const char *const ins_names[]; - static const char *const reg_names[]; -}; - -const char *const Entry::ins_names[]={ +const char *const lh5801_disassembler::ins_names[]={ "ILL", "ILL", nullptr, "NOP", "LDA", "STA", "LDI", "LDX", "STX", "LDE", "SDE", "LIN", "SIN", @@ -138,11 +48,11 @@ const char *const Entry::ins_names[]={ "RPV", "SPV", }; -const char *const Entry::reg_names[]= { +const char *const lh5801_disassembler::reg_names[]= { nullptr, "A", "XL", "XH", "X", "YL", "YH", "Y", "UL", "UH", "U", "P", "S" }; -const Entry Entry::table[0x100]={ +const lh5801_disassembler::Entry lh5801_disassembler::table[0x100]={ { SBC, Reg, XL }, // 0 { SBC, ME0, X }, { ADC, Reg, XL }, @@ -401,7 +311,7 @@ const Entry Entry::table[0x100]={ { ILL } }; -const Entry Entry::table_fd[0x100]={ +const lh5801_disassembler::Entry lh5801_disassembler::table_fd[0x100]={ { ILL2 }, // 0x00 { SBC, ME1, X }, { ILL2 }, @@ -660,90 +570,93 @@ const Entry Entry::table_fd[0x100]={ { ILL2 } }; -} // anonymous namespace +u32 lh5801_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(lh5801) +offs_t lh5801_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int pos = 0; + offs_t pos = pc; int oper; uint16_t absolut; const Entry *entry; int temp; - oper=oprom[pos++]; - entry=Entry::table+oper; + oper=opcodes.r8(pos++); + entry=table+oper; - if (Entry::table[oper].ins==Entry::PREFD) { - oper=oprom[pos++]; - entry=Entry::table_fd+oper; + if (table[oper].ins==PREFD) { + oper=opcodes.r8(pos++); + entry=table_fd+oper; } switch (entry->ins) { - case Entry::ILL: + case ILL: util::stream_format(stream, "%s %02x", entry->ins_name(), oper);break; - case Entry::ILL2: + case ILL2: util::stream_format(stream, "%s fd%02x", entry->ins_name(), oper);break; default: switch(entry->adr) { - case Entry::Imp: + case Imp: util::stream_format(stream, "%s", entry->ins_name());break; - case Entry::Reg: + case Reg: util::stream_format(stream, "%s %s", entry->ins_name(),entry->reg_name());break; - case Entry::RegImm: + case RegImm: util::stream_format(stream, "%s %s,%02x", entry->ins_name(), - entry->reg_name(), oprom[pos++]); + entry->reg_name(), opcodes.r8(pos++)); break; - case Entry::RegImm16: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case RegImm16: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s %s,%04x", entry->ins_name(),entry->reg_name(),absolut ); break; - case Entry::Vec: - util::stream_format(stream, "%s (ff%02x)", entry->ins_name(),oprom[pos++]);break; - case Entry::Vej: + case Vec: + util::stream_format(stream, "%s (ff%02x)", entry->ins_name(),opcodes.r8(pos++));break; + case Vej: util::stream_format(stream, "%s (ff%02x)", entry->ins_name(), oper);break; - case Entry::Imm: - util::stream_format(stream, "%s %02x", entry->ins_name(),oprom[pos++]);break; - case Entry::Imm16: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case Imm: + util::stream_format(stream, "%s %02x", entry->ins_name(),opcodes.r8(pos++));break; + case Imm16: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s %04x", entry->ins_name(),absolut);break; - case Entry::RelP: - temp=oprom[pos++]; + case RelP: + temp=opcodes.r8(pos++); util::stream_format(stream, "%s %04x", entry->ins_name(),pc+pos+temp);break; - case Entry::RelM: - temp=oprom[pos++]; + case RelM: + temp=opcodes.r8(pos++); util::stream_format(stream, "%s %04x", entry->ins_name(),pc+pos-temp);break; - case Entry::Abs: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case Abs: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s (%04x)", entry->ins_name(),absolut);break; - case Entry::ME1Abs: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case ME1Abs: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s #(%04x)", entry->ins_name(),absolut);break; - case Entry::AbsImm: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + case AbsImm: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s (%04x),%02x", entry->ins_name(),absolut, - oprom[pos++]);break; - case Entry::ME1AbsImm: - absolut=oprom[pos++]<<8; - absolut|=oprom[pos++]; + opcodes.r8(pos++));break; + case ME1AbsImm: + absolut=opcodes.r8(pos++)<<8; + absolut|=opcodes.r8(pos++); util::stream_format(stream, "%s #(%04x),%02x", entry->ins_name(),absolut, - oprom[pos++]);break; - case Entry::ME0: + opcodes.r8(pos++));break; + case ME0: util::stream_format(stream, "%s (%s)", entry->ins_name(),entry->reg_name());break; - case Entry::ME0Imm: - util::stream_format(stream, "%s (%s),%02x", entry->ins_name(),entry->reg_name(),oprom[pos++]); + case ME0Imm: + util::stream_format(stream, "%s (%s),%02x", entry->ins_name(),entry->reg_name(),opcodes.r8(pos++)); break; - case Entry::ME1: + case ME1: util::stream_format(stream, "%s #(%s)", entry->ins_name(),entry->reg_name());break; - case Entry::ME1Imm: - util::stream_format(stream, "%s #(%s),%02x", entry->ins_name(),entry->reg_name(),oprom[pos++]); + case ME1Imm: + util::stream_format(stream, "%s #(%s),%02x", entry->ins_name(),entry->reg_name(),opcodes.r8(pos++)); break; } } - return pos; + return pos - pc; } diff --git a/src/devices/cpu/lh5801/5801dasm.h b/src/devices/cpu/lh5801/5801dasm.h new file mode 100644 index 00000000000..9a6b66b0c5b --- /dev/null +++ b/src/devices/cpu/lh5801/5801dasm.h @@ -0,0 +1,110 @@ +// license:BSD-3-Clause +// copyright-holders:Peter Trauner +/***************************************************************************** + * + * disasm.c + * portable lh5801 emulator interface + * + * + *****************************************************************************/ + +#ifndef MAME_CPU_LH5801_5801DASM_H +#define MAME_CPU_LH5801_5801DASM_H + +#pragma once + +class lh5801_disassembler : public util::disasm_interface +{ +public: + lh5801_disassembler() = default; + virtual ~lh5801_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum Ins + { + ILL, ILL2, PREFD, NOP, + + LDA, STA, LDI, LDX, STX, + LDE, SDE, LIN, SIN, + TIN, // (x++)->(y++) + ADC, ADI, ADR, SBC, SBI, + DCA, DCS, // bcd add and sub + CPA, CPI, CIN, // A compared with (x++) + AND, ANI, ORA, ORI, EOR, EAI, BIT, BII, + INC, DEC, + DRL, DRR, // digit rotates + ROL, ROR, + SHL, SHR, + AEX, // A nibble swap + + BCR, BCS, BHR, BHS, BZR, BZS, BVR, BVS, + BCH, LOP, // loop with ul + JMP, SJP, RTN, RTI, HLT, + VCR, VCS, VHR, VHS, VVS, VZR, VZS, + VMJ, VEJ, + PSH, POP, ATT, TTA, + REC, SEC, RIE, SIE, + + AM0, AM1, // load timer reg + ITA, // reads input port + ATP, // akku send to data bus + CDV, // clears internal divider + OFF, // clears bf flip flop + RDP, SDP,// reset display flip flop + RPU, SPU,// flip flop pu off + RPV, SPV // flip flop pv off + }; + + enum Adr + { + Imp, + Reg, + Vec, // imm byte (vector at 0xffxx) + Vej, + Imm, + RegImm, + Imm16, + RegImm16, + ME0, + ME0Imm, + Abs, + AbsImm, + ME1, + ME1Imm, + ME1Abs, + ME1AbsImm, + RelP, + RelM + }; + + enum Regs + { + RegNone, + A, + XL, XH, X, + YL, YH, Y, + UL, UH, U, + P, S + }; + + struct Entry { + Ins ins; + Adr adr; + Regs reg; + + const char *ins_name() const { return ins_names[ins]; } + const char *reg_name() const { return reg_names[reg]; } + Entry(Ins i, Adr a = Imp, Regs r = RegNone) : ins(i), adr(a), reg(r) { } + }; + + static const char *const ins_names[]; + static const char *const reg_names[]; + + static const Entry table[0x100]; + static const Entry table_fd[0x100]; +}; + +#endif diff --git a/src/devices/cpu/lh5801/lh5801.cpp b/src/devices/cpu/lh5801/lh5801.cpp index 2b4a3708e44..6ba677d1e17 100644 --- a/src/devices/cpu/lh5801/lh5801.cpp +++ b/src/devices/cpu/lh5801/lh5801.cpp @@ -16,6 +16,7 @@ #include "emu.h" #include "lh5801.h" +#include "5801dasm.h" #include "debugger.h" @@ -91,7 +92,7 @@ void lh5801_cpu_device::device_start() { m_program = &space(AS_PROGRAM); m_io = &space(AS_IO); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_in_func.resolve_safe(0); @@ -256,8 +257,7 @@ void lh5801_cpu_device::execute_set_input(int irqline, int state) } } -offs_t lh5801_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *lh5801_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( lh5801 ); - return CPU_DISASSEMBLE_NAME(lh5801)(this, stream, pc, oprom, opram, options); + return new lh5801_disassembler; } diff --git a/src/devices/cpu/lh5801/lh5801.h b/src/devices/cpu/lh5801/lh5801.h index bc9ce08cdd6..2981bda7d0f 100644 --- a/src/devices/cpu/lh5801/lh5801.h +++ b/src/devices/cpu/lh5801/lh5801.h @@ -93,9 +93,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -105,7 +103,7 @@ private: address_space *m_program; //ME0 address_space *m_io; //ME1 - direct_read_data *m_direct; + direct_read_data<0> *m_direct; PAIR m_s; PAIR m_p; diff --git a/src/devices/cpu/lr35902/lr35902.cpp b/src/devices/cpu/lr35902/lr35902.cpp index cab2e820802..95a20eeaaf3 100644 --- a/src/devices/cpu/lr35902/lr35902.cpp +++ b/src/devices/cpu/lr35902/lr35902.cpp @@ -41,6 +41,7 @@ #include "emu.h" #include "lr35902.h" +#include "lr35902d.h" #include "debugger.h" /* Flag bit definitions */ @@ -231,14 +232,11 @@ void lr35902_cpu_device::device_reset() m_entering_halt = false; } - -offs_t lr35902_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *lr35902_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( lr35902 ); - return CPU_DISASSEMBLE_NAME(lr35902)(this, stream, pc, oprom, opram, options); + return new lr35902_disassembler; } - void lr35902_cpu_device::check_interrupts() { uint8_t irq = m_IE & m_IF; diff --git a/src/devices/cpu/lr35902/lr35902.h b/src/devices/cpu/lr35902/lr35902.h index 9364599be27..0d33bbbe548 100644 --- a/src/devices/cpu/lr35902/lr35902.h +++ b/src/devices/cpu/lr35902/lr35902.h @@ -89,9 +89,7 @@ protected: 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 1; } - 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; + virtual util::disasm_interface *create_disassembler() override; inline void cycles_passed(uint8_t cycles); inline uint8_t mem_read_byte(uint16_t addr); diff --git a/src/devices/cpu/lr35902/lr35902d.cpp b/src/devices/cpu/lr35902/lr35902d.cpp index a723cac408d..5b27f37778e 100644 --- a/src/devices/cpu/lr35902/lr35902d.cpp +++ b/src/devices/cpu/lr35902/lr35902d.cpp @@ -8,21 +8,9 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "lr35902.h" +#include "lr35902d.h" -enum e_mnemonics -{ - zADC, zADD, zAND, zBIT, zCALL, zCCF, zCP, - zCPL, zDAA, zDB, zDEC, zDI, zEI, zHLT, - zIN, zINC, zJP, zJR, zLD, zNOP, zOR, - zPOP, zPUSH, zRES, zRET, zRETI, zRL, zRLA, - zRLC, zRLCA, zRR, zRRA, zRRC, zRRCA, zRST, - zSBC, zSCF, zSET, zSLA, zSLL, zSRA, zSRL, - zSTOP, zSUB, zXOR, zSWAP -}; - -static const char *const s_mnemonic[] = +const char *const lr35902_disassembler::s_mnemonic[] = { "adc", "add", "and", "bit", "call","ccf", "cp", "cpl", "daa", "db", "dec", "di", "ei", "halt", @@ -33,26 +21,17 @@ static const char *const s_mnemonic[] = "stop","sub", "xor", "swap" }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t s_flags[] = { - 0 ,0 ,0 ,0 ,_OVER,0 ,0 , - 0 ,0 ,0 ,0 ,0 ,0 ,_OVER, - 0 ,0 ,0 ,0 ,0 ,0 ,0 , - 0 ,0 ,0 ,_OUT ,_OUT ,0 ,0 , - 0 ,0 ,0 ,0 ,0 ,0 ,_OVER, - 0 ,0 ,0 ,0 ,0 ,0 ,0 , - _OVER,0 ,0 ,0 -}; - -struct lr35902dasm -{ - uint8_t mnemonic; - const char *arguments; +const uint32_t lr35902_disassembler::s_flags[] = { + 0 ,0 ,0 ,0 ,STEP_OVER,0 ,0 , + 0 ,0 ,0 ,0 ,0 ,0 ,STEP_OVER, + 0 ,0 ,0 ,0 ,0 ,0 ,0 , + 0 ,0 ,0 ,STEP_OUT ,STEP_OUT ,0 ,0 , + 0 ,0 ,0 ,0 ,0 ,0 ,STEP_OVER, + 0 ,0 ,0 ,0 ,0 ,0 ,0 , + STEP_OVER,0 ,0 ,0 }; -static const lr35902dasm mnemonic_cb[256] = { +const lr35902_disassembler::lr35902dasm lr35902_disassembler::mnemonic_cb[256] = { {zRLC,"b"}, {zRLC,"c"}, {zRLC,"d"}, {zRLC,"e"}, {zRLC,"h"}, {zRLC,"l"}, {zRLC,"(hl)"}, {zRLC,"a"}, {zRRC,"b"}, {zRRC,"c"}, {zRRC,"d"}, {zRRC,"e"}, @@ -119,7 +98,7 @@ static const lr35902dasm mnemonic_cb[256] = { {zSET,"7,h"}, {zSET,"7,l"}, {zSET,"7,(hl)"},{zSET,"7,a"} }; -static const lr35902dasm mnemonic_main[256]= { +const lr35902_disassembler::lr35902dasm lr35902_disassembler::mnemonic_main[256]= { {zNOP,nullptr}, {zLD,"bc,N"}, {zLD,"(bc),a"}, {zINC,"bc"}, {zINC,"b"}, {zDEC,"b"}, {zLD,"b,B"}, {zRLCA,nullptr}, {zLD,"(W),sp"}, {zADD,"hl,bc"}, {zLD,"a,(bc)"}, {zDEC,"bc"}, @@ -186,11 +165,16 @@ static const lr35902dasm mnemonic_main[256]= { {zDB,"fc"}, {zDB,"fd"}, {zCP,"B"}, {zRST,"V"} }; +u32 lr35902_disassembler::opcode_alignment() const +{ + return 1; +} + /**************************************************************************** * Disassemble opcode at PC and return number of bytes it takes ****************************************************************************/ -CPU_DISASSEMBLE(lr35902) +offs_t lr35902_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const lr35902dasm *d; const char /* *symbol,*/ *src; @@ -201,11 +185,11 @@ CPU_DISASSEMBLE(lr35902) //symbol = nullptr; - op = oprom[pos++]; + op = opcodes.r8(pos++); op1 = 0; /* keep GCC happy */ if( op == 0xcb ) { - op = oprom[pos++]; + op = opcodes.r8(pos++); d = &mnemonic_cb[op]; } else { d = &mnemonic_main[op]; @@ -220,12 +204,12 @@ CPU_DISASSEMBLE(lr35902) util::stream_format(stream, "$%02X,$%02X", op, op1); break; case 'A': - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; case 'B': /* Byte op arg */ - ea = opram[pos++]; + ea = params.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case '(': /* Memory byte at (...) */ @@ -235,7 +219,7 @@ CPU_DISASSEMBLE(lr35902) } else if( !strncmp( src, "(hl)", 4) ) { } else if( !strncmp( src, "(sp)", 4) ) { } else if( !strncmp( src, "(F)", 3) ) { - ea = 0xFF00 + opram[pos++]; + ea = 0xFF00 + params.r8(pos++); util::stream_format(stream, "$%02X", ea); src++; } else if( !strncmp( src, "(C)", 3) ) { @@ -244,12 +228,12 @@ CPU_DISASSEMBLE(lr35902) } break; case 'N': /* Immediate 16 bit */ - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; case 'O': /* Offset relative to PC */ - offset = (int8_t) opram[pos++]; + offset = (int8_t) params.r8(pos++); util::stream_format(stream, "$%04X", pc + offset + 2); break; case 'V': /* Restart vector */ @@ -257,7 +241,7 @@ CPU_DISASSEMBLE(lr35902) util::stream_format(stream, "$%02X", ea); break; case 'W': /* Memory address word */ - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; @@ -271,5 +255,5 @@ CPU_DISASSEMBLE(lr35902) util::stream_format(stream, "%s", s_mnemonic[d->mnemonic]); } - return pos | s_flags[d->mnemonic] | DASMFLAG_SUPPORTED; + return pos | s_flags[d->mnemonic] | SUPPORTED; } diff --git a/src/devices/cpu/lr35902/lr35902d.h b/src/devices/cpu/lr35902/lr35902d.h new file mode 100644 index 00000000000..550a8bdaef8 --- /dev/null +++ b/src/devices/cpu/lr35902/lr35902d.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/***************************************************************************** + * + * lr35902d.c + * Portable Sharp LR35902 disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_LR35902_LR35902DASM_H +#define MAME_CPU_LR35902_LR35902DASM_H + +#pragma once + +class lr35902_disassembler : public util::disasm_interface +{ +public: + lr35902_disassembler() = default; + virtual ~lr35902_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + zADC, zADD, zAND, zBIT, zCALL, zCCF, zCP, + zCPL, zDAA, zDB, zDEC, zDI, zEI, zHLT, + zIN, zINC, zJP, zJR, zLD, zNOP, zOR, + zPOP, zPUSH, zRES, zRET, zRETI, zRL, zRLA, + zRLC, zRLCA, zRR, zRRA, zRRC, zRRCA, zRST, + zSBC, zSCF, zSET, zSLA, zSLL, zSRA, zSRL, + zSTOP, zSUB, zXOR, zSWAP + }; + + struct lr35902dasm + { + uint8_t mnemonic; + const char *arguments; + }; + + static const char *const s_mnemonic[]; + static const uint32_t s_flags[]; + static const lr35902dasm mnemonic_cb[256]; + static const lr35902dasm mnemonic_main[256]; +}; + +#endif diff --git a/src/devices/cpu/m37710/m37710.cpp b/src/devices/cpu/m37710/m37710.cpp index 1c6b78f1b06..53bb01301eb 100644 --- a/src/devices/cpu/m37710/m37710.cpp +++ b/src/devices/cpu/m37710/m37710.cpp @@ -939,21 +939,20 @@ void m37710_cpu_device::m37710_set_irq_line(int line, int state) (this->*m_set_line)(line, state); } -/* Disassemble an instruction */ -#include "m7700ds.h" - - -CPU_DISASSEMBLE( m37710 ) +bool m37710_cpu_device::get_m_flag() const { - return m7700_disassemble(stream, (pc&0xffff), pc>>16, oprom, 0, 0); + return FLAG_M; } - -offs_t m37710_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +bool m37710_cpu_device::get_x_flag() const { - return m7700_disassemble(stream, (pc&0xffff), pc>>16, oprom, FLAG_M, FLAG_X); + return FLAG_X; } +util::disasm_interface *m37710_cpu_device::create_disassembler() +{ + return new m7700_disassembler(this); +} void m37710_cpu_device::m37710_restore_state() { @@ -999,7 +998,7 @@ void m37710_cpu_device::device_start() memset(m_m37710_regs, 0, sizeof(m_m37710_regs)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_ICount = 0; diff --git a/src/devices/cpu/m37710/m37710.h b/src/devices/cpu/m37710/m37710.h index 69e2ccffb26..4a52bfd8bcc 100644 --- a/src/devices/cpu/m37710/m37710.h +++ b/src/devices/cpu/m37710/m37710.h @@ -12,6 +12,9 @@ M37710 CPU Emulator v0.1 */ +#include "m7700ds.h" + + /* ======================================================================== */ /* =============================== DEFINES ================================ */ /* ======================================================================== */ @@ -94,7 +97,7 @@ enum #define M37710_INTERNAL_ROM_REGION "internal" #define M37710_INTERNAL_ROM(_tag) (_tag ":" M37710_INTERNAL_ROM_REGION) -class m37710_cpu_device : public cpu_device +class m37710_cpu_device : public cpu_device, public m7700_disassembler::config { public: DECLARE_READ8_MEMBER( m37710_internal_r ); @@ -124,9 +127,9 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_m_flag() const override; + virtual bool get_x_flag() const override; private: address_space_config m_program_config; @@ -168,7 +171,7 @@ private: uint32_t m_source; /* temp register */ uint32_t m_destination; /* temp register */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint32_t m_stopped; /* Sets how the CPU is stopped */ diff --git a/src/devices/cpu/m37710/m7700ds.cpp b/src/devices/cpu/m37710/m7700ds.cpp index ed81e320a3c..bf8f791935b 100644 --- a/src/devices/cpu/m37710/m7700ds.cpp +++ b/src/devices/cpu/m37710/m7700ds.cpp @@ -12,76 +12,9 @@ Based on G65C816 CPU Emulator by Karl Stenerud #include "emu.h" #include "m7700ds.h" -#ifdef SEC -#undef SEC -#endif - #define ADDRESS_24BIT(A) ((A)&0xffffff) -namespace { - -class m7700_opcode_struct -{ -public: - bool is_call() const { return m_name == op::JSR; } - bool is_return() const { return (m_name == op::RTS) || (m_name == op::RTI); } - const char *name() const { return s_opnames[unsigned(m_name)]; } - - static const m7700_opcode_struct &get(unsigned char ins) { return s_opcodes[ins]; } - static const m7700_opcode_struct &get_prefix42(unsigned char ins) { return s_opcodes_prefix42[ins]; } - static const m7700_opcode_struct &get_prefix89(unsigned char ins) { return s_opcodes_prefix89[ins]; } - - unsigned char flag; - unsigned char ea; - -protected: - enum class op : unsigned - { - ADC , AND , ASL , BCC , BCS , BEQ , BIT , BMI , BNE , BPL , BRA , - BRK , BRL , BVC , BVS , CLC , CLD , CLI , CLV , CMP , COP , CPX , - CPY , DEA , DEC , DEX , DEY , EOR , INA , INC , INX , INY , JML , - JMP , JSL , JSR , LDA , LDX , LDY , LSR , MVN , MVP , NOP , ORA , - PEA , PEI , PER , PHA , PHT , PHD , PHK , PHP , PHX , PHY , PLA , - PLB , PLD , PLP , PLX , PLY , CLP , ROL , ROR , RTI , RTL , RTS , - SBC , SEC , SED , SEI , SEP , STA , STP , STX , STY , STZ , TAX , - TAY , TCS , TCD , TDC , TRB , TSB , TSC , TSX , TXA , TXS , TXY , - TYA , TYX , WAI , WDM , XBA , XCE , MPY , DIV , MPYS, DIVS, RLA , - EXTS, EXTZ , LDT , LDM , UNK , SEB , SEM , CLM , STB , LDB , ADCB , - SBCB, EORB , TBX , CMPB, INB , DEB , TXB , TYB , LSRB, ORB , CLB , - BBC, BBS, TBY, ANDB, PUL , PSH , PLAB, XAB , PHB - }; - - m7700_opcode_struct(op n, unsigned char f, unsigned char e) - : flag(f) - , ea(e) - , m_name(n) - { - } - - op m_name; - - static const char *const s_opnames[]; - static const m7700_opcode_struct s_opcodes[256]; - static const m7700_opcode_struct s_opcodes_prefix42[256]; - static const m7700_opcode_struct s_opcodes_prefix89[256]; -}; - -enum -{ - IMP , ACC , RELB, RELW, IMM , A , AI , AL , ALX , AX , AXI , - AY , D , DI , DIY , DLI , DLIY, DX , DXI , DY , S , SIY , - SIG , MVN , MVP , PEA , PEI , PER , LDM4, LDM5, LDM4X, LDM5X, - BBCD, BBCA, ACCB -}; - -enum -{ - I, /* ignore */ - M, /* check m bit */ - X /* check x bit */ -}; - -const char *const m7700_opcode_struct::s_opnames[] = +const char *const m7700_disassembler::s_opnames[] = { "ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL", "BRA", "BRK", "BRL", "BVC", "BVS", "CLC", "CLD", "CLI", "CLV", "CMP", "COP", "CPX", @@ -97,7 +30,7 @@ const char *const m7700_opcode_struct::s_opnames[] = "BBC", "BBS", "TBY", "ANDB","PUL", "PSH", "PLB", "XAB", "PHB", }; -const m7700_opcode_struct m7700_opcode_struct::s_opcodes[256] = +const m7700_disassembler::m7700_opcode_struct m7700_disassembler::s_opcodes[256] = { {op::BRK, I, SIG }, {op::ORA, M, DXI }, {op::UNK, I, SIG }, {op::ORA, M, S }, {op::SEB, M, LDM4 }, {op::ORA, M, D }, {op::ASL, M, D }, {op::ORA, M, DLI }, @@ -180,7 +113,7 @@ const m7700_opcode_struct m7700_opcode_struct::s_opcodes[256] = {op::JSR, I, AXI }, {op::SBC, M, AX }, {op::INC, M, AX }, {op::SBC, M, ALX } }; -const m7700_opcode_struct m7700_opcode_struct::s_opcodes_prefix42[256] = +const m7700_disassembler::m7700_opcode_struct m7700_disassembler::s_opcodes_prefix42[256] = { {op::BRK, I, SIG }, {op::ORB, M, DXI }, {op::COP, I, SIG }, {op::ORB, M, S }, {op::TSB, M, D }, {op::ORB, M, D }, {op::ASL, M, D }, {op::ORB, M, DLI }, @@ -263,7 +196,7 @@ const m7700_opcode_struct m7700_opcode_struct::s_opcodes_prefix42[256] = {op::JSR, I, AXI }, {op::SBCB,M, AX }, {op::INC, M, AX }, {op::SBCB, M, ALX } }; -const m7700_opcode_struct m7700_opcode_struct::s_opcodes_prefix89[256] = +const m7700_disassembler::m7700_opcode_struct m7700_disassembler::s_opcodes_prefix89[256] = { {op::BRK, I, SIG }, {op::MPY, M, DXI }, {op::COP, I, SIG }, {op::MPY, M, S }, {op::TSB, M, D }, {op::MPY, M, D }, {op::ASL, M, D }, {op::MPY, M, DLI }, @@ -346,71 +279,54 @@ const m7700_opcode_struct m7700_opcode_struct::s_opcodes_prefix89[256] = {op::JSR, I, AXI }, {op::SBC, M, AX }, {op::INC, M, AX }, {op::SBC, M, ALX } }; -} // anonymous namespace - -static inline unsigned int read_8(const uint8_t *oprom, unsigned int offset) +inline std::string m7700_disassembler::int_8_str(unsigned int val) { - return oprom[offset]; -} - -static inline unsigned int read_16(const uint8_t *oprom, unsigned int offset) -{ - unsigned int val = read_8(oprom, offset); - return val | (read_8(oprom, offset+1)<<8); -} - -static inline unsigned int read_24(const uint8_t *oprom, unsigned int offset) -{ - unsigned int val = read_8(oprom, offset); - val |= (read_8(oprom, offset+1)<<8); - return val | (read_8(oprom, offset+2)<<16); -} - -static inline char* int_8_str(unsigned int val) -{ - static char str[20]; - val &= 0xff; if(val & 0x80) - sprintf(str, "-$%x", (0-val) & 0x7f); + return util::string_format("-$%x", (0-val) & 0xff); else - sprintf(str, "$%x", val & 0x7f); - - return str; + return util::string_format("$%x", val & 0xff); } -static inline char* int_16_str(unsigned int val) +inline std::string m7700_disassembler::int_16_str(unsigned int val) { - static char str[20]; - val &= 0xffff; if(val & 0x8000) - sprintf(str, "-$%x", (0-val) & 0x7fff); + return util::string_format("-$%x", (0-val) & 0xffff); else - sprintf(str, "$%x", val & 0x7fff); + return util::string_format("$%x", val & 0xffff); +} - return str; +m7700_disassembler::m7700_disassembler(config *conf) : m_config(conf) +{ } +u32 m7700_disassembler::opcode_alignment() const +{ + return 1; +} -int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, const uint8_t *oprom, int m_flag, int x_flag) +offs_t m7700_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned int instruction; const m7700_opcode_struct *opcode; int var; signed char varS; int length = 1; - unsigned int address; //unsigned int start; uint32_t flags = 0; - pb <<= 16; + offs_t address = pc; + u32 pb = pc & 0xffff0000; + pc &= 0xffff; address = pc | pb; - //start = address; - instruction = read_8(oprom,0); + instruction = opcodes.r8(address); + + int m_flag = m_config->get_m_flag(); + int x_flag = m_config->get_x_flag(); // check for prefixes switch (instruction) @@ -418,16 +334,14 @@ int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, co case 0x42: address++; length++; - oprom++; - instruction = read_8(oprom,0); + instruction = opcodes.r8(address); opcode = &m7700_opcode_struct::get_prefix42(instruction); break; case 0x89: address++; length++; - oprom++; - instruction = read_8(oprom,0); + instruction = opcodes.r8(address); opcode = &m7700_opcode_struct::get_prefix89(instruction); break; @@ -437,9 +351,9 @@ int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, co } if (opcode->is_call()) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (opcode->is_return()) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; stream << opcode->name(); @@ -454,189 +368,184 @@ int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, co util::stream_format(stream, " B"); break; case RELB: - varS = read_8(oprom,1); + varS = opcodes.r8(address + 1); length++; util::stream_format(stream, " %06x (%s)", pb | ((pc + length + varS)&0xffff), int_8_str(varS)); break; case RELW: case PER : - var = read_16(oprom,1); + var = opcodes.r16(address + 1); length += 2; util::stream_format(stream, " %06x (%s)", pb | ((pc + length + var)&0xffff), int_16_str(var)); break; case IMM : if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x", read_16(oprom,1)); + util::stream_format(stream, " #$%04x", opcodes.r16(address + 1)); length += 2; } else { - util::stream_format(stream, " #$%02x", read_8(oprom,1)); + util::stream_format(stream, " #$%02x", opcodes.r8(address + 1)); length++; } break; case BBCD: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - varS = read_8(oprom,4); + varS = opcodes.r8(address + 4); length += 4; - util::stream_format(stream, " #$%04x, $%02x, %06x (%s)", read_16(oprom,2), read_8(oprom,1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); + util::stream_format(stream, " #$%04x, $%02x, %06x (%s)", opcodes.r16(address + 2), opcodes.r8(address + 1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); } else { - varS = read_8(oprom,3); + varS = opcodes.r8(address + 3); length += 3; - util::stream_format(stream, " #$%02x, $%02x, %06x (%s)", read_8(oprom,2), read_8(oprom,1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); + util::stream_format(stream, " #$%02x, $%02x, %06x (%s)", opcodes.r8(address + 2), opcodes.r8(address + 1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); } break; case BBCA: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { length += 5; - varS = read_8(oprom,5); - util::stream_format(stream, " #$%04x, $%04x, %06x (%s)", read_16(oprom,3), read_16(oprom,1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); + varS = opcodes.r8(address + 5); + util::stream_format(stream, " #$%04x, $%04x, %06x (%s)", opcodes.r16(address + 3), opcodes.r16(address + 1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); } else { length += 4; - varS = read_8(oprom,4); - util::stream_format(stream, " #$%02x, $%04x, %06x (%s)", read_8(oprom,3), read_16(oprom,1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); + varS = opcodes.r8(address + 4); + util::stream_format(stream, " #$%02x, $%04x, %06x (%s)", opcodes.r8(address + 3), opcodes.r16(address + 1), pb | ((pc + length + varS)&0xffff), int_8_str(varS)); } break; case LDM4: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x, $%02x", read_16(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " #$%04x, $%02x", opcodes.r16(address + 2), opcodes.r8(address + 1)); length += 3; } else { - util::stream_format(stream, " #$%02x, $%02x", read_8(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " #$%02x, $%02x", opcodes.r8(address + 2), opcodes.r8(address + 1)); length += 2; } break; case LDM5: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x, $%04x", read_16(oprom,3), read_16(oprom,1)); + util::stream_format(stream, " #$%04x, $%04x", opcodes.r16(address + 3), opcodes.r16(address + 1)); length += 4; } else { - util::stream_format(stream, " #$%02x, $%04x", read_8(oprom,3), read_16(oprom,1)); + util::stream_format(stream, " #$%02x, $%04x", opcodes.r8(address + 3), opcodes.r16(address + 1)); length += 3; } break; case LDM4X: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x, $%02x, X", read_16(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " #$%04x, $%02x, X", opcodes.r16(address + 2), opcodes.r8(address + 1)); length += 3; } else { - util::stream_format(stream, " #$%02x, $%02x, X", read_8(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " #$%02x, $%02x, X", opcodes.r8(address + 2), opcodes.r8(address + 1)); length += 2; } break; case LDM5X: if((opcode->flag == M && !m_flag) || (opcode->flag == X && !x_flag)) { - util::stream_format(stream, " #$%04x, $%04x, X", read_16(oprom,3), read_16(oprom,1)); + util::stream_format(stream, " #$%04x, $%04x, X", opcodes.r16(address + 3), opcodes.r16(address + 1)); length += 4; } else { - util::stream_format(stream, " #$%02x, $%04x, X", read_8(oprom,3), read_16(oprom,1)); + util::stream_format(stream, " #$%02x, $%04x, X", opcodes.r8(address + 3), opcodes.r16(address + 1)); length += 3; } break; case A : case PEA : - util::stream_format(stream, " $%04x", read_16(oprom,1)); + util::stream_format(stream, " $%04x", opcodes.r16(address + 1)); length += 2; break; case AI : - util::stream_format(stream, " ($%04x)", read_16(oprom,1)); + util::stream_format(stream, " ($%04x)", opcodes.r16(address + 1)); length += 2; break; case AL : - util::stream_format(stream, " $%06x", read_24(oprom,1)); + util::stream_format(stream, " $%06x", opcodes.r32(address + 1) & 0xffffff); length += 3; break; case ALX : - util::stream_format(stream, " $%06x,X", read_24(oprom,1)); + util::stream_format(stream, " $%06x,X", opcodes.r32(address + 1) & 0xffffff); length += 3; break; case AX : - util::stream_format(stream, " $%04x,X", read_16(oprom,1)); + util::stream_format(stream, " $%04x,X", opcodes.r16(address + 1)); length += 2; break; case AXI : - util::stream_format(stream, " ($%04x,X)", read_16(oprom,1)); + util::stream_format(stream, " ($%04x,X)", opcodes.r16(address + 1)); length += 2; break; case AY : - util::stream_format(stream, " $%04x,Y", read_16(oprom,1)); + util::stream_format(stream, " $%04x,Y", opcodes.r16(address + 1)); length += 2; break; case D : - util::stream_format(stream, " $%02x", read_8(oprom,1)); + util::stream_format(stream, " $%02x", opcodes.r8(address + 1)); length++; break; case DI : case PEI : - util::stream_format(stream, " ($%02x)", read_8(oprom,1)); + util::stream_format(stream, " ($%02x)", opcodes.r8(address + 1)); length++; break; case DIY : - util::stream_format(stream, " ($%02x),Y", read_8(oprom,1)); + util::stream_format(stream, " ($%02x),Y", opcodes.r8(address + 1)); length++; break; case DLI : - util::stream_format(stream, " [$%02x]", read_8(oprom,1)); + util::stream_format(stream, " [$%02x]", opcodes.r8(address + 1)); length++; break; case DLIY: - util::stream_format(stream, " [$%02x],Y", read_8(oprom,1)); + util::stream_format(stream, " [$%02x],Y", opcodes.r8(address + 1)); length++; break; case DX : - util::stream_format(stream, " $%02x,X", read_8(oprom,1)); + util::stream_format(stream, " $%02x,X", opcodes.r8(address + 1)); length++; break; case DXI : - util::stream_format(stream, " ($%02x,X)", read_8(oprom,1)); + util::stream_format(stream, " ($%02x,X)", opcodes.r8(address + 1)); length++; break; case DY : - util::stream_format(stream, " $%02x,Y", read_8(oprom,1)); + util::stream_format(stream, " $%02x,Y", opcodes.r8(address + 1)); length++; break; case S : - util::stream_format(stream, " %s,S", int_8_str(read_8(oprom,1))); + util::stream_format(stream, " %s,S", int_8_str(opcodes.r8(address + 1))); length++; break; case SIY : - util::stream_format(stream, " (%s,S),Y", int_8_str(read_8(oprom,1))); + util::stream_format(stream, " (%s,S),Y", int_8_str(opcodes.r8(address + 1))); length++; break; case SIG : - util::stream_format(stream, " #$%02x", read_8(oprom,1)); + util::stream_format(stream, " #$%02x", opcodes.r8(address + 1)); length++; break; case MVN : case MVP : - util::stream_format(stream, " $%02x, $%02x", read_8(oprom,2), read_8(oprom,1)); + util::stream_format(stream, " $%02x, $%02x", opcodes.r8(address + 2), opcodes.r8(address + 1)); length += 2; break; } - return length | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(m37710_generic) -{ - return m7700_disassemble(stream, (pc&0xffff), pc>>16, oprom, 0, 0); + return length | flags | SUPPORTED; } diff --git a/src/devices/cpu/m37710/m7700ds.h b/src/devices/cpu/m37710/m7700ds.h index 061070bf407..6a30eb1af61 100644 --- a/src/devices/cpu/m37710/m7700ds.h +++ b/src/devices/cpu/m37710/m7700ds.h @@ -18,6 +18,86 @@ All rights reserved. */ -int m7700_disassemble(std::ostream &stream, unsigned int pc, unsigned int pb, const uint8_t *oprom, int m_flag, int x_flag); +class m7700_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + + virtual bool get_m_flag() const = 0; + virtual bool get_x_flag() const = 0; + }; + + m7700_disassembler(config *conf); + virtual ~m7700_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum class op : unsigned + { + ADC , AND , ASL , BCC , BCS , BEQ , BIT , BMI , BNE , BPL , BRA , + BRK , BRL , BVC , BVS , CLC , CLD , CLI , CLV , CMP , COP , CPX , + CPY , DEA , DEC , DEX , DEY , EOR , INA , INC , INX , INY , JML , + JMP , JSL , JSR , LDA , LDX , LDY , LSR , MVN , MVP , NOP , ORA , + PEA , PEI , PER , PHA , PHT , PHD , PHK , PHP , PHX , PHY , PLA , + PLB , PLD , PLP , PLX , PLY , CLP , ROL , ROR , RTI , RTL , RTS , + SBC , SEC , SED , SEI , SEP , STA , STP , STX , STY , STZ , TAX , + TAY , TCS , TCD , TDC , TRB , TSB , TSC , TSX , TXA , TXS , TXY , + TYA , TYX , WAI , WDM , XBA , XCE , MPY , DIV , MPYS, DIVS, RLA , + EXTS, EXTZ , LDT , LDM , UNK , SEB , SEM , CLM , STB , LDB , ADCB , + SBCB, EORB , TBX , CMPB, INB , DEB , TXB , TYB , LSRB, ORB , CLB , + BBC, BBS, TBY, ANDB, PUL , PSH , PLAB, XAB , PHB + }; + + enum + { + IMP , ACC , RELB, RELW, IMM , A , AI , AL , ALX , AX , AXI , + AY , D , DI , DIY , DLI , DLIY, DX , DXI , DY , S , SIY , + SIG , MVN , MVP , PEA , PEI , PER , LDM4, LDM5, LDM4X, LDM5X, + BBCD, BBCA, ACCB + }; + + enum + { + I, /* ignore */ + M, /* check m bit */ + X /* check x bit */ + }; + + class m7700_opcode_struct + { + public: + bool is_call() const { return m_name == op::JSR; } + bool is_return() const { return (m_name == op::RTS) || (m_name == op::RTI); } + const char *name() const { return s_opnames[unsigned(m_name)]; } + + static const m7700_opcode_struct &get(unsigned char ins) { return s_opcodes[ins]; } + static const m7700_opcode_struct &get_prefix42(unsigned char ins) { return s_opcodes_prefix42[ins]; } + static const m7700_opcode_struct &get_prefix89(unsigned char ins) { return s_opcodes_prefix89[ins]; } + + unsigned char flag; + unsigned char ea; + op m_name; + + m7700_opcode_struct(op n, unsigned char f, unsigned char e) + : flag(f) + , ea(e) + , m_name(n) + { + } + }; + + static const char *const s_opnames[]; + static const m7700_opcode_struct s_opcodes[256]; + static const m7700_opcode_struct s_opcodes_prefix42[256]; + static const m7700_opcode_struct s_opcodes_prefix89[256]; + + config *m_config; + + std::string int_8_str(unsigned int val); + std::string int_16_str(unsigned int val); +}; #endif /* __M7700DS_H__ */ diff --git a/src/devices/cpu/m6502/deco16.cpp b/src/devices/cpu/m6502/deco16.cpp index 163403228d9..e5121676253 100644 --- a/src/devices/cpu/m6502/deco16.cpp +++ b/src/devices/cpu/m6502/deco16.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "deco16.h" +#include "deco16d.h" #define DECO16_VERBOSE 1 @@ -22,12 +23,11 @@ deco16_device::deco16_device(const machine_config &mconfig, const char *tag, dev { } -offs_t deco16_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *deco16_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new deco16_disassembler; } - void deco16_device::device_start() { if(direct_disabled) diff --git a/src/devices/cpu/m6502/deco16.h b/src/devices/cpu/m6502/deco16.h index c3f55764553..1c980b2e4c6 100644 --- a/src/devices/cpu/m6502/deco16.h +++ b/src/devices/cpu/m6502/deco16.h @@ -12,14 +12,14 @@ #define MAME_CPU_M6502_DECO16_H #include "m6502.h" +#include "deco16d.h" class deco16_device : public m6502_device { public: deco16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/deco16d.cpp b/src/devices/cpu/m6502/deco16d.cpp new file mode 100644 index 00000000000..8f126ef3023 --- /dev/null +++ b/src/devices/cpu/m6502/deco16d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + deco16d.cpp + + 6502, reverse-engineered DECO variant, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "deco16d.h" +#include "cpu/m6502/deco16d.hxx" + +deco16_disassembler::deco16_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/deco16d.h b/src/devices/cpu/m6502/deco16d.h new file mode 100644 index 00000000000..3658da9ea9a --- /dev/null +++ b/src/devices/cpu/m6502/deco16d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + deco16d.h + + 6502, reverse-engineered DECO variant, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_DECO16D_H +#define MAME_CPU_M6502_DECO16D_H + +#pragma once + +#include "m6502d.h" + +class deco16_disassembler : public m6502_base_disassembler +{ +public: + deco16_disassembler(); + virtual ~deco16_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m4510.cpp b/src/devices/cpu/m6502/m4510.cpp index 852d3e5807a..f3241497eb6 100644 --- a/src/devices/cpu/m6502/m4510.cpp +++ b/src/devices/cpu/m6502/m4510.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "m4510.h" +#include "m4510d.h" DEFINE_DEVICE_TYPE(M4510, m4510_device, "m4510", "M4510") @@ -18,17 +19,17 @@ m4510_device::m4510_device(const machine_config &mconfig, const char *tag, devic map_enable(0), nomap(false) { - program_config.m_addrbus_width = 20; + program_config.m_addr_width = 20; program_config.m_logaddr_width = 16; program_config.m_page_shift = 13; - sprogram_config.m_addrbus_width = 20; + sprogram_config.m_addr_width = 20; sprogram_config.m_logaddr_width = 16; sprogram_config.m_page_shift = 13; } -offs_t m4510_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m4510_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m4510_disassembler; } void m4510_device::device_start() diff --git a/src/devices/cpu/m6502/m4510.h b/src/devices/cpu/m6502/m4510.h index b093c8aeb56..a41a0620c93 100644 --- a/src/devices/cpu/m6502/m4510.h +++ b/src/devices/cpu/m6502/m4510.h @@ -19,9 +19,8 @@ class m4510_device : public m65ce02_device { public: m4510_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m4510d.cpp b/src/devices/cpu/m6502/m4510d.cpp new file mode 100644 index 00000000000..896a3f78124 --- /dev/null +++ b/src/devices/cpu/m6502/m4510d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m4510d.cpp + + 65ce02 with a mmu and a port, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m4510d.h" +#include "cpu/m6502/m4510d.hxx" + +m4510_disassembler::m4510_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m4510d.h b/src/devices/cpu/m6502/m4510d.h new file mode 100644 index 00000000000..1c025cfb8e7 --- /dev/null +++ b/src/devices/cpu/m6502/m4510d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m4510d.h + + 65ce02 with a mmu and a port, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M4510D_H +#define MAME_CPU_M6502_M4510D_H + +#pragma once + +#include "m6502d.h" + +class m4510_disassembler : public m6502_base_disassembler +{ +public: + m4510_disassembler(); + virtual ~m4510_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m6502.cpp b/src/devices/cpu/m6502/m6502.cpp index f498ca87771..2cbded54949 100644 --- a/src/devices/cpu/m6502/m6502.cpp +++ b/src/devices/cpu/m6502/m6502.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "debugger.h" #include "m6502.h" +#include "m6502d.h" DEFINE_DEVICE_TYPE(M6502, m6502_device, "m6502", "M6502") @@ -44,8 +45,8 @@ void m6502_device::init() mintf->program = &space(AS_PROGRAM); mintf->sprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : mintf->program; - mintf->direct = &mintf->program->direct(); - mintf->sdirect = &mintf->sprogram->direct(); + mintf->direct = mintf->program->direct<0>(); + mintf->sdirect = mintf->sprogram->direct<0>(); sync_w.resolve_safe(); @@ -453,179 +454,6 @@ void m6502_device::state_string_export(const device_state_entry &entry, std::str } } - -uint32_t m6502_device::disasm_min_opcode_bytes() const -{ - return 1; -} - -uint32_t m6502_device::disasm_max_opcode_bytes() const -{ - return 4; -} - -offs_t m6502_device::disassemble_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *table) -{ - const disasm_entry &e = table[oprom[0] | inst_state_base]; - uint32_t flags = e.flags | DASMFLAG_SUPPORTED; - util::stream_format(stream, "%s", e.opcode); - - switch(e.mode) { - case DASM_non: - flags |= 1; - break; - - case DASM_aba: - util::stream_format(stream, " $%02x%02x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_abx: - util::stream_format(stream, " $%02x%02x, x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_aby: - util::stream_format(stream, " $%02x%02x, y", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_acc: - util::stream_format(stream, " a"); - flags |= 1; - break; - - case DASM_adr: - util::stream_format(stream, " $%02x%02x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_bzp: - util::stream_format(stream, "%d $%02x", (oprom[0] >> 4) & 7, opram[1]); - flags |= 2; - break; - - case DASM_iax: - util::stream_format(stream, " ($%02x%02x, x)", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_idx: - util::stream_format(stream, " ($%02x, x)", opram[1]); - flags |= 2; - break; - - case DASM_idy: - util::stream_format(stream, " ($%02x), y", opram[1]); - flags |= 2; - break; - - case DASM_idz: - util::stream_format(stream, " ($%02x), z", opram[1]); - flags |= 2; - break; - - case DASM_imm: - util::stream_format(stream, " #$%02x", opram[1]); - flags |= 2; - break; - - case DASM_imp: - flags |= 1; - break; - - case DASM_ind: - util::stream_format(stream, " ($%02x%02x)", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_isy: - util::stream_format(stream, " ($%02x, s), y", opram[1]); - flags |= 2; - break; - - case DASM_iw2: - util::stream_format(stream, " #$%02x%02x", opram[2], opram[1]); - flags |= 3; - break; - - case DASM_iw3: - util::stream_format(stream, " #$%02x%02x%02x", opram[3], opram[2], opram[1]); - flags |= 4; - break; - - case DASM_rel: - util::stream_format(stream, " $%04x", (pc & 0xf0000) | uint16_t(pc + 2 + int8_t(opram[1]))); - flags |= 2; - break; - - case DASM_rw2: - util::stream_format(stream, " $%04x", (pc & 0xf0000) | uint16_t(pc + 2 + int16_t((opram[2] << 8) | opram[1]))); - flags |= 3; - break; - - case DASM_zpb: - util::stream_format(stream, "%d $%02x, $%04x", (oprom[0] >> 4) & 7, opram[1], (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(opram[2]))); - flags |= 3; - break; - - case DASM_zpg: - util::stream_format(stream, " $%02x", opram[1]); - flags |= 2; - break; - - case DASM_zpi: - util::stream_format(stream, " ($%02x)", opram[1]); - flags |= 2; - break; - - case DASM_zpx: - util::stream_format(stream, " $%02x, x", opram[1]); - flags |= 2; - break; - - case DASM_zpy: - util::stream_format(stream, " $%02x, y", opram[1]); - flags |= 2; - break; - - case DASM_imz: - util::stream_format(stream, " #$%02x, $%02x", opram[1], opram[2]); - flags |= 3; - break; - - case DASM_spg: - util::stream_format(stream, " \\$%02x", opram[1]); - flags |= 2; - break; - - case DASM_biz: - util::stream_format(stream, " %d, $%02x", (opram[0] >> 5) & 7, opram[1]); - flags |= 2; - break; - - case DASM_bzr: - util::stream_format(stream, " %d, $%02x, $%04x", (opram[0] >> 5) & 7, opram[1], (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(opram[2]))); - flags |= 3; - break; - - case DASM_bar: - util::stream_format(stream, " %d, a, $%04x", (opram[0] >> 5) & 7, (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(opram[1]))); - flags |= 2; - break; - - case DASM_bac: - util::stream_format(stream, " %d, a", (opram[0] >> 5) & 7); - flags |= 1; - break; - - default: - fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); - abort(); - } - return flags; -} - void m6502_device::prefetch() { sync = true; @@ -662,12 +490,11 @@ void m6502_device::set_nz(uint8_t v) P |= F_Z; } -offs_t m6502_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6502_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m6502_disassembler; } - uint8_t m6502_device::memory_interface::read_9(uint16_t adr) { return read(adr); diff --git a/src/devices/cpu/m6502/m6502.h b/src/devices/cpu/m6502/m6502.h index 71bc63a534e..8f5236818f9 100644 --- a/src/devices/cpu/m6502/m6502.h +++ b/src/devices/cpu/m6502/m6502.h @@ -41,7 +41,7 @@ protected: class memory_interface { public: address_space *program, *sprogram; - direct_read_data *direct, *sdirect; + direct_read_data<0> *direct, *sdirect; virtual ~memory_interface() {} virtual uint8_t read(uint16_t adr) = 0; @@ -68,50 +68,11 @@ protected: virtual uint8_t read_arg(uint16_t adr) override; }; - struct disasm_entry { - const char *opcode; - int mode; - offs_t flags; - }; - enum { STATE_RESET = 0xff00 }; enum { - DASM_non, /* no additional arguments */ - DASM_aba, /* absolute */ - DASM_abx, /* absolute + X */ - DASM_aby, /* absolute + Y */ - DASM_acc, /* accumulator */ - DASM_adr, /* absolute address (jmp,jsr) */ - DASM_bzp, /* zero page with bit selection */ - DASM_iax, /* indirect + X (65c02 jmp) */ - DASM_idx, /* zero page pre indexed */ - DASM_idy, /* zero page post indexed */ - DASM_idz, /* zero page post indexed (65ce02) */ - DASM_imm, /* immediate */ - DASM_imp, /* implicit */ - DASM_ind, /* indirect (jmp) */ - DASM_isy, /* zero page pre indexed sp and post indexed Y (65ce02) */ - DASM_iw2, /* immediate word (65ce02) */ - DASM_iw3, /* augment (65ce02) */ - DASM_rel, /* relative */ - DASM_rw2, /* relative word (65cs02, 65ce02) */ - DASM_zpb, /* zero page and branch (65c02 bbr, bbs) */ - DASM_zpg, /* zero page */ - DASM_zpi, /* zero page indirect (65c02) */ - DASM_zpx, /* zero page + X */ - DASM_zpy, /* zero page + Y */ - DASM_imz, /* load immediate byte, store to zero page address (M740) */ - DASM_spg, /* "special page": implied FF00 OR immediate value (M740)*/ - DASM_biz, /* bit, zero page (M740) */ - DASM_bzr, /* bit, zero page, relative offset (M740) */ - DASM_bar, /* bit, accumulator, relative offset (M740) */ - DASM_bac /* bit, accumulator (M740) */ - }; - - enum { F_N = 0x80, F_V = 0x40, F_E = 0x20, // 65ce02 @@ -145,9 +106,7 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config program_config, sprogram_config; @@ -170,9 +129,6 @@ protected: bool nmi_state, irq_state, apu_irq_state, v_state; bool irq_taken, sync, direct_disabled, inhibit_interrupts; - static const disasm_entry disasm_entries[0x100]; - - offs_t disassemble_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *table); uint8_t read(uint16_t adr) { return mintf->read(adr); } uint8_t read_9(uint16_t adr) { return mintf->read_9(adr); } void write(uint16_t adr, uint8_t val) { mintf->write(adr, val); } diff --git a/src/devices/cpu/m6502/m6502d.cpp b/src/devices/cpu/m6502/m6502d.cpp new file mode 100644 index 00000000000..89763113cde --- /dev/null +++ b/src/devices/cpu/m6502/m6502d.cpp @@ -0,0 +1,193 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6502d.cpp + + Mostek 6502, original NMOS variant, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m6502d.h" +#include "cpu/m6502/m6502d.hxx" + +m6502_base_disassembler::m6502_base_disassembler(const disasm_entry *_table) : table(_table) +{ +} + +u32 m6502_base_disassembler::get_instruction_bank() const +{ + return 0; +} + +u32 m6502_base_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t m6502_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + const disasm_entry &e = table[opcodes.r8(pc) | get_instruction_bank()]; + uint32_t flags = e.flags | SUPPORTED; + util::stream_format(stream, "%s", e.opcode); + + switch(e.mode) { + case DASM_non: + flags |= 1; + break; + + case DASM_aba: + util::stream_format(stream, " $%02x%02x", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_abx: + util::stream_format(stream, " $%02x%02x, x", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_aby: + util::stream_format(stream, " $%02x%02x, y", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_acc: + util::stream_format(stream, " a"); + flags |= 1; + break; + + case DASM_adr: + util::stream_format(stream, " $%02x%02x", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_bzp: + util::stream_format(stream, "%d $%02x", (opcodes.r8(pc) >> 4) & 7, params.r8(pc+1)); + flags |= 2; + break; + + case DASM_iax: + util::stream_format(stream, " ($%02x%02x, x)", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_idx: + util::stream_format(stream, " ($%02x, x)", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_idy: + util::stream_format(stream, " ($%02x), y", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_idz: + util::stream_format(stream, " ($%02x), z", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_imm: + util::stream_format(stream, " #$%02x", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_imp: + flags |= 1; + break; + + case DASM_ind: + util::stream_format(stream, " ($%02x%02x)", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_isy: + util::stream_format(stream, " ($%02x, s), y", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_iw2: + util::stream_format(stream, " #$%02x%02x", params.r8(pc+2), params.r8(pc+1)); + flags |= 3; + break; + + case DASM_iw3: + util::stream_format(stream, " #$%02x%02x%02x", params.r8(pc+3), params.r8(pc+2), params.r8(pc+1)); + flags |= 4; + break; + + case DASM_rel: + util::stream_format(stream, " $%04x", (pc & 0xf0000) | uint16_t(pc + 2 + int8_t(params.r8(pc+1)))); + flags |= 2; + break; + + case DASM_rw2: + util::stream_format(stream, " $%04x", (pc & 0xf0000) | uint16_t(pc + 2 + int16_t((params.r8(pc+2) << 8) | params.r8(pc+1)))); + flags |= 3; + break; + + case DASM_zpb: + util::stream_format(stream, "%d $%02x, $%04x", (opcodes.r8(pc) >> 4) & 7, params.r8(pc+1), (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(params.r8(pc+2)))); + flags |= 3; + break; + + case DASM_zpg: + util::stream_format(stream, " $%02x", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_zpi: + util::stream_format(stream, " ($%02x)", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_zpx: + util::stream_format(stream, " $%02x, x", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_zpy: + util::stream_format(stream, " $%02x, y", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_imz: + util::stream_format(stream, " #$%02x, $%02x", params.r8(pc+1), params.r8(pc+2)); + flags |= 3; + break; + + case DASM_spg: + util::stream_format(stream, " \\$%02x", params.r8(pc+1)); + flags |= 2; + break; + + case DASM_biz: + util::stream_format(stream, " %d, $%02x", (opcodes.r8(pc) >> 5) & 7, params.r8(pc+1)); + flags |= 2; + break; + + case DASM_bzr: + util::stream_format(stream, " %d, $%02x, $%04x", (opcodes.r8(pc) >> 5) & 7, params.r8(pc+1), (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(params.r8(pc+2)))); + flags |= 3; + break; + + case DASM_bar: + util::stream_format(stream, " %d, a, $%04x", (opcodes.r8(pc) >> 5) & 7, (pc & 0xf0000) | uint16_t(pc + 3 + int8_t(params.r8(pc+1)))); + flags |= 2; + break; + + case DASM_bac: + util::stream_format(stream, " %d, a", (opcodes.r8(pc) >> 5) & 7); + flags |= 1; + break; + + default: + fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); + abort(); + } + return flags; +} + +m6502_disassembler::m6502_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m6502d.h b/src/devices/cpu/m6502/m6502d.h new file mode 100644 index 00000000000..7b23417f753 --- /dev/null +++ b/src/devices/cpu/m6502/m6502d.h @@ -0,0 +1,81 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6502d.h + + Mostek 6502, original NMOS variant, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M6502D_H +#define MAME_CPU_M6502_M6502D_H + +#pragma once + +class m6502_base_disassembler : public util::disasm_interface +{ +public: + struct disasm_entry { + const char *opcode; + int mode; + offs_t flags; + }; + + m6502_base_disassembler(const disasm_entry *table); + virtual ~m6502_base_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum { + DASM_non, /* no additional arguments */ + DASM_aba, /* absolute */ + DASM_abx, /* absolute + X */ + DASM_aby, /* absolute + Y */ + DASM_acc, /* accumulator */ + DASM_adr, /* absolute address (jmp,jsr) */ + DASM_bzp, /* zero page with bit selection */ + DASM_iax, /* indirect + X (65c02 jmp) */ + DASM_idx, /* zero page pre indexed */ + DASM_idy, /* zero page post indexed */ + DASM_idz, /* zero page post indexed (65ce02) */ + DASM_imm, /* immediate */ + DASM_imp, /* implicit */ + DASM_ind, /* indirect (jmp) */ + DASM_isy, /* zero page pre indexed sp and post indexed Y (65ce02) */ + DASM_iw2, /* immediate word (65ce02) */ + DASM_iw3, /* augment (65ce02) */ + DASM_rel, /* relative */ + DASM_rw2, /* relative word (65cs02, 65ce02) */ + DASM_zpb, /* zero page and branch (65c02 bbr, bbs) */ + DASM_zpg, /* zero page */ + DASM_zpi, /* zero page indirect (65c02) */ + DASM_zpx, /* zero page + X */ + DASM_zpy, /* zero page + Y */ + DASM_imz, /* load immediate byte, store to zero page address (M740) */ + DASM_spg, /* "special page": implied FF00 OR immediate value (M740)*/ + DASM_biz, /* bit, zero page (M740) */ + DASM_bzr, /* bit, zero page, relative offset (M740) */ + DASM_bar, /* bit, accumulator, relative offset (M740) */ + DASM_bac /* bit, accumulator (M740) */ + }; + + virtual u32 get_instruction_bank() const; + +private: + const disasm_entry *table; +}; + +class m6502_disassembler : public m6502_base_disassembler +{ +public: + m6502_disassembler(); + virtual ~m6502_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m6502make.py b/src/devices/cpu/m6502/m6502make.py index 8bcd85f8e21..b874b7c5ba9 100755 --- a/src/devices/cpu/m6502/m6502make.py +++ b/src/devices/cpu/m6502/m6502make.py @@ -6,7 +6,7 @@ from __future__ import print_function USAGE = """ Usage: -%s device_name {opc.lst|-} disp.lst device.inc +%s prefix {opc.lst|-} disp.lst device.inc deviced.inc """ import sys import logging @@ -59,7 +59,7 @@ def emit(f, text): print(text, file=f) FULL_PROLOG="""\ -void %(device)s::%(opcode)s_full() +void %(device)s_device::%(opcode)s_full() { """ @@ -82,7 +82,7 @@ FULL_NONE="""\ """ PARTIAL_PROLOG="""\ -void %(device)s::%(opcode)s_partial() +void %(device)s_device::%(opcode)s_partial() { switch(inst_substate) { case 0: @@ -158,7 +158,7 @@ def save_opcodes(f, device, opcodes): DO_EXEC_FULL_PROLOG="""\ -void %(device)s::do_exec_full() +void %(device)s_device::do_exec_full() { \tswitch(inst_state) { """ @@ -169,7 +169,7 @@ DO_EXEC_FULL_EPILOG="""\ """ DO_EXEC_PARTIAL_PROLOG="""\ -void %(device)s::do_exec_partial() +void %(device)s_device::do_exec_partial() { \tswitch(inst_state) { """ @@ -180,7 +180,7 @@ DO_EXEC_PARTIAL_EPILOG="""\ """ DISASM_PROLOG="""\ -const %(device)s::disasm_entry %(device)s::disasm_entries[0x%(disasm_count)x] = { +const %(device)s_disassembler::disasm_entry %(device)s_disassembler::disasm_entries[0x%(disasm_count)x] = { """ DISASM_EPILOG="""\ @@ -194,25 +194,31 @@ def save_tables(f, device, states): "disasm_count": total_states-1 } - emit(f, DO_EXEC_FULL_PROLOG % d) for n, state in enumerate(states): if state == ".": continue if n < total_states - 1: - emit(f, "\tcase 0x%02x: %s_full(); break;\n" % (n, state)) + emit(f, "\tcase 0x%02x: %s_full(); break;" % (n, state)) else: - emit(f, "\tcase %s: %s_full(); break;\n" % ("STATE_RESET", state)) + emit(f, "\tcase %s: %s_full(); break;" % ("STATE_RESET", state)) emit(f, DO_EXEC_FULL_EPILOG % d) emit(f, DO_EXEC_PARTIAL_PROLOG % d) for n, state in enumerate(states): if state == ".": continue if n < total_states - 1: - emit(f, "\tcase 0x%02x: %s_partial(); break;\n" % (n, state)) + emit(f, "\tcase 0x%02x: %s_partial(); break;" % (n, state)) else: - emit(f, "\tcase %s: %s_partial(); break;\n" % ("STATE_RESET", state)) + emit(f, "\tcase %s: %s_partial(); break;" % ("STATE_RESET", state)) emit(f, DO_EXEC_PARTIAL_EPILOG % d) +def save_dasm(f, device, states): + total_states = len(states) + + d = { "device": device, + "disasm_count": total_states-1 + } + emit(f, DISASM_PROLOG % d ) for n, state in enumerate(states): if state == ".": continue @@ -222,13 +228,13 @@ def save_tables(f, device, states): mode = tokens[-1] extra = "0" if opc in ["jsr", "bsr"]: - extra = "DASMFLAG_STEP_OVER" + extra = "STEP_OVER" elif opc in ["rts", "rti", "rtn"]: - extra = "DASMFLAG_STEP_OUT" - emit(f, '\t{ "%s", DASM_%s, %s },\n' % (opc, mode, extra)) + extra = "STEP_OUT" + emit(f, '\t{ "%s", DASM_%s, %s },' % (opc, mode, extra)) emit(f, DISASM_EPILOG % d) -def save(fname, device, opcodes, states): +def saves(fname, device, opcodes, states): logging.info("saving: %s", fname) try: f = open(fname, "w") @@ -236,12 +242,24 @@ def save(fname, device, opcodes, states): err = sys.exc_info()[1] logging.error("cannot write file %s [%s]", fname, err) sys.exit(1) - save_opcodes(f,device, opcodes) + save_opcodes(f, device, opcodes) emit(f, "\n") save_tables(f, device, states) f.close() +def saved(fname, device, opcodes, states): + logging.info("saving: %s", fname) + try: + f = open(fname, "w") + except Exception: + err = sys.exc_info()[1] + logging.error("cannot write file %s [%s]", fname, err) + sys.exit(1) + save_dasm(f, device, states) + f.close() + + def main(argv): debug = False logformat=("%(levelname)s:" @@ -255,25 +273,29 @@ def main(argv): logging.basicConfig(level=logging.WARNING, format=logformat) - if len(argv) != 5: + if len(argv) != 6: print(USAGE % argv[0]) return 1 - device_name = argv[1] + mode = argv[1] + device_name = argv[2] opcodes = [] - if argv[2] != "-": - opcodes = load_opcodes(argv[2]) + if argv[3] != "-": + opcodes = load_opcodes(argv[3]) logging.info("found %d opcodes", len(opcodes)) else: logging.info("skipping opcode reading") - states = load_disp(argv[3]) + states = load_disp(argv[4]) logging.info("loaded %s states", len(states)) assert (len(states) & 0xff) == 1 - save(argv[4], device_name, opcodes, states) + if mode == 's': + saves(argv[5], device_name, opcodes, states) + else: + saved(argv[5], device_name, opcodes, states) # ====================================================================== diff --git a/src/devices/cpu/m6502/m6504.cpp b/src/devices/cpu/m6502/m6504.cpp index c6a20579333..0d7322b5fed 100644 --- a/src/devices/cpu/m6502/m6504.cpp +++ b/src/devices/cpu/m6502/m6504.cpp @@ -16,8 +16,8 @@ DEFINE_DEVICE_TYPE(M6504, m6504_device, "m6504", "M6504") m6504_device::m6504_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : m6502_device(mconfig, M6504, tag, owner, clock) { - program_config.m_addrbus_width = 13; - sprogram_config.m_addrbus_width = 13; + program_config.m_addr_width = 13; + sprogram_config.m_addr_width = 13; } void m6504_device::device_start() diff --git a/src/devices/cpu/m6502/m6507.cpp b/src/devices/cpu/m6502/m6507.cpp index d64b08c54c9..b6d44ae4c21 100644 --- a/src/devices/cpu/m6502/m6507.cpp +++ b/src/devices/cpu/m6502/m6507.cpp @@ -16,8 +16,8 @@ DEFINE_DEVICE_TYPE(M6507, m6507_device, "m6507", "M6507") m6507_device::m6507_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : m6502_device(mconfig, M6507, tag, owner, clock) { - program_config.m_addrbus_width = 13; - sprogram_config.m_addrbus_width = 13; + program_config.m_addr_width = 13; + sprogram_config.m_addr_width = 13; } void m6507_device::device_start() diff --git a/src/devices/cpu/m6502/m6509.cpp b/src/devices/cpu/m6502/m6509.cpp index 729b919fb50..828d3459b88 100644 --- a/src/devices/cpu/m6502/m6509.cpp +++ b/src/devices/cpu/m6502/m6509.cpp @@ -10,15 +10,16 @@ #include "emu.h" #include "m6509.h" +#include "m6509d.h" DEFINE_DEVICE_TYPE(M6509, m6509_device, "m6509", "M6509") m6509_device::m6509_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : m6502_device(mconfig, M6509, tag, owner, clock), XPC(0), bank_i(0), bank_y(0) { - program_config.m_addrbus_width = 20; + program_config.m_addr_width = 20; program_config.m_logaddr_width = 20; - sprogram_config.m_addrbus_width = 20; + sprogram_config.m_addr_width = 20; sprogram_config.m_logaddr_width = 20; } @@ -54,12 +55,11 @@ void m6509_device::state_export(const device_state_entry &entry) } } -offs_t m6509_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6509_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m6509_disassembler; } - m6509_device::mi_6509_normal::mi_6509_normal(m6509_device *_base) { base = _base; diff --git a/src/devices/cpu/m6502/m6509.h b/src/devices/cpu/m6502/m6509.h index 0057f900c83..c8fa2ba937e 100644 --- a/src/devices/cpu/m6502/m6509.h +++ b/src/devices/cpu/m6502/m6509.h @@ -17,9 +17,7 @@ class m6509_device : public m6502_device { public: m6509_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m6509d.cpp b/src/devices/cpu/m6502/m6509d.cpp new file mode 100644 index 00000000000..e7a27d9e1ce --- /dev/null +++ b/src/devices/cpu/m6502/m6509d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6509d.cpp + + 6502 with banking and extended address bus, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m6509d.h" +#include "cpu/m6502/m6509d.hxx" + +m6509_disassembler::m6509_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m6509d.h b/src/devices/cpu/m6502/m6509d.h new file mode 100644 index 00000000000..196b2d66de2 --- /dev/null +++ b/src/devices/cpu/m6502/m6509d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6509d.h + + 6502 with banking and extended address bus, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M6509D_H +#define MAME_CPU_M6502_M6509D_H + +#pragma once + +#include "m6502d.h" + +class m6509_disassembler : public m6502_base_disassembler +{ +public: + m6509_disassembler(); + virtual ~m6509_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m6510.cpp b/src/devices/cpu/m6502/m6510.cpp index e4b4585eaaa..a8fb427210b 100644 --- a/src/devices/cpu/m6502/m6510.cpp +++ b/src/devices/cpu/m6502/m6510.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "m6510.h" +#include "m6510d.h" DEFINE_DEVICE_TYPE(M6510, m6510_device, "m6510", "M6510") @@ -33,9 +34,9 @@ void m6510_device::set_pulls(uint8_t _pullup, uint8_t _floating) floating = _floating; } -offs_t m6510_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6510_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m6510_disassembler; } void m6510_device::device_start() diff --git a/src/devices/cpu/m6502/m6510.h b/src/devices/cpu/m6502/m6510.h index d3819f4899f..84f2cea32c7 100644 --- a/src/devices/cpu/m6502/m6510.h +++ b/src/devices/cpu/m6502/m6510.h @@ -32,9 +32,7 @@ public: write_port.set_callback(wr); } - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m6510d.cpp b/src/devices/cpu/m6502/m6510d.cpp new file mode 100644 index 00000000000..78be285262a --- /dev/null +++ b/src/devices/cpu/m6502/m6510d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6510d.cpp + + 6502 with 6 i/o pins, also known as 8500, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m6510d.h" +#include "cpu/m6502/m6510d.hxx" + +m6510_disassembler::m6510_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m6510d.h b/src/devices/cpu/m6502/m6510d.h new file mode 100644 index 00000000000..ddf94f93626 --- /dev/null +++ b/src/devices/cpu/m6502/m6510d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m6510d.h + + 6502 with 6 i/o pins, also known as 8500, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M6510D_H +#define MAME_CPU_M6502_M6510D_H + +#pragma once + +#include "m6502d.h" + +class m6510_disassembler : public m6502_base_disassembler +{ +public: + m6510_disassembler(); + virtual ~m6510_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m65c02.cpp b/src/devices/cpu/m6502/m65c02.cpp index d109cc502bf..bc79ea84231 100644 --- a/src/devices/cpu/m6502/m65c02.cpp +++ b/src/devices/cpu/m6502/m65c02.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "m65c02.h" +#include "m65c02d.h" DEFINE_DEVICE_TYPE(M65C02, m65c02_device, "m65c02", "M65C02") @@ -24,9 +25,9 @@ m65c02_device::m65c02_device(const machine_config &mconfig, device_type type, co { } -offs_t m65c02_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m65c02_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m65c02_disassembler; } #include "cpu/m6502/m65c02.hxx" diff --git a/src/devices/cpu/m6502/m65c02.h b/src/devices/cpu/m6502/m65c02.h index 828556e5f83..c1898912b03 100644 --- a/src/devices/cpu/m6502/m65c02.h +++ b/src/devices/cpu/m6502/m65c02.h @@ -19,9 +19,7 @@ class m65c02_device : public m6502_device { public: m65c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m65c02d.cpp b/src/devices/cpu/m6502/m65c02d.cpp new file mode 100644 index 00000000000..7a78219f129 --- /dev/null +++ b/src/devices/cpu/m6502/m65c02d.cpp @@ -0,0 +1,18 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m65c02d.cpp + + Mostek 6502, CMOS variant with some additional instructions (but + not the bitwise ones), disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m65c02d.h" +#include "cpu/m6502/m65c02d.hxx" + +m65c02_disassembler::m65c02_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m65c02d.h b/src/devices/cpu/m6502/m65c02d.h new file mode 100644 index 00000000000..d9599e548bb --- /dev/null +++ b/src/devices/cpu/m6502/m65c02d.h @@ -0,0 +1,29 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m65c02d.h + + Mostek 6502, CMOS variant with some additional instructions (but + not the bitwise ones), disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M65C02D_H +#define MAME_CPU_M6502_M65C02D_H + +#pragma once + +#include "m6502d.h" + +class m65c02_disassembler : public m6502_base_disassembler +{ +public: + m65c02_disassembler(); + virtual ~m65c02_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m65ce02.cpp b/src/devices/cpu/m6502/m65ce02.cpp index 239e900ed6d..e416cfa0089 100644 --- a/src/devices/cpu/m6502/m65ce02.cpp +++ b/src/devices/cpu/m6502/m65ce02.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "m65ce02.h" +#include "m65ce02d.h" DEFINE_DEVICE_TYPE(M65CE02, m65ce02_device, "m65ce02", "M65CE02") @@ -23,9 +24,9 @@ m65ce02_device::m65ce02_device(const machine_config &mconfig, device_type type, { } -offs_t m65ce02_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m65ce02_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new m65ce02_disassembler; } void m65ce02_device::init() diff --git a/src/devices/cpu/m6502/m65ce02.h b/src/devices/cpu/m6502/m65ce02.h index 191123683f6..e3c7a440ca8 100644 --- a/src/devices/cpu/m6502/m65ce02.h +++ b/src/devices/cpu/m6502/m65ce02.h @@ -18,9 +18,7 @@ class m65ce02_device : public m65c02_device { public: m65ce02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/m65ce02d.cpp b/src/devices/cpu/m6502/m65ce02d.cpp new file mode 100644 index 00000000000..f815eae4b5a --- /dev/null +++ b/src/devices/cpu/m6502/m65ce02d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m65ce02d.cpp + + 6502 with Z register and some more stuff, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m65ce02d.h" +#include "cpu/m6502/m65ce02d.hxx" + +m65ce02_disassembler::m65ce02_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/m65ce02d.h b/src/devices/cpu/m6502/m65ce02d.h new file mode 100644 index 00000000000..ea5cd8f072f --- /dev/null +++ b/src/devices/cpu/m6502/m65ce02d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m65ce02d.h + + 6502 with Z register and some more stuff, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M65CE02D_H +#define MAME_CPU_M6502_M65CE02D_H + +#pragma once + +#include "m6502d.h" + +class m65ce02_disassembler : public m6502_base_disassembler +{ +public: + m65ce02_disassembler(); + virtual ~m65ce02_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/m740.cpp b/src/devices/cpu/m6502/m740.cpp index 807eac55b09..cce9289b1de 100644 --- a/src/devices/cpu/m6502/m740.cpp +++ b/src/devices/cpu/m6502/m740.cpp @@ -23,9 +23,14 @@ m740_device::m740_device(const machine_config &mconfig, device_type type, const { } -offs_t m740_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +u32 m740_device::get_state_base() const { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return inst_state_base; +} + +util::disasm_interface *m740_device::create_disassembler() +{ + return new m740_disassembler(this); } void m740_device::device_start() diff --git a/src/devices/cpu/m6502/m740.h b/src/devices/cpu/m6502/m740.h index 350ea8bced6..be7245e328c 100644 --- a/src/devices/cpu/m6502/m740.h +++ b/src/devices/cpu/m6502/m740.h @@ -12,8 +12,9 @@ #define MAME_CPU_M6502_M740_H #include "m6502.h" +#include "m740d.h" -class m740_device : public m6502_device { +class m740_device : public m6502_device, public m740_disassembler::config { public: enum { @@ -41,11 +42,9 @@ public: virtual void device_start() override; virtual void device_reset() override; - static const disasm_entry disasm_entries[0x200]; - virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; virtual void execute_set_input(int inputnum, int state) override; @@ -55,6 +54,9 @@ protected: #define O(o) void o ## _full(); void o ## _partial() + u32 inst_state_base; /* Current instruction bank */ + virtual u32 get_state_base() const override; + uint8_t do_clb(uint8_t in, uint8_t bit); uint8_t do_seb(uint8_t in, uint8_t bit); uint8_t do_rrf(uint8_t in); diff --git a/src/devices/cpu/m6502/m740d.cpp b/src/devices/cpu/m6502/m740d.cpp new file mode 100644 index 00000000000..5da5ef53020 --- /dev/null +++ b/src/devices/cpu/m6502/m740d.cpp @@ -0,0 +1,22 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m740d.cpp + + Mitsubishi M740 series (M507xx/M509xx), disassembler + +***************************************************************************/ + +#include "emu.h" +#include "m740d.h" +#include "cpu/m6502/m740d.hxx" + +m740_disassembler::m740_disassembler(config *_conf) : m6502_base_disassembler(disasm_entries), conf(_conf) +{ +} + +u32 m740_disassembler::get_instruction_bank() const +{ + return conf->get_state_base(); +} diff --git a/src/devices/cpu/m6502/m740d.h b/src/devices/cpu/m6502/m740d.h new file mode 100644 index 00000000000..80029cc56a8 --- /dev/null +++ b/src/devices/cpu/m6502/m740d.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + m740d.h + + Mitsubishi M740 series (M507xx/M509xx), disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_M740D_H +#define MAME_CPU_M6502_M740D_H + +#pragma once + +#include "m6502d.h" + +class m740_disassembler : public m6502_base_disassembler +{ +public: + struct config { + virtual ~config() = default; + virtual u32 get_state_base() const = 0; + }; + + m740_disassembler(config *conf); + virtual ~m740_disassembler() = default; + +protected: + virtual u32 get_instruction_bank() const override; + +private: + static const disasm_entry disasm_entries[0x200]; + config *conf; +}; + +#endif diff --git a/src/devices/cpu/m6502/n2a03.cpp b/src/devices/cpu/m6502/n2a03.cpp index ca3a8a9b87b..f989d8d50f3 100644 --- a/src/devices/cpu/m6502/n2a03.cpp +++ b/src/devices/cpu/m6502/n2a03.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "n2a03.h" +#include "n2a03d.h" DEFINE_DEVICE_TYPE(N2A03, n2a03_device, "n2a03", "N2A03") @@ -56,9 +57,9 @@ n2a03_device::n2a03_device(const machine_config &mconfig, const char *tag, devic program_config.m_internal_map = ADDRESS_MAP_NAME(n2a03_map); } -offs_t n2a03_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *n2a03_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new n2a03_disassembler; } void n2a03_device::device_start() diff --git a/src/devices/cpu/m6502/n2a03.h b/src/devices/cpu/m6502/n2a03.h index 0a4cf346797..42e5eac8257 100644 --- a/src/devices/cpu/m6502/n2a03.h +++ b/src/devices/cpu/m6502/n2a03.h @@ -19,9 +19,8 @@ class n2a03_device : public m6502_device { public: n2a03_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; virtual void device_clock_changed() override; diff --git a/src/devices/cpu/m6502/n2a03d.cpp b/src/devices/cpu/m6502/n2a03d.cpp new file mode 100644 index 00000000000..bedb062f018 --- /dev/null +++ b/src/devices/cpu/m6502/n2a03d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + n2a03d.cpp + + 6502, NES variant, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "n2a03d.h" +#include "cpu/m6502/n2a03d.hxx" + +n2a03_disassembler::n2a03_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/n2a03d.h b/src/devices/cpu/m6502/n2a03d.h new file mode 100644 index 00000000000..568df91c23a --- /dev/null +++ b/src/devices/cpu/m6502/n2a03d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + n2a03d.h + + 6502, NES variant, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_N2A03D_H +#define MAME_CPU_M6502_N2A03D_H + +#pragma once + +#include "m6502d.h" + +class n2a03_disassembler : public m6502_base_disassembler +{ +public: + n2a03_disassembler(); + virtual ~n2a03_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6502/or65c02.lst b/src/devices/cpu/m6502/or65c02.lst new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/src/devices/cpu/m6502/or65c02.lst diff --git a/src/devices/cpu/m6502/r65c02.cpp b/src/devices/cpu/m6502/r65c02.cpp index 53c5b40b662..ab7bb936876 100644 --- a/src/devices/cpu/m6502/r65c02.cpp +++ b/src/devices/cpu/m6502/r65c02.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "r65c02.h" +#include "r65c02d.h" DEFINE_DEVICE_TYPE(R65C02, r65c02_device, "r65c02", "R65C02") @@ -23,9 +24,9 @@ r65c02_device::r65c02_device(const machine_config &mconfig, device_type type, co { } -offs_t r65c02_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *r65c02_device::create_disassembler() { - return disassemble_generic(stream, pc, oprom, opram, options, disasm_entries); + return new r65c02_disassembler; } #include "cpu/m6502/r65c02.hxx" diff --git a/src/devices/cpu/m6502/r65c02.h b/src/devices/cpu/m6502/r65c02.h index 41cea972944..d6c88417bd6 100644 --- a/src/devices/cpu/m6502/r65c02.h +++ b/src/devices/cpu/m6502/r65c02.h @@ -17,9 +17,7 @@ class r65c02_device : public m65c02_device { public: r65c02_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/m6502/r65c02d.cpp b/src/devices/cpu/m6502/r65c02d.cpp new file mode 100644 index 00000000000..20eae90c9bc --- /dev/null +++ b/src/devices/cpu/m6502/r65c02d.cpp @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + r65c02d.cpp + + Rockwell 65c02, CMOS variant with bitwise instructions, disassembler + +***************************************************************************/ + +#include "emu.h" +#include "r65c02d.h" +#include "cpu/m6502/r65c02d.hxx" + +r65c02_disassembler::r65c02_disassembler() : m6502_base_disassembler(disasm_entries) +{ +} diff --git a/src/devices/cpu/m6502/r65c02d.h b/src/devices/cpu/m6502/r65c02d.h new file mode 100644 index 00000000000..5f5f3a4a58a --- /dev/null +++ b/src/devices/cpu/m6502/r65c02d.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + r65c02d.h + + Rockwell 65c02, CMOS variant with bitwise instructions, disassembler + +***************************************************************************/ + +#ifndef MAME_CPU_M6502_R65C02D_H +#define MAME_CPU_M6502_R65C02D_H + +#pragma once + +#include "m6502d.h" + +class r65c02_disassembler : public m6502_base_disassembler +{ +public: + r65c02_disassembler(); + virtual ~r65c02_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/m6800/6800dasm.cpp b/src/devices/cpu/m6800/6800dasm.cpp index 781af28f468..dcd174e0cba 100644 --- a/src/devices/cpu/m6800/6800dasm.cpp +++ b/src/devices/cpu/m6800/6800dasm.cpp @@ -20,43 +20,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "m6800.h" +#include "6800dasm.h" -enum addr_mode { - inh, /* inherent */ - rel, /* relative */ - imb, /* immediate (byte) */ - imw, /* immediate (word) */ - dir, /* direct address */ - imd, /* HD63701YO: immediate, direct address */ - ext, /* extended address */ - idx, /* x + byte offset */ - imx, /* HD63701YO: immediate, x + byte offset */ - sx1 /* HD63701YO: undocumented opcodes: byte from (s+1) */ -}; - -enum op_names { - aba=0, abx, adca, adcb, adda, addb, addd, aim, - anda, andb, asl, asla, aslb, asld, asr, asra, - asrb, bcc, bcs, beq, bge, bgt, bhi, bita, - bitb, ble, bls, blt, bmi, bne, bpl, bra, - brn, bsr, bvc, bvs, cba, clc, cli, clr, - clra, clrb, clv, cmpa, cmpb, cmpx, com, coma, - comb, daa, dec, deca, decb, des, dex, eim, - eora, eorb, ill, inc, inca, incb, ins, inx, - jmp, jsr, lda, ldb, ldd, lds, ldx, lsr, - lsra, lsrb, lsrd, mul, neg, nega, negb, nop, - oim, ora, orb, psha, pshb, pshx, pula, pulb, - pulx, rol, rola, rolb, ror, rora, rorb, rti, - rts, sba, sbca, sbcb, sec, sev, sta, stb, - _std, sei, sts, stx, suba, subb, subd, swi, - wai, tab, tap, tba, tim, tpa, tst, tsta, - tstb, tsx, txs, asx1, asx2, xgdx, addx, adcx, - bitx -}; - -static const char *const op_name_str[] = { +const char *const m680x_disassembler::op_name_str[] = { "aba", "abx", "adca", "adcb", "adda", "addb", "addd", "aim", "anda", "andb", "asl", "asla", "aslb", "asld", "asr", "asra", "asrb", "bcc", "bcs", "beq", "bge", "bgt", "bhi", "bita", @@ -84,7 +50,7 @@ static const char *const op_name_str[] = { * 2 invalid opcode for 1:6800/6802/6808, 2:6801/6803, 4:HD63701 */ -static const uint8_t table[0x104][3] = { +const uint8_t m680x_disassembler::table[0x104][3] = { {ill, inh,7},{nop, inh,0},{ill, inh,7},{ill, inh,7},/* 00 */ {lsrd,inh,1},{asld,inh,1},{tap, inh,0},{tpa, inh,0}, {inx, inh,0},{dex, inh,0},{clv, inh,0},{sev, inh,0}, @@ -160,20 +126,23 @@ static const uint8_t table[0x104][3] = { {stx,imx,0} }; -/* some macros to keep things short */ -#define OP oprom[0] -#define ARG1 opram[1] -#define ARG2 opram[2] -#define ARGW (opram[1]<<8) + opram[2] +m680x_disassembler::m680x_disassembler(int subtype) : m_subtype(subtype) +{ +} + +u32 m680x_disassembler::opcode_alignment() const +{ + return 1; +} -static unsigned Dasm680x (int subtype, std::ostream &stream, unsigned pc, const uint8_t *oprom, const uint8_t *opram) +offs_t m680x_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t flags = 0; + offs_t flags = 0; int invalid_mask; - int code = OP; + int code = opcodes.r8(pc); uint8_t opcode, args, invalid; - switch( subtype ) + switch( m_subtype ) { case 6800: case 6802: case 6808: case 8105: invalid_mask = 1; @@ -186,14 +155,14 @@ static unsigned Dasm680x (int subtype, std::ostream &stream, unsigned pc, const } /* NSC-8105 is a special case */ - if (subtype == 8105) + if (m_subtype == 8105) { /* swap bits */ code = (code & 0x3c) | ((code & 0x41) << 1) | ((code & 0x82) >> 1); /* and check for extra instruction */ - if (code == 0xfc) code = 0x0100; - if (code == 0xec) code = 0x0101; + if (code == 0xfc) code = 0x0100; + if (code == 0xec) code = 0x0101; if (code == 0x7b) code = 0x0102; if (code == 0x71) code = 0x0103; } @@ -203,14 +172,14 @@ static unsigned Dasm680x (int subtype, std::ostream &stream, unsigned pc, const invalid = table[code][2]; if (opcode == bsr || opcode == jsr) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (opcode == rti || opcode == rts) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; if ( invalid & invalid_mask ) /* invalid for this cpu type ? */ { stream << "illegal"; - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; } util::stream_format(stream, "%-5s", op_name_str[opcode]); @@ -218,73 +187,33 @@ static unsigned Dasm680x (int subtype, std::ostream &stream, unsigned pc, const switch( args ) { case rel: /* relative */ - util::stream_format(stream, "$%04X", pc + (int8_t)ARG1 + 2); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "$%04X", pc + (int8_t)params.r8(pc+1) + 2); + return 2 | flags | SUPPORTED; case imb: /* immediate (byte) */ - util::stream_format(stream, "#$%02X", ARG1); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%02X", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case imw: /* immediate (word) */ - util::stream_format(stream, "#$%04X", ARGW); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%04X", params.r16(pc+1)); + return 3 | flags | SUPPORTED; case idx: /* indexed + byte offset */ - util::stream_format(stream, "(x+$%02X)", ARG1); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "(x+$%02X)", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case imx: /* immediate, indexed + byte offset */ - util::stream_format(stream, "#$%02X,(x+$%02x)", ARG1, ARG2); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%02X,(x+$%02x)", params.r8(pc+1), params.r8(pc+2)); + return 3 | flags | SUPPORTED; case dir: /* direct address */ - util::stream_format(stream, "$%02X", ARG1); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "$%02X", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case imd: /* immediate, direct address */ - util::stream_format(stream, "#$%02X,$%02X", ARG1, ARG2); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%02X,$%02X", params.r8(pc+1), params.r8(pc+2)); + return 3 | flags | SUPPORTED; case ext: /* extended address */ - util::stream_format(stream, "$%04X", ARGW); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "$%04X", params.r16(pc+1)); + return 3 | flags | SUPPORTED; case sx1: /* byte from address (s + 1) */ util::stream_format(stream, "(s+1)"); - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; default: - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; } } - -CPU_DISASSEMBLE( m6800 ) -{ - return Dasm680x(6800,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( m6801 ) -{ - return Dasm680x(6801,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( m6802 ) -{ - return Dasm680x(6802,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( m6803 ) -{ - return Dasm680x(6803,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( m6808 ) -{ - return Dasm680x(6808,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( hd6301 ) -{ - return Dasm680x(6301,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( hd63701 ) -{ - return Dasm680x(63701,stream,pc,oprom,opram); -} - -CPU_DISASSEMBLE( nsc8105 ) -{ - return Dasm680x(8105,stream,pc,oprom,opram); -} diff --git a/src/devices/cpu/m6800/6800dasm.h b/src/devices/cpu/m6800/6800dasm.h new file mode 100644 index 00000000000..a535e1299c0 --- /dev/null +++ b/src/devices/cpu/m6800/6800dasm.h @@ -0,0 +1,76 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/* + * A quick-hack 6803/6808 disassembler + * + * Note: this is not the good and proper way to disassemble anything, but it works + * + * I'm afraid to put my name on it, but I feel obligated: + * This code written by Aaron Giles (agiles@sirius.com) for the MAME project + * + * History: + * 990314 HJB + * The disassembler knows about valid opcodes for M6800/1/2/3/8 and HD63701. + * 990302 HJB + * Changed the string array into a table of opcode names (or tokens) and + * argument types. This second try should give somewhat better results. + * Named the undocumented HD63701YO opcodes $12 and $13 'asx1' and 'asx2', + * since 'add contents of stack to x register' is what they do. + * + */ + +#ifndef MAME_CPU_M6800_6800DASM_H +#define MAME_CPU_M6800_6800DASM_H + +#pragma once + +class m680x_disassembler : public util::disasm_interface +{ +public: + m680x_disassembler(int subtype); + virtual ~m680x_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum addr_mode { + inh, /* inherent */ + rel, /* relative */ + imb, /* immediate (byte) */ + imw, /* immediate (word) */ + dir, /* direct address */ + imd, /* HD63701YO: immediate, direct address */ + ext, /* extended address */ + idx, /* x + byte offset */ + imx, /* HD63701YO: immediate, x + byte offset */ + sx1 /* HD63701YO: undocumented opcodes: byte from (s+1) */ + }; + + enum op_names { + aba=0, abx, adca, adcb, adda, addb, addd, aim, + anda, andb, asl, asla, aslb, asld, asr, asra, + asrb, bcc, bcs, beq, bge, bgt, bhi, bita, + bitb, ble, bls, blt, bmi, bne, bpl, bra, + brn, bsr, bvc, bvs, cba, clc, cli, clr, + clra, clrb, clv, cmpa, cmpb, cmpx, com, coma, + comb, daa, dec, deca, decb, des, dex, eim, + eora, eorb, ill, inc, inca, incb, ins, inx, + jmp, jsr, lda, ldb, ldd, lds, ldx, lsr, + lsra, lsrb, lsrd, mul, neg, nega, negb, nop, + oim, ora, orb, psha, pshb, pshx, pula, pulb, + pulx, rol, rola, rolb, ror, rora, rorb, rti, + rts, sba, sbca, sbcb, sec, sev, sta, stb, + _std, sei, sts, stx, suba, subb, subd, swi, + wai, tab, tap, tba, tim, tpa, tst, tsta, + tstb, tsx, txs, asx1, asx2, xgdx, addx, adcx, + bitx + }; + + static const char *const op_name_str[]; + static const uint8_t table[0x104][3]; + + int m_subtype; +}; + +#endif diff --git a/src/devices/cpu/m6800/m6800.cpp b/src/devices/cpu/m6800/m6800.cpp index c640a5ce3f2..856172ee368 100644 --- a/src/devices/cpu/m6800/m6800.cpp +++ b/src/devices/cpu/m6800/m6800.cpp @@ -464,9 +464,9 @@ void m6800_cpu_device::EAT_CYCLES() void m6800_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_decrypted_opcodes = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program; - m_decrypted_opcodes_direct = &m_decrypted_opcodes->direct(); + m_decrypted_opcodes_direct = m_decrypted_opcodes->direct<0>(); m_pc.d = 0; m_s.d = 0; @@ -579,30 +579,22 @@ void m6800_cpu_device::execute_run() } while( m_icount>0 ); } - -offs_t m6800_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6800_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6800 ); - return CPU_DISASSEMBLE_NAME(m6800)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6800); } - -offs_t m6802_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6802_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6802 ); - return CPU_DISASSEMBLE_NAME(m6802)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6802); } - -offs_t m6808_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6808_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6808 ); - return CPU_DISASSEMBLE_NAME(m6808)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6808); } - -offs_t nsc8105_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *nsc8105_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( nsc8105 ); - return CPU_DISASSEMBLE_NAME(nsc8105)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(8105); } diff --git a/src/devices/cpu/m6800/m6800.h b/src/devices/cpu/m6800/m6800.h index d541deba9ac..38679e32e2b 100644 --- a/src/devices/cpu/m6800/m6800.h +++ b/src/devices/cpu/m6800/m6800.h @@ -7,6 +7,7 @@ #pragma once +#include "6800dasm.h" enum { @@ -65,9 +66,7 @@ protected: 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 1; } - 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; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_decrypted_opcodes_config; @@ -86,7 +85,7 @@ protected: /* Memory spaces */ address_space *m_program, *m_decrypted_opcodes; - direct_read_data *m_direct, *m_decrypted_opcodes_direct; + direct_read_data<0> *m_direct, *m_decrypted_opcodes_direct; const op_func *m_insn; const uint8_t *m_cycles; /* clock cycle of instruction table */ @@ -374,7 +373,7 @@ protected: virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 4 - 1) / 4; } virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 4); } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -384,7 +383,7 @@ public: m6808_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -394,7 +393,7 @@ public: nsc8105_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; diff --git a/src/devices/cpu/m6800/m6801.cpp b/src/devices/cpu/m6800/m6801.cpp index 87e2ce5e47c..3a32726e345 100644 --- a/src/devices/cpu/m6800/m6801.cpp +++ b/src/devices/cpu/m6800/m6801.cpp @@ -1259,32 +1259,24 @@ void m6801_cpu_device::m6801_clock_serial() } } - -offs_t m6801_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6801_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6801 ); - return CPU_DISASSEMBLE_NAME(m6801)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6801); } - -offs_t m6803_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6803_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6803 ); - return CPU_DISASSEMBLE_NAME(m6803)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6803); } - -offs_t hd6301_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hd6301_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( hd6301 ); - return CPU_DISASSEMBLE_NAME(hd6301)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(6301); } - -offs_t hd63701_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hd63701_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( hd63701 ); - return CPU_DISASSEMBLE_NAME(hd63701)(this, stream, pc, oprom, opram, options); + return new m680x_disassembler(63701); } void hd63701_cpu_device::TAKE_TRAP() diff --git a/src/devices/cpu/m6800/m6801.h b/src/devices/cpu/m6800/m6801.h index 3d2098d1f94..f071e3d75c5 100644 --- a/src/devices/cpu/m6800/m6801.h +++ b/src/devices/cpu/m6800/m6801.h @@ -87,7 +87,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_io_config; @@ -158,7 +158,7 @@ public: m6803_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -170,7 +170,7 @@ public: protected: hd6301_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -180,7 +180,7 @@ public: hd63701_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void TAKE_TRAP() override; }; diff --git a/src/devices/cpu/m68000/m68000.h b/src/devices/cpu/m68000/m68000.h index 776f097967c..a6a885d6f54 100644 --- a/src/devices/cpu/m68000/m68000.h +++ b/src/devices/cpu/m68000/m68000.h @@ -110,8 +110,6 @@ enum M68K_FPSR, M68K_FPCR }; -unsigned int m68k_disassemble_raw(std::ostream &stream, unsigned int pc, const unsigned char* opdata, const unsigned char* argdata, unsigned int cpu_type); - class m68000_base_device; @@ -129,12 +127,8 @@ public: void clear_all(void); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; - - - + // device_disasm_interface overrides + virtual util::disasm_interface *create_disassembler() override; // device_execute_interface overrides virtual uint32_t execute_min_cycles() const override { return 4; }; @@ -318,7 +312,7 @@ public: // m68k_memory_interface memory; address_space *m_space, *m_ospace; - direct_read_data *m_direct, *m_odirect; + direct_read_data<0> *m_direct, *m_odirect; uint32_t iotemp; @@ -407,9 +401,7 @@ public: m68000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -432,9 +424,7 @@ public: // construction/destruction m68301_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -454,9 +444,7 @@ public: // construction/destruction m68008_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -473,9 +461,7 @@ public: // construction/destruction m68008plcc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -492,9 +478,7 @@ public: // construction/destruction m68010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -511,9 +495,7 @@ public: // construction/destruction m68ec020_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -530,9 +512,7 @@ public: // construction/destruction m68020_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -549,9 +529,7 @@ public: // construction/destruction m68020fpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -568,9 +546,7 @@ public: // construction/destruction m68020pmmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -587,9 +563,7 @@ public: // construction/destruction m68020hmmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -608,9 +582,7 @@ public: // construction/destruction m68ec030_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -627,9 +599,7 @@ public: // construction/destruction m68030_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -646,9 +616,7 @@ public: // construction/destruction m68ec040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -665,9 +633,7 @@ public: // construction/destruction m68lc040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -684,9 +650,7 @@ public: // construction/destruction m68040_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -703,9 +667,7 @@ public: // construction/destruction scc68070_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 4; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -725,9 +687,7 @@ public: // construction/destruction fscpu32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; @@ -750,9 +710,7 @@ public: // construction/destruction mcf5206e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; }; - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; }; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual uint32_t execute_min_cycles() const override { return 2; }; virtual uint32_t execute_max_cycles() const override { return 158; }; diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp index c4199ecdf15..e387f946784 100644 --- a/src/devices/cpu/m68000/m68kcpu.cpp +++ b/src/devices/cpu/m68000/m68kcpu.cpp @@ -31,6 +31,7 @@ static const char copyright_notice[] = #include "m68kfpu.hxx" #include "m68kmmu.h" +#include "m68kdasm.h" extern void m68040_fpu_op0(m68000_base_device *m68k); extern void m68040_fpu_op1(m68000_base_device *m68k); @@ -1235,9 +1236,9 @@ uint16_t m68000_base_device::m68008_read_immediate_16(offs_t address) void m68000_base_device::init8(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); // m_cpustate = this; opcode_xor = 0; @@ -1274,9 +1275,9 @@ void m68000_base_device::m68000_write_byte(offs_t address, uint8_t data) void m68000_base_device::init16(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); opcode_xor = 0; @@ -1301,9 +1302,9 @@ void m68000_base_device::init16(address_space &space, address_space &ospace) void m68000_base_device::init32(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); opcode_xor = WORD_XOR_BE(0); readimm16 = m68k_readimm16_delegate(&m68000_base_device::read_immediate_16, this); @@ -1520,9 +1521,9 @@ void m68000_base_device::writelong_d32_mmu(offs_t address, uint32_t data) void m68000_base_device::init32mmu(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); opcode_xor = WORD_XOR_BE(0); readimm16 = m68k_readimm16_delegate(&m68000_base_device::read_immediate_16_mmu, this); @@ -1648,9 +1649,9 @@ void m68000_base_device::writelong_d32_hmmu(offs_t address, uint32_t data) void m68000_base_device::init32hmmu(address_space &space, address_space &ospace) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); m_ospace = &ospace; - m_odirect = &ospace.direct(); + m_odirect = ospace.direct<0>(); opcode_xor = WORD_XOR_BE(0); readimm16 = m68k_readimm16_delegate(&m68000_base_device::read_immediate_16_hmmu, this); @@ -1714,6 +1715,7 @@ void m68000_base_device::define_state(void) state_add(M68K_USP, "USP", iotemp).callimport().callexport(); if (cpu_type & MASK_020_OR_LATER) state_add(M68K_MSP, "MSP", iotemp).callimport().callexport(); + state_add(M68K_SR, "SR", iotemp).noshow().callimport().callexport(); for (int regnum = 0; regnum < 8; regnum++) { state_add(M68K_D0 + regnum, string_format("D%d", regnum).c_str(), dar[regnum]); @@ -2133,80 +2135,100 @@ void m68000_base_device::init_cpu_coldfire(void) define_state(); } -CPU_DISASSEMBLE( dasm_m68000 ) +util::disasm_interface *m68000_base_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68000); + return new m68k_disassembler(m68k_disassembler::TYPE_68000); } -CPU_DISASSEMBLE( dasm_m68008 ) +util::disasm_interface *m68000_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68008); + return new m68k_disassembler(m68k_disassembler::TYPE_68000); } -CPU_DISASSEMBLE( dasm_m68010 ) +util::disasm_interface *m68301_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68010); + return new m68k_disassembler(m68k_disassembler::TYPE_68000); } -CPU_DISASSEMBLE( dasm_m68020 ) +util::disasm_interface *m68008_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68020); + return new m68k_disassembler(m68k_disassembler::TYPE_68008); } -CPU_DISASSEMBLE( dasm_m68030 ) +util::disasm_interface *m68008plcc_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68030); + return new m68k_disassembler(m68k_disassembler::TYPE_68008); } -CPU_DISASSEMBLE( dasm_m68ec030 ) +util::disasm_interface *m68010_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68EC030); + return new m68k_disassembler(m68k_disassembler::TYPE_68010); } -CPU_DISASSEMBLE( dasm_m68040 ) +util::disasm_interface *m68ec020_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68040); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -CPU_DISASSEMBLE( dasm_m68ec040 ) +util::disasm_interface *m68020_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68EC040); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -CPU_DISASSEMBLE( dasm_m68lc040 ) +util::disasm_interface *m68020fpu_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68LC040); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -CPU_DISASSEMBLE( dasm_fscpu32 ) +util::disasm_interface *m68020pmmu_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_FSCPU32); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -CPU_DISASSEMBLE( dasm_coldfire ) +util::disasm_interface *m68020hmmu_device::create_disassembler() { - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_COLDFIRE); + return new m68k_disassembler(m68k_disassembler::TYPE_68020); } -offs_t m68000_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68000)(this, stream, pc, oprom, opram, options); } -offs_t m68000_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68000)(this, stream, pc, oprom, opram, options); } -offs_t m68301_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68000)(this, stream, pc, oprom, opram, options); } -offs_t m68008_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68008)(this, stream, pc, oprom, opram, options); } -offs_t m68008plcc_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68008)(this, stream, pc, oprom, opram, options); } -offs_t m68010_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68010)(this, stream, pc, oprom, opram, options); } -offs_t m68ec020_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68020_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68020fpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68020pmmu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68020hmmu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68020)(this, stream, pc, oprom, opram, options); } -offs_t m68ec030_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68ec030)(this, stream, pc, oprom, opram, options); } -offs_t m68030_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68030)(this, stream, pc, oprom, opram, options); } -offs_t m68ec040_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68ec040)(this, stream, pc, oprom, opram, options); } -offs_t m68lc040_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68lc040)(this, stream, pc, oprom, opram, options); } -offs_t m68040_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68040)(this, stream, pc, oprom, opram, options); } -offs_t scc68070_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_m68000)(this, stream, pc, oprom, opram, options); } -offs_t fscpu32_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_fscpu32)(this, stream, pc, oprom, opram, options); } -offs_t mcf5206e_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) { return CPU_DISASSEMBLE_NAME(dasm_coldfire)(this, stream, pc, oprom, opram, options); } +util::disasm_interface *m68ec030_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68030); +} + +util::disasm_interface *m68030_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68030); +} + +util::disasm_interface *m68ec040_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68040); +} + +util::disasm_interface *m68lc040_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68040); +} + +util::disasm_interface *m68040_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68040); +} + +util::disasm_interface *scc68070_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68000); +} + +util::disasm_interface *fscpu32_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_68340); +} + +util::disasm_interface *mcf5206e_device::create_disassembler() +{ + return new m68k_disassembler(m68k_disassembler::TYPE_COLDFIRE); +} /* Service an interrupt request and start exception processing */ diff --git a/src/devices/cpu/m68000/m68kcpu.h b/src/devices/cpu/m68000/m68kcpu.h index df2a754a13f..dce0c2205a8 100644 --- a/src/devices/cpu/m68000/m68kcpu.h +++ b/src/devices/cpu/m68000/m68kcpu.h @@ -1672,8 +1672,24 @@ static inline void m68ki_exception_address_error(m68000_base_device *m68k) } m68k->run_mode = RUN_MODE_BERR_AERR_RESET; - /* Note: This is implemented for 68000 only! */ - m68ki_stack_frame_buserr(m68k, sr); + if (!CPU_TYPE_IS_010_PLUS(m68k->cpu_type)) + { + /* Note: This is implemented for 68000 only! */ + m68ki_stack_frame_buserr(m68k, sr); + } + else if (CPU_TYPE_IS_010(m68k->cpu_type)) + { + /* only the 68010 throws this unique type-1000 frame */ + m68ki_stack_frame_1000(m68k, REG_PPC(m68k), sr, EXCEPTION_BUS_ERROR); + } + else if (m68k->mmu_tmp_buserror_address == REG_PPC(m68k)) + { + m68ki_stack_frame_1010(m68k, sr, EXCEPTION_BUS_ERROR, REG_PPC(m68k), m68k->mmu_tmp_buserror_address); + } + else + { + m68ki_stack_frame_1011(m68k, sr, EXCEPTION_BUS_ERROR, REG_PPC(m68k), m68k->mmu_tmp_buserror_address); + } m68ki_jump_vector(m68k, EXCEPTION_ADDRESS_ERROR); diff --git a/src/devices/cpu/m68000/m68kdasm.cpp b/src/devices/cpu/m68000/m68kdasm.cpp index 5bd074f731e..73850c1b082 100644 --- a/src/devices/cpu/m68000/m68kdasm.cpp +++ b/src/devices/cpu/m68000/m68kdasm.cpp @@ -18,640 +18,321 @@ /* ================================ INCLUDES ============================== */ /* ======================================================================== */ -#define m68ki_cpu_core void #include "emu.h" -#include "m68000.h" +#include "m68kdasm.h" -#ifndef DECL_SPEC -#define DECL_SPEC -#endif - -/* ======================================================================== */ -/* ============================ GENERAL DEFINES =========================== */ -/* ======================================================================== */ - -/* unsigned int and int must be at least 32 bits wide */ -#undef uint32_t -#define uint32_t unsigned int - -/* Bit Isolation Functions */ -#define BIT_0(A) ((A) & 0x00000001) -#define BIT_1(A) ((A) & 0x00000002) -#define BIT_2(A) ((A) & 0x00000004) -#define BIT_3(A) ((A) & 0x00000008) -#define BIT_4(A) ((A) & 0x00000010) -#define BIT_5(A) ((A) & 0x00000020) -#define BIT_6(A) ((A) & 0x00000040) -#define BIT_7(A) ((A) & 0x00000080) -#define BIT_8(A) ((A) & 0x00000100) -#define BIT_9(A) ((A) & 0x00000200) -#define BIT_A(A) ((A) & 0x00000400) -#define BIT_B(A) ((A) & 0x00000800) -#define BIT_C(A) ((A) & 0x00001000) -#define BIT_D(A) ((A) & 0x00002000) -#define BIT_E(A) ((A) & 0x00004000) -#define BIT_F(A) ((A) & 0x00008000) -#define BIT_10(A) ((A) & 0x00010000) -#define BIT_11(A) ((A) & 0x00020000) -#define BIT_12(A) ((A) & 0x00040000) -#define BIT_13(A) ((A) & 0x00080000) -#define BIT_14(A) ((A) & 0x00100000) -#define BIT_15(A) ((A) & 0x00200000) -#define BIT_16(A) ((A) & 0x00400000) -#define BIT_17(A) ((A) & 0x00800000) -#define BIT_18(A) ((A) & 0x01000000) -#define BIT_19(A) ((A) & 0x02000000) -#define BIT_1A(A) ((A) & 0x04000000) -#define BIT_1B(A) ((A) & 0x08000000) -#define BIT_1C(A) ((A) & 0x10000000) -#define BIT_1D(A) ((A) & 0x20000000) -#define BIT_1E(A) ((A) & 0x40000000) -#define BIT_1F(A) ((A) & 0x80000000) - -/* These are the CPU types understood by this disassembler */ -#define TYPE_68000 1 -#define TYPE_68008 2 -#define TYPE_68010 4 -#define TYPE_68020 8 -#define TYPE_68030 16 -#define TYPE_68040 32 -#define TYPE_68340 64 // (CPU32) -#define TYPE_COLDFIRE 128 - -#define M68000_ONLY (TYPE_68000 | TYPE_68008) - -#define M68010_ONLY TYPE_68010 -#define M68010_LESS (TYPE_68000 | TYPE_68008 | TYPE_68010) -#define M68010_PLUS (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE) - -#define M68020_ONLY (TYPE_68020 | TYPE_68340) -#define M68020_LESS (TYPE_68010 | TYPE_68020 | TYPE_68340) -#define M68020_PLUS (TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE) - -#define M68030_ONLY TYPE_68030 -#define M68030_LESS (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68340 ) -#define M68030_PLUS (TYPE_68030 | TYPE_68040) - -#define M68040_PLUS TYPE_68040 - -#define COLDFIRE TYPE_COLDFIRE - -/* Extension word formats */ -#define EXT_8BIT_DISPLACEMENT(A) ((A)&0xff) -#define EXT_FULL(A) BIT_8(A) -#define EXT_EFFECTIVE_ZERO(A) (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0) -#define EXT_BASE_REGISTER_PRESENT(A) (!BIT_7(A)) -#define EXT_INDEX_REGISTER_PRESENT(A) (!BIT_6(A)) -#define EXT_INDEX_REGISTER(A) (((A)>>12)&7) -#define EXT_INDEX_PRE_POST(A) (EXT_INDEX_PRESENT(A) && (A)&3) -#define EXT_INDEX_PRE(A) (EXT_INDEX_PRESENT(A) && ((A)&7) < 4 && ((A)&7) != 0) -#define EXT_INDEX_POST(A) (EXT_INDEX_PRESENT(A) && ((A)&7) > 4) -#define EXT_INDEX_SCALE(A) (((A)>>9)&3) -#define EXT_INDEX_LONG(A) BIT_B(A) -#define EXT_INDEX_AR(A) BIT_F(A) -#define EXT_BASE_DISPLACEMENT_PRESENT(A) (((A)&0x30) > 0x10) -#define EXT_BASE_DISPLACEMENT_WORD(A) (((A)&0x30) == 0x20) -#define EXT_BASE_DISPLACEMENT_LONG(A) (((A)&0x30) == 0x30) -#define EXT_OUTER_DISPLACEMENT_PRESENT(A) (((A)&3) > 1 && ((A)&0x47) < 0x44) -#define EXT_OUTER_DISPLACEMENT_WORD(A) (((A)&3) == 2 && ((A)&0x47) < 0x44) -#define EXT_OUTER_DISPLACEMENT_LONG(A) (((A)&3) == 3 && ((A)&0x47) < 0x44) - - -/* Opcode flags */ -#define SET_OPCODE_FLAGS(x) g_opcode_type = x; -#define COMBINE_OPCODE_FLAGS(x) ((x) | g_opcode_type | DASMFLAG_SUPPORTED) - - -/* ======================================================================== */ -/* =============================== PROTOTYPES ============================= */ -/* ======================================================================== */ - -/* Read data at the PC and increment PC */ -uint32_t read_imm_8(void); -uint32_t read_imm_16(void); -uint32_t read_imm_32(void); - -/* Read data at the PC but don't imcrement the PC */ -uint32_t peek_imm_8(void); -uint32_t peek_imm_16(void); -uint32_t peek_imm_32(void); - -/* make signed integers 100% portably */ -static int make_int_8(int value); -static int make_int_16(int value); -static int make_int_32(int value); - -/* make a string of a hex value */ -static char* make_signed_hex_str_8(uint32_t val); -static char* make_signed_hex_str_16(uint32_t val); -static char* make_signed_hex_str_32(uint32_t val); - -/* make string of ea mode */ -static char* get_ea_mode_str(uint32_t instruction, uint32_t size); - -char* get_ea_mode_str_8(uint32_t instruction); -char* get_ea_mode_str_16(uint32_t instruction); -char* get_ea_mode_str_32(uint32_t instruction); - -/* make string of immediate value */ -static char* get_imm_str_s(uint32_t size); -static char* get_imm_str_u(uint32_t size); - -char* get_imm_str_s8(void); -char* get_imm_str_s16(void); -char* get_imm_str_s32(void); - -/* Stuff to build the opcode handler jump table */ -static void build_opcode_table(void); -static int valid_ea(uint32_t opcode, uint32_t mask); -static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr); - -/* used to build opcode handler jump table */ -struct opcode_struct -{ - void (*opcode_handler)(void); /* handler function */ - uint32_t mask; /* mask on opcode */ - uint32_t match; /* what to match after masking */ - uint32_t ea_mask; /* what ea modes are allowed */ -}; - - - -/* ======================================================================== */ -/* ================================= DATA ================================= */ -/* ======================================================================== */ - -/* Opcode handler jump table */ -static void (*g_instruction_table[0x10000])(void); -/* Flag if disassembler initialized */ -static int g_initialized = 0; - -static char g_dasm_str[100]; /* string to hold disassembly */ -static char g_helper_str[100]; /* string to hold helpful info */ -static uint32_t g_cpu_pc; /* program counter */ -static uint32_t g_cpu_ir; /* instruction register */ -static uint32_t g_cpu_type; -static uint32_t g_opcode_type; -static const unsigned char* g_rawop; -static uint32_t g_rawbasepc; - -/* used by ops like asr, ror, addq, etc */ -static const uint32_t g_3bit_qdata_table[8] = {8, 1, 2, 3, 4, 5, 6, 7}; - -static const uint32_t g_5bit_data_table[32] = -{ - 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 -}; - -static const char *const g_cc[16] = -{"t", "f", "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi", "ge", "lt", "gt", "le"}; - -static const char *const g_cpcc[64] = -{/* 000 001 010 011 100 101 110 111 */ - "f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or", /* 000 */ - "un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t", /* 001 */ - "sf", "seq", "gt", "ge", "lt", "le", "gl" "gle", /* 010 */ - "ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st", /* 011 */ - "?", "?", "?", "?", "?", "?", "?", "?", /* 100 */ - "?", "?", "?", "?", "?", "?", "?", "?", /* 101 */ - "?", "?", "?", "?", "?", "?", "?", "?", /* 110 */ - "?", "?", "?", "?", "?", "?", "?", "?" /* 111 */ -}; - -static const char *const g_mmuregs[8] = -{ - "tc", "drp", "srp", "crp", "cal", "val", "sccr", "acr" -}; - -static const char *const g_mmucond[16] = -{ - "bs", "bc", "ls", "lc", "ss", "sc", "as", "ac", - "ws", "wc", "is", "ic", "gs", "gc", "cs", "cc" -}; - -/* ======================================================================== */ -/* =========================== UTILITY FUNCTIONS ========================== */ -/* ======================================================================== */ - -#define LIMIT_CPU_TYPES(ALLOWED_CPU_TYPES) \ - if(!(g_cpu_type & ALLOWED_CPU_TYPES)) \ - { \ - if((g_cpu_ir & 0xf000) == 0xf000) \ - d68000_1111(); \ - else d68000_illegal(); \ - return; \ - } - -static uint32_t dasm_read_imm_8(uint32_t advance) -{ - uint32_t result; - result = g_rawop[g_cpu_pc + 1 - g_rawbasepc]; - g_cpu_pc += advance; - return result; -} - -static uint32_t dasm_read_imm_16(uint32_t advance) -{ - uint32_t result; - result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 8) | - g_rawop[g_cpu_pc + 1 - g_rawbasepc]; - g_cpu_pc += advance; - return result; -} - -static uint32_t dasm_read_imm_32(uint32_t advance) -{ - uint32_t result; - result = (g_rawop[g_cpu_pc + 0 - g_rawbasepc] << 24) | - (g_rawop[g_cpu_pc + 1 - g_rawbasepc] << 16) | - (g_rawop[g_cpu_pc + 2 - g_rawbasepc] << 8) | - g_rawop[g_cpu_pc + 3 - g_rawbasepc]; - g_cpu_pc += advance; - return result; -} - -#define read_imm_8() dasm_read_imm_8(2) -#define read_imm_16() dasm_read_imm_16(2) -#define read_imm_32() dasm_read_imm_32(4) - -#define peek_imm_8() dasm_read_imm_8(0) -#define peek_imm_16() dasm_read_imm_16(0) -#define peek_imm_32() dasm_read_imm_32(0) - -/* Fake a split interface */ -#define get_ea_mode_str_8(instruction) get_ea_mode_str(instruction, 0) -#define get_ea_mode_str_16(instruction) get_ea_mode_str(instruction, 1) -#define get_ea_mode_str_32(instruction) get_ea_mode_str(instruction, 2) - -#define get_imm_str_s8() get_imm_str_s(0) -#define get_imm_str_s16() get_imm_str_s(1) -#define get_imm_str_s32() get_imm_str_s(2) - -#define get_imm_str_u8() get_imm_str_u(0) -#define get_imm_str_u16() get_imm_str_u(1) -#define get_imm_str_u32() get_imm_str_u(2) - -static int sext_7bit_int(int value) -{ - return (value & 0x40) ? (value | 0xffffff80) : (value & 0x7f); -} - - -/* 100% portable signed int generators */ -static int make_int_8(int value) -{ - return (value & 0x80) ? value | ~0xff : value & 0xff; -} - -static int make_int_16(int value) -{ - return (value & 0x8000) ? value | ~0xffff : value & 0xffff; -} - -static int make_int_32(int value) -{ - return (value & 0x80000000) ? value | ~0xffffffff : value & 0xffffffff; -} - -/* Get string representation of hex values */ -static char* make_signed_hex_str_8(uint32_t val) +std::string m68k_disassembler::make_signed_hex_str_8(u8 val) { - static char str[20]; - - val &= 0xff; - if(val == 0x80) - sprintf(str, "-$80"); + return "-$80"; else if(val & 0x80) - sprintf(str, "-$%x", (0-val) & 0x7f); + return util::string_format("-$%x", (-val) & 0x7f); else - sprintf(str, "$%x", val & 0x7f); - - return str; + return util::string_format("$%x", val & 0x7f); } -static char* make_signed_hex_str_16(uint32_t val) +std::string m68k_disassembler::make_signed_hex_str_16(u16 val) { - static char str[20]; - - val &= 0xffff; - if(val == 0x8000) - sprintf(str, "-$8000"); + return "-$8000"; else if(val & 0x8000) - sprintf(str, "-$%x", (0-val) & 0x7fff); + return util::string_format("-$%x", (-val) & 0x7fff); else - sprintf(str, "$%x", val & 0x7fff); - - return str; + return util::string_format("$%x", val & 0x7fff); } -static char* make_signed_hex_str_32(uint32_t val) +std::string m68k_disassembler::make_signed_hex_str_32(u32 val) { - static char str[20]; - - val &= 0xffffffff; - if(val == 0x80000000) - sprintf(str, "-$80000000"); + return "-$80000000"; else if(val & 0x80000000) - sprintf(str, "-$%x", (0-val) & 0x7fffffff); + return util::string_format("-$%x", (-val) & 0x7fffffff); else - sprintf(str, "$%x", val & 0x7fffffff); - - return str; + return util::string_format("$%x", val & 0x7fffffff); } - -/* make string of immediate value */ -static char* get_imm_str_s(uint32_t size) +std::string m68k_disassembler::get_imm_str_s(u32 size) { - static char str[15]; - if(size == 0) - sprintf(str, "#%s", make_signed_hex_str_8(read_imm_8())); - else if(size == 1) - sprintf(str, "#%s", make_signed_hex_str_16(read_imm_16())); - else - sprintf(str, "#%s", make_signed_hex_str_32(read_imm_32())); - return str; + switch(size) { + case 0: return util::string_format("#%s", make_signed_hex_str_8(read_imm_8())); + case 1: return util::string_format("#%s", make_signed_hex_str_16(read_imm_16())); + case 2: return util::string_format("#%s", make_signed_hex_str_32(read_imm_32())); + default: abort(); + } } -static char* get_imm_str_u(uint32_t size) +std::string m68k_disassembler::get_imm_str_u(u32 size) { - static char str[15]; - if(size == 0) - sprintf(str, "#$%x", read_imm_8() & 0xff); - else if(size == 1) - sprintf(str, "#$%x", read_imm_16() & 0xffff); - else - sprintf(str, "#$%x", read_imm_32() & 0xffffffff); - return str; -} - -/* Make string of effective address mode */ -static char* get_ea_mode_str(uint32_t instruction, uint32_t size) -{ - static char b1[64]; - static char b2[64]; - static char* mode = b2; - uint32_t extension; - uint32_t base; - uint32_t outer; - char base_reg[4]; - char index_reg[8]; - uint32_t preindex; - uint32_t postindex; - uint32_t comma = 0; - uint32_t temp_value; - char invalid_mode = 0; - - /* Switch buffers so we don't clobber on a double-call to this function */ - mode = mode == b1 ? b2 : b1; + switch(size) { + case 0: return util::string_format("#$%x", read_imm_8()); + case 1: return util::string_format("#$%x", read_imm_16()); + case 2: return util::string_format("#$%x", read_imm_32()); + default: abort(); + } +} +std::string m68k_disassembler::get_ea_mode_str(u16 instruction, u32 size) +{ switch(instruction & 0x3f) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: /* data register direct */ - sprintf(mode, "D%d", instruction&7); + return util::string_format("D%d", instruction&7); break; case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: /* address register direct */ - sprintf(mode, "A%d", instruction&7); + return util::string_format("A%d", instruction&7); break; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: /* address register indirect */ - sprintf(mode, "(A%d)", instruction&7); + return util::string_format("(A%d)", instruction&7); break; case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: /* address register indirect with postincrement */ - sprintf(mode, "(A%d)+", instruction&7); + return util::string_format("(A%d)+", instruction&7); break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: /* address register indirect with predecrement */ - sprintf(mode, "-(A%d)", instruction&7); + return util::string_format("-(A%d)", instruction&7); break; case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: /* address register indirect with displacement*/ - sprintf(mode, "(%s,A%d)", make_signed_hex_str_16(read_imm_16()), instruction&7); + return util::string_format("(%s,A%d)", make_signed_hex_str_16(read_imm_16()), instruction&7); break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + { /* address register indirect with index */ - extension = read_imm_16(); + u16 extension = read_imm_16(); - if((g_cpu_type & M68010_LESS) && EXT_INDEX_SCALE(extension)) - { - invalid_mode = 1; + if((m_cpu_type & M68010_LESS) && ext_index_scale(extension)) break; - } - if(EXT_FULL(extension)) + if(ext_full(extension)) { - if(g_cpu_type & M68010_LESS) - { - invalid_mode = 1; + if(m_cpu_type & M68010_LESS) break; - } - if(EXT_EFFECTIVE_ZERO(extension)) - { - strcpy(mode, "0"); - break; - } + if(ext_effective_zero(extension)) + return "0"; - base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - if(EXT_BASE_REGISTER_PRESENT(extension)) - sprintf(base_reg, "A%d", instruction&7); - else - *base_reg = 0; - if(EXT_INDEX_REGISTER_PRESENT(extension)) - { - sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension)); - } - else - *index_reg = 0; - preindex = (extension&7) > 0 && (extension&7) < 4; - postindex = (extension&7) > 4; + u32 base = ext_base_displacement_present(extension) ? (ext_base_displacement_long(extension) ? read_imm_32() : read_imm_16()) : 0; + u32 outer = ext_outer_displacement_present(extension) ? (ext_outer_displacement_long(extension) ? read_imm_32() : read_imm_16()) : 0; + std::string base_reg = ext_base_register_present(extension) ? util::string_format("A%d", instruction&7) : ""; + std::string index_reg = ext_index_register_present(extension) ? + util::string_format("%c%d.%c%s", ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w', + ext_index_scale(extension) ? util::string_format("*%d", 1 << ext_index_scale(extension)) : "") + : ""; + + bool preindex = (extension&7) > 0 && (extension&7) < 4; + bool postindex = (extension&7) > 4; - strcpy(mode, "("); + std::string mode = "("; if(preindex || postindex) - strcat(mode, "["); + mode += '['; + bool comma = false; if(base) { - if (EXT_BASE_DISPLACEMENT_LONG(extension)) - { - strcat(mode, make_signed_hex_str_32(base)); - } + if(ext_base_displacement_long(extension)) + mode += make_signed_hex_str_32(base); else - { - strcat(mode, make_signed_hex_str_16(base)); - } - comma = 1; + mode += make_signed_hex_str_16(base); + comma = true; } - if(*base_reg) + if(!base_reg.empty()) { if(comma) - strcat(mode, ","); - strcat(mode, base_reg); - comma = 1; + mode += ','; + mode += base_reg; + comma = true; } if(postindex) { - strcat(mode, "]"); - comma = 1; + mode += ']'; + comma = true; } - if(*index_reg) + if(!index_reg.empty()) { if(comma) - strcat(mode, ","); - strcat(mode, index_reg); - comma = 1; + mode += ','; + mode += index_reg; + comma = true; } if(preindex) { - strcat(mode, "]"); - comma = 1; + mode += ']'; } if(outer) { if(comma) - strcat(mode, ","); - strcat(mode, make_signed_hex_str_16(outer)); + mode += ','; + mode += make_signed_hex_str_16(outer); } - strcat(mode, ")"); - break; + mode += ')'; + return mode; } - if(EXT_8BIT_DISPLACEMENT(extension) == 0) - sprintf(mode, "(A%d,%c%d.%c", instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - else - sprintf(mode, "(%s,A%d,%c%d.%c", make_signed_hex_str_8(extension), instruction&7, EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension)); - strcat(mode, ")"); - break; + std::string mode = ext_8bit_displacement(extension) ? + util::string_format("(%s,A%d,%c%d.%c", make_signed_hex_str_8(extension), instruction&7, ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w') : + util::string_format("(A%d,%c%d.%c", instruction&7, ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w'); + if(ext_index_scale(extension)) + mode += util::string_format("*%d", 1 << ext_index_scale(extension)); + mode += ')'; + return mode; + } case 0x38: /* absolute short address */ - sprintf(mode, "$%x.w", read_imm_16()); + return util::string_format("$%x.w", read_imm_16()); break; case 0x39: /* absolute long address */ - sprintf(mode, "$%x.l", read_imm_32()); + return util::string_format("$%x.l", read_imm_32()); break; case 0x3a: + { /* program counter with displacement */ - temp_value = read_imm_16(); - sprintf(mode, "(%s,PC)", make_signed_hex_str_16(temp_value)); - sprintf(g_helper_str, "; ($%x)", (make_int_16(temp_value) + g_cpu_pc-2) & 0xffffffff); - break; + u16 temp_value = read_imm_16(); + return util::string_format("(%s,PC) ; ($%x)", make_signed_hex_str_16(temp_value), + (make_int_16(temp_value) + m_cpu_pc-2) & 0xffffffff); + } case 0x3b: + { /* program counter with index */ - extension = read_imm_16(); + u16 extension = read_imm_16(); - if((g_cpu_type & M68010_LESS) && EXT_INDEX_SCALE(extension)) - { - invalid_mode = 1; + if((m_cpu_type & M68010_LESS) && ext_index_scale(extension)) break; - } - if(EXT_FULL(extension)) + if(ext_full(extension)) { - if(g_cpu_type & M68010_LESS) - { - invalid_mode = 1; - break; - } - - if(EXT_EFFECTIVE_ZERO(extension)) - { - strcpy(mode, "0"); + if(m_cpu_type & M68010_LESS) break; - } - base = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - outer = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32() : read_imm_16()) : 0; - if(EXT_BASE_REGISTER_PRESENT(extension)) - strcpy(base_reg, "PC"); - else - *base_reg = 0; - if(EXT_INDEX_REGISTER_PRESENT(extension)) - { - sprintf(index_reg, "%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(index_reg+strlen(index_reg), "*%d", 1 << EXT_INDEX_SCALE(extension)); - } - else - *index_reg = 0; - preindex = (extension&7) > 0 && (extension&7) < 4; - postindex = (extension&7) > 4; - strcpy(mode, "("); + if(ext_effective_zero(extension)) + return "0"; + + u32 base = ext_base_displacement_present(extension) ? (ext_base_displacement_long(extension) ? read_imm_32() : read_imm_16()) : 0; + u32 outer = ext_outer_displacement_present(extension) ? (ext_outer_displacement_long(extension) ? read_imm_32() : read_imm_16()) : 0; + std::string base_reg = ext_base_register_present(extension) ? "PC" : ""; + std::string index_reg = + ext_index_register_present(extension) ? + util::string_format("%c%d.%c%s", ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w', + ext_index_scale(extension) ? + util::string_format("*%d", 1 << ext_index_scale(extension)) : "") : ""; + bool preindex = (extension&7) > 0 && (extension&7) < 4; + bool postindex = (extension&7) > 4; + + bool comma = false; + std::string mode = "("; if(preindex || postindex) - strcat(mode, "["); + mode += '['; if(base) { - strcat(mode, make_signed_hex_str_16(base)); - comma = 1; + mode += make_signed_hex_str_16(base); + comma = true; } - if(*base_reg) + if(!base_reg.empty()) { if(comma) - strcat(mode, ","); - strcat(mode, base_reg); - comma = 1; + mode += ','; + mode += base_reg; + comma = true; } if(postindex) { - strcat(mode, "]"); - comma = 1; + mode += ']'; + comma = true; } - if(*index_reg) + if(!index_reg.empty()) { if(comma) - strcat(mode, ","); - strcat(mode, index_reg); - comma = 1; + mode += ','; + mode += index_reg; + comma = true; } if(preindex) { - strcat(mode, "]"); - comma = 1; + mode += ']'; + comma = true; } if(outer) { if(comma) - strcat(mode, ","); - strcat(mode, make_signed_hex_str_16(outer)); + mode += ','; + mode += make_signed_hex_str_16(outer); } - strcat(mode, ")"); - break; + mode += ')'; + return mode; } - if(EXT_8BIT_DISPLACEMENT(extension) == 0) - sprintf(mode, "(PC,%c%d.%c", EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - else - sprintf(mode, "(%s,PC,%c%d.%c", make_signed_hex_str_8(extension), EXT_INDEX_AR(extension) ? 'A' : 'D', EXT_INDEX_REGISTER(extension), EXT_INDEX_LONG(extension) ? 'l' : 'w'); - if(EXT_INDEX_SCALE(extension)) - sprintf(mode+strlen(mode), "*%d", 1 << EXT_INDEX_SCALE(extension)); - strcat(mode, ")"); - break; + std::string mode = ext_8bit_displacement(extension) ? + util::string_format("(%s,PC,%c%d.%c", make_signed_hex_str_8(extension), ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w') : + util::string_format("(PC,%c%d.%c", ext_index_ar(extension) ? 'A' : 'D', ext_index_register(extension), ext_index_long(extension) ? 'l' : 'w'); + + if(ext_index_scale(extension)) + mode += util::string_format("*%d", 1 << ext_index_scale(extension)); + mode += ')'; + return mode; + } case 0x3c: /* Immediate */ - sprintf(mode, "%s", get_imm_str_u(size)); - break; - default: - invalid_mode = 1; + return get_imm_str_u(size); } - if(invalid_mode) - sprintf(mode, "INVALID %x", instruction & 0x3f); - - return mode; + return util::string_format("INVALID %x", instruction & 0x3f); } +/* ======================================================================== */ +/* ================================= DATA ================================= */ +/* ======================================================================== */ + +/* used by ops like asr, ror, addq, etc */ +const u32 m68k_disassembler::m_3bit_qdata_table[8] = {8, 1, 2, 3, 4, 5, 6, 7}; + +const u32 m68k_disassembler::m_5bit_data_table[32] = +{ + 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; + +const char *const m68k_disassembler::m_cc[16] = +{ + "t", "f", "hi", "ls", "cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi", "ge", "lt", "gt", "le" +}; + +const char *const m68k_disassembler::m_cpcc[64] = +{/* 000 001 010 011 100 101 110 111 */ + "f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or", /* 000 */ + "un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t", /* 001 */ + "sf", "seq", "gt", "ge", "lt", "le", "gl" "gle", /* 010 */ + "ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st", /* 011 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 100 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 101 */ + "?", "?", "?", "?", "?", "?", "?", "?", /* 110 */ + "?", "?", "?", "?", "?", "?", "?", "?" /* 111 */ +}; + +const char *const m68k_disassembler::m_mmuregs[8] = +{ + "tc", "drp", "srp", "crp", "cal", "val", "sccr", "acr" +}; + +const char *const m68k_disassembler::m_mmucond[16] = +{ + "bs", "bc", "ls", "lc", "ss", "sc", "as", "ac", + "ws", "wc", "is", "ic", "gs", "gc", "cs", "cc" +}; +std::pair<bool, std::string> m68k_disassembler::limit_cpu_types(u32 allowed) +{ + if(!(m_cpu_type & allowed)) + { + if((m_cpu_ir & 0xf000) == 0xf000) + return std::make_pair(true, d68000_1111()); + else + return std::make_pair(true, d68000_illegal()); + } + return std::make_pair(false, std::string()); +} /* ======================================================================== */ /* ========================= INSTRUCTION HANDLERS ========================= */ @@ -691,578 +372,534 @@ static char* get_ea_mode_str(uint32_t instruction, uint32_t size) * al : absolute long */ -static void d68000_illegal(void) +std::string m68k_disassembler::d68000_illegal() { - sprintf(g_dasm_str, "dc.w $%04x; ILLEGAL", g_cpu_ir); + return util::string_format("dc.w $%04x; ILLEGAL", m_cpu_ir); } -static void d68000_1010(void) +std::string m68k_disassembler::d68000_1010() { - sprintf(g_dasm_str, "dc.w $%04x; opcode 1010", g_cpu_ir); + return util::string_format("dc.w $%04x; opcode 1010", m_cpu_ir); } -static void d68000_1111(void) +std::string m68k_disassembler::d68000_1111() { - sprintf(g_dasm_str, "dc.w $%04x; opcode 1111", g_cpu_ir); + return util::string_format("dc.w $%04x; opcode 1111", m_cpu_ir); } -static void d68000_abcd_rr(void) +std::string m68k_disassembler::d68000_abcd_rr() { - sprintf(g_dasm_str, "abcd D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("abcd D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_abcd_mm(void) +std::string m68k_disassembler::d68000_abcd_mm() { - sprintf(g_dasm_str, "abcd -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("abcd -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_add_er_8(void) +std::string m68k_disassembler::d68000_add_er_8() { - sprintf(g_dasm_str, "add.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("add.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_add_er_16(void) +std::string m68k_disassembler::d68000_add_er_16() { - sprintf(g_dasm_str, "add.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("add.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_add_er_32(void) +std::string m68k_disassembler::d68000_add_er_32() { - sprintf(g_dasm_str, "add.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("add.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_add_re_8(void) +std::string m68k_disassembler::d68000_add_re_8() { - sprintf(g_dasm_str, "add.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("add.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_add_re_16(void) +std::string m68k_disassembler::d68000_add_re_16() { - sprintf(g_dasm_str, "add.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("add.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_add_re_32(void) +std::string m68k_disassembler::d68000_add_re_32() { - sprintf(g_dasm_str, "add.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("add.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_adda_16(void) +std::string m68k_disassembler::d68000_adda_16() { - sprintf(g_dasm_str, "adda.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("adda.w %s, A%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_adda_32(void) +std::string m68k_disassembler::d68000_adda_32() { - sprintf(g_dasm_str, "adda.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("adda.l %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_addi_8(void) +std::string m68k_disassembler::d68000_addi_8() { - char* str = get_imm_str_s8(); - sprintf(g_dasm_str, "addi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_s8(); + return util::string_format("addi.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_addi_16(void) +std::string m68k_disassembler::d68000_addi_16() { - char* str = get_imm_str_s16(); - sprintf(g_dasm_str, "addi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_s16(); + return util::string_format("addi.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_addi_32(void) +std::string m68k_disassembler::d68000_addi_32() { - char* str = get_imm_str_s32(); - sprintf(g_dasm_str, "addi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_s32(); + return util::string_format("addi.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_addq_8(void) +std::string m68k_disassembler::d68000_addq_8() { - sprintf(g_dasm_str, "addq.b #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("addq.b #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_addq_16(void) +std::string m68k_disassembler::d68000_addq_16() { - sprintf(g_dasm_str, "addq.w #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("addq.w #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_addq_32(void) +std::string m68k_disassembler::d68000_addq_32() { - sprintf(g_dasm_str, "addq.l #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("addq.l #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_addx_rr_8(void) +std::string m68k_disassembler::d68000_addx_rr_8() { - sprintf(g_dasm_str, "addx.b D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.b D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_rr_16(void) +std::string m68k_disassembler::d68000_addx_rr_16() { - sprintf(g_dasm_str, "addx.w D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.w D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_rr_32(void) +std::string m68k_disassembler::d68000_addx_rr_32() { - sprintf(g_dasm_str, "addx.l D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.l D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_mm_8(void) +std::string m68k_disassembler::d68000_addx_mm_8() { - sprintf(g_dasm_str, "addx.b -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.b -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_mm_16(void) +std::string m68k_disassembler::d68000_addx_mm_16() { - sprintf(g_dasm_str, "addx.w -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.w -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_addx_mm_32(void) +std::string m68k_disassembler::d68000_addx_mm_32() { - sprintf(g_dasm_str, "addx.l -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("addx.l -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_and_er_8(void) +std::string m68k_disassembler::d68000_and_er_8() { - sprintf(g_dasm_str, "and.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("and.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_and_er_16(void) +std::string m68k_disassembler::d68000_and_er_16() { - sprintf(g_dasm_str, "and.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("and.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_and_er_32(void) +std::string m68k_disassembler::d68000_and_er_32() { - sprintf(g_dasm_str, "and.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("and.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_and_re_8(void) +std::string m68k_disassembler::d68000_and_re_8() { - sprintf(g_dasm_str, "and.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("and.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_and_re_16(void) +std::string m68k_disassembler::d68000_and_re_16() { - sprintf(g_dasm_str, "and.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("and.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_and_re_32(void) +std::string m68k_disassembler::d68000_and_re_32() { - sprintf(g_dasm_str, "and.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("and.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_andi_8(void) +std::string m68k_disassembler::d68000_andi_8() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "andi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("andi.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_andi_16(void) +std::string m68k_disassembler::d68000_andi_16() { - char* str = get_imm_str_u16(); - sprintf(g_dasm_str, "andi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_u16(); + return util::string_format("andi.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_andi_32(void) +std::string m68k_disassembler::d68000_andi_32() { - char* str = get_imm_str_u32(); - sprintf(g_dasm_str, "andi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_u32(); + return util::string_format("andi.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_andi_to_ccr(void) +std::string m68k_disassembler::d68000_andi_to_ccr() { - sprintf(g_dasm_str, "andi %s, CCR", get_imm_str_u8()); + return util::string_format("andi %s, CCR", get_imm_str_u8()); } -static void d68000_andi_to_sr(void) +std::string m68k_disassembler::d68000_andi_to_sr() { - sprintf(g_dasm_str, "andi %s, SR", get_imm_str_u16()); + return util::string_format("andi %s, SR", get_imm_str_u16()); } -static void d68000_asr_s_8(void) +std::string m68k_disassembler::d68000_asr_s_8() { - sprintf(g_dasm_str, "asr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asr.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asr_s_16(void) +std::string m68k_disassembler::d68000_asr_s_16() { - sprintf(g_dasm_str, "asr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asr.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asr_s_32(void) +std::string m68k_disassembler::d68000_asr_s_32() { - sprintf(g_dasm_str, "asr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asr.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asr_r_8(void) +std::string m68k_disassembler::d68000_asr_r_8() { - sprintf(g_dasm_str, "asr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asr.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asr_r_16(void) +std::string m68k_disassembler::d68000_asr_r_16() { - sprintf(g_dasm_str, "asr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asr.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asr_r_32(void) +std::string m68k_disassembler::d68000_asr_r_32() { - sprintf(g_dasm_str, "asr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asr.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asr_ea(void) +std::string m68k_disassembler::d68000_asr_ea() { - sprintf(g_dasm_str, "asr.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("asr.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_asl_s_8(void) +std::string m68k_disassembler::d68000_asl_s_8() { - sprintf(g_dasm_str, "asl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asl.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asl_s_16(void) +std::string m68k_disassembler::d68000_asl_s_16() { - sprintf(g_dasm_str, "asl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asl.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asl_s_32(void) +std::string m68k_disassembler::d68000_asl_s_32() { - sprintf(g_dasm_str, "asl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("asl.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_asl_r_8(void) +std::string m68k_disassembler::d68000_asl_r_8() { - sprintf(g_dasm_str, "asl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asl.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asl_r_16(void) +std::string m68k_disassembler::d68000_asl_r_16() { - sprintf(g_dasm_str, "asl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asl.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asl_r_32(void) +std::string m68k_disassembler::d68000_asl_r_32() { - sprintf(g_dasm_str, "asl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("asl.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_asl_ea(void) +std::string m68k_disassembler::d68000_asl_ea() { - sprintf(g_dasm_str, "asl.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("asl.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_bcc_8(void) +std::string m68k_disassembler::d68000_bcc_8() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "b%-2s $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_8(g_cpu_ir)); + u32 temp_pc = m_cpu_pc; + return util::string_format("b%-2s $%x", m_cc[(m_cpu_ir>>8)&0xf], temp_pc + make_int_8(m_cpu_ir)); } -static void d68000_bcc_16(void) +std::string m68k_disassembler::d68000_bcc_16() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "b%-2s $%x", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + make_int_16(read_imm_16())); + u32 temp_pc = m_cpu_pc; + return util::string_format("b%-2s $%x", m_cc[(m_cpu_ir>>8)&0xf], temp_pc + make_int_16(read_imm_16())); } -static void d68020_bcc_32(void) +std::string m68k_disassembler::d68020_bcc_32() { - uint32_t temp_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "b%-2s $%x; (2+)", g_cc[(g_cpu_ir>>8)&0xf], temp_pc + read_imm_32()); + u32 temp_pc = m_cpu_pc; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("b%-2s $%x; (2+)", m_cc[(m_cpu_ir>>8)&0xf], temp_pc + read_imm_32()); } -static void d68000_bchg_r(void) +std::string m68k_disassembler::d68000_bchg_r() { - sprintf(g_dasm_str, "bchg D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("bchg D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bchg_s(void) +std::string m68k_disassembler::d68000_bchg_s() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "bchg %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("bchg %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bclr_r(void) +std::string m68k_disassembler::d68000_bclr_r() { - sprintf(g_dasm_str, "bclr D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("bclr D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bclr_s(void) +std::string m68k_disassembler::d68000_bclr_s() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "bclr %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("bclr %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68010_bkpt(void) +std::string m68k_disassembler::d68010_bkpt() { - LIMIT_CPU_TYPES(M68010_PLUS); - sprintf(g_dasm_str, "bkpt #%d; (1+)", g_cpu_ir&7); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + return util::string_format("bkpt #%d; (1+)", m_cpu_ir&7); } -static void d68020_bfchg(void) +std::string m68k_disassembler::d68020_bfchg() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfchg %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfchg %s {%s:%s}; (2+)", get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfclr(void) +std::string m68k_disassembler::d68020_bfclr() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfclr %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfclr %s {%s:%s}; (2+)", get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfexts(void) +std::string m68k_disassembler::d68020_bfexts() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfexts D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfexts D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfextu(void) +std::string m68k_disassembler::d68020_bfextu() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfextu D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfextu D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfffo(void) +std::string m68k_disassembler::d68020_bfffo() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfffo D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfffo D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfins(void) +std::string m68k_disassembler::d68020_bfins() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfins D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfins D%d, %s {%s:%s}; (2+)", (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bfset(void) +std::string m68k_disassembler::d68020_bfset() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bfset %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bfset %s {%s:%s}; (2+)", get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68020_bftst(void) +std::string m68k_disassembler::d68020_bftst() { - uint32_t extension; - char offset[3]; - char width[3]; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - LIMIT_CPU_TYPES(M68020_PLUS); + u16 extension = read_imm_16(); - extension = read_imm_16(); + std::string offset = BIT(extension, 11) ? util::string_format("D%d", (extension>>6)&7) : util::string_format("%d", (extension>>6)&31); - if(BIT_B(extension)) - sprintf(offset, "D%d", (extension>>6)&7); - else - sprintf(offset, "%d", (extension>>6)&31); - if(BIT_5(extension)) - sprintf(width, "D%d", extension&7); - else - sprintf(width, "%d", g_5bit_data_table[extension&31]); - sprintf(g_dasm_str, "bftst %s {%s:%s}; (2+)", get_ea_mode_str_8(g_cpu_ir), offset, width); + std::string width = BIT(extension, 5) ? util::string_format("D%d", extension&7) : util::string_format("%d", m_5bit_data_table[extension&31]); + return util::string_format("bftst %s {%s:%s}; (2+)", get_ea_mode_str_8(m_cpu_ir), offset, width); } -static void d68000_bra_8(void) +std::string m68k_disassembler::d68000_bra_8() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bra $%x", temp_pc + make_int_8(g_cpu_ir)); + u32 temp_pc = m_cpu_pc; + return util::string_format("bra $%x", temp_pc + make_int_8(m_cpu_ir)); } -static void d68000_bra_16(void) +std::string m68k_disassembler::d68000_bra_16() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bra $%x", temp_pc + make_int_16(read_imm_16())); + u32 temp_pc = m_cpu_pc; + return util::string_format("bra $%x", temp_pc + make_int_16(read_imm_16())); } -static void d68020_bra_32(void) +std::string m68k_disassembler::d68020_bra_32() { - uint32_t temp_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "bra $%x; (2+)", temp_pc + read_imm_32()); + u32 temp_pc = m_cpu_pc; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("bra $%x; (2+)", temp_pc + read_imm_32()); } -static void d68000_bset_r(void) +std::string m68k_disassembler::d68000_bset_r() { - sprintf(g_dasm_str, "bset D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("bset D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bset_s(void) +std::string m68k_disassembler::d68000_bset_s() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "bset %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("bset %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_bsr_8(void) +std::string m68k_disassembler::d68000_bsr_8() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bsr $%x", temp_pc + make_int_8(g_cpu_ir)); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + m_flags = STEP_OVER; + return util::string_format("bsr $%x", temp_pc + make_int_8(m_cpu_ir)); } -static void d68000_bsr_16(void) +std::string m68k_disassembler::d68000_bsr_16() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "bsr $%x", temp_pc + make_int_16(read_imm_16())); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + m_flags = STEP_OVER; + return util::string_format("bsr $%x", temp_pc + make_int_16(read_imm_16())); } -static void d68020_bsr_32(void) +std::string m68k_disassembler::d68020_bsr_32() { - uint32_t temp_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "bsr $%x; (2+)", temp_pc + read_imm_32()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("bsr $%x; (2+)", temp_pc + read_imm_32()); } -static void d68000_btst_r(void) +std::string m68k_disassembler::d68000_btst_r() { - sprintf(g_dasm_str, "btst D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("btst D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_btst_s(void) +std::string m68k_disassembler::d68000_btst_s() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "btst %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("btst %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_callm(void) +std::string m68k_disassembler::d68020_callm() { - char* str; - LIMIT_CPU_TYPES(M68020_ONLY); - str = get_imm_str_u8(); + auto limit = limit_cpu_types(M68020_ONLY); + if(limit.first) + return limit.second; + std::string str = get_imm_str_u8(); - sprintf(g_dasm_str, "callm %s, %s; (2)", str, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("callm %s, %s; (2)", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_cas_8(void) +std::string m68k_disassembler::d68020_cas_8() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "cas.b D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("cas.b D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_cas_16(void) +std::string m68k_disassembler::d68020_cas_16() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "cas.w D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("cas.w D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_cas_32(void) +std::string m68k_disassembler::d68020_cas_32() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "cas.l D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("cas.l D%d, D%d, %s; (2+)", extension&7, (extension>>8)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_cas2_16(void) +std::string m68k_disassembler::d68020_cas2_16() { /* CAS2 Dc1:Dc2,Du1:Dc2:(Rn1):(Rn2) f e d c b a 9 8 7 6 5 4 3 2 1 0 @@ -1270,495 +907,520 @@ f e d c b a 9 8 7 6 5 4 3 2 1 0 DARn2 0 0 0 Du2 0 0 0 Dc2 */ - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_32(); - sprintf(g_dasm_str, "cas2.w D%d:D%d:D%d:D%d, (%c%d):(%c%d); (2+)", + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 extension = read_imm_32(); + return util::string_format("cas2.w D%d:D%d:D%d:D%d, (%c%d):(%c%d); (2+)", (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7, - BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7, - BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + BIT(extension, 31) ? 'A' : 'D', (extension>>28)&7, + BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68020_cas2_32(void) +std::string m68k_disassembler::d68020_cas2_32() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_32(); - sprintf(g_dasm_str, "cas2.l D%d:D%d:D%d:D%d, (%c%d):(%c%d); (2+)", + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 extension = read_imm_32(); + return util::string_format("cas2.l D%d:D%d:D%d:D%d, (%c%d):(%c%d); (2+)", (extension>>16)&7, extension&7, (extension>>22)&7, (extension>>6)&7, - BIT_1F(extension) ? 'A' : 'D', (extension>>28)&7, - BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + BIT(extension, 31) ? 'A' : 'D', (extension>>28)&7, + BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68000_chk_16(void) +std::string m68k_disassembler::d68000_chk_16() { - sprintf(g_dasm_str, "chk.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + m_flags = STEP_OVER; + return util::string_format("chk.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68020_chk_32(void) +std::string m68k_disassembler::d68020_chk_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "chk.l %s, D%d; (2+)", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("chk.l %s, D%d; (2+)", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68020_chk2_cmp2_8(void) +std::string m68k_disassembler::d68020_chk2_cmp2_8() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "%s.b %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("%s.b %s, %c%d; (2+)", BIT(extension, 11) ? "chk2" : "cmp2", get_ea_mode_str_8(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68020_chk2_cmp2_16(void) +std::string m68k_disassembler::d68020_chk2_cmp2_16() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "%s.w %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("%s.w %s, %c%d; (2+)", BIT(extension, 11) ? "chk2" : "cmp2", get_ea_mode_str_16(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68020_chk2_cmp2_32(void) +std::string m68k_disassembler::d68020_chk2_cmp2_32() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); - sprintf(g_dasm_str, "%s.l %s, %c%d; (2+)", BIT_B(extension) ? "chk2" : "cmp2", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + return util::string_format("%s.l %s, %c%d; (2+)", BIT(extension, 11) ? "chk2" : "cmp2", get_ea_mode_str_32(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68040_cinv(void) +std::string m68k_disassembler::d68040_cinv() { - LIMIT_CPU_TYPES(M68040_PLUS); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; static const char *cachetype[4] = { "nop", "data", "inst", "both" }; - switch((g_cpu_ir>>3)&3) + switch((m_cpu_ir>>3)&3) { case 0: - sprintf(g_dasm_str, "cinv (illegal scope); (4)"); + return util::string_format("cinv (illegal scope); (4)"); break; case 1: - sprintf(g_dasm_str, "cinvl %s, (A%d); (4)", cachetype[(g_cpu_ir>>6)&3], g_cpu_ir&7); + return util::string_format("cinvl %s, (A%d); (4)", cachetype[(m_cpu_ir>>6)&3], m_cpu_ir&7); break; case 2: - sprintf(g_dasm_str, "cinvp %s, (A%d); (4)", cachetype[(g_cpu_ir>>6)&3], g_cpu_ir&7); + return util::string_format("cinvp %s, (A%d); (4)", cachetype[(m_cpu_ir>>6)&3], m_cpu_ir&7); break; - case 3: - sprintf(g_dasm_str, "cinva %s; (4)", cachetype[(g_cpu_ir>>6)&3]); + case 3: default: + return util::string_format("cinva %s; (4)", cachetype[(m_cpu_ir>>6)&3]); break; } } -static void d68000_clr_8(void) +std::string m68k_disassembler::d68000_clr_8() { - sprintf(g_dasm_str, "clr.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("clr.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_clr_16(void) +std::string m68k_disassembler::d68000_clr_16() { - sprintf(g_dasm_str, "clr.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("clr.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_clr_32(void) +std::string m68k_disassembler::d68000_clr_32() { - sprintf(g_dasm_str, "clr.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("clr.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_cmp_8(void) +std::string m68k_disassembler::d68000_cmp_8() { - sprintf(g_dasm_str, "cmp.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmp.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmp_16(void) +std::string m68k_disassembler::d68000_cmp_16() { - sprintf(g_dasm_str, "cmp.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmp.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmp_32(void) +std::string m68k_disassembler::d68000_cmp_32() { - sprintf(g_dasm_str, "cmp.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmp.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmpa_16(void) +std::string m68k_disassembler::d68000_cmpa_16() { - sprintf(g_dasm_str, "cmpa.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmpa.w %s, A%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmpa_32(void) +std::string m68k_disassembler::d68000_cmpa_32() { - sprintf(g_dasm_str, "cmpa.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("cmpa.l %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_cmpi_8(void) +std::string m68k_disassembler::d68000_cmpi_8() { - char* str = get_imm_str_s8(); - sprintf(g_dasm_str, "cmpi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_s8(); + return util::string_format("cmpi.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_cmpi_pcdi_8(void) +std::string m68k_disassembler::d68020_cmpi_pcdi_8() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s8(); - sprintf(g_dasm_str, "cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s8(); + return util::string_format("cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_cmpi_pcix_8(void) +std::string m68k_disassembler::d68020_cmpi_pcix_8() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s8(); - sprintf(g_dasm_str, "cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s8(); + return util::string_format("cmpi.b %s, %s; (2+)", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_cmpi_16(void) +std::string m68k_disassembler::d68000_cmpi_16() { - char* str; - str = get_imm_str_s16(); - sprintf(g_dasm_str, "cmpi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_s16(); + return util::string_format("cmpi.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_cmpi_pcdi_16(void) +std::string m68k_disassembler::d68020_cmpi_pcdi_16() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s16(); - sprintf(g_dasm_str, "cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s16(); + return util::string_format("cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_cmpi_pcix_16(void) +std::string m68k_disassembler::d68020_cmpi_pcix_16() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s16(); - sprintf(g_dasm_str, "cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s16(); + return util::string_format("cmpi.w %s, %s; (2+)", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_cmpi_32(void) +std::string m68k_disassembler::d68000_cmpi_32() { - char* str; - str = get_imm_str_s32(); - sprintf(g_dasm_str, "cmpi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_s32(); + return util::string_format("cmpi.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_cmpi_pcdi_32(void) +std::string m68k_disassembler::d68020_cmpi_pcdi_32() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s32(); - sprintf(g_dasm_str, "cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s32(); + return util::string_format("cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_cmpi_pcix_32(void) +std::string m68k_disassembler::d68020_cmpi_pcix_32() { - char* str; - LIMIT_CPU_TYPES(M68010_PLUS); - str = get_imm_str_s32(); - sprintf(g_dasm_str, "cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + std::string str = get_imm_str_s32(); + return util::string_format("cmpi.l %s, %s; (2+)", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_cmpm_8(void) +std::string m68k_disassembler::d68000_cmpm_8() { - sprintf(g_dasm_str, "cmpm.b (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("cmpm.b (A%d)+, (A%d)+", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_cmpm_16(void) +std::string m68k_disassembler::d68000_cmpm_16() { - sprintf(g_dasm_str, "cmpm.w (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("cmpm.w (A%d)+, (A%d)+", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_cmpm_32(void) +std::string m68k_disassembler::d68000_cmpm_32() { - sprintf(g_dasm_str, "cmpm.l (A%d)+, (A%d)+", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("cmpm.l (A%d)+, (A%d)+", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68020_cpbcc_16(void) +std::string m68k_disassembler::d68020_cpbcc_16() { - uint32_t extension; - uint32_t new_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 new_pc = m_cpu_pc; + u16 extension = read_imm_16(); new_pc += make_int_16(read_imm_16()); - sprintf(g_dasm_str, "%db%-4s %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); + return util::string_format("%db%-4s %s; %x (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[m_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); } -static void d68020_cpbcc_32(void) +std::string m68k_disassembler::d68020_cpbcc_32() { - uint32_t extension; - uint32_t new_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 new_pc = m_cpu_pc; + u16 extension = read_imm_16(); new_pc += read_imm_32(); - sprintf(g_dasm_str, "%db%-4s %s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[g_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); + return util::string_format("%db%-4s %s; %x (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[m_cpu_ir&0x3f], get_imm_str_s16(), new_pc, extension); } -static void d68020_cpdbcc(void) +std::string m68k_disassembler::d68020_cpdbcc() { - uint32_t extension1; - uint32_t extension2; - uint32_t new_pc = g_cpu_pc; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u32 new_pc = m_cpu_pc; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); new_pc += make_int_16(read_imm_16()); - sprintf(g_dasm_str, "%ddb%-4s D%d,%s; %x (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], g_cpu_ir&7, get_imm_str_s16(), new_pc, extension2); + return util::string_format("%ddb%-4s D%d,%s; %x (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], m_cpu_ir&7, get_imm_str_s16(), new_pc, extension2); } -static void d68020_cpgen(void) +std::string m68k_disassembler::d68020_cpgen() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "%dgen %s; (2-3)", (g_cpu_ir>>9)&7, get_imm_str_u32()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("%dgen %s; (2-3)", (m_cpu_ir>>9)&7, get_imm_str_u32()); } -static void d68020_cprestore(void) +std::string m68k_disassembler::d68020_cprestore() { - LIMIT_CPU_TYPES(M68020_PLUS); - if (((g_cpu_ir>>9)&7) == 1) + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + if (((m_cpu_ir>>9)&7) == 1) { - sprintf(g_dasm_str, "frestore %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("frestore %s", get_ea_mode_str_8(m_cpu_ir)); } else { - sprintf(g_dasm_str, "%drestore %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("%drestore %s; (2-3)", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } } -static void d68020_cpsave(void) +std::string m68k_disassembler::d68020_cpsave() { - LIMIT_CPU_TYPES(M68020_PLUS); - if (((g_cpu_ir>>9)&7) == 1) + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + if (((m_cpu_ir>>9)&7) == 1) { - sprintf(g_dasm_str, "fsave %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("fsave %s", get_ea_mode_str_8(m_cpu_ir)); } else { - sprintf(g_dasm_str, "%dsave %s; (2-3)", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("%dsave %s; (2-3)", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } } -static void d68020_cpscc(void) +std::string m68k_disassembler::d68020_cpscc() { - uint32_t extension1; - uint32_t extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%ds%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_ea_mode_str_8(g_cpu_ir), extension2); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); + return util::string_format("%ds%-4s %s; (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], get_ea_mode_str_8(m_cpu_ir), extension2); } -static void d68020_cptrapcc_0(void) +std::string m68k_disassembler::d68020_cptrapcc_0() { - uint32_t extension1; - uint32_t extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%dtrap%-4s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], extension2); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); + return util::string_format("%dtrap%-4s; (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], extension2); } -static void d68020_cptrapcc_16(void) +std::string m68k_disassembler::d68020_cptrapcc_16() { - uint32_t extension1; - uint32_t extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u16(), extension2); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); + return util::string_format("%dtrap%-4s %s; (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], get_imm_str_u16(), extension2); } -static void d68020_cptrapcc_32(void) +std::string m68k_disassembler::d68020_cptrapcc_32() { - uint32_t extension1; - uint32_t extension2; - LIMIT_CPU_TYPES(M68020_PLUS); - extension1 = read_imm_16(); - extension2 = read_imm_16(); - sprintf(g_dasm_str, "%dtrap%-4s %s; (extension = %x) (2-3)", (g_cpu_ir>>9)&7, g_cpcc[extension1&0x3f], get_imm_str_u32(), extension2); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension1 = read_imm_16(); + u16 extension2 = read_imm_16(); + return util::string_format("%dtrap%-4s %s; (extension = %x) (2-3)", (m_cpu_ir>>9)&7, m_cpcc[extension1&0x3f], get_imm_str_u32(), extension2); } -static void d68040_cpush(void) +std::string m68k_disassembler::d68040_cpush() { + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + static const char *cachetype[4] = { "nop", "data", "inst", "both" }; - LIMIT_CPU_TYPES(M68040_PLUS); - switch((g_cpu_ir>>3)&3) + switch((m_cpu_ir>>3)&3) { case 0: - sprintf(g_dasm_str, "cpush (illegal scope); (4)"); + return util::string_format("cpush (illegal scope); (4)"); break; case 1: - sprintf(g_dasm_str, "cpushl %s, (A%d); (4)", cachetype[(g_cpu_ir>>6)&3], g_cpu_ir&7); + return util::string_format("cpushl %s, (A%d); (4)", cachetype[(m_cpu_ir>>6)&3], m_cpu_ir&7); break; case 2: - sprintf(g_dasm_str, "cpushp %s, (A%d); (4)", cachetype[(g_cpu_ir>>6)&3], g_cpu_ir&7); + return util::string_format("cpushp %s, (A%d); (4)", cachetype[(m_cpu_ir>>6)&3], m_cpu_ir&7); break; - case 3: - sprintf(g_dasm_str, "cpusha %s; (4)", cachetype[(g_cpu_ir>>6)&3]); + case 3: default: + return util::string_format("cpusha %s; (4)", cachetype[(m_cpu_ir>>6)&3]); break; } } -static void d68000_dbra(void) +std::string m68k_disassembler::d68000_dbra() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "dbra D%d, $%x", g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + m_flags = STEP_OVER; + return util::string_format("dbra D%d, $%x", m_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); } -static void d68000_dbcc(void) +std::string m68k_disassembler::d68000_dbcc() { - uint32_t temp_pc = g_cpu_pc; - sprintf(g_dasm_str, "db%-2s D%d, $%x", g_cc[(g_cpu_ir>>8)&0xf], g_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + u32 temp_pc = m_cpu_pc; + m_flags = STEP_OVER; + return util::string_format("db%-2s D%d, $%x", m_cc[(m_cpu_ir>>8)&0xf], m_cpu_ir & 7, temp_pc + make_int_16(read_imm_16())); } -static void d68000_divs(void) +std::string m68k_disassembler::d68000_divs() { - sprintf(g_dasm_str, "divs.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("divs.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_divu(void) +std::string m68k_disassembler::d68000_divu() { - sprintf(g_dasm_str, "divu.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("divu.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68020_divl(void) +std::string m68k_disassembler::d68020_divl() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; - if(BIT_A(extension)) - sprintf(g_dasm_str, "div%c.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); + u16 extension = read_imm_16(); + + if(BIT(extension, 10)) + return util::string_format("div%c.l %s, D%d:D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), extension&7, (extension>>12)&7); else if((extension&7) == ((extension>>12)&7)) - sprintf(g_dasm_str, "div%c.l %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7); + return util::string_format("div%c.l %s, D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), (extension>>12)&7); else - sprintf(g_dasm_str, "div%cl.l %s, D%d:D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); + return util::string_format("div%cl.l %s, D%d:D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), extension&7, (extension>>12)&7); } -static void d68000_eor_8(void) +std::string m68k_disassembler::d68000_eor_8() { - sprintf(g_dasm_str, "eor.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("eor.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_eor_16(void) +std::string m68k_disassembler::d68000_eor_16() { - sprintf(g_dasm_str, "eor.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("eor.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_eor_32(void) +std::string m68k_disassembler::d68000_eor_32() { - sprintf(g_dasm_str, "eor.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("eor.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_eori_8(void) +std::string m68k_disassembler::d68000_eori_8() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "eori.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("eori.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_eori_16(void) +std::string m68k_disassembler::d68000_eori_16() { - char* str = get_imm_str_u16(); - sprintf(g_dasm_str, "eori.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_u16(); + return util::string_format("eori.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_eori_32(void) +std::string m68k_disassembler::d68000_eori_32() { - char* str = get_imm_str_u32(); - sprintf(g_dasm_str, "eori.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_u32(); + return util::string_format("eori.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_eori_to_ccr(void) +std::string m68k_disassembler::d68000_eori_to_ccr() { - sprintf(g_dasm_str, "eori %s, CCR", get_imm_str_u8()); + return util::string_format("eori %s, CCR", get_imm_str_u8()); } -static void d68000_eori_to_sr(void) +std::string m68k_disassembler::d68000_eori_to_sr() { - sprintf(g_dasm_str, "eori %s, SR", get_imm_str_u16()); + return util::string_format("eori %s, SR", get_imm_str_u16()); } -static void d68000_exg_dd(void) +std::string m68k_disassembler::d68000_exg_dd() { - sprintf(g_dasm_str, "exg D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("exg D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_exg_aa(void) +std::string m68k_disassembler::d68000_exg_aa() { - sprintf(g_dasm_str, "exg A%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("exg A%d, A%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_exg_da(void) +std::string m68k_disassembler::d68000_exg_da() { - sprintf(g_dasm_str, "exg D%d, A%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("exg D%d, A%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_ext_16(void) +std::string m68k_disassembler::d68000_ext_16() { - sprintf(g_dasm_str, "ext.w D%d", g_cpu_ir&7); + return util::string_format("ext.w D%d", m_cpu_ir&7); } -static void d68000_ext_32(void) +std::string m68k_disassembler::d68000_ext_32() { - sprintf(g_dasm_str, "ext.l D%d", g_cpu_ir&7); + return util::string_format("ext.l D%d", m_cpu_ir&7); } -static void d68020_extb_32(void) +std::string m68k_disassembler::d68020_extb_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "extb.l D%d; (2+)", g_cpu_ir&7); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("extb.l D%d; (2+)", m_cpu_ir&7); } -static void d68881_ftrap(void) +std::string m68k_disassembler::d68881_ftrap() { - uint16_t w2, w3; - uint32_t l2; - - LIMIT_CPU_TYPES(M68020_PLUS); - w2 = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 w2 = read_imm_16(); - switch (g_cpu_ir & 0x7) + switch (m_cpu_ir & 0x7) { case 2: // word operand - w3 = read_imm_16(); - sprintf(g_dasm_str, "ftrap%s.w $%04x", g_cpcc[w2 & 0x3f], w3); - break; + return util::string_format("ftrap%s.w $%04x", m_cpcc[w2 & 0x3f], read_imm_16()); case 3: // long word operand - l2 = read_imm_32(); - sprintf(g_dasm_str, "ftrap%s.l $%08x", g_cpcc[w2 & 0x3f], l2); - break; + return util::string_format("ftrap%s.l $%08x", m_cpcc[w2 & 0x3f], read_imm_32()); case 4: // no operand - sprintf(g_dasm_str, "ftrap%s", g_cpcc[w2 & 0x3f]); - break; + return util::string_format("ftrap%s", m_cpcc[w2 & 0x3f]); } + return util::string_format("ftrap%s<%d>?", m_cpcc[w2 & 0x3f], m_cpu_ir & 7); + } -static void d68040_fpu(void) +std::string m68k_disassembler::d68040_fpu() { char float_data_format[8][3] = { ".l", ".s", ".x", ".p", ".w", ".d", ".b", ".p" }; - char mnemonic[40]; - uint32_t w2, src, dst_reg; - LIMIT_CPU_TYPES(M68020_PLUS); - w2 = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + + u16 w2 = read_imm_16(); - src = (w2 >> 10) & 0x7; - dst_reg = (w2 >> 7) & 0x7; + u16 src = (w2 >> 10) & 0x7; + u16 dst_reg = (w2 >> 7) & 0x7; // special override for FMOVECR if ((((w2 >> 13) & 0x7) == 2) && (((w2>>10)&0x7) == 7)) { - sprintf(g_dasm_str, "fmovecr #$%0x, fp%d", (w2&0x7f), dst_reg); - return; + return util::string_format("fmovecr #$%0x, fp%d", (w2&0x7f), dst_reg); } + std::string mnemonic; switch ((w2 >> 13) & 0x7) { case 0x0: @@ -1766,72 +1428,71 @@ static void d68040_fpu(void) { switch(w2 & 0x7f) { - case 0x00: sprintf(mnemonic, "fmove"); break; - case 0x01: sprintf(mnemonic, "fint"); break; - case 0x02: sprintf(mnemonic, "fsinh"); break; - case 0x03: sprintf(mnemonic, "fintrz"); break; - case 0x04: sprintf(mnemonic, "fsqrt"); break; - case 0x06: sprintf(mnemonic, "flognp1"); break; - case 0x08: sprintf(mnemonic, "fetoxm1"); break; - case 0x09: sprintf(mnemonic, "ftanh1"); break; - case 0x0a: sprintf(mnemonic, "fatan"); break; - case 0x0c: sprintf(mnemonic, "fasin"); break; - case 0x0d: sprintf(mnemonic, "fatanh"); break; - case 0x0e: sprintf(mnemonic, "fsin"); break; - case 0x0f: sprintf(mnemonic, "ftan"); break; - case 0x10: sprintf(mnemonic, "fetox"); break; - case 0x11: sprintf(mnemonic, "ftwotox"); break; - case 0x12: sprintf(mnemonic, "ftentox"); break; - case 0x14: sprintf(mnemonic, "flogn"); break; - case 0x15: sprintf(mnemonic, "flog10"); break; - case 0x16: sprintf(mnemonic, "flog2"); break; - case 0x18: sprintf(mnemonic, "fabs"); break; - case 0x19: sprintf(mnemonic, "fcosh"); break; - case 0x1a: sprintf(mnemonic, "fneg"); break; - case 0x1c: sprintf(mnemonic, "facos"); break; - case 0x1d: sprintf(mnemonic, "fcos"); break; - case 0x1e: sprintf(mnemonic, "fgetexp"); break; - case 0x1f: sprintf(mnemonic, "fgetman"); break; - case 0x20: sprintf(mnemonic, "fdiv"); break; - case 0x21: sprintf(mnemonic, "fmod"); break; - case 0x22: sprintf(mnemonic, "fadd"); break; - case 0x23: sprintf(mnemonic, "fmul"); break; - case 0x24: sprintf(mnemonic, "fsgldiv"); break; - case 0x25: sprintf(mnemonic, "frem"); break; - case 0x26: sprintf(mnemonic, "fscale"); break; - case 0x27: sprintf(mnemonic, "fsglmul"); break; - case 0x28: sprintf(mnemonic, "fsub"); break; + case 0x00: mnemonic = "fmove"; break; + case 0x01: mnemonic = "fint"; break; + case 0x02: mnemonic = "fsinh"; break; + case 0x03: mnemonic = "fintrz"; break; + case 0x04: mnemonic = "fsqrt"; break; + case 0x06: mnemonic = "flognp1"; break; + case 0x08: mnemonic = "fetoxm1"; break; + case 0x09: mnemonic = "ftanh1"; break; + case 0x0a: mnemonic = "fatan"; break; + case 0x0c: mnemonic = "fasin"; break; + case 0x0d: mnemonic = "fatanh"; break; + case 0x0e: mnemonic = "fsin"; break; + case 0x0f: mnemonic = "ftan"; break; + case 0x10: mnemonic = "fetox"; break; + case 0x11: mnemonic = "ftwotox"; break; + case 0x12: mnemonic = "ftentox"; break; + case 0x14: mnemonic = "flogn"; break; + case 0x15: mnemonic = "flog10"; break; + case 0x16: mnemonic = "flog2"; break; + case 0x18: mnemonic = "fabs"; break; + case 0x19: mnemonic = "fcosh"; break; + case 0x1a: mnemonic = "fneg"; break; + case 0x1c: mnemonic = "facos"; break; + case 0x1d: mnemonic = "fcos"; break; + case 0x1e: mnemonic = "fgetexp"; break; + case 0x1f: mnemonic = "fgetman"; break; + case 0x20: mnemonic = "fdiv"; break; + case 0x21: mnemonic = "fmod"; break; + case 0x22: mnemonic = "fadd"; break; + case 0x23: mnemonic = "fmul"; break; + case 0x24: mnemonic = "fsgldiv"; break; + case 0x25: mnemonic = "frem"; break; + case 0x26: mnemonic = "fscale"; break; + case 0x27: mnemonic = "fsglmul"; break; + case 0x28: mnemonic = "fsub"; break; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: - sprintf(mnemonic, "fsincos"); break; - case 0x38: sprintf(mnemonic, "fcmp"); break; - case 0x3a: sprintf(mnemonic, "ftst"); break; - case 0x41: sprintf(mnemonic, "fssqrt"); break; - case 0x45: sprintf(mnemonic, "fdsqrt"); break; - case 0x58: sprintf(mnemonic, "fsabs"); break; - case 0x5a: sprintf(mnemonic, "fsneg"); break; - case 0x5c: sprintf(mnemonic, "fdabs"); break; - case 0x5e: sprintf(mnemonic, "fdneg"); break; - case 0x60: sprintf(mnemonic, "fsdiv"); break; - case 0x62: sprintf(mnemonic, "fsadd"); break; - case 0x63: sprintf(mnemonic, "fsmul"); break; - case 0x64: sprintf(mnemonic, "fddiv"); break; - case 0x66: sprintf(mnemonic, "fdadd"); break; - case 0x67: sprintf(mnemonic, "fdmul"); break; - case 0x68: sprintf(mnemonic, "fssub"); break; - case 0x6c: sprintf(mnemonic, "fdsub"); break; - - default: sprintf(mnemonic, "FPU (?)"); break; + mnemonic = "fsincos"; break; + case 0x38: mnemonic = "fcmp"; break; + case 0x3a: mnemonic = "ftst"; break; + case 0x41: mnemonic = "fssqrt"; break; + case 0x45: mnemonic = "fdsqrt"; break; + case 0x58: mnemonic = "fsabs"; break; + case 0x5a: mnemonic = "fsneg"; break; + case 0x5c: mnemonic = "fdabs"; break; + case 0x5e: mnemonic = "fdneg"; break; + case 0x60: mnemonic = "fsdiv"; break; + case 0x62: mnemonic = "fsadd"; break; + case 0x63: mnemonic = "fsmul"; break; + case 0x64: mnemonic = "fddiv"; break; + case 0x66: mnemonic = "fdadd"; break; + case 0x67: mnemonic = "fdmul"; break; + case 0x68: mnemonic = "fssub"; break; + case 0x6c: mnemonic = "fdsub"; break; + + default: mnemonic = "FPU (?)"; break; } if (w2 & 0x4000) { - sprintf(g_dasm_str, "%s%s %s, FP%d", mnemonic, float_data_format[src], get_ea_mode_str_32(g_cpu_ir), dst_reg); + return util::string_format("%s%s %s, FP%d", mnemonic, float_data_format[src], get_ea_mode_str_32(m_cpu_ir), dst_reg); } else { - sprintf(g_dasm_str, "%s.x FP%d, FP%d", mnemonic, src, dst_reg); + return util::string_format("%s.x FP%d, FP%d", mnemonic, src, dst_reg); } - break; } case 0x3: @@ -1839,15 +1500,13 @@ static void d68040_fpu(void) switch ((w2>>10)&7) { case 3: // packed decimal w/fixed k-factor - sprintf(g_dasm_str, "fmove%s FP%d, %s {#%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), sext_7bit_int(w2&0x7f)); - break; + return util::string_format("fmove%s FP%d, %s {#%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(m_cpu_ir), sext_7bit_int(w2&0x7f)); case 7: // packed decimal w/dynamic k-factor (register) - sprintf(g_dasm_str, "fmove%s FP%d, %s {D%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7); - break; + return util::string_format("fmove%s FP%d, %s {D%d}", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(m_cpu_ir), (w2>>4)&7); default: - sprintf(g_dasm_str, "fmove%s FP%d, %s", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("fmove%s FP%d, %s", float_data_format[(w2>>10)&7], dst_reg, get_ea_mode_str_32(m_cpu_ir)); break; } break; @@ -1855,264 +1514,250 @@ static void d68040_fpu(void) case 0x4: // ea to control { - sprintf(g_dasm_str, "fmovem.l %s, ", get_ea_mode_str_32(g_cpu_ir)); - if (w2 & 0x1000) strcat(g_dasm_str, "fpcr"); - if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr"); - if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar"); - break; + std::string dasm = util::string_format("fmovem.l %s, ", get_ea_mode_str_32(m_cpu_ir)); + if (w2 & 0x1000) return dasm + "fpcr"; + if (w2 & 0x0800) return dasm + "/fpsr"; + if (w2 & 0x0400) return dasm + "/fpiar"; + return dasm; } case 0x5: // control to ea { - strcpy(g_dasm_str, "fmovem.l "); - if (w2 & 0x1000) strcat(g_dasm_str, "fpcr"); - if (w2 & 0x0800) strcat(g_dasm_str, "/fpsr"); - if (w2 & 0x0400) strcat(g_dasm_str, "/fpiar"); - strcat(g_dasm_str, ", "); - strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir)); - break; + std::string dasm = "fmovem.l "; + if (w2 & 0x1000) dasm += "fpcr"; + if (w2 & 0x0800) dasm += "/fpsr"; + if (w2 & 0x0400) dasm += "/fpiar"; + return dasm + ", " + get_ea_mode_str_32(m_cpu_ir); } case 0x6: // memory to FPU, list { - char temp[32]; - if ((w2>>11) & 1) // dynamic register list { - sprintf(g_dasm_str, "fmovem.x %s, D%d", get_ea_mode_str_32(g_cpu_ir), (w2>>4)&7); + return util::string_format("fmovem.x %s, D%d", get_ea_mode_str_32(m_cpu_ir), (w2>>4)&7); } else // static register list { - int i; - - sprintf(g_dasm_str, "fmovem.x %s, ", get_ea_mode_str_32(g_cpu_ir)); + std::string dasm = util::string_format("fmovem.x %s, ", get_ea_mode_str_32(m_cpu_ir)); - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { if (w2 & (1<<i)) { if ((w2>>12) & 1) // postincrement or control { - sprintf(temp, "FP%d ", 7-i); + dasm += util::string_format("FP%d ", 7-i); } else // predecrement { - sprintf(temp, "FP%d ", i); + dasm += util::string_format("FP%d ", i); } - strcat(g_dasm_str, temp); } } + return dasm; } - break; } case 0x7: // FPU to memory, list { - char temp[32]; - if ((w2>>11) & 1) // dynamic register list { - sprintf(g_dasm_str, "fmovem.x D%d, %s", (w2>>4)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("fmovem.x D%d, %s", (w2>>4)&7, get_ea_mode_str_32(m_cpu_ir)); } else // static register list { - int i; + std::string dasm = util::string_format("fmovem.x "); - sprintf(g_dasm_str, "fmovem.x "); - - for (i = 0; i < 8; i++) + for (int i = 0; i < 8; i++) { if (w2 & (1<<i)) { if ((w2>>12) & 1) // postincrement or control { - sprintf(temp, "FP%d ", 7-i); + dasm += util::string_format("FP%d ", 7-i); } else // predecrement { - sprintf(temp, "FP%d ", i); + dasm += util::string_format("FP%d ", i); } - strcat(g_dasm_str, temp); } } - strcat(g_dasm_str, ", "); - strcat(g_dasm_str, get_ea_mode_str_32(g_cpu_ir)); + return dasm + ", " + get_ea_mode_str_32(m_cpu_ir); } - break; - } - - default: - { - sprintf(g_dasm_str, "FPU (?) "); - break; } } + return util::string_format("FPU (?) "); } -static void d68000_jmp(void) +std::string m68k_disassembler::d68000_jmp() { - sprintf(g_dasm_str, "jmp %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("jmp %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_jsr(void) +std::string m68k_disassembler::d68000_jsr() { - sprintf(g_dasm_str, "jsr %s", get_ea_mode_str_32(g_cpu_ir)); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + m_flags = STEP_OVER; + return util::string_format("jsr %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_lea(void) +std::string m68k_disassembler::d68000_lea() { - sprintf(g_dasm_str, "lea %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("lea %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_link_16(void) +std::string m68k_disassembler::d68000_link_16() { - sprintf(g_dasm_str, "link A%d, %s", g_cpu_ir&7, get_imm_str_s16()); + return util::string_format("link A%d, %s", m_cpu_ir&7, get_imm_str_s16()); } -static void d68020_link_32(void) +std::string m68k_disassembler::d68020_link_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "link A%d, %s; (2+)", g_cpu_ir&7, get_imm_str_s32()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("link A%d, %s; (2+)", m_cpu_ir&7, get_imm_str_s32()); } -static void d68000_lsr_s_8(void) +std::string m68k_disassembler::d68000_lsr_s_8() { - sprintf(g_dasm_str, "lsr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsr.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsr_s_16(void) +std::string m68k_disassembler::d68000_lsr_s_16() { - sprintf(g_dasm_str, "lsr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsr.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsr_s_32(void) +std::string m68k_disassembler::d68000_lsr_s_32() { - sprintf(g_dasm_str, "lsr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsr.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsr_r_8(void) +std::string m68k_disassembler::d68000_lsr_r_8() { - sprintf(g_dasm_str, "lsr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsr.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsr_r_16(void) +std::string m68k_disassembler::d68000_lsr_r_16() { - sprintf(g_dasm_str, "lsr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsr.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsr_r_32(void) +std::string m68k_disassembler::d68000_lsr_r_32() { - sprintf(g_dasm_str, "lsr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsr.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsr_ea(void) +std::string m68k_disassembler::d68000_lsr_ea() { - sprintf(g_dasm_str, "lsr.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("lsr.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_lsl_s_8(void) +std::string m68k_disassembler::d68000_lsl_s_8() { - sprintf(g_dasm_str, "lsl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsl.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsl_s_16(void) +std::string m68k_disassembler::d68000_lsl_s_16() { - sprintf(g_dasm_str, "lsl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsl.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsl_s_32(void) +std::string m68k_disassembler::d68000_lsl_s_32() { - sprintf(g_dasm_str, "lsl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("lsl.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_lsl_r_8(void) +std::string m68k_disassembler::d68000_lsl_r_8() { - sprintf(g_dasm_str, "lsl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsl.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsl_r_16(void) +std::string m68k_disassembler::d68000_lsl_r_16() { - sprintf(g_dasm_str, "lsl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsl.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsl_r_32(void) +std::string m68k_disassembler::d68000_lsl_r_32() { - sprintf(g_dasm_str, "lsl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("lsl.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_lsl_ea(void) +std::string m68k_disassembler::d68000_lsl_ea() { - sprintf(g_dasm_str, "lsl.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("lsl.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_move_8(void) +std::string m68k_disassembler::d68000_move_8() { - char* str = get_ea_mode_str_8(g_cpu_ir); - sprintf(g_dasm_str, "move.b %s, %s", str, get_ea_mode_str_8(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); + std::string str = get_ea_mode_str_8(m_cpu_ir); + return util::string_format("move.b %s, %s", str, get_ea_mode_str_8(((m_cpu_ir>>9) & 7) | ((m_cpu_ir>>3) & 0x38))); } -static void d68000_move_16(void) +std::string m68k_disassembler::d68000_move_16() { - char* str = get_ea_mode_str_16(g_cpu_ir); - sprintf(g_dasm_str, "move.w %s, %s", str, get_ea_mode_str_16(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); + std::string str = get_ea_mode_str_16(m_cpu_ir); + return util::string_format("move.w %s, %s", str, get_ea_mode_str_16(((m_cpu_ir>>9) & 7) | ((m_cpu_ir>>3) & 0x38))); } -static void d68000_move_32(void) +std::string m68k_disassembler::d68000_move_32() { - char* str = get_ea_mode_str_32(g_cpu_ir); - sprintf(g_dasm_str, "move.l %s, %s", str, get_ea_mode_str_32(((g_cpu_ir>>9) & 7) | ((g_cpu_ir>>3) & 0x38))); + std::string str = get_ea_mode_str_32(m_cpu_ir); + return util::string_format("move.l %s, %s", str, get_ea_mode_str_32(((m_cpu_ir>>9) & 7) | ((m_cpu_ir>>3) & 0x38))); } -static void d68000_movea_16(void) +std::string m68k_disassembler::d68000_movea_16() { - sprintf(g_dasm_str, "movea.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("movea.w %s, A%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_movea_32(void) +std::string m68k_disassembler::d68000_movea_32() { - sprintf(g_dasm_str, "movea.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("movea.l %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_move_to_ccr(void) +std::string m68k_disassembler::d68000_move_to_ccr() { - sprintf(g_dasm_str, "move %s, CCR", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("move %s, CCR", get_ea_mode_str_8(m_cpu_ir)); } -static void d68010_move_fr_ccr(void) +std::string m68k_disassembler::d68010_move_fr_ccr() { - LIMIT_CPU_TYPES(M68010_PLUS); - sprintf(g_dasm_str, "move CCR, %s; (1+)", get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move CCR, %s; (1+)", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_move_fr_sr(void) +std::string m68k_disassembler::d68000_move_fr_sr() { - sprintf(g_dasm_str, "move SR, %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("move SR, %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_move_to_sr(void) +std::string m68k_disassembler::d68000_move_to_sr() { - sprintf(g_dasm_str, "move %s, SR", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("move %s, SR", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_move_fr_usp(void) +std::string m68k_disassembler::d68000_move_fr_usp() { - sprintf(g_dasm_str, "move USP, A%d", g_cpu_ir&7); + return util::string_format("move USP, A%d", m_cpu_ir&7); } -static void d68000_move_to_usp(void) +std::string m68k_disassembler::d68000_move_to_usp() { - sprintf(g_dasm_str, "move A%d, USP", g_cpu_ir&7); + return util::string_format("move A%d, USP", m_cpu_ir&7); } -static void d68010_movec(void) +std::string m68k_disassembler::d68010_movec() { - uint32_t extension; - const char* reg_name; - const char* processor; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + + std::string reg_name, processor; + u16 extension = read_imm_16(); switch(extension & 0xfff) { @@ -2153,7 +1798,7 @@ static void d68010_movec(void) processor = "4+"; break; case 0x004: - if(g_cpu_type & COLDFIRE) + if(m_cpu_type & COLDFIRE) { reg_name = "ACR0"; processor = "CF"; @@ -2165,7 +1810,7 @@ static void d68010_movec(void) } break; case 0x005: - if(g_cpu_type & COLDFIRE) + if(m_cpu_type & COLDFIRE) { reg_name = "ACR1"; processor = "CF"; @@ -2177,7 +1822,7 @@ static void d68010_movec(void) } break; case 0x006: - if(g_cpu_type & COLDFIRE) + if(m_cpu_type & COLDFIRE) { reg_name = "ACR2"; processor = "CF"; @@ -2189,7 +1834,7 @@ static void d68010_movec(void) } break; case 0x007: - if(g_cpu_type & COLDFIRE) + if(m_cpu_type & COLDFIRE) { reg_name = "ACR3"; processor = "CF"; @@ -2249,994 +1894,1026 @@ static void d68010_movec(void) processor = "?"; } - if(BIT_0(g_cpu_ir)) - sprintf(g_dasm_str, "movec %c%d, %s; (%s)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, reg_name, processor); + if(BIT(m_cpu_ir, 0)) + return util::string_format("movec %c%d, %s; (%s)", BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, reg_name, processor); else - sprintf(g_dasm_str, "movec %s, %c%d; (%s)", reg_name, BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, processor); + return util::string_format("movec %s, %c%d; (%s)", reg_name, BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, processor); } -static void d68000_movem_pd_16(void) +std::string m68k_disassembler::d68000_movem_pd_16() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<(15-i))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(15-(i+1))))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(7-i))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(7-(i+1))))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("movem.w %s, %s", regs, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_movem_pd_32(void) +std::string m68k_disassembler::d68000_movem_pd_32() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<(15-i))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(15-(i+1))))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(7-i))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(7-(i+1))))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("movem.l %s, %s", regs, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_movem_er_16(void) +std::string m68k_disassembler::d68000_movem_er_16() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<i)) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(i+8))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+8+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.w %s, %s", get_ea_mode_str_16(g_cpu_ir), buffer); + return util::string_format("movem.w %s, %s", get_ea_mode_str_16(m_cpu_ir), regs); } -static void d68000_movem_er_32(void) +std::string m68k_disassembler::d68000_movem_er_32() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<i)) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(i+8))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+8+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.l %s, %s", get_ea_mode_str_32(g_cpu_ir), buffer); + return util::string_format("movem.l %s, %s", get_ea_mode_str_32(m_cpu_ir), regs); } -static void d68000_movem_re_16(void) +std::string m68k_disassembler::d68000_movem_re_16() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<i)) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(i+8))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+8+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.w %s, %s", buffer, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("movem.w %s, %s", regs, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_movem_re_32(void) +std::string m68k_disassembler::d68000_movem_re_32() { - uint32_t data = read_imm_16(); - char buffer[40]; - uint32_t first; - uint32_t run_length; - uint32_t i; + u32 data = read_imm_16(); - buffer[0] = 0; - for(i=0;i<8;i++) + std::string regs; + for(int i=0;i<8;i++) { if(data&(1<<i)) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "D%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("D%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-D%d", first + run_length); + regs += util::string_format("-D%d", first + run_length); } } - for(i=0;i<8;i++) + for(int i=0;i<8;i++) { if(data&(1<<(i+8))) { - first = i; - run_length = 0; + int first = i; + int run_length = 0; while(i<7 && (data&(1<<(i+8+1)))) { i++; run_length++; } - if(buffer[0] != 0) - strcat(buffer, "/"); - sprintf(buffer+strlen(buffer), "A%d", first); + if(!regs.empty()) + regs += '/'; + regs += util::string_format("A%d", first); if(run_length > 0) - sprintf(buffer+strlen(buffer), "-A%d", first + run_length); + regs += util::string_format("-A%d", first + run_length); } } - sprintf(g_dasm_str, "movem.l %s, %s", buffer, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("movem.l %s, %s", regs, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_movep_re_16(void) +std::string m68k_disassembler::d68000_movep_re_16() { - sprintf(g_dasm_str, "movep.w D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7); + return util::string_format("movep.w D%d, ($%x,A%d)", (m_cpu_ir>>9)&7, read_imm_16(), m_cpu_ir&7); } -static void d68000_movep_re_32(void) +std::string m68k_disassembler::d68000_movep_re_32() { - sprintf(g_dasm_str, "movep.l D%d, ($%x,A%d)", (g_cpu_ir>>9)&7, read_imm_16(), g_cpu_ir&7); + return util::string_format("movep.l D%d, ($%x,A%d)", (m_cpu_ir>>9)&7, read_imm_16(), m_cpu_ir&7); } -static void d68000_movep_er_16(void) +std::string m68k_disassembler::d68000_movep_er_16() { - sprintf(g_dasm_str, "movep.w ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("movep.w ($%x,A%d), D%d", read_imm_16(), m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_movep_er_32(void) +std::string m68k_disassembler::d68000_movep_er_32() { - sprintf(g_dasm_str, "movep.l ($%x,A%d), D%d", read_imm_16(), g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("movep.l ($%x,A%d), D%d", read_imm_16(), m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68010_moves_8(void) +std::string m68k_disassembler::d68010_moves_8() { - uint32_t extension; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(g_dasm_str, "moves.b %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + if(BIT(extension, 11)) + return util::string_format("moves.b %c%d, %s; (1+)", BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_8(m_cpu_ir)); else - sprintf(g_dasm_str, "moves.b %s, %c%d; (1+)", get_ea_mode_str_8(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + return util::string_format("moves.b %s, %c%d; (1+)", get_ea_mode_str_8(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68010_moves_16(void) +std::string m68k_disassembler::d68010_moves_16() { - uint32_t extension; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(g_dasm_str, "moves.w %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + if(BIT(extension, 11)) + return util::string_format("moves.w %c%d, %s; (1+)", BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_16(m_cpu_ir)); else - sprintf(g_dasm_str, "moves.w %s, %c%d; (1+)", get_ea_mode_str_16(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + return util::string_format("moves.w %s, %c%d; (1+)", get_ea_mode_str_16(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68010_moves_32(void) +std::string m68k_disassembler::d68010_moves_32() { - uint32_t extension; - LIMIT_CPU_TYPES(M68010_PLUS); - extension = read_imm_16(); - if(BIT_B(extension)) - sprintf(g_dasm_str, "moves.l %c%d, %s; (1+)", BIT_F(extension) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); + if(BIT(extension, 11)) + return util::string_format("moves.l %c%d, %s; (1+)", BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7, get_ea_mode_str_32(m_cpu_ir)); else - sprintf(g_dasm_str, "moves.l %s, %c%d; (1+)", get_ea_mode_str_32(g_cpu_ir), BIT_F(extension) ? 'A' : 'D', (extension>>12)&7); + return util::string_format("moves.l %s, %c%d; (1+)", get_ea_mode_str_32(m_cpu_ir), BIT(extension, 15) ? 'A' : 'D', (extension>>12)&7); } -static void d68000_moveq(void) +std::string m68k_disassembler::d68000_moveq() { - sprintf(g_dasm_str, "moveq #%s, D%d", make_signed_hex_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("moveq #%s, D%d", make_signed_hex_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68040_move16_pi_pi(void) +std::string m68k_disassembler::d68040_move16_pi_pi() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 (A%d)+, (A%d)+; (4)", g_cpu_ir&7, (read_imm_16()>>12)&7); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 (A%d)+, (A%d)+; (4)", m_cpu_ir&7, (read_imm_16()>>12)&7); } -static void d68040_move16_pi_al(void) +std::string m68k_disassembler::d68040_move16_pi_al() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 (A%d)+, %s; (4)", g_cpu_ir&7, get_imm_str_u32()); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 (A%d)+, %s; (4)", m_cpu_ir&7, get_imm_str_u32()); } -static void d68040_move16_al_pi(void) +std::string m68k_disassembler::d68040_move16_al_pi() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 %s, (A%d)+; (4)", get_imm_str_u32(), g_cpu_ir&7); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 %s, (A%d)+; (4)", get_imm_str_u32(), m_cpu_ir&7); } -static void d68040_move16_ai_al(void) +std::string m68k_disassembler::d68040_move16_ai_al() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 (A%d), %s; (4)", g_cpu_ir&7, get_imm_str_u32()); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 (A%d), %s; (4)", m_cpu_ir&7, get_imm_str_u32()); } -static void d68040_move16_al_ai(void) +std::string m68k_disassembler::d68040_move16_al_ai() { - LIMIT_CPU_TYPES(M68040_PLUS); - sprintf(g_dasm_str, "move16 %s, (A%d); (4)", get_imm_str_u32(), g_cpu_ir&7); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; + return util::string_format("move16 %s, (A%d); (4)", get_imm_str_u32(), m_cpu_ir&7); } -static void d68000_muls(void) +std::string m68k_disassembler::d68000_muls() { - sprintf(g_dasm_str, "muls.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("muls.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_mulu(void) +std::string m68k_disassembler::d68000_mulu() { - sprintf(g_dasm_str, "mulu.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("mulu.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68020_mull(void) +std::string m68k_disassembler::d68020_mull() { - uint32_t extension; - LIMIT_CPU_TYPES(M68020_PLUS); - extension = read_imm_16(); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + u16 extension = read_imm_16(); - if(BIT_A(extension)) - sprintf(g_dasm_str, "mul%c.l %s, D%d-D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), extension&7, (extension>>12)&7); + if(BIT(extension, 10)) + return util::string_format("mul%c.l %s, D%d-D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), extension&7, (extension>>12)&7); else - sprintf(g_dasm_str, "mul%c.l %s, D%d; (2+)", BIT_B(extension) ? 's' : 'u', get_ea_mode_str_32(g_cpu_ir), (extension>>12)&7); + return util::string_format("mul%c.l %s, D%d; (2+)", BIT(extension, 11) ? 's' : 'u', get_ea_mode_str_32(m_cpu_ir), (extension>>12)&7); } -static void d68000_nbcd(void) +std::string m68k_disassembler::d68000_nbcd() { - sprintf(g_dasm_str, "nbcd %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("nbcd %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_neg_8(void) +std::string m68k_disassembler::d68000_neg_8() { - sprintf(g_dasm_str, "neg.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("neg.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_neg_16(void) +std::string m68k_disassembler::d68000_neg_16() { - sprintf(g_dasm_str, "neg.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("neg.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_neg_32(void) +std::string m68k_disassembler::d68000_neg_32() { - sprintf(g_dasm_str, "neg.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("neg.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_negx_8(void) +std::string m68k_disassembler::d68000_negx_8() { - sprintf(g_dasm_str, "negx.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("negx.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_negx_16(void) +std::string m68k_disassembler::d68000_negx_16() { - sprintf(g_dasm_str, "negx.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("negx.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_negx_32(void) +std::string m68k_disassembler::d68000_negx_32() { - sprintf(g_dasm_str, "negx.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("negx.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_nop(void) +std::string m68k_disassembler::d68000_nop() { - sprintf(g_dasm_str, "nop"); + return util::string_format("nop"); } -static void d68000_not_8(void) +std::string m68k_disassembler::d68000_not_8() { - sprintf(g_dasm_str, "not.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("not.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_not_16(void) +std::string m68k_disassembler::d68000_not_16() { - sprintf(g_dasm_str, "not.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("not.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_not_32(void) +std::string m68k_disassembler::d68000_not_32() { - sprintf(g_dasm_str, "not.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("not.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_or_er_8(void) +std::string m68k_disassembler::d68000_or_er_8() { - sprintf(g_dasm_str, "or.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("or.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_or_er_16(void) +std::string m68k_disassembler::d68000_or_er_16() { - sprintf(g_dasm_str, "or.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("or.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_or_er_32(void) +std::string m68k_disassembler::d68000_or_er_32() { - sprintf(g_dasm_str, "or.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("or.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_or_re_8(void) +std::string m68k_disassembler::d68000_or_re_8() { - sprintf(g_dasm_str, "or.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("or.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_or_re_16(void) +std::string m68k_disassembler::d68000_or_re_16() { - sprintf(g_dasm_str, "or.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("or.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_or_re_32(void) +std::string m68k_disassembler::d68000_or_re_32() { - sprintf(g_dasm_str, "or.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("or.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_ori_8(void) +std::string m68k_disassembler::d68000_ori_8() { - char* str = get_imm_str_u8(); - sprintf(g_dasm_str, "ori.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_u8(); + return util::string_format("ori.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_ori_16(void) +std::string m68k_disassembler::d68000_ori_16() { - char* str = get_imm_str_u16(); - sprintf(g_dasm_str, "ori.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_u16(); + return util::string_format("ori.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_ori_32(void) +std::string m68k_disassembler::d68000_ori_32() { - char* str = get_imm_str_u32(); - sprintf(g_dasm_str, "ori.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_u32(); + return util::string_format("ori.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_ori_to_ccr(void) +std::string m68k_disassembler::d68000_ori_to_ccr() { - sprintf(g_dasm_str, "ori %s, CCR", get_imm_str_u8()); + return util::string_format("ori %s, CCR", get_imm_str_u8()); } -static void d68000_ori_to_sr(void) +std::string m68k_disassembler::d68000_ori_to_sr() { - sprintf(g_dasm_str, "ori %s, SR", get_imm_str_u16()); + return util::string_format("ori %s, SR", get_imm_str_u16()); } -static void d68020_pack_rr(void) +std::string m68k_disassembler::d68020_pack_rr() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "pack D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("pack D%d, D%d, %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16()); } -static void d68020_pack_mm(void) +std::string m68k_disassembler::d68020_pack_mm() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "pack -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("pack -(A%d), -(A%d), %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16()); } -static void d68000_pea(void) +std::string m68k_disassembler::d68000_pea() { - sprintf(g_dasm_str, "pea %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("pea %s", get_ea_mode_str_32(m_cpu_ir)); } // this is a 68040-specific form of PFLUSH -static void d68040_pflush(void) +std::string m68k_disassembler::d68040_pflush() { - LIMIT_CPU_TYPES(M68040_PLUS); + auto limit = limit_cpu_types(M68040_PLUS); + if(limit.first) + return limit.second; - if (g_cpu_ir & 0x10) + if (m_cpu_ir & 0x10) { - sprintf(g_dasm_str, "pflusha%s", (g_cpu_ir & 8) ? "" : "n"); + return util::string_format("pflusha%s", (m_cpu_ir & 8) ? "" : "n"); } else { - sprintf(g_dasm_str, "pflush%s(A%d)", (g_cpu_ir & 8) ? "" : "n", g_cpu_ir & 7); + return util::string_format("pflush%s(A%d)", (m_cpu_ir & 8) ? "" : "n", m_cpu_ir & 7); } } -static void d68000_reset(void) +std::string m68k_disassembler::d68000_reset() { - sprintf(g_dasm_str, "reset"); + return util::string_format("reset"); } -static void d68000_ror_s_8(void) +std::string m68k_disassembler::d68000_ror_s_8() { - sprintf(g_dasm_str, "ror.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("ror.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_ror_s_16(void) +std::string m68k_disassembler::d68000_ror_s_16() { - sprintf(g_dasm_str, "ror.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7],g_cpu_ir&7); + return util::string_format("ror.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7],m_cpu_ir&7); } -static void d68000_ror_s_32(void) +std::string m68k_disassembler::d68000_ror_s_32() { - sprintf(g_dasm_str, "ror.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("ror.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_ror_r_8(void) +std::string m68k_disassembler::d68000_ror_r_8() { - sprintf(g_dasm_str, "ror.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("ror.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_ror_r_16(void) +std::string m68k_disassembler::d68000_ror_r_16() { - sprintf(g_dasm_str, "ror.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("ror.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_ror_r_32(void) +std::string m68k_disassembler::d68000_ror_r_32() { - sprintf(g_dasm_str, "ror.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("ror.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_ror_ea(void) +std::string m68k_disassembler::d68000_ror_ea() { - sprintf(g_dasm_str, "ror.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("ror.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_rol_s_8(void) +std::string m68k_disassembler::d68000_rol_s_8() { - sprintf(g_dasm_str, "rol.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("rol.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_rol_s_16(void) +std::string m68k_disassembler::d68000_rol_s_16() { - sprintf(g_dasm_str, "rol.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("rol.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_rol_s_32(void) +std::string m68k_disassembler::d68000_rol_s_32() { - sprintf(g_dasm_str, "rol.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("rol.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_rol_r_8(void) +std::string m68k_disassembler::d68000_rol_r_8() { - sprintf(g_dasm_str, "rol.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("rol.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_rol_r_16(void) +std::string m68k_disassembler::d68000_rol_r_16() { - sprintf(g_dasm_str, "rol.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("rol.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_rol_r_32(void) +std::string m68k_disassembler::d68000_rol_r_32() { - sprintf(g_dasm_str, "rol.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("rol.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_rol_ea(void) +std::string m68k_disassembler::d68000_rol_ea() { - sprintf(g_dasm_str, "rol.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("rol.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_roxr_s_8(void) +std::string m68k_disassembler::d68000_roxr_s_8() { - sprintf(g_dasm_str, "roxr.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxr.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxr_s_16(void) +std::string m68k_disassembler::d68000_roxr_s_16() { - sprintf(g_dasm_str, "roxr.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxr.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxr_s_32(void) +std::string m68k_disassembler::d68000_roxr_s_32() { - sprintf(g_dasm_str, "roxr.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxr.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxr_r_8(void) +std::string m68k_disassembler::d68000_roxr_r_8() { - sprintf(g_dasm_str, "roxr.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxr.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxr_r_16(void) +std::string m68k_disassembler::d68000_roxr_r_16() { - sprintf(g_dasm_str, "roxr.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxr.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxr_r_32(void) +std::string m68k_disassembler::d68000_roxr_r_32() { - sprintf(g_dasm_str, "roxr.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxr.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxr_ea(void) +std::string m68k_disassembler::d68000_roxr_ea() { - sprintf(g_dasm_str, "roxr.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("roxr.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_roxl_s_8(void) +std::string m68k_disassembler::d68000_roxl_s_8() { - sprintf(g_dasm_str, "roxl.b #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxl.b #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxl_s_16(void) +std::string m68k_disassembler::d68000_roxl_s_16() { - sprintf(g_dasm_str, "roxl.w #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxl.w #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxl_s_32(void) +std::string m68k_disassembler::d68000_roxl_s_32() { - sprintf(g_dasm_str, "roxl.l #%d, D%d", g_3bit_qdata_table[(g_cpu_ir>>9)&7], g_cpu_ir&7); + return util::string_format("roxl.l #%d, D%d", m_3bit_qdata_table[(m_cpu_ir>>9)&7], m_cpu_ir&7); } -static void d68000_roxl_r_8(void) +std::string m68k_disassembler::d68000_roxl_r_8() { - sprintf(g_dasm_str, "roxl.b D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxl.b D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxl_r_16(void) +std::string m68k_disassembler::d68000_roxl_r_16() { - sprintf(g_dasm_str, "roxl.w D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxl.w D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxl_r_32(void) +std::string m68k_disassembler::d68000_roxl_r_32() { - sprintf(g_dasm_str, "roxl.l D%d, D%d", (g_cpu_ir>>9)&7, g_cpu_ir&7); + return util::string_format("roxl.l D%d, D%d", (m_cpu_ir>>9)&7, m_cpu_ir&7); } -static void d68000_roxl_ea(void) +std::string m68k_disassembler::d68000_roxl_ea() { - sprintf(g_dasm_str, "roxl.w %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("roxl.w %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68010_rtd(void) +std::string m68k_disassembler::d68010_rtd() { - LIMIT_CPU_TYPES(M68010_PLUS); - sprintf(g_dasm_str, "rtd %s; (1+)", get_imm_str_s16()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + auto limit = limit_cpu_types(M68010_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OUT; + return util::string_format("rtd %s; (1+)", get_imm_str_s16()); } -static void d68000_rte(void) +std::string m68k_disassembler::d68000_rte() { - sprintf(g_dasm_str, "rte"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + m_flags = STEP_OUT; + return util::string_format("rte"); } -static void d68020_rtm(void) +std::string m68k_disassembler::d68020_rtm() { - LIMIT_CPU_TYPES(M68020_ONLY); - sprintf(g_dasm_str, "rtm %c%d; (2+)", BIT_3(g_cpu_ir) ? 'A' : 'D', g_cpu_ir&7); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + auto limit = limit_cpu_types(M68020_ONLY); + if(limit.first) + return limit.second; + m_flags = STEP_OUT; + return util::string_format("rtm %c%d; (2+)", BIT(m_cpu_ir, 3) ? 'A' : 'D', m_cpu_ir&7); } -static void d68000_rtr(void) +std::string m68k_disassembler::d68000_rtr() { - sprintf(g_dasm_str, "rtr"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + m_flags = STEP_OUT; + return util::string_format("rtr"); } -static void d68000_rts(void) +std::string m68k_disassembler::d68000_rts() { - sprintf(g_dasm_str, "rts"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OUT); + m_flags = STEP_OUT; + return util::string_format("rts"); } -static void d68000_sbcd_rr(void) +std::string m68k_disassembler::d68000_sbcd_rr() { - sprintf(g_dasm_str, "sbcd D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("sbcd D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_sbcd_mm(void) +std::string m68k_disassembler::d68000_sbcd_mm() { - sprintf(g_dasm_str, "sbcd -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("sbcd -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_scc(void) +std::string m68k_disassembler::d68000_scc() { - sprintf(g_dasm_str, "s%-2s %s", g_cc[(g_cpu_ir>>8)&0xf], get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("s%-2s %s", m_cc[(m_cpu_ir>>8)&0xf], get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_stop(void) +std::string m68k_disassembler::d68000_stop() { - sprintf(g_dasm_str, "stop %s", get_imm_str_s16()); + return util::string_format("stop %s", get_imm_str_s16()); } -static void d68000_sub_er_8(void) +std::string m68k_disassembler::d68000_sub_er_8() { - sprintf(g_dasm_str, "sub.b %s, D%d", get_ea_mode_str_8(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("sub.b %s, D%d", get_ea_mode_str_8(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_sub_er_16(void) +std::string m68k_disassembler::d68000_sub_er_16() { - sprintf(g_dasm_str, "sub.w %s, D%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("sub.w %s, D%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_sub_er_32(void) +std::string m68k_disassembler::d68000_sub_er_32() { - sprintf(g_dasm_str, "sub.l %s, D%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("sub.l %s, D%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_sub_re_8(void) +std::string m68k_disassembler::d68000_sub_re_8() { - sprintf(g_dasm_str, "sub.b D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("sub.b D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_sub_re_16(void) +std::string m68k_disassembler::d68000_sub_re_16() { - sprintf(g_dasm_str, "sub.w D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("sub.w D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_sub_re_32(void) +std::string m68k_disassembler::d68000_sub_re_32() { - sprintf(g_dasm_str, "sub.l D%d, %s", (g_cpu_ir>>9)&7, get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("sub.l D%d, %s", (m_cpu_ir>>9)&7, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_suba_16(void) +std::string m68k_disassembler::d68000_suba_16() { - sprintf(g_dasm_str, "suba.w %s, A%d", get_ea_mode_str_16(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("suba.w %s, A%d", get_ea_mode_str_16(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_suba_32(void) +std::string m68k_disassembler::d68000_suba_32() { - sprintf(g_dasm_str, "suba.l %s, A%d", get_ea_mode_str_32(g_cpu_ir), (g_cpu_ir>>9)&7); + return util::string_format("suba.l %s, A%d", get_ea_mode_str_32(m_cpu_ir), (m_cpu_ir>>9)&7); } -static void d68000_subi_8(void) +std::string m68k_disassembler::d68000_subi_8() { - char* str = get_imm_str_s8(); - sprintf(g_dasm_str, "subi.b %s, %s", str, get_ea_mode_str_8(g_cpu_ir)); + std::string str = get_imm_str_s8(); + return util::string_format("subi.b %s, %s", str, get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_subi_16(void) +std::string m68k_disassembler::d68000_subi_16() { - char* str = get_imm_str_s16(); - sprintf(g_dasm_str, "subi.w %s, %s", str, get_ea_mode_str_16(g_cpu_ir)); + std::string str = get_imm_str_s16(); + return util::string_format("subi.w %s, %s", str, get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_subi_32(void) +std::string m68k_disassembler::d68000_subi_32() { - char* str = get_imm_str_s32(); - sprintf(g_dasm_str, "subi.l %s, %s", str, get_ea_mode_str_32(g_cpu_ir)); + std::string str = get_imm_str_s32(); + return util::string_format("subi.l %s, %s", str, get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_subq_8(void) +std::string m68k_disassembler::d68000_subq_8() { - sprintf(g_dasm_str, "subq.b #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("subq.b #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_subq_16(void) +std::string m68k_disassembler::d68000_subq_16() { - sprintf(g_dasm_str, "subq.w #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("subq.w #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_subq_32(void) +std::string m68k_disassembler::d68000_subq_32() { - sprintf(g_dasm_str, "subq.l #%d, %s", g_3bit_qdata_table[(g_cpu_ir>>9)&7], get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("subq.l #%d, %s", m_3bit_qdata_table[(m_cpu_ir>>9)&7], get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_subx_rr_8(void) +std::string m68k_disassembler::d68000_subx_rr_8() { - sprintf(g_dasm_str, "subx.b D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.b D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_rr_16(void) +std::string m68k_disassembler::d68000_subx_rr_16() { - sprintf(g_dasm_str, "subx.w D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.w D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_rr_32(void) +std::string m68k_disassembler::d68000_subx_rr_32() { - sprintf(g_dasm_str, "subx.l D%d, D%d", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.l D%d, D%d", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_mm_8(void) +std::string m68k_disassembler::d68000_subx_mm_8() { - sprintf(g_dasm_str, "subx.b -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.b -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_mm_16(void) +std::string m68k_disassembler::d68000_subx_mm_16() { - sprintf(g_dasm_str, "subx.w -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.w -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_subx_mm_32(void) +std::string m68k_disassembler::d68000_subx_mm_32() { - sprintf(g_dasm_str, "subx.l -(A%d), -(A%d)", g_cpu_ir&7, (g_cpu_ir>>9)&7); + return util::string_format("subx.l -(A%d), -(A%d)", m_cpu_ir&7, (m_cpu_ir>>9)&7); } -static void d68000_swap(void) +std::string m68k_disassembler::d68000_swap() { - sprintf(g_dasm_str, "swap D%d", g_cpu_ir&7); + return util::string_format("swap D%d", m_cpu_ir&7); } -static void d68000_tas(void) +std::string m68k_disassembler::d68000_tas() { - sprintf(g_dasm_str, "tas %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("tas %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_trap(void) +std::string m68k_disassembler::d68000_trap() { - sprintf(g_dasm_str, "trap #$%x", g_cpu_ir&0xf); + return util::string_format("trap #$%x", m_cpu_ir&0xf); } -static void d68020_trapcc_0(void) +std::string m68k_disassembler::d68020_trapcc_0() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "trap%-2s; (2+)", g_cc[(g_cpu_ir>>8)&0xf]); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("trap%-2s; (2+)", m_cc[(m_cpu_ir>>8)&0xf]); } -static void d68020_trapcc_16(void) +std::string m68k_disassembler::d68020_trapcc_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "trap%-2s %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u16()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("trap%-2s %s; (2+)", m_cc[(m_cpu_ir>>8)&0xf], get_imm_str_u16()); } -static void d68020_trapcc_32(void) +std::string m68k_disassembler::d68020_trapcc_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "trap%-2s %s; (2+)", g_cc[(g_cpu_ir>>8)&0xf], get_imm_str_u32()); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + m_flags = STEP_OVER; + return util::string_format("trap%-2s %s; (2+)", m_cc[(m_cpu_ir>>8)&0xf], get_imm_str_u32()); } -static void d68000_trapv(void) +std::string m68k_disassembler::d68000_trapv() { - sprintf(g_dasm_str, "trapv"); - SET_OPCODE_FLAGS(DASMFLAG_STEP_OVER); + m_flags = STEP_OVER; + return util::string_format("trapv"); } -static void d68000_tst_8(void) +std::string m68k_disassembler::d68000_tst_8() { - sprintf(g_dasm_str, "tst.b %s", get_ea_mode_str_8(g_cpu_ir)); + return util::string_format("tst.b %s", get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_tst_pcdi_8(void) +std::string m68k_disassembler::d68020_tst_pcdi_8() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.b %s; (2+)", get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_tst_pcix_8(void) +std::string m68k_disassembler::d68020_tst_pcix_8() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.b %s; (2+)", get_ea_mode_str_8(m_cpu_ir)); } -static void d68020_tst_i_8(void) +std::string m68k_disassembler::d68020_tst_i_8() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.b %s; (2+)", get_ea_mode_str_8(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.b %s; (2+)", get_ea_mode_str_8(m_cpu_ir)); } -static void d68000_tst_16(void) +std::string m68k_disassembler::d68000_tst_16() { - sprintf(g_dasm_str, "tst.w %s", get_ea_mode_str_16(g_cpu_ir)); + return util::string_format("tst.w %s", get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_tst_a_16(void) +std::string m68k_disassembler::d68020_tst_a_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.w %s; (2+)", get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_tst_pcdi_16(void) +std::string m68k_disassembler::d68020_tst_pcdi_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.w %s; (2+)", get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_tst_pcix_16(void) +std::string m68k_disassembler::d68020_tst_pcix_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.w %s; (2+)", get_ea_mode_str_16(m_cpu_ir)); } -static void d68020_tst_i_16(void) +std::string m68k_disassembler::d68020_tst_i_16() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.w %s; (2+)", get_ea_mode_str_16(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.w %s; (2+)", get_ea_mode_str_16(m_cpu_ir)); } -static void d68000_tst_32(void) +std::string m68k_disassembler::d68000_tst_32() { - sprintf(g_dasm_str, "tst.l %s", get_ea_mode_str_32(g_cpu_ir)); + return util::string_format("tst.l %s", get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_tst_a_32(void) +std::string m68k_disassembler::d68020_tst_a_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.l %s; (2+)", get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_tst_pcdi_32(void) +std::string m68k_disassembler::d68020_tst_pcdi_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.l %s; (2+)", get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_tst_pcix_32(void) +std::string m68k_disassembler::d68020_tst_pcix_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.l %s; (2+)", get_ea_mode_str_32(m_cpu_ir)); } -static void d68020_tst_i_32(void) +std::string m68k_disassembler::d68020_tst_i_32() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "tst.l %s; (2+)", get_ea_mode_str_32(g_cpu_ir)); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("tst.l %s; (2+)", get_ea_mode_str_32(m_cpu_ir)); } -static void d68000_unlk(void) +std::string m68k_disassembler::d68000_unlk() { - sprintf(g_dasm_str, "unlk A%d", g_cpu_ir&7); + return util::string_format("unlk A%d", m_cpu_ir&7); } -static void d68020_unpk_rr(void) +std::string m68k_disassembler::d68020_unpk_rr() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "unpk D%d, D%d, %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("unpk D%d, D%d, %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16()); } -static void d68020_unpk_mm(void) +std::string m68k_disassembler::d68020_unpk_mm() { - LIMIT_CPU_TYPES(M68020_PLUS); - sprintf(g_dasm_str, "unpk -(A%d), -(A%d), %s; (2+)", g_cpu_ir&7, (g_cpu_ir>>9)&7, get_imm_str_u16()); + auto limit = limit_cpu_types(M68020_PLUS); + if(limit.first) + return limit.second; + return util::string_format("unpk -(A%d), -(A%d), %s; (2+)", m_cpu_ir&7, (m_cpu_ir>>9)&7, get_imm_str_u16()); } @@ -3249,54 +2926,48 @@ static void d68020_unpk_mm(void) // PMOVE 3: 011xxxx000000000 // PTEST: 100xxxxxxxxxxxxx // PFLUSHR: 1010000000000000 -static void d68851_p000(void) +std::string m68k_disassembler::d68851_p000() { - char* str; - uint16_t modes = read_imm_16(); + u16 modes = read_imm_16(); // do this after fetching the second PMOVE word so we properly get the 3rd if necessary - str = get_ea_mode_str_32(g_cpu_ir); + std::string str = get_ea_mode_str_32(m_cpu_ir); if ((modes & 0xfde0) == 0x2000) // PLOAD { if (modes & 0x0200) { - sprintf(g_dasm_str, "pload #%d, %s", (modes>>10)&7, str); + return util::string_format("pload #%d, %s", (modes>>10)&7, str); } else { - sprintf(g_dasm_str, "pload %s, #%d", str, (modes>>10)&7); + return util::string_format("pload %s, #%d", str, (modes>>10)&7); } - return; } if ((modes & 0xe200) == 0x2000) // PFLUSH { - sprintf(g_dasm_str, "pflushr %x, %x, %s", modes & 0x1f, (modes>>5)&0xf, str); - return; + return util::string_format("pflushr %x, %x, %s", modes & 0x1f, (modes>>5)&0xf, str); } if (modes == 0xa000) // PFLUSHR { - sprintf(g_dasm_str, "pflushr %s", str); + return util::string_format("pflushr %s", str); } if (modes == 0x2800) // PVALID (FORMAT 1) { - sprintf(g_dasm_str, "pvalid VAL, %s", str); - return; + return util::string_format("pvalid VAL, %s", str); } if ((modes & 0xfff8) == 0x2c00) // PVALID (FORMAT 2) { - sprintf(g_dasm_str, "pvalid A%d, %s", modes & 0xf, str); - return; + return util::string_format("pvalid A%d, %s", modes & 0xf, str); } if ((modes & 0xe000) == 0x8000) // PTEST { - sprintf(g_dasm_str, "ptest #%d, %s", modes & 0x1f, str); - return; + return util::string_format("ptest #%d, %s", modes & 0x1f, str); } switch ((modes>>13) & 0x7) @@ -3307,22 +2978,22 @@ static void d68851_p000(void) { if (modes & 0x0200) { - sprintf(g_dasm_str, "pmovefd %s, %s", g_mmuregs[(modes>>10)&7], str); + return util::string_format("pmovefd %s, %s", m_mmuregs[(modes>>10)&7], str); } else { - sprintf(g_dasm_str, "pmovefd %s, %s", str, g_mmuregs[(modes>>10)&7]); + return util::string_format("pmovefd %s, %s", str, m_mmuregs[(modes>>10)&7]); } } else { if (modes & 0x0200) { - sprintf(g_dasm_str, "pmove %s, %s", g_mmuregs[(modes>>10)&7], str); + return util::string_format("pmove %s, %s", m_mmuregs[(modes>>10)&7], str); } else { - sprintf(g_dasm_str, "pmove %s, %s", str, g_mmuregs[(modes>>10)&7]); + return util::string_format("pmove %s, %s", str, m_mmuregs[(modes>>10)&7]); } } break; @@ -3330,63 +3001,65 @@ static void d68851_p000(void) case 3: // MC68030 to/from status reg if (modes & 0x0200) { - sprintf(g_dasm_str, "pmove mmusr, %s", str); + return util::string_format("pmove mmusr, %s", str); } else { - sprintf(g_dasm_str, "pmove %s, mmusr", str); + return util::string_format("pmove %s, mmusr", str); } break; - default: - sprintf(g_dasm_str, "pmove [unknown form] %s", str); - break; } + return util::string_format("pmove [unknown form] %s", str); } -static void d68851_pbcc16(void) +std::string m68k_disassembler::d68851_pbcc16() { - uint32_t temp_pc = g_cpu_pc; + u32 temp_pc = m_cpu_pc; - sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_16(read_imm_16())); + return util::string_format("pb%s %x", m_mmucond[m_cpu_ir&0xf], temp_pc + make_int_16(read_imm_16())); } -static void d68851_pbcc32(void) +std::string m68k_disassembler::d68851_pbcc32() { - uint32_t temp_pc = g_cpu_pc; + u32 temp_pc = m_cpu_pc; - sprintf(g_dasm_str, "pb%s %x", g_mmucond[g_cpu_ir&0xf], temp_pc + make_int_32(read_imm_32())); + return util::string_format("pb%s %x", m_mmucond[m_cpu_ir&0xf], temp_pc + make_int_32(read_imm_32())); } -static void d68851_pdbcc(void) +std::string m68k_disassembler::d68851_pdbcc() { - uint32_t temp_pc = g_cpu_pc; + u32 temp_pc = m_cpu_pc; uint16_t modes = read_imm_16(); - sprintf(g_dasm_str, "pb%s %x", g_mmucond[modes&0xf], temp_pc + make_int_16(read_imm_16())); + return util::string_format("pb%s %x", m_mmucond[modes&0xf], temp_pc + make_int_16(read_imm_16())); } // PScc: 0000000000xxxxxx -static void d68851_p001(void) +std::string m68k_disassembler::d68851_p001() { - sprintf(g_dasm_str, "MMU 001 group"); + return util::string_format("MMU 001 group"); } // fbcc is 68040 and 68881 -static void d68040_fbcc_16() +std::string m68k_disassembler::d68040_fbcc_16() { - LIMIT_CPU_TYPES(M68030_PLUS); - uint32_t temp_pc = g_cpu_pc; + auto limit = limit_cpu_types(M68030_PLUS); + if(limit.first) + return limit.second; + u32 temp_pc = m_cpu_pc; int16_t disp = make_int_16(read_imm_16()); - sprintf(g_dasm_str, "fb%-s $%x", g_cpcc[g_cpu_ir & 0x3f], temp_pc + disp); + return util::string_format("fb%-s $%x", m_cpcc[m_cpu_ir & 0x3f], temp_pc + disp); } -static void d68040_fbcc_32() +std::string m68k_disassembler::d68040_fbcc_32() { - LIMIT_CPU_TYPES(M68030_PLUS); - uint32_t temp_pc = g_cpu_pc; - uint32_t disp = read_imm_32(); - sprintf(g_dasm_str, "fb%-s $%x", g_cpcc[g_cpu_ir & 0x3f], temp_pc + disp); + auto limit = limit_cpu_types(M68030_PLUS); + if(limit.first) + return limit.second; + u32 temp_pc = m_cpu_pc; + u32 disp = read_imm_32(); + return util::string_format("fb%-s $%x", m_cpcc[m_cpu_ir & 0x3f], temp_pc + disp); } /* ======================================================================== */ @@ -3408,325 +3081,325 @@ static void d68040_fbcc_32() 1 = pc idx */ -static const opcode_struct g_opcode_info[] = +const m68k_disassembler::opcode_struct m68k_disassembler::m_opcode_info[] = { /* opcode handler mask match ea mask */ - {d68000_1010 , 0xf000, 0xa000, 0x000}, - {d68000_1111 , 0xf000, 0xf000, 0x000}, - {d68000_abcd_rr , 0xf1f8, 0xc100, 0x000}, - {d68000_abcd_mm , 0xf1f8, 0xc108, 0x000}, - {d68000_add_er_8 , 0xf1c0, 0xd000, 0xbff}, - {d68000_add_er_16 , 0xf1c0, 0xd040, 0xfff}, - {d68000_add_er_32 , 0xf1c0, 0xd080, 0xfff}, - {d68000_add_re_8 , 0xf1c0, 0xd100, 0x3f8}, - {d68000_add_re_16 , 0xf1c0, 0xd140, 0x3f8}, - {d68000_add_re_32 , 0xf1c0, 0xd180, 0x3f8}, - {d68000_adda_16 , 0xf1c0, 0xd0c0, 0xfff}, - {d68000_adda_32 , 0xf1c0, 0xd1c0, 0xfff}, - {d68000_addi_8 , 0xffc0, 0x0600, 0xbf8}, - {d68000_addi_16 , 0xffc0, 0x0640, 0xbf8}, - {d68000_addi_32 , 0xffc0, 0x0680, 0xbf8}, - {d68000_addq_8 , 0xf1c0, 0x5000, 0xbf8}, - {d68000_addq_16 , 0xf1c0, 0x5040, 0xff8}, - {d68000_addq_32 , 0xf1c0, 0x5080, 0xff8}, - {d68000_addx_rr_8 , 0xf1f8, 0xd100, 0x000}, - {d68000_addx_rr_16 , 0xf1f8, 0xd140, 0x000}, - {d68000_addx_rr_32 , 0xf1f8, 0xd180, 0x000}, - {d68000_addx_mm_8 , 0xf1f8, 0xd108, 0x000}, - {d68000_addx_mm_16 , 0xf1f8, 0xd148, 0x000}, - {d68000_addx_mm_32 , 0xf1f8, 0xd188, 0x000}, - {d68000_and_er_8 , 0xf1c0, 0xc000, 0xbff}, - {d68000_and_er_16 , 0xf1c0, 0xc040, 0xbff}, - {d68000_and_er_32 , 0xf1c0, 0xc080, 0xbff}, - {d68000_and_re_8 , 0xf1c0, 0xc100, 0x3f8}, - {d68000_and_re_16 , 0xf1c0, 0xc140, 0x3f8}, - {d68000_and_re_32 , 0xf1c0, 0xc180, 0x3f8}, - {d68000_andi_to_ccr , 0xffff, 0x023c, 0x000}, - {d68000_andi_to_sr , 0xffff, 0x027c, 0x000}, - {d68000_andi_8 , 0xffc0, 0x0200, 0xbf8}, - {d68000_andi_16 , 0xffc0, 0x0240, 0xbf8}, - {d68000_andi_32 , 0xffc0, 0x0280, 0xbf8}, - {d68000_asr_s_8 , 0xf1f8, 0xe000, 0x000}, - {d68000_asr_s_16 , 0xf1f8, 0xe040, 0x000}, - {d68000_asr_s_32 , 0xf1f8, 0xe080, 0x000}, - {d68000_asr_r_8 , 0xf1f8, 0xe020, 0x000}, - {d68000_asr_r_16 , 0xf1f8, 0xe060, 0x000}, - {d68000_asr_r_32 , 0xf1f8, 0xe0a0, 0x000}, - {d68000_asr_ea , 0xffc0, 0xe0c0, 0x3f8}, - {d68000_asl_s_8 , 0xf1f8, 0xe100, 0x000}, - {d68000_asl_s_16 , 0xf1f8, 0xe140, 0x000}, - {d68000_asl_s_32 , 0xf1f8, 0xe180, 0x000}, - {d68000_asl_r_8 , 0xf1f8, 0xe120, 0x000}, - {d68000_asl_r_16 , 0xf1f8, 0xe160, 0x000}, - {d68000_asl_r_32 , 0xf1f8, 0xe1a0, 0x000}, - {d68000_asl_ea , 0xffc0, 0xe1c0, 0x3f8}, - {d68000_bcc_8 , 0xf000, 0x6000, 0x000}, - {d68000_bcc_16 , 0xf0ff, 0x6000, 0x000}, - {d68020_bcc_32 , 0xf0ff, 0x60ff, 0x000}, - {d68000_bchg_r , 0xf1c0, 0x0140, 0xbf8}, - {d68000_bchg_s , 0xffc0, 0x0840, 0xbf8}, - {d68000_bclr_r , 0xf1c0, 0x0180, 0xbf8}, - {d68000_bclr_s , 0xffc0, 0x0880, 0xbf8}, - {d68020_bfchg , 0xffc0, 0xeac0, 0xa78}, - {d68020_bfclr , 0xffc0, 0xecc0, 0xa78}, - {d68020_bfexts , 0xffc0, 0xebc0, 0xa7b}, - {d68020_bfextu , 0xffc0, 0xe9c0, 0xa7b}, - {d68020_bfffo , 0xffc0, 0xedc0, 0xa7b}, - {d68020_bfins , 0xffc0, 0xefc0, 0xa78}, - {d68020_bfset , 0xffc0, 0xeec0, 0xa78}, - {d68020_bftst , 0xffc0, 0xe8c0, 0xa7b}, - {d68881_ftrap , 0xfff8, 0xf278, 0x000}, - {d68010_bkpt , 0xfff8, 0x4848, 0x000}, - {d68000_bra_8 , 0xff00, 0x6000, 0x000}, - {d68000_bra_16 , 0xffff, 0x6000, 0x000}, - {d68020_bra_32 , 0xffff, 0x60ff, 0x000}, - {d68000_bset_r , 0xf1c0, 0x01c0, 0xbf8}, - {d68000_bset_s , 0xffc0, 0x08c0, 0xbf8}, - {d68000_bsr_8 , 0xff00, 0x6100, 0x000}, - {d68000_bsr_16 , 0xffff, 0x6100, 0x000}, - {d68020_bsr_32 , 0xffff, 0x61ff, 0x000}, - {d68000_btst_r , 0xf1c0, 0x0100, 0xbff}, - {d68000_btst_s , 0xffc0, 0x0800, 0xbfb}, - {d68020_callm , 0xffc0, 0x06c0, 0x27b}, - {d68020_cas_8 , 0xffc0, 0x0ac0, 0x3f8}, - {d68020_cas_16 , 0xffc0, 0x0cc0, 0x3f8}, - {d68020_cas_32 , 0xffc0, 0x0ec0, 0x3f8}, - {d68020_cas2_16 , 0xffff, 0x0cfc, 0x000}, - {d68020_cas2_32 , 0xffff, 0x0efc, 0x000}, - {d68000_chk_16 , 0xf1c0, 0x4180, 0xbff}, - {d68020_chk_32 , 0xf1c0, 0x4100, 0xbff}, - {d68020_chk2_cmp2_8 , 0xffc0, 0x00c0, 0x27b}, - {d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b}, - {d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b}, - {d68040_cinv , 0xff20, 0xf400, 0x000}, - {d68000_clr_8 , 0xffc0, 0x4200, 0xbf8}, - {d68000_clr_16 , 0xffc0, 0x4240, 0xbf8}, - {d68000_clr_32 , 0xffc0, 0x4280, 0xbf8}, - {d68000_cmp_8 , 0xf1c0, 0xb000, 0xbff}, - {d68000_cmp_16 , 0xf1c0, 0xb040, 0xfff}, - {d68000_cmp_32 , 0xf1c0, 0xb080, 0xfff}, - {d68000_cmpa_16 , 0xf1c0, 0xb0c0, 0xfff}, - {d68000_cmpa_32 , 0xf1c0, 0xb1c0, 0xfff}, - {d68000_cmpi_8 , 0xffc0, 0x0c00, 0xbf8}, - {d68020_cmpi_pcdi_8 , 0xffff, 0x0c3a, 0x000}, - {d68020_cmpi_pcix_8 , 0xffff, 0x0c3b, 0x000}, - {d68000_cmpi_16 , 0xffc0, 0x0c40, 0xbf8}, - {d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000}, - {d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000}, - {d68000_cmpi_32 , 0xffc0, 0x0c80, 0xbf8}, - {d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000}, - {d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000}, - {d68000_cmpm_8 , 0xf1f8, 0xb108, 0x000}, - {d68000_cmpm_16 , 0xf1f8, 0xb148, 0x000}, - {d68000_cmpm_32 , 0xf1f8, 0xb188, 0x000}, - {d68020_cpbcc_16 , 0xf1c0, 0xf080, 0x000}, - {d68020_cpbcc_32 , 0xf1c0, 0xf0c0, 0x000}, - {d68020_cpdbcc , 0xf1f8, 0xf048, 0x000}, - {d68020_cpgen , 0xf1c0, 0xf000, 0x000}, - {d68020_cprestore , 0xf1c0, 0xf140, 0x37f}, - {d68020_cpsave , 0xf1c0, 0xf100, 0x2f8}, - {d68020_cpscc , 0xf1c0, 0xf040, 0xbf8}, - {d68020_cptrapcc_0 , 0xf1ff, 0xf07c, 0x000}, - {d68020_cptrapcc_16 , 0xf1ff, 0xf07a, 0x000}, - {d68020_cptrapcc_32 , 0xf1ff, 0xf07b, 0x000}, - {d68040_cpush , 0xff20, 0xf420, 0x000}, - {d68000_dbcc , 0xf0f8, 0x50c8, 0x000}, - {d68000_dbra , 0xfff8, 0x51c8, 0x000}, - {d68000_divs , 0xf1c0, 0x81c0, 0xbff}, - {d68000_divu , 0xf1c0, 0x80c0, 0xbff}, - {d68020_divl , 0xffc0, 0x4c40, 0xbff}, - {d68000_eor_8 , 0xf1c0, 0xb100, 0xbf8}, - {d68000_eor_16 , 0xf1c0, 0xb140, 0xbf8}, - {d68000_eor_32 , 0xf1c0, 0xb180, 0xbf8}, - {d68000_eori_to_ccr , 0xffff, 0x0a3c, 0x000}, - {d68000_eori_to_sr , 0xffff, 0x0a7c, 0x000}, - {d68000_eori_8 , 0xffc0, 0x0a00, 0xbf8}, - {d68000_eori_16 , 0xffc0, 0x0a40, 0xbf8}, - {d68000_eori_32 , 0xffc0, 0x0a80, 0xbf8}, - {d68000_exg_dd , 0xf1f8, 0xc140, 0x000}, - {d68000_exg_aa , 0xf1f8, 0xc148, 0x000}, - {d68000_exg_da , 0xf1f8, 0xc188, 0x000}, - {d68020_extb_32 , 0xfff8, 0x49c0, 0x000}, - {d68000_ext_16 , 0xfff8, 0x4880, 0x000}, - {d68000_ext_32 , 0xfff8, 0x48c0, 0x000}, - {d68040_fpu , 0xffc0, 0xf200, 0x000}, - {d68000_illegal , 0xffff, 0x4afc, 0x000}, - {d68000_jmp , 0xffc0, 0x4ec0, 0x27b}, - {d68000_jsr , 0xffc0, 0x4e80, 0x27b}, - {d68000_lea , 0xf1c0, 0x41c0, 0x27b}, - {d68000_link_16 , 0xfff8, 0x4e50, 0x000}, - {d68020_link_32 , 0xfff8, 0x4808, 0x000}, - {d68000_lsr_s_8 , 0xf1f8, 0xe008, 0x000}, - {d68000_lsr_s_16 , 0xf1f8, 0xe048, 0x000}, - {d68000_lsr_s_32 , 0xf1f8, 0xe088, 0x000}, - {d68000_lsr_r_8 , 0xf1f8, 0xe028, 0x000}, - {d68000_lsr_r_16 , 0xf1f8, 0xe068, 0x000}, - {d68000_lsr_r_32 , 0xf1f8, 0xe0a8, 0x000}, - {d68000_lsr_ea , 0xffc0, 0xe2c0, 0x3f8}, - {d68000_lsl_s_8 , 0xf1f8, 0xe108, 0x000}, - {d68000_lsl_s_16 , 0xf1f8, 0xe148, 0x000}, - {d68000_lsl_s_32 , 0xf1f8, 0xe188, 0x000}, - {d68000_lsl_r_8 , 0xf1f8, 0xe128, 0x000}, - {d68000_lsl_r_16 , 0xf1f8, 0xe168, 0x000}, - {d68000_lsl_r_32 , 0xf1f8, 0xe1a8, 0x000}, - {d68000_lsl_ea , 0xffc0, 0xe3c0, 0x3f8}, - {d68000_move_8 , 0xf000, 0x1000, 0xbff}, - {d68000_move_16 , 0xf000, 0x3000, 0xfff}, - {d68000_move_32 , 0xf000, 0x2000, 0xfff}, - {d68000_movea_16 , 0xf1c0, 0x3040, 0xfff}, - {d68000_movea_32 , 0xf1c0, 0x2040, 0xfff}, - {d68000_move_to_ccr , 0xffc0, 0x44c0, 0xbff}, - {d68010_move_fr_ccr , 0xffc0, 0x42c0, 0xbf8}, - {d68000_move_to_sr , 0xffc0, 0x46c0, 0xbff}, - {d68000_move_fr_sr , 0xffc0, 0x40c0, 0xbf8}, - {d68000_move_to_usp , 0xfff8, 0x4e60, 0x000}, - {d68000_move_fr_usp , 0xfff8, 0x4e68, 0x000}, - {d68010_movec , 0xfffe, 0x4e7a, 0x000}, - {d68000_movem_pd_16 , 0xfff8, 0x48a0, 0x000}, - {d68000_movem_pd_32 , 0xfff8, 0x48e0, 0x000}, - {d68000_movem_re_16 , 0xffc0, 0x4880, 0x2f8}, - {d68000_movem_re_32 , 0xffc0, 0x48c0, 0x2f8}, - {d68000_movem_er_16 , 0xffc0, 0x4c80, 0x37b}, - {d68000_movem_er_32 , 0xffc0, 0x4cc0, 0x37b}, - {d68000_movep_er_16 , 0xf1f8, 0x0108, 0x000}, - {d68000_movep_er_32 , 0xf1f8, 0x0148, 0x000}, - {d68000_movep_re_16 , 0xf1f8, 0x0188, 0x000}, - {d68000_movep_re_32 , 0xf1f8, 0x01c8, 0x000}, - {d68010_moves_8 , 0xffc0, 0x0e00, 0x3f8}, - {d68010_moves_16 , 0xffc0, 0x0e40, 0x3f8}, - {d68010_moves_32 , 0xffc0, 0x0e80, 0x3f8}, - {d68000_moveq , 0xf100, 0x7000, 0x000}, - {d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000}, - {d68040_move16_pi_al , 0xfff8, 0xf600, 0x000}, - {d68040_move16_al_pi , 0xfff8, 0xf608, 0x000}, - {d68040_move16_ai_al , 0xfff8, 0xf610, 0x000}, - {d68040_move16_al_ai , 0xfff8, 0xf618, 0x000}, - {d68000_muls , 0xf1c0, 0xc1c0, 0xbff}, - {d68000_mulu , 0xf1c0, 0xc0c0, 0xbff}, - {d68020_mull , 0xffc0, 0x4c00, 0xbff}, - {d68000_nbcd , 0xffc0, 0x4800, 0xbf8}, - {d68000_neg_8 , 0xffc0, 0x4400, 0xbf8}, - {d68000_neg_16 , 0xffc0, 0x4440, 0xbf8}, - {d68000_neg_32 , 0xffc0, 0x4480, 0xbf8}, - {d68000_negx_8 , 0xffc0, 0x4000, 0xbf8}, - {d68000_negx_16 , 0xffc0, 0x4040, 0xbf8}, - {d68000_negx_32 , 0xffc0, 0x4080, 0xbf8}, - {d68000_nop , 0xffff, 0x4e71, 0x000}, - {d68000_not_8 , 0xffc0, 0x4600, 0xbf8}, - {d68000_not_16 , 0xffc0, 0x4640, 0xbf8}, - {d68000_not_32 , 0xffc0, 0x4680, 0xbf8}, - {d68000_or_er_8 , 0xf1c0, 0x8000, 0xbff}, - {d68000_or_er_16 , 0xf1c0, 0x8040, 0xbff}, - {d68000_or_er_32 , 0xf1c0, 0x8080, 0xbff}, - {d68000_or_re_8 , 0xf1c0, 0x8100, 0x3f8}, - {d68000_or_re_16 , 0xf1c0, 0x8140, 0x3f8}, - {d68000_or_re_32 , 0xf1c0, 0x8180, 0x3f8}, - {d68000_ori_to_ccr , 0xffff, 0x003c, 0x000}, - {d68000_ori_to_sr , 0xffff, 0x007c, 0x000}, - {d68000_ori_8 , 0xffc0, 0x0000, 0xbf8}, - {d68000_ori_16 , 0xffc0, 0x0040, 0xbf8}, - {d68000_ori_32 , 0xffc0, 0x0080, 0xbf8}, - {d68020_pack_rr , 0xf1f8, 0x8140, 0x000}, - {d68020_pack_mm , 0xf1f8, 0x8148, 0x000}, - {d68000_pea , 0xffc0, 0x4840, 0x27b}, - {d68040_pflush , 0xffe0, 0xf500, 0x000}, - {d68000_reset , 0xffff, 0x4e70, 0x000}, - {d68000_ror_s_8 , 0xf1f8, 0xe018, 0x000}, - {d68000_ror_s_16 , 0xf1f8, 0xe058, 0x000}, - {d68000_ror_s_32 , 0xf1f8, 0xe098, 0x000}, - {d68000_ror_r_8 , 0xf1f8, 0xe038, 0x000}, - {d68000_ror_r_16 , 0xf1f8, 0xe078, 0x000}, - {d68000_ror_r_32 , 0xf1f8, 0xe0b8, 0x000}, - {d68000_ror_ea , 0xffc0, 0xe6c0, 0x3f8}, - {d68000_rol_s_8 , 0xf1f8, 0xe118, 0x000}, - {d68000_rol_s_16 , 0xf1f8, 0xe158, 0x000}, - {d68000_rol_s_32 , 0xf1f8, 0xe198, 0x000}, - {d68000_rol_r_8 , 0xf1f8, 0xe138, 0x000}, - {d68000_rol_r_16 , 0xf1f8, 0xe178, 0x000}, - {d68000_rol_r_32 , 0xf1f8, 0xe1b8, 0x000}, - {d68000_rol_ea , 0xffc0, 0xe7c0, 0x3f8}, - {d68000_roxr_s_8 , 0xf1f8, 0xe010, 0x000}, - {d68000_roxr_s_16 , 0xf1f8, 0xe050, 0x000}, - {d68000_roxr_s_32 , 0xf1f8, 0xe090, 0x000}, - {d68000_roxr_r_8 , 0xf1f8, 0xe030, 0x000}, - {d68000_roxr_r_16 , 0xf1f8, 0xe070, 0x000}, - {d68000_roxr_r_32 , 0xf1f8, 0xe0b0, 0x000}, - {d68000_roxr_ea , 0xffc0, 0xe4c0, 0x3f8}, - {d68000_roxl_s_8 , 0xf1f8, 0xe110, 0x000}, - {d68000_roxl_s_16 , 0xf1f8, 0xe150, 0x000}, - {d68000_roxl_s_32 , 0xf1f8, 0xe190, 0x000}, - {d68000_roxl_r_8 , 0xf1f8, 0xe130, 0x000}, - {d68000_roxl_r_16 , 0xf1f8, 0xe170, 0x000}, - {d68000_roxl_r_32 , 0xf1f8, 0xe1b0, 0x000}, - {d68000_roxl_ea , 0xffc0, 0xe5c0, 0x3f8}, - {d68010_rtd , 0xffff, 0x4e74, 0x000}, - {d68000_rte , 0xffff, 0x4e73, 0x000}, - {d68020_rtm , 0xfff0, 0x06c0, 0x000}, - {d68000_rtr , 0xffff, 0x4e77, 0x000}, - {d68000_rts , 0xffff, 0x4e75, 0x000}, - {d68000_sbcd_rr , 0xf1f8, 0x8100, 0x000}, - {d68000_sbcd_mm , 0xf1f8, 0x8108, 0x000}, - {d68000_scc , 0xf0c0, 0x50c0, 0xbf8}, - {d68000_stop , 0xffff, 0x4e72, 0x000}, - {d68000_sub_er_8 , 0xf1c0, 0x9000, 0xbff}, - {d68000_sub_er_16 , 0xf1c0, 0x9040, 0xfff}, - {d68000_sub_er_32 , 0xf1c0, 0x9080, 0xfff}, - {d68000_sub_re_8 , 0xf1c0, 0x9100, 0x3f8}, - {d68000_sub_re_16 , 0xf1c0, 0x9140, 0x3f8}, - {d68000_sub_re_32 , 0xf1c0, 0x9180, 0x3f8}, - {d68000_suba_16 , 0xf1c0, 0x90c0, 0xfff}, - {d68000_suba_32 , 0xf1c0, 0x91c0, 0xfff}, - {d68000_subi_8 , 0xffc0, 0x0400, 0xbf8}, - {d68000_subi_16 , 0xffc0, 0x0440, 0xbf8}, - {d68000_subi_32 , 0xffc0, 0x0480, 0xbf8}, - {d68000_subq_8 , 0xf1c0, 0x5100, 0xbf8}, - {d68000_subq_16 , 0xf1c0, 0x5140, 0xff8}, - {d68000_subq_32 , 0xf1c0, 0x5180, 0xff8}, - {d68000_subx_rr_8 , 0xf1f8, 0x9100, 0x000}, - {d68000_subx_rr_16 , 0xf1f8, 0x9140, 0x000}, - {d68000_subx_rr_32 , 0xf1f8, 0x9180, 0x000}, - {d68000_subx_mm_8 , 0xf1f8, 0x9108, 0x000}, - {d68000_subx_mm_16 , 0xf1f8, 0x9148, 0x000}, - {d68000_subx_mm_32 , 0xf1f8, 0x9188, 0x000}, - {d68000_swap , 0xfff8, 0x4840, 0x000}, - {d68000_tas , 0xffc0, 0x4ac0, 0xbf8}, - {d68000_trap , 0xfff0, 0x4e40, 0x000}, - {d68020_trapcc_0 , 0xf0ff, 0x50fc, 0x000}, - {d68020_trapcc_16 , 0xf0ff, 0x50fa, 0x000}, - {d68020_trapcc_32 , 0xf0ff, 0x50fb, 0x000}, - {d68000_trapv , 0xffff, 0x4e76, 0x000}, - {d68000_tst_8 , 0xffc0, 0x4a00, 0xbf8}, - {d68020_tst_pcdi_8 , 0xffff, 0x4a3a, 0x000}, - {d68020_tst_pcix_8 , 0xffff, 0x4a3b, 0x000}, - {d68020_tst_i_8 , 0xffff, 0x4a3c, 0x000}, - {d68000_tst_16 , 0xffc0, 0x4a40, 0xbf8}, - {d68020_tst_a_16 , 0xfff8, 0x4a48, 0x000}, - {d68020_tst_pcdi_16 , 0xffff, 0x4a7a, 0x000}, - {d68020_tst_pcix_16 , 0xffff, 0x4a7b, 0x000}, - {d68020_tst_i_16 , 0xffff, 0x4a7c, 0x000}, - {d68000_tst_32 , 0xffc0, 0x4a80, 0xbf8}, - {d68020_tst_a_32 , 0xfff8, 0x4a88, 0x000}, - {d68020_tst_pcdi_32 , 0xffff, 0x4aba, 0x000}, - {d68020_tst_pcix_32 , 0xffff, 0x4abb, 0x000}, - {d68020_tst_i_32 , 0xffff, 0x4abc, 0x000}, - {d68000_unlk , 0xfff8, 0x4e58, 0x000}, - {d68020_unpk_rr , 0xf1f8, 0x8180, 0x000}, - {d68020_unpk_mm , 0xf1f8, 0x8188, 0x000}, - {d68851_p000 , 0xffc0, 0xf000, 0x000}, - {d68851_pbcc16 , 0xffc0, 0xf080, 0x000}, - {d68851_pbcc32 , 0xffc0, 0xf0c0, 0x000}, - {d68851_pdbcc , 0xfff8, 0xf048, 0x000}, - {d68851_p001 , 0xffc0, 0xf040, 0x000}, - {d68040_fbcc_16 , 0xffc0, 0xf280, 0x000}, - {d68040_fbcc_32 , 0xffc0, 0xf2c0, 0x000}, + {&m68k_disassembler::d68000_1010 , 0xf000, 0xa000, 0x000}, + {&m68k_disassembler::d68000_1111 , 0xf000, 0xf000, 0x000}, + {&m68k_disassembler::d68000_abcd_rr , 0xf1f8, 0xc100, 0x000}, + {&m68k_disassembler::d68000_abcd_mm , 0xf1f8, 0xc108, 0x000}, + {&m68k_disassembler::d68000_add_er_8 , 0xf1c0, 0xd000, 0xbff}, + {&m68k_disassembler::d68000_add_er_16 , 0xf1c0, 0xd040, 0xfff}, + {&m68k_disassembler::d68000_add_er_32 , 0xf1c0, 0xd080, 0xfff}, + {&m68k_disassembler::d68000_add_re_8 , 0xf1c0, 0xd100, 0x3f8}, + {&m68k_disassembler::d68000_add_re_16 , 0xf1c0, 0xd140, 0x3f8}, + {&m68k_disassembler::d68000_add_re_32 , 0xf1c0, 0xd180, 0x3f8}, + {&m68k_disassembler::d68000_adda_16 , 0xf1c0, 0xd0c0, 0xfff}, + {&m68k_disassembler::d68000_adda_32 , 0xf1c0, 0xd1c0, 0xfff}, + {&m68k_disassembler::d68000_addi_8 , 0xffc0, 0x0600, 0xbf8}, + {&m68k_disassembler::d68000_addi_16 , 0xffc0, 0x0640, 0xbf8}, + {&m68k_disassembler::d68000_addi_32 , 0xffc0, 0x0680, 0xbf8}, + {&m68k_disassembler::d68000_addq_8 , 0xf1c0, 0x5000, 0xbf8}, + {&m68k_disassembler::d68000_addq_16 , 0xf1c0, 0x5040, 0xff8}, + {&m68k_disassembler::d68000_addq_32 , 0xf1c0, 0x5080, 0xff8}, + {&m68k_disassembler::d68000_addx_rr_8 , 0xf1f8, 0xd100, 0x000}, + {&m68k_disassembler::d68000_addx_rr_16 , 0xf1f8, 0xd140, 0x000}, + {&m68k_disassembler::d68000_addx_rr_32 , 0xf1f8, 0xd180, 0x000}, + {&m68k_disassembler::d68000_addx_mm_8 , 0xf1f8, 0xd108, 0x000}, + {&m68k_disassembler::d68000_addx_mm_16 , 0xf1f8, 0xd148, 0x000}, + {&m68k_disassembler::d68000_addx_mm_32 , 0xf1f8, 0xd188, 0x000}, + {&m68k_disassembler::d68000_and_er_8 , 0xf1c0, 0xc000, 0xbff}, + {&m68k_disassembler::d68000_and_er_16 , 0xf1c0, 0xc040, 0xbff}, + {&m68k_disassembler::d68000_and_er_32 , 0xf1c0, 0xc080, 0xbff}, + {&m68k_disassembler::d68000_and_re_8 , 0xf1c0, 0xc100, 0x3f8}, + {&m68k_disassembler::d68000_and_re_16 , 0xf1c0, 0xc140, 0x3f8}, + {&m68k_disassembler::d68000_and_re_32 , 0xf1c0, 0xc180, 0x3f8}, + {&m68k_disassembler::d68000_andi_to_ccr , 0xffff, 0x023c, 0x000}, + {&m68k_disassembler::d68000_andi_to_sr , 0xffff, 0x027c, 0x000}, + {&m68k_disassembler::d68000_andi_8 , 0xffc0, 0x0200, 0xbf8}, + {&m68k_disassembler::d68000_andi_16 , 0xffc0, 0x0240, 0xbf8}, + {&m68k_disassembler::d68000_andi_32 , 0xffc0, 0x0280, 0xbf8}, + {&m68k_disassembler::d68000_asr_s_8 , 0xf1f8, 0xe000, 0x000}, + {&m68k_disassembler::d68000_asr_s_16 , 0xf1f8, 0xe040, 0x000}, + {&m68k_disassembler::d68000_asr_s_32 , 0xf1f8, 0xe080, 0x000}, + {&m68k_disassembler::d68000_asr_r_8 , 0xf1f8, 0xe020, 0x000}, + {&m68k_disassembler::d68000_asr_r_16 , 0xf1f8, 0xe060, 0x000}, + {&m68k_disassembler::d68000_asr_r_32 , 0xf1f8, 0xe0a0, 0x000}, + {&m68k_disassembler::d68000_asr_ea , 0xffc0, 0xe0c0, 0x3f8}, + {&m68k_disassembler::d68000_asl_s_8 , 0xf1f8, 0xe100, 0x000}, + {&m68k_disassembler::d68000_asl_s_16 , 0xf1f8, 0xe140, 0x000}, + {&m68k_disassembler::d68000_asl_s_32 , 0xf1f8, 0xe180, 0x000}, + {&m68k_disassembler::d68000_asl_r_8 , 0xf1f8, 0xe120, 0x000}, + {&m68k_disassembler::d68000_asl_r_16 , 0xf1f8, 0xe160, 0x000}, + {&m68k_disassembler::d68000_asl_r_32 , 0xf1f8, 0xe1a0, 0x000}, + {&m68k_disassembler::d68000_asl_ea , 0xffc0, 0xe1c0, 0x3f8}, + {&m68k_disassembler::d68000_bcc_8 , 0xf000, 0x6000, 0x000}, + {&m68k_disassembler::d68000_bcc_16 , 0xf0ff, 0x6000, 0x000}, + {&m68k_disassembler::d68020_bcc_32 , 0xf0ff, 0x60ff, 0x000}, + {&m68k_disassembler::d68000_bchg_r , 0xf1c0, 0x0140, 0xbf8}, + {&m68k_disassembler::d68000_bchg_s , 0xffc0, 0x0840, 0xbf8}, + {&m68k_disassembler::d68000_bclr_r , 0xf1c0, 0x0180, 0xbf8}, + {&m68k_disassembler::d68000_bclr_s , 0xffc0, 0x0880, 0xbf8}, + {&m68k_disassembler::d68020_bfchg , 0xffc0, 0xeac0, 0xa78}, + {&m68k_disassembler::d68020_bfclr , 0xffc0, 0xecc0, 0xa78}, + {&m68k_disassembler::d68020_bfexts , 0xffc0, 0xebc0, 0xa7b}, + {&m68k_disassembler::d68020_bfextu , 0xffc0, 0xe9c0, 0xa7b}, + {&m68k_disassembler::d68020_bfffo , 0xffc0, 0xedc0, 0xa7b}, + {&m68k_disassembler::d68020_bfins , 0xffc0, 0xefc0, 0xa78}, + {&m68k_disassembler::d68020_bfset , 0xffc0, 0xeec0, 0xa78}, + {&m68k_disassembler::d68020_bftst , 0xffc0, 0xe8c0, 0xa7b}, + {&m68k_disassembler::d68881_ftrap , 0xfff8, 0xf278, 0x000}, + {&m68k_disassembler::d68010_bkpt , 0xfff8, 0x4848, 0x000}, + {&m68k_disassembler::d68000_bra_8 , 0xff00, 0x6000, 0x000}, + {&m68k_disassembler::d68000_bra_16 , 0xffff, 0x6000, 0x000}, + {&m68k_disassembler::d68020_bra_32 , 0xffff, 0x60ff, 0x000}, + {&m68k_disassembler::d68000_bset_r , 0xf1c0, 0x01c0, 0xbf8}, + {&m68k_disassembler::d68000_bset_s , 0xffc0, 0x08c0, 0xbf8}, + {&m68k_disassembler::d68000_bsr_8 , 0xff00, 0x6100, 0x000}, + {&m68k_disassembler::d68000_bsr_16 , 0xffff, 0x6100, 0x000}, + {&m68k_disassembler::d68020_bsr_32 , 0xffff, 0x61ff, 0x000}, + {&m68k_disassembler::d68000_btst_r , 0xf1c0, 0x0100, 0xbff}, + {&m68k_disassembler::d68000_btst_s , 0xffc0, 0x0800, 0xbfb}, + {&m68k_disassembler::d68020_callm , 0xffc0, 0x06c0, 0x27b}, + {&m68k_disassembler::d68020_cas_8 , 0xffc0, 0x0ac0, 0x3f8}, + {&m68k_disassembler::d68020_cas_16 , 0xffc0, 0x0cc0, 0x3f8}, + {&m68k_disassembler::d68020_cas_32 , 0xffc0, 0x0ec0, 0x3f8}, + {&m68k_disassembler::d68020_cas2_16 , 0xffff, 0x0cfc, 0x000}, + {&m68k_disassembler::d68020_cas2_32 , 0xffff, 0x0efc, 0x000}, + {&m68k_disassembler::d68000_chk_16 , 0xf1c0, 0x4180, 0xbff}, + {&m68k_disassembler::d68020_chk_32 , 0xf1c0, 0x4100, 0xbff}, + {&m68k_disassembler::d68020_chk2_cmp2_8 , 0xffc0, 0x00c0, 0x27b}, + {&m68k_disassembler::d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b}, + {&m68k_disassembler::d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b}, + {&m68k_disassembler::d68040_cinv , 0xff20, 0xf400, 0x000}, + {&m68k_disassembler::d68000_clr_8 , 0xffc0, 0x4200, 0xbf8}, + {&m68k_disassembler::d68000_clr_16 , 0xffc0, 0x4240, 0xbf8}, + {&m68k_disassembler::d68000_clr_32 , 0xffc0, 0x4280, 0xbf8}, + {&m68k_disassembler::d68000_cmp_8 , 0xf1c0, 0xb000, 0xbff}, + {&m68k_disassembler::d68000_cmp_16 , 0xf1c0, 0xb040, 0xfff}, + {&m68k_disassembler::d68000_cmp_32 , 0xf1c0, 0xb080, 0xfff}, + {&m68k_disassembler::d68000_cmpa_16 , 0xf1c0, 0xb0c0, 0xfff}, + {&m68k_disassembler::d68000_cmpa_32 , 0xf1c0, 0xb1c0, 0xfff}, + {&m68k_disassembler::d68000_cmpi_8 , 0xffc0, 0x0c00, 0xbf8}, + {&m68k_disassembler::d68020_cmpi_pcdi_8 , 0xffff, 0x0c3a, 0x000}, + {&m68k_disassembler::d68020_cmpi_pcix_8 , 0xffff, 0x0c3b, 0x000}, + {&m68k_disassembler::d68000_cmpi_16 , 0xffc0, 0x0c40, 0xbf8}, + {&m68k_disassembler::d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000}, + {&m68k_disassembler::d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000}, + {&m68k_disassembler::d68000_cmpi_32 , 0xffc0, 0x0c80, 0xbf8}, + {&m68k_disassembler::d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000}, + {&m68k_disassembler::d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000}, + {&m68k_disassembler::d68000_cmpm_8 , 0xf1f8, 0xb108, 0x000}, + {&m68k_disassembler::d68000_cmpm_16 , 0xf1f8, 0xb148, 0x000}, + {&m68k_disassembler::d68000_cmpm_32 , 0xf1f8, 0xb188, 0x000}, + {&m68k_disassembler::d68020_cpbcc_16 , 0xf1c0, 0xf080, 0x000}, + {&m68k_disassembler::d68020_cpbcc_32 , 0xf1c0, 0xf0c0, 0x000}, + {&m68k_disassembler::d68020_cpdbcc , 0xf1f8, 0xf048, 0x000}, + {&m68k_disassembler::d68020_cpgen , 0xf1c0, 0xf000, 0x000}, + {&m68k_disassembler::d68020_cprestore , 0xf1c0, 0xf140, 0x37f}, + {&m68k_disassembler::d68020_cpsave , 0xf1c0, 0xf100, 0x2f8}, + {&m68k_disassembler::d68020_cpscc , 0xf1c0, 0xf040, 0xbf8}, + {&m68k_disassembler::d68020_cptrapcc_0 , 0xf1ff, 0xf07c, 0x000}, + {&m68k_disassembler::d68020_cptrapcc_16 , 0xf1ff, 0xf07a, 0x000}, + {&m68k_disassembler::d68020_cptrapcc_32 , 0xf1ff, 0xf07b, 0x000}, + {&m68k_disassembler::d68040_cpush , 0xff20, 0xf420, 0x000}, + {&m68k_disassembler::d68000_dbcc , 0xf0f8, 0x50c8, 0x000}, + {&m68k_disassembler::d68000_dbra , 0xfff8, 0x51c8, 0x000}, + {&m68k_disassembler::d68000_divs , 0xf1c0, 0x81c0, 0xbff}, + {&m68k_disassembler::d68000_divu , 0xf1c0, 0x80c0, 0xbff}, + {&m68k_disassembler::d68020_divl , 0xffc0, 0x4c40, 0xbff}, + {&m68k_disassembler::d68000_eor_8 , 0xf1c0, 0xb100, 0xbf8}, + {&m68k_disassembler::d68000_eor_16 , 0xf1c0, 0xb140, 0xbf8}, + {&m68k_disassembler::d68000_eor_32 , 0xf1c0, 0xb180, 0xbf8}, + {&m68k_disassembler::d68000_eori_to_ccr , 0xffff, 0x0a3c, 0x000}, + {&m68k_disassembler::d68000_eori_to_sr , 0xffff, 0x0a7c, 0x000}, + {&m68k_disassembler::d68000_eori_8 , 0xffc0, 0x0a00, 0xbf8}, + {&m68k_disassembler::d68000_eori_16 , 0xffc0, 0x0a40, 0xbf8}, + {&m68k_disassembler::d68000_eori_32 , 0xffc0, 0x0a80, 0xbf8}, + {&m68k_disassembler::d68000_exg_dd , 0xf1f8, 0xc140, 0x000}, + {&m68k_disassembler::d68000_exg_aa , 0xf1f8, 0xc148, 0x000}, + {&m68k_disassembler::d68000_exg_da , 0xf1f8, 0xc188, 0x000}, + {&m68k_disassembler::d68020_extb_32 , 0xfff8, 0x49c0, 0x000}, + {&m68k_disassembler::d68000_ext_16 , 0xfff8, 0x4880, 0x000}, + {&m68k_disassembler::d68000_ext_32 , 0xfff8, 0x48c0, 0x000}, + {&m68k_disassembler::d68040_fpu , 0xffc0, 0xf200, 0x000}, + {&m68k_disassembler::d68000_illegal , 0xffff, 0x4afc, 0x000}, + {&m68k_disassembler::d68000_jmp , 0xffc0, 0x4ec0, 0x27b}, + {&m68k_disassembler::d68000_jsr , 0xffc0, 0x4e80, 0x27b}, + {&m68k_disassembler::d68000_lea , 0xf1c0, 0x41c0, 0x27b}, + {&m68k_disassembler::d68000_link_16 , 0xfff8, 0x4e50, 0x000}, + {&m68k_disassembler::d68020_link_32 , 0xfff8, 0x4808, 0x000}, + {&m68k_disassembler::d68000_lsr_s_8 , 0xf1f8, 0xe008, 0x000}, + {&m68k_disassembler::d68000_lsr_s_16 , 0xf1f8, 0xe048, 0x000}, + {&m68k_disassembler::d68000_lsr_s_32 , 0xf1f8, 0xe088, 0x000}, + {&m68k_disassembler::d68000_lsr_r_8 , 0xf1f8, 0xe028, 0x000}, + {&m68k_disassembler::d68000_lsr_r_16 , 0xf1f8, 0xe068, 0x000}, + {&m68k_disassembler::d68000_lsr_r_32 , 0xf1f8, 0xe0a8, 0x000}, + {&m68k_disassembler::d68000_lsr_ea , 0xffc0, 0xe2c0, 0x3f8}, + {&m68k_disassembler::d68000_lsl_s_8 , 0xf1f8, 0xe108, 0x000}, + {&m68k_disassembler::d68000_lsl_s_16 , 0xf1f8, 0xe148, 0x000}, + {&m68k_disassembler::d68000_lsl_s_32 , 0xf1f8, 0xe188, 0x000}, + {&m68k_disassembler::d68000_lsl_r_8 , 0xf1f8, 0xe128, 0x000}, + {&m68k_disassembler::d68000_lsl_r_16 , 0xf1f8, 0xe168, 0x000}, + {&m68k_disassembler::d68000_lsl_r_32 , 0xf1f8, 0xe1a8, 0x000}, + {&m68k_disassembler::d68000_lsl_ea , 0xffc0, 0xe3c0, 0x3f8}, + {&m68k_disassembler::d68000_move_8 , 0xf000, 0x1000, 0xbff}, + {&m68k_disassembler::d68000_move_16 , 0xf000, 0x3000, 0xfff}, + {&m68k_disassembler::d68000_move_32 , 0xf000, 0x2000, 0xfff}, + {&m68k_disassembler::d68000_movea_16 , 0xf1c0, 0x3040, 0xfff}, + {&m68k_disassembler::d68000_movea_32 , 0xf1c0, 0x2040, 0xfff}, + {&m68k_disassembler::d68000_move_to_ccr , 0xffc0, 0x44c0, 0xbff}, + {&m68k_disassembler::d68010_move_fr_ccr , 0xffc0, 0x42c0, 0xbf8}, + {&m68k_disassembler::d68000_move_to_sr , 0xffc0, 0x46c0, 0xbff}, + {&m68k_disassembler::d68000_move_fr_sr , 0xffc0, 0x40c0, 0xbf8}, + {&m68k_disassembler::d68000_move_to_usp , 0xfff8, 0x4e60, 0x000}, + {&m68k_disassembler::d68000_move_fr_usp , 0xfff8, 0x4e68, 0x000}, + {&m68k_disassembler::d68010_movec , 0xfffe, 0x4e7a, 0x000}, + {&m68k_disassembler::d68000_movem_pd_16 , 0xfff8, 0x48a0, 0x000}, + {&m68k_disassembler::d68000_movem_pd_32 , 0xfff8, 0x48e0, 0x000}, + {&m68k_disassembler::d68000_movem_re_16 , 0xffc0, 0x4880, 0x2f8}, + {&m68k_disassembler::d68000_movem_re_32 , 0xffc0, 0x48c0, 0x2f8}, + {&m68k_disassembler::d68000_movem_er_16 , 0xffc0, 0x4c80, 0x37b}, + {&m68k_disassembler::d68000_movem_er_32 , 0xffc0, 0x4cc0, 0x37b}, + {&m68k_disassembler::d68000_movep_er_16 , 0xf1f8, 0x0108, 0x000}, + {&m68k_disassembler::d68000_movep_er_32 , 0xf1f8, 0x0148, 0x000}, + {&m68k_disassembler::d68000_movep_re_16 , 0xf1f8, 0x0188, 0x000}, + {&m68k_disassembler::d68000_movep_re_32 , 0xf1f8, 0x01c8, 0x000}, + {&m68k_disassembler::d68010_moves_8 , 0xffc0, 0x0e00, 0x3f8}, + {&m68k_disassembler::d68010_moves_16 , 0xffc0, 0x0e40, 0x3f8}, + {&m68k_disassembler::d68010_moves_32 , 0xffc0, 0x0e80, 0x3f8}, + {&m68k_disassembler::d68000_moveq , 0xf100, 0x7000, 0x000}, + {&m68k_disassembler::d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000}, + {&m68k_disassembler::d68040_move16_pi_al , 0xfff8, 0xf600, 0x000}, + {&m68k_disassembler::d68040_move16_al_pi , 0xfff8, 0xf608, 0x000}, + {&m68k_disassembler::d68040_move16_ai_al , 0xfff8, 0xf610, 0x000}, + {&m68k_disassembler::d68040_move16_al_ai , 0xfff8, 0xf618, 0x000}, + {&m68k_disassembler::d68000_muls , 0xf1c0, 0xc1c0, 0xbff}, + {&m68k_disassembler::d68000_mulu , 0xf1c0, 0xc0c0, 0xbff}, + {&m68k_disassembler::d68020_mull , 0xffc0, 0x4c00, 0xbff}, + {&m68k_disassembler::d68000_nbcd , 0xffc0, 0x4800, 0xbf8}, + {&m68k_disassembler::d68000_neg_8 , 0xffc0, 0x4400, 0xbf8}, + {&m68k_disassembler::d68000_neg_16 , 0xffc0, 0x4440, 0xbf8}, + {&m68k_disassembler::d68000_neg_32 , 0xffc0, 0x4480, 0xbf8}, + {&m68k_disassembler::d68000_negx_8 , 0xffc0, 0x4000, 0xbf8}, + {&m68k_disassembler::d68000_negx_16 , 0xffc0, 0x4040, 0xbf8}, + {&m68k_disassembler::d68000_negx_32 , 0xffc0, 0x4080, 0xbf8}, + {&m68k_disassembler::d68000_nop , 0xffff, 0x4e71, 0x000}, + {&m68k_disassembler::d68000_not_8 , 0xffc0, 0x4600, 0xbf8}, + {&m68k_disassembler::d68000_not_16 , 0xffc0, 0x4640, 0xbf8}, + {&m68k_disassembler::d68000_not_32 , 0xffc0, 0x4680, 0xbf8}, + {&m68k_disassembler::d68000_or_er_8 , 0xf1c0, 0x8000, 0xbff}, + {&m68k_disassembler::d68000_or_er_16 , 0xf1c0, 0x8040, 0xbff}, + {&m68k_disassembler::d68000_or_er_32 , 0xf1c0, 0x8080, 0xbff}, + {&m68k_disassembler::d68000_or_re_8 , 0xf1c0, 0x8100, 0x3f8}, + {&m68k_disassembler::d68000_or_re_16 , 0xf1c0, 0x8140, 0x3f8}, + {&m68k_disassembler::d68000_or_re_32 , 0xf1c0, 0x8180, 0x3f8}, + {&m68k_disassembler::d68000_ori_to_ccr , 0xffff, 0x003c, 0x000}, + {&m68k_disassembler::d68000_ori_to_sr , 0xffff, 0x007c, 0x000}, + {&m68k_disassembler::d68000_ori_8 , 0xffc0, 0x0000, 0xbf8}, + {&m68k_disassembler::d68000_ori_16 , 0xffc0, 0x0040, 0xbf8}, + {&m68k_disassembler::d68000_ori_32 , 0xffc0, 0x0080, 0xbf8}, + {&m68k_disassembler::d68020_pack_rr , 0xf1f8, 0x8140, 0x000}, + {&m68k_disassembler::d68020_pack_mm , 0xf1f8, 0x8148, 0x000}, + {&m68k_disassembler::d68000_pea , 0xffc0, 0x4840, 0x27b}, + {&m68k_disassembler::d68040_pflush , 0xffe0, 0xf500, 0x000}, + {&m68k_disassembler::d68000_reset , 0xffff, 0x4e70, 0x000}, + {&m68k_disassembler::d68000_ror_s_8 , 0xf1f8, 0xe018, 0x000}, + {&m68k_disassembler::d68000_ror_s_16 , 0xf1f8, 0xe058, 0x000}, + {&m68k_disassembler::d68000_ror_s_32 , 0xf1f8, 0xe098, 0x000}, + {&m68k_disassembler::d68000_ror_r_8 , 0xf1f8, 0xe038, 0x000}, + {&m68k_disassembler::d68000_ror_r_16 , 0xf1f8, 0xe078, 0x000}, + {&m68k_disassembler::d68000_ror_r_32 , 0xf1f8, 0xe0b8, 0x000}, + {&m68k_disassembler::d68000_ror_ea , 0xffc0, 0xe6c0, 0x3f8}, + {&m68k_disassembler::d68000_rol_s_8 , 0xf1f8, 0xe118, 0x000}, + {&m68k_disassembler::d68000_rol_s_16 , 0xf1f8, 0xe158, 0x000}, + {&m68k_disassembler::d68000_rol_s_32 , 0xf1f8, 0xe198, 0x000}, + {&m68k_disassembler::d68000_rol_r_8 , 0xf1f8, 0xe138, 0x000}, + {&m68k_disassembler::d68000_rol_r_16 , 0xf1f8, 0xe178, 0x000}, + {&m68k_disassembler::d68000_rol_r_32 , 0xf1f8, 0xe1b8, 0x000}, + {&m68k_disassembler::d68000_rol_ea , 0xffc0, 0xe7c0, 0x3f8}, + {&m68k_disassembler::d68000_roxr_s_8 , 0xf1f8, 0xe010, 0x000}, + {&m68k_disassembler::d68000_roxr_s_16 , 0xf1f8, 0xe050, 0x000}, + {&m68k_disassembler::d68000_roxr_s_32 , 0xf1f8, 0xe090, 0x000}, + {&m68k_disassembler::d68000_roxr_r_8 , 0xf1f8, 0xe030, 0x000}, + {&m68k_disassembler::d68000_roxr_r_16 , 0xf1f8, 0xe070, 0x000}, + {&m68k_disassembler::d68000_roxr_r_32 , 0xf1f8, 0xe0b0, 0x000}, + {&m68k_disassembler::d68000_roxr_ea , 0xffc0, 0xe4c0, 0x3f8}, + {&m68k_disassembler::d68000_roxl_s_8 , 0xf1f8, 0xe110, 0x000}, + {&m68k_disassembler::d68000_roxl_s_16 , 0xf1f8, 0xe150, 0x000}, + {&m68k_disassembler::d68000_roxl_s_32 , 0xf1f8, 0xe190, 0x000}, + {&m68k_disassembler::d68000_roxl_r_8 , 0xf1f8, 0xe130, 0x000}, + {&m68k_disassembler::d68000_roxl_r_16 , 0xf1f8, 0xe170, 0x000}, + {&m68k_disassembler::d68000_roxl_r_32 , 0xf1f8, 0xe1b0, 0x000}, + {&m68k_disassembler::d68000_roxl_ea , 0xffc0, 0xe5c0, 0x3f8}, + {&m68k_disassembler::d68010_rtd , 0xffff, 0x4e74, 0x000}, + {&m68k_disassembler::d68000_rte , 0xffff, 0x4e73, 0x000}, + {&m68k_disassembler::d68020_rtm , 0xfff0, 0x06c0, 0x000}, + {&m68k_disassembler::d68000_rtr , 0xffff, 0x4e77, 0x000}, + {&m68k_disassembler::d68000_rts , 0xffff, 0x4e75, 0x000}, + {&m68k_disassembler::d68000_sbcd_rr , 0xf1f8, 0x8100, 0x000}, + {&m68k_disassembler::d68000_sbcd_mm , 0xf1f8, 0x8108, 0x000}, + {&m68k_disassembler::d68000_scc , 0xf0c0, 0x50c0, 0xbf8}, + {&m68k_disassembler::d68000_stop , 0xffff, 0x4e72, 0x000}, + {&m68k_disassembler::d68000_sub_er_8 , 0xf1c0, 0x9000, 0xbff}, + {&m68k_disassembler::d68000_sub_er_16 , 0xf1c0, 0x9040, 0xfff}, + {&m68k_disassembler::d68000_sub_er_32 , 0xf1c0, 0x9080, 0xfff}, + {&m68k_disassembler::d68000_sub_re_8 , 0xf1c0, 0x9100, 0x3f8}, + {&m68k_disassembler::d68000_sub_re_16 , 0xf1c0, 0x9140, 0x3f8}, + {&m68k_disassembler::d68000_sub_re_32 , 0xf1c0, 0x9180, 0x3f8}, + {&m68k_disassembler::d68000_suba_16 , 0xf1c0, 0x90c0, 0xfff}, + {&m68k_disassembler::d68000_suba_32 , 0xf1c0, 0x91c0, 0xfff}, + {&m68k_disassembler::d68000_subi_8 , 0xffc0, 0x0400, 0xbf8}, + {&m68k_disassembler::d68000_subi_16 , 0xffc0, 0x0440, 0xbf8}, + {&m68k_disassembler::d68000_subi_32 , 0xffc0, 0x0480, 0xbf8}, + {&m68k_disassembler::d68000_subq_8 , 0xf1c0, 0x5100, 0xbf8}, + {&m68k_disassembler::d68000_subq_16 , 0xf1c0, 0x5140, 0xff8}, + {&m68k_disassembler::d68000_subq_32 , 0xf1c0, 0x5180, 0xff8}, + {&m68k_disassembler::d68000_subx_rr_8 , 0xf1f8, 0x9100, 0x000}, + {&m68k_disassembler::d68000_subx_rr_16 , 0xf1f8, 0x9140, 0x000}, + {&m68k_disassembler::d68000_subx_rr_32 , 0xf1f8, 0x9180, 0x000}, + {&m68k_disassembler::d68000_subx_mm_8 , 0xf1f8, 0x9108, 0x000}, + {&m68k_disassembler::d68000_subx_mm_16 , 0xf1f8, 0x9148, 0x000}, + {&m68k_disassembler::d68000_subx_mm_32 , 0xf1f8, 0x9188, 0x000}, + {&m68k_disassembler::d68000_swap , 0xfff8, 0x4840, 0x000}, + {&m68k_disassembler::d68000_tas , 0xffc0, 0x4ac0, 0xbf8}, + {&m68k_disassembler::d68000_trap , 0xfff0, 0x4e40, 0x000}, + {&m68k_disassembler::d68020_trapcc_0 , 0xf0ff, 0x50fc, 0x000}, + {&m68k_disassembler::d68020_trapcc_16 , 0xf0ff, 0x50fa, 0x000}, + {&m68k_disassembler::d68020_trapcc_32 , 0xf0ff, 0x50fb, 0x000}, + {&m68k_disassembler::d68000_trapv , 0xffff, 0x4e76, 0x000}, + {&m68k_disassembler::d68000_tst_8 , 0xffc0, 0x4a00, 0xbf8}, + {&m68k_disassembler::d68020_tst_pcdi_8 , 0xffff, 0x4a3a, 0x000}, + {&m68k_disassembler::d68020_tst_pcix_8 , 0xffff, 0x4a3b, 0x000}, + {&m68k_disassembler::d68020_tst_i_8 , 0xffff, 0x4a3c, 0x000}, + {&m68k_disassembler::d68000_tst_16 , 0xffc0, 0x4a40, 0xbf8}, + {&m68k_disassembler::d68020_tst_a_16 , 0xfff8, 0x4a48, 0x000}, + {&m68k_disassembler::d68020_tst_pcdi_16 , 0xffff, 0x4a7a, 0x000}, + {&m68k_disassembler::d68020_tst_pcix_16 , 0xffff, 0x4a7b, 0x000}, + {&m68k_disassembler::d68020_tst_i_16 , 0xffff, 0x4a7c, 0x000}, + {&m68k_disassembler::d68000_tst_32 , 0xffc0, 0x4a80, 0xbf8}, + {&m68k_disassembler::d68020_tst_a_32 , 0xfff8, 0x4a88, 0x000}, + {&m68k_disassembler::d68020_tst_pcdi_32 , 0xffff, 0x4aba, 0x000}, + {&m68k_disassembler::d68020_tst_pcix_32 , 0xffff, 0x4abb, 0x000}, + {&m68k_disassembler::d68020_tst_i_32 , 0xffff, 0x4abc, 0x000}, + {&m68k_disassembler::d68000_unlk , 0xfff8, 0x4e58, 0x000}, + {&m68k_disassembler::d68020_unpk_rr , 0xf1f8, 0x8180, 0x000}, + {&m68k_disassembler::d68020_unpk_mm , 0xf1f8, 0x8188, 0x000}, + {&m68k_disassembler::d68851_p000 , 0xffc0, 0xf000, 0x000}, + {&m68k_disassembler::d68851_pbcc16 , 0xffc0, 0xf080, 0x000}, + {&m68k_disassembler::d68851_pbcc32 , 0xffc0, 0xf0c0, 0x000}, + {&m68k_disassembler::d68851_pdbcc , 0xfff8, 0xf048, 0x000}, + {&m68k_disassembler::d68851_p001 , 0xffc0, 0xf040, 0x000}, + {&m68k_disassembler::d68040_fbcc_16 , 0xffc0, 0xf280, 0x000}, + {&m68k_disassembler::d68040_fbcc_32 , 0xffc0, 0xf2c0, 0x000}, {nullptr, 0, 0, 0} }; /* Check if opcode is using a valid ea mode */ -static int valid_ea(uint32_t opcode, uint32_t mask) +bool m68k_disassembler::valid_ea(u32 opcode, u32 mask) { if(mask == 0) - return 1; + return true; switch(opcode & 0x3f) { @@ -3762,15 +3435,14 @@ static int valid_ea(uint32_t opcode, uint32_t mask) case 0x3c: return (mask & 0x004) != 0; } - return 0; - + return false; } /* Used by qsort */ -static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr) +bool m68k_disassembler::compare_nof_true_bits(const opcode_struct *aptr, const opcode_struct *bptr) { - uint32_t a = ((const opcode_struct*)aptr)->mask; - uint32_t b = ((const opcode_struct*)bptr)->mask; + u32 a = aptr->mask; + u32 b = bptr->mask; a = ((a & 0xAAAA) >> 1) + (a & 0x5555); a = ((a & 0xCCCC) >> 2) + (a & 0x3333); @@ -3782,39 +3454,35 @@ static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr) b = ((b & 0xF0F0) >> 4) + (b & 0x0F0F); b = ((b & 0xFF00) >> 8) + (b & 0x00FF); - return b - a; /* reversed to get greatest to least sorting */ + return b < a; /* reversed to get greatest to least sorting */ } /* build the opcode handler jump table */ -static void build_opcode_table(void) +void m68k_disassembler::build_opcode_table() { - uint32_t i; - uint32_t opcode; - opcode_struct* ostruct; - opcode_struct opcode_info[ARRAY_LENGTH(g_opcode_info)]; + std::vector<const opcode_struct *> opcode_info; + for(unsigned int i=0; m_opcode_info[i].handler; i++) + opcode_info.push_back(m_opcode_info + i); + std::sort(opcode_info.begin(), opcode_info.end(), compare_nof_true_bits); - memcpy(opcode_info, g_opcode_info, sizeof(g_opcode_info)); - qsort((void *)opcode_info, ARRAY_LENGTH(opcode_info)-1, sizeof(opcode_info[0]), compare_nof_true_bits); - - for(i=0;i<0x10000;i++) + for(u32 opcode = 0; opcode != 0x10000; opcode++) { - g_instruction_table[i] = d68000_illegal; /* default to illegal */ - opcode = i; + m_instruction_table[opcode] = &m68k_disassembler::d68000_illegal; /* default to illegal */ /* search through opcode info for a match */ - for(ostruct = opcode_info;ostruct->opcode_handler != nullptr;ostruct++) + for(const opcode_struct *ostruct : opcode_info) { /* match opcode mask and allowed ea modes */ if((opcode & ostruct->mask) == ostruct->match) { /* Handle destination ea for move instructions */ - if((ostruct->opcode_handler == d68000_move_8 || - ostruct->opcode_handler == d68000_move_16 || - ostruct->opcode_handler == d68000_move_32) && - !valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8)) - continue; + if((ostruct->handler == &m68k_disassembler::d68000_move_8 || + ostruct->handler == &m68k_disassembler::d68000_move_16 || + ostruct->handler == &m68k_disassembler::d68000_move_32) && + !valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8)) + continue; if(valid_ea(opcode, ostruct->ea_mask)) { - g_instruction_table[i] = ostruct->opcode_handler; + m_instruction_table[opcode] = ostruct->handler; break; } } @@ -3828,330 +3496,22 @@ static void build_opcode_table(void) /* ================================= API ================================== */ /* ======================================================================== */ -/* Disasemble one instruction at pc and store in str_buff */ -static unsigned int m68k_disassemble(std::ostream &stream, unsigned int pc, unsigned int cpu_type) +m68k_disassembler::m68k_disassembler(u32 type) : m_cpu_type(type) { - if(!g_initialized) - { - build_opcode_table(); - g_initialized = 1; - } - switch(cpu_type) - { - case M68K_CPU_TYPE_68000: - g_cpu_type = TYPE_68000; - break; - case M68K_CPU_TYPE_68008: - g_cpu_type = TYPE_68008; - break; - case M68K_CPU_TYPE_68010: - g_cpu_type = TYPE_68010; - break; - case M68K_CPU_TYPE_68EC020: - case M68K_CPU_TYPE_68020: - g_cpu_type = TYPE_68020; - break; - case M68K_CPU_TYPE_68EC030: - case M68K_CPU_TYPE_68030: - g_cpu_type = TYPE_68030; - break; - case M68K_CPU_TYPE_68040: - case M68K_CPU_TYPE_68EC040: - case M68K_CPU_TYPE_68LC040: - g_cpu_type = TYPE_68040; - break; - case M68K_CPU_TYPE_FSCPU32: - g_cpu_type = TYPE_68340; - break; - case M68K_CPU_TYPE_COLDFIRE: - g_cpu_type = TYPE_COLDFIRE; - break; - default: - return 0; - } - - g_cpu_pc = pc; - g_helper_str[0] = 0; - g_cpu_ir = read_imm_16(); - g_opcode_type = 0; - g_instruction_table[g_cpu_ir](); - util::stream_format(stream, "%s%s", g_dasm_str, g_helper_str); - return COMBINE_OPCODE_FLAGS(g_cpu_pc - pc); + build_opcode_table(); } -#ifdef UNUSED_FUNCTION -char* m68ki_disassemble_quick(unsigned int pc, unsigned int cpu_type) +u32 m68k_disassembler::opcode_alignment() const { - static char buff[100]; - buff[0] = 0; - m68k_disassemble(buff, pc, cpu_type); - return buff; + return 2; } -#endif -unsigned int m68k_disassemble_raw(std::ostream &stream, unsigned int pc, const unsigned char* opdata, const unsigned char* argdata, unsigned int cpu_type) +offs_t m68k_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned int result; - - g_rawop = opdata; - g_rawbasepc = pc; - result = m68k_disassemble(stream, pc, cpu_type); - g_rawop = nullptr; - return result; + m_cpu_pc = pc; + m_buffer = &opcodes; + m_cpu_ir = read_imm_16(); + m_flags = 0; + stream << (this->*m_instruction_table[m_cpu_ir])(); + return (m_cpu_pc - pc) | m_flags | SUPPORTED; } - -#ifdef UNUSED_FUNCTION -/* Check if the instruction is a valid one */ -unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type) -{ - if(!g_initialized) - { - build_opcode_table(); - g_initialized = 1; - } - - instruction &= 0xffff; - if(g_instruction_table[instruction] == d68000_illegal) - return 0; - - switch(cpu_type) - { - case M68K_CPU_TYPE_68000: - case M68K_CPU_TYPE_68008: - if(g_instruction_table[instruction] == d68010_bkpt) - return 0; - if(g_instruction_table[instruction] == d68010_move_fr_ccr) - return 0; - if(g_instruction_table[instruction] == d68010_movec) - return 0; - if(g_instruction_table[instruction] == d68010_moves_8) - return 0; - if(g_instruction_table[instruction] == d68010_moves_16) - return 0; - if(g_instruction_table[instruction] == d68010_moves_32) - return 0; - if(g_instruction_table[instruction] == d68010_rtd) - return 0; - case M68K_CPU_TYPE_68010: - if(g_instruction_table[instruction] == d68020_bcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_bfchg) - return 0; - if(g_instruction_table[instruction] == d68020_bfclr) - return 0; - if(g_instruction_table[instruction] == d68020_bfexts) - return 0; - if(g_instruction_table[instruction] == d68020_bfextu) - return 0; - if(g_instruction_table[instruction] == d68020_bfffo) - return 0; - if(g_instruction_table[instruction] == d68020_bfins) - return 0; - if(g_instruction_table[instruction] == d68020_bfset) - return 0; - if(g_instruction_table[instruction] == d68020_bftst) - return 0; - if(g_instruction_table[instruction] == d68020_bra_32) - return 0; - if(g_instruction_table[instruction] == d68020_bsr_32) - return 0; - if(g_instruction_table[instruction] == d68020_callm) - return 0; - if(g_instruction_table[instruction] == d68020_cas_8) - return 0; - if(g_instruction_table[instruction] == d68020_cas_16) - return 0; - if(g_instruction_table[instruction] == d68020_cas_32) - return 0; - if(g_instruction_table[instruction] == d68020_cas2_16) - return 0; - if(g_instruction_table[instruction] == d68020_cas2_32) - return 0; - if(g_instruction_table[instruction] == d68020_chk_32) - return 0; - if(g_instruction_table[instruction] == d68020_chk2_cmp2_8) - return 0; - if(g_instruction_table[instruction] == d68020_chk2_cmp2_16) - return 0; - if(g_instruction_table[instruction] == d68020_chk2_cmp2_32) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcdi_8) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcix_8) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcdi_16) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcix_16) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcdi_32) - return 0; - if(g_instruction_table[instruction] == d68020_cmpi_pcix_32) - return 0; - if(g_instruction_table[instruction] == d68020_cpbcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cpbcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_cpdbcc) - return 0; - if(g_instruction_table[instruction] == d68020_cpgen) - return 0; - if(g_instruction_table[instruction] == d68020_cprestore) - return 0; - if(g_instruction_table[instruction] == d68020_cpsave) - return 0; - if(g_instruction_table[instruction] == d68020_cpscc) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_0) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_divl) - return 0; - if(g_instruction_table[instruction] == d68020_extb_32) - return 0; - if(g_instruction_table[instruction] == d68020_link_32) - return 0; - if(g_instruction_table[instruction] == d68020_mull) - return 0; - if(g_instruction_table[instruction] == d68020_pack_rr) - return 0; - if(g_instruction_table[instruction] == d68020_pack_mm) - return 0; - if(g_instruction_table[instruction] == d68020_rtm) - return 0; - if(g_instruction_table[instruction] == d68020_trapcc_0) - return 0; - if(g_instruction_table[instruction] == d68020_trapcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_trapcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcdi_8) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcix_8) - return 0; - if(g_instruction_table[instruction] == d68020_tst_i_8) - return 0; - if(g_instruction_table[instruction] == d68020_tst_a_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcdi_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcix_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_i_16) - return 0; - if(g_instruction_table[instruction] == d68020_tst_a_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcdi_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_pcix_32) - return 0; - if(g_instruction_table[instruction] == d68020_tst_i_32) - return 0; - if(g_instruction_table[instruction] == d68020_unpk_rr) - return 0; - if(g_instruction_table[instruction] == d68020_unpk_mm) - return 0; - if(g_instruction_table[instruction] == d68040_fbcc_16) - return 0; - if(g_instruction_table[instruction] == d68040_fbcc_32) - return 0; - case M68K_CPU_TYPE_68EC020: - case M68K_CPU_TYPE_68020: - case M68K_CPU_TYPE_68030: - case M68K_CPU_TYPE_68EC030: - case M68K_CPU_TYPE_FSCPU32: - case M68K_CPU_TYPE_COLDFIRE: - if(g_instruction_table[instruction] == d68040_cinv) - return 0; - if(g_instruction_table[instruction] == d68040_cpush) - return 0; - if(g_instruction_table[instruction] == d68040_move16_pi_pi) - return 0; - if(g_instruction_table[instruction] == d68040_move16_pi_al) - return 0; - if(g_instruction_table[instruction] == d68040_move16_al_pi) - return 0; - if(g_instruction_table[instruction] == d68040_move16_ai_al) - return 0; - if(g_instruction_table[instruction] == d68040_move16_al_ai) - return 0; - case M68K_CPU_TYPE_68040: - case M68K_CPU_TYPE_68EC040: - case M68K_CPU_TYPE_68LC040: - if(g_instruction_table[instruction] == d68020_cpbcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cpbcc_32) - return 0; - if(g_instruction_table[instruction] == d68020_cpdbcc) - return 0; - if(g_instruction_table[instruction] == d68020_cpgen) - return 0; - if(g_instruction_table[instruction] == d68020_cprestore) - return 0; - if(g_instruction_table[instruction] == d68020_cpsave) - return 0; - if(g_instruction_table[instruction] == d68020_cpscc) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_0) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_16) - return 0; - if(g_instruction_table[instruction] == d68020_cptrapcc_32) - return 0; - if(g_instruction_table[instruction] == d68040_pflush) - return 0; - } - if(cpu_type != M68K_CPU_TYPE_68020 && cpu_type != M68K_CPU_TYPE_68EC020 && - (g_instruction_table[instruction] == d68020_callm || - g_instruction_table[instruction] == d68020_rtm)) - return 0; - - return 1; -} -#endif - -CPU_DISASSEMBLE( m68000 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68000); -} - -CPU_DISASSEMBLE( m68008 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68008); -} - -CPU_DISASSEMBLE( m68010 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68010); -} - -CPU_DISASSEMBLE( m68020 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68020); -} - -CPU_DISASSEMBLE( m68030 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68030); -} - -CPU_DISASSEMBLE( m68040 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_68040); -} - -CPU_DISASSEMBLE( m68340 ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_FSCPU32); -} - -CPU_DISASSEMBLE( coldfire ) -{ - return m68k_disassemble_raw(stream, pc, oprom, opram, M68K_CPU_TYPE_COLDFIRE); -} - -/* ======================================================================== */ -/* ============================== END OF FILE ============================= */ -/* ======================================================================== */ diff --git a/src/devices/cpu/m68000/m68kdasm.h b/src/devices/cpu/m68000/m68kdasm.h new file mode 100644 index 00000000000..43dfd144980 --- /dev/null +++ b/src/devices/cpu/m68000/m68kdasm.h @@ -0,0 +1,454 @@ +// license:BSD-3-Clause +// copyright-holders:Karl Stenerud +/* ======================================================================== */ +/* ========================= LICENSING & COPYRIGHT ======================== */ +/* ======================================================================== */ +/* + * MUSASHI + * Version 3.32 + * + * A portable Motorola M680x0 processor emulation engine. + * Copyright Karl Stenerud. All rights reserved. + * + */ + +#ifndef MAME_CPU_M68000_M68KDASM_H +#define MAME_CPU_M68000_M68KDASM_H + +#pragma once + +class m68k_disassembler : public util::disasm_interface +{ +public: + enum { + TYPE_68000 = 1, + TYPE_68008 = 2, + TYPE_68010 = 4, + TYPE_68020 = 8, + TYPE_68030 = 16, + TYPE_68040 = 32, + TYPE_68340 = 64, // (CPU32) + TYPE_COLDFIRE = 128, + }; + + m68k_disassembler(u32 type); + virtual ~m68k_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum { + M68000_ONLY = (TYPE_68000 | TYPE_68008), + M68010_ONLY = TYPE_68010, + M68010_LESS = (TYPE_68000 | TYPE_68008 | TYPE_68010), + M68010_PLUS = (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE), + M68020_ONLY = (TYPE_68020 | TYPE_68340), + M68020_LESS = (TYPE_68010 | TYPE_68020 | TYPE_68340), + M68020_PLUS = (TYPE_68020 | TYPE_68030 | TYPE_68040 | TYPE_68340 | TYPE_COLDFIRE), + + M68030_ONLY = TYPE_68030, + M68030_LESS = (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68340 ), + M68030_PLUS = (TYPE_68030 | TYPE_68040), + M68040_PLUS = TYPE_68040, + + COLDFIRE = TYPE_COLDFIRE + }; + + typedef std::string (m68k_disassembler::*opcode_handler)(); + + struct opcode_struct { + opcode_handler handler; /* handler function */ + u32 mask; /* mask on opcode */ + u32 match; /* what to match after masking */ + u32 ea_mask; /* what ea modes are allowed */ + }; + + /* Extension word formats */ + static inline u32 ext_8bit_displacement(u32 A) { return ((A)&0xff); } + static inline u32 ext_full(u32 A) { return BIT(A, 8); } + static inline u32 ext_effective_zero(u32 A) { return (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0); } + static inline u32 ext_base_register_present(u32 A) { return (!BIT(A, 7)); } + static inline u32 ext_index_register_present(u32 A) { return (!BIT(A, 6)); } + static inline u32 ext_index_register(u32 A) { return (((A)>>12)&7); } + static inline u32 ext_index_scale(u32 A) { return (((A)>>9)&3); } + static inline u32 ext_index_long(u32 A) { return BIT(A, 11); } + static inline u32 ext_index_ar(u32 A) { return BIT(A, 15); } + static inline u32 ext_base_displacement_present(u32 A) { return (((A)&0x30) > 0x10); } + static inline u32 ext_base_displacement_word(u32 A) { return (((A)&0x30) == 0x20); } + static inline u32 ext_base_displacement_long(u32 A) { return (((A)&0x30) == 0x30); } + static inline u32 ext_outer_displacement_present(u32 A) { return (((A)&3) > 1 && ((A)&0x47) < 0x44); } + static inline u32 ext_outer_displacement_word(u32 A) { return (((A)&3) == 2 && ((A)&0x47) < 0x44); } + static inline u32 ext_outer_displacement_long(u32 A) { return (((A)&3) == 3 && ((A)&0x47) < 0x44); } + + static inline s32 sext_7bit_int(u32 value) { return (value & 0x40) ? (value | 0xffffff80) : (value & 0x7f); } + static inline s32 make_int_8(u8 value) { return s8(value); } + static inline s32 make_int_16(u16 value) { return s16(value); } + static inline s32 make_int_32(u32 value) { return s32(value); } + + static std::string make_signed_hex_str_8(u8 val); + static std::string make_signed_hex_str_16(u16 val); + static std::string make_signed_hex_str_32(u32 val); + + inline u32 read_imm_8 (u32 advance) { u32 result = m_buffer->r8 (m_cpu_pc + 1); m_cpu_pc += advance; return result; } + inline u32 read_imm_16(u32 advance) { u32 result = m_buffer->r16(m_cpu_pc); m_cpu_pc += advance; return result; } + inline u32 read_imm_32(u32 advance) { u32 result = m_buffer->r32(m_cpu_pc); m_cpu_pc += advance; return result; } + + inline u32 read_imm_8 () { return read_imm_8 (2); } // 2 to keep alignement + inline u32 read_imm_16() { return read_imm_16(2); } + inline u32 read_imm_32() { return read_imm_32(4); } + + inline u32 peek_imm_8 () { return read_imm_8 (0); } + inline u32 peek_imm_16() { return read_imm_16(0); } + inline u32 peek_imm_32() { return read_imm_32(0); } + + std::string get_imm_str_s(u32 size); + inline std::string get_imm_str_s8 () { return get_imm_str_s(0); } + inline std::string get_imm_str_s16() { return get_imm_str_s(1); } + inline std::string get_imm_str_s32() { return get_imm_str_s(2); } + + std::string get_imm_str_u(u32 size); + inline std::string get_imm_str_u8 () { return get_imm_str_u(0); } + inline std::string get_imm_str_u16() { return get_imm_str_u(1); } + inline std::string get_imm_str_u32() { return get_imm_str_u(2); } + + std::string get_ea_mode_str(u16 instruction, u32 size); + inline std::string get_ea_mode_str_8 (u16 instruction) { return get_ea_mode_str(instruction, 0); } + inline std::string get_ea_mode_str_16(u16 instruction) { return get_ea_mode_str(instruction, 1); } + inline std::string get_ea_mode_str_32(u16 instruction) { return get_ea_mode_str(instruction, 2); } + + inline std::pair<bool, std::string> limit_cpu_types(u32 allowed); + + std::string d68000_illegal(); + std::string d68000_1010(); + std::string d68000_1111(); + std::string d68000_abcd_rr(); + std::string d68000_abcd_mm(); + std::string d68000_add_er_8(); + std::string d68000_add_er_16(); + std::string d68000_add_er_32(); + std::string d68000_add_re_8(); + std::string d68000_add_re_16(); + std::string d68000_add_re_32(); + std::string d68000_adda_16(); + std::string d68000_adda_32(); + std::string d68000_addi_8(); + std::string d68000_addi_16(); + std::string d68000_addi_32(); + std::string d68000_addq_8(); + std::string d68000_addq_16(); + std::string d68000_addq_32(); + std::string d68000_addx_rr_8(); + std::string d68000_addx_rr_16(); + std::string d68000_addx_rr_32(); + std::string d68000_addx_mm_8(); + std::string d68000_addx_mm_16(); + std::string d68000_addx_mm_32(); + std::string d68000_and_er_8(); + std::string d68000_and_er_16(); + std::string d68000_and_er_32(); + std::string d68000_and_re_8(); + std::string d68000_and_re_16(); + std::string d68000_and_re_32(); + std::string d68000_andi_8(); + std::string d68000_andi_16(); + std::string d68000_andi_32(); + std::string d68000_andi_to_ccr(); + std::string d68000_andi_to_sr(); + std::string d68000_asr_s_8(); + std::string d68000_asr_s_16(); + std::string d68000_asr_s_32(); + std::string d68000_asr_r_8(); + std::string d68000_asr_r_16(); + std::string d68000_asr_r_32(); + std::string d68000_asr_ea(); + std::string d68000_asl_s_8(); + std::string d68000_asl_s_16(); + std::string d68000_asl_s_32(); + std::string d68000_asl_r_8(); + std::string d68000_asl_r_16(); + std::string d68000_asl_r_32(); + std::string d68000_asl_ea(); + std::string d68000_bcc_8(); + std::string d68000_bcc_16(); + std::string d68020_bcc_32(); + std::string d68000_bchg_r(); + std::string d68000_bchg_s(); + std::string d68000_bclr_r(); + std::string d68000_bclr_s(); + std::string d68010_bkpt(); + std::string d68020_bfchg(); + std::string d68020_bfclr(); + std::string d68020_bfexts(); + std::string d68020_bfextu(); + std::string d68020_bfffo(); + std::string d68020_bfins(); + std::string d68020_bfset(); + std::string d68020_bftst(); + std::string d68000_bra_8(); + std::string d68000_bra_16(); + std::string d68020_bra_32(); + std::string d68000_bset_r(); + std::string d68000_bset_s(); + std::string d68000_bsr_8(); + std::string d68000_bsr_16(); + std::string d68020_bsr_32(); + std::string d68000_btst_r(); + std::string d68000_btst_s(); + std::string d68020_callm(); + std::string d68020_cas_8(); + std::string d68020_cas_16(); + std::string d68020_cas_32(); + std::string d68020_cas2_16(); + std::string d68020_cas2_32(); + std::string d68000_chk_16(); + std::string d68020_chk_32(); + std::string d68020_chk2_cmp2_8(); + std::string d68020_chk2_cmp2_16(); + std::string d68020_chk2_cmp2_32(); + std::string d68040_cinv(); + std::string d68000_clr_8(); + std::string d68000_clr_16(); + std::string d68000_clr_32(); + std::string d68000_cmp_8(); + std::string d68000_cmp_16(); + std::string d68000_cmp_32(); + std::string d68000_cmpa_16(); + std::string d68000_cmpa_32(); + std::string d68000_cmpi_8(); + std::string d68020_cmpi_pcdi_8(); + std::string d68020_cmpi_pcix_8(); + std::string d68000_cmpi_16(); + std::string d68020_cmpi_pcdi_16(); + std::string d68020_cmpi_pcix_16(); + std::string d68000_cmpi_32(); + std::string d68020_cmpi_pcdi_32(); + std::string d68020_cmpi_pcix_32(); + std::string d68000_cmpm_8(); + std::string d68000_cmpm_16(); + std::string d68000_cmpm_32(); + std::string d68020_cpbcc_16(); + std::string d68020_cpbcc_32(); + std::string d68020_cpdbcc(); + std::string d68020_cpgen(); + std::string d68020_cprestore(); + std::string d68020_cpsave(); + std::string d68020_cpscc(); + std::string d68020_cptrapcc_0(); + std::string d68020_cptrapcc_16(); + std::string d68020_cptrapcc_32(); + std::string d68040_cpush(); + std::string d68000_dbra(); + std::string d68000_dbcc(); + std::string d68000_divs(); + std::string d68000_divu(); + std::string d68020_divl(); + std::string d68000_eor_8(); + std::string d68000_eor_16(); + std::string d68000_eor_32(); + std::string d68000_eori_8(); + std::string d68000_eori_16(); + std::string d68000_eori_32(); + std::string d68000_eori_to_ccr(); + std::string d68000_eori_to_sr(); + std::string d68000_exg_dd(); + std::string d68000_exg_aa(); + std::string d68000_exg_da(); + std::string d68000_ext_16(); + std::string d68000_ext_32(); + std::string d68020_extb_32(); + std::string d68881_ftrap(); + std::string d68040_fpu(); + std::string d68000_jmp(); + std::string d68000_jsr(); + std::string d68000_lea(); + std::string d68000_link_16(); + std::string d68020_link_32(); + std::string d68000_lsr_s_8(); + std::string d68000_lsr_s_16(); + std::string d68000_lsr_s_32(); + std::string d68000_lsr_r_8(); + std::string d68000_lsr_r_16(); + std::string d68000_lsr_r_32(); + std::string d68000_lsr_ea(); + std::string d68000_lsl_s_8(); + std::string d68000_lsl_s_16(); + std::string d68000_lsl_s_32(); + std::string d68000_lsl_r_8(); + std::string d68000_lsl_r_16(); + std::string d68000_lsl_r_32(); + std::string d68000_lsl_ea(); + std::string d68000_move_8(); + std::string d68000_move_16(); + std::string d68000_move_32(); + std::string d68000_movea_16(); + std::string d68000_movea_32(); + std::string d68000_move_to_ccr(); + std::string d68010_move_fr_ccr(); + std::string d68000_move_fr_sr(); + std::string d68000_move_to_sr(); + std::string d68000_move_fr_usp(); + std::string d68000_move_to_usp(); + std::string d68010_movec(); + std::string d68000_movem_pd_16(); + std::string d68000_movem_pd_32(); + std::string d68000_movem_er_16(); + std::string d68000_movem_er_32(); + std::string d68000_movem_re_16(); + std::string d68000_movem_re_32(); + std::string d68000_movep_re_16(); + std::string d68000_movep_re_32(); + std::string d68000_movep_er_16(); + std::string d68000_movep_er_32(); + std::string d68010_moves_8(); + std::string d68010_moves_16(); + std::string d68010_moves_32(); + std::string d68000_moveq(); + std::string d68040_move16_pi_pi(); + std::string d68040_move16_pi_al(); + std::string d68040_move16_al_pi(); + std::string d68040_move16_ai_al(); + std::string d68040_move16_al_ai(); + std::string d68000_muls(); + std::string d68000_mulu(); + std::string d68020_mull(); + std::string d68000_nbcd(); + std::string d68000_neg_8(); + std::string d68000_neg_16(); + std::string d68000_neg_32(); + std::string d68000_negx_8(); + std::string d68000_negx_16(); + std::string d68000_negx_32(); + std::string d68000_nop(); + std::string d68000_not_8(); + std::string d68000_not_16(); + std::string d68000_not_32(); + std::string d68000_or_er_8(); + std::string d68000_or_er_16(); + std::string d68000_or_er_32(); + std::string d68000_or_re_8(); + std::string d68000_or_re_16(); + std::string d68000_or_re_32(); + std::string d68000_ori_8(); + std::string d68000_ori_16(); + std::string d68000_ori_32(); + std::string d68000_ori_to_ccr(); + std::string d68000_ori_to_sr(); + std::string d68020_pack_rr(); + std::string d68020_pack_mm(); + std::string d68000_pea(); + std::string d68040_pflush(); + std::string d68000_reset(); + std::string d68000_ror_s_8(); + std::string d68000_ror_s_16(); + std::string d68000_ror_s_32(); + std::string d68000_ror_r_8(); + std::string d68000_ror_r_16(); + std::string d68000_ror_r_32(); + std::string d68000_ror_ea(); + std::string d68000_rol_s_8(); + std::string d68000_rol_s_16(); + std::string d68000_rol_s_32(); + std::string d68000_rol_r_8(); + std::string d68000_rol_r_16(); + std::string d68000_rol_r_32(); + std::string d68000_rol_ea(); + std::string d68000_roxr_s_8(); + std::string d68000_roxr_s_16(); + std::string d68000_roxr_s_32(); + std::string d68000_roxr_r_8(); + std::string d68000_roxr_r_16(); + std::string d68000_roxr_r_32(); + std::string d68000_roxr_ea(); + std::string d68000_roxl_s_8(); + std::string d68000_roxl_s_16(); + std::string d68000_roxl_s_32(); + std::string d68000_roxl_r_8(); + std::string d68000_roxl_r_16(); + std::string d68000_roxl_r_32(); + std::string d68000_roxl_ea(); + std::string d68010_rtd(); + std::string d68000_rte(); + std::string d68020_rtm(); + std::string d68000_rtr(); + std::string d68000_rts(); + std::string d68000_sbcd_rr(); + std::string d68000_sbcd_mm(); + std::string d68000_scc(); + std::string d68000_stop(); + std::string d68000_sub_er_8(); + std::string d68000_sub_er_16(); + std::string d68000_sub_er_32(); + std::string d68000_sub_re_8(); + std::string d68000_sub_re_16(); + std::string d68000_sub_re_32(); + std::string d68000_suba_16(); + std::string d68000_suba_32(); + std::string d68000_subi_8(); + std::string d68000_subi_16(); + std::string d68000_subi_32(); + std::string d68000_subq_8(); + std::string d68000_subq_16(); + std::string d68000_subq_32(); + std::string d68000_subx_rr_8(); + std::string d68000_subx_rr_16(); + std::string d68000_subx_rr_32(); + std::string d68000_subx_mm_8(); + std::string d68000_subx_mm_16(); + std::string d68000_subx_mm_32(); + std::string d68000_swap(); + std::string d68000_tas(); + std::string d68000_trap(); + std::string d68020_trapcc_0(); + std::string d68020_trapcc_16(); + std::string d68020_trapcc_32(); + std::string d68000_trapv(); + std::string d68000_tst_8(); + std::string d68020_tst_pcdi_8(); + std::string d68020_tst_pcix_8(); + std::string d68020_tst_i_8(); + std::string d68000_tst_16(); + std::string d68020_tst_a_16(); + std::string d68020_tst_pcdi_16(); + std::string d68020_tst_pcix_16(); + std::string d68020_tst_i_16(); + std::string d68000_tst_32(); + std::string d68020_tst_a_32(); + std::string d68020_tst_pcdi_32(); + std::string d68020_tst_pcix_32(); + std::string d68020_tst_i_32(); + std::string d68000_unlk(); + std::string d68020_unpk_rr(); + std::string d68020_unpk_mm(); + std::string d68851_p000(); + std::string d68851_pbcc16(); + std::string d68851_pbcc32(); + std::string d68851_pdbcc(); + std::string d68851_p001(); + std::string d68040_fbcc_16(); + std::string d68040_fbcc_32(); + + static bool valid_ea(u32 opcode, u32 mask); + static bool compare_nof_true_bits(const opcode_struct *aptr, const opcode_struct *bptr); + void build_opcode_table(); + + + /* used by ops like asr, ror, addq, etc */ + static const u32 m_3bit_qdata_table[8]; + static const u32 m_5bit_data_table[32]; + + static const char *const m_cc[16]; + static const char *const m_cpcc[64]; + static const char *const m_mmuregs[8]; + static const char *const m_mmucond[16]; + + static const opcode_struct m_opcode_info[]; + opcode_handler m_instruction_table[0x10000]; + + const data_buffer *m_buffer; + u32 m_cpu_type, m_cpu_pc, m_flags; + u16 m_cpu_ir; +}; + + +#endif diff --git a/src/devices/cpu/m6805/6805dasm.cpp b/src/devices/cpu/m6805/6805dasm.cpp index e8cca5bf4e3..3f6b2fbb14b 100644 --- a/src/devices/cpu/m6805/6805dasm.cpp +++ b/src/devices/cpu/m6805/6805dasm.cpp @@ -5,56 +5,21 @@ * * Note: this is not the good and proper way to disassemble anything, but it works * + * Secondary note: it actually stopped being not nice a while ago + * * I'm afraid to put my name on it, but I feel obligated: * This code written by Aaron Giles (agiles@sirius.com) for the MAME project * */ #include "emu.h" -#include "m6805.h" - -#include "debugger.h" - -namespace { - -enum class md { - INH, // inherent - BTR, // bit test and relative - BIT, // bit set/clear - REL, // relative - IMM, // immediate - DIR, // direct address - EXT, // extended address - IDX, // indexed - IX1, // indexed + byte offset - IX2 // indexed + word offset -}; - -enum class lvl { - HMOS, - CMOS, - HC -}; - -enum class op_names { - adca, adda, anda, asl, asla, aslx, asr, asra, - asrx, bcc, bclr, bcs, beq, bhcc, bhcs, bhi, - bih, bil, bit, bls, bmc, bmi, bms, bne, - bpl, bra, brclr, brn, brset, bset, bsr, clc, - cli, clr, clra, clrx, cmpa, com, coma, comx, - cpx, dec, deca, decx, eora, ill, inc, inca, - incx, jmp, jsr, lda, ldx, lsr, lsra, lsrx, - mul, neg, nega, negx, nop, ora, rol, rola, - rolx, ror, rora, rorx, rsp, rti, rts, sbca, - sec, sei, sta, stop, stx, suba, swi, tax, - tst, tsta, tstx, txa, wait -}; +#include "6805dasm.h" #define OP(name, mode) { op_names::name, #name, md::mode, lvl::HMOS } #define OPC(name, mode) { op_names::name, #name, md::mode, lvl::CMOS } #define OPHC(name, mode) { op_names::name, #name, md::mode, lvl::HC } #define ILLEGAL { op_names::ill, nullptr, md::INH, lvl::HMOS } -struct { op_names op; char const *name; md mode; lvl level; } const disasm[0x100] = { +const m6805_base_disassembler::info m6805_base_disassembler::disasm[0x100] = { OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), // 00 OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), OP (brset,BTR), OP (brclr,BTR), @@ -121,43 +86,35 @@ struct { op_names op; char const *name; md mode; lvl level; } const disasm[0x100 OP (jmp, IDX), OP (jsr, IDX), OP (ldx, IDX), OP (stx, IDX) }; +m6805_base_disassembler::m6805_base_disassembler(lvl level, std::pair<u16, char const *> const symbols[], std::size_t symbol_count) : m_level(level), m_symbols(symbols), m_symbol_count(symbol_count) +{ +} + +u32 m6805_base_disassembler::opcode_alignment() const +{ + return 1; +} -template <typename T> -void format_address( - std::ostream& stream, - T address, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +template <typename T> std::string m6805_base_disassembler::address(T offset) const { - auto const symbol= std::lower_bound( - &symbols[0], - &symbols[symbol_count], - address, - [] (auto const &sym, u16 addr) { return sym.first < addr; }); - if ((symbol_count != (symbol - symbols)) && (symbol->first == address)) - stream << symbol->second; + auto const symbol = std::lower_bound(m_symbols, + m_symbols + m_symbol_count, + offset, + [] (auto const &sym, u16 addr) { return sym.first < addr; }); + if ((m_symbol_count != (symbol - m_symbols)) && (symbol->first == offset)) + return symbol->second; else - util::stream_format(stream, "$%0*X", 2 * sizeof(T), address); + return util::string_format("$%0*X", 2 * sizeof(T), offset); } - -offs_t disassemble( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - lvl level, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +offs_t m6805_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - u8 const code = oprom[0]; + u8 const code = opcodes.r8(pc); - if (!disasm[code].name || (disasm[code].level > level)) + if (!disasm[code].name || (disasm[code].level > m_level)) { util::stream_format(stream, "%-6s$%02X", "fcb", code); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } else { @@ -166,11 +123,11 @@ offs_t disassemble( { case op_names::bsr: case op_names::jsr: - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case op_names::rts: case op_names::rti: - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; default: flags = 0; @@ -178,55 +135,46 @@ offs_t disassemble( util::stream_format(stream, "%-6s", disasm[code].name); - int bit; - u16 ea; switch (disasm[code].mode) { case md::INH: // inherent - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; case md::BTR: // bit test and relative branch - bit = (code >> 1) & 7; - util::stream_format(stream, "%d,", bit); - format_address(stream, opram[1], symbols, symbol_count); - util::stream_format(stream, ",$%03X", pc + 3 + s8(opram[2])); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "%d, %s, $%03X", (code >> 1) & 7, address(params.r8(pc+1)), pc + 3 + s8(params.r8(pc+2))); + return 3 | flags | SUPPORTED; case md::BIT: // bit test - bit = (code >> 1) & 7; - util::stream_format(stream, "%d,", bit); - format_address(stream, opram[1], symbols, symbol_count); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "%d, %s", (code >> 1) & 7, address(params.r8(pc+1))); + return 2 | flags | SUPPORTED; case md::REL: // relative - util::stream_format(stream, "$%03X", pc + 2 + s8(opram[1])); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "$%03X", pc + 2 + s8(params.r8(pc+1))); + return 2 | flags | SUPPORTED; case md::IMM: // immediate - util::stream_format(stream, "#$%02X", opram[1]); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "#$%02X", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case md::DIR: // direct (zero page address) - format_address(stream, opram[1], symbols, symbol_count); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "%s", address(params.r8(pc+1))); + return 2 | flags | SUPPORTED; case md::EXT: // extended (16 bit address) - ea = (opram[1] << 8) + opram[2]; - format_address(stream, ea, symbols, symbol_count); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "%s", address(params.r16(pc+1))); + return 3 | flags | SUPPORTED; case md::IDX: // indexed util::stream_format(stream, "(x)"); - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; case md::IX1: // indexed + byte (zero page) - util::stream_format(stream, "(x+$%02X)", opram[1]); - return 2 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "(x+$%02X)", params.r8(pc+1)); + return 2 | flags | SUPPORTED; case md::IX2: // indexed + word (16 bit address) - ea = (opram[1] << 8) + opram[2]; - util::stream_format(stream, "(x+$%04X)", ea); - return 3 | flags | DASMFLAG_SUPPORTED; + util::stream_format(stream, "(x+$%04X)", params.r16(pc+1)); + return 3 | flags | SUPPORTED; } // if we fall off the switch statement something is very wrong @@ -234,48 +182,22 @@ offs_t disassemble( } } -} // anonymous namespace - +m6805_disassembler::m6805_disassembler() : m6805_base_disassembler(lvl::HMOS) +{ +} -offs_t CPU_DISASSEMBLE_NAME(m6805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +m6805_disassembler::m6805_disassembler(std::pair<u16, char const *> const symbols[], std::size_t symbol_count) : m6805_base_disassembler(lvl::HMOS, symbols, symbol_count) { - return disassemble(device, stream, pc, oprom, opram, options, lvl::HMOS, symbols, symbol_count); } -offs_t CPU_DISASSEMBLE_NAME(m146805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +m146805_disassembler::m146805_disassembler() : m6805_base_disassembler(lvl::CMOS) { - return disassemble(device, stream, pc, oprom, opram, options, lvl::CMOS, symbols, symbol_count); } -offs_t CPU_DISASSEMBLE_NAME(m68hc05)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count) +m68hc05_disassembler::m68hc05_disassembler() : m6805_base_disassembler(lvl::HC) { - return disassemble(device, stream, pc, oprom, opram, options, lvl::HC, symbols, symbol_count); } -CPU_DISASSEMBLE(m6805) { return CPU_DISASSEMBLE_NAME(m6805) (device, stream, pc, oprom, opram, options, nullptr, 0); } -CPU_DISASSEMBLE(m146805) { return CPU_DISASSEMBLE_NAME(m146805)(device, stream, pc, oprom, opram, options, nullptr, 0); } -CPU_DISASSEMBLE(m68hc05) { return CPU_DISASSEMBLE_NAME(m68hc05)(device, stream, pc, oprom, opram, options, nullptr, 0); } +m68hc05_disassembler::m68hc05_disassembler(std::pair<u16, char const *> const symbols[], std::size_t symbol_count) : m6805_base_disassembler(lvl::HC, symbols, symbol_count) +{ +} diff --git a/src/devices/cpu/m6805/6805dasm.h b/src/devices/cpu/m6805/6805dasm.h new file mode 100644 index 00000000000..95a03afb61c --- /dev/null +++ b/src/devices/cpu/m6805/6805dasm.h @@ -0,0 +1,100 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, Aaron Giles, Vas Crabb + +// 6805 disassembler interface + +#ifndef MAME_CPU_M6805_6805DASM_H +#define MAME_CPU_M6805_6805DASM_H + +#pragma once + +class m6805_base_disassembler : public util::disasm_interface +{ +public: + enum class lvl { + HMOS, + CMOS, + HC + }; + + m6805_base_disassembler(lvl level, std::pair<u16, char const *> const symbols[], std::size_t symbol_count); + + m6805_base_disassembler(lvl level) : m6805_base_disassembler(level, nullptr, 0) {} + + virtual ~m6805_base_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum class md { + INH, // inherent + BTR, // bit test and relative + BIT, // bit set/clear + REL, // relative + IMM, // immediate + DIR, // direct address + EXT, // extended address + IDX, // indexed + IX1, // indexed + byte offset + IX2 // indexed + word offset + }; + + enum class op_names { + adca, adda, anda, asl, asla, aslx, asr, asra, + asrx, bcc, bclr, bcs, beq, bhcc, bhcs, bhi, + bih, bil, bit, bls, bmc, bmi, bms, bne, + bpl, bra, brclr, brn, brset, bset, bsr, clc, + cli, clr, clra, clrx, cmpa, com, coma, comx, + cpx, dec, deca, decx, eora, ill, inc, inca, + incx, jmp, jsr, lda, ldx, lsr, lsra, lsrx, + mul, neg, nega, negx, nop, ora, rol, rola, + rolx, ror, rora, rorx, rsp, rti, rts, sbca, + sec, sei, sta, stop, stx, suba, swi, tax, + tst, tsta, tstx, txa, wait + }; + + struct info { + op_names op; + char const *name; + md mode; + lvl level; + }; + + static const info disasm[0x100]; + + lvl m_level; + std::pair<u16, char const *> const *m_symbols; + std::size_t m_symbol_count; + + template <typename T> std::string address(T offset) const; +}; + +class m6805_disassembler : public m6805_base_disassembler +{ +public: + m6805_disassembler(); + m6805_disassembler(std::pair<u16, char const *> const symbols[], std::size_t symbol_count); + template<size_t N> m6805_disassembler(std::pair<u16, char const *> const (&symbols)[N]) : m6805_disassembler(symbols, N) {} + + virtual ~m6805_disassembler() = default; +}; + +class m146805_disassembler : public m6805_base_disassembler +{ +public: + m146805_disassembler(); + virtual ~m146805_disassembler() = default; +}; + +class m68hc05_disassembler : public m6805_base_disassembler +{ +public: + m68hc05_disassembler(); + m68hc05_disassembler(std::pair<u16, char const *> const symbols[], std::size_t symbol_count); + template<size_t N> m68hc05_disassembler(std::pair<u16, char const *> const (&symbols)[N]) : m68hc05_disassembler(symbols, N) {} + virtual ~m68hc05_disassembler() = default; +}; + + +#endif diff --git a/src/devices/cpu/m6805/m6805.cpp b/src/devices/cpu/m6805/m6805.cpp index eb80246e368..0b8a9b42eb1 100644 --- a/src/devices/cpu/m6805/m6805.cpp +++ b/src/devices/cpu/m6805/m6805.cpp @@ -35,6 +35,7 @@ #include "emu.h" #include "m6805.h" #include "m6805defs.h" +#include "6805dasm.h" #include "debugger.h" @@ -262,7 +263,7 @@ m6805_base_device::m6805_base_device( void m6805_base_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // set our instruction counter m_icountptr = &m_icount; @@ -303,9 +304,6 @@ void m6805_base_device::device_reset() m_nmi_state = 0; - m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); - /* IRQ disabled */ SEI; @@ -409,35 +407,13 @@ void m6805_base_device::interrupt() //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t m6805_base_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t m6805_base_device::disasm_max_opcode_bytes() const -{ - return 3; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t m6805_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6805_base_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options); + return new m6805_disassembler; } diff --git a/src/devices/cpu/m6805/m6805.h b/src/devices/cpu/m6805/m6805.h index fb8fc97dee3..643b1617991 100644 --- a/src/devices/cpu/m6805/m6805.h +++ b/src/devices/cpu/m6805/m6805.h @@ -119,9 +119,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -279,7 +277,7 @@ protected: // address spaces address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; }; @@ -362,8 +360,4 @@ protected: #define HD63705_INT_ADCONV 0x07 #define HD63705_INT_NMI 0x08 -CPU_DISASSEMBLE( m6805 ); -CPU_DISASSEMBLE( m146805 ); -CPU_DISASSEMBLE( m68hc05 ); - #endif // MAME_CPU_M6805_M6805_H diff --git a/src/devices/cpu/m6805/m6805defs.h b/src/devices/cpu/m6805/m6805defs.h index 670beda2683..1e5d8c6e7fb 100644 --- a/src/devices/cpu/m6805/m6805defs.h +++ b/src/devices/cpu/m6805/m6805defs.h @@ -116,73 +116,4 @@ inline void m6805_base_device::skipbyte() { rdop_arg(PC++); } /* Macros for branch instructions */ #define BRANCH(f) do { u8 t; immbyte(t); if (bool(f) == bool(C)) PC += SIGNED(t); } while (false) -offs_t CPU_DISASSEMBLE_NAME(m146805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count); - -offs_t CPU_DISASSEMBLE_NAME(m68hc05)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count); - -offs_t CPU_DISASSEMBLE_NAME(m6805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const symbols[], - std::size_t symbol_count); - -template <size_t N> -inline offs_t CPU_DISASSEMBLE_NAME(m6805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const (&symbols)[N]) -{ - return CPU_DISASSEMBLE_NAME(m6805)(device, stream, pc, oprom, opram, options, symbols, N); -} - -template <size_t N> -inline offs_t CPU_DISASSEMBLE_NAME(m146805)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const (&symbols)[N]) -{ - return CPU_DISASSEMBLE_NAME(m146805)(device, stream, pc, oprom, opram, options, symbols, N); -} - -template <size_t N> -inline offs_t CPU_DISASSEMBLE_NAME(m68hc05)( - cpu_device *device, - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - int options, - std::pair<u16, char const *> const (&symbols)[N]) -{ - return CPU_DISASSEMBLE_NAME(m68hc05)(device, stream, pc, oprom, opram, options, symbols, N); -} - #endif // MAME_CPU_M6805_M6805DEFS_H diff --git a/src/devices/cpu/m6805/m68705.cpp b/src/devices/cpu/m6805/m68705.cpp index ba4dae3a39f..08e40e41d9a 100644 --- a/src/devices/cpu/m6805/m68705.cpp +++ b/src/devices/cpu/m6805/m68705.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "m68705.h" #include "m6805defs.h" +#include "6805dasm.h" /**************************************************************************** * Configurable logging @@ -697,14 +698,9 @@ void m68705p_device::device_start() state_add(M68705_MOR, "MOR", get_user_rom()[0x0784]).mask(0xff); } -offs_t m68705p_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) +util::disasm_interface *m68705p_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options, m68705p_syms); + return new m6805_disassembler(m68705p_syms); } @@ -776,14 +772,9 @@ void m68705u_device::device_start() // TODO: MISC register } -offs_t m68705u_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) +util::disasm_interface *m68705u_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options, m68705u_syms); + return new m6805_disassembler(m68705u_syms); } @@ -834,17 +825,11 @@ void m68705r_device::device_start() // TODO: ADC } -offs_t m68705r_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) +util::disasm_interface *m68705r_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m6805)(this, stream, pc, oprom, opram, options, m68705r_syms); + return new m6805_disassembler(m68705r_syms); } - /**************************************************************************** * M68705P3 device ****************************************************************************/ diff --git a/src/devices/cpu/m6805/m68705.h b/src/devices/cpu/m6805/m68705.h index aaa2f88d693..08701917b47 100644 --- a/src/devices/cpu/m6805/m68705.h +++ b/src/devices/cpu/m6805/m68705.h @@ -202,12 +202,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -240,12 +235,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -268,12 +258,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const uint8_t *oprom, - const uint8_t *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; diff --git a/src/devices/cpu/m6805/m68hc05.cpp b/src/devices/cpu/m6805/m68hc05.cpp index 90575e98ab2..24580270a9c 100644 --- a/src/devices/cpu/m6805/m68hc05.cpp +++ b/src/devices/cpu/m6805/m68hc05.cpp @@ -18,6 +18,7 @@ certain value. #include "emu.h" #include "m68hc05.h" #include "m6805defs.h" +#include "6805dasm.h" /**************************************************************************** @@ -541,15 +542,9 @@ u64 m68hc05_device::execute_cycles_to_clocks(u64 cycles) const return cycles * 2; } - -offs_t m68hc05_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) +util::disasm_interface *m68hc05_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options); + return new m68hc05_disassembler; } @@ -777,14 +772,9 @@ void m68hc05c4_device::device_start() } -offs_t m68hc05c4_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) +util::disasm_interface *m68hc05c4_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options, m68hc05c4_syms); + return new m68hc05_disassembler(m68hc05c4_syms); } @@ -845,15 +835,10 @@ void m68hc05c8_device::device_start() } -offs_t m68hc05c8_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) +util::disasm_interface *m68hc05c8_device::create_disassembler() { // same I/O registers as MC68HC05C4 - return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options, m68hc05c4_syms); + return new m68hc05_disassembler(m68hc05c4_syms); } @@ -937,12 +922,7 @@ void m68hc705c8a_device::device_reset() } -offs_t m68hc705c8a_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) +util::disasm_interface *m68hc705c8a_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(m68hc05)(this, stream, pc, oprom, opram, options, m68hc705c8a_syms); + return new m68hc05_disassembler(m68hc705c8a_syms); } diff --git a/src/devices/cpu/m6805/m68hc05.h b/src/devices/cpu/m6805/m68hc05.h index db61afc8b60..355a675d803 100644 --- a/src/devices/cpu/m6805/m68hc05.h +++ b/src/devices/cpu/m6805/m68hc05.h @@ -138,12 +138,7 @@ protected: virtual u64 execute_clocks_to_cycles(u64 clocks) const override; virtual u64 execute_cycles_to_clocks(u64 cycles) const override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const uint8_t *opram, - u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void interrupt() override; virtual bool test_il() override; @@ -229,12 +224,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -250,12 +240,7 @@ protected: virtual void device_start() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -274,12 +259,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - const u8 *oprom, - const u8 *opram, - u32 options) override; + virtual util::disasm_interface *create_disassembler() override; }; diff --git a/src/devices/cpu/m6809/6x09dasm.cpp b/src/devices/cpu/m6809/6x09dasm.cpp index 1b07fb3c92b..3df936df070 100644 --- a/src/devices/cpu/m6809/6x09dasm.cpp +++ b/src/devices/cpu/m6809/6x09dasm.cpp @@ -27,118 +27,41 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" +#include "6x09dasm.h" -enum m6x09_addressing_mode -{ - INH, // Inherent - PSHS, PSHU, // Push - PULS, PULU, // Pull - DIR, // Direct - DIR_IM, // Direct in memory (6309 only) - IND, // Indexed - REL, // Relative (8 bit) - LREL, // Long relative (16 bit) - EXT, // Extended - IMM, // Immediate - IMM_RR, // Register-to-register - IMM_BW, // Bitwise operations (6309 only) - IMM_TFM, // Transfer from memory (6309 only) - PG1, // Switch to page 1 opcodes - PG2 // Switch to page 2 opcodes -}; -// General, or 6309 only? -enum m6x09_instruction_level -{ - M6x09_GENERAL, - HD6309_EXCLUSIVE -}; +const char *const m6x09_base_disassembler::m6x09_regs[5] = { "X", "Y", "U", "S", "PC" }; -// Opcode structure -class opcodeinfo -{ -public: - constexpr opcodeinfo(uint16_t opcode, uint8_t length, const char *name, m6x09_addressing_mode mode, m6x09_instruction_level level, unsigned flags = 0) - : m_opcode(opcode), m_length(length), m_mode(mode), m_level(level), m_flags(flags), m_name(name) - { - } +const char *const m6x09_base_disassembler::m6x09_btwregs[5] = { "CC", "A", "B", "inv" }; - uint16_t opcode() const { return m_opcode; } - uint8_t length() const { return m_length; } - m6x09_addressing_mode mode() const { return m_mode; } - m6x09_instruction_level level() const { return m_level; } - unsigned flags() const { return m_flags; } - const char *name() const { return m_name; } - -private: - uint16_t m_opcode; // 8-bit opcode value - uint8_t m_length; // Opcode length in bytes - m6x09_addressing_mode m_mode : 6; // Addressing mode - m6x09_instruction_level m_level : 2; // General, or 6309 only? - unsigned m_flags; // Disassembly flags - const char * m_name; // Opcode name -}; -static const char *const m6x09_regs[5] = { "X", "Y", "U", "S", "PC" }; - -static const char *const m6x09_btwregs[5] = { "CC", "A", "B", "inv" }; - -static const char *const hd6309_tfmregs[16] = { - "D", "X", "Y", "U", "S", "inv", "inv", "inv", +const char *const m6x09_base_disassembler::hd6309_tfmregs[16] = { + "D", "X", "Y", "U", "S", "inv", "inv", "inv", "inv", "inv", "inv", "inv", "inv", "inv", "inv", "inv" }; -static const char *const tfm_s[] = { "%s+,%s+", "%s-,%s-", "%s+,%s", "%s,%s+" }; +const char *const m6x09_base_disassembler::tfm_s[] = { "%s+,%s+", "%s-,%s-", "%s+,%s", "%s,%s+" }; //************************************************************************** // BASE CLASS //************************************************************************** -// ======================> m6x09_disassembler_base - -// base class for M6809/HD6309/Konami disassemblers -namespace +u32 m6x09_base_disassembler::opcode_alignment() const { - class m6x09_disassembler_base - { - public: - m6x09_disassembler_base(const opcodeinfo *opcodes, size_t opcode_count, m6x09_instruction_level level) - : m_opcodes(opcodes, opcode_count), m_level(level) - { - } - - offs_t disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram); - - protected: - virtual void indirect(std::ostream &stream, uint8_t pb, const uint8_t *opram, int &p) = 0; - virtual void register_register(std::ostream &stream, uint8_t pb) = 0; - - private: - util::contiguous_sequence_wrapper<const opcodeinfo> m_opcodes; - m6x09_instruction_level m_level; - - const opcodeinfo *fetch_opcode(const uint8_t *oprom, int &p); - - void assert_hd6309_exclusive() - { - if (m_level < HD6309_EXCLUSIVE) - throw false; - } - }; + return 1; } //------------------------------------------------- // fetch_opcode //------------------------------------------------- -const opcodeinfo *m6x09_disassembler_base::fetch_opcode(const uint8_t *oprom, int &p) +const m6x09_base_disassembler::opcodeinfo *m6x09_base_disassembler::fetch_opcode(const data_buffer &opcodes, offs_t &p) { uint16_t page = 0; const opcodeinfo *op = nullptr; while(!op) { // retrieve the opcode - uint16_t opcode = page | oprom[p++]; + uint16_t opcode = page | opcodes.r8(p++); // perform the lookup auto iter = std::find_if( @@ -179,29 +102,28 @@ const opcodeinfo *m6x09_disassembler_base::fetch_opcode(const uint8_t *oprom, in // disassemble - core of the disassembler //------------------------------------------------- -offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram) +offs_t m6x09_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint8_t pb; unsigned int ea; int offset; - int p = 0; + offs_t p = pc; // look up the opcode - const opcodeinfo *op = fetch_opcode(oprom, p); + const opcodeinfo *op = fetch_opcode(opcodes, p); if (!op) { stream << "Illegal Opcode"; - return p | DASMFLAG_SUPPORTED; + return (p - pc) | SUPPORTED; } // how many operands do we have? - int numoperands = (p == 1) + int numoperands = (p - pc == 1) ? op->length() - 1 : op->length() - 2; - const uint8_t *operandarray = &opram[p]; + offs_t ppc = p; p += numoperands; - pc += p; // output the base instruction name util::stream_format(stream, "%-6s", op->name()); @@ -214,7 +136,7 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con case PSHS: case PSHU: - pb = operandarray[0]; + pb = params.r8(ppc); if (pb & 0x80) util::stream_format(stream, "PC"); if (pb & 0x40) @@ -235,7 +157,7 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con case PULS: case PULU: - pb = operandarray[0]; + pb = params.r8(ppc); if (pb & 0x01) util::stream_format(stream, "CC"); if (pb & 0x02) @@ -255,23 +177,23 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con break; case DIR: - ea = operandarray[0]; + ea = params.r8(ppc); util::stream_format(stream, "$%02X", ea); break; case DIR_IM: assert_hd6309_exclusive(); - util::stream_format(stream, "#$%02X;", operandarray[0]); - util::stream_format(stream, "$%02X", operandarray[1]); + util::stream_format(stream, "#$%02X;", params.r8(ppc)); + util::stream_format(stream, "$%02X", params.r8(ppc + 1)); break; case REL: - offset = (int8_t)operandarray[0]; + offset = (int8_t)params.r8(ppc); util::stream_format(stream, "$%04X", (pc + offset) & 0xffff); break; case LREL: - offset = (int16_t)((operandarray[0] << 8) + operandarray[1]); + offset = (int16_t)params.r16(ppc); util::stream_format(stream, "$%04X", (pc + offset) & 0xffff); break; @@ -279,13 +201,13 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con if (numoperands == 3) { assert_hd6309_exclusive(); - pb = operandarray[0]; - ea = (operandarray[1] << 8) + operandarray[2]; + pb = params.r8(ppc); + ea = params.r16(ppc+1); util::stream_format(stream, "#$%02X,$%04X", pb, ea); } else if (numoperands == 2) { - ea = (operandarray[0] << 8) + operandarray[1]; + ea = params.r16(ppc); util::stream_format(stream, "$%04X", ea); } break; @@ -294,52 +216,52 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con if (numoperands == 2) { assert_hd6309_exclusive(); - util::stream_format(stream, "#$%02X;", operandarray[0]); - pb = operandarray[1]; + util::stream_format(stream, "#$%02X;", params.r8(ppc)); + pb = params.r8(ppc+1); } else { - pb = operandarray[0]; + pb = params.r8(ppc); } - indirect(stream, pb, opram, p); + indirect(stream, pb, params, p); break; case IMM: if (numoperands == 4) { - ea = (operandarray[0] << 24) + (operandarray[1] << 16) + (operandarray[2] << 8) + operandarray[3]; + ea = params.r32(ppc); util::stream_format(stream, "#$%08X", ea); } else if (numoperands == 2) { - ea = (operandarray[0] << 8) + operandarray[1]; + ea = params.r16(ppc); util::stream_format(stream, "#$%04X", ea); } else if (numoperands == 1) { - ea = operandarray[0]; + ea = params.r8(ppc); util::stream_format(stream, "#$%02X", ea); } break; case IMM_RR: - pb = operandarray[0]; + pb = params.r8(ppc); register_register(stream, pb); break; case IMM_BW: - pb = operandarray[0]; + pb = params.r8(ppc); util::stream_format(stream, "%s,", m6x09_btwregs[((pb & 0xc0) >> 6)]); util::stream_format(stream, "%d,", (pb & 0x38) >> 3); util::stream_format(stream, "%d,", (pb & 0x07)); - util::stream_format(stream, "$%02X", operandarray[1]); + util::stream_format(stream, "$%02X", params.r8(ppc+1)); break; case IMM_TFM: - pb = operandarray[0]; + pb = params.r8(ppc); util::stream_format(stream, tfm_s[op->opcode() & 0x07], hd6309_tfmregs[(pb >> 4) & 0xf], hd6309_tfmregs[pb & 0xf]); break; @@ -347,7 +269,7 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con throw false; } - return p | op->flags() | DASMFLAG_SUPPORTED; + return (p - pc) | op->flags() | SUPPORTED; } @@ -355,7 +277,7 @@ offs_t m6x09_disassembler_base::disassemble(std::ostream &stream, offs_t pc, con // M6809/HD6309 disassembler //************************************************************************** -static const opcodeinfo m6x09_opcodes[] = +const m6x09_base_disassembler::opcodeinfo m6x09_disassembler::m6x09_opcodes[] = { // Page 0 opcodes (single byte) { 0x00, 2, "NEG", DIR, M6x09_GENERAL }, @@ -381,7 +303,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0x13, 1, "SYNC", INH, M6x09_GENERAL }, { 0x14, 1, "SEXW", INH, HD6309_EXCLUSIVE }, { 0x16, 3, "LBRA", LREL, M6x09_GENERAL }, - { 0x17, 3, "LBSR", LREL, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0x17, 3, "LBSR", LREL, M6x09_GENERAL, STEP_OVER }, { 0x19, 1, "DAA", INH, M6x09_GENERAL }, { 0x1A, 2, "ORCC", IMM, M6x09_GENERAL }, { 0x1C, 2, "ANDCC", IMM, M6x09_GENERAL }, @@ -491,7 +413,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0x8A, 2, "ORA", IMM, M6x09_GENERAL }, { 0x8B, 2, "ADDA", IMM, M6x09_GENERAL }, { 0x8C, 3, "CMPX", IMM, M6x09_GENERAL }, - { 0x8D, 2, "BSR", REL, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0x8D, 2, "BSR", REL, M6x09_GENERAL, STEP_OVER }, { 0x8E, 3, "LDX", IMM, M6x09_GENERAL }, { 0x90, 2, "SUBA", DIR, M6x09_GENERAL }, @@ -507,7 +429,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0x9A, 2, "ORA", DIR, M6x09_GENERAL }, { 0x9B, 2, "ADDA", DIR, M6x09_GENERAL }, { 0x9C, 2, "CMPX", DIR, M6x09_GENERAL }, - { 0x9D, 2, "JSR", DIR, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0x9D, 2, "JSR", DIR, M6x09_GENERAL, STEP_OVER }, { 0x9E, 2, "LDX", DIR, M6x09_GENERAL }, { 0x9F, 2, "STX", DIR, M6x09_GENERAL }, @@ -524,7 +446,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0xAA, 2, "ORA", IND, M6x09_GENERAL }, { 0xAB, 2, "ADDA", IND, M6x09_GENERAL }, { 0xAC, 2, "CMPX", IND, M6x09_GENERAL }, - { 0xAD, 2, "JSR", IND, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0xAD, 2, "JSR", IND, M6x09_GENERAL, STEP_OVER }, { 0xAE, 2, "LDX", IND, M6x09_GENERAL }, { 0xAF, 2, "STX", IND, M6x09_GENERAL }, @@ -541,7 +463,7 @@ static const opcodeinfo m6x09_opcodes[] = { 0xBA, 3, "ORA", EXT, M6x09_GENERAL }, { 0xBB, 3, "ADDA", EXT, M6x09_GENERAL }, { 0xBC, 3, "CMPX", EXT, M6x09_GENERAL }, - { 0xBD, 3, "JSR", EXT, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0xBD, 3, "JSR", EXT, M6x09_GENERAL, STEP_OVER }, { 0xBE, 3, "LDX", EXT, M6x09_GENERAL }, { 0xBF, 3, "STX", EXT, M6x09_GENERAL }, @@ -875,33 +797,17 @@ static const opcodeinfo m6x09_opcodes[] = // ======================> m6x09_disassembler -// M6809/HD6309 disassembler -namespace +m6x09_disassembler::m6x09_disassembler(m6x09_instruction_level level, const char teregs[16][4]) + : m6x09_base_disassembler(m6x09_opcodes, ARRAY_LENGTH(m6x09_opcodes), level) + , m_teregs(*reinterpret_cast<const std::array<std::array<char, 4>, 16> *>(teregs)) { - class m6x09_disassembler : public m6x09_disassembler_base - { - public: - m6x09_disassembler(m6x09_instruction_level level, const char teregs[16][4]) - : m6x09_disassembler_base(m6x09_opcodes, ARRAY_LENGTH(m6x09_opcodes), level) - , m_teregs(*reinterpret_cast<const std::array<std::array<char, 4>, 16> *>(teregs)) - { - } - - protected: - virtual void indirect(std::ostream &stream, uint8_t pb, const uint8_t *opram, int &p) override; - virtual void register_register(std::ostream &stream, uint8_t pb) override; - - private: - const std::array<std::array<char, 4>, 16> &m_teregs; - }; -}; - +} //------------------------------------------------- // indirect addressing mode for M6809/HD6309 //------------------------------------------------- -void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_t *opram, int &p) +void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const data_buffer ¶ms, offs_t &p) { uint8_t reg = (pb >> 5) & 3; uint8_t pbm = pb & 0x8f; @@ -924,7 +830,7 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ util::stream_format(stream, ",W"); break; case 0x01: - offset = (int16_t)((opram[p + 0] << 8) + opram[p + 1]); + offset = (int16_t)params.r16(p); p += 2; util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%04X,W", (offset < 0) ? -offset : offset); @@ -973,14 +879,14 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ break; case 0x88: // (+/- 7 bit offset),R - offset = (int8_t)opram[p++]; + offset = (int8_t)params.r8(p++); util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%02X,", (offset < 0) ? -offset : offset); util::stream_format(stream, "%s", m6x09_regs[reg]); break; case 0x89: // (+/- 15 bit offset),R - offset = (int16_t)((opram[p + 0] << 8) + opram[p + 1]); + offset = (int16_t)params.r16(p); p += 2; util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%04X,", (offset < 0) ? -offset : offset); @@ -996,13 +902,13 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ break; case 0x8c: // (+/- 7 bit offset),PC - offset = (int8_t)opram[p++]; + offset = (int8_t)params.r8(p); util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%02X,PC", (offset < 0) ? -offset : offset); break; case 0x8d: // (+/- 15 bit offset),PC - offset = (int16_t)((opram[p + 0] << 8) + opram[p + 1]); + offset = (int16_t)params.r16(p); p += 2; util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%04X,PC", (offset < 0) ? -offset : offset); @@ -1015,7 +921,7 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ case 0x8f: // address or operations relative to W if (indirect) { - ea = (uint16_t)((opram[p + 0] << 8) + opram[p + 1]); + ea = (uint16_t)params.r16(p); p += 2; util::stream_format(stream, "$%04X", ea); break; @@ -1028,7 +934,7 @@ void m6x09_disassembler::indirect(std::ostream &stream, uint8_t pb, const uint8_ util::stream_format(stream, ",W"); break; case 0x01: - offset = (int16_t)((opram[p + 0] << 8) + opram[p + 1]); + offset = (int16_t)params.r16(p); p += 2; util::stream_format(stream, "%s", (offset < 0) ? "-" : ""); util::stream_format(stream, "$%04X,W", (offset < 0) ? -offset : offset); @@ -1075,15 +981,15 @@ void m6x09_disassembler::register_register(std::ostream &stream, uint8_t pb) // M6809 disassembler entry point //------------------------------------------------- -CPU_DISASSEMBLE(m6809) +const char m6809_disassembler::m6809_teregs[16][4] = +{ + "D", "X", "Y", "U", "S", "PC", "inv", "inv", + "A", "B", "CC", "DP", "inv", "inv", "inv", "inv" +}; + + +m6809_disassembler::m6809_disassembler() : m6x09_disassembler(M6x09_GENERAL, m6809_teregs) { - static const char m6809_teregs[16][4] = - { - "D", "X", "Y", "U", "S", "PC", "inv", "inv", - "A", "B", "CC", "DP", "inv", "inv", "inv", "inv" - }; - m6x09_disassembler disasm(M6x09_GENERAL, m6809_teregs); - return disasm.disassemble(stream, pc, oprom, opram); } @@ -1091,15 +997,14 @@ CPU_DISASSEMBLE(m6809) // HD6309 disassembler entry point //------------------------------------------------- -CPU_DISASSEMBLE(hd6309) +const char hd6309_disassembler::hd6309_teregs[16][4] = +{ + "D", "X", "Y", "U", "S", "PC", "W", "V", + "A", "B", "CC", "DP", "0", "0", "E", "F" +}; + +hd6309_disassembler::hd6309_disassembler() : m6x09_disassembler(HD6309_EXCLUSIVE, hd6309_teregs) { - static const char hd6309_teregs[16][4] = - { - "D", "X", "Y", "U", "S", "PC", "W", "V", - "A", "B", "CC", "DP", "0", "0", "E", "F" - }; - m6x09_disassembler disasm(HD6309_EXCLUSIVE, hd6309_teregs); - return disasm.disassemble(stream, pc, oprom, opram); } @@ -1107,7 +1012,7 @@ CPU_DISASSEMBLE(hd6309) // Konami disassembler //************************************************************************** -static const opcodeinfo konami_opcodes[] = +const m6x09_base_disassembler::opcodeinfo konami_disassembler::konami_opcodes[] = { { 0x08, 2, "LEAX", IND, M6x09_GENERAL }, { 0x09, 2, "LEAY", IND, M6x09_GENERAL }, @@ -1277,9 +1182,9 @@ static const opcodeinfo konami_opcodes[] = { 0xA6, 2, "ASLW", IND, M6x09_GENERAL }, { 0xA7, 2, "ROLW", IND, M6x09_GENERAL }, { 0xA8, 2, "JMP", IND, M6x09_GENERAL }, - { 0xA9, 2, "JSR", IND, M6x09_GENERAL, DASMFLAG_STEP_OVER }, - { 0xAA, 2, "BSR", REL, M6x09_GENERAL, DASMFLAG_STEP_OVER }, - { 0xAB, 3, "LBSR", LREL, M6x09_GENERAL, DASMFLAG_STEP_OVER }, + { 0xA9, 2, "JSR", IND, M6x09_GENERAL, STEP_OVER }, + { 0xAA, 2, "BSR", REL, M6x09_GENERAL, STEP_OVER }, + { 0xAB, 3, "LBSR", LREL, M6x09_GENERAL, STEP_OVER }, { 0xAC, 2, "DECB,JNZ", REL, M6x09_GENERAL }, { 0xAD, 2, "DECX,JNZ", REL, M6x09_GENERAL }, { 0xAE, 1, "NOP", INH, M6x09_GENERAL }, @@ -1324,27 +1229,15 @@ static const opcodeinfo konami_opcodes[] = // ======================> konami_disassembler -namespace +konami_disassembler::konami_disassembler() : m6x09_base_disassembler(konami_opcodes, ARRAY_LENGTH(konami_opcodes), M6x09_GENERAL) { - // Konami disassembler - class konami_disassembler : public m6x09_disassembler_base - { - public: - konami_disassembler() - : m6x09_disassembler_base(konami_opcodes, ARRAY_LENGTH(konami_opcodes), M6x09_GENERAL) { } - - protected: - virtual void indirect(std::ostream &stream, uint8_t pb, const uint8_t *opram, int &p) override; - virtual void register_register(std::ostream &stream, uint8_t pb) override; - }; -}; - +} //------------------------------------------------- // indirect addressing mode for Konami //------------------------------------------------- -void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uint8_t *opram, int &p) +void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const data_buffer ¶ms, offs_t &p) { static const char index_reg[8][3] = { @@ -1379,7 +1272,7 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 0x04: /* direct - mode */ - util::stream_format(stream, "[$%02x]", opram[p++]); + util::stream_format(stream, "[$%02x]", params.r8(p++)); break; case 0x07: /* register d */ @@ -1404,7 +1297,7 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 0x04: /* direct - mode */ - util::stream_format(stream, "$%02x", opram[p++]); + util::stream_format(stream, "$%02x", params.r8(p++)); break; case 0x07: /* register d */ @@ -1441,7 +1334,7 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 4: // post byte offset - val = opram[p++]; + val = params.r8(p++); if (val & 0x80) util::stream_format(stream, "[#$-%02x,%s]", 0x100 - val, index_reg[idx]); @@ -1450,8 +1343,8 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 5: // post word offset - val = opram[p++] << 8; - val |= opram[p++]; + val = params.r16(p); + p += 2; if (val & 0x8000) util::stream_format(stream, "[#$-%04x,%s]", 0x10000 - val, index_reg[idx]); @@ -1464,8 +1357,8 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 7: // extended - val = opram[p++] << 8; - val |= opram[p++]; + val = params.r16(p); + p += 2; util::stream_format(stream, "[$%04x]", val); break; @@ -1492,7 +1385,7 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 4: // post byte offset - val = opram[p++]; + val = params.r8(p++); if (val & 0x80) util::stream_format(stream, "#$-%02x,%s", 0x100 - val, index_reg[idx]); @@ -1501,8 +1394,8 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 5: // post word offset - val = opram[p++] << 8; - val |= opram[p++]; + val = params.r16(p); + p += 2; if (val & 0x8000) util::stream_format(stream, "#$-%04x,%s", 0x10000 - val, index_reg[idx]); @@ -1515,8 +1408,8 @@ void konami_disassembler::indirect(std::ostream &stream, uint8_t mode, const uin break; case 7: // extended - val = opram[p++] << 8; - val |= opram[p++]; + val = params.r16(p); + p += 2; util::stream_format(stream, "$%04x", val); break; @@ -1540,14 +1433,3 @@ void konami_disassembler::register_register(std::ostream &stream, uint8_t pb) konami_teregs[(pb >> 0) & 0x7], konami_teregs[(pb >> 4) & 0x7]); } - - -//------------------------------------------------- -// Konami disassembler entry point -//------------------------------------------------- - -CPU_DISASSEMBLE(konami) -{ - konami_disassembler disasm; - return disasm.disassemble(stream, pc, oprom, opram); -} diff --git a/src/devices/cpu/m6809/6x09dasm.h b/src/devices/cpu/m6809/6x09dasm.h new file mode 100644 index 00000000000..4a230799801 --- /dev/null +++ b/src/devices/cpu/m6809/6x09dasm.h @@ -0,0 +1,166 @@ +// license:BSD-3-Clause +// copyright-holders:Nathan Woods,Sean Riddle,Tim Lindner +/***************************************************************************** + + 6x09dasm.cpp - a 6809/6309/Konami opcode disassembler + + Based on: + 6309dasm.c - a 6309 opcode disassembler + Version 1.0 5-AUG-2000 + Copyright Tim Lindner + + and + + 6809dasm.c - a 6809 opcode disassembler + Version 1.4 1-MAR-95 + Copyright Sean Riddle + + Thanks to Franklin Bowen for bug fixes, ideas + + Freely distributable on any medium given all copyrights are retained + by the author and no charge greater than $7.00 is made for obtaining + this software + + Please send all bug reports, update ideas and data files to: + sriddle@ionet.net and tlindner@ix.netcom.com + +*****************************************************************************/ + +#ifndef MAME_CPU_M6809_6X09DASM_H +#define MAME_CPU_M6809_6X09DASM_H + +#pragma once + +class m6x09_base_disassembler : public util::disasm_interface +{ +protected: + class opcodeinfo; + +public: + // General, or 6309 only? + enum m6x09_instruction_level + { + M6x09_GENERAL, + HD6309_EXCLUSIVE + }; + + m6x09_base_disassembler(const opcodeinfo *opcodes, size_t opcode_count, m6x09_instruction_level level) + : m_opcodes(opcodes, opcode_count), m_level(level) + { + } + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum m6x09_addressing_mode + { + INH, // Inherent + PSHS, PSHU, // Push + PULS, PULU, // Pull + DIR, // Direct + DIR_IM, // Direct in memory (6309 only) + IND, // Indexed + REL, // Relative (8 bit) + LREL, // Long relative (16 bit) + EXT, // Extended + IMM, // Immediate + IMM_RR, // Register-to-register + IMM_BW, // Bitwise operations (6309 only) + IMM_TFM, // Transfer from memory (6309 only) + PG1, // Switch to page 1 opcodes + PG2 // Switch to page 2 opcodes + }; + + // Opcode structure + class opcodeinfo + { + public: + constexpr opcodeinfo(uint16_t opcode, uint8_t length, const char *name, m6x09_addressing_mode mode, m6x09_instruction_level level, unsigned flags = 0) + : m_opcode(opcode), m_length(length), m_mode(mode), m_level(level), m_flags(flags), m_name(name) + { + } + + uint16_t opcode() const { return m_opcode; } + uint8_t length() const { return m_length; } + m6x09_addressing_mode mode() const { return m_mode; } + m6x09_instruction_level level() const { return m_level; } + unsigned flags() const { return m_flags; } + const char *name() const { return m_name; } + + private: + uint16_t m_opcode; // 8-bit opcode value + uint8_t m_length; // Opcode length in bytes + m6x09_addressing_mode m_mode : 6; // Addressing mode + m6x09_instruction_level m_level : 2; // General, or 6309 only? + unsigned m_flags; // Disassembly flags + const char * m_name; // Opcode name + }; + + static const char *const m6x09_regs[5]; + static const char *const m6x09_btwregs[5]; + static const char *const hd6309_tfmregs[16]; + static const char *const tfm_s[]; + + virtual void indirect(std::ostream &stream, uint8_t pb, const data_buffer ¶ms, offs_t &p) = 0; + virtual void register_register(std::ostream &stream, uint8_t pb) = 0; + +private: + util::contiguous_sequence_wrapper<const opcodeinfo> m_opcodes; + m6x09_instruction_level m_level; + + const opcodeinfo *fetch_opcode(const data_buffer &opcodes, offs_t &p); + + void assert_hd6309_exclusive() + { + if (m_level < HD6309_EXCLUSIVE) + throw false; + } +}; + +class m6x09_disassembler : public m6x09_base_disassembler +{ +public: + m6x09_disassembler(m6x09_instruction_level level, const char teregs[16][4]); + +protected: + virtual void indirect(std::ostream &stream, uint8_t pb, const data_buffer ¶ms, offs_t &p) override; + virtual void register_register(std::ostream &stream, uint8_t pb) override; + +private: + static const opcodeinfo m6x09_opcodes[]; + const std::array<std::array<char, 4>, 16> &m_teregs; +}; + + +class konami_disassembler : public m6x09_base_disassembler +{ +public: + konami_disassembler(); + +protected: + virtual void indirect(std::ostream &stream, uint8_t pb, const data_buffer ¶ms, offs_t &p) override; + virtual void register_register(std::ostream &stream, uint8_t pb) override; + +private: + static const opcodeinfo konami_opcodes[]; +}; + +class m6809_disassembler : public m6x09_disassembler +{ +public: + m6809_disassembler(); + +private: + static const char m6809_teregs[16][4]; +}; + +class hd6309_disassembler : public m6x09_disassembler +{ +public: + hd6309_disassembler(); + +private: + static const char hd6309_teregs[16][4]; +}; + +#endif diff --git a/src/devices/cpu/m6809/hd6309.cpp b/src/devices/cpu/m6809/hd6309.cpp index 30de26db2c6..1b40d17e06f 100644 --- a/src/devices/cpu/m6809/hd6309.cpp +++ b/src/devices/cpu/m6809/hd6309.cpp @@ -118,6 +118,7 @@ March 2013 NPW: #include "debugger.h" #include "hd6309.h" #include "m6809inl.h" +#include "6x09dasm.h" //************************************************************************** @@ -285,38 +286,13 @@ void hd6309_device::device_post_load() //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t hd6309_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t hd6309_device::disasm_max_opcode_bytes() const -{ - return 5; -} - - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t hd6309_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hd6309_device::create_disassembler() { - extern CPU_DISASSEMBLE( hd6309 ); - return CPU_DISASSEMBLE_NAME(hd6309)(this, stream, pc, oprom, opram, options); + return new hd6309_disassembler; } diff --git a/src/devices/cpu/m6809/hd6309.h b/src/devices/cpu/m6809/hd6309.h index a097902da1f..8e209f9f7b2 100644 --- a/src/devices/cpu/m6809/hd6309.h +++ b/src/devices/cpu/m6809/hd6309.h @@ -42,9 +42,7 @@ protected: virtual void execute_run() override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual bool is_6809() override { return false; }; diff --git a/src/devices/cpu/m6809/konami.cpp b/src/devices/cpu/m6809/konami.cpp index 55f3a864744..cf41649a101 100644 --- a/src/devices/cpu/m6809/konami.cpp +++ b/src/devices/cpu/m6809/konami.cpp @@ -58,6 +58,7 @@ March 2013 NPW: #include "debugger.h" #include "konami.h" #include "m6809inl.h" +#include "6x09dasm.h" //************************************************************************** @@ -105,14 +106,13 @@ void konami_cpu_device::device_start() //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t konami_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *konami_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( konami ); - return CPU_DISASSEMBLE_NAME(konami)(this, stream, pc, oprom, opram, options); + return new konami_disassembler; } diff --git a/src/devices/cpu/m6809/konami.h b/src/devices/cpu/m6809/konami.h index 1d9d900c138..216b007302a 100644 --- a/src/devices/cpu/m6809/konami.h +++ b/src/devices/cpu/m6809/konami.h @@ -46,7 +46,7 @@ protected: virtual void execute_run() override; // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: typedef m6809_base_device super; diff --git a/src/devices/cpu/m6809/m6809.cpp b/src/devices/cpu/m6809/m6809.cpp index 584af3e4912..42f64d5e5b2 100644 --- a/src/devices/cpu/m6809/m6809.cpp +++ b/src/devices/cpu/m6809/m6809.cpp @@ -83,6 +83,7 @@ March 2013 NPW: #include "debugger.h" #include "m6809.h" #include "m6809inl.h" +#include "6x09dasm.h" //************************************************************************** @@ -133,8 +134,8 @@ void m6809_base_device::device_start() m_mintf->m_program = &space(AS_PROGRAM); m_mintf->m_sprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_mintf->m_program; - m_mintf->m_direct = &m_mintf->m_program->direct(); - m_mintf->m_sdirect = &m_mintf->m_sprogram->direct(); + m_mintf->m_direct = m_mintf->m_program->direct<0>(); + m_mintf->m_sdirect = m_mintf->m_sprogram->direct<0>(); m_lic_func.resolve_safe(); @@ -350,36 +351,13 @@ void m6809_base_device::state_string_export(const device_state_entry &entry, std //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t m6809_base_device::disasm_min_opcode_bytes() const -{ - return 1; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t m6809_base_device::disasm_max_opcode_bytes() const -{ - return 5; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t m6809_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *m6809_base_device::create_disassembler() { - extern CPU_DISASSEMBLE( m6809 ); - return CPU_DISASSEMBLE_NAME(m6809)(this, stream, pc, oprom, opram, options); + return new m6809_disassembler; } diff --git a/src/devices/cpu/m6809/m6809.h b/src/devices/cpu/m6809/m6809.h index 29d1acbcf9e..759e37113a5 100644 --- a/src/devices/cpu/m6809/m6809.h +++ b/src/devices/cpu/m6809/m6809.h @@ -34,7 +34,7 @@ protected: class memory_interface { public: address_space *m_program, *m_sprogram; - direct_read_data *m_direct, *m_sdirect; + direct_read_data<0> *m_direct, *m_sdirect; virtual ~memory_interface() {} virtual uint8_t read(uint16_t adr) = 0; @@ -71,9 +71,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_import(const device_state_entry &entry) override; diff --git a/src/devices/cpu/mb86233/mb86233.cpp b/src/devices/cpu/mb86233/mb86233.cpp index 526ac63e208..32bdd8f2ea7 100644 --- a/src/devices/cpu/mb86233/mb86233.cpp +++ b/src/devices/cpu/mb86233/mb86233.cpp @@ -18,6 +18,7 @@ #include "emu.h" #include "debugger.h" #include "mb86233.h" +#include "mb86233d.h" DEFINE_DEVICE_TYPE(MB86233, mb86233_cpu_device, "mb86233", "MB86233") @@ -46,10 +47,9 @@ device_memory_interface::space_config_vector mb86233_cpu_device::memory_space_co } -offs_t mb86233_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mb86233_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( mb86233 ); - return CPU_DISASSEMBLE_NAME(mb86233)(this, stream, pc, oprom, opram, options); + return new mb86233_disassembler; } @@ -79,9 +79,9 @@ offs_t mb86233_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, c #define GETBRAM() m_BRAM #define GETREPCNT() m_repcnt -#define ROPCODE(a) m_direct->read_dword(a<<2) -#define RDMEM(a) m_program->read_dword((a<<2)) -#define WRMEM(a,v) m_program->write_dword((a<<2), v) +#define ROPCODE(a) m_direct->read_dword(a) +#define RDMEM(a) m_program->read_dword(a) +#define WRMEM(a,v) m_program->write_dword((a), v) /*************************************************************************** Initialization and Shutdown @@ -110,7 +110,7 @@ void mb86233_cpu_device::device_start() m_fifo_write_cb.resolve_safe(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-2>(); if ( m_tablergn ) { diff --git a/src/devices/cpu/mb86233/mb86233.h b/src/devices/cpu/mb86233/mb86233.h index c60aabd987e..49ba58d7ea8 100644 --- a/src/devices/cpu/mb86233/mb86233.h +++ b/src/devices/cpu/mb86233/mb86233.h @@ -77,9 +77,7 @@ protected: 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -111,7 +109,7 @@ private: uint32_t m_extport[0x30]; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-2> *m_direct; int m_icount; /* FIFO */ diff --git a/src/devices/cpu/mb86233/mb86233d.cpp b/src/devices/cpu/mb86233/mb86233d.cpp index 0919ca1ef58..5d5c9b13a27 100644 --- a/src/devices/cpu/mb86233/mb86233d.cpp +++ b/src/devices/cpu/mb86233/mb86233d.cpp @@ -1,8 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Ernesto Corvi #include "emu.h" -#include "debugger.h" -#include "mb86233.h" +#include "mb86233d.h" /* @@ -74,14 +73,14 @@ -static const char *const regnames[0x40] = { +const char *const mb86233_disassembler::regnames[0x40] = { "b0", "b1", "x0", "x1", "x2", "i0", "i1", "i2", "sp", "pag", "vsm", "dmc", "c0", "c1", "pc", "-", "a", "ah", "al", "b", "bh", "bl", "c", "ch", "cl", "d", "dh", "dl", "p", "ph", "pl", "sft", "rf0", "rf1", "rf2", "rf3", "rf4", "rf5", "rf6", "rf7", "rf8", "rf9", "rfa", "rfb", "rfc", "rfd", "rfe", "rff", "sio0", "si1", "pio", "pioa", "rpc", "r?35", "r?36", "r?37", "pad", "mod", "ear", "st", "mask", "tim", "cx", "dx" }; -static std::string condition(unsigned int cond, bool invert) +std::string mb86233_disassembler::condition(unsigned int cond, bool invert) { std::ostringstream stream; @@ -101,12 +100,12 @@ static std::string condition(unsigned int cond, bool invert) return stream.str(); } -static std::string regs(uint32_t reg) +std::string mb86233_disassembler::regs(u32 reg) { return regnames[reg & 0x3f]; } -static std::string memory(uint32_t reg, bool x1) +std::string mb86233_disassembler::memory(u32 reg, bool x1) { std::ostringstream stream; @@ -182,7 +181,7 @@ static std::string memory(uint32_t reg, bool x1) return stream.str(); } -static std::string alu0_func( uint32_t alu) +std::string mb86233_disassembler::alu0_func(u32 alu) { std::ostringstream stream; @@ -224,14 +223,16 @@ static std::string alu0_func( uint32_t alu) return stream.str(); } -static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) +offs_t mb86233_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { + u32 opcode = opcodes.r32(pc); + switch((opcode >> 26) & 0x3f) { case 0x00: { // Dual move AB - uint32_t r1 = opcode & 0x1ff; - uint32_t r2 = (opcode >> 9) & 0x1ff; - uint32_t alu = (opcode >> 21) & 0x1f; - uint32_t op = (opcode >> 18) & 0x7; + u32 r1 = opcode & 0x1ff; + u32 r2 = (opcode >> 9) & 0x1ff; + u32 alu = (opcode >> 21) & 0x1f; + u32 op = (opcode >> 18) & 0x7; if(alu) util::stream_format(stream, "%s : ", alu0_func(alu) ); @@ -253,10 +254,10 @@ static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) } case 0x07: { // LD/MOV - uint32_t r1 = opcode & 0x1ff; - uint32_t r2 = (opcode >> 9) & 0x1ff; - uint32_t alu = (opcode >> 21) & 0x1f; - uint32_t op = (opcode >> 18) & 0x7; + u32 r1 = opcode & 0x1ff; + u32 r2 = (opcode >> 9) & 0x1ff; + u32 alu = (opcode >> 21) & 0x1f; + u32 op = (opcode >> 18) & 0x7; if(alu) { util::stream_format(stream, "%s", alu0_func(alu)); @@ -345,8 +346,8 @@ static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) } case 0x0f: { // rep/clr0/clr1/set - uint32_t alu = (opcode >> 21) & 0x1f; - uint32_t sub2 = (opcode >> 17) & 7; + u32 alu = (opcode >> 21) & 0x1f; + u32 sub2 = (opcode >> 17) & 7; if(alu) util::stream_format(stream, "%s : ", alu0_func(alu)); @@ -400,9 +401,9 @@ static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) break; case 0x2f: case 0x3f: { - uint32_t cond = ( opcode >> 20 ) & 0x1f; - uint32_t subtype = ( opcode >> 17 ) & 7; - uint32_t data = opcode & 0xffff; + u32 cond = ( opcode >> 20 ) & 0x1f; + u32 subtype = ( opcode >> 17 ) & 7; + u32 data = opcode & 0xffff; bool invert = opcode & 0x40000000; switch(subtype) { @@ -454,12 +455,10 @@ static unsigned dasm_mb86233(std::ostream &stream, uint32_t opcode ) break; } - return (1 | DASMFLAG_SUPPORTED); + return 1 | SUPPORTED; } -CPU_DISASSEMBLE(mb86233) +u32 mb86233_disassembler::opcode_alignment() const { - uint32_t op = *(uint32_t *)oprom; - op = little_endianize_int32(op); - return dasm_mb86233(stream, op); + return 1; } diff --git a/src/devices/cpu/mb86233/mb86233d.h b/src/devices/cpu/mb86233/mb86233d.h new file mode 100644 index 00000000000..50a48a6f0a9 --- /dev/null +++ b/src/devices/cpu/mb86233/mb86233d.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Ernesto Corvi + +#ifndef MAME_CPU_MB86233_MB86233D_H +#define MAME_CPU_MB86233_MB86233D_H + +#pragma once + +class mb86233_disassembler : public util::disasm_interface +{ +public: + mb86233_disassembler() = default; + virtual ~mb86233_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const regnames[0x40]; + static std::string condition(unsigned int cond, bool invert); + static std::string regs(u32 reg); + static std::string memory(u32 reg, bool x1); + static std::string alu0_func(u32 alu); +}; + +#endif diff --git a/src/devices/cpu/mb86235/mb86235.cpp b/src/devices/cpu/mb86235/mb86235.cpp index 223b27db6d3..77a24bc43a4 100644 --- a/src/devices/cpu/mb86235/mb86235.cpp +++ b/src/devices/cpu/mb86235/mb86235.cpp @@ -14,6 +14,7 @@ #include "emu.h" #include "mb86235.h" #include "mb86235fe.h" +#include "mb86235d.h" #include "debugger.h" @@ -56,7 +57,7 @@ void mb86235_device::execute_run() void mb86235_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-3>(); m_dataa = &space(AS_DATA); m_datab = &space(AS_IO); @@ -234,10 +235,9 @@ void mb86235_device::state_string_export(const device_state_entry &entry, std::s } } -offs_t mb86235_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mb86235_device::create_disassembler() { - extern CPU_DISASSEMBLE( mb86235 ); - return CPU_DISASSEMBLE_NAME(mb86235)(this, stream, pc, oprom, opram, options); + return new mb86235_disassembler; } diff --git a/src/devices/cpu/mb86235/mb86235.h b/src/devices/cpu/mb86235/mb86235.h index ebe151213da..f1845bfce6f 100644 --- a/src/devices/cpu/mb86235/mb86235.h +++ b/src/devices/cpu/mb86235/mb86235.h @@ -71,11 +71,9 @@ protected: 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 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; - direct_read_data *m_direct; + direct_read_data<-3> *m_direct; private: @@ -228,7 +226,4 @@ private: DECLARE_DEVICE_TYPE(MB86235, mb86235_device) - -CPU_DISASSEMBLE( mb86235 ); - #endif // MAME_CPU_MB86235_MB86235_H diff --git a/src/devices/cpu/mb86235/mb86235d.cpp b/src/devices/cpu/mb86235/mb86235d.cpp index f32fcba8969..e705500f1cd 100644 --- a/src/devices/cpu/mb86235/mb86235d.cpp +++ b/src/devices/cpu/mb86235/mb86235d.cpp @@ -1,10 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Angelo Salese, ElSemi, Ville Linde #include "emu.h" -#include "debugger.h" -#include "mb86235.h" +#include "mb86235d.h" -static const char *regname[128] = +const char *mb86235_disassembler::regname[128] = { "MA0", "MA1", "MA2", "MA3", "MA4", "MA5", "MA6", "MA7", "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", @@ -16,7 +15,7 @@ static const char *regname[128] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *db_mnemonic[64] = +const char *mb86235_disassembler::db_mnemonic[64] = { "DBMN", "DBMZ", "DBMV", "DBMU", "DBZD", "DBNR", "DBIL", "DBZC", "DBAN", "DBAZ", "DBAV", "DBAU", "DBMD", "DBAD", "???", "???", @@ -28,7 +27,7 @@ static const char *db_mnemonic[64] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *dbn_mnemonic[64] = +const char *mb86235_disassembler::dbn_mnemonic[64] = { "DBNMN", "DBNMZ", "DBNMV", "DBNMU", "DBNZD", "DBNNR", "DBNIL", "DBNZC", "DBNAN", "DBNAZ", "DBNAV", "DBNAU", "DBNMD", "DBNAD", "???", "???", @@ -40,7 +39,7 @@ static const char *dbn_mnemonic[64] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *dc_mnemonic[64] = +const char *mb86235_disassembler::dc_mnemonic[64] = { "DCMN", "DCMZ", "DCMV", "DCMU", "DCZD", "DCNR", "DCIL", "DCZC", "DCAN", "DCAZ", "DCAV", "DCAU", "DCMD", "DCAD", "???", "???", @@ -52,7 +51,7 @@ static const char *dc_mnemonic[64] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *dcn_mnemonic[64] = +const char *mb86235_disassembler::dcn_mnemonic[64] = { "DCNMN", "DCNMZ", "DCNMV", "DCNMU", "DCNZD", "DCNNR", "DCNIL", "DCNZC", "DCNAN", "DCNAZ", "DCNAV", "DCNAU", "DCNMD", "DCNAD", "???", "???", @@ -64,29 +63,29 @@ static const char *dcn_mnemonic[64] = "???", "???", "???", "???", "???", "???", "???", "???" }; -static const char *mi1_field[16] = +const char *mb86235_disassembler::mi1_field[16] = { "MA0", "MA1", "MA2", "MA3", "MA4", "MA5", "MA6", "MA7", "MB0", "MB1", "MB2", "MB3", "MB4", "MB5", "MB6", "MB7" }; -static const char *mi2_field[32] = +const char *mb86235_disassembler::mi2_field[32] = { "MA0", "MA1", "MA2", "MA3", "MA4", "MA5", "MA6", "MA7", "MB0", "MB1", "MB2", "MB3", "MB4", "MB5", "MB6", "MB7", "PR", "PR++", "PR--", "PR#0", "???", "???", "???", "???", "-1.0E+0", "0.0E+0", "0.5E+0", "1.0E+0", "1.5E+0", "2.0E+0", "3.0E+0", "5.0E+0" }; -static const char *mo_field[32] = +const char *mb86235_disassembler::mo_field[32] = { "MA0", "MA1", "MA2", "MA3", "MA4", "MA5", "MA6", "MA7", "MB0", "MB1", "MB2", "MB3", "MB4", "MB5", "MB6", "MB7", "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", "AB0", "AB1", "AB2", "AB3", "AB4", "AB5", "AB6", "AB7" }; -static const char *ai1_field[16] = +const char *mb86235_disassembler::ai1_field[16] = { "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", "AB0", "AB1", "AB2", "AB3", "AB4", "AB5", "AB6", "AB7" }; -static const char *ai2_field[32] = +const char *mb86235_disassembler::ai2_field[32] = { "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", "AB0", "AB1", "AB2", "AB3", "AB4", "AB5", "AB6", "AB7", "PR", "PR++", "PR--", "PR#0", "???", "???", "???", "???", "0", "1", "-1", "???", "???", "???", "???", "???" }; -static const char *ai2f_field[32] = +const char *mb86235_disassembler::ai2f_field[32] = { "AA0", "AA1", "AA2", "AA3", "AA4", "AA5", "AA6", "AA7", "AB0", "AB1", "AB2", "AB3", "AB4", "AB5", "AB6", "AB7", "PR", "PR++", "PR--", "PR#0", "???", "???", "???", "???", "-1.0E+0", "0.0E+0", "0.5E+0", "1.0E+0", "1.5E+0", "2.0E+0", "3.0E+0", "5.0E+0" }; -static void dasm_ea(std::ostream &stream, int md, int arx, int ary, int disp) +void mb86235_disassembler::dasm_ea(std::ostream &stream, int md, int arx, int ary, int disp) { if (arx & 0x20) stream << "B("; @@ -117,7 +116,7 @@ static void dasm_ea(std::ostream &stream, int md, int arx, int ary, int disp) stream << ')'; } -static void dasm_alu_mul(std::ostream &stream, uint64_t opcode, bool twoop) +void mb86235_disassembler::dasm_alu_mul(std::ostream &stream, uint64_t opcode, bool twoop) { int ma = (opcode & ((uint64_t)(1) << 41)) ? 1 : 0; int o = (opcode >> 42) & 0x1f; @@ -220,7 +219,7 @@ static void dasm_alu_mul(std::ostream &stream, uint64_t opcode, bool twoop) } } -static void dasm_control(std::ostream &stream, uint32_t pc, uint64_t opcode) +void mb86235_disassembler::dasm_control(std::ostream &stream, uint32_t pc, uint64_t opcode) { int ef1 = (opcode >> 16) & 0x3f; int ef2 = opcode & 0xffff; @@ -335,7 +334,7 @@ static void dasm_control(std::ostream &stream, uint32_t pc, uint64_t opcode) } } -static void dasm_double_xfer1(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_double_xfer1(std::ostream &stream, uint64_t opcode) { int sd = (opcode >> 25) & 3; @@ -413,7 +412,7 @@ static void dasm_double_xfer1(std::ostream &stream, uint64_t opcode) } } -static void dasm_xfer1(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_xfer1(std::ostream &stream, uint64_t opcode) { int dr = (opcode >> 12) & 0x7f; int sr = (opcode >> 19) & 0x7f; @@ -469,7 +468,7 @@ static void dasm_xfer1(std::ostream &stream, uint64_t opcode) } } -static void dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field) +void mb86235_disassembler::dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field) { switch (sd) { @@ -537,7 +536,7 @@ static void dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field } } -static void dasm_double_xfer2(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_double_xfer2(std::ostream &stream, uint64_t opcode) { int asd = (opcode >> 38) & 3; int bsd = (opcode >> 18) & 3; @@ -583,7 +582,7 @@ static void dasm_double_xfer2(std::ostream &stream, uint64_t opcode) } } -static void dasm_xfer2(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_xfer2(std::ostream &stream, uint64_t opcode) { int op = (opcode >> 39) & 3; int trm = (opcode >> 38) & 1; @@ -652,7 +651,7 @@ static void dasm_xfer2(std::ostream &stream, uint64_t opcode) } } -static void dasm_xfer3(std::ostream &stream, uint64_t opcode) +void mb86235_disassembler::dasm_xfer3(std::ostream &stream, uint64_t opcode) { uint32_t imm = (uint32_t)(opcode >> 27); int dr = (opcode >> 19) & 0x7f; @@ -668,8 +667,9 @@ static void dasm_xfer3(std::ostream &stream, uint64_t opcode) dasm_ea(stream, md, dr, ary, disp); } -static unsigned dasm_mb86235(std::ostream &stream, uint32_t pc, uint64_t opcode) +offs_t mb86235_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { + u64 opcode = opcodes.r64(pc); switch ((opcode >> 61) & 7) { case 0: // ALU / MUL / double transfer (type 1) @@ -711,14 +711,11 @@ static unsigned dasm_mb86235(std::ostream &stream, uint32_t pc, uint64_t opcode) break; } - return (1 | DASMFLAG_SUPPORTED); + return 1 | SUPPORTED; } - -CPU_DISASSEMBLE(mb86235) +u32 mb86235_disassembler::opcode_alignment() const { - uint64_t op = *(uint64_t*)oprom; - op = little_endianize_int64(op); - - return dasm_mb86235(stream, pc, op); + return 1; } + diff --git a/src/devices/cpu/mb86235/mb86235d.h b/src/devices/cpu/mb86235/mb86235d.h new file mode 100644 index 00000000000..a29fe41f064 --- /dev/null +++ b/src/devices/cpu/mb86235/mb86235d.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese, ElSemi, Ville Linde +#ifndef MAME_CPU_MB86235_MB86235D_H +#define MAME_CPU_MB86235_MB86235D_H + +#pragma once + +class mb86235_disassembler : public util::disasm_interface +{ +public: + mb86235_disassembler() = default; + virtual ~mb86235_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *regname[128]; + static const char *db_mnemonic[64]; + static const char *dbn_mnemonic[64]; + static const char *dc_mnemonic[64]; + static const char *dcn_mnemonic[64]; + static const char *mi1_field[16]; + static const char *mi2_field[32]; + static const char *mo_field[32]; + static const char *ai1_field[16]; + static const char *ai2_field[32]; + static const char *ai2f_field[32]; + + void dasm_ea(std::ostream &stream, int md, int arx, int ary, int disp); + void dasm_alu_mul(std::ostream &stream, uint64_t opcode, bool twoop); + void dasm_control(std::ostream &stream, uint32_t pc, uint64_t opcode); + void dasm_double_xfer1(std::ostream &stream, uint64_t opcode); + void dasm_xfer1(std::ostream &stream, uint64_t opcode); + void dasm_double_xfer2_field(std::ostream &stream, int sd, uint32_t field); + void dasm_double_xfer2(std::ostream &stream, uint64_t opcode); + void dasm_xfer2(std::ostream &stream, uint64_t opcode); + void dasm_xfer3(std::ostream &stream, uint64_t opcode); + +}; + +#endif diff --git a/src/devices/cpu/mb86235/mb86235drc.cpp b/src/devices/cpu/mb86235/mb86235drc.cpp index d3fa314b0ae..fa1f829a07b 100644 --- a/src/devices/cpu/mb86235/mb86235drc.cpp +++ b/src/devices/cpu/mb86235/mb86235drc.cpp @@ -498,7 +498,6 @@ void mb86235_device::static_generate_memory_accessors() UML_CMP(block, I0, 0x400); UML_JMPc(block, COND_GE, label); // internal A-RAM - UML_SHL(block, I0, I0, 2); UML_READ(block, I1, I0, SIZE_DWORD, SPACE_DATA); UML_RET(block); // external @@ -506,7 +505,6 @@ void mb86235_device::static_generate_memory_accessors() UML_AND(block, I0, I0, 0x3fff); UML_AND(block, I2, mem(&m_core->eb), ~0x3fff); UML_OR(block, I0, I0, I2); - UML_SHL(block, I0, I0, 2); UML_READ(block, I1, I0, SIZE_DWORD, SPACE_DATA); UML_RET(block); @@ -523,7 +521,6 @@ void mb86235_device::static_generate_memory_accessors() UML_CMP(block, I0, 0x400); UML_JMPc(block, COND_GE, label); // internal A-RAM - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_DATA); UML_RET(block); // external @@ -531,7 +528,6 @@ void mb86235_device::static_generate_memory_accessors() UML_AND(block, I0, I0, 0x3fff); UML_AND(block, I2, mem(&m_core->eb), ~0x3fff); UML_OR(block, I0, I0, I2); - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_DATA); UML_RET(block); @@ -1666,7 +1662,6 @@ void mb86235_device::generate_xfer1(drcuml_block *block, compiler_state *compile generate_ea(block, compiler, desc, md, sr & 7, ary, disp5); if (sr & 0x20) // RAM-B { - UML_SHL(block, I0, I0, 2); UML_READ(block, I1, I0, SIZE_DWORD, SPACE_IO); } else // RAM-A @@ -1684,7 +1679,6 @@ void mb86235_device::generate_xfer1(drcuml_block *block, compiler_state *compile generate_ea(block, compiler, desc, md, dr & 7, ary, disp5); if (dr & 0x20) // RAM-B { - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_IO); } else // RAM-A @@ -1743,7 +1737,6 @@ void mb86235_device::generate_xfer2(drcuml_block *block, compiler_state *compile generate_ea(block, compiler, desc, md, sr & 7, ary, disp14); if (sr & 0x20) // RAM-B { - UML_SHL(block, I0, I0, 2); UML_READ(block, I1, I0, SIZE_DWORD, SPACE_IO); } else // RAM-A @@ -1761,7 +1754,6 @@ void mb86235_device::generate_xfer2(drcuml_block *block, compiler_state *compile generate_ea(block, compiler, desc, md, dr & 7, ary, disp14); if (dr & 0x20) // RAM-B { - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_IO); } else // RAM-A @@ -1779,14 +1771,12 @@ void mb86235_device::generate_xfer2(drcuml_block *block, compiler_state *compile generate_reg_read(block, compiler, desc, dr & 0x3f, I0); UML_ADD(block, I1, mem(&m_core->eb), mem(&m_core->eo)); UML_ADD(block, I1, I1, disp14); - UML_SHL(block, I1, I1, 2); UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_DATA); } else { UML_ADD(block, I1, mem(&m_core->eb), mem(&m_core->eo)); UML_ADD(block, I1, I1, disp14); - UML_SHL(block, I1, I1, 2); UML_READ(block, I0, I1, SIZE_DWORD, SPACE_DATA); generate_reg_write(block, compiler, desc, dr & 0x3f, I0); } @@ -1835,7 +1825,6 @@ void mb86235_device::generate_xfer3(drcuml_block *block, compiler_state *compile case 3: // RAM-B generate_ea(block, compiler, desc, md, dr & 7, ary, disp); - UML_SHL(block, I0, I0, 2); UML_WRITE(block, I0, imm, SIZE_DWORD, SPACE_IO); break; } diff --git a/src/devices/cpu/mb86235/mb86235fe.cpp b/src/devices/cpu/mb86235/mb86235fe.cpp index 854fd97abb7..5e60cfe6216 100644 --- a/src/devices/cpu/mb86235/mb86235fe.cpp +++ b/src/devices/cpu/mb86235/mb86235fe.cpp @@ -63,7 +63,7 @@ mb86235_frontend::mb86235_frontend(mb86235_device *core, uint32_t window_start, bool mb86235_frontend::describe(opcode_desc &desc, const opcode_desc *prev) { - uint64_t opcode = desc.opptr.q[0] = m_core->m_direct->read_qword(desc.pc * 8, 0); + uint64_t opcode = desc.opptr.q[0] = m_core->m_direct->read_qword(desc.pc, 0); desc.length = 1; desc.cycles = 1; diff --git a/src/devices/cpu/mb88xx/mb88dasm.cpp b/src/devices/cpu/mb88xx/mb88dasm.cpp index eced68233b0..2ab2856e1e8 100644 --- a/src/devices/cpu/mb88xx/mb88dasm.cpp +++ b/src/devices/cpu/mb88xx/mb88dasm.cpp @@ -10,14 +10,18 @@ *******************************************************************************/ #include "emu.h" -#include "mb88xx.h" +#include "mb88dasm.h" +u32 mb88_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(mb88) +offs_t mb88_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned startpc = pc; - uint8_t op = oprom[pc++ - startpc]; - uint8_t arg = oprom[pc - startpc]; + uint8_t op = opcodes.r8(pc++); + uint8_t arg = opcodes.r8(pc); switch( op ) { @@ -220,5 +224,5 @@ CPU_DISASSEMBLE(mb88) break; } - return (pc - startpc) | DASMFLAG_SUPPORTED; + return (pc - startpc) | SUPPORTED; } diff --git a/src/devices/cpu/mb88xx/mb88dasm.h b/src/devices/cpu/mb88xx/mb88dasm.h new file mode 100644 index 00000000000..80a37a374c7 --- /dev/null +++ b/src/devices/cpu/mb88xx/mb88dasm.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Ernesto Corvi +/******************************************************************************* + + mb88dasm.c + Core implementation for the portable Fujitsu MB88xx series MCU disassembler. + + Written by Ernesto Corvi + +*******************************************************************************/ + + +#ifndef MAME_CPU_MB88XX_MB88DASM_H +#define MAME_CPU_MB88XX_MB88DASM_H + +#pragma once + +class mb88_disassembler : public util::disasm_interface +{ +public: + mb88_disassembler() = default; + virtual ~mb88_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/mb88xx/mb88xx.cpp b/src/devices/cpu/mb88xx/mb88xx.cpp index b896a07c6cf..1473a3452ae 100644 --- a/src/devices/cpu/mb88xx/mb88xx.cpp +++ b/src/devices/cpu/mb88xx/mb88xx.cpp @@ -17,6 +17,7 @@ #include "emu.h" #include "mb88xx.h" +#include "mb88dasm.h" #include "debugger.h" @@ -162,10 +163,9 @@ device_memory_interface::space_config_vector mb88_cpu_device::memory_space_confi }; } -offs_t mb88_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mb88_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( mb88 ); - return CPU_DISASSEMBLE_NAME(mb88)(this, stream, pc, oprom, opram, options); + return new mb88_disassembler; } @@ -176,7 +176,7 @@ offs_t mb88_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons void mb88_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_read_k.resolve_safe(0); diff --git a/src/devices/cpu/mb88xx/mb88xx.h b/src/devices/cpu/mb88xx/mb88xx.h index f4485e47f26..0be1ac9b06e 100644 --- a/src/devices/cpu/mb88xx/mb88xx.h +++ b/src/devices/cpu/mb88xx/mb88xx.h @@ -122,9 +122,6 @@ enum #define MB88_IRQ_LINE 0 -CPU_DISASSEMBLE( mb88 ); - - class mb88_cpu_device : public cpu_device { public: @@ -165,9 +162,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -215,7 +210,7 @@ private: uint8_t m_pending_interrupt; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; int m_icount; diff --git a/src/devices/cpu/mc68hc11/hc11dasm.cpp b/src/devices/cpu/mc68hc11/hc11dasm.cpp index 20ad20c4d0a..9fdc77409fe 100644 --- a/src/devices/cpu/mc68hc11/hc11dasm.cpp +++ b/src/devices/cpu/mc68hc11/hc11dasm.cpp @@ -7,33 +7,9 @@ */ #include "emu.h" +#include "hc11dasm.h" -enum -{ - EA_IMM8 = 1, - EA_IMM16, - EA_EXT, - EA_REL, - EA_DIRECT, - EA_DIRECT_IMM8, - EA_DIRECT_IMM8_REL, - EA_IND_X, - EA_IND_X_IMM8, - EA_IND_X_IMM8_REL, - EA_IND_Y, - EA_IND_Y_IMM8, - EA_IND_Y_IMM8_REL, - PAGE2, - PAGE3, - PAGE4 -}; - -struct M68HC11_OPCODE { - char mnemonic[32]; - int address_mode; -}; - -static const M68HC11_OPCODE opcode_table[256] = +const hc11_disassembler::M68HC11_OPCODE hc11_disassembler::opcode_table[256] = { /* 0x00 - 0x0f */ { "test", 0, }, @@ -313,7 +289,7 @@ static const M68HC11_OPCODE opcode_table[256] = /*****************************************************************************/ -static const M68HC11_OPCODE opcode_table_page2[256] = +const hc11_disassembler::M68HC11_OPCODE hc11_disassembler::opcode_table_page2[256] = { /* 0x00 - 0x0f */ { "?", 0, }, @@ -593,7 +569,7 @@ static const M68HC11_OPCODE opcode_table_page2[256] = /*****************************************************************************/ -static const M68HC11_OPCODE opcode_table_page3[256] = +const hc11_disassembler::M68HC11_OPCODE hc11_disassembler::opcode_table_page3[256] = { /* 0x00 - 0x0f */ { "?", 0, }, @@ -873,7 +849,7 @@ static const M68HC11_OPCODE opcode_table_page3[256] = /*****************************************************************************/ -static const M68HC11_OPCODE opcode_table_page4[256] = +const hc11_disassembler::M68HC11_OPCODE hc11_disassembler::opcode_table_page4[256] = { /* 0x00 - 0x0f */ { "?", 0, }, @@ -1152,137 +1128,126 @@ static const M68HC11_OPCODE opcode_table_page4[256] = /*****************************************************************************/ -static const uint8_t *rombase; - -static uint8_t fetch(void) +u32 hc11_disassembler::opcode_alignment() const { - return *rombase++; + return 1; } -static uint16_t fetch16(void) +offs_t hc11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint16_t w; - w = (rombase[0] << 8) | rombase[1]; - rombase+=2; - return w; -} + offs_t cpc = pc; + + uint8_t opcode = opcodes.r8(cpc++); + const M68HC11_OPCODE *op_table = &opcode_table[opcode]; -static uint32_t decode_opcode(std::ostream &stream, uint32_t pc, const M68HC11_OPCODE *op_table) -{ uint8_t imm8, mask; int8_t rel8; uint16_t imm16; uint8_t op2; uint32_t flags = 0; + loop: if (!strcmp(op_table->mnemonic, "jsr") || !strcmp(op_table->mnemonic, "bsr")) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strcmp(op_table->mnemonic, "rts") || !strcmp(op_table->mnemonic, "rti")) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; switch(op_table->address_mode) { case EA_IMM8: - imm8 = fetch(); + imm8 = opcodes.r8(cpc++); util::stream_format(stream, "%s 0x%02X", op_table->mnemonic, imm8); break; case EA_IMM16: - imm16 = fetch16(); + imm16 = opcodes.r16(cpc++); + cpc += 2; util::stream_format(stream, "%s 0x%04X", op_table->mnemonic, imm16); break; case EA_DIRECT: - imm8 = fetch(); + imm8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (0x%04X)", op_table->mnemonic, imm8); break; case EA_EXT: - imm16 = fetch16(); + imm16 = opcodes.r16(cpc++); + cpc += 2; util::stream_format(stream, "%s (0x%04X)", op_table->mnemonic, imm16); break; case EA_IND_X: - imm8 = fetch(); + imm8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (X+0x%02X)", op_table->mnemonic, imm8); break; case EA_REL: - rel8 = fetch(); + rel8 = opcodes.r8(cpc++); util::stream_format(stream, "%s [0x%04X]", op_table->mnemonic, pc+2+rel8); break; case EA_DIRECT_IMM8: - imm8 = fetch(); - mask = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); util::stream_format(stream, "%s (0x%04X), 0x%02X", op_table->mnemonic, imm8, mask); break; case EA_IND_X_IMM8: - imm8 = fetch(); - mask = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); util::stream_format(stream, "%s (X+0x%02X), 0x%02X", op_table->mnemonic, imm8, mask); break; case EA_DIRECT_IMM8_REL: - imm8 = fetch(); - mask = fetch(); - rel8 = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); + rel8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (0x%04X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+4+rel8); break; case EA_IND_X_IMM8_REL: - imm8 = fetch(); - mask = fetch(); - rel8 = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); + rel8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (X+0x%02X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+4+rel8); break; case EA_IND_Y: - imm8 = fetch(); + imm8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (Y+0x%02X)", op_table->mnemonic, imm8); break; case EA_IND_Y_IMM8: - imm8 = fetch(); - mask = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); util::stream_format(stream, "%s (Y+0x%02X), 0x%02X", op_table->mnemonic, imm8, mask); break; case EA_IND_Y_IMM8_REL: - imm8 = fetch(); - mask = fetch(); - rel8 = fetch(); + imm8 = opcodes.r8(cpc++); + mask = opcodes.r8(cpc++); + rel8 = opcodes.r8(cpc++); util::stream_format(stream, "%s (Y+0x%02X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+2+rel8); break; case PAGE2: - op2 = fetch(); - return decode_opcode(stream, pc, &opcode_table_page2[op2]); + op2 = opcodes.r8(cpc++); + op_table = &opcode_table_page2[op2]; + goto loop; case PAGE3: - op2 = fetch(); - return decode_opcode(stream, pc, &opcode_table_page3[op2]); + op2 = opcodes.r8(cpc++); + op_table = &opcode_table_page3[op2]; + goto loop; case PAGE4: - op2 = fetch(); - return decode_opcode(stream, pc, &opcode_table_page4[op2]); + op2 = opcodes.r8(cpc++); + op_table = &opcode_table_page4[op2]; + goto loop; default: util::stream_format(stream, "%s", op_table->mnemonic); } - return flags; -} - -CPU_DISASSEMBLE(hc11) -{ - uint32_t flags; - uint8_t opcode; - - rombase = oprom; - - opcode = fetch(); - flags = decode_opcode(stream, pc, &opcode_table[opcode]); - return (rombase-oprom) | flags | DASMFLAG_SUPPORTED; + return (cpc - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/mc68hc11/hc11dasm.h b/src/devices/cpu/mc68hc11/hc11dasm.h new file mode 100644 index 00000000000..d1c606a964d --- /dev/null +++ b/src/devices/cpu/mc68hc11/hc11dasm.h @@ -0,0 +1,55 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde +/* + Motorola M68HC11 disassembler + + Written by Ville Linde +*/ + +#ifndef MAME_CPU_MC68HC11_HC11DASM_H +#define MAME_CPU_MC68HC11_HC11DASM_H + +#pragma once + +class hc11_disassembler : public util::disasm_interface +{ +public: + hc11_disassembler() = default; + virtual ~hc11_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum + { + EA_IMM8 = 1, + EA_IMM16, + EA_EXT, + EA_REL, + EA_DIRECT, + EA_DIRECT_IMM8, + EA_DIRECT_IMM8_REL, + EA_IND_X, + EA_IND_X_IMM8, + EA_IND_X_IMM8_REL, + EA_IND_Y, + EA_IND_Y_IMM8, + EA_IND_Y_IMM8_REL, + PAGE2, + PAGE3, + PAGE4 + }; + + struct M68HC11_OPCODE { + char mnemonic[32]; + int address_mode; + }; + + static const M68HC11_OPCODE opcode_table[256]; + static const M68HC11_OPCODE opcode_table_page2[256]; + static const M68HC11_OPCODE opcode_table_page3[256]; + static const M68HC11_OPCODE opcode_table_page4[256]; +}; + +#endif diff --git a/src/devices/cpu/mc68hc11/mc68hc11.cpp b/src/devices/cpu/mc68hc11/mc68hc11.cpp index 1ecd2793529..76d4ef56c56 100644 --- a/src/devices/cpu/mc68hc11/mc68hc11.cpp +++ b/src/devices/cpu/mc68hc11/mc68hc11.cpp @@ -16,6 +16,7 @@ TODO: #include "emu.h" #include "debugger.h" #include "mc68hc11.h" +#include "hc11dasm.h" enum { @@ -61,10 +62,9 @@ device_memory_interface::space_config_vector mc68hc11_cpu_device::memory_space_c }; } -offs_t mc68hc11_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mc68hc11_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( hc11 ); - return CPU_DISASSEMBLE_NAME(hc11)(this, stream, pc, oprom, opram, options); + return new hc11_disassembler; } @@ -397,7 +397,7 @@ void mc68hc11_cpu_device::device_start() m_internal_ram.resize(m_internal_ram_size); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_pc)); diff --git a/src/devices/cpu/mc68hc11/mc68hc11.h b/src/devices/cpu/mc68hc11/mc68hc11.h index e2a1f52f3d7..35b0cb98170 100644 --- a/src/devices/cpu/mc68hc11/mc68hc11.h +++ b/src/devices/cpu/mc68hc11/mc68hc11.h @@ -70,9 +70,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -102,7 +100,7 @@ private: int m_ad_channel; uint8_t m_irq_state[2]; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_program; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/mcs40/mcs40.cpp b/src/devices/cpu/mcs40/mcs40.cpp index 866587579d3..4b1cf6a8e2e 100644 --- a/src/devices/cpu/mcs40/mcs40.cpp +++ b/src/devices/cpu/mcs40/mcs40.cpp @@ -9,6 +9,7 @@ *****************************************************************************/ #include "emu.h" #include "mcs40.h" +#include "mcs40dasm.h" #include "debugger.h" @@ -85,7 +86,7 @@ mcs40_cpu_device_base::mcs40_cpu_device_base( device_type type, const char *tag, device_t *owner, - uint32_t clock, + u32 clock, bool extended_cm, unsigned rom_width, unsigned stack_ptr_mask, @@ -141,7 +142,7 @@ void mcs40_cpu_device_base::device_start() m_spaces[AS_RAM_STATUS] = &space(AS_RAM_STATUS); m_spaces[AS_RAM_PORTS] = &space(AS_RAM_PORTS); m_spaces[AS_PROGRAM_MEMORY] = &space(AS_PROGRAM_MEMORY); - m_direct = &m_spaces[AS_ROM]->direct(); + m_direct = m_spaces[AS_ROM]->direct<0>(); m_bus_cycle_cb.bind_relative_to(*owner()); m_sync_cb.resolve_safe(); @@ -416,21 +417,6 @@ void mcs40_cpu_device_base::state_string_export(device_state_entry const &entry, /*********************************************************************** - device_disasm_interface implementation -***********************************************************************/ - -u32 mcs40_cpu_device_base::disasm_min_opcode_bytes() const -{ - return 1U; -} - -u32 mcs40_cpu_device_base::disasm_max_opcode_bytes() const -{ - return 2U; -} - - -/*********************************************************************** register access ***********************************************************************/ @@ -842,7 +828,7 @@ inline void mcs40_cpu_device_base::update_4289_f_l(u8 val) -i4004_cpu_device::i4004_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) +i4004_cpu_device::i4004_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : mcs40_cpu_device_base(mconfig, I4004, tag, owner, clock, false, 12U, 0x3U, 16U, 0x7U) { } @@ -874,15 +860,9 @@ void i4004_cpu_device::execute_set_input(int inputnum, int state) device_disasm_interface implementation ***********************************************************************/ -offs_t i4004_cpu_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - uint8_t const *oprom, - uint8_t const *opram, - uint32_t options) +util::disasm_interface *i4004_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(i4004); - return CPU_DISASSEMBLE_NAME(i4004)(this, stream, pc, oprom, opram, options); + return new i4004_disassembler; } @@ -897,7 +877,7 @@ bool i4004_cpu_device::is_io_op(u8 opr) i4004_cpu_device::cycle i4004_cpu_device::do_cycle1(u8 opr, u8 opa, pmem &program_op) { - static constexpr uint8_t kbp_table[] = { 0x0, 0x1, 0x2, 0xf, 0x3, 0xf, 0xf, 0xf, 0x4, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf }; + static constexpr u8 kbp_table[] = { 0x0, 0x1, 0x2, 0xf, 0x3, 0xf, 0xf, 0xf, 0x4, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf }; switch (opr) { @@ -1158,7 +1138,7 @@ u8 i4004_cpu_device::do_io(u8 opr, u8 opa) -i4040_cpu_device::i4040_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) +i4040_cpu_device::i4040_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : i4004_cpu_device(mconfig, I4040, tag, owner, clock, true, 13U, 0x7U, 24U, 0xfU) { } @@ -1190,15 +1170,9 @@ void i4040_cpu_device::execute_set_input(int inputnum, int state) device_disasm_interface implementation ***********************************************************************/ -offs_t i4040_cpu_device::disasm_disassemble( - std::ostream &stream, - offs_t pc, - uint8_t const *oprom, - uint8_t const *opram, - uint32_t options) +util::disasm_interface *i4040_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(i4040); - return CPU_DISASSEMBLE_NAME(i4040)(this, stream, pc, oprom, opram, options); + return new i4040_disassembler; } diff --git a/src/devices/cpu/mcs40/mcs40.h b/src/devices/cpu/mcs40/mcs40.h index 42302263d50..3a7605fc366 100644 --- a/src/devices/cpu/mcs40/mcs40.h +++ b/src/devices/cpu/mcs40/mcs40.h @@ -178,7 +178,7 @@ protected: device_type type, char const *tag, device_t *owner, - uint32_t clock, + u32 clock, bool extended_cm, unsigned rom_width, unsigned stack_ptr_mask, @@ -200,10 +200,6 @@ protected: virtual void state_export(device_state_entry const &entry) override; virtual void state_string_export(device_state_entry const &entry, std::string &str) const override; - // device_disasm_interface implementation - virtual u32 disasm_min_opcode_bytes() const override; - virtual u32 disasm_max_opcode_bytes() const override; - // instruction execution virtual bool is_io_op(u8 opr) = 0; virtual cycle do_cycle1(u8 opr, u8 opa, pmem &program_op) = 0; @@ -295,7 +291,7 @@ private: // address spaces address_space_config const m_space_config[7]; address_space *m_spaces[7]; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; // bus snooping callback bus_cycle_delegate m_bus_cycle_cb; @@ -368,7 +364,7 @@ public: template <unsigned N, typename Obj> static devcb_base &set_cm_ram_cb(device_t &device, Obj &&cb) { return downcast<i4004_cpu_device &>(device).set_cm_ram_cb<N>(std::forward<Obj>(cb)); } - i4004_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + i4004_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); protected: using mcs40_cpu_device_base::mcs40_cpu_device_base; @@ -378,12 +374,7 @@ protected: virtual void execute_set_input(int inputnum, int state) override; // device_disasm_interface implementation - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - uint8_t const *oprom, - uint8_t const *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // mcs40_cpu_device_base implementation virtual bool is_io_op(u8 opr) override; @@ -413,16 +404,11 @@ public: template <typename Obj> static devcb_base &set_stp_ack_cb(device_t &device, Obj &&cb) { return downcast<i4040_cpu_device &>(device).set_stp_ack_cb(std::forward<Obj>(cb)); } - i4040_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock); + i4040_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); protected: // device_disasm_interface implementation - virtual offs_t disasm_disassemble( - std::ostream &stream, - offs_t pc, - uint8_t const *oprom, - uint8_t const *opram, - uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_execute_interface implementation virtual u32 execute_input_lines() const override; diff --git a/src/devices/cpu/mcs40/mcs40dasm.cpp b/src/devices/cpu/mcs40/mcs40dasm.cpp index 3ecf5712308..d0afd6e99a4 100644 --- a/src/devices/cpu/mcs40/mcs40dasm.cpp +++ b/src/devices/cpu/mcs40/mcs40dasm.cpp @@ -9,96 +9,69 @@ *****************************************************************************/ #include "emu.h" +#include "mcs40dasm.h" -namespace { - -enum class format -{ - ILL, - SIMPLE, - IMM4, - REG, - REGPAGE, - PAIR, - PAIRIMM, - ABS, - PAGE, - COND, - EXT -}; - -enum class level -{ - I4004, - I4040 -}; - -struct op -{ - format m_format; - level m_level; - char const *m_name; - op const *m_ext; -}; #define OP(fmt, lvl, name) { format::fmt, level::lvl, #name, nullptr } #define OPX(tbl) { format::EXT, level::I4004, nullptr, f_opx_##tbl } -op const f_opx_0[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_0[16] = { OP(SIMPLE, I4004, nop), OP(SIMPLE, I4040, hlt), OP(SIMPLE, I4040, bbs), OP(SIMPLE, I4040, lcr), OP(SIMPLE, I4040, or4), OP(SIMPLE, I4040, or5), OP(SIMPLE, I4040, an6), OP(SIMPLE, I4040, an7), OP(SIMPLE, I4040, db0), OP(SIMPLE, I4040, db1), OP(SIMPLE, I4040, sb0), OP(SIMPLE, I4040, sb1), OP(SIMPLE, I4040, ein), OP(SIMPLE, I4040, din), OP(SIMPLE, I4040, rpm), OP(ILL, I4004, ill) }; -op const f_opx_2[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_2[16] = { OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src), OP(PAIRIMM, I4004, fim), OP(PAIR, I4004, src) }; -op const f_opx_3[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_3[16] = { OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin), OP(PAIR, I4004, fin), OP(PAIR, I4004, jin) }; -op const f_opx_io[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_io[16] = { OP(SIMPLE, I4004, wrm), OP(SIMPLE, I4004, wmp), OP(SIMPLE, I4004, wrr), OP(SIMPLE, I4004, wpm), OP(SIMPLE, I4004, wr0), OP(SIMPLE, I4004, wr1), OP(SIMPLE, I4004, wr2), OP(SIMPLE, I4004, wr3), OP(SIMPLE, I4004, sbm), OP(SIMPLE, I4004, rdm), OP(SIMPLE, I4004, rdr), OP(SIMPLE, I4004, adm), OP(SIMPLE, I4004, rd0), OP(SIMPLE, I4004, rd1), OP(SIMPLE, I4004, rd2), OP(SIMPLE, I4004, rd3) }; -op const f_opx_f[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_opx_f[16] = { OP(SIMPLE, I4004, clb), OP(SIMPLE, I4004, clc), OP(SIMPLE, I4004, iac), OP(SIMPLE, I4004, cmc), OP(SIMPLE, I4004, cma), OP(SIMPLE, I4004, ral), OP(SIMPLE, I4004, rar), OP(SIMPLE, I4004, tcc), OP(SIMPLE, I4004, dac), OP(SIMPLE, I4004, tcs), OP(SIMPLE, I4004, stc), OP(SIMPLE, I4004, daa), OP(SIMPLE, I4004, kbp), OP(SIMPLE, I4004, dcl), OP(ILL, I4004, ill), OP(ILL, I4004, ill) }; -op const f_ops[16] = { +mcs40_disassembler::op const mcs40_disassembler::f_ops[16] = { OPX(0), OP(COND, I4004, jcn), OPX(2), OPX(3), OP(ABS, I4004, jun), OP(ABS, I4004, jms), OP(REG, I4004, inc), OP(REGPAGE, I4004, isz), OP(REG, I4004, add), OP(REG, I4004, sub), OP(REG, I4004, ld ), OP(REG, I4004, xch), OP(IMM4, I4004, bbl), OP(IMM4, I4004, ldm), OPX(io), OPX(f) }; -char const *const f_cond[16] = { +char const *const mcs40_disassembler::f_cond[16] = { "$0", "nt", "c", "$3", "z", "$5", "$6", "$7", "$8", "t", "nc", "$b", "nz", "$d", "$e", "$f" }; -offs_t disassemble( - cpu_device *device, - std::ostream &stream, - offs_t pc, - u8 const *oprom, - u8 const *opram, - int options, - level lvl, - unsigned pcmask) +u32 mcs40_disassembler::opcode_alignment() const +{ + return 1; +} + +mcs40_disassembler::mcs40_disassembler(level lvl, unsigned pcmask) : m_lvl(lvl), m_pcmask(pcmask) +{ + (void)m_pcmask; +} + +offs_t mcs40_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { offs_t npc(pc + 1); - u8 const opcode(oprom[0]); + u8 const opcode(opcodes.r8(pc)); op const &base_op(f_ops[(opcode >> 4) & 0x0f]); op const &ext_op((base_op.m_format == format::EXT) ? base_op.m_ext[opcode & 0x0f] : base_op); - op const desc((ext_op.m_level > lvl) ? f_opx_f[0x0f] : ext_op); + op const desc((ext_op.m_level > m_lvl) ? f_opx_f[0x0f] : ext_op); u8 const imm4(opcode & 0x0f); u8 const pair(opcode & 0x0e); @@ -118,26 +91,26 @@ offs_t disassemble( break; case format::REGPAGE: npc++; - util::stream_format(stream, "%-3s r%01x,$%03x", desc.m_name, imm4, oprom[1] | (npc & 0x0f00U)); + util::stream_format(stream, "%-3s r%01x,$%03x", desc.m_name, imm4, opcodes.r8(pc+1) | (npc & 0x0f00U)); break; case format::PAIR: util::stream_format(stream, "%-3s r%01xr%01x", desc.m_name, pair, pair + 1U); break; case format::PAIRIMM: npc++; - util::stream_format(stream, "%-3s r%01xr%01x,$%02x", desc.m_name, pair, pair + 1, oprom[1]); + util::stream_format(stream, "%-3s r%01xr%01x,$%02x", desc.m_name, pair, pair + 1, opcodes.r8(pc+1)); break; case format::ABS: npc++; - util::stream_format(stream, "%-3s $%03x", desc.m_name, ((u16(opcode) & 0x0fU) << 8) | oprom[1]); + util::stream_format(stream, "%-3s $%03x", desc.m_name, ((u16(opcode) & 0x0fU) << 8) | opcodes.r8(pc+1)); break; case format::PAGE: npc++; - util::stream_format(stream, "%-3s $%03x", desc.m_name, oprom[1] | (npc & 0x0f00U)); + util::stream_format(stream, "%-3s $%03x", desc.m_name, opcodes.r8(pc+1) | (npc & 0x0f00U)); break; case format::COND: npc++; - util::stream_format(stream, "%-3s %s,$%03x", desc.m_name, f_cond[imm4], oprom[1] | (npc & 0x0f00U)); + util::stream_format(stream, "%-3s %s,$%03x", desc.m_name, f_cond[imm4], opcodes.r8(pc+1) | (npc & 0x0f00U)); break; default: throw false; @@ -147,16 +120,19 @@ offs_t disassemble( if (format::ILL != desc.m_format) { if (0x50U == (opcode & 0xf0U)) // JMS - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if ((0xc0 == (opcode & 0xf0)) || (0x02 == opcode)) // BBL/BBS - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } - return (npc - pc) | flags | DASMFLAG_SUPPORTED; + return (npc - pc) | flags | SUPPORTED; } -} // anonymous namespace +i4004_disassembler::i4004_disassembler() : mcs40_disassembler(level::I4004, 0x0fffU) +{ +} -CPU_DISASSEMBLE(i4004) { return disassemble(device, stream, pc, oprom, opram, options, level::I4004, 0x0fffU); } -CPU_DISASSEMBLE(i4040) { return disassemble(device, stream, pc, oprom, opram, options, level::I4040, 0x1fffU); } +i4040_disassembler::i4040_disassembler() : mcs40_disassembler(level::I4040, 0x1fffU) +{ +} diff --git a/src/devices/cpu/mcs40/mcs40dasm.h b/src/devices/cpu/mcs40/mcs40dasm.h new file mode 100644 index 00000000000..c7124f2beee --- /dev/null +++ b/src/devices/cpu/mcs40/mcs40dasm.h @@ -0,0 +1,84 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/***************************************************************************** + * + * 4004dasm.cpp + * + * Intel MCS-40 CPU Disassembly + * + *****************************************************************************/ + +#ifndef MAME_CPU_MCS40_MCS40DASM_H +#define MAME_CPU_MCS40_MCS40DASM_H + +#pragma once + +class mcs40_disassembler : public util::disasm_interface +{ +public: + enum class level + { + I4004, + I4040 + }; + + mcs40_disassembler(level lvl, unsigned pcmask); + virtual ~mcs40_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + virtual u32 interface_flags() const override { return PAGED; } + virtual u32 page_address_bits() const override { return 12; } + +private: + enum class format + { + ILL, + SIMPLE, + IMM4, + REG, + REGPAGE, + PAIR, + PAIRIMM, + ABS, + PAGE, + COND, + EXT + }; + + struct op + { + format m_format; + level m_level; + char const *m_name; + op const *m_ext; + }; + + static op const f_opx_0[16]; + static op const f_opx_2[16]; + static op const f_opx_3[16]; + static op const f_opx_io[16]; + static op const f_opx_f[16]; + static op const f_ops[16]; + static char const *const f_cond[16]; + + level m_lvl; + unsigned m_pcmask; +}; + +class i4004_disassembler : public mcs40_disassembler +{ +public: + i4004_disassembler(); + virtual ~i4004_disassembler() = default; +}; + +class i4040_disassembler : public mcs40_disassembler +{ +public: + i4040_disassembler(); + virtual ~i4040_disassembler() = default; +}; + +#endif diff --git a/src/devices/cpu/mcs48/mcs48.cpp b/src/devices/cpu/mcs48/mcs48.cpp index eba06d7a156..de499c23ac2 100644 --- a/src/devices/cpu/mcs48/mcs48.cpp +++ b/src/devices/cpu/mcs48/mcs48.cpp @@ -8,12 +8,12 @@ - T0 output clock - get rid of i/o addressmap, use devcb for mcu pins - add CMOS devices, 1 new opcode (01 HALT) - - make timer update cleaner: - timer is updated on S4 while I/O happens on S5 - due to very bad coding, Kaypro 10 keyboard depends on being able to see T=0 before interrupt is taken - right now this is implemented with a hack in the mov_a_t handler - in theory it should also be possible to see the timer flag before the interrupt is taken - mov_t_a should also update the T register after it's incremented + - make timer update cleaner: + timer is updated on S4 while I/O happens on S5 + due to very bad coding, Kaypro 10 keyboard depends on being able to see T=0 before interrupt is taken + right now this is implemented with a hack in the mov_a_t handler + in theory it should also be possible to see the timer flag before the interrupt is taken + mov_t_a should also update the T register after it's incremented */ /*************************************************************************** @@ -85,6 +85,7 @@ #include "emu.h" #include "debugger.h" #include "mcs48.h" +#include "mcs48dsm.h" /*************************************************************************** @@ -329,17 +330,14 @@ device_memory_interface::space_config_vector mcs48_cpu_device::memory_space_conf }; } -offs_t mcs48_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mcs48_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( mcs48 ); - return CPU_DISASSEMBLE_NAME(mcs48)(this, stream, pc, oprom, opram, options); + return new mcs48_disassembler(false); } - -offs_t upi41_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upi41_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( upi41 ); - return CPU_DISASSEMBLE_NAME(upi41)(this, stream, pc, oprom, opram, options); + return new mcs48_disassembler(true); } /*************************************************************************** @@ -975,7 +973,7 @@ void mcs48_cpu_device::device_start() m_ea = (m_int_rom_size ? 0 : 1); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); diff --git a/src/devices/cpu/mcs48/mcs48.h b/src/devices/cpu/mcs48/mcs48.h index 210d2b84d3c..e0609621559 100644 --- a/src/devices/cpu/mcs48/mcs48.h +++ b/src/devices/cpu/mcs48/mcs48.h @@ -180,9 +180,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; protected: address_space_config m_program_config; @@ -230,7 +228,7 @@ protected: /* Memory spaces */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; address_space *m_io; @@ -243,11 +241,11 @@ protected: static const mcs48_ophandler s_opcode_table[256]; /* ROM is mapped to AS_PROGRAM */ - uint8_t program_r(offs_t a) { return m_program->read_byte(a); } + uint8_t program_r(offs_t a) { return m_program->read_byte(a); } /* RAM is mapped to AS_DATA */ - uint8_t ram_r(offs_t a) { return m_data->read_byte(a); } - void ram_w(offs_t a, uint8_t v) { m_data->write_byte(a, v); } + uint8_t ram_r(offs_t a) { return m_data->read_byte(a); } + void ram_w(offs_t a, uint8_t v) { m_data->write_byte(a, v); } /* ports are mapped to AS_IO and callbacks */ uint8_t ext_r(offs_t a) { return m_io->read_byte(a); } @@ -650,7 +648,7 @@ protected: // construction/destruction upi41_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int rom_size, int ram_size); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; TIMER_CALLBACK_MEMBER( master_callback ); }; diff --git a/src/devices/cpu/mcs48/mcs48dsm.cpp b/src/devices/cpu/mcs48/mcs48dsm.cpp index 08afa12f6b3..e265e83534e 100644 --- a/src/devices/cpu/mcs48/mcs48dsm.cpp +++ b/src/devices/cpu/mcs48/mcs48dsm.cpp @@ -10,27 +10,35 @@ ***************************************************************************/ #include "emu.h" +#include "mcs48dsm.h" +mcs48_disassembler::mcs48_disassembler(bool upi41) : m_upi41(upi41) +{ +} -static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, bool upi41) +u32 mcs48_disassembler::opcode_alignment() const { - const uint8_t *startram = opram; - uint32_t flags = 0; + return 1; +} - opram++; - switch (*oprom++) +offs_t mcs48_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + offs_t cpc = pc; + offs_t flags = 0; + + switch (opcodes.r8(cpc++)) { case 0x00: util::stream_format(stream, "nop"); break; - case 0x02: if (!upi41) + case 0x02: if (!m_upi41) util::stream_format(stream, "out bus,a"); else util::stream_format(stream, "out dbb,a"); break; - case 0x03: util::stream_format(stream, "add a,#$%02X", *opram++); break; - case 0x04: util::stream_format(stream, "jmp $0%02X", *opram++); break; + case 0x03: util::stream_format(stream, "add a,#$%02X", params.r8(cpc++)); break; + case 0x04: util::stream_format(stream, "jmp $0%02X", params.r8(cpc++)); break; case 0x05: util::stream_format(stream, "en i"); break; case 0x07: util::stream_format(stream, "dec a"); break; - case 0x08: if (!upi41) + case 0x08: if (!m_upi41) util::stream_format(stream, "in a,bus"); else util::stream_format(stream, "illegal"); @@ -43,11 +51,11 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x0f: util::stream_format(stream, "movd a,p7"); break; case 0x10: util::stream_format(stream, "inc @r0"); break; case 0x11: util::stream_format(stream, "inc @r1"); break; - case 0x12: util::stream_format(stream, "jb0 $%03X", (pc & 0xf00) | *opram++); break; - case 0x13: util::stream_format(stream, "addc a,#$%02X", *opram++); break; - case 0x14: util::stream_format(stream, "call $0%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0x12: util::stream_format(stream, "jb0 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x13: util::stream_format(stream, "addc a,#$%02X", params.r8(cpc++)); break; + case 0x14: util::stream_format(stream, "call $0%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0x15: util::stream_format(stream, "dis i"); break; - case 0x16: util::stream_format(stream, "jtf $%03X", (pc & 0xf00) | *opram++); break; + case 0x16: util::stream_format(stream, "jtf $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x17: util::stream_format(stream, "inc a"); break; case 0x18: util::stream_format(stream, "inc r0"); break; case 0x19: util::stream_format(stream, "inc r1"); break; @@ -59,15 +67,15 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x1f: util::stream_format(stream, "inc r7"); break; case 0x20: util::stream_format(stream, "xch a,@r0"); break; case 0x21: util::stream_format(stream, "xch a,@r1"); break; - case 0x22: if (!upi41) + case 0x22: if (!m_upi41) util::stream_format(stream, "illegal"); else util::stream_format(stream, "in a,dbb"); break; - case 0x23: util::stream_format(stream, "mov a,#$%02X", *opram++); break; - case 0x24: util::stream_format(stream, "jmp $1%02X", *opram++); break; + case 0x23: util::stream_format(stream, "mov a,#$%02X", params.r8(cpc++)); break; + case 0x24: util::stream_format(stream, "jmp $1%02X", params.r8(cpc++)); break; case 0x25: util::stream_format(stream, "en tcnti"); break; - case 0x26: util::stream_format(stream, "jnt0 $%03X", (pc & 0xf00) | *opram++); break; + case 0x26: util::stream_format(stream, "jnt0 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x27: util::stream_format(stream, "clr a"); break; case 0x28: util::stream_format(stream, "xch a,r0"); break; case 0x29: util::stream_format(stream, "xch a,r1"); break; @@ -79,10 +87,10 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x2f: util::stream_format(stream, "xch a,r7"); break; case 0x30: util::stream_format(stream, "xchd a,@r0"); break; case 0x31: util::stream_format(stream, "xchd a,@r1"); break; - case 0x32: util::stream_format(stream, "jb1 $%03X", (pc & 0xf00) | *opram++); break; - case 0x34: util::stream_format(stream, "call $1%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0x32: util::stream_format(stream, "jb1 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x34: util::stream_format(stream, "call $1%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0x35: util::stream_format(stream, "dis tcnti"); break; - case 0x36: util::stream_format(stream, "jt0 $%03X", (pc & 0xf00) | *opram++); break; + case 0x36: util::stream_format(stream, "jt0 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x37: util::stream_format(stream, "cpl a"); break; case 0x39: util::stream_format(stream, "outl p1,a"); break; case 0x3a: util::stream_format(stream, "outl p2,a"); break; @@ -93,10 +101,10 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x40: util::stream_format(stream, "orl a,@r0"); break; case 0x41: util::stream_format(stream, "orl a,@r1"); break; case 0x42: util::stream_format(stream, "mov a,t"); break; - case 0x43: util::stream_format(stream, "orl a,#$%02X", *opram++); break; - case 0x44: util::stream_format(stream, "jmp $2%02X", *opram++); break; + case 0x43: util::stream_format(stream, "orl a,#$%02X", params.r8(cpc++)); break; + case 0x44: util::stream_format(stream, "jmp $2%02X", params.r8(cpc++)); break; case 0x45: util::stream_format(stream, "strt cnt"); break; - case 0x46: util::stream_format(stream, "jnt1 $%03X", (pc & 0xf00) | *opram++); break; + case 0x46: util::stream_format(stream, "jnt1 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x47: util::stream_format(stream, "swap a"); break; case 0x48: util::stream_format(stream, "orl a,r0"); break; case 0x49: util::stream_format(stream, "orl a,r1"); break; @@ -108,11 +116,11 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x4f: util::stream_format(stream, "orl a,r7"); break; case 0x50: util::stream_format(stream, "anl a,@r0"); break; case 0x51: util::stream_format(stream, "anl a,@r1"); break; - case 0x52: util::stream_format(stream, "jb2 $%03X", (pc & 0xf00) | *opram++); break; - case 0x53: util::stream_format(stream, "anl a,#$%02X", *opram++); break; - case 0x54: util::stream_format(stream, "call $2%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0x52: util::stream_format(stream, "jb2 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x53: util::stream_format(stream, "anl a,#$%02X", params.r8(cpc++)); break; + case 0x54: util::stream_format(stream, "call $2%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0x55: util::stream_format(stream, "strt t"); break; - case 0x56: util::stream_format(stream, "jt1 $%03X", (pc & 0xf00) | *opram++); break; + case 0x56: util::stream_format(stream, "jt1 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x57: util::stream_format(stream, "da a"); break; case 0x58: util::stream_format(stream, "anl a,r0"); break; case 0x59: util::stream_format(stream, "anl a,r1"); break; @@ -125,7 +133,7 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x60: util::stream_format(stream, "add a,@r0"); break; case 0x61: util::stream_format(stream, "add a,@r1"); break; case 0x62: util::stream_format(stream, "mov t,a"); break; - case 0x64: util::stream_format(stream, "jmp $3%02X", *opram++); break; + case 0x64: util::stream_format(stream, "jmp $3%02X", params.r8(cpc++)); break; case 0x65: util::stream_format(stream, "stop tcnt"); break; case 0x67: util::stream_format(stream, "rrc a"); break; case 0x68: util::stream_format(stream, "add a,r0"); break; @@ -138,14 +146,14 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x6f: util::stream_format(stream, "add a,r7"); break; case 0x70: util::stream_format(stream, "addc a,@r0"); break; case 0x71: util::stream_format(stream, "addc a,@r1"); break; - case 0x72: util::stream_format(stream, "jb3 $%03X", (pc & 0xf00) | *opram++); break; - case 0x74: util::stream_format(stream, "call $3%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0x75: if (!upi41) + case 0x72: util::stream_format(stream, "jb3 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x74: util::stream_format(stream, "call $3%02X", params.r8(cpc++)); flags = STEP_OVER; break; + case 0x75: if (!m_upi41) util::stream_format(stream, "ent0 clk"); else util::stream_format(stream, "illegal"); break; - case 0x76: util::stream_format(stream, "jf1 $%03X", (pc & 0xf00) | *opram++); break; + case 0x76: util::stream_format(stream, "jf1 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x77: util::stream_format(stream, "rr a"); break; case 0x78: util::stream_format(stream, "addc a,r0"); break; case 0x79: util::stream_format(stream, "addc a,r1"); break; @@ -155,58 +163,58 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0x7d: util::stream_format(stream, "addc a,r5"); break; case 0x7e: util::stream_format(stream, "addc a,r6"); break; case 0x7f: util::stream_format(stream, "addc a,r7"); break; - case 0x80: if (!upi41) + case 0x80: if (!m_upi41) util::stream_format(stream, "movx a,@r0"); else util::stream_format(stream, "illegal"); break; - case 0x81: if (!upi41) + case 0x81: if (!m_upi41) util::stream_format(stream, "movx a,@r1"); else util::stream_format(stream, "illegal"); break; - case 0x83: util::stream_format(stream, "ret"); flags = DASMFLAG_STEP_OUT; break; - case 0x84: util::stream_format(stream, "jmp $4%02X", *opram++); break; + case 0x83: util::stream_format(stream, "ret"); flags = STEP_OUT; break; + case 0x84: util::stream_format(stream, "jmp $4%02X", params.r8(cpc++)); break; case 0x85: util::stream_format(stream, "clr f0"); break; - case 0x86: if (!upi41) - util::stream_format(stream, "jni $%03X", (pc & 0xf00) | *opram++); + case 0x86: if (!m_upi41) + util::stream_format(stream, "jni $%03X", (pc & 0xf00) | params.r8(cpc++)); else - util::stream_format(stream, "jobf $%03X", (pc & 0xf00) | *opram++); + util::stream_format(stream, "jobf $%03X", (pc & 0xf00) | params.r8(cpc++)); break; - case 0x88: if (!upi41) - util::stream_format(stream, "orl bus,#$%02X", *opram++); + case 0x88: if (!m_upi41) + util::stream_format(stream, "orl bus,#$%02X", params.r8(cpc++)); else util::stream_format(stream, "illegal"); break; - case 0x89: util::stream_format(stream, "orl p1,#$%02X", *opram++); break; - case 0x8a: util::stream_format(stream, "orl p2,#$%02X", *opram++); break; + case 0x89: util::stream_format(stream, "orl p1,#$%02X", params.r8(cpc++)); break; + case 0x8a: util::stream_format(stream, "orl p2,#$%02X", params.r8(cpc++)); break; case 0x8c: util::stream_format(stream, "orld p4,a"); break; case 0x8d: util::stream_format(stream, "orld p5,a"); break; case 0x8e: util::stream_format(stream, "orld p6,a"); break; case 0x8f: util::stream_format(stream, "orld p7,a"); break; - case 0x90: if (!upi41) + case 0x90: if (!m_upi41) util::stream_format(stream, "movx @r0,a"); else util::stream_format(stream, "mov sts,a"); break; - case 0x91: if (!upi41) + case 0x91: if (!m_upi41) util::stream_format(stream, "movx @r1,a"); else util::stream_format(stream, "illegal"); break; - case 0x92: util::stream_format(stream, "jb4 $%03X", (pc & 0xf00) | *opram++); break; - case 0x93: util::stream_format(stream, "retr"); flags = DASMFLAG_STEP_OUT; break; - case 0x94: util::stream_format(stream, "call $4%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0x92: util::stream_format(stream, "jb4 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0x93: util::stream_format(stream, "retr"); flags = STEP_OUT; break; + case 0x94: util::stream_format(stream, "call $4%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0x95: util::stream_format(stream, "cpl f0"); break; - case 0x96: util::stream_format(stream, "jnz $%03X", (pc & 0xf00) | *opram++); break; + case 0x96: util::stream_format(stream, "jnz $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0x97: util::stream_format(stream, "clr c"); break; - case 0x98: if (!upi41) - util::stream_format(stream, "anl bus,#$%02X", *opram++); + case 0x98: if (!m_upi41) + util::stream_format(stream, "anl bus,#$%02X", params.r8(cpc++)); else util::stream_format(stream, "illegal"); break; - case 0x99: util::stream_format(stream, "anl p1,#$%02X", *opram++); break; - case 0x9a: util::stream_format(stream, "anl p2,#$%02X", *opram++); break; + case 0x99: util::stream_format(stream, "anl p1,#$%02X", params.r8(cpc++)); break; + case 0x9a: util::stream_format(stream, "anl p2,#$%02X", params.r8(cpc++)); break; case 0x9c: util::stream_format(stream, "anld p4,a"); break; case 0x9d: util::stream_format(stream, "anld p5,a"); break; case 0x9e: util::stream_format(stream, "anld p6,a"); break; @@ -214,7 +222,7 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0xa0: util::stream_format(stream, "mov @r0,a"); break; case 0xa1: util::stream_format(stream, "mov @r1,a"); break; case 0xa3: util::stream_format(stream, "movp a,@a"); break; - case 0xa4: util::stream_format(stream, "jmp $5%02X", *opram++); break; + case 0xa4: util::stream_format(stream, "jmp $5%02X", params.r8(cpc++)); break; case 0xa5: util::stream_format(stream, "clr f1"); break; case 0xa7: util::stream_format(stream, "cpl c"); break; case 0xa8: util::stream_format(stream, "mov r0,a"); break; @@ -225,24 +233,24 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0xad: util::stream_format(stream, "mov r5,a"); break; case 0xae: util::stream_format(stream, "mov r6,a"); break; case 0xaf: util::stream_format(stream, "mov r7,a"); break; - case 0xb0: util::stream_format(stream, "mov @r0,#$%02X", *opram++); break; - case 0xb1: util::stream_format(stream, "mov @r1,#$%02X", *opram++); break; - case 0xb2: util::stream_format(stream, "jb5 $%03X", (pc & 0xf00) | *opram++); break; + case 0xb0: util::stream_format(stream, "mov @r0,#$%02X", params.r8(cpc++)); break; + case 0xb1: util::stream_format(stream, "mov @r1,#$%02X", params.r8(cpc++)); break; + case 0xb2: util::stream_format(stream, "jb5 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xb3: util::stream_format(stream, "jmpp @a"); break; - case 0xb4: util::stream_format(stream, "call $5%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0xb4: util::stream_format(stream, "call $5%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0xb5: util::stream_format(stream, "cpl f1"); break; - case 0xb6: util::stream_format(stream, "jf0 $%03X", (pc & 0xf00) | *opram++); break; - case 0xb8: util::stream_format(stream, "mov r0,#$%02X", *opram++); break; - case 0xb9: util::stream_format(stream, "mov r1,#$%02X", *opram++); break; - case 0xba: util::stream_format(stream, "mov r2,#$%02X", *opram++); break; - case 0xbb: util::stream_format(stream, "mov r3,#$%02X", *opram++); break; - case 0xbc: util::stream_format(stream, "mov r4,#$%02X", *opram++); break; - case 0xbd: util::stream_format(stream, "mov r5,#$%02X", *opram++); break; - case 0xbe: util::stream_format(stream, "mov r6,#$%02X", *opram++); break; - case 0xbf: util::stream_format(stream, "mov r7,#$%02X", *opram++); break; - case 0xc4: util::stream_format(stream, "jmp $6%02X", *opram++); break; + case 0xb6: util::stream_format(stream, "jf0 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0xb8: util::stream_format(stream, "mov r0,#$%02X", params.r8(cpc++)); break; + case 0xb9: util::stream_format(stream, "mov r1,#$%02X", params.r8(cpc++)); break; + case 0xba: util::stream_format(stream, "mov r2,#$%02X", params.r8(cpc++)); break; + case 0xbb: util::stream_format(stream, "mov r3,#$%02X", params.r8(cpc++)); break; + case 0xbc: util::stream_format(stream, "mov r4,#$%02X", params.r8(cpc++)); break; + case 0xbd: util::stream_format(stream, "mov r5,#$%02X", params.r8(cpc++)); break; + case 0xbe: util::stream_format(stream, "mov r6,#$%02X", params.r8(cpc++)); break; + case 0xbf: util::stream_format(stream, "mov r7,#$%02X", params.r8(cpc++)); break; + case 0xc4: util::stream_format(stream, "jmp $6%02X", params.r8(cpc++)); break; case 0xc5: util::stream_format(stream, "sel rb0"); break; - case 0xc6: util::stream_format(stream, "jz $%03X", (pc & 0xf00) | *opram++); break; + case 0xc6: util::stream_format(stream, "jz $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xc7: util::stream_format(stream, "mov a,psw"); break; case 0xc8: util::stream_format(stream, "dec r0"); break; case 0xc9: util::stream_format(stream, "dec r1"); break; @@ -254,14 +262,14 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0xcf: util::stream_format(stream, "dec r7"); break; case 0xd0: util::stream_format(stream, "xrl a,@r0"); break; case 0xd1: util::stream_format(stream, "xrl a,@r1"); break; - case 0xd2: util::stream_format(stream, "jb6 $%03X", (pc & 0xf00) | *opram++); break; - case 0xd3: util::stream_format(stream, "xrl a,#$%02X", *opram++); break; - case 0xd4: util::stream_format(stream, "call $6%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0xd2: util::stream_format(stream, "jb6 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0xd3: util::stream_format(stream, "xrl a,#$%02X", params.r8(cpc++)); break; + case 0xd4: util::stream_format(stream, "call $6%02X", params.r8(cpc++)); flags = STEP_OVER; break; case 0xd5: util::stream_format(stream, "sel rb1"); break; - case 0xd6: if (!upi41) + case 0xd6: if (!m_upi41) util::stream_format(stream, "illegal"); else - util::stream_format(stream, "jnibf $%03X", (pc & 0xf00) | *opram++); + util::stream_format(stream, "jnibf $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xd7: util::stream_format(stream, "mov psw,a"); break; case 0xd8: util::stream_format(stream, "xrl a,r0"); break; @@ -273,32 +281,32 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c case 0xde: util::stream_format(stream, "xrl a,r6"); break; case 0xdf: util::stream_format(stream, "xrl a,r7"); break; case 0xe3: util::stream_format(stream, "movp3 a,@a"); break; - case 0xe4: util::stream_format(stream, "jmp $7%02X", *opram++); break; - case 0xe5: if (!upi41) + case 0xe4: util::stream_format(stream, "jmp $7%02X", params.r8(cpc++)); break; + case 0xe5: if (!m_upi41) util::stream_format(stream, "sel mb0"); else util::stream_format(stream, "en dma"); break; - case 0xe6: util::stream_format(stream, "jnc $%03X", (pc & 0xf00) | *opram++); break; + case 0xe6: util::stream_format(stream, "jnc $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xe7: util::stream_format(stream, "rl a"); break; - case 0xe8: util::stream_format(stream, "djnz r0,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xe9: util::stream_format(stream, "djnz r1,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xea: util::stream_format(stream, "djnz r2,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xeb: util::stream_format(stream, "djnz r3,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xec: util::stream_format(stream, "djnz r4,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xed: util::stream_format(stream, "djnz r5,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xee: util::stream_format(stream, "djnz r6,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xef: util::stream_format(stream, "djnz r7,$%03X", (pc & 0xf00) | *opram++); flags = DASMFLAG_STEP_OVER; break; + case 0xe8: util::stream_format(stream, "djnz r0,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xe9: util::stream_format(stream, "djnz r1,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xea: util::stream_format(stream, "djnz r2,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xeb: util::stream_format(stream, "djnz r3,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xec: util::stream_format(stream, "djnz r4,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xed: util::stream_format(stream, "djnz r5,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xee: util::stream_format(stream, "djnz r6,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; + case 0xef: util::stream_format(stream, "djnz r7,$%03X", (pc & 0xf00) | params.r8(cpc++)); flags = STEP_OVER; break; case 0xf0: util::stream_format(stream, "mov a,@r0"); break; case 0xf1: util::stream_format(stream, "mov a,@r1"); break; - case 0xf2: util::stream_format(stream, "jb7 $%03X", (pc & 0xf00) | *opram++); break; - case 0xf4: util::stream_format(stream, "call $7%02X", *opram++); flags = DASMFLAG_STEP_OVER; break; - case 0xf5: if (!upi41) + case 0xf2: util::stream_format(stream, "jb7 $%03X", (pc & 0xf00) | params.r8(cpc++)); break; + case 0xf4: util::stream_format(stream, "call $7%02X", params.r8(cpc++)); flags = STEP_OVER; break; + case 0xf5: if (!m_upi41) util::stream_format(stream, "sel mb1"); else util::stream_format(stream, "en flags"); break; - case 0xf6: util::stream_format(stream, "jc $%03X", (pc & 0xf00) | *opram++); break; + case 0xf6: util::stream_format(stream, "jc $%03X", (pc & 0xf00) | params.r8(cpc++)); break; case 0xf7: util::stream_format(stream, "rlc a"); break; case 0xf8: util::stream_format(stream, "mov a,r0"); break; case 0xf9: util::stream_format(stream, "mov a,r1"); break; @@ -311,17 +319,5 @@ static uint32_t common_dasm(device_t *device, std::ostream &stream, offs_t pc, c default: util::stream_format(stream, "illegal"); break; } - return (opram - startram) | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( mcs48 ) -{ - return common_dasm(device, stream, pc, oprom, opram, false); -} - - -CPU_DISASSEMBLE( upi41 ) -{ - return common_dasm(device, stream, pc, oprom, opram, true); + return (cpc - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/mcs48/mcs48dsm.h b/src/devices/cpu/mcs48/mcs48dsm.h new file mode 100644 index 00000000000..c4c7dde9a9c --- /dev/null +++ b/src/devices/cpu/mcs48/mcs48dsm.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + mcs48dsm.c + + Simple MCS-48/UPI-41 disassembler. + Written by Aaron Giles + +***************************************************************************/ + + +#ifndef MAME_CPU_MCS48_MCS48DASM_H +#define MAME_CPU_MCS48_MCS48DASM_H + +#pragma once + +class mcs48_disassembler : public util::disasm_interface +{ +public: + mcs48_disassembler(bool upi41); + virtual ~mcs48_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + bool m_upi41; +}; + +#endif diff --git a/src/devices/cpu/mcs51/mcs51.cpp b/src/devices/cpu/mcs51/mcs51.cpp index 1c682e06e0e..536565bbbe7 100644 --- a/src/devices/cpu/mcs51/mcs51.cpp +++ b/src/devices/cpu/mcs51/mcs51.cpp @@ -130,6 +130,7 @@ #include "emu.h" #include "debugger.h" #include "mcs51.h" +#include "mcs51dasm.h" #define VERBOSE 0 @@ -2101,7 +2102,7 @@ uint8_t mcs51_cpu_device::sfr_read(size_t offset) void mcs51_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); @@ -2506,45 +2507,32 @@ void ds5002fp_device::nvram_write( emu_file &file ) file.write( m_sfr_ram, 0x80 ); } - - -offs_t mcs51_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mcs51_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( i8051 ); - return CPU_DISASSEMBLE_NAME(i8051)(this, stream, pc, oprom, opram, options); + return new i8051_disassembler; } - -offs_t i8052_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8052_device::create_disassembler() { - extern CPU_DISASSEMBLE( i8052 ); - return CPU_DISASSEMBLE_NAME(i8052)(this, stream, pc, oprom, opram, options); + return new i8052_disassembler; } - -offs_t i80c31_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i80c31_device::create_disassembler() { - extern CPU_DISASSEMBLE( i80c51 ); - return CPU_DISASSEMBLE_NAME(i80c51)(this, stream, pc, oprom, opram, options); + return new i80c51_disassembler; } - -offs_t i80c51_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i80c51_device::create_disassembler() { - extern CPU_DISASSEMBLE( i80c51 ); - return CPU_DISASSEMBLE_NAME(i80c51)(this, stream, pc, oprom, opram, options); + return new i80c51_disassembler; } - -offs_t i80c52_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i80c52_device::create_disassembler() { - extern CPU_DISASSEMBLE( i80c52 ); - return CPU_DISASSEMBLE_NAME(i80c52)(this, stream, pc, oprom, opram, options); + return new i80c52_disassembler; } - -offs_t ds5002fp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ds5002fp_device::create_disassembler() { - extern CPU_DISASSEMBLE( ds5002fp ); - return CPU_DISASSEMBLE_NAME(ds5002fp)(this, stream, pc, oprom, opram, options); + return new ds5002fp_disassembler; } diff --git a/src/devices/cpu/mcs51/mcs51.h b/src/devices/cpu/mcs51/mcs51.h index 13f19d3fd28..f324e428ad5 100644 --- a/src/devices/cpu/mcs51/mcs51.h +++ b/src/devices/cpu/mcs51/mcs51.h @@ -115,9 +115,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; protected: address_space_config m_program_config; @@ -168,7 +166,7 @@ protected: /* Memory spaces */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; address_space *m_io; @@ -390,7 +388,7 @@ public: protected: i8052_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features = 0); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; /* SFR Callbacks */ virtual void sfr_write(size_t offset, uint8_t data) override; @@ -418,7 +416,7 @@ public: i80c31_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; @@ -431,7 +429,7 @@ public: protected: i80c51_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features = 0); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; class i87c51_device : public i80c51_device @@ -451,7 +449,7 @@ public: protected: i80c52_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int program_width, int data_width, uint8_t features = 0); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; /* SFR Callbacks */ virtual void sfr_write(size_t offset, uint8_t data) override; @@ -522,7 +520,7 @@ public: virtual void nvram_write( emu_file &file ) override; protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; /* SFR Callbacks */ virtual void sfr_write(size_t offset, uint8_t data) override; diff --git a/src/devices/cpu/mcs51/mcs51dasm.cpp b/src/devices/cpu/mcs51/mcs51dasm.cpp index b96ae46a4a1..fce9b90208f 100644 --- a/src/devices/cpu/mcs51/mcs51dasm.cpp +++ b/src/devices/cpu/mcs51/mcs51dasm.cpp @@ -24,223 +24,215 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "mcs51.h" +#include "mcs51dasm.h" + +// Note: addresses >= 0x100 are bit addresses + +const mcs51_disassembler::mem_info mcs51_disassembler::default_names[] = { + { 0x00, "rb0r0" }, + { 0x01, "rb0r1" }, + { 0x02, "rb0r2" }, + { 0x03, "rb0r3" }, + { 0x04, "rb0r4" }, + { 0x05, "rb0r5" }, + { 0x06, "rb0r6" }, + { 0x07, "rb0r7" }, + { 0x08, "rb1r0" }, + { 0x09, "rb1r1" }, + { 0x0a, "rb1r2" }, + { 0x0b, "rb1r3" }, + { 0x0c, "rb1r4" }, + { 0x0d, "rb1r5" }, + { 0x0e, "rb1r6" }, + { 0x0f, "rb1r7" }, + { 0x10, "rb2r0" }, + { 0x11, "rb2r1" }, + { 0x12, "rb2r2" }, + { 0x13, "rb2r3" }, + { 0x14, "rb2r4" }, + { 0x15, "rb2r5" }, + { 0x16, "rb2r6" }, + { 0x17, "rb2r7" }, + { 0x18, "rb3r0" }, + { 0x19, "rb3r1" }, + { 0x1a, "rb3r2" }, + { 0x1b, "rb3r3" }, + { 0x1c, "rb3r4" }, + { 0x1d, "rb3r5" }, + { 0x1e, "rb3r6" }, + { 0x1f, "rb3r7" }, + + { 0x80, "p0" }, + { 0x81, "sp" }, + { 0x82, "dpl" }, + { 0x83, "dph" }, + { 0x87, "pcon" }, + { 0x88, "tcon" }, + { 0x89, "tmod" }, + { 0x8a, "tl0" }, + { 0x8b, "tl1" }, + { 0x8c, "th0" }, + { 0x8d, "th1" }, + { 0x90, "p1" }, + { 0x98, "scon" }, + { 0x99, "sbuf" }, + { 0xa0, "p2" }, + { 0xa8, "ie" }, + { 0xb0, "p3" }, + { 0xb8, "ip" }, + { 0xd0, "psw" }, + { 0xe0, "acc" }, + { 0xf0, "b" }, + + { 0x188, "it0" }, + { 0x189, "ie0" }, + { 0x18a, "it1" }, + { 0x18b, "ie1" }, + { 0x18c, "tr0" }, + { 0x18d, "tf0" }, + { 0x18e, "tr1" }, + { 0x18f, "tf1" }, + + { 0x198, "ri" }, + { 0x199, "ti" }, + { 0x19a, "rb8" }, + { 0x19b, "tb8" }, + { 0x19c, "ren" }, + { 0x19d, "sm2" }, + { 0x19e, "sm1" }, + { 0x19f, "sm0" }, + + { 0x1a8, "ex0" }, + { 0x1a9, "et0" }, + { 0x1aa, "ex1" }, + { 0x1ab, "et1" }, + { 0x1ac, "es" }, + { 0x1ad, "ie.5" }, + { 0x1ae, "ie.6" }, + { 0x1af, "ea" }, -enum -{ - FEATURE_NONE = 0x00, - FEATURE_I8052 = 0x01, - FEATURE_CMOS = 0x02, - FEATURE_I80C52 = 0x04, - FEATURE_DS5002FP = 0x08, - FEATURE_I83C751 = 0x08 + /* FIXME: port 3 - depends on external circuits and not really + * implemented in the core. TBD */ + { 0x1b0, "rxd" }, + { 0x1b1, "txd" }, + { 0x1b2, "int0" }, + { 0x1b3, "int1" }, + { 0x1b4, "t0" }, + { 0x1b5, "t1" }, + { 0x1b6, "wr" }, + { 0x1b7, "rd" }, + + { 0x1b8, "px0" }, + { 0x1b9, "pt0" }, + { 0x1ba, "px1" }, + { 0x1bb, "pt1" }, + { 0x1bc, "ps" }, + { 0x1bd, "ip.5" }, + { 0x1be, "ip.6" }, + { 0x1bf, "ip.7" }, + + { 0x1d0, "p" }, + { 0x1d1, "psw.1" }, + { 0x1d2, "ov" }, + { 0x1d3, "rs0" }, + { 0x1d4, "rs1" }, + { 0x1d5, "f0" }, + { 0x1d6, "ac" }, + { 0x1d7, "cy" }, + + { -1 } }; +const mcs51_disassembler::mem_info mcs51_disassembler::i8052_names[] = { + { 0xc8, "t2con" }, + { 0xca, "rcap2l" }, + { 0xcb, "rcap2h" }, + { 0xcc, "tl2" }, + { 0xcd, "th2" }, + + { 0x1ad, "et2" }, + { 0x1bd, "pt2" }, + + { 0x1c8, "cprl2" }, + { 0x1c9, "ct2" }, + { 0x1ca, "tr2" }, + { 0x1cb, "exen2" }, + { 0x1cc, "tclk" }, + { 0x1cd, "rclk" }, + { 0x1ce, "exf2" }, + { 0x1cf, "tf2" }, -#define SHOW_MEMORY_NAMES 1 + { -1 } +}; -#ifdef SHOW_MEMORY_NAMES +const mcs51_disassembler::mem_info mcs51_disassembler::i80c52_names[] = { + { 0xb7, "iph" }, + { 0xa9, "saddr" }, + { 0xb9, "saden" }, -/*Display the memory address names for data & bit address access*/ + { -1 } +}; -//SFR Names +const mcs51_disassembler::mem_info mcs51_disassembler::ds5002fp_names[] = { + { 0x8e, "pwcm" }, + { 0x8f, "pwmp" }, + { 0xc1, "crcr" }, + { 0xc2, "crcl" }, + { 0xc3, "crch" }, + { 0xc6, "mcon" }, + { 0xc7, "ta" }, + { 0xcf, "rnr" }, + { 0xd8, "rpctl" }, + { 0xd9, "rps" }, + + { 0x1d8, "rg0" }, + { 0x1d9, "rpc" }, + { 0x1da, "dma" }, + { 0x1db, "ibi" }, + { 0x1dc, "ae" }, + { 0x1dd, "exbs" }, + { 0x1de, "d8.6" }, + { 0x1df, "rnr" }, -static const struct { - int feature; - int addr; - const char *name; -} mem_name_feature[] = -{ - { FEATURE_NONE, 0x00, "rb0r0" }, - { FEATURE_NONE, 0x01, "rb0r1" }, - { FEATURE_NONE, 0x02, "rb0r2" }, - { FEATURE_NONE, 0x03, "rb0r3" }, - { FEATURE_NONE, 0x04, "rb0r4" }, - { FEATURE_NONE, 0x05, "rb0r5" }, - { FEATURE_NONE, 0x06, "rb0r6" }, - { FEATURE_NONE, 0x07, "rb0r7" }, - { FEATURE_NONE, 0x08, "rb1r0" }, - { FEATURE_NONE, 0x09, "rb1r1" }, - { FEATURE_NONE, 0x0a, "rb1r2" }, - { FEATURE_NONE, 0x0b, "rb1r3" }, - { FEATURE_NONE, 0x0c, "rb1r4" }, - { FEATURE_NONE, 0x0d, "rb1r5" }, - { FEATURE_NONE, 0x0e, "rb1r6" }, - { FEATURE_NONE, 0x0f, "rb1r7" }, - { FEATURE_NONE, 0x10, "rb2r0" }, - { FEATURE_NONE, 0x11, "rb2r1" }, - { FEATURE_NONE, 0x12, "rb2r2" }, - { FEATURE_NONE, 0x13, "rb2r3" }, - { FEATURE_NONE, 0x14, "rb2r4" }, - { FEATURE_NONE, 0x15, "rb2r5" }, - { FEATURE_NONE, 0x16, "rb2r6" }, - { FEATURE_NONE, 0x17, "rb2r7" }, - { FEATURE_NONE, 0x18, "rb3r0" }, - { FEATURE_NONE, 0x19, "rb3r1" }, - { FEATURE_NONE, 0x1a, "rb3r2" }, - { FEATURE_NONE, 0x1b, "rb3r3" }, - { FEATURE_NONE, 0x1c, "rb3r4" }, - { FEATURE_NONE, 0x1d, "rb3r5" }, - { FEATURE_NONE, 0x1e, "rb3r6" }, - { FEATURE_NONE, 0x1f, "rb3r7" }, - - { FEATURE_NONE, 0x80, "p0" }, - { FEATURE_NONE, 0x81, "sp" }, - { FEATURE_NONE, 0x82, "dpl" }, - { FEATURE_NONE, 0x83, "dph" }, - { FEATURE_NONE, 0x87, "pcon" }, - { FEATURE_NONE, 0x88, "tcon" }, - { FEATURE_NONE, 0x89, "tmod" }, - { FEATURE_NONE, 0x8a, "tl0" }, - { FEATURE_NONE, 0x8b, "tl1" }, - { FEATURE_NONE, 0x8c, "th0" }, - { FEATURE_NONE, 0x8d, "th1" }, - { FEATURE_NONE, 0x90, "p1" }, - { FEATURE_NONE, 0x98, "scon" }, - { FEATURE_NONE, 0x99, "sbuf" }, - { FEATURE_NONE, 0xa0, "p2" }, - { FEATURE_NONE, 0xa8, "ie" }, - { FEATURE_NONE, 0xb0, "p3" }, - { FEATURE_NONE, 0xb8, "ip" }, - { FEATURE_NONE, 0xd0, "psw" }, - { FEATURE_NONE, 0xe0, "acc" }, - { FEATURE_NONE, 0xf0, "b" }, - - { FEATURE_I8052, 0xc8, "t2con" }, - { FEATURE_I8052, 0xca, "rcap2l" }, - { FEATURE_I8052, 0xcb, "rcap2h" }, - { FEATURE_I8052, 0xcc, "tl2" }, - { FEATURE_I8052, 0xcd, "th2" }, - - { FEATURE_I80C52, 0xb7, "iph" }, - { FEATURE_I80C52, 0xa9, "saddr" }, - { FEATURE_I80C52, 0xb9, "saden" }, - - { FEATURE_DS5002FP, 0x8e, "pwcm" }, - { FEATURE_DS5002FP, 0x8f, "pwmp" }, - { FEATURE_DS5002FP, 0xc1, "crcr" }, - { FEATURE_DS5002FP, 0xc2, "crcl" }, - { FEATURE_DS5002FP, 0xc3, "crch" }, - { FEATURE_DS5002FP, 0xc6, "mcon" }, - { FEATURE_DS5002FP, 0xc7, "ta" }, - { FEATURE_DS5002FP, 0xcf, "rnr" }, - { FEATURE_DS5002FP, 0xd8, "rpctl" }, - { FEATURE_DS5002FP, 0xd9, "rps" }, - - { FEATURE_I83C751, 0x98, "i2con" }, - { FEATURE_I83C751, 0x99, "i2dat" }, - { FEATURE_I83C751, 0xd8, "i2cfg" }, - { FEATURE_I83C751, 0xf8, "i2sta" }, /* read only */ - - /* bit addresses */ - - { FEATURE_NONE, 0x188, "it0" }, - { FEATURE_NONE, 0x189, "ie0" }, - { FEATURE_NONE, 0x18a, "it1" }, - { FEATURE_NONE, 0x18b, "ie1" }, - { FEATURE_NONE, 0x18c, "tr0" }, - { FEATURE_NONE, 0x18d, "tf0" }, - { FEATURE_NONE, 0x18e, "tr1" }, - { FEATURE_NONE, 0x18f, "tf1" }, - - { FEATURE_NONE, 0x198, "ri" }, - { FEATURE_NONE, 0x199, "ti" }, - { FEATURE_NONE, 0x19a, "rb8" }, - { FEATURE_NONE, 0x19b, "tb8" }, - { FEATURE_NONE, 0x19c, "ren" }, - { FEATURE_NONE, 0x19d, "sm2" }, - { FEATURE_NONE, 0x19e, "sm1" }, - { FEATURE_NONE, 0x19f, "sm0" }, - - { FEATURE_I83C751, 0x198, "xstp" }, /* read: no function */ - { FEATURE_I83C751, 0x199, "xstr" }, /* read: MASTER */ - { FEATURE_I83C751, 0x19a, "cstp" }, /* read: STP */ - { FEATURE_I83C751, 0x19b, "cstr" }, /* read: STR */ - { FEATURE_I83C751, 0x19c, "carl" }, /* read: ARL */ - { FEATURE_I83C751, 0x19d, "cdr" }, /* read: DRDY */ - { FEATURE_I83C751, 0x19e, "idle" }, /* read: ATN */ - { FEATURE_I83C751, 0x19f, "cxa" }, /* read: RDAT */ - - { FEATURE_NONE, 0x1a8, "ex0" }, - { FEATURE_NONE, 0x1a9, "et0" }, - { FEATURE_NONE, 0x1aa, "ex1" }, - { FEATURE_NONE, 0x1ab, "et1" }, - { FEATURE_NONE, 0x1ac, "es" }, - { FEATURE_NONE, 0x1ad, "ie.5" }, - { FEATURE_NONE, 0x1ae, "ie.6" }, - { FEATURE_NONE, 0x1af, "ea" }, - - { FEATURE_I83C751, 0x1ac, "ei2" }, - { FEATURE_I8052, 0x1ad, "et2" }, + { -1 } +}; - /* FIXME: port 3 - depends on external circuits and not really - * implemented in the core. TBD */ - { FEATURE_NONE, 0x1b0, "rxd" }, - { FEATURE_NONE, 0x1b1, "txd" }, - { FEATURE_NONE, 0x1b2, "int0" }, - { FEATURE_NONE, 0x1b3, "int1" }, - { FEATURE_NONE, 0x1b4, "t0" }, - { FEATURE_NONE, 0x1b5, "t1" }, - { FEATURE_NONE, 0x1b6, "wr" }, - { FEATURE_NONE, 0x1b7, "rd" }, - - { FEATURE_NONE, 0x1b8, "px0" }, - { FEATURE_NONE, 0x1b9, "pt0" }, - { FEATURE_NONE, 0x1ba, "px1" }, - { FEATURE_NONE, 0x1bb, "pt1" }, - { FEATURE_NONE, 0x1bc, "ps" }, - { FEATURE_NONE, 0x1bd, "ip.5" }, - { FEATURE_NONE, 0x1be, "ip.6" }, - { FEATURE_NONE, 0x1bf, "ip.7" }, - - { FEATURE_I8052, 0x1bd, "pt2" }, - { FEATURE_I83C751, 0x1bc, "pi2" }, - - { FEATURE_I8052, 0x1c8, "cprl2" }, - { FEATURE_I8052, 0x1c9, "ct2" }, - { FEATURE_I8052, 0x1ca, "tr2" }, - { FEATURE_I8052, 0x1cb, "exen2" }, - { FEATURE_I8052, 0x1cc, "tclk" }, - { FEATURE_I8052, 0x1cd, "rclk" }, - { FEATURE_I8052, 0x1ce, "exf2" }, - { FEATURE_I8052, 0x1cf, "tf2" }, - - { FEATURE_NONE, 0x1d0, "p" }, - { FEATURE_NONE, 0x1d1, "psw.1" }, - { FEATURE_NONE, 0x1d2, "ov" }, - { FEATURE_NONE, 0x1d3, "rs0" }, - { FEATURE_NONE, 0x1d4, "rs1" }, - { FEATURE_NONE, 0x1d5, "f0" }, - { FEATURE_NONE, 0x1d6, "ac" }, - { FEATURE_NONE, 0x1d7, "cy" }, - - { FEATURE_DS5002FP, 0x1d8, "rg0" }, - { FEATURE_DS5002FP, 0x1d9, "rpc" }, - { FEATURE_DS5002FP, 0x1da, "dma" }, - { FEATURE_DS5002FP, 0x1db, "ibi" }, - { FEATURE_DS5002FP, 0x1dc, "ae" }, - { FEATURE_DS5002FP, 0x1dd, "exbs" }, - { FEATURE_DS5002FP, 0x1de, "d8.6" }, - { FEATURE_DS5002FP, 0x1df, "rnr" }, - - { FEATURE_I83C751, 0x1d8, "ct0" }, - { FEATURE_I83C751, 0x1d9, "ct1" }, - { FEATURE_I83C751, 0x1da, "i2cfg.2" }, - { FEATURE_I83C751, 0x1db, "i2cfg.3" }, - { FEATURE_I83C751, 0x1dc, "tirun" }, - { FEATURE_I83C751, 0x1dd, "clrti" }, - { FEATURE_I83C751, 0x1de, "masterq" }, - { FEATURE_I83C751, 0x1df, "slaven" }, - - { FEATURE_I83C751, 0x1f8, "xstp" }, - { FEATURE_I83C751, 0x1f9, "xstr" }, - { FEATURE_I83C751, 0x1fa, "makstp" }, - { FEATURE_I83C751, 0x1fb, "makstr" }, - { FEATURE_I83C751, 0x1fc, "xactv" }, - { FEATURE_I83C751, 0x1fd, "xdata" }, - { FEATURE_I83C751, 0x1fe, "idle" }, - { FEATURE_I83C751, 0x1ff, "i2sta.7" }, +const mcs51_disassembler::mem_info mcs51_disassembler::i8xc751_names[] = { + { 0x98, "i2con" }, + { 0x99, "i2dat" }, + { 0xd8, "i2cfg" }, + { 0xf8, "i2sta" }, /* read only */ + + { 0x198, "xstp" }, /* read: no function */ + { 0x199, "xstr" }, /* read: MASTER */ + { 0x19a, "cstp" }, /* read: STP */ + { 0x19b, "cstr" }, /* read: STR */ + { 0x19c, "carl" }, /* read: ARL */ + { 0x19d, "cdr" }, /* read: DRDY */ + { 0x19e, "idle" }, /* read: ATN */ + { 0x19f, "cxa" }, /* read: RDAT */ + + { 0x1ac, "ei2" }, + + { 0x1bc, "pi2" }, + + { 0x1d8, "ct0" }, + { 0x1d9, "ct1" }, + { 0x1da, "i2cfg.2" }, + { 0x1db, "i2cfg.3" }, + { 0x1dc, "tirun" }, + { 0x1dd, "clrti" }, + { 0x1de, "masterq" }, + { 0x1df, "slaven" }, + + { 0x1f8, "xstp" }, + { 0x1f9, "xstr" }, + { 0x1fa, "makstp" }, + { 0x1fb, "makstr" }, + { 0x1fc, "xactv" }, + { 0x1fd, "xdata" }, + { 0x1fe, "idle" }, + { 0x1ff, "i2sta.7" }, /* unknown * "ibf", "obf", "idsm", "obfc", e8 - eb @@ -250,97 +242,67 @@ static const struct { { -1 } }; -static void init_mem_names(int feature_set, const char **mem_names) +mcs51_disassembler::mcs51_disassembler() { - int i; - int feature; - - /* Set defaults / i8051 */ - for (i = 0; feature = mem_name_feature[i].feature, feature >= 0; i++) - { - if ( feature == FEATURE_NONE ) - mem_names[mem_name_feature[i].addr] = mem_name_feature[i].name; - } - - /* Set specific memory names */ - for (i = 0; feature = mem_name_feature[i].feature, feature >= 0; i++) - { - if (feature & feature_set) - mem_names[mem_name_feature[i].addr] = mem_name_feature[i].name; - } +} +void mcs51_disassembler::add_names(const mem_info *info) +{ + for(unsigned int i=0; info[i].addr >= 0; i++) + m_names[info[i].addr] = info[i].name; } -static const char *get_data_address( const char **mem_names, uint8_t arg ) +u32 mcs51_disassembler::opcode_alignment() const { - static char buffer_array[4][32]; - static int whichbuf; - char *buffer = &buffer_array[++whichbuf % 4][0]; + return 1; +} + - if (mem_names[arg] == nullptr) - sprintf(buffer,"$%02X",arg); +std::string mcs51_disassembler::get_data_address( uint8_t arg ) const +{ + auto i = m_names.find(arg); + if (i == m_names.end()) + return util::string_format("$%02X", arg); else - sprintf(buffer,"%s", mem_names[arg]); - return buffer; + return i->second; } -static const char *get_bit_address( const char **mem_names, uint8_t arg ) +std::string mcs51_disassembler::get_bit_address( uint8_t arg ) const { - static char buffer[32]; - if(arg < 0x80) { //Bit address 0-7F can be referred to as 20.0, 20.1, to 20.7 for address 0, and 2f.0,2f.1 to 2f.7 for address 7f if(arg < 0x7f) - sprintf(buffer,"$%02X.%d",(arg >> 3) | 0x20, arg & 0x07); + return util::string_format("$%02X.%d", (arg >> 3) | 0x20, arg & 0x07); else - sprintf(buffer,"$%02X",arg); + return util::string_format("$%02X", arg); } else { - if (mem_names[arg | 0x100] == nullptr) + auto i = m_names.find(arg | 0x100); + if (i == m_names.end()) { - if (mem_names[arg & 0xf8] == nullptr) - sprintf(buffer,"$%02X.%d", arg & 0xf8, arg & 0x07); + i = m_names.find(arg & 0xf8); + if (i == m_names.end()) + return util::string_format("$%02X.%d", arg & 0xf8, arg & 0x07); else - sprintf(buffer,"%s.%d", mem_names[arg & 0xf8], arg & 0x07); + return util::string_format("%s.%d", i->second, arg & 0x07); } else - sprintf(buffer,"%s", mem_names[arg | 0x100]); + return i->second; } - return buffer; } -#else - -/*Just display the actual memory address for data & bit address access*/ - -static const char *get_data_address( uint8_t arg ) -{ - static char buffer[32]; - sprintf(buffer,"$%02X",arg); - return buffer; -} - -static const char *get_bit_address( uint8_t arg ) -{ - static char buffer[32]; - sprintf(buffer,"$%02X",arg); - return buffer; -} - -#endif - -static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram) +offs_t mcs51_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; unsigned PC = pc; - const char *sym, *sym2; + std::string sym, sym2; uint8_t op, data; uint16_t addr; int8_t rel; - op = oprom[PC++ - pc]; + op = opcodes.r8(PC++); switch( op ) { //NOP @@ -357,15 +319,15 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xa1: case 0xc1: case 0xe1: - addr = opram[PC++ - pc]; + addr = params.r8(PC++); addr|= (PC & 0xf800) | ((op & 0xe0) << 3); util::stream_format(stream, "ajmp $%04X", addr); break; //LJMP code addr case 0x02: /* 1: 0000 0010 */ - addr = (opram[PC++ - pc]<<8) & 0xff00; - addr|= opram[PC++ - pc]; + addr = (params.r8(PC++)<<8) & 0xff00; + addr|= params.r8(PC++); util::stream_format(stream, "ljmp $%04X", addr); break; @@ -381,7 +343,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //INC data addr case 0x05: /* 1: 0000 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "inc %s", sym); break; @@ -405,8 +367,8 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JBC bit addr, code addr case 0x10: /* 1: 0001 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_bit_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "jbc %s,$%04X", sym, PC + rel); break; @@ -419,17 +381,17 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xb1: case 0xd1: case 0xf1: - util::stream_format(stream, "acall $%04X", (PC & 0xf800) | ((op & 0xe0) << 3) | opram[PC - pc]); + util::stream_format(stream, "acall $%04X", (PC & 0xf800) | ((op & 0xe0) << 3) | params.r8(PC)); PC++; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; //LCALL code addr case 0x12: /* 1: 0001 0010 */ - addr = (opram[PC++ - pc]<<8) & 0xff00; - addr|= opram[PC++ - pc]; + addr = (params.r8(PC++)<<8) & 0xff00; + addr|= params.r8(PC++); util::stream_format(stream, "lcall $%04X", addr); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; //RRC A @@ -444,7 +406,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //DEC data addr case 0x15: /* 1: 0001 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "dec %s", sym); break; @@ -469,15 +431,15 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JB bit addr, code addr case 0x20: /* 1: 0010 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_bit_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "jb %s,$%04X", sym, (PC + rel)); break; //RET case 0x22: /* 1: 0010 0010 */ util::stream_format(stream, "ret"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; //RL A @@ -487,12 +449,12 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //ADD A, #data case 0x24: /* 1: 0010 0100 */ - util::stream_format(stream, "add a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "add a,#$%02X", params.r8(PC++)); break; //ADD A, data addr case 0x25: /* 1: 0010 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "add a,%s", sym); break; @@ -517,15 +479,15 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JNB bit addr, code addr case 0x30: /* 1: 0011 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_bit_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "jnb %s,$%04X", sym, (PC + rel)); break; //RETI case 0x32: /* 1: 0011 0010 */ util::stream_format(stream, "reti"); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; //RLC A @@ -535,12 +497,12 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //ADDC A, #data case 0x34: /* 1: 0011 0100 */ - util::stream_format(stream, "addc a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "addc a,#$%02X", params.r8(PC++)); break; //ADDC A, data addr case 0x35: /* 1: 0011 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "addc a,%s", sym); break; @@ -564,31 +526,31 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JC code addr case 0x40: /* 1: 0100 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "jc $%04X", PC + rel); break; //ORL data addr, A case 0x42: /* 1: 0100 0010 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "orl %s,a", sym); break; //ORL data addr, #data case 0x43: /* 1: 0100 0011 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - util::stream_format(stream, "orl %s,#$%02X", sym, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + util::stream_format(stream, "orl %s,#$%02X", sym, params.r8(PC++)); break; //Unable to Test //ORL A, #data case 0x44: /* 1: 0100 0100 */ - util::stream_format(stream, "orl a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "orl a,#$%02X", params.r8(PC++)); break; //ORL A, data addr case 0x45: /* 1: 0100 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "orl a,%s", sym); break; @@ -612,32 +574,32 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JNC code addr case 0x50: /* 1: 0101 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "jnc $%04X", PC + rel); break; //Unable to test //ANL data addr, A case 0x52: /* 1: 0101 0010 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "anl %s,a", sym); break; //Unable to test //ANL data addr, #data case 0x53: /* 1: 0101 0011 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - util::stream_format(stream, "anl %s,#$%02X", sym, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + util::stream_format(stream, "anl %s,#$%02X", sym, params.r8(PC++)); break; //ANL A, #data case 0x54: /* 1: 0101 0100 */ - util::stream_format(stream, "anl a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "anl a,#$%02X", params.r8(PC++)); break; //ANL A, data addr case 0x55: /* 1: 0101 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "anl a,%s", sym); break; @@ -662,31 +624,31 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JZ code addr case 0x60: /* 1: 0110 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "jz $%04X", PC + rel); break; //Unable to test //XRL data addr, A case 0x62: /* 1: 0110 0010 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "xrl %s,a", sym); break; //XRL data addr, #data case 0x63: /* 1: 0110 0011 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - util::stream_format(stream, "xrl %s,#$%02X", sym, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + util::stream_format(stream, "xrl %s,#$%02X", sym, params.r8(PC++)); break; //XRL A, #data case 0x64: /* 1: 0110 0100 */ - util::stream_format(stream, "xrl a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "xrl a,#$%02X", params.r8(PC++)); break; //XRL A, data addr case 0x65: /* 1: 0110 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "xrl a,%s", sym); break; @@ -711,14 +673,14 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //JNZ code addr case 0x70: /* 1: 0111 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "jnz $%04X", PC + rel); break; //Unable to test //ORL C, bit addr case 0x72: /* 1: 0111 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "orl c,%s", sym); break; @@ -730,20 +692,20 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV A, #data case 0x74: /* 1: 0111 0100 */ - util::stream_format(stream, "mov a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "mov a,#$%02X", params.r8(PC++)); break; //MOV data addr, #data case 0x75: /* 1: 0111 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - util::stream_format(stream, "mov %s,#$%02X", sym, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + util::stream_format(stream, "mov %s,#$%02X", sym, params.r8(PC++)); break; //Unable to test //MOV @R0/@R1, #data /* 1: 0111 011i */ case 0x76: case 0x77: - util::stream_format(stream, "mov @r%d,#$%02X", op&1, opram[PC++ - pc]); + util::stream_format(stream, "mov @r%d,#$%02X", op&1, params.r8(PC++)); break; //MOV R0 to R7, #data /* 1: 0111 1rrr */ @@ -755,18 +717,18 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "mov r%d,#$%02X", (op & 7), opram[PC++ - pc]); + util::stream_format(stream, "mov r%d,#$%02X", (op & 7), params.r8(PC++)); break; //SJMP code addr case 0x80: /* 1: 1000 0000 */ - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "sjmp $%04X", PC + rel); break; //ANL C, bit addr case 0x82: /* 1: 1000 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "anl c,%s", sym); break; @@ -782,8 +744,8 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV data addr, data addr (Note: 1st address is src, 2nd is dst, but the mov command works as mov dst,src) case 0x85: /* 1: 1000 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - sym2 = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); + sym2 = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov %s,%s", sym2, sym); break; @@ -791,7 +753,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV data addr, @R0/@R1/* 1: 1000 011i */ case 0x86: case 0x87: - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov %s,@r%d", sym, op&1); break; @@ -804,20 +766,20 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0x8d: case 0x8e: case 0x8f: - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov %s,r%d", sym, op&7); break; //MOV DPTR, #data16 case 0x90: /* 1: 1001 0000 */ - addr = (opram[PC++ - pc]<<8) & 0xff00; - addr|= opram[PC++ - pc]; + addr = (params.r8(PC++)<<8) & 0xff00; + addr|= params.r8(PC++); util::stream_format(stream, "mov dptr,#$%04X", addr); break; //MOV bit addr, C case 0x92: /* 1: 1001 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "mov %s,c", sym); break; @@ -828,12 +790,12 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //SUBB A, #data case 0x94: /* 1: 1001 0100 */ - util::stream_format(stream, "subb a,#$%02X", opram[PC++ - pc]); + util::stream_format(stream, "subb a,#$%02X", params.r8(PC++)); break; //SUBB A, data addr case 0x95: /* 1: 1001 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "subb a,%s", sym); break; @@ -859,13 +821,13 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //Unable to test //ORL C, /bit addr case 0xa0: /* 1: 1010 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "orl c,/%s", sym); break; //MOV C, bit addr case 0xa2: /* 1: 1010 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "mov c,%s", sym); break; @@ -888,7 +850,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV @R0/@R1, data addr /* 1: 1010 011i */ case 0xa6: case 0xa7: - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov @r%d,%s", op&1, sym); break; @@ -901,19 +863,19 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xad: case 0xae: case 0xaf: - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov r%d,%s", op&7, sym); break; //ANL C,/bit addr case 0xb0: /* 1: 1011 0000 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "anl c,/%s", sym); break; //CPL bit addr case 0xb2: /* 1: 1011 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "cpl %s", sym); break; @@ -925,15 +887,15 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //CJNE A, #data, code addr case 0xb4: /* 1: 1011 0100 */ - data = opram[PC++ - pc]; - rel = opram[PC++ - pc]; + data = params.r8(PC++); + rel = params.r8(PC++); util::stream_format(stream, "cjne a,#$%02X,$%04X", data, PC + rel); break; //CJNE A, data addr, code addr case 0xb5: /* 1: 1011 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_data_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "cjne a,%s,$%04X", sym, PC + rel); break; @@ -941,8 +903,8 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //CJNE @R0/@R1, #data, code addr /* 1: 1011 011i */ case 0xb6: case 0xb7: - data = opram[PC++ - pc]; - rel = opram[PC++ - pc]; + data = params.r8(PC++); + rel = params.r8(PC++); util::stream_format(stream, "cjne @r%d,#$%02X,$%04X", op&1, data, PC + rel); break; @@ -955,20 +917,20 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xbd: case 0xbe: case 0xbf: - data = opram[PC++ - pc]; - rel = opram[PC++ - pc]; + data = params.r8(PC++); + rel = params.r8(PC++); util::stream_format(stream, "cjne r%d,#$%02X,$%04X", op&7, data, PC + rel); break; //PUSH data addr case 0xc0: /* 1: 1100 0000 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "push %s", sym); break; //CLR bit addr case 0xc2: /* 1: 1100 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "clr %s", sym); break; @@ -984,7 +946,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //XCH A, data addr case 0xc5: /* 1: 1100 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "xch a,%s", sym); break; @@ -1008,13 +970,13 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //POP data addr case 0xd0: /* 1: 1101 0000 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "pop %s", sym); break; //SETB bit addr case 0xd2: /* 1: 1101 0010 */ - sym = get_bit_address(mem_names, opram[PC++ - pc]); + sym = get_bit_address(params.r8(PC++)); util::stream_format(stream, "setb %s", sym); break; @@ -1031,10 +993,10 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //DJNZ data addr, code addr case 0xd5: /* 1: 1101 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); - rel = opram[PC++ - pc]; + sym = get_data_address(params.r8(PC++)); + rel = params.r8(PC++); util::stream_format(stream, "djnz %s,$%04X", sym, PC + rel); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; //XCHD A, @R0/@R1 /* 1: 1101 011i */ @@ -1052,9 +1014,9 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p case 0xdd: case 0xde: case 0xdf: - rel = opram[PC++ - pc]; + rel = params.r8(PC++); util::stream_format(stream, "djnz r%d,$%04X", op&7, (PC + rel)); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; //MOVX A,@DPTR @@ -1076,7 +1038,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV A, data addr case 0xe5: /* 1: 1110 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov a,%s", sym); break; @@ -1118,7 +1080,7 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p //MOV data addr, A case 0xf5: /* 1: 1111 0101 */ - sym = get_data_address(mem_names, opram[PC++ - pc]); + sym = get_data_address(params.r8(PC++)); util::stream_format(stream, "mov %s,a", sym); break; @@ -1144,70 +1106,25 @@ static offs_t mcs51_dasm( const char **mem_names, std::ostream &stream, offs_t p util::stream_format(stream, "illegal"); } - return (PC - pc) | flags | DASMFLAG_SUPPORTED; + return (PC - pc) | flags | SUPPORTED; } -CPU_DISASSEMBLE( i8051 ) +i8051_disassembler::i8051_disassembler() : mcs51_disassembler(default_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_NONE, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } -CPU_DISASSEMBLE( i8052 ) +i8052_disassembler::i8052_disassembler() : mcs51_disassembler(default_names, i8052_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_I8052, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } -CPU_DISASSEMBLE( i80c51 ) +i80c51_disassembler::i80c51_disassembler() : mcs51_disassembler(default_names, i80c52_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_CMOS, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } -CPU_DISASSEMBLE( i80c52 ) +i80c52_disassembler::i80c52_disassembler() : mcs51_disassembler(default_names, i80c52_names, i80c52_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_I8052 | FEATURE_CMOS | FEATURE_I80C52, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } -CPU_DISASSEMBLE( ds5002fp ) +ds5002fp_disassembler::ds5002fp_disassembler() : mcs51_disassembler(default_names, i80c52_names, ds5002fp_names, i8xc751_names) { - static const char *mem_names[0x200]; - static int mem_names_initialized = 0; - - if (!mem_names_initialized) - { - init_mem_names( FEATURE_DS5002FP | FEATURE_CMOS, mem_names); - mem_names_initialized = 1; - } - return mcs51_dasm(mem_names, stream, pc, oprom, opram); } diff --git a/src/devices/cpu/mcs51/mcs51dasm.h b/src/devices/cpu/mcs51/mcs51dasm.h new file mode 100644 index 00000000000..98272befc89 --- /dev/null +++ b/src/devices/cpu/mcs51/mcs51dasm.h @@ -0,0 +1,106 @@ +// license:BSD-3-Clause +// copyright-holders:Steve Ellenoff +/***************************************************************************** + * + * i8051dasm.c + * Portable MCS-51 Family Emulator + * + * Chips in the family: + * 8051 Product Line (8031,8051,8751) + * 8052 Product Line (8032,8052,8752) + * 8054 Product Line (8054) + * 8058 Product Line (8058) + * + * Copyright Steve Ellenoff, all rights reserved. + * + * This work is based on: + * #1) 'Intel(tm) MC51 Microcontroller Family Users Manual' and + * #2) 8051 simulator by Travis Marlatte + * #3) Portable UPI-41/8041/8741/8042/8742 emulator V0.1 by Juergen Buchmueller (MAME CORE) + * + ***************************************************************************** + * Symbol Memory Name Tables borrowed from: + * D52 8052 Disassembler - Copyright Jeffery L. Post + *****************************************************************************/ + +#ifndef MAME_CPU_MCS51_MCS51DASM_H +#define MAME_CPU_MCS51_MCS51DASM_H + +#pragma once + +class mcs51_disassembler : public util::disasm_interface +{ +public: + struct mem_info { + int addr; + const char *name; + }; + + static const mem_info default_names[]; + static const mem_info i8052_names[]; + static const mem_info i80c52_names[]; + static const mem_info ds5002fp_names[]; + static const mem_info i8xc751_names[]; + + template<typename ...Names> mcs51_disassembler(Names &&... names) : mcs51_disassembler() { + add_names(names...); + } + + mcs51_disassembler(); + virtual ~mcs51_disassembler() = default; + + template<typename ...Names> void add_names(const mem_info *info, Names &&... names) + { + add_names(names...); + add_names(info); + } + + void add_names(const mem_info *info); + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + std::unordered_map<offs_t, const char *> m_names; + + std::string get_data_address( uint8_t arg ) const; + std::string get_bit_address( uint8_t arg ) const; +}; + +class i8051_disassembler : public mcs51_disassembler +{ +public: + i8051_disassembler(); + virtual ~i8051_disassembler() = default; +}; + +class i8052_disassembler : public mcs51_disassembler +{ +public: + i8052_disassembler(); + virtual ~i8052_disassembler() = default; +}; + +class i80c51_disassembler : public mcs51_disassembler +{ +public: + i80c51_disassembler(); + virtual ~i80c51_disassembler() = default; +}; + +class i80c52_disassembler : public mcs51_disassembler +{ +public: + i80c52_disassembler(); + virtual ~i80c52_disassembler() = default; +}; + +class ds5002fp_disassembler : public mcs51_disassembler +{ +public: + ds5002fp_disassembler(); + virtual ~ds5002fp_disassembler() = default; +}; + + +#endif diff --git a/src/devices/cpu/mcs96/i8x9x.cpp b/src/devices/cpu/mcs96/i8x9x.cpp index c3a6c7876af..cdb65bd3954 100644 --- a/src/devices/cpu/mcs96/i8x9x.cpp +++ b/src/devices/cpu/mcs96/i8x9x.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "i8x9x.h" +#include "i8x9xd.h" i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : mcs96_device(mconfig, type, tag, owner, clock, 8), @@ -18,9 +19,9 @@ i8x9x_device::i8x9x_device(const machine_config &mconfig, device_type type, cons { } -offs_t i8x9x_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8x9x_device::create_disassembler() { - return disasm_generic(stream, pc, oprom, opram, options, disasm_entries); + return new i8x9x_disassembler; } device_memory_interface::space_config_vector i8x9x_device::memory_space_config() const @@ -72,7 +73,7 @@ void i8x9x_device::commit_hso_cam() void i8x9x_device::ad_start(uint64_t current_time) { - ad_result = (io->read_word(2*((ad_command & 7) + A0)) << 6) | 8 | (ad_command & 7); + ad_result = (io->read_word((ad_command & 7) + A0) << 6) | 8 | (ad_command & 7); ad_done = current_time + 88; internal_update(current_time); } @@ -86,7 +87,7 @@ void i8x9x_device::serial_send(uint8_t data) void i8x9x_device::serial_send_done() { serial_send_timer = 0; - io->write_word(SERIAL*2, serial_send_buf); + io->write_word(SERIAL, serial_send_buf); pending_irq |= IRQ_SERIAL; sp_stat |= 0x20; check_irq(); @@ -133,11 +134,11 @@ void i8x9x_device::io_w8(uint8_t adr, uint8_t data) break; case 0x0f: logerror("%s: io port 1 %02x (%04x)\n", tag(), data, PPC); - io->write_word(P1*2, data); + io->write_word(P1, data); break; case 0x10: logerror("%s: io port 2 %02x (%04x)\n", tag(), data, PPC); - io->write_word(P2*2, data); + io->write_word(P2, data); break; case 0x11: logerror("%s: sp con %02x (%04x)\n", tag(), data, PPC); @@ -216,16 +217,16 @@ uint8_t i8x9x_device::io_r8(uint8_t adr) return timer_value(2, total_cycles()) >> 8; case 0x0e: { static int last = -1; - if(io->read_word(P0*2) != last) { - last = io->read_word(P0*2); + if(io->read_word(P0) != last) { + last = io->read_word(P0); logerror("%s: read p0 %02x\n", tag(), io->read_word(P0*2)); } - return io->read_word(P0*2); + return io->read_word(P0); } case 0x0f: - return io->read_word(P1*2); + return io->read_word(P1); case 0x10: - return io->read_word(P2*2); + return io->read_word(P2); case 0x11: { uint8_t res = sp_stat; sp_stat &= 0x80; diff --git a/src/devices/cpu/mcs96/i8x9x.h b/src/devices/cpu/mcs96/i8x9x.h index 8fda92de323..5684a95afc3 100644 --- a/src/devices/cpu/mcs96/i8x9x.h +++ b/src/devices/cpu/mcs96/i8x9x.h @@ -30,9 +30,8 @@ protected: virtual void device_reset() override; virtual space_config_vector memory_space_config() const override; - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; virtual void internal_update(uint64_t current_time) override; diff --git a/src/devices/cpu/mcs96/i8x9xd.cpp b/src/devices/cpu/mcs96/i8x9xd.cpp new file mode 100644 index 00000000000..40b66d9d492 --- /dev/null +++ b/src/devices/cpu/mcs96/i8x9xd.cpp @@ -0,0 +1,19 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + i8x9x.h + + MCS96, 8x9x branch, the original version + +***************************************************************************/ + +#include "emu.h" +#include "i8x9xd.h" + +i8x9x_disassembler::i8x9x_disassembler() : mcs96_disassembler(disasm_entries) +{ +} + +#include "cpu/mcs96/i8x9xd.hxx" + diff --git a/src/devices/cpu/mcs96/i8x9xd.h b/src/devices/cpu/mcs96/i8x9xd.h new file mode 100644 index 00000000000..72227f7933f --- /dev/null +++ b/src/devices/cpu/mcs96/i8x9xd.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + i8x9x.h + + MCS96, 8x9x branch, the original version + +***************************************************************************/ + +#ifndef MAME_CPU_MCS96_I8X9XD_H +#define MAME_CPU_MCS96_I8X9XD_H + +#include "mcs96d.h" + +class i8x9x_disassembler : public mcs96_disassembler +{ +public: + i8x9x_disassembler(); + virtual ~i8x9x_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/mcs96/i8xc196.cpp b/src/devices/cpu/mcs96/i8xc196.cpp index adffde72dc0..d415630f0fa 100644 --- a/src/devices/cpu/mcs96/i8xc196.cpp +++ b/src/devices/cpu/mcs96/i8xc196.cpp @@ -10,15 +10,16 @@ #include "emu.h" #include "i8xc196.h" +#include "i8xc196d.h" i8xc196_device::i8xc196_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : mcs96_device(mconfig, type, tag, owner, clock, 16) { } -offs_t i8xc196_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *i8xc196_device::create_disassembler() { - return disasm_generic(stream, pc, oprom, opram, options, disasm_entries); + return new i8xc196_disassembler; } void i8xc196_device::io_w8(uint8_t adr, uint8_t data) diff --git a/src/devices/cpu/mcs96/i8xc196.h b/src/devices/cpu/mcs96/i8xc196.h index bd5489a1721..a82c1ea0515 100644 --- a/src/devices/cpu/mcs96/i8xc196.h +++ b/src/devices/cpu/mcs96/i8xc196.h @@ -17,9 +17,8 @@ class i8xc196_device : public mcs96_device { protected: i8xc196_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - static const disasm_entry disasm_entries[0x100]; + virtual util::disasm_interface *create_disassembler() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; virtual void do_exec_full() override; virtual void do_exec_partial() override; diff --git a/src/devices/cpu/mcs96/i8xc196d.cpp b/src/devices/cpu/mcs96/i8xc196d.cpp new file mode 100644 index 00000000000..8d56aad09e7 --- /dev/null +++ b/src/devices/cpu/mcs96/i8xc196d.cpp @@ -0,0 +1,18 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + i8xc196.h + + MCS96, c196 branch, the enhanced 16 bits bus version + +***************************************************************************/ + +#include "emu.h" +#include "i8xc196d.h" + +i8xc196_disassembler::i8xc196_disassembler() : mcs96_disassembler(disasm_entries) +{ +} + +#include "cpu/mcs96/i8xc196d.hxx" diff --git a/src/devices/cpu/mcs96/i8xc196d.h b/src/devices/cpu/mcs96/i8xc196d.h new file mode 100644 index 00000000000..53c4f65db2f --- /dev/null +++ b/src/devices/cpu/mcs96/i8xc196d.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + i8xc196.h + + MCS96, c196 branch, the enhanced 16 bits bus version + +***************************************************************************/ + +#ifndef MAME_CPU_MCS96_I8XC196D_H +#define MAME_CPU_MCS96_I8XC196D_H + +#include "mcs96d.h" + +class i8xc196_disassembler : public mcs96_disassembler +{ +public: + i8xc196_disassembler(); + virtual ~i8xc196_disassembler() = default; + +private: + static const disasm_entry disasm_entries[0x100]; +}; + +#endif diff --git a/src/devices/cpu/mcs96/mcs96.cpp b/src/devices/cpu/mcs96/mcs96.cpp index 92a8ed23a37..fa7e75498b3 100644 --- a/src/devices/cpu/mcs96/mcs96.cpp +++ b/src/devices/cpu/mcs96/mcs96.cpp @@ -23,7 +23,7 @@ mcs96_device::mcs96_device(const machine_config &mconfig, device_type type, cons void mcs96_device::device_start() { program = &space(AS_PROGRAM); - direct = &program->direct(); + direct = program->direct<0>(); m_icountptr = &icount; state_add(STATE_GENPC, "GENPC", PC).noshow(); @@ -156,276 +156,6 @@ void mcs96_device::state_string_export(const device_state_entry &entry, std::str } } -std::string mcs96_device::regname(uint8_t reg) -{ - char res[32]; - switch(reg) { - case 0x18: - strcpy(res, "sp"); - break; - - case 0x19: - strcpy(res, "sph"); - break; - - default: - sprintf(res, "%02x", reg); - break; - } - return res; -} - -offs_t mcs96_device::disasm_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *entries) -{ - bool prefix_fe = false; - int off = 0; - if(oprom[0] == 0xfe && entries[oprom[1]].opcode_fe) { - prefix_fe = true; - pc++; - off++; - oprom++; - } - const disasm_entry &e = entries[oprom[0]]; - uint32_t flags = e.flags | DASMFLAG_SUPPORTED; - util::stream_format(stream, "%s", prefix_fe ? e.opcode_fe : e.opcode); - - switch(e.mode) { - case DASM_none: - flags |= 1; - break; - - case DASM_nop_2: - util::stream_format(stream, " %02x", oprom[1]); - flags |= 2; - break; - - case DASM_rel8: { - int delta = oprom[1]; - if(delta & 0x80) - delta -= 0x100; - util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff); - flags |= 2; - break; - } - - case DASM_rel11: { - int delta = ((oprom[0] << 8) | oprom[1]) & 0x7ff; - if(delta & 0x400) - delta -= 0x800; - util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff); - flags |= 2; - break; - } - - case DASM_rel16: { - int delta = oprom[1] | (oprom[2] << 8); - util::stream_format(stream, " %04x", (pc+3+delta) & 0xffff); - flags |= 3; - break; - } - - case DASM_rrel8: { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - util::stream_format(stream, " %s, %04x", regname(oprom[1]), (pc+3+delta) & 0xffff); - flags |= 3; - break; - } - - case DASM_brrel8: { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - util::stream_format(stream, " %d, %s, %04x", oprom[0] & 7, regname(oprom[1]), (pc+3+delta) & 0xffff); - flags |= 3; - break; - } - - case DASM_direct_1: - util::stream_format(stream, " %s", regname(oprom[1])); - flags |= 2; - break; - - case DASM_direct_2: - util::stream_format(stream, " %s, %s", regname(oprom[2]), regname(oprom[1])); - flags |= 3; - break; - - case DASM_direct_3: - util::stream_format(stream, " %s, %s, %s", regname(oprom[3]), regname(oprom[2]), regname(oprom[1])); - flags |= 4; - break; - - case DASM_immed_1b: - util::stream_format(stream, " #%02x", oprom[1]); - flags |= 2; - break; - - case DASM_immed_2b: - util::stream_format(stream, " %s, #%02x", regname(oprom[2]), oprom[1]); - flags |= 3; - break; - - case DASM_immed_or_reg_2b: - if(oprom[1] >= 0x10) - util::stream_format(stream, " %s, %s", regname(oprom[2]), regname(oprom[1])); - else - util::stream_format(stream, " %s, #%02x", regname(oprom[2]), oprom[1]); - flags |= 3; - break; - - case DASM_immed_3b: - util::stream_format(stream, " %s, %s, #%02x", regname(oprom[3]), regname(oprom[2]), oprom[1]); - flags |= 4; - break; - - case DASM_immed_1w: - util::stream_format(stream, " #%02x%02x", oprom[2], oprom[1]); - flags |= 3; - break; - - case DASM_immed_2w: - util::stream_format(stream, " %s, #%02x%02x", regname(oprom[3]), oprom[2], oprom[1]); - flags |= 4; - break; - - case DASM_immed_3w: - util::stream_format(stream, " %s, %s, #%02x%02x", regname(oprom[4]), regname(oprom[3]), oprom[2], oprom[1]); - flags |= 5; - break; - - case DASM_indirect_1n: - util::stream_format(stream, " [%s]", regname(oprom[1])); - flags |= 2; - break; - - case DASM_indirect_1: - if(oprom[1] & 0x01) { - util::stream_format(stream, " [%s]+", regname(oprom[1]-1)); - flags |= 2; - } else { - util::stream_format(stream, " [%s]", regname(oprom[1])); - flags |= 2; - } - break; - - case DASM_indirect_2: - if(oprom[1] & 0x01) { - util::stream_format(stream, " %s, [%s]+", regname(oprom[2]), regname(oprom[1]-1)); - flags |= 3; - } else { - util::stream_format(stream, " %s, [%s]", regname(oprom[2]), regname(oprom[1])); - flags |= 3; - } - break; - - case DASM_indirect_3: - if(oprom[1] & 0x01) { - util::stream_format(stream, " %s, %s, [%s]+", regname(oprom[3]), regname(oprom[2]), regname(oprom[1]-1)); - flags |= 4; - } else { - util::stream_format(stream, " %s, %s, [%s]", regname(oprom[3]), regname(oprom[2]), regname(oprom[1])); - flags |= 4; - } - break; - - case DASM_indexed_1: - if(oprom[1] & 0x01) { - if(oprom[1] == 0x01) - util::stream_format(stream, " %02x%02x", oprom[3], oprom[2]); - else - util::stream_format(stream, " %02x%02x[%s]", oprom[3], oprom[2], regname(oprom[1]-1)); - flags |= 4; - } else { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - if(oprom[1] == 0x00) { - if(delta < 0) - util::stream_format(stream, " %04x", delta & 0xffff); - else - util::stream_format(stream, " %02x", delta); - } else { - if(delta < 0) - util::stream_format(stream, " -%02x[%s]", -delta, regname(oprom[1])); - else - util::stream_format(stream, " %02x[%s]", delta, regname(oprom[1])); - } - flags |= 3; - } - break; - - case DASM_indexed_2: - if(oprom[1] & 0x01) { - if(oprom[1] == 0x01) - util::stream_format(stream, " %s, %02x%02x", regname(oprom[4]), oprom[3], oprom[2]); - else - util::stream_format(stream, " %s, %02x%02x[%s]", regname(oprom[4]), oprom[3], oprom[2], regname(oprom[1]-1)); - flags |= 5; - } else { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - if(oprom[1] == 0x00) { - if(delta < 0) - util::stream_format(stream, " %s, %04x", regname(oprom[3]), delta & 0xffff); - else - util::stream_format(stream, " %s, %02x", regname(oprom[3]), delta); - } else { - if(delta < 0) - util::stream_format(stream, " %s, -%02x[%s]", regname(oprom[3]), -delta, regname(oprom[1])); - else - util::stream_format(stream, " %s, %02x[%s]", regname(oprom[3]), delta, regname(oprom[1])); - } - flags |= 4; - } - break; - - case DASM_indexed_3: - if(oprom[1] & 0x01) { - if(oprom[1] == 0x01) - util::stream_format(stream, " %s, %s, %02x%02x", regname(oprom[5]), regname(oprom[4]), oprom[3], oprom[2]); - else - util::stream_format(stream, " %s, %s, %02x%02x[%s]", regname(oprom[5]), regname(oprom[4]), oprom[3], oprom[2], regname(oprom[1]-1)); - flags |= 6; - } else { - int delta = oprom[2]; - if(delta & 0x80) - delta -= 0x100; - if(oprom[1] == 0x00) { - if(delta < 0) - util::stream_format(stream, " %s, %s, %04x", regname(oprom[4]), regname(oprom[3]), delta & 0xffff); - else - util::stream_format(stream, " %s, %s, %02x", regname(oprom[4]), regname(oprom[3]), delta); - } else { - if(delta < 0) - util::stream_format(stream, " %s, %s, -%02x[%s]", regname(oprom[4]), regname(oprom[3]), -delta, regname(oprom[1])); - else - util::stream_format(stream, " %s, %s, %02x[%s]", regname(oprom[4]), regname(oprom[3]), delta, regname(oprom[1])); - } - flags |= 5; - } - break; - - default: - fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); - abort(); - }; - - return flags+off; -} - -uint32_t mcs96_device::disasm_min_opcode_bytes() const -{ - return 1; -} - -uint32_t mcs96_device::disasm_max_opcode_bytes() const -{ - return 7; -} - void mcs96_device::io_w8(uint8_t adr, uint8_t data) { switch(adr) { diff --git a/src/devices/cpu/mcs96/mcs96.h b/src/devices/cpu/mcs96/mcs96.h index 159d04bbdc3..3ff9f02d4d2 100644 --- a/src/devices/cpu/mcs96/mcs96.h +++ b/src/devices/cpu/mcs96/mcs96.h @@ -41,38 +41,6 @@ protected: F_Z = 0x8000 }; - struct disasm_entry { - const char *opcode, *opcode_fe; - int mode; - offs_t flags; - }; - - enum { - DASM_none, /* No parameters */ - DASM_nop_2, /* One ignored parameter byte */ - DASM_rel8, /* Relative, 8 bits */ - DASM_rel11, /* Relative, 11 bits */ - DASM_rel16, /* Relative, 16 bits */ - DASM_rrel8, /* Register + relative, 8 bits */ - DASM_brrel8, /* Bit test + register + relative, 8 bits */ - DASM_direct_1, /* Register-direct references, 1 operator */ - DASM_direct_2, /* Register-direct references, 2 operators */ - DASM_direct_3, /* Register-direct references, 3 operators */ - DASM_immed_1b, /* Immediate references to byte, 1 operator */ - DASM_immed_2b, /* Immediate references to byte, 2 operators */ - DASM_immed_or_reg_2b, /* Immediate references to byte or register, 2 operators */ - DASM_immed_3b, /* Immediate references to byte, 3 operators */ - DASM_immed_1w, /* Immediate references to word, 1 operator */ - DASM_immed_2w, /* Immediate references to word, 2 operators */ - DASM_immed_3w, /* Immediate references to word, 3 operators */ - DASM_indirect_1n, /* Indirect normal, 1 operator */ - DASM_indirect_1, /* Indirect, normal or auto-incrementing, 1 operator */ - DASM_indirect_2, /* Indirect, normal or auto-incrementing, 2 operators */ - DASM_indirect_3, /* Indirect, normal or auto-incrementing, 3 operators */ - DASM_indexed_1, /* Indexed, short or long, 1 operator */ - DASM_indexed_2, /* Indexed, short or long, 2 operators */ - DASM_indexed_3 /* Indexed, short or long, 3 operators */ - }; mcs96_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int data_width); @@ -95,14 +63,9 @@ protected: virtual void state_export(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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_generic(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, const disasm_entry *entries); - address_space_config program_config; address_space *program; - direct_read_data *direct; + direct_read_data<0> *direct; int icount, bcount, inst_state, cycles_scaling; uint8_t pending_irq; @@ -122,7 +85,6 @@ protected: virtual uint16_t io_r16(uint8_t adr) = 0; void recompute_bcount(uint64_t event_time); - static std::string regname(uint8_t reg); inline void next(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH; } inline void next_noirq(int cycles) { icount -= cycles_scaling*cycles; inst_state = STATE_FETCH_NOIRQ; } diff --git a/src/devices/cpu/mcs96/mcs96d.cpp b/src/devices/cpu/mcs96/mcs96d.cpp new file mode 100644 index 00000000000..1508fb3ca5f --- /dev/null +++ b/src/devices/cpu/mcs96/mcs96d.cpp @@ -0,0 +1,278 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + mcs96.h + + MCS96, 8098/8398/8798 branch + +***************************************************************************/ + +#include "emu.h" +#include "mcs96d.h" + +mcs96_disassembler::mcs96_disassembler(const disasm_entry *entries) : m_entries(entries) +{ +} + +u32 mcs96_disassembler::opcode_alignment() const +{ + return 1; +} + +std::string mcs96_disassembler::regname(uint8_t reg) +{ + switch(reg) { + case 0x18: + return "sp"; + break; + + case 0x19: + return "sph"; + break; + + default: + return util::string_format("%02x", reg); + break; + } +} + +offs_t mcs96_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + bool prefix_fe = false; + int off = 0; + if(opcodes.r8(pc) == 0xfe && m_entries[opcodes.r8(pc+1)].opcode_fe) { + prefix_fe = true; + pc++; + off++; + } + const disasm_entry &e = m_entries[opcodes.r8(pc)]; + uint32_t flags = e.flags | SUPPORTED; + util::stream_format(stream, "%s", prefix_fe ? e.opcode_fe : e.opcode); + + switch(e.mode) { + case DASM_none: + flags |= 1; + break; + + case DASM_nop_2: + util::stream_format(stream, " %02x", opcodes.r8(pc+1)); + flags |= 2; + break; + + case DASM_rel8: { + int delta = opcodes.r8(pc+1); + if(delta & 0x80) + delta -= 0x100; + util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff); + flags |= 2; + break; + } + + case DASM_rel11: { + int delta = ((opcodes.r8(pc) << 8) | opcodes.r8(pc+1)) & 0x7ff; + if(delta & 0x400) + delta -= 0x800; + util::stream_format(stream, " %04x", (pc+2+delta) & 0xffff); + flags |= 2; + break; + } + + case DASM_rel16: { + int delta = opcodes.r8(pc+1) | (opcodes.r8(pc+2) << 8); + util::stream_format(stream, " %04x", (pc+3+delta) & 0xffff); + flags |= 3; + break; + } + + case DASM_rrel8: { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + util::stream_format(stream, " %s, %04x", regname(opcodes.r8(pc+1)), (pc+3+delta) & 0xffff); + flags |= 3; + break; + } + + case DASM_brrel8: { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + util::stream_format(stream, " %d, %s, %04x", opcodes.r8(pc) & 7, regname(opcodes.r8(pc+1)), (pc+3+delta) & 0xffff); + flags |= 3; + break; + } + + case DASM_direct_1: + util::stream_format(stream, " %s", regname(opcodes.r8(pc+1))); + flags |= 2; + break; + + case DASM_direct_2: + util::stream_format(stream, " %s, %s", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + flags |= 3; + break; + + case DASM_direct_3: + util::stream_format(stream, " %s, %s, %s", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + flags |= 4; + break; + + case DASM_immed_1b: + util::stream_format(stream, " #%02x", opcodes.r8(pc+1)); + flags |= 2; + break; + + case DASM_immed_2b: + util::stream_format(stream, " %s, #%02x", regname(opcodes.r8(pc+2)), opcodes.r8(pc+1)); + flags |= 3; + break; + + case DASM_immed_or_reg_2b: + if(opcodes.r8(pc+1) >= 0x10) + util::stream_format(stream, " %s, %s", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + else + util::stream_format(stream, " %s, #%02x", regname(opcodes.r8(pc+2)), opcodes.r8(pc+1)); + flags |= 3; + break; + + case DASM_immed_3b: + util::stream_format(stream, " %s, %s, #%02x", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), opcodes.r8(pc+1)); + flags |= 4; + break; + + case DASM_immed_1w: + util::stream_format(stream, " #%02x%02x", opcodes.r8(pc+2), opcodes.r8(pc+1)); + flags |= 3; + break; + + case DASM_immed_2w: + util::stream_format(stream, " %s, #%02x%02x", regname(opcodes.r8(pc+3)), opcodes.r8(pc+2), opcodes.r8(pc+1)); + flags |= 4; + break; + + case DASM_immed_3w: + util::stream_format(stream, " %s, %s, #%02x%02x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), opcodes.r8(pc+2), opcodes.r8(pc+1)); + flags |= 5; + break; + + case DASM_indirect_1n: + util::stream_format(stream, " [%s]", regname(opcodes.r8(pc+1))); + flags |= 2; + break; + + case DASM_indirect_1: + if(opcodes.r8(pc+1) & 0x01) { + util::stream_format(stream, " [%s]+", regname(opcodes.r8(pc+1)-1)); + flags |= 2; + } else { + util::stream_format(stream, " [%s]", regname(opcodes.r8(pc+1))); + flags |= 2; + } + break; + + case DASM_indirect_2: + if(opcodes.r8(pc+1) & 0x01) { + util::stream_format(stream, " %s, [%s]+", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)-1)); + flags |= 3; + } else { + util::stream_format(stream, " %s, [%s]", regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + flags |= 3; + } + break; + + case DASM_indirect_3: + if(opcodes.r8(pc+1) & 0x01) { + util::stream_format(stream, " %s, %s, [%s]+", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1)-1)); + flags |= 4; + } else { + util::stream_format(stream, " %s, %s, [%s]", regname(opcodes.r8(pc+3)), regname(opcodes.r8(pc+2)), regname(opcodes.r8(pc+1))); + flags |= 4; + } + break; + + case DASM_indexed_1: + if(opcodes.r8(pc+1) & 0x01) { + if(opcodes.r8(pc+1) == 0x01) + util::stream_format(stream, " %02x%02x", opcodes.r8(pc+3), opcodes.r8(pc+2)); + else + util::stream_format(stream, " %02x%02x[%s]", opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1)); + flags |= 4; + } else { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + if(opcodes.r8(pc+1) == 0x00) { + if(delta < 0) + util::stream_format(stream, " %04x", delta & 0xffff); + else + util::stream_format(stream, " %02x", delta); + } else { + if(delta < 0) + util::stream_format(stream, " -%02x[%s]", -delta, regname(opcodes.r8(pc+1))); + else + util::stream_format(stream, " %02x[%s]", delta, regname(opcodes.r8(pc+1))); + } + flags |= 3; + } + break; + + case DASM_indexed_2: + if(opcodes.r8(pc+1) & 0x01) { + if(opcodes.r8(pc+1) == 0x01) + util::stream_format(stream, " %s, %02x%02x", regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2)); + else + util::stream_format(stream, " %s, %02x%02x[%s]", regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1)); + flags |= 5; + } else { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + if(opcodes.r8(pc+1) == 0x00) { + if(delta < 0) + util::stream_format(stream, " %s, %04x", regname(opcodes.r8(pc+3)), delta & 0xffff); + else + util::stream_format(stream, " %s, %02x", regname(opcodes.r8(pc+3)), delta); + } else { + if(delta < 0) + util::stream_format(stream, " %s, -%02x[%s]", regname(opcodes.r8(pc+3)), -delta, regname(opcodes.r8(pc+1))); + else + util::stream_format(stream, " %s, %02x[%s]", regname(opcodes.r8(pc+3)), delta, regname(opcodes.r8(pc+1))); + } + flags |= 4; + } + break; + + case DASM_indexed_3: + if(opcodes.r8(pc+1) & 0x01) { + if(opcodes.r8(pc+1) == 0x01) + util::stream_format(stream, " %s, %s, %02x%02x", regname(opcodes.r8(pc+5)), regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2)); + else + util::stream_format(stream, " %s, %s, %02x%02x[%s]", regname(opcodes.r8(pc+5)), regname(opcodes.r8(pc+4)), opcodes.r8(pc+3), opcodes.r8(pc+2), regname(opcodes.r8(pc+1)-1)); + flags |= 6; + } else { + int delta = opcodes.r8(pc+2); + if(delta & 0x80) + delta -= 0x100; + if(opcodes.r8(pc+1) == 0x00) { + if(delta < 0) + util::stream_format(stream, " %s, %s, %04x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta & 0xffff); + else + util::stream_format(stream, " %s, %s, %02x", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta); + } else { + if(delta < 0) + util::stream_format(stream, " %s, %s, -%02x[%s]", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), -delta, regname(opcodes.r8(pc+1))); + else + util::stream_format(stream, " %s, %s, %02x[%s]", regname(opcodes.r8(pc+4)), regname(opcodes.r8(pc+3)), delta, regname(opcodes.r8(pc+1))); + } + flags |= 5; + } + break; + + default: + fprintf(stderr, "Unhandled dasm mode %d\n", e.mode); + abort(); + }; + + return flags+off; +} diff --git a/src/devices/cpu/mcs96/mcs96d.h b/src/devices/cpu/mcs96/mcs96d.h new file mode 100644 index 00000000000..453727258bf --- /dev/null +++ b/src/devices/cpu/mcs96/mcs96d.h @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont +/*************************************************************************** + + mcs96.h + + MCS96 + +***************************************************************************/ + +#ifndef MAME_CPU_MCS96_MCS96D_H +#define MAME_CPU_MCS96_MCS96D_H + +#pragma once + +class mcs96_disassembler : public util::disasm_interface +{ +public: + struct disasm_entry { + const char *opcode, *opcode_fe; + int mode; + offs_t flags; + }; + + mcs96_disassembler(const disasm_entry *entries); + virtual ~mcs96_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum { + DASM_none, /* No parameters */ + DASM_nop_2, /* One ignored parameter byte */ + DASM_rel8, /* Relative, 8 bits */ + DASM_rel11, /* Relative, 11 bits */ + DASM_rel16, /* Relative, 16 bits */ + DASM_rrel8, /* Register + relative, 8 bits */ + DASM_brrel8, /* Bit test + register + relative, 8 bits */ + DASM_direct_1, /* Register-direct references, 1 operator */ + DASM_direct_2, /* Register-direct references, 2 operators */ + DASM_direct_3, /* Register-direct references, 3 operators */ + DASM_immed_1b, /* Immediate references to byte, 1 operator */ + DASM_immed_2b, /* Immediate references to byte, 2 operators */ + DASM_immed_or_reg_2b, /* Immediate references to byte or register, 2 operators */ + DASM_immed_3b, /* Immediate references to byte, 3 operators */ + DASM_immed_1w, /* Immediate references to word, 1 operator */ + DASM_immed_2w, /* Immediate references to word, 2 operators */ + DASM_immed_3w, /* Immediate references to word, 3 operators */ + DASM_indirect_1n, /* Indirect normal, 1 operator */ + DASM_indirect_1, /* Indirect, normal or auto-incrementing, 1 operator */ + DASM_indirect_2, /* Indirect, normal or auto-incrementing, 2 operators */ + DASM_indirect_3, /* Indirect, normal or auto-incrementing, 3 operators */ + DASM_indexed_1, /* Indexed, short or long, 1 operator */ + DASM_indexed_2, /* Indexed, short or long, 2 operators */ + DASM_indexed_3 /* Indexed, short or long, 3 operators */ + }; + + const disasm_entry *m_entries; + + static std::string regname(uint8_t reg); +}; + +#endif diff --git a/src/devices/cpu/mcs96/mcs96make.py b/src/devices/cpu/mcs96/mcs96make.py index b4844942e3d..2a9398cd662 100644 --- a/src/devices/cpu/mcs96/mcs96make.py +++ b/src/devices/cpu/mcs96/mcs96make.py @@ -117,7 +117,7 @@ class OpcodeList: self.opcode_per_id[i] = inf def save_dasm(self, f, t): - print("const %s_device::disasm_entry %s_device::disasm_entries[0x100] = {" % (t, t), file=f) + print("const %s_disassembler::disasm_entry %s_disassembler::disasm_entries[0x100] = {" % (t, t), file=f) for i in range(0, 0x100): if i in self.opcode_per_id: opc = self.opcode_per_id[i] @@ -125,9 +125,9 @@ class OpcodeList: if i + 0xfe00 in self.opcode_per_id: alt = "\"" + self.opcode_per_id[i+0xfe00].name + "\"" if opc.name == "scall" or opc.name == "lcall": - flags = "DASMFLAG_STEP_OVER" + flags = "STEP_OVER" elif opc.name == "rts": - flags = "DASMFLAG_STEP_OUT" + flags = "STEP_OUT" else: flags = "0" print("\t{ \"%s\", %s, DASM_%s, %s }," % (opc.name, alt, opc.amode, flags), file=f) @@ -170,25 +170,26 @@ class OpcodeList: print("}", file=f) def main(argv): - if len(argv) != 4: + if len(argv) != 5: print(USAGE % argv[0]) return 1 - - t = argv[1] - opcodes = OpcodeList(argv[2], t == "i8xc196") + + m = argv[1] + t = argv[2] + opcodes = OpcodeList(argv[3], t == "i8xc196") try: - f = open(argv[3], "w") + f = open(argv[4], "w") except Exception: err = sys.exc_info()[1] - sys.stderr.write("cannot write file %s [%s]\n" % (argv[3], err)) + sys.stderr.write("cannot write file %s [%s]\n" % (argv[4], err)) sys.exit(1) - if t != "mcs96": + if t != "mcs96" and m == "d": opcodes.save_dasm(f, t) - if t != "i8x9x": + if t != "i8x9x" and m == "s": opcodes.save_opcodes(f, t) - if t != "mcs96": + if t != "mcs96" and m == "s": opcodes.save_exec(f, t) f.close() diff --git a/src/devices/cpu/melps4/m58846.cpp b/src/devices/cpu/melps4/m58846.cpp index 6f4924da86e..48c75803439 100644 --- a/src/devices/cpu/melps4/m58846.cpp +++ b/src/devices/cpu/melps4/m58846.cpp @@ -30,15 +30,6 @@ m58846_device::m58846_device(const machine_config &mconfig, const char *tag, dev { } -// disasm -offs_t m58846_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE(m58846); - return CPU_DISASSEMBLE_NAME(m58846)(this, stream, pc, oprom, opram, options); -} - - - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- diff --git a/src/devices/cpu/melps4/m58846.h b/src/devices/cpu/melps4/m58846.h index 4a3bf8674bf..34042e6a61b 100644 --- a/src/devices/cpu/melps4/m58846.h +++ b/src/devices/cpu/melps4/m58846.h @@ -29,9 +29,6 @@ protected: // device_execute_interface overrides virtual void execute_one() override; - // device_disasm_interface overrides - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; - // timers virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void write_v(uint8_t data) override; diff --git a/src/devices/cpu/melps4/melps4.cpp b/src/devices/cpu/melps4/melps4.cpp index bf386f1e30d..a749f4bc5c6 100644 --- a/src/devices/cpu/melps4/melps4.cpp +++ b/src/devices/cpu/melps4/melps4.cpp @@ -39,6 +39,7 @@ #include "emu.h" #include "melps4.h" +#include "melps4d.h" #include "debugger.h" @@ -453,7 +454,7 @@ void melps4_cpu_device::execute_run() // fetch next opcode debugger_instruction_hook(this, m_pc); m_icount--; - m_op = m_program->read_word(m_pc << 1) & 0x1ff; + m_op = m_program->read_word(m_pc) & 0x1ff; m_bitmask = 1 << (m_op & 3); m_pc = (m_pc & ~0x7f) | ((m_pc + 1) & 0x7f); // stays in the same page @@ -471,3 +472,8 @@ void melps4_cpu_device::execute_run() execute_one(); } } + +util::disasm_interface *melps4_cpu_device::create_disassembler() +{ + return new melps4_disassembler; +} diff --git a/src/devices/cpu/melps4/melps4.h b/src/devices/cpu/melps4/melps4.h index 1f9a7752cd6..c268d74e508 100644 --- a/src/devices/cpu/melps4/melps4.h +++ b/src/devices/cpu/melps4/melps4.h @@ -135,8 +135,8 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } + virtual util::disasm_interface *create_disassembler() override; + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; address_space_config m_program_config; diff --git a/src/devices/cpu/melps4/melps4d.cpp b/src/devices/cpu/melps4/melps4d.cpp index efd199097c5..8ab9c0bd2c7 100644 --- a/src/devices/cpu/melps4/melps4d.cpp +++ b/src/devices/cpu/melps4/melps4d.cpp @@ -10,27 +10,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "melps4.h" +#include "melps4d.h" - -// opcode mnemonics -enum e_mnemonics -{ - em_ILL, - em_TAB, em_TBA, em_TAY, em_TYA, em_TEAB, em_TABE, em_TEPA, em_TXA, em_TAX, - em_LXY, em_LZ, em_INY, em_DEY, em_LCPS, em_SADR, - em_TAM, em_XAM, em_XAMD, em_XAMI, - em_LA, em_AM, em_AMC, em_AMCS, em_A, em_SC, em_RC, em_SZC, em_CMA, em_RL, em_RR, - em_SB, em_RB, em_SZB, em_SEAM, em_SEY, - em_TLA, em_THA, em_TAJ, em_XAL, em_XAH, em_LC7, em_DEC, em_SHL, em_RHL, em_CPA, em_CPAS, em_CPAE, em_SZJ, - em_T1AB, em_TRAB, em_T2AB, em_TAB1, em_TABR, em_TAB2, em_TVA, em_TWA, em_SNZ1, em_SNZ2, - em_BA, em_SP, em_B, em_BM, em_RT, em_RTS, em_RTI, - em_CLD, em_CLS, em_CLDS, em_SD, em_RD, em_SZD, em_OSAB, em_OSPA, em_OSE, em_IAS, em_OFA, em_IAF, em_OGA, em_IAK, em_SZK, em_SU, em_RU, - em_EI, em_DI, em_INTH, em_INTL, em_NOP -}; - -static const char *const em_name[] = +const char *const melps4_disassembler::em_name[] = { "?", "TAB", "TBA", "TAY", "TYA", "TEAB", "TABE", "TEPA", "TXA", "TAX", @@ -46,7 +28,7 @@ static const char *const em_name[] = }; // number of bits per opcode parameter -static const uint8_t em_bits[] = +const uint8_t melps4_disassembler::em_bits[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -61,10 +43,7 @@ static const uint8_t em_bits[] = 0, 0, 0, 0, 0 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t em_flags[] = +const uint32_t melps4_disassembler::em_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -74,7 +53,7 @@ static const uint32_t em_flags[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, _OVER, _OUT, _OUT, _OUT, + 0, 0, 0, STEP_OVER, STEP_OUT, STEP_OUT, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -83,7 +62,7 @@ static const uint32_t em_flags[] = // M58846 disasm -static const uint8_t m58846_opmap[0xc0] = +const uint8_t melps4_disassembler::m58846_opmap[0xc0] = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F em_NOP, em_BA, em_INY, em_DEY, em_DI, em_EI, em_RU, em_SU, 0, em_TABE, em_AM, em_OSE, em_TYA, 0, 0, em_CMA, // 0x @@ -100,9 +79,9 @@ static const uint8_t m58846_opmap[0xc0] = em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA, em_LA // Bx }; -CPU_DISASSEMBLE(m58846) +offs_t melps4_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint16_t op = (oprom[0] | oprom[1] << 8) & 0x1ff; + uint16_t op = opcodes.r16(pc) & 0x1ff; // get opcode uint8_t instr; @@ -136,5 +115,20 @@ CPU_DISASSEMBLE(m58846) util::stream_format(stream, " %d", param); } - return 1 | em_flags[instr] | DASMFLAG_SUPPORTED; + return 1 | em_flags[instr] | SUPPORTED; +} + +u32 melps4_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 melps4_disassembler::interface_flags() const +{ + return PAGED; +} + +u32 melps4_disassembler::page_address_bits() const +{ + return 7; } diff --git a/src/devices/cpu/melps4/melps4d.h b/src/devices/cpu/melps4/melps4d.h new file mode 100644 index 00000000000..229358e7432 --- /dev/null +++ b/src/devices/cpu/melps4/melps4d.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Mitsubishi MELPS 4 MCU family disassembler + + Not counting the extra opcodes for peripherals (eg. timers, A/D), + each MCU in the series has small differences in the opcode map. + +*/ + +#ifndef MAME_CPU_MELPS4_MELPS4D_H +#define MAME_CPU_MELPS4_MELPS4D_H + +#pragma once + +class melps4_disassembler : public util::disasm_interface +{ +public: + melps4_disassembler() = default; + virtual ~melps4_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // opcode mnemonics + enum e_mnemonics + { + em_ILL, + em_TAB, em_TBA, em_TAY, em_TYA, em_TEAB, em_TABE, em_TEPA, em_TXA, em_TAX, + em_LXY, em_LZ, em_INY, em_DEY, em_LCPS, em_SADR, + em_TAM, em_XAM, em_XAMD, em_XAMI, + em_LA, em_AM, em_AMC, em_AMCS, em_A, em_SC, em_RC, em_SZC, em_CMA, em_RL, em_RR, + em_SB, em_RB, em_SZB, em_SEAM, em_SEY, + em_TLA, em_THA, em_TAJ, em_XAL, em_XAH, em_LC7, em_DEC, em_SHL, em_RHL, em_CPA, em_CPAS, em_CPAE, em_SZJ, + em_T1AB, em_TRAB, em_T2AB, em_TAB1, em_TABR, em_TAB2, em_TVA, em_TWA, em_SNZ1, em_SNZ2, + em_BA, em_SP, em_B, em_BM, em_RT, em_RTS, em_RTI, + em_CLD, em_CLS, em_CLDS, em_SD, em_RD, em_SZD, em_OSAB, em_OSPA, em_OSE, em_IAS, em_OFA, em_IAF, em_OGA, em_IAK, em_SZK, em_SU, em_RU, + em_EI, em_DI, em_INTH, em_INTL, em_NOP + }; + + static const char *const em_name[]; + static const uint8_t em_bits[]; + static const uint32_t em_flags[]; + static const uint8_t m58846_opmap[0xc0]; + +}; + +#endif diff --git a/src/devices/cpu/minx/minx.cpp b/src/devices/cpu/minx/minx.cpp index 883abb6f843..7e4a898e22c 100644 --- a/src/devices/cpu/minx/minx.cpp +++ b/src/devices/cpu/minx/minx.cpp @@ -46,6 +46,7 @@ TODO: #include "emu.h" #include "minx.h" +#include "minxd.h" #include "debugger.h" #define FLAG_I 0x80 @@ -234,8 +235,7 @@ void minx_cpu_device::execute_set_input(int inputnum, int state) } -offs_t minx_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *minx_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( minx ); - return CPU_DISASSEMBLE_NAME(minx)(this, stream, pc, oprom, opram, options); + return new minx_disassembler; } diff --git a/src/devices/cpu/minx/minx.h b/src/devices/cpu/minx/minx.h index babc3d182aa..57f0456c76b 100644 --- a/src/devices/cpu/minx/minx.h +++ b/src/devices/cpu/minx/minx.h @@ -39,9 +39,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/minx/minxd.cpp b/src/devices/cpu/minx/minxd.cpp index 0e3b9d5b090..413f588369f 100644 --- a/src/devices/cpu/minx/minxd.cpp +++ b/src/devices/cpu/minx/minxd.cpp @@ -8,61 +8,10 @@ ************************************************************/ #include "emu.h" -#include "debugger.h" -#include "minx.h" +#include "minxd.h" -enum e_mnemonic { - zADD=0, zADDC, zAND, zBCDD, zBCDE, zBCDX, zCALL, zCALLC, zCALLG, zCALLGE, zCALLL, - zCALLLE, zCALLN, zCALLNC, zCALLNO, zCALLNZ, zCALLO, zCALLP, zCALLNX0, - zCALLNX1, zCALLNX2, zCALLNX3, zCALLX0, zCALLX1, zCALLX2, zCALLX3, zCALLZ, - zCMP, zCMPN, zDEC, zDIV, zEXT, zHALT, zINC, zINT, - zJC, zJDBNZ, zJG, zJGE, zJINT, zJL, zJLE, zJMP, - zJN, zJNX0, zJNX1, zJNX2, zJNX3, zJNC, zJNO, zJNZ, - zJO, zJP, zJX0, zJX1, zJX2, zJX3, zJZ, zMOV, - zMUL, zNEG, zNOP, zNOT, zOR, zPOP, zPOPA, zPOPAX, - zPOPX, zPUSH, zPUSHA, zPUSHAX, zPUSHX, zRET, zRETI, zRETSKIP, - zROL, zROLC, zROR, zRORC, zSAL, zSAR, zSHL, zSHR, zSUB, - zSUBC, zTEST, zXCHG, zXOR, zDB -}; - -enum e_operand { - R_A=1, /* A */ - R_B, /* B */ - R_L, /* L */ - R_H, /* H */ - R_N, /* N */ - R_F, /* F */ - R_SP, /* SP */ - R_BA, /* BA */ - R_HL, /* HL */ - R_X, /* X */ - R_Y, /* Y */ - R_U, /* U */ - R_V, /* V */ - R_I, /* I */ - R_XI, /* XI */ - R_YI, /* YI */ - R_PC, /* PC */ - I_8, /* 8 bit immediate */ - I_16, /* 16 bit immediate */ - D_8, /* PC + 8 bit displacement (signed) */ - D_16, /* PC + 16 bit displacement */ - S_8, /* SP + 8 bit displacement (signed) */ - M_IHL, /* [I+HL] */ - M_N8, /* [I+N+ofs8] */ - M_I16, /* [I+ofs16] */ - M_X, /* [X] */ - M_Y, /* [Y] */ - M_X8, /* [X + 8 bit displacement (signed)] */ - M_Y8, /* [Y + 8 bit displacement (signed)] */ - M_XL, /* [X + L (signed)] */ - M_YL, /* [Y + L (signed)] */ - M_16, /* [16bit] */ - M_HL, /* [HL] */ - OP, OP1 -}; -static const char *const s_mnemonic[] = { +const char *const minx_disassembler::s_mnemonic[] = { "add", "addc", "and", "bcdd", "bcde", "bcdx", "call", "callc", "callg", "callge", "calll", "callle", "calln", "callnc", "callno", "callnz", "callo", "callp", "callnx0", "callnx1", "callnx2", "callnx3", "callx0", "callx1", "callx2", "callx3", "callz", @@ -76,30 +25,21 @@ static const char *const s_mnemonic[] = { "subc", "test", "xchg", "xor", "db" }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t s_flags[] = { - 0, 0, 0, 0, 0, 0, _OVER, _OVER, _OVER, _OVER, _OVER, - _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, - _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, _OVER, - 0, 0, 0, 0, 0, _OVER, 0, _OVER, +const uint32_t minx_disassembler::s_flags[] = { + 0, 0, 0, 0, 0, 0, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, + STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, + STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, STEP_OVER, + 0, 0, 0, 0, 0, STEP_OVER, 0, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, _OUT, _OUT, _OUT, + 0, 0, 0, 0, 0, STEP_OUT, STEP_OUT, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -struct minxdasm { - uint8_t mnemonic; - uint8_t argument1; - uint8_t argument2; -}; - -static const minxdasm mnemonic[256] = { +const minx_disassembler::minxdasm minx_disassembler::mnemonic[256] = { /* 00 - 0F */ {zADD,R_A,R_A}, {zADD,R_A,R_B}, {zADD,R_A,I_8}, {zADD,R_A,M_IHL}, {zADD,R_A,M_N8}, {zADD,R_A,M_I16}, {zADD,R_A,M_X}, {zADD,R_A,M_Y}, @@ -182,7 +122,7 @@ static const minxdasm mnemonic[256] = { {zINT,I_8,0}, {zJINT,I_8,0}, {zDB,OP,0}, {zNOP,0,0} }; -static const minxdasm mnemonic_ce[256] = { +const minx_disassembler::minxdasm minx_disassembler::mnemonic_ce[256] = { /* 00 - 0F */ {zADD,R_A,M_X8}, {zADD,R_A,M_Y8}, {zADD,R_A,M_XL}, {zADD,R_A,M_YL}, {zADD,M_IHL,R_A}, {zADD,M_IHL,I_8}, {zADD,M_IHL,M_X}, {zADD,M_IHL,M_Y}, @@ -265,7 +205,7 @@ static const minxdasm mnemonic_ce[256] = { {zCALLX0,D_8,0}, {zCALLX1,D_8,0}, {zCALLX2,D_8,0}, {zCALLX3,D_8,0} }; -static const minxdasm mnemonic_cf[256] = { +const minx_disassembler::minxdasm minx_disassembler::mnemonic_cf[256] = { /* 00 - 0F */ {zADD,R_BA,R_BA}, {zADD,R_BA,R_HL}, {zADD,R_BA,R_X}, {zADD,R_BA,R_Y}, {zADDC,R_BA,R_BA}, {zADDC,R_BA,R_HL}, {zADDC,R_BA,R_X}, {zADDC,R_BA,R_Y}, @@ -367,76 +307,81 @@ case R_XI: util::stream_format(stream, "%cXI", fill); break; \ case R_YI: util::stream_format(stream, "%cYI", fill); break; \ case R_PC: util::stream_format(stream, "%cPC", fill); break; \ case I_8: /* 8 bit immediate */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%c$%02X", fill, ea); \ break; \ case I_16: /* 16 bit immediate */ \ - ea = oprom[pos++]; \ - ea += oprom[pos++] << 8; \ + ea = opcodes.r8(pos++); \ + ea += opcodes.r8(pos++) << 8; \ util::stream_format(stream, "%c$%04X", fill, ea); \ break; \ case D_8: /* PC + 8 bit displacement (signed) */ \ - ofs8 = oprom[pos++]; \ + ofs8 = opcodes.r8(pos++); \ util::stream_format(stream, "%c$%04X", fill, pc + pos - 1 + ofs8); \ break; \ case D_16: /* PC + 16 bit displacement */ \ - ea = oprom[pos++]; \ - ea += oprom[pos++] << 8; \ + ea = opcodes.r8(pos++); \ + ea += opcodes.r8(pos++) << 8; \ ea = ea - 1; \ util::stream_format(stream, "%c$%04X", fill, pc + pos + ea); \ break; \ case S_8: /* SP + 8 bit displacement (signed) */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%cSP+$%02X", fill, ea); \ break; \ case M_IHL: util::stream_format(stream, "%c[I+HL]", fill); break; \ case M_N8: /* [I+N+ofs8] */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%c[I+N+$%02X]", fill, ea); \ break; \ case M_I16: /* [I+ofs16] */ \ - ea = oprom[pos++]; \ - ea += oprom[pos++] << 8; \ + ea = opcodes.r8(pos++); \ + ea += opcodes.r8(pos++) << 8; \ util::stream_format(stream, "%c[I+$%04X]", fill, ea); \ break; \ case M_X: util::stream_format(stream, "%c[X]", fill); break; \ case M_Y: util::stream_format(stream, "%c[Y]", fill); break; \ case M_X8: /* [X + 8 bit displacement (signed)] */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%c[X+$%02X]", fill, ea); \ break; \ case M_Y8: /* [Y + 8 bit displacement (signed)] */ \ - ea = oprom[pos++]; \ + ea = opcodes.r8(pos++); \ util::stream_format(stream, "%c[Y+$%02X]", fill, ea); \ break; \ case M_XL: util::stream_format(stream, "%c[X+L]", fill); break; \ case M_YL: util::stream_format(stream, "%c[Y+L]", fill); break; \ case M_16: /* [16bit] */ \ - ea = oprom[pos++]; \ - ea += oprom[pos++] << 8; \ + ea = opcodes.r8(pos++); \ + ea += opcodes.r8(pos++) << 8; \ util::stream_format(stream, "%c[$%04X]", fill, ea); \ break; \ case M_HL: util::stream_format(stream, "%c[HL]", fill); break; \ case OP: util::stream_format(stream, "%c$%02X", fill, op); break; \ case OP1: util::stream_format(stream, "%c$%02X", fill, op1); break; -CPU_DISASSEMBLE(minx) +u32 minx_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t minx_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const minxdasm *instr; uint8_t op, op1; int8_t ofs8; uint16_t ea; - int pos = 0; + offs_t pos = pc; - op1 = op = oprom[pos++]; + op1 = op = opcodes.r8(pos++); switch (op) { case 0xCE: - op = oprom[pos++]; + op = opcodes.r8(pos++); instr = &mnemonic_ce[op]; break; case 0xCF: - op = oprom[pos++]; + op = opcodes.r8(pos++); instr = &mnemonic_cf[op]; break; default: @@ -460,5 +405,5 @@ CPU_DISASSEMBLE(minx) HANDLE_ARGUMENT; } } - return pos | s_flags[instr->mnemonic] | DASMFLAG_SUPPORTED; + return (pos - pc) | s_flags[instr->mnemonic] | SUPPORTED; } diff --git a/src/devices/cpu/minx/minxd.h b/src/devices/cpu/minx/minxd.h new file mode 100644 index 00000000000..bb7a6da4e0d --- /dev/null +++ b/src/devices/cpu/minx/minxd.h @@ -0,0 +1,89 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/************************************************************ + + Nintendo Minx CPU disassembly + + +************************************************************/ + +#ifndef MAME_CPU_MINX_MINXDASM_H +#define MAME_CPU_MINX_MINXDASM_H + +#pragma once + +class minx_disassembler : public util::disasm_interface +{ +public: + minx_disassembler() = default; + virtual ~minx_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonic { + zADD=0, zADDC, zAND, zBCDD, zBCDE, zBCDX, zCALL, zCALLC, zCALLG, zCALLGE, zCALLL, + zCALLLE, zCALLN, zCALLNC, zCALLNO, zCALLNZ, zCALLO, zCALLP, zCALLNX0, + zCALLNX1, zCALLNX2, zCALLNX3, zCALLX0, zCALLX1, zCALLX2, zCALLX3, zCALLZ, + zCMP, zCMPN, zDEC, zDIV, zEXT, zHALT, zINC, zINT, + zJC, zJDBNZ, zJG, zJGE, zJINT, zJL, zJLE, zJMP, + zJN, zJNX0, zJNX1, zJNX2, zJNX3, zJNC, zJNO, zJNZ, + zJO, zJP, zJX0, zJX1, zJX2, zJX3, zJZ, zMOV, + zMUL, zNEG, zNOP, zNOT, zOR, zPOP, zPOPA, zPOPAX, + zPOPX, zPUSH, zPUSHA, zPUSHAX, zPUSHX, zRET, zRETI, zRETSKIP, + zROL, zROLC, zROR, zRORC, zSAL, zSAR, zSHL, zSHR, zSUB, + zSUBC, zTEST, zXCHG, zXOR, zDB + }; + + enum e_operand { + R_A=1, /* A */ + R_B, /* B */ + R_L, /* L */ + R_H, /* H */ + R_N, /* N */ + R_F, /* F */ + R_SP, /* SP */ + R_BA, /* BA */ + R_HL, /* HL */ + R_X, /* X */ + R_Y, /* Y */ + R_U, /* U */ + R_V, /* V */ + R_I, /* I */ + R_XI, /* XI */ + R_YI, /* YI */ + R_PC, /* PC */ + I_8, /* 8 bit immediate */ + I_16, /* 16 bit immediate */ + D_8, /* PC + 8 bit displacement (signed) */ + D_16, /* PC + 16 bit displacement */ + S_8, /* SP + 8 bit displacement (signed) */ + M_IHL, /* [I+HL] */ + M_N8, /* [I+N+ofs8] */ + M_I16, /* [I+ofs16] */ + M_X, /* [X] */ + M_Y, /* [Y] */ + M_X8, /* [X + 8 bit displacement (signed)] */ + M_Y8, /* [Y + 8 bit displacement (signed)] */ + M_XL, /* [X + L (signed)] */ + M_YL, /* [Y + L (signed)] */ + M_16, /* [16bit] */ + M_HL, /* [HL] */ + OP, OP1 + }; + + struct minxdasm { + uint8_t mnemonic; + uint8_t argument1; + uint8_t argument2; + }; + + static const char *const s_mnemonic[]; + static const uint32_t s_flags[]; + static const minxdasm mnemonic[256]; + static const minxdasm mnemonic_ce[256]; + static const minxdasm mnemonic_cf[256]; +}; + +#endif diff --git a/src/devices/cpu/mips/mips3.cpp b/src/devices/cpu/mips/mips3.cpp index d55d26623d1..f71f4bb738c 100644 --- a/src/devices/cpu/mips/mips3.cpp +++ b/src/devices/cpu/mips/mips3.cpp @@ -12,6 +12,7 @@ #include "debugger.h" #include "mips3.h" #include "mips3com.h" +#include "mips3dsm.h" #define ENABLE_OVERFLOWS 0 @@ -192,7 +193,10 @@ mips3_device::mips3_device(const machine_config &mconfig, device_type type, cons memset(m_hotspot, 0, sizeof(m_hotspot)); // configure the virtual TLB - set_vtlb_fixed_entries(2 * m_tlbentries + 2); + if (m_flavor == MIPS3_TYPE_TX4925) + set_vtlb_fixed_entries(2 * m_tlbentries + 3); + else + set_vtlb_fixed_entries(2 * m_tlbentries + 2); } device_memory_interface::space_config_vector mips3_device::memory_space_config() const @@ -333,7 +337,7 @@ void mips3_device::device_start() m_cpu_clock = clock(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); /* set up the endianness */ m_program->accessors(m_memory); @@ -940,11 +944,16 @@ void mips3_device::device_reset() entry->entry_lo[1] = 0xfffffff8; vtlb_load(2 * tlbindex + 0, 0, 0, 0); vtlb_load(2 * tlbindex + 1, 0, 0, 0); + if (m_flavor == MIPS3_TYPE_TX4925) + vtlb_load(2 * tlbindex + 2, 0, 0, 0); } /* load the fixed TLB range */ vtlb_load(2 * m_tlbentries + 0, (0xa0000000 - 0x80000000) >> MIPS3_MIN_PAGE_SHIFT, 0x80000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID); vtlb_load(2 * m_tlbentries + 1, (0xc0000000 - 0xa0000000) >> MIPS3_MIN_PAGE_SHIFT, 0xa0000000, 0x00000000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID); + // TX4925 on-board peripherals pass-through + if (m_flavor == MIPS3_TYPE_TX4925) + vtlb_load(2 * m_tlbentries + 2, (0xff200000 - 0xff1f0000) >> MIPS3_MIN_PAGE_SHIFT, 0xff1f0000, 0xff1f0000 | VTLB_READ_ALLOWED | VTLB_WRITE_ALLOWED | VTLB_FETCH_ALLOWED | VTLB_FLAG_VALID); m_core->mode = (MODE_KERNEL << 1) | 0; m_cache_dirty = true; @@ -967,14 +976,9 @@ bool mips3_device::memory_translate(int spacenum, int intention, offs_t &address } -offs_t mips3_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mips3_device::create_disassembler() { - uint32_t op = *(uint32_t *)oprom; - if (m_bigendian) - op = big_endianize_int32(op); - else - op = little_endianize_int32(op); - return dasmmips3(stream, pc, op); + return new mips3_disassembler; } @@ -985,12 +989,6 @@ offs_t mips3_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u inline bool mips3_device::RBYTE(offs_t address, uint32_t *result) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_byte)(*m_program, address); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1024,12 +1022,6 @@ inline bool mips3_device::RBYTE(offs_t address, uint32_t *result) inline bool mips3_device::RHALF(offs_t address, uint32_t *result) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_word)(*m_program, address); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1063,12 +1055,6 @@ inline bool mips3_device::RHALF(offs_t address, uint32_t *result) inline bool mips3_device::RWORD(offs_t address, uint32_t *result) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_dword)(*m_program, address); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1102,12 +1088,6 @@ inline bool mips3_device::RWORD(offs_t address, uint32_t *result) inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_t mem_mask) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_dword_masked)(*m_program, address, mem_mask); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1131,11 +1111,6 @@ inline bool mips3_device::RWORD_MASKED(offs_t address, uint32_t *result, uint32_ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_qword)(*m_program, address); - return true; - } const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1159,12 +1134,6 @@ inline bool mips3_device::RDOUBLE(offs_t address, uint64_t *result) inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint64_t mem_mask) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - *result = (*m_memory.read_qword_masked)(*m_program, address, mem_mask); - return true; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_READ_ALLOWED) { @@ -1188,12 +1157,6 @@ inline bool mips3_device::RDOUBLE_MASKED(offs_t address, uint64_t *result, uint6 inline void mips3_device::WBYTE(offs_t address, uint8_t data) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_byte)(*m_program, address, data); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1228,11 +1191,6 @@ inline void mips3_device::WBYTE(offs_t address, uint8_t data) inline void mips3_device::WHALF(offs_t address, uint16_t data) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_word)(*m_program, address, data); - return; - } const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1267,12 +1225,6 @@ inline void mips3_device::WHALF(offs_t address, uint16_t data) inline void mips3_device::WWORD(offs_t address, uint32_t data) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_dword)(*m_program, address, data); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1307,12 +1259,6 @@ inline void mips3_device::WWORD(offs_t address, uint32_t data) inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t mem_mask) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_dword_masked)(*m_program, address, data, mem_mask); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1337,12 +1283,6 @@ inline void mips3_device::WWORD_MASKED(offs_t address, uint32_t data, uint32_t m inline void mips3_device::WDOUBLE(offs_t address, uint64_t data) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_qword)(*m_program, address, data); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { @@ -1367,12 +1307,6 @@ inline void mips3_device::WDOUBLE(offs_t address, uint64_t data) inline void mips3_device::WDOUBLE_MASKED(offs_t address, uint64_t data, uint64_t mem_mask) { - if ((m_flavor == MIPS3_TYPE_TX4925) && ((address & 0xffff0000) == 0xff1f0000)) - { - (*m_memory.write_qword_masked)(*m_program, address, data, mem_mask); - return; - } - const uint32_t tlbval = vtlb_table()[address >> 12]; if (tlbval & VTLB_WRITE_ALLOWED) { diff --git a/src/devices/cpu/mips/mips3.h b/src/devices/cpu/mips/mips3.h index 6d763c8792b..dd0bac966d9 100644 --- a/src/devices/cpu/mips/mips3.h +++ b/src/devices/cpu/mips/mips3.h @@ -312,9 +312,7 @@ protected: 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; + virtual util::disasm_interface *create_disassembler() override; private: @@ -374,7 +372,7 @@ private: loadstore_func m_sdr; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; uint32_t c_system_clock; uint32_t m_cpu_clock; emu_timer * m_compare_int_timer; @@ -802,11 +800,4 @@ private: #define MIPS3DRC_FASTEST_OPTIONS (0) -/*************************************************************************** - DISASSEMBLING -***************************************************************************/ - -unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op); - - #endif // MAME_CPU_MIPS_MIPS3_H diff --git a/src/devices/cpu/mips/mips3drc.cpp b/src/devices/cpu/mips/mips3drc.cpp index a3bd2e1469c..db90d525149 100644 --- a/src/devices/cpu/mips/mips3drc.cpp +++ b/src/devices/cpu/mips/mips3drc.cpp @@ -27,6 +27,7 @@ #include "debugger.h" #include "mips3com.h" #include "mips3fe.h" +#include "mips3dsm.h" #include "cpu/drcfe.h" #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" @@ -161,12 +162,6 @@ void mips3_device::mips3drc_set_options(uint32_t options) -------------------------------------------------*/ void mips3_device::clear_fastram(uint32_t select_start) { - for (int i=select_start; i<MIPS3_MAX_FASTRAM; i++) { - m_fastram[i].start = 0; - m_fastram[i].end = 0; - m_fastram[i].readonly = false; - m_fastram[i].base = nullptr; - } m_fastram_select=select_start; // Set cache to dirty so that re-mapping occurs m_cache_dirty = true; @@ -189,6 +184,8 @@ void mips3_device::add_fastram(offs_t start, offs_t end, uint8_t readonly, void m_fastram[m_fastram_select].offset_base16 = (uint16_t*)((uint8_t*)base - start); m_fastram[m_fastram_select].offset_base32 = (uint32_t*)((uint8_t*)base - start); m_fastram_select++; + // Set cache to dirty so that re-mapping occurs + m_cache_dirty = true; } } @@ -840,69 +837,6 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri UML_LABEL(block, addrok); // addrok: } - /* TX4925 on-board peripherals pass-through */ - if (m_flavor == MIPS3_TYPE_TX4925) - { - int addrok; - UML_AND(block, I3, I0, 0xffff0000); // and i3, i0, 0xffff0000 - UML_CMP(block, I3, 0xff1f0000); // cmp i3, 0xff1f0000 - UML_JMPc(block, COND_NZ, addrok = label++); - - switch (size) - { - case 1: - if (iswrite) - UML_WRITE(block, I0, I1, SIZE_BYTE, SPACE_PROGRAM); // write i0,i1,program_byte - else - UML_READ(block, I0, I0, SIZE_BYTE, SPACE_PROGRAM); // read i0,i0,program_byte - break; - - case 2: - if (iswrite) - UML_WRITE(block, I0, I1, SIZE_WORD, SPACE_PROGRAM); // write i0,i1,program_word - else - UML_READ(block, I0, I0, SIZE_WORD, SPACE_PROGRAM); // read i0,i0,program_word - break; - - case 4: - if (iswrite) - { - if (!ismasked) - UML_WRITE(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); // write i0,i1,program_dword - else - UML_WRITEM(block, I0, I1, I2, SIZE_DWORD, SPACE_PROGRAM); // writem i0,i1,i2,program_dword - } - else - { - if (!ismasked) - UML_READ(block, I0, I0, SIZE_DWORD, SPACE_PROGRAM); // read i0,i0,program_dword - else - UML_READM(block, I0, I0, I2, SIZE_DWORD, SPACE_PROGRAM); // readm i0,i0,i2,program_dword - } - break; - - case 8: - if (iswrite) - { - if (!ismasked) - UML_DWRITE(block, I0, I1, SIZE_QWORD, SPACE_PROGRAM); // dwrite i0,i1,program_qword - else - UML_DWRITEM(block, I0, I1, I2, SIZE_QWORD, SPACE_PROGRAM); // dwritem i0,i1,i2,program_qword - } - else - { - if (!ismasked) - UML_DREAD(block, I0, I0, SIZE_QWORD, SPACE_PROGRAM); // dread i0,i0,program_qword - else - UML_DREADM(block, I0, I0, I2, SIZE_QWORD, SPACE_PROGRAM); // dreadm i0,i0,i2,program_qword - } - break; - } - UML_RET(block); - - UML_LABEL(block, addrok); - } - /* general case: assume paging and perform a translation */ UML_SHR(block, I3, I0, 12); // shr i3,i0,12 UML_LOAD(block, I3, (void *)vtlb_table(), I3, SIZE_DWORD, SCALE_x4);// load i3,[vtlb_table],i3,dword @@ -911,8 +845,8 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri UML_ROLINS(block, I0, I3, 0, 0xfffff000); // rolins i0,i3,0,0xfffff000 if ((machine().debug_flags & DEBUG_FLAG_ENABLED) == 0) - for (ramnum = 0; ramnum < MIPS3_MAX_FASTRAM; ramnum++) - if (m_fastram[ramnum].base != nullptr && (!iswrite || !m_fastram[ramnum].readonly)) + for (ramnum = 0; ramnum < m_fastram_select; ramnum++) + if (!(iswrite && m_fastram[ramnum].readonly)) { void *fastbase = (uint8_t *)m_fastram[ramnum].base - m_fastram[ramnum].start; uint32_t skip = label++; @@ -926,7 +860,6 @@ void mips3_device::static_generate_memory_accessor(int mode, int size, int iswri UML_CMP(block, I0, m_fastram[ramnum].start);// cmp i0,fastram_start UML_JMPc(block, COND_B, skip); // jb skip } - if (!iswrite) { if (size == 1) @@ -3354,8 +3287,9 @@ void mips3_device::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint { if (m_drcuml->logging()) { + mips3_disassembler mips3d; std::ostringstream stream; - dasmmips3(stream, pc, op); + mips3d.dasm_one(stream, pc, op); const std::string stream_string = stream.str(); block->append_comment("%08X: %s", pc, stream_string.c_str()); // comment } @@ -3493,7 +3427,10 @@ void mips3_device::log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desc if (desclist->flags & OPFLAG_VIRTUAL_NOOP) buffer << "<virtual nop>"; else - dasmmips3(buffer, desclist->pc, desclist->opptr.l[0]); + { + mips3_disassembler mips3d; + mips3d.dasm_one(buffer, desclist->pc, desclist->opptr.l[0]); + } } else buffer << "???"; diff --git a/src/devices/cpu/mips/mips3dsm.cpp b/src/devices/cpu/mips/mips3dsm.cpp index acc7abbcc75..5252a552b8c 100644 --- a/src/devices/cpu/mips/mips3dsm.cpp +++ b/src/devices/cpu/mips/mips3dsm.cpp @@ -9,11 +9,12 @@ ***************************************************************************/ #include "emu.h" +#include "mips3dsm.h" #define USE_ABI_REG_NAMES (1) #if USE_ABI_REG_NAMES -static const char *const reg[32] = +const char *const mips3_disassembler::reg[32] = { "$0", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", @@ -21,7 +22,7 @@ static const char *const reg[32] = "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra" }; #else -static const char *const reg[32] = +const char *const mips3_disassembler::reg[32] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -30,7 +31,7 @@ static const char *const reg[32] = }; #endif -static const char *const cacheop[32] = +const char *const mips3_disassembler::cacheop[32] = { "I_Invd", "D_WBInvd", "Unknown 2", "Unknown 3", "I_IndexLoadTag", "D_IndexLoadTag", "Unknown 6", "Unknown 7", "I_IndexStoreTag", "D_IndexStoreTag", "Unknown 10", "Unknown 11", "Unknown 12", "D_CreateDirtyExcl", "Unknown 14", "Unknown 15", @@ -39,7 +40,7 @@ static const char *const cacheop[32] = }; -static const char *const cpreg[4][32] = +const char *const mips3_disassembler::cpreg[4][32] = { { "Index","Random","EntryLo0","EntryLo1","Context","PageMask","Wired","Error", @@ -68,7 +69,7 @@ static const char *const cpreg[4][32] = }; -static const char *const ccreg[4][32] = +const char *const mips3_disassembler::ccreg[4][32] = { { "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7", @@ -101,17 +102,15 @@ static const char *const ccreg[4][32] = CODE CODE ***************************************************************************/ -static inline char *signed_16bit(int16_t val) +inline std::string mips3_disassembler::signed_16bit(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "$%x", val); - return temp; + return util::string_format("$%x", val); } -static uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t mips3_disassembler::dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -157,7 +156,7 @@ static uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream) case 0x02: util::stream_format(stream, "tlbwi"); break; case 0x06: util::stream_format(stream, "tlbwr"); break; case 0x08: util::stream_format(stream, "tlbp"); break; - case 0x10: util::stream_format(stream, "rfe"); flags = DASMFLAG_STEP_OUT; break; + case 0x10: util::stream_format(stream, "rfe"); flags = STEP_OUT; break; case 0x18: util::stream_format(stream, "eret [invalid]"); break; default: util::stream_format(stream, "cop0 $%07x", op & 0x01ffffff); break; } @@ -167,9 +166,9 @@ static uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t mips3_disassembler::dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) { - static const char *const format_table[] = + const char *const format_table[] = { "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?", "s","d","?","?","w","l","?","?","?","?","?","?","?","?","?","?" @@ -195,8 +194,8 @@ static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) { case 0x00: util::stream_format(stream, "bc1f $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break; case 0x01: util::stream_format(stream, "bc1t $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break; - case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break; + case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break; } break; default: /* COP */ @@ -250,9 +249,9 @@ static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -static uint32_t dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t mips3_disassembler::dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream) { - static const char *const format3_table[] = + const char *const format3_table[] = { "s","d","?","?","w","l","?","?" }; @@ -310,7 +309,7 @@ static uint32_t dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -static uint32_t dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t mips3_disassembler::dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -357,7 +356,12 @@ static uint32_t dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) +u32 mips3_disassembler::opcode_alignment() const +{ + return 4; +} + +offs_t mips3_disassembler::dasm_one(std::ostream &stream, offs_t pc, u32 op) { int rs = (op >> 21) & 31; int rt = (op >> 16) & 31; @@ -381,17 +385,17 @@ unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) case 0x04: util::stream_format(stream, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x06: util::stream_format(stream, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x07: util::stream_format(stream, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; - case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = DASMFLAG_STEP_OUT; break; + case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = STEP_OUT; break; case 0x09: if (rd == 31) util::stream_format(stream, "jalr %s", reg[rs]); else util::stream_format(stream, "jalr %s,%s", reg[rs], reg[rd]); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; case 0x0a: util::stream_format(stream, "movz %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x0b: util::stream_format(stream, "movn %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; - case 0x0c: util::stream_format(stream, "syscall"); flags = DASMFLAG_STEP_OVER; break; - case 0x0d: util::stream_format(stream, "break"); flags = DASMFLAG_STEP_OVER; break; + case 0x0c: util::stream_format(stream, "syscall"); flags = STEP_OVER; break; + case 0x0d: util::stream_format(stream, "break"); flags = STEP_OVER; break; case 0x0f: util::stream_format(stream, "sync"); break; case 0x10: util::stream_format(stream, "mfhi %s", reg[rd]); break; case 0x11: util::stream_format(stream, "mthi %s", reg[rs]); break; @@ -422,12 +426,12 @@ unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) case 0x2d: util::stream_format(stream, "daddu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2e: util::stream_format(stream, "dsub %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; case 0x2f: util::stream_format(stream, "dsubu %s,%s,%s", reg[rd], reg[rs], reg[rt]); break; - case 0x30: util::stream_format(stream, "tge %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x31: util::stream_format(stream, "tgeu %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x32: util::stream_format(stream, "tlt %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x33: util::stream_format(stream, "tltu %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x34: util::stream_format(stream, "teq %s,%s", reg[rs], reg[rt]); flags = DASMFLAG_STEP_OVER; break; - case 0x36: util::stream_format(stream, "tne %s,%s", reg[rs], reg[rt]) ;flags = DASMFLAG_STEP_OVER; break; + case 0x30: util::stream_format(stream, "tge %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x31: util::stream_format(stream, "tgeu %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x32: util::stream_format(stream, "tlt %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x33: util::stream_format(stream, "tltu %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x34: util::stream_format(stream, "teq %s,%s", reg[rs], reg[rt]); flags = STEP_OVER; break; + case 0x36: util::stream_format(stream, "tne %s,%s", reg[rs], reg[rt]) ;flags = STEP_OVER; break; case 0x38: util::stream_format(stream, "dsll %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3a: util::stream_format(stream, "dsrl %s,%s,%d", reg[rd], reg[rt], shift); break; case 0x3b: util::stream_format(stream, "dsra %s,%s,%d", reg[rd], reg[rt], shift); break; @@ -445,22 +449,22 @@ unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) case 0x01: util::stream_format(stream, "bgez %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x02: util::stream_format(stream, "bltzl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; case 0x03: util::stream_format(stream, "bgezl %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); break; - case 0x08: util::stream_format(stream, "tgei %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x09: util::stream_format(stream, "tgeiu %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x0a: util::stream_format(stream, "tlti %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x0b: util::stream_format(stream, "tltiu %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x0c: util::stream_format(stream, "teqi %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x0e: util::stream_format(stream, "tnei %s,%s", reg[rs], signed_16bit(op)); flags = DASMFLAG_STEP_OVER; break; - case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x12: util::stream_format(stream, "bltzall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x13: util::stream_format(stream, "bgezall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x08: util::stream_format(stream, "tgei %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x09: util::stream_format(stream, "tgeiu %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x0a: util::stream_format(stream, "tlti %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x0b: util::stream_format(stream, "tltiu %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x0c: util::stream_format(stream, "teqi %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x0e: util::stream_format(stream, "tnei %s,%s", reg[rs], signed_16bit(op)); flags = STEP_OVER; break; + case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; + case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; + case 0x12: util::stream_format(stream, "bltzall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; + case 0x13: util::stream_format(stream, "bgezall %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break; } break; case 0x02: util::stream_format(stream, "j $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); break; - case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x03ffffff) << 2)); flags = STEP_OVER | step_over_extra(1); break; case 0x04: if (rs == 0 && rt == 0) util::stream_format(stream, "b $%08x", pc + 4 + ((int16_t)op << 2)); else @@ -532,21 +536,11 @@ unsigned dasmmips3(std::ostream &stream, unsigned pc, uint32_t op) case 0x3f: util::stream_format(stream, "sd %s,%s(%s)", reg[rt], signed_16bit(op), reg[rs]); break; default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break; } - return 4 | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( mips3be ) -{ - uint32_t op = *(uint32_t *)oprom; - op = big_endianize_int32(op); - return dasmmips3(stream, pc, op); + return 4 | flags | SUPPORTED; } - -CPU_DISASSEMBLE( mips3le ) +offs_t mips3_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t op = *(uint32_t *)oprom; - op = little_endianize_int32(op); - return dasmmips3(stream, pc, op); + u32 op = opcodes.r32(pc); + return dasm_one(stream, pc, op); } diff --git a/src/devices/cpu/mips/mips3dsm.h b/src/devices/cpu/mips/mips3dsm.h new file mode 100644 index 00000000000..a38771bbba0 --- /dev/null +++ b/src/devices/cpu/mips/mips3dsm.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + mips3dsm.c + Disassembler for the portable MIPS 3 emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_MIPS_MIPS3DSM_H +#define MAME_CPU_MIPS_MIPS3DSM_H + +#pragma once + +class mips3_disassembler : public util::disasm_interface +{ +public: + mips3_disassembler() = default; + virtual ~mips3_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + offs_t dasm_one(std::ostream &stream, offs_t pc, u32 op); + +private: + static const char *const reg[32]; + static const char *const cacheop[32]; + static const char *const cpreg[4][32]; + static const char *const ccreg[4][32]; + inline std::string signed_16bit(int16_t val); + uint32_t dasm_cop0(uint32_t pc, uint32_t op, std::ostream &stream); + uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream); + uint32_t dasm_cop1x(uint32_t pc, uint32_t op, std::ostream &stream); + uint32_t dasm_cop2(uint32_t pc, uint32_t op, std::ostream &stream); + +}; + +#endif diff --git a/src/devices/cpu/mips/r3000.cpp b/src/devices/cpu/mips/r3000.cpp index 2e29e967747..db1a35ec370 100644 --- a/src/devices/cpu/mips/r3000.cpp +++ b/src/devices/cpu/mips/r3000.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "r3000.h" +#include "r3kdasm.h" #include "debugger.h" @@ -213,7 +214,7 @@ void r3000_device::device_start() { // get our address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // determine the cache sizes switch (m_chip_type) @@ -453,41 +454,13 @@ void r3000_device::state_string_export(const device_state_entry &entry, std::str //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t r3000_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t r3000_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t r3000_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *r3000_device::create_disassembler() { - extern CPU_DISASSEMBLE( r3000le ); - extern CPU_DISASSEMBLE( r3000be ); - - if (m_endianness == ENDIANNESS_BIG) - return CPU_DISASSEMBLE_NAME(r3000be)(this, stream, pc, oprom, opram, options); - else - return CPU_DISASSEMBLE_NAME(r3000le)(this, stream, pc, oprom, opram, options); + return new r3000_disassembler; } diff --git a/src/devices/cpu/mips/r3000.h b/src/devices/cpu/mips/r3000.h index 1d458d93de9..a5f9998a23c 100644 --- a/src/devices/cpu/mips/r3000.h +++ b/src/devices/cpu/mips/r3000.h @@ -131,9 +131,7 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // memory accessors struct r3000_data_accessors @@ -214,7 +212,7 @@ protected: const address_space_config m_program_config_be; const address_space_config m_program_config_le; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; // configuration chip_type m_chip_type; diff --git a/src/devices/cpu/mips/r3kdasm.cpp b/src/devices/cpu/mips/r3kdasm.cpp index 1e8a2d7a16d..7e004a95068 100644 --- a/src/devices/cpu/mips/r3kdasm.cpp +++ b/src/devices/cpu/mips/r3kdasm.cpp @@ -9,9 +9,9 @@ ***************************************************************************/ #include "emu.h" +#include "r3kdasm.h" - -static const char *const reg[32] = +const char *const r3000_disassembler::reg[32] = { "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -20,7 +20,7 @@ static const char *const reg[32] = }; -static const char *const cpreg[4][32] = +const char *const r3000_disassembler::cpreg[4][32] = { { "Index","Random","EntryLo","cpr3", "Context", "cpr5", "cpr6", "cpr7", @@ -49,7 +49,7 @@ static const char *const cpreg[4][32] = }; -static const char *const ccreg[4][32] = +const char *const r3000_disassembler::ccreg[4][32] = { { "ccr0", "ccr1", "ccr2", "ccr3", "ccr4", "ccr5", "ccr6", "ccr7", @@ -82,17 +82,15 @@ static const char *const ccreg[4][32] = CODE CODE ***************************************************************************/ -static inline char *signed_16bit(int16_t val) +std::string r3000_disassembler::signed_16bit(int16_t val) { - static char temp[10]; if (val < 0) - sprintf(temp, "-$%x", -val); + return util::string_format("-$%x", -val); else - sprintf(temp, "$%x", val); - return temp; + return util::string_format("$%x", val); } -static uint32_t dasm_cop(uint32_t pc, int cop, uint32_t op, std::ostream &stream) +uint32_t r3000_disassembler::dasm_cop(uint32_t pc, int cop, uint32_t op, std::ostream &stream) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -152,7 +150,7 @@ static uint32_t dasm_cop(uint32_t pc, int cop, uint32_t op, std::ostream &stream return flags; } -static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) +uint32_t r3000_disassembler::dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) { static const char *const format_table[] = { @@ -180,8 +178,8 @@ static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) { case 0x00: util::stream_format(stream, "bc1f $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break; case 0x01: util::stream_format(stream, "bc1t $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); break; - case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x02: util::stream_format(stream, "bc1fl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break; + case 0x03: util::stream_format(stream, "bc1tl $%08x,%d", pc + 4 + ((int16_t)op << 2), (op >> 18) & 7); flags = STEP_OVER | step_over_extra(1); break; } break; default: /* COP */ @@ -235,8 +233,9 @@ static uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream) return flags; } -static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) +offs_t r3000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { + uint32_t op = opcodes.r32(pc); int rs = (op >> 21) & 31; int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -258,15 +257,15 @@ static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) case 0x04: util::stream_format(stream, "sllv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x06: util::stream_format(stream, "srlv %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; case 0x07: util::stream_format(stream, "srav %s,%s,%s", reg[rd], reg[rt], reg[rs]); break; - case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = DASMFLAG_STEP_OUT; break; + case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = STEP_OUT; break; case 0x09: if (rd == 31) util::stream_format(stream, "jalr %s", reg[rs]); else util::stream_format(stream, "jalr %s,%s", reg[rs], reg[rd]); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; - case 0x0c: util::stream_format(stream, "syscall"); flags = DASMFLAG_STEP_OVER; break; - case 0x0d: util::stream_format(stream, "break"); flags = DASMFLAG_STEP_OVER; break; + case 0x0c: util::stream_format(stream, "syscall"); flags = STEP_OVER; break; + case 0x0d: util::stream_format(stream, "break"); flags = STEP_OVER; break; case 0x0f: util::stream_format(stream, "sync [invalid]"); break; case 0x10: util::stream_format(stream, "mfhi %s", reg[rd]); break; case 0x11: util::stream_format(stream, "mthi %s", reg[rs]); break; @@ -309,8 +308,8 @@ static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) case 0x0b: util::stream_format(stream, "tltiu [invalid]"); break; case 0x0c: util::stream_format(stream, "teqi [invalid]"); break; case 0x0e: util::stream_format(stream, "tnei [invalid]"); break; - case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; - case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x10: util::stream_format(stream, "bltzal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; + case 0x11: util::stream_format(stream, "bgezal %s,$%08x", reg[rs], pc + 4 + ((int16_t)op << 2)); flags = STEP_OVER | step_over_extra(1); break; case 0x12: util::stream_format(stream, "bltzall [invalid]"); break; case 0x13: util::stream_format(stream, "bgezall [invalid]"); break; default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break; @@ -318,7 +317,7 @@ static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) break; case 0x02: util::stream_format(stream, "j $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); break; - case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); break; + case 0x03: util::stream_format(stream, "jal $%08x", (pc & 0xf0000000) | ((op & 0x0fffffff) << 2)); flags = STEP_OVER | step_over_extra(1); break; case 0x04: if (rs == 0 && rt == 0) util::stream_format(stream, "b $%08x", pc + 4 + ((int16_t)op << 2)); else @@ -374,21 +373,10 @@ static unsigned dasmr3k(std::ostream &stream, unsigned pc, uint32_t op) case 0x3f: util::stream_format(stream, "sdc3 [invalid]"); break; default: util::stream_format(stream, "dc.l $%08x [invalid]", op); break; } - return 4 | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( r3000be ) -{ - uint32_t op = *(uint32_t *)oprom; - op = big_endianize_int32(op); - return dasmr3k(stream, pc, op); + return 4 | flags | SUPPORTED; } - -CPU_DISASSEMBLE( r3000le ) +uint32_t r3000_disassembler::opcode_alignment() const { - uint32_t op = *(uint32_t *)oprom; - op = little_endianize_int32(op); - return dasmr3k(stream, pc, op); + return 4; } diff --git a/src/devices/cpu/mips/r3kdasm.h b/src/devices/cpu/mips/r3kdasm.h new file mode 100644 index 00000000000..7eec7e7c1f8 --- /dev/null +++ b/src/devices/cpu/mips/r3kdasm.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + r3kdasm.c + Disassembler for the portable R3000 emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_MIPS_R3KDASM_H +#define MAME_CPU_MIPS_R3KDASM_H + +#pragma once + +class r3000_disassembler : public util::disasm_interface +{ +public: + r3000_disassembler() = default; + virtual ~r3000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const reg[32]; + static const char *const cpreg[4][32]; + static const char *const ccreg[4][32]; + std::string signed_16bit(int16_t val); + uint32_t dasm_cop(uint32_t pc, int cop, uint32_t op, std::ostream &stream); + uint32_t dasm_cop1(uint32_t pc, uint32_t op, std::ostream &stream); + + +}; + +#endif diff --git a/src/devices/cpu/mn10200/mn10200.cpp b/src/devices/cpu/mn10200/mn10200.cpp index 59407b507ca..74757bd9e53 100644 --- a/src/devices/cpu/mn10200/mn10200.cpp +++ b/src/devices/cpu/mn10200/mn10200.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "debugger.h" #include "mn10200.h" +#include "mn102dis.h" #define log_write(...) #define log_event(...) @@ -88,10 +89,9 @@ void mn10200_device::state_string_export(const device_state_entry &entry, std::s } } -offs_t mn10200_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mn10200_device::create_disassembler() { - extern CPU_DISASSEMBLE( mn10200 ); - return CPU_DISASSEMBLE_NAME(mn10200)(this, stream, pc, oprom, opram, options); + return new mn10200_disassembler; } diff --git a/src/devices/cpu/mn10200/mn10200.h b/src/devices/cpu/mn10200/mn10200.h index 307b0b4b6a9..7f3524df68c 100644 --- a/src/devices/cpu/mn10200/mn10200.h +++ b/src/devices/cpu/mn10200/mn10200.h @@ -87,9 +87,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 7; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/mn10200/mn102dis.cpp b/src/devices/cpu/mn10200/mn102dis.cpp index be3fb46c0eb..8be02ad6a58 100644 --- a/src/devices/cpu/mn10200/mn102dis.cpp +++ b/src/devices/cpu/mn10200/mn102dis.cpp @@ -5,76 +5,47 @@ */ #include "emu.h" +#include "mn102dis.h" -#include <stdio.h> - -static const uint8_t *sOpROM; // current opROM pointer -static uint32_t sBasePC; - -static uint8_t program_read_byte(offs_t pc) -{ - return sOpROM[pc - sBasePC]; -} - -static uint32_t r16u(offs_t pc) -{ - return sOpROM[pc - sBasePC] | (sOpROM[pc - sBasePC + 1]<<8); -} - -static int32_t r16s(offs_t pc) -{ - return (int16_t)(sOpROM[pc - sBasePC] | (sOpROM[pc - sBasePC + 1]<<8)); -} - -static uint32_t r24u(offs_t pc) +u32 mn10200_disassembler::r24(const data_buffer &opcodes, offs_t pc) { - return sOpROM[pc - sBasePC] | (sOpROM[pc - sBasePC + 1]<<8) | (sOpROM[pc - sBasePC + 2]<<16); + return opcodes.r16(pc) | (opcodes.r8(pc+2) << 16); } -static int32_t r24s(offs_t pc) +std::string mn10200_disassembler::i8str(s8 v) { - return sOpROM[pc - sBasePC] | (sOpROM[pc - sBasePC + 1]<<8) | ((int8_t)sOpROM[pc - sBasePC + 2]<<16); -} - -static const char *i8str(int8_t v) -{ - static char res[0x10]; if(v>=0) - sprintf(res, "$%x", v); + return util::string_format("$%x", v); else - sprintf(res, "-$%x", (uint8_t)(-v)); - return res; + return util::string_format("-$%x", u8(-v)); } -static const char *i16str(int16_t v) +std::string mn10200_disassembler::i16str(int16_t v) { - static char res[0x10]; if(v>=0) - sprintf(res, "$%x", v); + return util::string_format("$%x", v); else - sprintf(res, "-$%x", (uint16_t)(-v)); - return res; + return util::string_format("-$%x", u16(-v)); } -static const char *i24str(int32_t v) -{ - static char res[0x10]; - if(v>=0) - sprintf(res, "$%x", v); +std::string mn10200_disassembler::i24str(u32 v) +{ + if(!(v & 0x800000)) + return util::string_format("$%x", v & 0xffffff); else - sprintf(res, "-$%x", -v); - return res; + return util::string_format("-$%x", (-v) & 0xffffff); } - -static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *oprom) +u32 mn10200_disassembler::opcode_alignment() const { - uint8_t opcode; + return 1; +} - sOpROM = oprom; - sBasePC = pc; +offs_t mn10200_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + u8 opcode; - opcode = program_read_byte(pc); + opcode = opcodes.r8(pc); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: @@ -99,22 +70,22 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: - util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i8str(program_read_byte(pc+1)), (opcode>>2) & 3); + util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i8str(opcodes.r8(pc+1)), (opcode>>2) & 3); return 2; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i8str(program_read_byte(pc+1)), (opcode>>2) & 3); + util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i8str(opcodes.r8(pc+1)), (opcode>>2) & 3); return 2; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: - util::stream_format(stream, "mov (%s, a%d), d%d", i8str(program_read_byte(pc+1)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), d%d", i8str(opcodes.r8(pc+1)), (opcode>>2) & 3, opcode & 3); return 2; case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "mov (%s, a%d), a%d", i8str(program_read_byte(pc+1)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), a%d", i8str(opcodes.r8(pc+1)), (opcode>>2) & 3, opcode & 3); return 2; case 0x81: case 0x82: case 0x83: case 0x84: case 0x86: case 0x87: @@ -123,7 +94,7 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 1; case 0x80: case 0x85: case 0x8a: case 0x8f: - util::stream_format(stream, "mov %s, d%d", i8str(program_read_byte(pc+1)), opcode & 3); + util::stream_format(stream, "mov %s, d%d", i8str(opcodes.r8(pc+1)), opcode & 3); return 2; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: @@ -153,79 +124,79 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 1; case 0xc0: case 0xc1: case 0xc2: case 0xc3: - util::stream_format(stream, "mov d%d, ($%04x)", opcode & 3, r16u(pc+1)); + util::stream_format(stream, "mov d%d, ($%04x)", opcode & 3, opcodes.r16(pc+1)); return 3; case 0xc4: case 0xc5: case 0xc6: case 0xc7: - util::stream_format(stream, "movb d%d, ($%04x)", opcode & 3, r16u(pc+1)); + util::stream_format(stream, "movb d%d, ($%04x)", opcode & 3, opcodes.r16(pc+1)); return 3; case 0xc8: case 0xc9: case 0xca: case 0xcb: - util::stream_format(stream, "mov ($%04x), d%d", r16u(pc+1), opcode & 3); + util::stream_format(stream, "mov ($%04x), d%d", opcodes.r16(pc+1), opcode & 3); return 3; case 0xcc: case 0xcd: case 0xce: case 0xcf: - util::stream_format(stream, "movbu ($%04x), d%d", r16u(pc+1), opcode & 3); + util::stream_format(stream, "movbu ($%04x), d%d", opcodes.r16(pc+1), opcode & 3); return 3; case 0xd0: case 0xd1: case 0xd2: case 0xd3: - util::stream_format(stream, "add %s, a%d", i8str(program_read_byte(pc+1)), opcode & 3); + util::stream_format(stream, "add %s, a%d", i8str(opcodes.r8(pc+1)), opcode & 3); return 2; case 0xd4: case 0xd5: case 0xd6: case 0xd7: - util::stream_format(stream, "add %s, d%d", i8str(program_read_byte(pc+1)), opcode & 3); + util::stream_format(stream, "add %s, d%d", i8str(opcodes.r8(pc+1)), opcode & 3); return 2; case 0xd8: case 0xd9: case 0xda: case 0xdb: - util::stream_format(stream, "cmp %s, d%d", i8str(program_read_byte(pc+1)), opcode & 3); + util::stream_format(stream, "cmp %s, d%d", i8str(opcodes.r8(pc+1)), opcode & 3); return 2; case 0xdc: case 0xdd: case 0xde: case 0xdf: - util::stream_format(stream, "move $%04x, a%d", r16u(pc+1), opcode & 3); + util::stream_format(stream, "move $%04x, a%d", opcodes.r16(pc+1), opcode & 3); return 3; case 0xe0: - util::stream_format(stream, "blt $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "blt $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe1: - util::stream_format(stream, "bgt $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bgt $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe2: - util::stream_format(stream, "bge $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bge $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe3: - util::stream_format(stream, "ble $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "ble $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe4: - util::stream_format(stream, "bcs $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bcs $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe5: - util::stream_format(stream, "bhi $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bhi $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe6: - util::stream_format(stream, "bcc $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bcc $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe7: - util::stream_format(stream, "bls $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bls $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe8: - util::stream_format(stream, "beq $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "beq $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xe9: - util::stream_format(stream, "bne $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bne $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xea: - util::stream_format(stream, "bra $%x", (pc+2+(int8_t)program_read_byte(pc+1)) & 0xffffff); + util::stream_format(stream, "bra $%x", (pc+2+(s8)opcodes.r8(pc+1)) & 0xffffff); return 2; case 0xeb: @@ -233,11 +204,11 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 1; case 0xec: case 0xed: case 0xee: case 0xef: - util::stream_format(stream, "cmp $%04x, a%d", r16u(pc+1), opcode & 3); + util::stream_format(stream, "cmp $%04x, a%d", opcodes.r16(pc+1), opcode & 3); return 3; case 0xf0: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x04: case 0x08: case 0x0c: @@ -296,7 +267,7 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf1: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode&0xc0) { case 0x00: @@ -318,7 +289,7 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o break; case 0xf2: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode&0xf0) { case 0x00: @@ -382,7 +353,7 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf3: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: @@ -465,25 +436,25 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 2; case 0xfe: - opcode = program_read_byte(pc+2); + opcode = opcodes.r8(pc+2); switch(opcode) { case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: - util::stream_format(stream, "tbz ($%x) %d, $%x", r24u(pc+3), opcode & 7, - (pc+7+(int8_t)program_read_byte(pc+6)) & 0xffffff); + util::stream_format(stream, "tbz ($%x) %d, $%x", r24(opcodes, pc+3), opcode & 7, + (pc+7+(s8)opcodes.r8(pc+6)) & 0xffffff); return 7; case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: - util::stream_format(stream, "tbnz ($%x) %d, $%x", r24u(pc+3), opcode & 7, - (pc+7+(int8_t)program_read_byte(pc+6)) & 0xffffff); + util::stream_format(stream, "tbnz ($%x) %d, $%x", r24(opcodes, pc+3), opcode & 7, + (pc+7+(s8)opcodes.r8(pc+6)) & 0xffffff); return 7; case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: - util::stream_format(stream, "bset ($%x) %d", r24u(pc+2), opcode & 7); + util::stream_format(stream, "bset ($%x) %d", r24(opcodes, pc+2), opcode & 7); return 6; case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - util::stream_format(stream, "bclr ($%x) %d", r24u(pc+2), opcode & 7); + util::stream_format(stream, "bclr ($%x) %d", r24(opcodes, pc+2), opcode & 7); return 6; default: @@ -491,29 +462,29 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xff: - opcode = program_read_byte(pc+2); + opcode = opcodes.r8(pc+2); switch(opcode) { case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: - util::stream_format(stream, "tbz (%s, a%d) %d, $%x", i8str(program_read_byte(pc+3)), 2+((opcode>>3)&1), opcode & 7, - (pc+5+(int8_t)program_read_byte(pc+4)) & 0xffffff); + util::stream_format(stream, "tbz (%s, a%d) %d, $%x", i8str(opcodes.r8(pc+3)), 2+((opcode>>3)&1), opcode & 7, + (pc+5+(s8)opcodes.r8(pc+4)) & 0xffffff); return 5; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: - util::stream_format(stream, "bset (%s, a%d) %d", i8str(program_read_byte(pc+3)), 2+((opcode>>3)&1), opcode & 7); + util::stream_format(stream, "bset (%s, a%d) %d", i8str(opcodes.r8(pc+3)), 2+((opcode>>3)&1), opcode & 7); return 4; case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: - util::stream_format(stream, "tbnz (%s, a%d) %d, $%x", i8str(program_read_byte(pc+3)), 2+((opcode>>3)&1), opcode & 7, - (pc+5+(int8_t)program_read_byte(pc+4)) & 0xffffff); + util::stream_format(stream, "tbnz (%s, a%d) %d, $%x", i8str(opcodes.r8(pc+3)), 2+((opcode>>3)&1), opcode & 7, + (pc+5+(s8)opcodes.r8(pc+4)) & 0xffffff); return 5; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: - util::stream_format(stream, "bclr (%s, a%d) %d", i8str(program_read_byte(pc+3)), 2+((opcode>>3)&1), opcode & 7); + util::stream_format(stream, "bclr (%s, a%d) %d", i8str(opcodes.r8(pc+3)), 2+((opcode>>3)&1), opcode & 7); return 4; default: @@ -525,144 +496,144 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf4: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: - util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i24str(r24s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i24str(r24(opcodes, pc+2)), (opcode>>2) & 3); return 5; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i24str(r24s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i24str(r24(opcodes, pc+2)), (opcode>>2) & 3); return 5; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i24str(r24s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i24str(r24(opcodes, pc+2)), (opcode>>2) & 3); return 5; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i24str(r24s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i24str(r24(opcodes, pc+2)), (opcode>>2) & 3); return 5; case 0x40: case 0x41: case 0x42: case 0x43: - util::stream_format(stream, "mov d%d, ($%06x)", opcode & 3, r24u(pc+2)); + util::stream_format(stream, "mov d%d, ($%06x)", opcode & 3, r24(opcodes, pc+2)); return 5; case 0x44: case 0x45: case 0x46: case 0x47: - util::stream_format(stream, "movb d%d, ($%06x)", opcode & 3, r24u(pc+2)); + util::stream_format(stream, "movb d%d, ($%06x)", opcode & 3, r24(opcodes, pc+2)); return 5; case 0x4b: - util::stream_format(stream, "bset %02x, ($%06x)", program_read_byte(pc+5), r24u(pc+2)); + util::stream_format(stream, "bset %02x, ($%06x)", opcodes.r8(pc+5), r24(opcodes, pc+2)); return 6; case 0x4f: - util::stream_format(stream, "bclr %02x, ($%06x)", program_read_byte(pc+5), r24u(pc+2)); + util::stream_format(stream, "bclr %02x, ($%06x)", opcodes.r8(pc+5), r24(opcodes, pc+2)); return 6; case 0x50: case 0x51: case 0x52: case 0x53: - util::stream_format(stream, "mov a%d, ($%06x)", opcode & 3, r24u(pc+2)); + util::stream_format(stream, "mov a%d, ($%06x)", opcode & 3, r24(opcodes, pc+2)); return 5; case 0x60: case 0x61: case 0x62: case 0x63: - util::stream_format(stream, "add %s, d%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "add %s, d%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x64: case 0x65: case 0x66: case 0x67: - util::stream_format(stream, "add %s, a%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "add %s, a%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x68: case 0x69: case 0x6a: case 0x6b: - util::stream_format(stream, "sub %s, d%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "sub %s, d%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x6c: case 0x6d: case 0x6e: case 0x6f: - util::stream_format(stream, "sub %s, a%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "sub %s, a%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x70: case 0x71: case 0x72: case 0x73: - util::stream_format(stream, "mov %s, d%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "mov %s, d%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x74: case 0x75: case 0x76: case 0x77: - util::stream_format(stream, "mov $%06x, a%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "mov $%06x, a%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0x78: case 0x79: case 0x7a: case 0x7b: - util::stream_format(stream, "cmp %s, d%d", i24str(r24s(pc+2)), opcode & 3); + util::stream_format(stream, "cmp %s, d%d", i24str(r24(opcodes, pc+2)), opcode & 3); return 5; case 0x7c: case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "cmp $%06x, a%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "cmp $%06x, a%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: - util::stream_format(stream, "mov (%s, a%d), d%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), d%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: - util::stream_format(stream, "movbu (%s, a%d), d%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movbu (%s, a%d), d%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: - util::stream_format(stream, "movb (%s, a%d), d%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movb (%s, a%d), d%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: - util::stream_format(stream, "movx (%s, a%d), d%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movx (%s, a%d), d%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; case 0xc0: case 0xc1: case 0xc2: case 0xc3: - util::stream_format(stream, "mov ($%06x), d%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "mov ($%06x), d%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0xc4: case 0xc5: case 0xc6: case 0xc7: - util::stream_format(stream, "movb ($%06x), d%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "movb ($%06x), d%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0xc8: case 0xc9: case 0xca: case 0xcb: - util::stream_format(stream, "movbu ($%06x), d%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "movbu ($%06x), d%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0xd0: case 0xd1: case 0xd2: case 0xd3: - util::stream_format(stream, "mov ($%06x), a%d", r24u(pc+2), opcode & 3); + util::stream_format(stream, "mov ($%06x), a%d", r24(opcodes, pc+2), opcode & 3); return 5; case 0xe0: - util::stream_format(stream, "jmp $%x", (pc+5+r24s(pc+2)) & 0xffffff); + util::stream_format(stream, "jmp $%x", (pc+5+r24(opcodes, pc+2)) & 0xffffff); return 5; case 0xe1: - util::stream_format(stream, "jsr $%x", (pc+5+r24s(pc+2)) & 0xffffff); + util::stream_format(stream, "jsr $%x", (pc+5+r24(opcodes, pc+2)) & 0xffffff); return 5; case 0xe3: - util::stream_format(stream, "bset $%02x, ($%x)", program_read_byte(pc+4), r16u(pc+2)); + util::stream_format(stream, "bset $%02x, ($%x)", opcodes.r8(pc+4), opcodes.r16(pc+2)); return 6; case 0xe7: - util::stream_format(stream, "bclr $%02x, ($%x)", program_read_byte(pc+4), r16u(pc+2)); + util::stream_format(stream, "bclr $%02x, ($%x)", opcodes.r8(pc+4), opcodes.r16(pc+2)); return 6; case 0xe8: case 0xe9: case 0xea: case 0xeb: - util::stream_format(stream, "bset $%02x, (%s, a%d)", program_read_byte(pc+3), i8str(program_read_byte(pc+2)), opcode & 3); + util::stream_format(stream, "bset $%02x, (%s, a%d)", opcodes.r8(pc+3), i8str(opcodes.r8(pc+2)), opcode & 3); return 4; case 0xec: case 0xed: case 0xee: case 0xef: - util::stream_format(stream, "bclr $%02x, (%s, a%d)", program_read_byte(pc+3), i8str(program_read_byte(pc+2)), opcode & 3); + util::stream_format(stream, "bclr $%02x, (%s, a%d)", opcodes.r8(pc+3), i8str(opcodes.r8(pc+2)), opcode & 3); return 4; case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: - util::stream_format(stream, "mov (%s, a%d), a%d", i24str(r24s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), a%d", i24str(r24(opcodes, pc+2)), (opcode>>2) & 3, opcode & 3); return 5; default: @@ -670,44 +641,44 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf5: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: - util::stream_format(stream, "and $%02x, d%d", program_read_byte(pc+2), opcode & 3); + util::stream_format(stream, "and $%02x, d%d", opcodes.r8(pc+2), opcode & 3); return 3; case 0x04: case 0x05: case 0x06: case 0x07: - util::stream_format(stream, "btst $%02x, d%d", program_read_byte(pc+2), opcode & 3); + util::stream_format(stream, "btst $%02x, d%d", opcodes.r8(pc+2), opcode & 3); return 3; case 0x08: case 0x09: case 0x0a: case 0x0b: - util::stream_format(stream, "or $%02x, d%d", program_read_byte(pc+2), opcode & 3); + util::stream_format(stream, "or $%02x, d%d", opcodes.r8(pc+2), opcode & 3); return 3; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - util::stream_format(stream, "addnf %s, a%d", i8str(program_read_byte(pc+2)), opcode & 3); + util::stream_format(stream, "addnf %s, a%d", i8str(opcodes.r8(pc+2)), opcode & 3); return 3; case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i8str(program_read_byte(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i8str(opcodes.r8(pc+2)), (opcode>>2) & 3); return 3; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: - util::stream_format(stream, "movb (%s, a%d), d%d", i8str(program_read_byte(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movb (%s, a%d), d%d", i8str(opcodes.r8(pc+2)), (opcode>>2) & 3, opcode & 3); return 3; case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: - util::stream_format(stream, "movbu (%s, a%d), d%d", i8str(program_read_byte(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movbu (%s, a%d), d%d", i8str(opcodes.r8(pc+2)), (opcode>>2) & 3, opcode & 3); return 3; case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: { - uint8_t opcode2 = program_read_byte(pc+2); + u8 opcode2 = opcodes.r8(pc+2); switch(opcode2) { case 0x00: @@ -725,13 +696,13 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i8str(program_read_byte(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i8str(opcodes.r8(pc+2)), (opcode>>2) & 3); return 3; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: { - uint8_t opcode2 = program_read_byte(pc+2); + u8 opcode2 = opcodes.r8(pc+2); switch(opcode2) { case 0x10: @@ -745,124 +716,124 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "movx (%s, a%d), d%d", i8str(program_read_byte(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movx (%s, a%d), d%d", i8str(opcodes.r8(pc+2)), (opcode>>2) & 3, opcode & 3); return 3; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: - util::stream_format(stream, "tbz (%s, a%d) %d, $%x", i8str(program_read_byte(pc+2)), (opcode>>3)&1, opcode & 7, - (pc+4+(int8_t)program_read_byte(pc+3)) & 0xffffff); + util::stream_format(stream, "tbz (%s, a%d) %d, $%x", i8str(opcodes.r8(pc+2)), (opcode>>3)&1, opcode & 7, + (pc+4+(s8)opcodes.r8(pc+3)) & 0xffffff); return 4; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: - util::stream_format(stream, "bset (%s, a%d) %d", i8str(program_read_byte(pc+2)), (opcode>>3)&1, opcode & 7); + util::stream_format(stream, "bset (%s, a%d) %d", i8str(opcodes.r8(pc+2)), (opcode>>3)&1, opcode & 7); return 3; case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: - util::stream_format(stream, "tbnz (%s, a%d) %d, $%x", i8str(program_read_byte(pc+2)), (opcode>>3)&1, opcode & 7, - (pc+4+(int8_t)program_read_byte(pc+3)) & 0xffffff); + util::stream_format(stream, "tbnz (%s, a%d) %d, $%x", i8str(opcodes.r8(pc+2)), (opcode>>3)&1, opcode & 7, + (pc+4+(s8)opcodes.r8(pc+3)) & 0xffffff); return 4; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: - util::stream_format(stream, "bclr (%s, a%d) %d", i8str(program_read_byte(pc+2)), (opcode>>3)&1, opcode & 7); + util::stream_format(stream, "bclr (%s, a%d) %d", i8str(opcodes.r8(pc+2)), (opcode>>3)&1, opcode & 7); return 3; case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: - util::stream_format(stream, "tbz ($%x) %d, $%x", r16u(pc+2), opcode & 7, - (pc+5+(int8_t)program_read_byte(pc+4)) & 0xffffff); + util::stream_format(stream, "tbz ($%x) %d, $%x", opcodes.r16(pc+2), opcode & 7, + (pc+5+(s8)opcodes.r8(pc+4)) & 0xffffff); return 5; case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: - util::stream_format(stream, "tbnz ($%x) %d, $%x", r16u(pc+2), opcode & 7, - (pc+5+(int8_t)program_read_byte(pc+4)) & 0xffffff); + util::stream_format(stream, "tbnz ($%x) %d, $%x", opcodes.r16(pc+2), opcode & 7, + (pc+5+(s8)opcodes.r8(pc+4)) & 0xffffff); return 5; case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: - util::stream_format(stream, "bset ($%x) %d", r16u(pc+2), opcode & 7); + util::stream_format(stream, "bset ($%x) %d", opcodes.r16(pc+2), opcode & 7); return 4; case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - util::stream_format(stream, "bclr ($%x) %d", r16u(pc+2), opcode & 7); + util::stream_format(stream, "bclr ($%x) %d", opcodes.r16(pc+2), opcode & 7); return 4; case 0xe0: - util::stream_format(stream, "bltx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bltx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe1: - util::stream_format(stream, "bgtx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bgtx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe2: - util::stream_format(stream, "bgex $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bgex $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe3: - util::stream_format(stream, "blex $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "blex $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe4: - util::stream_format(stream, "bcsx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bcsx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe5: - util::stream_format(stream, "bhix $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bhix $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe6: - util::stream_format(stream, "bccx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bccx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe7: - util::stream_format(stream, "blsx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "blsx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe8: - util::stream_format(stream, "beqx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "beqx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xe9: - util::stream_format(stream, "bnex $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bnex $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xec: - util::stream_format(stream, "bvcx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bvcx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xed: - util::stream_format(stream, "bvsx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bvsx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xee: - util::stream_format(stream, "bncx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bncx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xef: - util::stream_format(stream, "bnsx $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bnsx $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: { - uint8_t opcode2 = program_read_byte(pc+2); + u8 opcode2 = opcodes.r8(pc+2); switch(opcode2) { case 0x04: - util::stream_format(stream, "mulql %s, d%d", i8str(program_read_byte(pc+3)), opcode & 3); + util::stream_format(stream, "mulql %s, d%d", i8str(opcodes.r8(pc+3)), opcode & 3); return 4; case 0x05: - util::stream_format(stream, "mulqh %s, d%d", i8str(program_read_byte(pc+3)), opcode & 3); + util::stream_format(stream, "mulqh %s, d%d", i8str(opcodes.r8(pc+3)), opcode & 3); return 4; case 0x08: - util::stream_format(stream, "mulql %s, d%d", i16str(r16s(pc+3)), opcode & 3); + util::stream_format(stream, "mulql %s, d%d", i16str(opcodes.r16(pc+3)), opcode & 3); return 5; case 0x09: - util::stream_format(stream, "mulqh %s, d%d", i16str(r16s(pc+3)), opcode & 3); + util::stream_format(stream, "mulqh %s, d%d", i16str(opcodes.r16(pc+3)), opcode & 3); return 5; default: @@ -871,19 +842,19 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xfc: - util::stream_format(stream, "bvc $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bvc $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xfd: - util::stream_format(stream, "bvs $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bvs $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xfe: - util::stream_format(stream, "bnc $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bnc $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; case 0xff: - util::stream_format(stream, "bns $%x", (pc+3+(int8_t)program_read_byte(pc+2)) & 0xffffff); + util::stream_format(stream, "bns $%x", (pc+3+s8(opcodes.r8(pc+2))) & 0xffffff); return 3; default: @@ -895,104 +866,104 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o return 1; case 0xf7: - opcode = program_read_byte(pc+1); + opcode = opcodes.r8(pc+1); switch(opcode) { case 0x00: case 0x01: case 0x02: case 0x03: - util::stream_format(stream, "and $%04x, d%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "and $%04x, d%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x04: case 0x05: case 0x06: case 0x07: - util::stream_format(stream, "btst $%04x, d%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "btst $%04x, d%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x08: case 0x09: case 0x0a: case 0x0b: - util::stream_format(stream, "add %s, a%d", i16str(r16s(pc+2)), opcode & 3); + util::stream_format(stream, "add %s, a%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - util::stream_format(stream, "sub %s, a%d", i16str(r16s(pc+2)), opcode & 3); + util::stream_format(stream, "sub %s, a%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x10: - util::stream_format(stream, "and $%04x, psw", r16u(pc+2)); + util::stream_format(stream, "and $%04x, psw", opcodes.r16(pc+2)); return 4; case 0x14: - util::stream_format(stream, "or $%04x, psw", r16u(pc+2)); + util::stream_format(stream, "or $%04x, psw", opcodes.r16(pc+2)); return 4; case 0x18: case 0x19: case 0x1a: case 0x1b: - util::stream_format(stream, "add %s, d%d", i16str(r16u(pc+2)), opcode & 3); + util::stream_format(stream, "add %s, d%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x1c: case 0x1d: case 0x1e: case 0x1f: - util::stream_format(stream, "sub %s, d%d", i16str(r16s(pc+2)), opcode & 3); + util::stream_format(stream, "sub %s, d%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x20: case 0x21: case 0x22: case 0x23: - util::stream_format(stream, "mov a%d, ($%04x)", opcode & 3, r16u(pc+2)); + util::stream_format(stream, "mov a%d, ($%04x)", opcode & 3, opcodes.r16(pc+2)); return 4; case 0x30: case 0x31: case 0x32: case 0x33: - util::stream_format(stream, "mov ($%04x), a%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "mov ($%04x), a%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x40: case 0x41: case 0x42: case 0x43: - util::stream_format(stream, "or $%04x, d%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "or $%04x, d%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x48: case 0x49: case 0x4a: case 0x4b: - util::stream_format(stream, "cmp %s, d%d", i16str(r16u(pc+2)), opcode & 3); + util::stream_format(stream, "cmp %s, d%d", i16str(opcodes.r16(pc+2)), opcode & 3); return 4; case 0x4c: case 0x4d: case 0x4e: case 0x4f: - util::stream_format(stream, "xor $%04x, d%d", r16u(pc+2), opcode & 3); + util::stream_format(stream, "xor $%04x, d%d", opcodes.r16(pc+2), opcode & 3); return 4; case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - util::stream_format(stream, "movbu (%s, a%d), d%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movbu (%s, a%d), d%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: - util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i16str(r16s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movx d%d, (%s, a%d)", opcode & 3, i16str(opcodes.r16(pc+2)), (opcode>>2) & 3); return 4; case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "movx (%s, a%d), d%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movx (%s, a%d), d%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: - util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i16str(r16s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "mov d%d, (%s, a%d)", opcode & 3, i16str(opcodes.r16(pc+2)), (opcode>>2) & 3); return 4; case 0x90: case 0x91: case 0x92: case 0x93: case 0x94: case 0x95: case 0x96: case 0x97: case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f: - util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i16str(r16s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "movb d%d, (%s, a%d)", opcode & 3, i16str(opcodes.r16(pc+2)), (opcode>>2) & 3); return 4; case 0xa0: case 0xa1: case 0xa2: case 0xa3: case 0xa4: case 0xa5: case 0xa6: case 0xa7: case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: - util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i16str(r16s(pc+2)), (opcode>>2) & 3); + util::stream_format(stream, "mov a%d, (%s, a%d)", opcode & 3, i16str(opcodes.r16(pc+2)), (opcode>>2) & 3); return 4; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: - util::stream_format(stream, "mov (%s, a%d), a%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), a%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: - util::stream_format(stream, "mov (%s, a%d), d%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "mov (%s, a%d), d%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: - util::stream_format(stream, "movb (%s, a%d), d%d", i16str(r16s(pc+2)), (opcode>>2) & 3, opcode & 3); + util::stream_format(stream, "movb (%s, a%d), d%d", i16str(opcodes.r16(pc+2)), (opcode>>2) & 3, opcode & 3); return 4; default: @@ -1000,15 +971,15 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o } case 0xf8: case 0xf9: case 0xfa: case 0xfb: - util::stream_format(stream, "mov %s, d%d", i16str(r16s(pc+1)), opcode & 3); + util::stream_format(stream, "mov %s, d%d", i16str(opcodes.r16(pc+1)), opcode & 3); return 3; case 0xfc: - util::stream_format(stream, "jmp $%x", (pc+3+r16s(pc+1)) & 0xffffff); + util::stream_format(stream, "jmp $%x", (pc+3+s16(opcodes.r16(pc+1))) & 0xffffff); return 3; case 0xfd: - util::stream_format(stream, "jsr $%x", (pc+3+r16s(pc+1)) & 0xffffff); + util::stream_format(stream, "jsr $%x", (pc+3+s16(opcodes.r16(pc+1))) & 0xffffff); return 3; case 0xfe: @@ -1020,19 +991,14 @@ static int mn102_disassemble(std::ostream &stream, uint32_t pc, const uint8_t *o }; illegal1: - util::stream_format(stream, "dc.b $%02x", program_read_byte(pc)); + util::stream_format(stream, "dc.b $%02x", opcodes.r8(pc)); return 1; illegal2: - util::stream_format(stream, "dc.b $%02x $%02x", program_read_byte(pc), program_read_byte(pc+1)); + util::stream_format(stream, "dc.b $%02x $%02x", opcodes.r8(pc), opcodes.r8(pc+1)); return 2; illegal3: - util::stream_format(stream, "dc.b $%02x $%02x $%02x", program_read_byte(pc), program_read_byte(pc+1), program_read_byte(pc+2)); + util::stream_format(stream, "dc.b $%02x $%02x $%02x", opcodes.r8(pc), opcodes.r8(pc+1), opcodes.r8(pc+2)); return 3; } - -CPU_DISASSEMBLE( mn10200 ) -{ - return mn102_disassemble(stream, pc, oprom); -} diff --git a/src/devices/cpu/mn10200/mn102dis.h b/src/devices/cpu/mn10200/mn102dis.h new file mode 100644 index 00000000000..4fa8e932812 --- /dev/null +++ b/src/devices/cpu/mn10200/mn102dis.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert, R. Belmont, hap +/* + Panasonic MN10200 disassembler +*/ + +#ifndef MAME_CPU_MN10200_MN102DIS_H +#define MAME_CPU_MN10200_MN102DIS_H + +#pragma once + +class mn10200_disassembler : public util::disasm_interface +{ +public: + mn10200_disassembler() = default; + virtual ~mn10200_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + u32 r24(const data_buffer &opcodes, offs_t pc); + std::string i8str(s8 v); + std::string i16str(int16_t v); + std::string i24str(u32 v); +}; + +#endif diff --git a/src/devices/cpu/nanoprocessor/nanoprocessor.cpp b/src/devices/cpu/nanoprocessor/nanoprocessor.cpp index 655dfdb6af2..8533ec2b102 100644 --- a/src/devices/cpu/nanoprocessor/nanoprocessor.cpp +++ b/src/devices/cpu/nanoprocessor/nanoprocessor.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "nanoprocessor.h" +#include "nanoprocessor_dasm.h" #include "debugger.h" // Index of state variables @@ -33,8 +34,8 @@ enum { #define BIT_MASK(n) (1U << (n)) // Macros to clear/set single bits -#define BIT_CLR(w , n) ((w) &= ~BIT_MASK(n)) -#define BIT_SET(w , n) ((w) |= BIT_MASK(n)) +#define BIT_CLR(w, n) ((w) &= ~BIT_MASK(n)) +#define BIT_SET(w, n) ((w) |= BIT_MASK(n)) // Bits in m_flags #define NANO_DC0_BIT 0 // DC0 @@ -44,42 +45,42 @@ enum { DEFINE_DEVICE_TYPE(HP_NANOPROCESSOR, hp_nanoprocessor_device, "nanoprocessor", "HP-Nanoprocessor") hp_nanoprocessor_device::hp_nanoprocessor_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - cpu_device(mconfig , HP_NANOPROCESSOR , tag , owner , clock), + cpu_device(mconfig, HP_NANOPROCESSOR, tag, owner, clock), m_dc_changed_func(*this), m_read_dc_func(*this), - m_program_config("program" , ENDIANNESS_BIG , 8 , 11), - m_io_config("io" , ENDIANNESS_BIG , 8 , 4) + m_program_config("program", ENDIANNESS_BIG, 8, 11), + m_io_config("io", ENDIANNESS_BIG, 8, 4) { } void hp_nanoprocessor_device::device_start() { - state_add(NANO_REG_A , "A" , m_reg_A); - state_add(NANO_REG_R0 , "R0" , m_reg_R[ 0 ]); - state_add(NANO_REG_R1 , "R1" , m_reg_R[ 1 ]); - state_add(NANO_REG_R2 , "R2" , m_reg_R[ 2 ]); - state_add(NANO_REG_R3 , "R3" , m_reg_R[ 3 ]); - state_add(NANO_REG_R4 , "R4" , m_reg_R[ 4 ]); - state_add(NANO_REG_R5 , "R5" , m_reg_R[ 5 ]); - state_add(NANO_REG_R6 , "R6" , m_reg_R[ 6 ]); - state_add(NANO_REG_R7 , "R7" , m_reg_R[ 7 ]); - state_add(NANO_REG_R8 , "R8" , m_reg_R[ 8 ]); - state_add(NANO_REG_R9 , "R9" , m_reg_R[ 9 ]); - state_add(NANO_REG_R10 , "R10" , m_reg_R[ 10 ]); - state_add(NANO_REG_R11 , "R11" , m_reg_R[ 11 ]); - state_add(NANO_REG_R12 , "R12" , m_reg_R[ 12 ]); - state_add(NANO_REG_R13 , "R13" , m_reg_R[ 13 ]); - state_add(NANO_REG_R14 , "R14" , m_reg_R[ 14 ]); - state_add(NANO_REG_R15 , "R15" , m_reg_R[ 15 ]); - state_add(NANO_REG_PA , "PA" , m_reg_PA).formatstr("%03X"); - state_add(STATE_GENPC , "GENPC" , m_reg_PA).noshow(); - state_add(STATE_GENPCBASE , "GENPCBASE" , m_reg_PA).noshow(); - state_add(NANO_REG_SSR , "SSR" , m_reg_SSR).formatstr("%03X"); - state_add(NANO_REG_ISR , "ISR" , m_reg_ISR).formatstr("%03X"); - state_add(STATE_GENFLAGS , "GENFLAGS" , m_flags).noshow().formatstr("%10s"); + state_add(NANO_REG_A, "A", m_reg_A); + state_add(NANO_REG_R0, "R0", m_reg_R[ 0 ]); + state_add(NANO_REG_R1, "R1", m_reg_R[ 1 ]); + state_add(NANO_REG_R2, "R2", m_reg_R[ 2 ]); + state_add(NANO_REG_R3, "R3", m_reg_R[ 3 ]); + state_add(NANO_REG_R4, "R4", m_reg_R[ 4 ]); + state_add(NANO_REG_R5, "R5", m_reg_R[ 5 ]); + state_add(NANO_REG_R6, "R6", m_reg_R[ 6 ]); + state_add(NANO_REG_R7, "R7", m_reg_R[ 7 ]); + state_add(NANO_REG_R8, "R8", m_reg_R[ 8 ]); + state_add(NANO_REG_R9, "R9", m_reg_R[ 9 ]); + state_add(NANO_REG_R10, "R10", m_reg_R[ 10 ]); + state_add(NANO_REG_R11, "R11", m_reg_R[ 11 ]); + state_add(NANO_REG_R12, "R12", m_reg_R[ 12 ]); + state_add(NANO_REG_R13, "R13", m_reg_R[ 13 ]); + state_add(NANO_REG_R14, "R14", m_reg_R[ 14 ]); + state_add(NANO_REG_R15, "R15", m_reg_R[ 15 ]); + state_add(NANO_REG_PA, "PA", m_reg_PA).formatstr("%03X"); + state_add(STATE_GENPC, "GENPC", m_reg_PA).noshow(); + state_add(STATE_GENPCBASE, "GENPCBASE", m_reg_PA).noshow(); + state_add(NANO_REG_SSR, "SSR", m_reg_SSR).formatstr("%03X"); + state_add(NANO_REG_ISR, "ISR", m_reg_ISR).formatstr("%03X"); + state_add(STATE_GENFLAGS, "GENFLAGS", m_flags).noshow().formatstr("%10s"); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_reg_A)); @@ -122,7 +123,7 @@ void hp_nanoprocessor_device::execute_run() // Check for interrupts (interrupt line is always enabled. Masking is done // outside of the NP, usually by ANDing the DC7 line with the interrupt // request signal) - if (BIT(m_flags , NANO_I_BIT)) { + if (BIT(m_flags, NANO_I_BIT)) { m_reg_ISR = m_reg_PA; m_reg_PA = (uint16_t)(standard_irq_callback(0) & 0xff); // Vector fetching takes 1 cycle @@ -131,7 +132,7 @@ void hp_nanoprocessor_device::execute_run() // Need this to propagate the clearing of DC7 to the clearing of int. line yield(); } else { - debugger_instruction_hook(this , m_reg_PA); + debugger_instruction_hook(this, m_reg_PA); uint8_t opcode = fetch(); execute_one(opcode); @@ -156,23 +157,22 @@ void hp_nanoprocessor_device::state_string_export(const device_state_entry &entr { if (entry.index() == STATE_GENFLAGS) { // DC7 is reported as "I" because it is usually used as interrupt enable - str = string_format("%c %c%c%c%c%c%c%c%c" , BIT(m_flags , NANO_E_BIT) ? 'E' : ' ', - BIT(m_flags , NANO_DC0_BIT + 7) ? 'I' : ' ', - BIT(m_flags , NANO_DC0_BIT + 6) ? '6' : ' ', - BIT(m_flags , NANO_DC0_BIT + 5) ? '5' : ' ', - BIT(m_flags , NANO_DC0_BIT + 4) ? '4' : ' ', - BIT(m_flags , NANO_DC0_BIT + 3) ? '3' : ' ', - BIT(m_flags , NANO_DC0_BIT + 2) ? '2' : ' ', - BIT(m_flags , NANO_DC0_BIT + 1) ? '1' : ' ', - BIT(m_flags , NANO_DC0_BIT + 0) ? '0' : ' '); + str = string_format("%c %c%c%c%c%c%c%c%c", BIT(m_flags, NANO_E_BIT) ? 'E' : ' ', + BIT(m_flags, NANO_DC0_BIT + 7) ? 'I' : ' ', + BIT(m_flags, NANO_DC0_BIT + 6) ? '6' : ' ', + BIT(m_flags, NANO_DC0_BIT + 5) ? '5' : ' ', + BIT(m_flags, NANO_DC0_BIT + 4) ? '4' : ' ', + BIT(m_flags, NANO_DC0_BIT + 3) ? '3' : ' ', + BIT(m_flags, NANO_DC0_BIT + 2) ? '2' : ' ', + BIT(m_flags, NANO_DC0_BIT + 1) ? '1' : ' ', + BIT(m_flags, NANO_DC0_BIT + 0) ? '0' : ' '); } } -offs_t hp_nanoprocessor_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *hp_nanoprocessor_device::create_disassembler() { - extern CPU_DISASSEMBLE(hp_nanoprocessor); - return CPU_DISASSEMBLE_NAME(hp_nanoprocessor)(this , stream , pc , oprom , opram , options); + return new hp_nanoprocessor_disassembler; } void hp_nanoprocessor_device::execute_one(uint8_t opcode) @@ -299,14 +299,14 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) case 0x1f: // SES - if (BIT(m_flags , NANO_E_BIT)) { + if (BIT(m_flags, NANO_E_BIT)) { skip(); } break; case 0x3f: // SEZ - if (!BIT(m_flags , NANO_E_BIT)) { + if (!BIT(m_flags, NANO_E_BIT)) { skip(); } break; @@ -359,7 +359,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) switch (opcode & 0xf8) { case 0x10: // SBS - if (BIT(m_reg_A , opcode & 7)) { + if (BIT(m_reg_A, opcode & 7)) { skip(); } break; @@ -369,7 +369,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) { uint8_t tmp = m_read_dc_func(); tmp &= (uint8_t)(m_flags >> NANO_DC0_BIT); - if (BIT(tmp , opcode & 7)) { + if (BIT(tmp, opcode & 7)) { skip(); } } @@ -387,7 +387,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) case 0x30: // SBZ - if (!BIT(m_reg_A , opcode & 7)) { + if (!BIT(m_reg_A, opcode & 7)) { skip(); } break; @@ -397,7 +397,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) { uint8_t tmp = m_read_dc_func(); tmp &= (uint8_t)(m_flags >> NANO_DC0_BIT); - if (!BIT(tmp , opcode & 7)) { + if (!BIT(tmp, opcode & 7)) { skip(); } } @@ -459,7 +459,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) case 0x50: // OTA - m_io->write_byte(opcode & 0xf , m_reg_A); + m_io->write_byte(opcode & 0xf, m_reg_A); break; case 0x60: @@ -474,7 +474,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) case 0xc0: // OTR - m_io->write_byte(opcode & 0xf , fetch()); + m_io->write_byte(opcode & 0xf, fetch()); break; case 0xd0: @@ -493,7 +493,7 @@ void hp_nanoprocessor_device::execute_one(uint8_t opcode) break; default: - logerror("Unknown opcode %02x @ 0x03x\n" , opcode , m_reg_PA); + logerror("Unknown opcode %02x @ 0x03x\n", opcode, m_reg_PA); break; } } diff --git a/src/devices/cpu/nanoprocessor/nanoprocessor.h b/src/devices/cpu/nanoprocessor/nanoprocessor.h index 3518d80810b..98b717e6c07 100644 --- a/src/devices/cpu/nanoprocessor/nanoprocessor.h +++ b/src/devices/cpu/nanoprocessor/nanoprocessor.h @@ -91,9 +91,7 @@ public: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: static constexpr unsigned HP_NANO_REGS = 16; // Number of GP registers @@ -116,7 +114,7 @@ private: address_space_config m_io_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; // device_t overrides diff --git a/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.cpp b/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.cpp index 6ec1239dbc6..352c8fcbcf2 100644 --- a/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.cpp +++ b/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.cpp @@ -5,126 +5,118 @@ // ******************************* #include "emu.h" -#include "debugger.h" -#include "nanoprocessor.h" +#include "nanoprocessor_dasm.h" -typedef void (*fn_dis_param)(std::ostream& stream , uint8_t opcode , const uint8_t* opram); - -typedef struct { - uint8_t m_op_mask; - uint8_t m_opcode; - const char *m_mnemonic; - fn_dis_param m_param_fn; - uint32_t m_dasm_flags; -} dis_entry_t; - -static void param_bitno(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_bitno(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { stream << (char)('0' + (opcode & 7)); } -static void param_ds(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_ds(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "DS%u" , opcode & 0xf); + util::stream_format(stream, "DS%u", opcode & 0xf); } -static void param_reg(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_reg(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "R%u" , opcode & 0xf); + util::stream_format(stream, "R%u", opcode & 0xf); } -static void param_11bit(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_11bit(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - unsigned tmp = ((unsigned)(opcode & 7) << 8) | *opram; - util::stream_format(stream , "$%03x" , tmp); + unsigned tmp = ((unsigned)(opcode & 7) << 8) | params.r8(pc); + util::stream_format(stream, "$%03x", tmp); } -static void param_page_no(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_page_no(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { stream << (char)('0' + (opcode & 7)); } -static void param_byte(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "$%02x" , *opram); + util::stream_format(stream, "$%02x", params.r8(pc)); } -static void param_ds_byte(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_ds_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "DS%u,$%02x" , opcode & 0xf , *opram); + util::stream_format(stream, "DS%u,$%02x", opcode & 0xf, params.r8(pc)); } -static void param_reg_byte(std::ostream& stream , uint8_t opcode , const uint8_t* opram) +void hp_nanoprocessor_disassembler::param_reg_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms) { - util::stream_format(stream , "R%u,$%02x" , opcode & 0xf , *opram); + util::stream_format(stream, "R%u,$%02x", opcode & 0xf, params.r8(pc)); } -static const dis_entry_t dis_table[] = { - {0xff , 0x00 , "INB" , nullptr , 1}, - {0xff , 0x01 , "DEB" , nullptr , 1}, - {0xff , 0x02 , "IND" , nullptr , 1}, - {0xff , 0x03 , "DED" , nullptr , 1}, - {0xff , 0x04 , "CLA" , nullptr , 1}, - {0xff , 0x05 , "CMA" , nullptr , 1}, - {0xff , 0x06 , "RSA" , nullptr , 1}, - {0xff , 0x07 , "LSA" , nullptr , 1}, - {0xff , 0x08 , "SGT" , nullptr , 1}, - {0xff , 0x09 , "SLT" , nullptr , 1}, - {0xff , 0x0a , "SEQ" , nullptr , 1}, - {0xff , 0x0b , "SAZ" , nullptr , 1}, - {0xff , 0x0c , "SLE" , nullptr , 1}, - {0xff , 0x0d , "SGE" , nullptr , 1}, - {0xff , 0x0e , "SNE" , nullptr , 1}, - {0xff , 0x0f , "SAN" , nullptr , 1}, - {0xf8 , 0x10 , "SBS" , param_bitno , 1}, - {0xff , 0x1f , "SES" , nullptr , 1}, - {0xf8 , 0x18 , "SFS" , param_bitno , 1}, - {0xf8 , 0x20 , "SBN" , param_bitno , 1}, - {0xff , 0x2f , "ENI" , nullptr , 1}, - {0xf8 , 0x28 , "STC" , param_bitno , 1}, - {0xf8 , 0x30 , "SBZ" , param_bitno , 1}, - {0xff , 0x3f , "SEZ" , nullptr , 1}, - {0xf8 , 0x38 , "SFZ" , param_bitno , 1}, - {0xf0 , 0x40 , "INA" , param_ds , 1}, - {0xff , 0x5f , "NOP" , nullptr , 1}, - {0xf0 , 0x50 , "OTA" , param_ds , 1}, - {0xf0 , 0x60 , "LDA" , param_reg , 1}, - {0xf0 , 0x70 , "STA" , param_reg , 1}, - {0xf8 , 0x80 , "JMP" , param_11bit , 2}, - {0xf8 , 0x88 , "JSB" , param_11bit , 2 | DASMFLAG_STEP_OVER}, - {0xf8 , 0x90 , "JAI" , param_page_no , 1}, - {0xf8 , 0x98 , "JAS" , param_page_no , 1 | DASMFLAG_STEP_OVER}, - {0xf8 , 0xa0 , "CBN" , param_bitno , 1}, - {0xff , 0xaf , "DSI" , nullptr , 1}, - {0xf8 , 0xa8 , "CLC" , param_bitno , 1}, - {0xff , 0xb0 , "RTI" , nullptr , 1 | DASMFLAG_STEP_OUT}, - {0xff , 0xb1 , "RTE" , nullptr , 1 | DASMFLAG_STEP_OUT}, - {0xff , 0xb4 , "STE" , nullptr , 1}, - {0xff , 0xb5 , "CLE" , nullptr , 1}, - {0xff , 0xb8 , "RTS" , nullptr , 1 | DASMFLAG_STEP_OUT}, - {0xff , 0xb9 , "RSE" , nullptr , 1 | DASMFLAG_STEP_OUT}, - {0xff , 0xcf , "LDR" , param_byte , 2}, - {0xf0 , 0xc0 , "OTR" , param_ds_byte , 2}, - {0xf0 , 0xd0 , "STR" , param_reg_byte , 2}, - {0xf0 , 0xe0 , "LDI" , param_reg , 1}, - {0xf0 , 0xf0 , "STI" , param_reg , 1}, +const hp_nanoprocessor_disassembler::dis_entry_t hp_nanoprocessor_disassembler::dis_table[] = { + {0xff, 0x00, "INB", nullptr, 1}, + {0xff, 0x01, "DEB", nullptr, 1}, + {0xff, 0x02, "IND", nullptr, 1}, + {0xff, 0x03, "DED", nullptr, 1}, + {0xff, 0x04, "CLA", nullptr, 1}, + {0xff, 0x05, "CMA", nullptr, 1}, + {0xff, 0x06, "RSA", nullptr, 1}, + {0xff, 0x07, "LSA", nullptr, 1}, + {0xff, 0x08, "SGT", nullptr, 1}, + {0xff, 0x09, "SLT", nullptr, 1}, + {0xff, 0x0a, "SEQ", nullptr, 1}, + {0xff, 0x0b, "SAZ", nullptr, 1}, + {0xff, 0x0c, "SLE", nullptr, 1}, + {0xff, 0x0d, "SGE", nullptr, 1}, + {0xff, 0x0e, "SNE", nullptr, 1}, + {0xff, 0x0f, "SAN", nullptr, 1}, + {0xf8, 0x10, "SBS", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0x1f, "SES", nullptr, 1}, + {0xf8, 0x18, "SFS", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xf8, 0x20, "SBN", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0x2f, "ENI", nullptr, 1}, + {0xf8, 0x28, "STC", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xf8, 0x30, "SBZ", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0x3f, "SEZ", nullptr, 1}, + {0xf8, 0x38, "SFZ", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xf0, 0x40, "INA", &hp_nanoprocessor_disassembler::param_ds, 1}, + {0xff, 0x5f, "NOP", nullptr, 1}, + {0xf0, 0x50, "OTA", &hp_nanoprocessor_disassembler::param_ds, 1}, + {0xf0, 0x60, "LDA", &hp_nanoprocessor_disassembler::param_reg, 1}, + {0xf0, 0x70, "STA", &hp_nanoprocessor_disassembler::param_reg, 1}, + {0xf8, 0x80, "JMP", &hp_nanoprocessor_disassembler::param_11bit, 2}, + {0xf8, 0x88, "JSB", &hp_nanoprocessor_disassembler::param_11bit, 2 | STEP_OVER}, + {0xf8, 0x90, "JAI", &hp_nanoprocessor_disassembler::param_page_no, 1}, + {0xf8, 0x98, "JAS", &hp_nanoprocessor_disassembler::param_page_no, 1 | STEP_OVER}, + {0xf8, 0xa0, "CBN", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0xaf, "DSI", nullptr, 1}, + {0xf8, 0xa8, "CLC", &hp_nanoprocessor_disassembler::param_bitno, 1}, + {0xff, 0xb0, "RTI", nullptr, 1 | STEP_OUT}, + {0xff, 0xb1, "RTE", nullptr, 1 | STEP_OUT}, + {0xff, 0xb4, "STE", nullptr, 1}, + {0xff, 0xb5, "CLE", nullptr, 1}, + {0xff, 0xb8, "RTS", nullptr, 1 | STEP_OUT}, + {0xff, 0xb9, "RSE", nullptr, 1 | STEP_OUT}, + {0xff, 0xcf, "LDR", &hp_nanoprocessor_disassembler::param_byte, 2}, + {0xf0, 0xc0, "OTR", &hp_nanoprocessor_disassembler::param_ds_byte, 2}, + {0xf0, 0xd0, "STR", &hp_nanoprocessor_disassembler::param_reg_byte, 2}, + {0xf0, 0xe0, "LDI", &hp_nanoprocessor_disassembler::param_reg, 1}, + {0xf0, 0xf0, "STI", &hp_nanoprocessor_disassembler::param_reg, 1}, // Catchall for undefined opcodes - {0x00 , 0x00 , "???" , nullptr , 1} + {0x00, 0x00, "???", nullptr, 1} }; -CPU_DISASSEMBLE(hp_nanoprocessor) +u32 hp_nanoprocessor_disassembler::opcode_alignment() const { - const uint8_t opcode = *oprom; + return 1; +} - opram++; +offs_t hp_nanoprocessor_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + const uint8_t opcode = opcodes.r8(pc); for (const dis_entry_t& ent : dis_table) { if ((opcode & ent.m_op_mask) == ent.m_opcode) { stream << ent.m_mnemonic << ' '; if (ent.m_param_fn != nullptr) { - ent.m_param_fn(stream , opcode , opram); + (this->*ent.m_param_fn)(stream, opcode, pc+1, params); } - return ent.m_dasm_flags | DASMFLAG_SUPPORTED; + return ent.m_dasm_flags | SUPPORTED; } } // Should never ever happen diff --git a/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.h b/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.h new file mode 100644 index 00000000000..1287e0db605 --- /dev/null +++ b/src/devices/cpu/nanoprocessor/nanoprocessor_dasm.h @@ -0,0 +1,44 @@ +// license:BSD-3-Clause +// copyright-holders:F. Ulivi +// ******************************* +// * HP nanoprocessor disassembler +// ******************************* + +#ifndef MAME_CPU_NANOPROCESSOR_NANOPROCESSOR_DASM_H +#define MAME_CPU_NANOPROCESSOR_NANOPROCESSOR_DASM_H + +#pragma once + +class hp_nanoprocessor_disassembler : public util::disasm_interface +{ +public: + hp_nanoprocessor_disassembler() = default; + virtual ~hp_nanoprocessor_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + typedef void (hp_nanoprocessor_disassembler::*fn_dis_param)(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + + typedef struct { + uint8_t m_op_mask; + uint8_t m_opcode; + const char *m_mnemonic; + fn_dis_param m_param_fn; + uint32_t m_dasm_flags; + } dis_entry_t; + + void param_bitno(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_ds(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_reg(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_11bit(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_page_no(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_ds_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + void param_reg_byte(std::ostream& stream, uint8_t opcode, offs_t pc, const data_buffer ¶ms); + + static const dis_entry_t dis_table[]; +}; + +#endif diff --git a/src/devices/cpu/nec/nec.cpp b/src/devices/cpu/nec/nec.cpp index a4410cc12e8..c3acf3b5be3 100644 --- a/src/devices/cpu/nec/nec.cpp +++ b/src/devices/cpu/nec/nec.cpp @@ -106,6 +106,7 @@ #include "emu.h" #include "nec.h" +#include "necdasm.h" #include "debugger.h" typedef uint8_t BOOLEAN; @@ -169,10 +170,9 @@ v33a_device::v33a_device(const machine_config &mconfig, const char *tag, device_ } -offs_t nec_common_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *nec_common_device::create_disassembler() { - extern CPU_DISASSEMBLE( nec ); - return CPU_DISASSEMBLE_NAME(nec)(this, stream, pc, oprom, opram, options); + return new nec_disassembler; } @@ -223,8 +223,8 @@ uint8_t nec_common_device::fetch() uint16_t nec_common_device::fetchword() { - uint16_t r = FETCH(); - r |= (FETCH()<<8); + uint16_t r = fetch(); + r |= (fetch()<<8); return r; } @@ -419,7 +419,7 @@ void nec_common_device::device_start() save_item(NAME(m_prefetch_reset)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); state_add( NEC_PC, "PC", m_debugger_temp).callimport().callexport().formatstr("%05X"); diff --git a/src/devices/cpu/nec/nec.h b/src/devices/cpu/nec/nec.h index 4ec9e02459d..c868b58524e 100644 --- a/src/devices/cpu/nec/nec.h +++ b/src/devices/cpu/nec/nec.h @@ -48,9 +48,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -90,7 +88,7 @@ private: uint8_t m_halted; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/nec/nec_common.h b/src/devices/cpu/nec/nec_common.h deleted file mode 100644 index 4356214a302..00000000000 --- a/src/devices/cpu/nec/nec_common.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef NEC_COMMON_H -#define NEC_COMMON_H - -#include <stdint.h> - -extern int necv_dasm_one(std::ostream &stream, uint32_t eip, const uint8_t *oprom, const uint8_t *decryption_table); -extern int necv_dasm_one(char *buffer, uint32_t eip, const uint8_t *oprom, const uint8_t *decryption_table); - -#endif // NEC_COMMON_H diff --git a/src/devices/cpu/nec/necdasm.cpp b/src/devices/cpu/nec/necdasm.cpp index d313eeaf531..36f155d2527 100644 --- a/src/devices/cpu/nec/necdasm.cpp +++ b/src/devices/cpu/nec/necdasm.cpp @@ -8,82 +8,9 @@ */ #include "emu.h" -#include "nec_common.h" +#include "necdasm.h" -static const uint8_t *Iconfig; - -enum -{ - PARAM_REG8 = 1, /* 8-bit register */ - PARAM_REG16, /* 16-bit register */ - PARAM_REG2_8, /* 8-bit register */ - PARAM_REG2_16, /* 16-bit register */ - PARAM_RM8, /* 8-bit memory or register */ - PARAM_RM16, /* 16-bit memory or register */ - PARAM_RMPTR8, /* 8-bit memory or register */ - PARAM_RMPTR16, /* 16-bit memory or register */ - PARAM_I3, /* 3-bit immediate */ - PARAM_I4, /* 4-bit immediate */ - PARAM_I8, /* 8-bit signed immediate */ - PARAM_I16, /* 16-bit signed immediate */ - PARAM_UI8, /* 8-bit unsigned immediate */ - PARAM_IMM, /* 16-bit immediate */ - PARAM_ADDR, /* 16:16 address */ - PARAM_REL8, /* 8-bit PC-relative displacement */ - PARAM_REL16, /* 16-bit PC-relative displacement */ - PARAM_MEM_OFFS, /* 16-bit mem offset */ - PARAM_SREG, /* segment register */ - PARAM_SFREG, /* V25/V35 special function register */ - PARAM_1, /* used by shift/rotate instructions */ - PARAM_AL, - PARAM_CL, - PARAM_DL, - PARAM_BL, - PARAM_AH, - PARAM_CH, - PARAM_DH, - PARAM_BH, - PARAM_AW, - PARAM_CW, - PARAM_DW, - PARAM_BW, - PARAM_SP, - PARAM_BP, - PARAM_IX, - PARAM_IY -}; - -enum -{ - MODRM = 1, - GROUP, - FPU, - TWO_BYTE, - PREFIX, - SEG_PS, - SEG_DS0, - SEG_DS1, - SEG_SS -}; - -struct NEC_I386_OPCODE { - char mnemonic[32]; - uint32_t flags; - uint32_t param1; - uint32_t param2; - uint32_t param3; - offs_t dasm_flags; -}; - -struct NEC_GROUP_OP { - char mnemonic[32]; - const NEC_I386_OPCODE *opcode; -}; - -static const uint8_t *opcode_ptr; -static const uint8_t *opcode_ptr_base; - -static const NEC_I386_OPCODE necv_opcode_table1[256] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::necv_opcode_table1[256] = { // 0x00 {"add", MODRM, PARAM_RM8, PARAM_REG8, 0 }, @@ -191,7 +118,7 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"push r", 0, 0, 0, 0 }, {"pop r", 0, 0, 0, 0 }, {"chkind", MODRM, PARAM_REG16, PARAM_RM16, 0 }, - {"brkn", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, /* V25S/V35S only */ + {"brkn", 0, PARAM_UI8, 0, 0, STEP_OVER}, /* V25S/V35S only */ {"repnc", PREFIX, 0, 0, 0 }, {"repc", PREFIX, 0, 0, 0 }, {"fpo2 0", 0, 0, 0, 0 }, /* for a coprocessor that was never made */ @@ -249,7 +176,7 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"xch", 0, PARAM_AW, PARAM_IY, 0 }, {"cvtbw", 0, 0, 0, 0 }, {"cvtwl", 0, 0, 0, 0 }, - {"call", 0, PARAM_ADDR, 0, 0, DASMFLAG_STEP_OVER}, + {"call", 0, PARAM_ADDR, 0, 0, STEP_OVER}, {"poll", 0, 0, 0, 0 }, {"push psw", 0, 0, 0, 0 }, {"pop psw", 0, 0, 0, 0 }, @@ -292,20 +219,20 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = // 0xc0 {"shiftbi", GROUP, 0, 0, 0 }, {"shiftwi", GROUP, 0, 0, 0 }, - {"ret", 0, PARAM_I16, 0, 0, DASMFLAG_STEP_OUT}, - {"ret", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, + {"ret", 0, PARAM_I16, 0, 0, STEP_OUT}, + {"ret", 0, 0, 0, 0, STEP_OUT}, {"mov ds1,", MODRM, PARAM_REG16, PARAM_RM16, 0 }, {"mov ds0,", MODRM, PARAM_REG16, PARAM_RM16, 0 }, {"mov", MODRM, PARAM_RMPTR8, PARAM_UI8, 0 }, {"mov", MODRM, PARAM_RMPTR16, PARAM_IMM, 0 }, {"prepare", 0, PARAM_I16, PARAM_UI8, 0 }, {"dispose", 0, 0, 0, 0 }, - {"retf", 0, PARAM_I16, 0, 0, DASMFLAG_STEP_OUT}, - {"retf", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, - {"brk 3", 0, 0, 0, 0, DASMFLAG_STEP_OVER}, - {"brk", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, + {"retf", 0, PARAM_I16, 0, 0, STEP_OUT}, + {"retf", 0, 0, 0, 0, STEP_OUT}, + {"brk 3", 0, 0, 0, 0, STEP_OVER}, + {"brk", 0, PARAM_UI8, 0, 0, STEP_OVER}, {"brkv", 0, 0, 0, 0 }, - {"reti", 0, 0, 0, 0, DASMFLAG_STEP_OUT}, + {"reti", 0, 0, 0, 0, STEP_OUT}, // 0xd0 {"shiftb", GROUP, 0, 0, 0 }, {"shiftw", GROUP, 0, 0, 0 }, @@ -324,15 +251,15 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"escape", FPU, 0, 0, 0 }, {"escape", FPU, 0, 0, 0 }, // 0xe0 - {"dbnzne", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, - {"dbnze", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, - {"dbnz", 0, PARAM_REL8, 0, 0, DASMFLAG_STEP_OVER}, + {"dbnzne", 0, PARAM_REL8, 0, 0, STEP_OVER}, + {"dbnze", 0, PARAM_REL8, 0, 0, STEP_OVER}, + {"dbnz", 0, PARAM_REL8, 0, 0, STEP_OVER}, {"bcwz", 0, PARAM_REL8, 0, 0 }, {"in", 0, PARAM_AL, PARAM_UI8, 0 }, {"in", 0, PARAM_AW, PARAM_UI8, 0 }, {"out", 0, PARAM_UI8, PARAM_AL, 0 }, {"out", 0, PARAM_UI8, PARAM_AW, 0 }, - {"call", 0, PARAM_REL16, 0, 0, DASMFLAG_STEP_OVER}, + {"call", 0, PARAM_REL16, 0, 0, STEP_OVER}, {"br", 0, PARAM_REL16, 0, 0 }, {"br", 0, PARAM_ADDR, 0, 0 }, {"br", 0, PARAM_REL8, 0, 0 }, @@ -342,7 +269,7 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"out", 0, PARAM_DW, PARAM_AW, 0 }, // 0xf0 {"buslock", PREFIX, 0, 0, 0 }, - {"brks", 0, PARAM_UI8, 0, 0, DASMFLAG_STEP_OVER}, /* V25S/V35S only */ + {"brks", 0, PARAM_UI8, 0, 0, STEP_OVER}, /* V25S/V35S only */ {"repne", PREFIX, 0, 0, 0 }, {"rep", PREFIX, 0, 0, 0 }, {"halt", 0, 0, 0, 0 }, @@ -359,7 +286,7 @@ static const NEC_I386_OPCODE necv_opcode_table1[256] = {"group2w", GROUP, 0, 0, 0 } }; -static const NEC_I386_OPCODE necv_opcode_table2[256] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::necv_opcode_table2[256] = { // 0x00 {"???", 0, 0, 0, 0 }, @@ -409,7 +336,7 @@ static const NEC_I386_OPCODE necv_opcode_table2[256] = {"ror4", MODRM, PARAM_RMPTR8, 0, 0 }, {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, - {"brkcs", MODRM, PARAM_REG2_16, 0, 0, DASMFLAG_STEP_OVER}, /* V25/V35 only */ + {"brkcs", MODRM, PARAM_REG2_16, 0, 0, STEP_OVER}, /* V25/V35 only */ {"???", 0, 0, 0, 0 }, {"???", 0, 0, 0, 0 }, // 0x30 @@ -635,7 +562,7 @@ static const NEC_I386_OPCODE necv_opcode_table2[256] = {"brkem", 0, PARAM_UI8, 0, 0 } /* V20,30,40,50 only */ }; -static const NEC_I386_OPCODE immb_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::immb_table[8] = { {"add", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"or", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, @@ -647,7 +574,7 @@ static const NEC_I386_OPCODE immb_table[8] = {"cmp", 0, PARAM_RMPTR8, PARAM_UI8, 0 } }; -static const NEC_I386_OPCODE immw_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::immw_table[8] = { {"add", 0, PARAM_RMPTR16, PARAM_IMM, 0 }, {"or", 0, PARAM_RMPTR16, PARAM_IMM, 0 }, @@ -659,7 +586,7 @@ static const NEC_I386_OPCODE immw_table[8] = {"cmp", 0, PARAM_RMPTR16, PARAM_IMM, 0 } }; -static const NEC_I386_OPCODE immws_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::immws_table[8] = { {"add", 0, PARAM_RMPTR16, PARAM_I8, 0 }, {"or", 0, PARAM_RMPTR16, PARAM_I8, 0 }, @@ -671,7 +598,7 @@ static const NEC_I386_OPCODE immws_table[8] = {"cmp", 0, PARAM_RMPTR16, PARAM_I8, 0 } }; -static const NEC_I386_OPCODE shiftbi_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftbi_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_I8, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_I8, 0 }, @@ -683,7 +610,7 @@ static const NEC_I386_OPCODE shiftbi_table[8] = {"shra", 0, PARAM_RMPTR8, PARAM_I8, 0 } }; -static const NEC_I386_OPCODE shiftwi_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftwi_table[8] = { {"rol", 0, PARAM_RMPTR16, PARAM_I8, 0 }, {"ror", 0, PARAM_RMPTR16, PARAM_I8, 0 }, @@ -695,7 +622,7 @@ static const NEC_I386_OPCODE shiftwi_table[8] = {"shra", 0, PARAM_RMPTR16, PARAM_I8, 0 } }; -static const NEC_I386_OPCODE shiftb_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftb_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_1, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_1, 0 }, @@ -707,7 +634,7 @@ static const NEC_I386_OPCODE shiftb_table[8] = {"shra", 0, PARAM_RMPTR8, PARAM_1, 0 } }; -static const NEC_I386_OPCODE shiftw_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftw_table[8] = { {"rol", 0, PARAM_RMPTR16, PARAM_1, 0 }, {"ror", 0, PARAM_RMPTR16, PARAM_1, 0 }, @@ -719,7 +646,7 @@ static const NEC_I386_OPCODE shiftw_table[8] = {"shra", 0, PARAM_RMPTR16, PARAM_1, 0 } }; -static const NEC_I386_OPCODE shiftbv_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftbv_table[8] = { {"rol", 0, PARAM_RMPTR8, PARAM_CL, 0 }, {"ror", 0, PARAM_RMPTR8, PARAM_CL, 0 }, @@ -731,7 +658,7 @@ static const NEC_I386_OPCODE shiftbv_table[8] = {"shra", 0, PARAM_RMPTR8, PARAM_CL, 0 } }; -static const NEC_I386_OPCODE shiftwv_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::shiftwv_table[8] = { {"rol", 0, PARAM_RMPTR16, PARAM_CL, 0 }, {"ror", 0, PARAM_RMPTR16, PARAM_CL, 0 }, @@ -743,7 +670,7 @@ static const NEC_I386_OPCODE shiftwv_table[8] = {"shra", 0, PARAM_RMPTR16, PARAM_CL, 0 } }; -static const NEC_I386_OPCODE group1b_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::group1b_table[8] = { {"test", 0, PARAM_RMPTR8, PARAM_UI8, 0 }, {"???", 0, 0, 0, 0 }, @@ -755,7 +682,7 @@ static const NEC_I386_OPCODE group1b_table[8] = {"div", 0, PARAM_RMPTR8, 0, 0 } }; -static const NEC_I386_OPCODE group1w_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::group1w_table[8] = { {"test", 0, PARAM_RMPTR16, PARAM_IMM, 0 }, {"???", 0, 0, 0, 0 }, @@ -767,7 +694,7 @@ static const NEC_I386_OPCODE group1w_table[8] = {"div", 0, PARAM_RMPTR16, 0, 0 } }; -static const NEC_I386_OPCODE group2b_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::group2b_table[8] = { {"inc", 0, PARAM_RMPTR8, 0, 0 }, {"dec", 0, PARAM_RMPTR8, 0, 0 }, @@ -779,19 +706,19 @@ static const NEC_I386_OPCODE group2b_table[8] = {"???", 0, 0, 0, 0 } }; -static const NEC_I386_OPCODE group2w_table[8] = +const nec_disassembler::NEC_I386_OPCODE nec_disassembler::group2w_table[8] = { {"inc", 0, PARAM_RMPTR16, 0, 0 }, {"dec", 0, PARAM_RMPTR16, 0, 0 }, - {"call", 0, PARAM_RMPTR16, 0, 0, DASMFLAG_STEP_OVER}, - {"call far ptr ",0, PARAM_RM16, 0, 0, DASMFLAG_STEP_OVER}, + {"call", 0, PARAM_RMPTR16, 0, 0, STEP_OVER}, + {"call far ptr ",0, PARAM_RM16, 0, 0, STEP_OVER}, {"br", 0, PARAM_RMPTR16, 0, 0 }, {"br far ptr ",0, PARAM_RM16, 0, 0 }, {"push", 0, PARAM_RMPTR16, 0, 0 }, {"???", 0, 0, 0, 0 } }; -static const NEC_GROUP_OP group_op_table[] = +const nec_disassembler::NEC_GROUP_OP nec_disassembler::group_op_table[] = { { "immb", immb_table }, { "immw", immw_table }, @@ -810,10 +737,10 @@ static const NEC_GROUP_OP group_op_table[] = -static const char *const nec_reg[8] = { "aw", "cw", "dw", "bw", "sp", "bp", "ix", "iy" }; -static const char *const nec_reg8[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }; -static const char *const nec_sreg[8] = { "ds1", "ps", "ss", "ds0", "???", "???", "???", "???" }; -static const char *const nec_sfreg[256] = +const char *const nec_disassembler::nec_reg[8] = { "aw", "cw", "dw", "bw", "sp", "bp", "ix", "iy" }; +const char *const nec_disassembler::nec_reg8[8] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }; +const char *const nec_disassembler::nec_sreg[8] = { "ds1", "ps", "ss", "ds0", "???", "???", "???", "???" }; +const char *const nec_disassembler::nec_sfreg[256] = { /* 0x00 */ "p0", "pm0", "pmc0", "???", "???", "???", "???", "???", @@ -865,130 +792,88 @@ static const char *const nec_sfreg[256] = "???", "???", "???", "???", "ispr", "???", "???", "idb" }; -static uint32_t pc; -static uint8_t modrm; -static uint32_t segment; -static offs_t dasm_flags; -static char modrm_string[256]; - -#define MODRM_REG1 ((modrm >> 3) & 0x7) -#define MODRM_REG2 (modrm & 0x7) +#define MODRM_REG1 ((m_modrm >> 3) & 0x7) +#define MODRM_REG2 (m_modrm & 0x7) #define MAX_LENGTH 8 -static inline uint8_t FETCH(void) +uint8_t nec_disassembler::FETCH(offs_t pc_base, offs_t &pc, const data_buffer &opcodes) { - if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH) + if ((pc - pc_base) + 1 > MAX_LENGTH) return 0xff; + u8 r = opcodes.r8(pc); pc++; - return *opcode_ptr++; -} - -#if 0 -static inline uint16_t FETCH16(void) -{ - uint16_t d; - if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH) - return 0xffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8); - opcode_ptr += 2; - pc += 2; - return d; + return r; } -#endif -static inline uint8_t FETCHD(void) +uint16_t nec_disassembler::FETCH16(offs_t pc_base, offs_t &pc, const data_buffer &opcodes) { - if ((opcode_ptr - opcode_ptr_base) + 1 > MAX_LENGTH) + if ((pc - pc_base) + 1 > MAX_LENGTH) return 0xff; - pc++; - return *opcode_ptr++; -} - -static inline uint16_t FETCHD16(void) -{ - uint16_t d; - if ((opcode_ptr - opcode_ptr_base) + 2 > MAX_LENGTH) - return 0xffff; - d = opcode_ptr[0] | (opcode_ptr[1] << 8); - opcode_ptr += 2; + u16 r = opcodes.r16(pc); pc += 2; - return d; + return r; } -static char *hexstring(uint32_t value, int digits) +std::string nec_disassembler::hexstring(uint32_t value, int digits) { - static char buffer[20]; - buffer[0] = '0'; + std::string buffer; if (digits) - sprintf(&buffer[1], "%0*Xh", digits, value); + buffer = string_format("%0*Xh", digits, value); else - sprintf(&buffer[1], "%Xh", value); - return (buffer[1] >= '0' && buffer[1] <= '9') ? &buffer[1] : &buffer[0]; + buffer = string_format("%Xh", value); + return buffer[0] > '9' ? '0' + buffer : buffer; } -static char *shexstring(uint32_t value, int digits, bool always) +std::string nec_disassembler::shexstring(uint32_t value, int digits, bool always) { - static char buffer[20]; if (value >= 0x80000000) - sprintf(buffer, "-%s", hexstring(-value, digits)); + return '-' + hexstring(-value, digits); else if (always) - sprintf(buffer, "+%s", hexstring(value, digits)); + return '+' + hexstring(value, digits); else return hexstring(value, digits); - return buffer; } -static void handle_modrm(char* s) +void nec_disassembler::handle_modrm(offs_t pc_base, offs_t &pc, const data_buffer ¶ms) { - int8_t disp8; - int16_t disp16; - uint8_t mod, rm; + m_modrm_string = ""; - modrm = FETCHD(); - mod = (modrm >> 6) & 0x3; - rm = (modrm & 0x7); + m_modrm = FETCH(pc_base, pc, params); + u8 mod = (m_modrm >> 6) & 0x3; + u8 rm = (m_modrm & 0x7); - if( modrm >= 0xc0 ) + if( m_modrm >= 0xc0 ) return; - switch(segment) + switch(m_segment) { - case SEG_PS: s += sprintf( s, "ps:" ); break; - case SEG_DS0: s += sprintf( s, "ds0:" ); break; - case SEG_DS1: s += sprintf( s, "ds1:" ); break; - case SEG_SS: s += sprintf( s, "ss:" ); break; + case SEG_PS: m_modrm_string += "ps:"; break; + case SEG_DS0: m_modrm_string += "ds0:"; break; + case SEG_DS1: m_modrm_string += "ds1:"; break; + case SEG_SS: m_modrm_string += "ss:"; break; } - s += sprintf( s, "[" ); + m_modrm_string += '['; switch( rm ) { - case 0: s += sprintf( s, "bw+ix" ); break; - case 1: s += sprintf( s, "bw+iy" ); break; - case 2: s += sprintf( s, "bp+ix" ); break; - case 3: s += sprintf( s, "bp+iy" ); break; - case 4: s += sprintf( s, "ix" ); break; - case 5: s += sprintf( s, "iy" ); break; - case 6: - if( mod == 0 ) { - disp16 = FETCHD16(); - s += sprintf( s, "%s", hexstring((unsigned) (uint16_t) disp16, 0) ); - } else { - s += sprintf( s, "bp" ); - } - break; - case 7: s += sprintf( s, "bw" ); break; - } - if( mod == 1 ) { - disp8 = FETCHD(); - s += sprintf( s, "%s", shexstring((int32_t)disp8, 0, true) ); - } else if( mod == 2 ) { - disp16 = FETCHD16(); - s += sprintf( s, "%s", shexstring((int32_t)disp16, 0, true) ); + case 0: m_modrm_string += "bw+ix"; break; + case 1: m_modrm_string += "bw+iy"; break; + case 2: m_modrm_string += "bp+ix"; break; + case 3: m_modrm_string += "bp+iy"; break; + case 4: m_modrm_string += "ix"; break; + case 5: m_modrm_string += "iy"; break; + case 6: m_modrm_string += mod == 0 ? hexstring(u16(FETCH16(pc_base, pc, params)), 0) : "bp"; break; + case 7: m_modrm_string += "bw"; break; } - s += sprintf( s, "]" );} + if( mod == 1 ) + m_modrm_string += shexstring(s8(FETCH(pc_base, pc, params)), 0, true); + else if( mod == 2 ) + m_modrm_string += shexstring(s16(FETCH16(pc_base, pc, params)), 0, true); + m_modrm_string += ']'; +} -static void handle_param(std::ostream &stream, uint32_t param) +void nec_disassembler::handle_param(std::ostream &stream, uint32_t param, offs_t pc_base, offs_t &pc, const data_buffer ¶ms) { uint8_t i8; uint16_t i16; @@ -1017,76 +902,76 @@ static void handle_param(std::ostream &stream, uint32_t param) case PARAM_RM8: case PARAM_RMPTR8: - if( modrm >= 0xc0 ) { + if( m_modrm >= 0xc0 ) { util::stream_format( stream, "%s", nec_reg8[MODRM_REG2] ); } else { if (param == PARAM_RMPTR8) util::stream_format( stream, "byte ptr " ); - util::stream_format( stream, "%s", modrm_string ); + util::stream_format( stream, "%s", m_modrm_string ); } break; case PARAM_RM16: case PARAM_RMPTR16: - if( modrm >= 0xc0 ) { + if( m_modrm >= 0xc0 ) { util::stream_format( stream, "%s", nec_reg[MODRM_REG2] ); } else { if (param == PARAM_RMPTR16) util::stream_format( stream, "word ptr " ); - util::stream_format( stream, "%s", modrm_string ); + util::stream_format( stream, "%s", m_modrm_string ); } break; case PARAM_I3: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%d", i8 & 0x07 ); break; case PARAM_I4: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%d", i8 & 0x0f ); break; case PARAM_I8: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%s", shexstring((int8_t)i8, 0, false) ); break; case PARAM_I16: - i16 = FETCHD16(); + i16 = FETCH16(pc_base, pc, params); util::stream_format( stream, "%s", shexstring((int16_t)i16, 0, false) ); break; case PARAM_UI8: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%s", shexstring((uint8_t)i8, 0, false) ); break; case PARAM_IMM: - i16 = FETCHD16(); + i16 = FETCH16(pc_base, pc, params); util::stream_format( stream, "%s", hexstring(i16, 0) ); break; case PARAM_ADDR: - addr = FETCHD16(); - ptr = FETCHD16(); + addr = FETCH16(pc_base, pc, params); + ptr = FETCH16(pc_base, pc, params); util::stream_format( stream, "%s:", hexstring(ptr, 4) ); util::stream_format( stream, "%s", hexstring(addr, 0) ); break; case PARAM_REL16: /* make sure to keep the relative offset within the segment */ - d16 = FETCHD16(); + d16 = FETCH16(pc_base, pc, params); util::stream_format( stream, "%s", hexstring((pc & 0xFFFF0000) | ((pc + d16) & 0x0000FFFF), 0) ); break; case PARAM_REL8: - d8 = FETCHD(); + d8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%s", hexstring(pc + d8, 0) ); break; case PARAM_MEM_OFFS: - switch(segment) + switch(m_segment) { case SEG_PS: util::stream_format( stream, "ps:" ); break; case SEG_DS0: util::stream_format( stream, "ds0:" ); break; @@ -1094,7 +979,7 @@ static void handle_param(std::ostream &stream, uint32_t param) case SEG_SS: util::stream_format( stream, "ss:" ); break; } - i16 = FETCHD16(); + i16 = FETCH16(pc_base, pc, params); util::stream_format( stream, "[%s]", hexstring(i16, 0) ); break; @@ -1103,7 +988,7 @@ static void handle_param(std::ostream &stream, uint32_t param) break; case PARAM_SFREG: - i8 = FETCHD(); + i8 = FETCH(pc_base, pc, params); util::stream_format( stream, "%s", nec_sfreg[i8] ); break; @@ -1131,7 +1016,7 @@ static void handle_param(std::ostream &stream, uint32_t param) } } -static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) +void nec_disassembler::handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t pc_base, offs_t &pc, const data_buffer ¶ms) { switch (op1 & 0x7) { @@ -1140,18 +1025,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fadd dword ptr %s", modrm_string); break; - case 1: util::stream_format(stream, "fmul dword ptr %s", modrm_string); break; - case 2: util::stream_format(stream, "fcom dword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fcomp dword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fsub dword ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fsubr dword ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fdiv dword ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fdivr dword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fadd dword ptr %s", m_modrm_string); break; + case 1: util::stream_format(stream, "fmul dword ptr %s", m_modrm_string); break; + case 2: util::stream_format(stream, "fcom dword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fcomp dword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fsub dword ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fsubr dword ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fdiv dword ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fdivr dword ptr %s", m_modrm_string); break; } } else @@ -1176,18 +1060,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fld dword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fld dword ptr %s", m_modrm_string); break; case 1: util::stream_format(stream, "??? (FPU)"); break; - case 2: util::stream_format(stream, "fst dword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fstp dword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fldenv word ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fldcw word ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fstenv word ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fstcw word ptr %s", modrm_string); break; + case 2: util::stream_format(stream, "fst dword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fstp dword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fldenv word ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fldcw word ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fstenv word ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fstcw word ptr %s", m_modrm_string); break; } } else @@ -1240,18 +1123,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fiadd dword ptr %s", modrm_string); break; - case 1: util::stream_format(stream, "fimul dword ptr %s", modrm_string); break; - case 2: util::stream_format(stream, "ficom dword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "ficomp dword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fisub dword ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fisubr dword ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fidiv dword ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fidivr dword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fiadd dword ptr %s", m_modrm_string); break; + case 1: util::stream_format(stream, "fimul dword ptr %s", m_modrm_string); break; + case 2: util::stream_format(stream, "ficom dword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "ficomp dword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fisub dword ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fisubr dword ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fidiv dword ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fidivr dword ptr %s", m_modrm_string); break; } } else @@ -1282,18 +1164,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fild dword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fild dword ptr %s", m_modrm_string); break; case 1: util::stream_format(stream, "??? (FPU)"); break; - case 2: util::stream_format(stream, "fist dword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fistp dword ptr %s", modrm_string); break; + case 2: util::stream_format(stream, "fist dword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fistp dword ptr %s", m_modrm_string); break; case 4: util::stream_format(stream, "??? (FPU)"); break; - case 5: util::stream_format(stream, "fld tword ptr %s", modrm_string); break; + case 5: util::stream_format(stream, "fld tword ptr %s", m_modrm_string); break; case 6: util::stream_format(stream, "??? (FPU)"); break; - case 7: util::stream_format(stream, "fstp tword ptr %s", modrm_string); break; + case 7: util::stream_format(stream, "fstp tword ptr %s", m_modrm_string); break; } } else @@ -1332,18 +1213,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fadd qword ptr %s", modrm_string); break; - case 1: util::stream_format(stream, "fmul qword ptr %s", modrm_string); break; - case 2: util::stream_format(stream, "fcom qword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fcomp qword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fsub qword ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fsubr qword ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fdiv qword ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fdivr qword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fadd qword ptr %s", m_modrm_string); break; + case 1: util::stream_format(stream, "fmul qword ptr %s", m_modrm_string); break; + case 2: util::stream_format(stream, "fcom qword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fcomp qword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fsub qword ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fsubr qword ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fdiv qword ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fdivr qword ptr %s", m_modrm_string); break; } } else @@ -1379,18 +1259,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fld qword ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fld qword ptr %s", m_modrm_string); break; case 1: util::stream_format(stream, "??? (FPU)"); break; - case 2: util::stream_format(stream, "fst qword ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fstp qword ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "frstor %s", modrm_string); break; + case 2: util::stream_format(stream, "fst qword ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fstp qword ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "frstor %s", m_modrm_string); break; case 5: util::stream_format(stream, "??? (FPU)"); break; - case 6: util::stream_format(stream, "fsave %s", modrm_string); break; - case 7: util::stream_format(stream, "fstsw word ptr %s", modrm_string); break; + case 6: util::stream_format(stream, "fsave %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fstsw word ptr %s", m_modrm_string); break; } } else @@ -1423,18 +1302,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fiadd word ptr %s", modrm_string); break; - case 1: util::stream_format(stream, "fimul word ptr %s", modrm_string); break; - case 2: util::stream_format(stream, "ficom word ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "ficomp word ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fisub word ptr %s", modrm_string); break; - case 5: util::stream_format(stream, "fisubr word ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fidiv word ptr %s", modrm_string); break; - case 7: util::stream_format(stream, "fidivr word ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fiadd word ptr %s", m_modrm_string); break; + case 1: util::stream_format(stream, "fimul word ptr %s", m_modrm_string); break; + case 2: util::stream_format(stream, "ficom word ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "ficomp word ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fisub word ptr %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fisubr word ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fidiv word ptr %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fidivr word ptr %s", m_modrm_string); break; } } else @@ -1472,18 +1350,17 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) if (op2 < 0xc0) { pc--; // adjust fetch pointer, so modrm byte read again - opcode_ptr--; - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); switch ((op2 >> 3) & 0x7) { - case 0: util::stream_format(stream, "fild word ptr %s", modrm_string); break; + case 0: util::stream_format(stream, "fild word ptr %s", m_modrm_string); break; case 1: util::stream_format(stream, "??? (FPU)"); break; - case 2: util::stream_format(stream, "fist word ptr %s", modrm_string); break; - case 3: util::stream_format(stream, "fistp word ptr %s", modrm_string); break; - case 4: util::stream_format(stream, "fbld %s", modrm_string); break; - case 5: util::stream_format(stream, "fild qword ptr %s", modrm_string); break; - case 6: util::stream_format(stream, "fbstp %s", modrm_string); break; - case 7: util::stream_format(stream, "fistp qword ptr %s", modrm_string); break; + case 2: util::stream_format(stream, "fist word ptr %s", m_modrm_string); break; + case 3: util::stream_format(stream, "fistp word ptr %s", m_modrm_string); break; + case 4: util::stream_format(stream, "fbld %s", m_modrm_string); break; + case 5: util::stream_format(stream, "fild qword ptr %s", m_modrm_string); break; + case 6: util::stream_format(stream, "fbstp %s", m_modrm_string); break; + case 7: util::stream_format(stream, "fistp qword ptr %s", m_modrm_string); break; } } else @@ -1506,7 +1383,7 @@ static void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2) } } -static void decode_opcode(std::ostream &stream, const NEC_I386_OPCODE *op, uint8_t op1 ) +void nec_disassembler::decode_opcode(std::ostream &stream, const NEC_I386_OPCODE *op, uint8_t op1, offs_t pc_base, offs_t &pc, const data_buffer &opcodes, const data_buffer ¶ms) { int i; uint8_t op2; @@ -1514,63 +1391,63 @@ static void decode_opcode(std::ostream &stream, const NEC_I386_OPCODE *op, uint8 switch( op->flags ) { case TWO_BYTE: - op2 = FETCHD(); - decode_opcode( stream, &necv_opcode_table2[op2], op1 ); + op2 = FETCH(pc_base, pc, params); + decode_opcode( stream, &necv_opcode_table2[op2], op1, pc_base, pc, opcodes, params ); return; case SEG_PS: case SEG_DS0: case SEG_DS1: case SEG_SS: - segment = op->flags; - op2 = FETCH(); - if (Iconfig) op2 = Iconfig[op2]; - decode_opcode( stream, &necv_opcode_table1[op2], op1 ); + m_segment = op->flags; + op2 = FETCH(pc_base, pc, opcodes); + if (m_decryption_table) op2 = m_decryption_table[op2]; + decode_opcode( stream, &necv_opcode_table1[op2], op1, pc_base, pc, opcodes, params ); return; case PREFIX: util::stream_format( stream, "%-8s", op->mnemonic ); - op2 = FETCH(); - if (Iconfig) op2 = Iconfig[op2]; - decode_opcode( stream, &necv_opcode_table1[op2], op1 ); + op2 = FETCH(pc_base, pc, opcodes); + if (m_decryption_table) op2 = m_decryption_table[op2]; + decode_opcode( stream, &necv_opcode_table1[op2], op1, pc_base, pc, opcodes, params ); return; case GROUP: - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); for( i=0; i < ARRAY_LENGTH(group_op_table); i++ ) { if( strcmp(op->mnemonic, group_op_table[i].mnemonic) == 0 ) { - decode_opcode( stream, &group_op_table[i].opcode[MODRM_REG1], op1 ); + decode_opcode( stream, &group_op_table[i].opcode[MODRM_REG1], op1, pc_base, pc, opcodes, params ); return; } } goto handle_unknown; case FPU: - op2 = FETCHD(); - handle_fpu( stream, op1, op2); + op2 = FETCH(pc_base, pc, params); + handle_fpu( stream, op1, op2, pc_base, pc, params); return; case MODRM: - handle_modrm( modrm_string ); + handle_modrm( pc_base, pc, params ); break; } util::stream_format( stream, "%-8s", op->mnemonic ); - dasm_flags = op->dasm_flags; + m_dasm_flags = op->dasm_flags; if( op->param1 != 0 ) { - handle_param(stream, op->param1); + handle_param(stream, op->param1, pc_base, pc, params); } if( op->param2 != 0 ) { util::stream_format( stream, "," ); - handle_param(stream, op->param2); + handle_param(stream, op->param2, pc_base, pc, params); } if( op->param3 != 0 ) { util::stream_format( stream, "," ); - handle_param(stream, op->param3); + handle_param(stream, op->param3, pc_base, pc, params); } return; @@ -1578,25 +1455,29 @@ handle_unknown: util::stream_format(stream, "???"); } -int necv_dasm_one(std::ostream &stream, uint32_t eip, const uint8_t *oprom, const uint8_t *decryption_table) +offs_t nec_disassembler::disassemble(std::ostream &stream, offs_t eip, const data_buffer &opcodes, const data_buffer ¶ms) { uint8_t op; - Iconfig = decryption_table; - opcode_ptr = opcode_ptr_base = oprom; - pc = eip; - dasm_flags = 0; - segment = 0; + offs_t pc = eip; + m_dasm_flags = 0; + m_segment = 0; - op = FETCH(); + op = FETCH(eip, pc, opcodes); - if (Iconfig) op = Iconfig[op]; + if (m_decryption_table) + op = m_decryption_table[op]; - decode_opcode( stream, &necv_opcode_table1[op], op ); - return (pc-eip) | dasm_flags | DASMFLAG_SUPPORTED; + decode_opcode( stream, &necv_opcode_table1[op], op, eip, pc, opcodes, params ); + return (pc-eip) | m_dasm_flags | SUPPORTED; } -CPU_DISASSEMBLE( nec ) +nec_disassembler::nec_disassembler(const u8 *decryption_table) : m_decryption_table(decryption_table) { - return necv_dasm_one(stream, pc, oprom, nullptr); } + +u32 nec_disassembler::opcode_alignment() const +{ + return 1; +} + diff --git a/src/devices/cpu/nec/necdasm.h b/src/devices/cpu/nec/necdasm.h new file mode 100644 index 00000000000..9b243ffe66f --- /dev/null +++ b/src/devices/cpu/nec/necdasm.h @@ -0,0 +1,129 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// NEC disassembler interface + +#ifndef MAME_CPU_NEC_NECDASM_H +#define MAME_CPU_NEC_NECDASM_H + +#pragma once + +class nec_disassembler : public util::disasm_interface +{ +public: + nec_disassembler(const u8 *decryption_table = nullptr); + virtual ~nec_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum + { + PARAM_REG8 = 1, /* 8-bit register */ + PARAM_REG16, /* 16-bit register */ + PARAM_REG2_8, /* 8-bit register */ + PARAM_REG2_16, /* 16-bit register */ + PARAM_RM8, /* 8-bit memory or register */ + PARAM_RM16, /* 16-bit memory or register */ + PARAM_RMPTR8, /* 8-bit memory or register */ + PARAM_RMPTR16, /* 16-bit memory or register */ + PARAM_I3, /* 3-bit immediate */ + PARAM_I4, /* 4-bit immediate */ + PARAM_I8, /* 8-bit signed immediate */ + PARAM_I16, /* 16-bit signed immediate */ + PARAM_UI8, /* 8-bit unsigned immediate */ + PARAM_IMM, /* 16-bit immediate */ + PARAM_ADDR, /* 16:16 address */ + PARAM_REL8, /* 8-bit PC-relative displacement */ + PARAM_REL16, /* 16-bit PC-relative displacement */ + PARAM_MEM_OFFS, /* 16-bit mem offset */ + PARAM_SREG, /* segment register */ + PARAM_SFREG, /* V25/V35 special function register */ + PARAM_1, /* used by shift/rotate instructions */ + PARAM_AL, + PARAM_CL, + PARAM_DL, + PARAM_BL, + PARAM_AH, + PARAM_CH, + PARAM_DH, + PARAM_BH, + PARAM_AW, + PARAM_CW, + PARAM_DW, + PARAM_BW, + PARAM_SP, + PARAM_BP, + PARAM_IX, + PARAM_IY + }; + + enum + { + MODRM = 1, + GROUP, + FPU, + TWO_BYTE, + PREFIX, + SEG_PS, + SEG_DS0, + SEG_DS1, + SEG_SS + }; + + struct NEC_I386_OPCODE { + char mnemonic[32]; + uint32_t flags; + uint32_t param1; + uint32_t param2; + uint32_t param3; + offs_t dasm_flags; + }; + + struct NEC_GROUP_OP { + char mnemonic[32]; + const NEC_I386_OPCODE *opcode; + }; + + static const NEC_I386_OPCODE necv_opcode_table1[256]; + static const NEC_I386_OPCODE necv_opcode_table2[256]; + static const NEC_I386_OPCODE immb_table[8]; + static const NEC_I386_OPCODE immw_table[8]; + static const NEC_I386_OPCODE immws_table[8]; + static const NEC_I386_OPCODE shiftbi_table[8]; + static const NEC_I386_OPCODE shiftwi_table[8]; + static const NEC_I386_OPCODE shiftb_table[8]; + static const NEC_I386_OPCODE shiftw_table[8]; + static const NEC_I386_OPCODE shiftbv_table[8]; + static const NEC_I386_OPCODE shiftwv_table[8]; + static const NEC_I386_OPCODE group1b_table[8]; + static const NEC_I386_OPCODE group1w_table[8]; + static const NEC_I386_OPCODE group2b_table[8]; + static const NEC_I386_OPCODE group2w_table[8]; + static const NEC_GROUP_OP group_op_table[]; + static const char *const nec_reg[8]; + static const char *const nec_reg8[8]; + static const char *const nec_sreg[8]; + static const char *const nec_sfreg[256]; + + const u8 *m_decryption_table; + + u8 m_modrm; + u32 m_segment; + offs_t m_dasm_flags; + std::string m_modrm_string; + + inline u8 FETCH(offs_t pc_base, offs_t &pc, const data_buffer &opcodes); + inline u16 FETCH16(offs_t pc_base, offs_t &pc, const data_buffer &opcodes); + std::string hexstring(uint32_t value, int digits); + std::string shexstring(uint32_t value, int digits, bool always); + void handle_modrm(offs_t pc_base, offs_t &pc, const data_buffer ¶ms); + void handle_param(std::ostream &stream, uint32_t param, offs_t pc_base, offs_t &pc, const data_buffer ¶ms); + void handle_fpu(std::ostream &stream, uint8_t op1, uint8_t op2, offs_t pc_base, offs_t &pc, const data_buffer ¶ms); + + void decode_opcode(std::ostream &stream, const NEC_I386_OPCODE *op, uint8_t op1, offs_t pc_base, offs_t &pc, const data_buffer &opcodes, const data_buffer ¶ms); +}; + + +#endif diff --git a/src/devices/cpu/nec/necea.h b/src/devices/cpu/nec/necea.h index 1a20c0cdf54..a8b42329233 100644 --- a/src/devices/cpu/nec/necea.h +++ b/src/devices/cpu/nec/necea.h @@ -7,26 +7,26 @@ uint32_t nec_common_device::EA_002() { m_EO=Wreg(BP)+Wreg(IX); m_EA=DefaultBase( uint32_t nec_common_device::EA_003() { m_EO=Wreg(BP)+Wreg(IY); m_EA=DefaultBase(SS)+m_EO; return m_EA; } uint32_t nec_common_device::EA_004() { m_EO=Wreg(IX); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } uint32_t nec_common_device::EA_005() { m_EO=Wreg(IY); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_006() { m_EO=FETCH(); m_EO+=FETCH()<<8; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_006() { m_EO=fetch(); m_EO+=fetch()<<8; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } uint32_t nec_common_device::EA_007() { m_EO=Wreg(BW); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_100() { m_EO=(Wreg(BW)+Wreg(IX)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_101() { m_EO=(Wreg(BW)+Wreg(IY)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_102() { m_EO=(Wreg(BP)+Wreg(IX)+(int8_t)FETCH()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_103() { m_EO=(Wreg(BP)+Wreg(IY)+(int8_t)FETCH()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_104() { m_EO=(Wreg(IX)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_105() { m_EO=(Wreg(IY)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_106() { m_EO=(Wreg(BP)+(int8_t)FETCH()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_107() { m_EO=(Wreg(BW)+(int8_t)FETCH()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_100() { m_EO=(Wreg(BW)+Wreg(IX)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_101() { m_EO=(Wreg(BW)+Wreg(IY)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_102() { m_EO=(Wreg(BP)+Wreg(IX)+(int8_t)fetch()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_103() { m_EO=(Wreg(BP)+Wreg(IY)+(int8_t)fetch()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_104() { m_EO=(Wreg(IX)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_105() { m_EO=(Wreg(IY)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_106() { m_EO=(Wreg(BP)+(int8_t)fetch()); m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_107() { m_EO=(Wreg(BW)+(int8_t)fetch()); m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_200() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BW)+Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_201() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BW)+Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_202() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BP)+Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_203() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BP)+Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_204() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_205() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_206() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BP)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } -uint32_t nec_common_device::EA_207() { m_E16=FETCH(); m_E16+=FETCH()<<8; m_EO=Wreg(BW)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_200() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BW)+Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_201() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BW)+Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_202() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BP)+Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_203() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BP)+Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_204() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(IX)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_205() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(IY)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_206() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BP)+(int16_t)m_E16; m_EA=DefaultBase(SS)+m_EO; return m_EA; } +uint32_t nec_common_device::EA_207() { m_E16=fetch(); m_E16+=fetch()<<8; m_EO=Wreg(BW)+(int16_t)m_E16; m_EA=DefaultBase(DS0)+m_EO; return m_EA; } const nec_common_device::nec_eahandler nec_common_device::s_GetEA[192]= { diff --git a/src/devices/cpu/nec/necinstr.hxx b/src/devices/cpu/nec/necinstr.hxx index 98863c4c431..0499c49c65b 100644 --- a/src/devices/cpu/nec/necinstr.hxx +++ b/src/devices/cpu/nec/necinstr.hxx @@ -19,7 +19,7 @@ OP( 0x0c, i_or_ald8 ) { DEF_ald8; ORB; Breg(AL)=dst; CLKS(4,4,2); OP( 0x0d, i_or_axd16 ) { DEF_axd16; ORW; Wreg(AW)=dst; CLKS(4,4,2); } OP( 0x0e, i_push_cs ) { PUSH(Sreg(PS)); CLKS(12,8,3); } OP( 0x0f, i_pre_nec ) { uint32_t ModRM, tmp, tmp2; - switch (FETCH()) { + switch (fetch()) { case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ @@ -29,25 +29,25 @@ OP( 0x0f, i_pre_nec ) { uint32_t ModRM, tmp, tmp2; case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ - case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ - case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ - case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ - case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */ - case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */ - case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */ - case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ - case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ + case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (fetch()) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ + case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (fetch()) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ + case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (fetch()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ + case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (fetch()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */ + case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (fetch()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */ + case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (fetch()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */ + case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (fetch()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ + case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (fetch()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ case 0x20 : ADD4S; CLKS(7,7,2); break; case 0x22 : SUB4S; CLKS(7,7,2); break; case 0x26 : CMP4S; CLKS(7,7,2); break; - case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break; - case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break; - case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break; - case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break; - case 0xe0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC()); break; - case 0xf0 : ModRM = FETCH(); ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC()); break; - case 0xff : ModRM = FETCH(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC()); break; + case 0x28 : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break; + case 0x2a : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break; + case 0x31 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break; + case 0x33 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break; + case 0xe0 : ModRM = fetch(); ModRM=0; logerror("%06x: V33 unimplemented BRKXA (break to expansion address)\n",PC()); break; + case 0xf0 : ModRM = fetch(); ModRM=0; logerror("%06x: V33 unimplemented RETXA (return from expansion address)\n",PC()); break; + case 0xff : ModRM = fetch(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC()); break; default: logerror("%06x: Unknown V20 instruction\n",PC()); break; } } @@ -234,10 +234,10 @@ OP( 0x65, i_repc ) { uint32_t next = fetchop(); uint16_t c = Wreg(CW); m_seg_prefix=false; } -OP( 0x68, i_push_d16 ) { uint32_t tmp; tmp = FETCHWORD(); PUSH(tmp); CLKW(12,12,5,12,8,5,Wreg(SP)); } -OP( 0x69, i_imul_d16 ) { uint32_t tmp; DEF_r16w; tmp = FETCHWORD(); dst = (int32_t)((int16_t)src)*(int32_t)((int16_t)tmp); m_CarryVal = m_OverVal = (((int32_t)dst) >> 15 != 0) && (((int32_t)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?38:47;} -OP( 0x6a, i_push_d8 ) { uint32_t tmp = (WORD)((int16_t)((int8_t)FETCH())); PUSH(tmp); CLKW(11,11,5,11,7,3,Wreg(SP)); } -OP( 0x6b, i_imul_d8 ) { uint32_t src2; DEF_r16w; src2= (WORD)((int16_t)((int8_t)FETCH())); dst = (int32_t)((int16_t)src)*(int32_t)((int16_t)src2); m_CarryVal = m_OverVal = (((int32_t)dst) >> 15 != 0) && (((int32_t)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?31:39; } +OP( 0x68, i_push_d16 ) { uint32_t tmp; tmp = fetchword(); PUSH(tmp); CLKW(12,12,5,12,8,5,Wreg(SP)); } +OP( 0x69, i_imul_d16 ) { uint32_t tmp; DEF_r16w; tmp = fetchword(); dst = (int32_t)((int16_t)src)*(int32_t)((int16_t)tmp); m_CarryVal = m_OverVal = (((int32_t)dst) >> 15 != 0) && (((int32_t)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?38:47;} +OP( 0x6a, i_push_d8 ) { uint32_t tmp = (WORD)((int16_t)((int8_t)fetch())); PUSH(tmp); CLKW(11,11,5,11,7,3,Wreg(SP)); } +OP( 0x6b, i_imul_d8 ) { uint32_t src2; DEF_r16w; src2= (WORD)((int16_t)((int8_t)fetch())); dst = (int32_t)((int16_t)src)*(int32_t)((int16_t)src2); m_CarryVal = m_OverVal = (((int32_t)dst) >> 15 != 0) && (((int32_t)dst) >> 15 != -1); RegWord(ModRM)=(WORD)dst; m_icount-=(ModRM >=0xc0 )?31:39; } OP( 0x6c, i_insb ) { PutMemB(DS1,Wreg(IY),read_port_byte(Wreg(DW))); Wreg(IY)+= -2 * m_DF + 1; CLK(8); } OP( 0x6d, i_insw ) { PutMemW(DS1,Wreg(IY),read_port_word(Wreg(DW))); Wreg(IY)+= -4 * m_DF + 2; CLKS(18,10,8); } OP( 0x6e, i_outsb ) { write_port_byte(Wreg(DW),GetMemB(DS0,Wreg(IX))); Wreg(IX)+= -2 * m_DF + 1; CLK(8); } @@ -260,7 +260,7 @@ OP( 0x7d, i_jnl ) { JMP((ZF)||(SF==OF)); CLKS(4,4,3); } OP( 0x7e, i_jle ) { JMP((ZF)||(SF!=OF)); CLKS(4,4,3); } OP( 0x7f, i_jnle ) { JMP((SF==OF)&&(!ZF)); CLKS(4,4,3); } -OP( 0x80, i_80pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src = FETCH(); +OP( 0x80, i_80pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src = fetch(); if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7) switch (ModRM & 0x38) { case 0x00: ADDB; PutbackRMByte(ModRM,dst); break; @@ -274,7 +274,7 @@ OP( 0x80, i_80pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src } } -OP( 0x81, i_81pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src = FETCH(); src+= (FETCH() << 8); +OP( 0x81, i_81pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src = fetch(); src+= (fetch() << 8); if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,m_EA) else CLKW(26,26,11,26,18,7,m_EA) switch (ModRM & 0x38) { case 0x00: ADDW; PutbackRMWord(ModRM,dst); break; @@ -288,7 +288,7 @@ OP( 0x81, i_81pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src } } -OP( 0x82, i_82pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src = (BYTE)((int8_t)FETCH()); +OP( 0x82, i_82pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src = (BYTE)((int8_t)fetch()); if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKS(13,13,6) else CLKS(18,18,7) switch (ModRM & 0x38) { case 0x00: ADDB; PutbackRMByte(ModRM,dst); break; @@ -302,7 +302,7 @@ OP( 0x82, i_82pre ) { uint32_t dst, src; GetModRM; dst = GetRMByte(ModRM); src } } -OP( 0x83, i_83pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src = (WORD)((int16_t)((int8_t)FETCH())); +OP( 0x83, i_83pre ) { uint32_t dst, src; GetModRM; dst = GetRMWord(ModRM); src = (WORD)((int16_t)((int8_t)fetch())); if (ModRM >=0xc0 ) CLKS(4,4,2) else if ((ModRM & 0x38)==0x38) CLKW(17,17,8,17,13,6,m_EA) else CLKW(26,26,11,26,18,7,m_EA) switch (ModRM & 0x38) { case 0x00: ADDW; PutbackRMWord(ModRM,dst); break; @@ -334,7 +334,7 @@ OP( 0x8c, i_mov_wsreg ) { GetModRM; default: logerror("%06x: MOV Sreg - Invalid register\n",PC()); } } -OP( 0x8d, i_lea ) { uint16_t ModRM = FETCH(); (void)(this->*s_GetEA[ModRM])(); RegWord(ModRM)=m_EO; CLKS(4,4,2); } +OP( 0x8d, i_lea ) { uint16_t ModRM = fetch(); (void)(this->*s_GetEA[ModRM])(); RegWord(ModRM)=m_EO; CLKS(4,4,2); } OP( 0x8e, i_mov_sregw ) { uint16_t src; GetModRM; src = GetRMWord(ModRM); CLKR(15,15,7,15,11,5,2,m_EA); switch (ModRM & 0x38) { case 0x00: Sreg(DS1) = src; break; /* mov es,ew */ @@ -357,17 +357,17 @@ OP( 0x97, i_xchg_axdi ) { XchgAWReg(IY); CLK(3); } OP( 0x98, i_cbw ) { Breg(AH) = (Breg(AL) & 0x80) ? 0xff : 0; CLK(2); } OP( 0x99, i_cwd ) { Wreg(DW) = (Breg(AH) & 0x80) ? 0xffff : 0; CLK(4); } -OP( 0x9a, i_call_far ) { uint32_t tmp, tmp2; tmp = FETCHWORD(); tmp2 = FETCHWORD(); PUSH(Sreg(PS)); PUSH(m_ip); m_ip = (WORD)tmp; Sreg(PS) = (WORD)tmp2; CHANGE_PC; CLKW(29,29,13,29,21,9,Wreg(SP)); } +OP( 0x9a, i_call_far ) { uint32_t tmp, tmp2; tmp = fetchword(); tmp2 = fetchword(); PUSH(Sreg(PS)); PUSH(m_ip); m_ip = (WORD)tmp; Sreg(PS) = (WORD)tmp2; CHANGE_PC; CLKW(29,29,13,29,21,9,Wreg(SP)); } OP( 0x9b, i_wait ) { if (!m_poll_state) m_ip--; CLK(5); } OP( 0x9c, i_pushf ) { uint16_t tmp = CompressFlags(); PUSH( tmp ); CLKS(12,8,3); } OP( 0x9d, i_popf ) { uint32_t tmp; POP(tmp); ExpandFlags(tmp); CLKS(12,8,5); if (m_TF) nec_trap(); } OP( 0x9e, i_sahf ) { uint32_t tmp = (CompressFlags() & 0xff00) | (Breg(AH) & 0xd5); ExpandFlags(tmp); CLKS(3,3,2); } OP( 0x9f, i_lahf ) { Breg(AH) = CompressFlags() & 0xff; CLKS(3,3,2); } -OP( 0xa0, i_mov_aldisp ) { uint32_t addr; addr = FETCHWORD(); Breg(AL) = GetMemB(DS0, addr); CLKS(10,10,5); } -OP( 0xa1, i_mov_axdisp ) { uint32_t addr; addr = FETCHWORD(); Wreg(AW) = GetMemW(DS0, addr); CLKW(14,14,7,14,10,5,addr); } -OP( 0xa2, i_mov_dispal ) { uint32_t addr; addr = FETCHWORD(); PutMemB(DS0, addr, Breg(AL)); CLKS(9,9,3); } -OP( 0xa3, i_mov_dispax ) { uint32_t addr; addr = FETCHWORD(); PutMemW(DS0, addr, Wreg(AW)); CLKW(13,13,5,13,9,3,addr); } +OP( 0xa0, i_mov_aldisp ) { uint32_t addr; addr = fetchword(); Breg(AL) = GetMemB(DS0, addr); CLKS(10,10,5); } +OP( 0xa1, i_mov_axdisp ) { uint32_t addr; addr = fetchword(); Wreg(AW) = GetMemW(DS0, addr); CLKW(14,14,7,14,10,5,addr); } +OP( 0xa2, i_mov_dispal ) { uint32_t addr; addr = fetchword(); PutMemB(DS0, addr, Breg(AL)); CLKS(9,9,3); } +OP( 0xa3, i_mov_dispax ) { uint32_t addr; addr = fetchword(); PutMemW(DS0, addr, Wreg(AW)); CLKW(13,13,5,13,9,3,addr); } OP( 0xa4, i_movsb ) { uint32_t tmp = GetMemB(DS0,Wreg(IX)); PutMemB(DS1,Wreg(IY), tmp); Wreg(IY) += -2 * m_DF + 1; Wreg(IX) += -2 * m_DF + 1; CLKS(8,8,6); } OP( 0xa5, i_movsw ) { uint32_t tmp = GetMemW(DS0,Wreg(IX)); PutMemW(DS1,Wreg(IY), tmp); Wreg(IY) += -4 * m_DF + 2; Wreg(IX) += -4 * m_DF + 2; CLKS(16,16,10); } OP( 0xa6, i_cmpsb ) { uint32_t src = GetMemB(DS1, Wreg(IY)); uint32_t dst = GetMemB(DS0, Wreg(IX)); SUBB; Wreg(IY) += -2 * m_DF + 1; Wreg(IX) += -2 * m_DF + 1; CLKS(14,14,14); } @@ -382,28 +382,28 @@ OP( 0xad, i_lodsw ) { Wreg(AW) = GetMemW(DS0,Wreg(IX)); Wreg(IX) += -4 * m_ OP( 0xae, i_scasb ) { uint32_t src = GetMemB(DS1, Wreg(IY)); uint32_t dst = Breg(AL); SUBB; Wreg(IY) += -2 * m_DF + 1; CLKS(4,4,3); } OP( 0xaf, i_scasw ) { uint32_t src = GetMemW(DS1, Wreg(IY)); uint32_t dst = Wreg(AW); SUBW; Wreg(IY) += -4 * m_DF + 2; CLKW(8,8,5,8,4,3,Wreg(IY)); } -OP( 0xb0, i_mov_ald8 ) { Breg(AL) = FETCH(); CLKS(4,4,2); } -OP( 0xb1, i_mov_cld8 ) { Breg(CL) = FETCH(); CLKS(4,4,2); } -OP( 0xb2, i_mov_dld8 ) { Breg(DL) = FETCH(); CLKS(4,4,2); } -OP( 0xb3, i_mov_bld8 ) { Breg(BL) = FETCH(); CLKS(4,4,2); } -OP( 0xb4, i_mov_ahd8 ) { Breg(AH) = FETCH(); CLKS(4,4,2); } -OP( 0xb5, i_mov_chd8 ) { Breg(CH) = FETCH(); CLKS(4,4,2); } -OP( 0xb6, i_mov_dhd8 ) { Breg(DH) = FETCH(); CLKS(4,4,2); } -OP( 0xb7, i_mov_bhd8 ) { Breg(BH) = FETCH(); CLKS(4,4,2); } - -OP( 0xb8, i_mov_axd16 ) { Breg(AL) = FETCH(); Breg(AH) = FETCH(); CLKS(4,4,2); } -OP( 0xb9, i_mov_cxd16 ) { Breg(CL) = FETCH(); Breg(CH) = FETCH(); CLKS(4,4,2); } -OP( 0xba, i_mov_dxd16 ) { Breg(DL) = FETCH(); Breg(DH) = FETCH(); CLKS(4,4,2); } -OP( 0xbb, i_mov_bxd16 ) { Breg(BL) = FETCH(); Breg(BH) = FETCH(); CLKS(4,4,2); } -OP( 0xbc, i_mov_spd16 ) { Wreg(SP) = FETCHWORD(); CLKS(4,4,2); } -OP( 0xbd, i_mov_bpd16 ) { Wreg(BP) = FETCHWORD(); CLKS(4,4,2); } -OP( 0xbe, i_mov_sid16 ) { Wreg(IX) = FETCHWORD(); CLKS(4,4,2); } -OP( 0xbf, i_mov_did16 ) { Wreg(IY) = FETCHWORD(); CLKS(4,4,2); } +OP( 0xb0, i_mov_ald8 ) { Breg(AL) = fetch(); CLKS(4,4,2); } +OP( 0xb1, i_mov_cld8 ) { Breg(CL) = fetch(); CLKS(4,4,2); } +OP( 0xb2, i_mov_dld8 ) { Breg(DL) = fetch(); CLKS(4,4,2); } +OP( 0xb3, i_mov_bld8 ) { Breg(BL) = fetch(); CLKS(4,4,2); } +OP( 0xb4, i_mov_ahd8 ) { Breg(AH) = fetch(); CLKS(4,4,2); } +OP( 0xb5, i_mov_chd8 ) { Breg(CH) = fetch(); CLKS(4,4,2); } +OP( 0xb6, i_mov_dhd8 ) { Breg(DH) = fetch(); CLKS(4,4,2); } +OP( 0xb7, i_mov_bhd8 ) { Breg(BH) = fetch(); CLKS(4,4,2); } + +OP( 0xb8, i_mov_axd16 ) { Breg(AL) = fetch(); Breg(AH) = fetch(); CLKS(4,4,2); } +OP( 0xb9, i_mov_cxd16 ) { Breg(CL) = fetch(); Breg(CH) = fetch(); CLKS(4,4,2); } +OP( 0xba, i_mov_dxd16 ) { Breg(DL) = fetch(); Breg(DH) = fetch(); CLKS(4,4,2); } +OP( 0xbb, i_mov_bxd16 ) { Breg(BL) = fetch(); Breg(BH) = fetch(); CLKS(4,4,2); } +OP( 0xbc, i_mov_spd16 ) { Wreg(SP) = fetchword(); CLKS(4,4,2); } +OP( 0xbd, i_mov_bpd16 ) { Wreg(BP) = fetchword(); CLKS(4,4,2); } +OP( 0xbe, i_mov_sid16 ) { Wreg(IX) = fetchword(); CLKS(4,4,2); } +OP( 0xbf, i_mov_did16 ) { Wreg(IY) = fetchword(); CLKS(4,4,2); } OP( 0xc0, i_rotshft_bd8 ) { uint32_t src, dst; uint8_t c; GetModRM; src = (unsigned)GetRMByte(ModRM); dst=src; - c=FETCH(); + c=fetch(); CLKM(7,7,2,19,19,6); if (c) switch (ModRM & 0x38) { case 0x00: do { ROL_BYTE; c--; CLK(1); } while (c>0); PutbackRMByte(ModRM,(BYTE)dst); break; @@ -420,7 +420,7 @@ OP( 0xc0, i_rotshft_bd8 ) { OP( 0xc1, i_rotshft_wd8 ) { uint32_t src, dst; uint8_t c; GetModRM; src = (unsigned)GetRMWord(ModRM); dst=src; - c=FETCH(); + c=fetch(); CLKM(7,7,2,27,19,6); if (c) switch (ModRM & 0x38) { case 0x00: do { ROL_WORD; c--; CLK(1); } while (c>0); PutbackRMWord(ModRM,(WORD)dst); break; @@ -434,7 +434,7 @@ OP( 0xc1, i_rotshft_wd8 ) { } } -OP( 0xc2, i_ret_d16 ) { uint32_t count = FETCH(); count += FETCH() << 8; POP(m_ip); Wreg(SP)+=count; CHANGE_PC; CLKS(24,24,10); } +OP( 0xc2, i_ret_d16 ) { uint32_t count = fetch(); count += fetch() << 8; POP(m_ip); Wreg(SP)+=count; CHANGE_PC; CLKS(24,24,10); } OP( 0xc3, i_ret ) { POP(m_ip); CHANGE_PC; CLKS(19,19,10); } OP( 0xc4, i_les_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS1) = GetnextRMWord; CLKW(26,26,14,26,18,10,m_EA); } OP( 0xc5, i_lds_dw ) { GetModRM; WORD tmp = GetRMWord(ModRM); RegWord(ModRM)=tmp; Sreg(DS0) = GetnextRMWord; CLKW(26,26,14,26,18,10,m_EA); } @@ -442,12 +442,12 @@ OP( 0xc6, i_mov_bd8 ) { GetModRM; PutImmRMByte(ModRM); m_icount-=(ModRM >=0xc0 OP( 0xc7, i_mov_wd16 ) { GetModRM; PutImmRMWord(ModRM); m_icount-=(ModRM >=0xc0 )?4:15; } OP( 0xc8, i_enter ) { - uint32_t nb = FETCH(); + uint32_t nb = fetch(); uint32_t i,level; m_icount-=23; - nb += FETCH() << 8; - level = FETCH(); + nb += fetch() << 8; + level = fetch(); PUSH(Wreg(BP)); Wreg(BP)=Wreg(SP); Wreg(SP) -= nb; @@ -462,10 +462,10 @@ OP( 0xc9, i_leave ) { POP(Wreg(BP)); m_icount-=8; } -OP( 0xca, i_retf_d16 ) { uint32_t count = FETCH(); count += FETCH() << 8; POP(m_ip); POP(Sreg(PS)); Wreg(SP)+=count; CHANGE_PC; CLKS(32,32,16); } +OP( 0xca, i_retf_d16 ) { uint32_t count = fetch(); count += fetch() << 8; POP(m_ip); POP(Sreg(PS)); Wreg(SP)+=count; CHANGE_PC; CLKS(32,32,16); } OP( 0xcb, i_retf ) { POP(m_ip); POP(Sreg(PS)); CHANGE_PC; CLKS(29,29,16); } OP( 0xcc, i_int3 ) { nec_interrupt(3, BRK); CLKS(50,50,24); } -OP( 0xcd, i_int ) { nec_interrupt(FETCH(), BRK); CLKS(50,50,24); } +OP( 0xcd, i_int ) { nec_interrupt(fetch(), BRK); CLKS(50,50,24); } OP( 0xce, i_into ) { if (OF) { nec_interrupt(NEC_BRKV_VECTOR, BRK); CLKS(52,52,26); } else CLK(3); } OP( 0xcf, i_iret ) { POP(m_ip); POP(Sreg(PS)); i_popf(); CHANGE_PC; CLKS(39,39,19); } @@ -531,25 +531,25 @@ OP( 0xd3, i_rotshft_wcl ) { } } -OP( 0xd4, i_aam ) { FETCH(); Breg(AH) = Breg(AL) / 10; Breg(AL) %= 10; SetSZPF_Word(Wreg(AW)); CLKS(15,15,12); } -OP( 0xd5, i_aad ) { FETCH(); Breg(AL) = Breg(AH) * 10 + Breg(AL); Breg(AH) = 0; SetSZPF_Byte(Breg(AL)); CLKS(7,7,8); } +OP( 0xd4, i_aam ) { fetch(); Breg(AH) = Breg(AL) / 10; Breg(AL) %= 10; SetSZPF_Word(Wreg(AW)); CLKS(15,15,12); } +OP( 0xd5, i_aad ) { fetch(); Breg(AL) = Breg(AH) * 10 + Breg(AL); Breg(AH) = 0; SetSZPF_Byte(Breg(AL)); CLKS(7,7,8); } OP( 0xd6, i_setalc ) { Breg(AL) = (CF)?0xff:0x00; m_icount-=3; logerror("%06x: Undefined opcode (SETALC)\n",PC()); } OP( 0xd7, i_trans ) { uint32_t dest = (Wreg(BW)+Breg(AL))&0xffff; Breg(AL) = GetMemB(DS0, dest); CLKS(9,9,5); } OP( 0xd8, i_fpo ) { GetModRM; GetRMByte(ModRM); m_icount-=2; logerror("%06x: Unimplemented floating point control %04x\n",PC(),ModRM); } -OP( 0xe0, i_loopne ) { int8_t disp = (int8_t)FETCH(); Wreg(CW)--; if (!ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); } -OP( 0xe1, i_loope ) { int8_t disp = (int8_t)FETCH(); Wreg(CW)--; if ( ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); } -OP( 0xe2, i_loop ) { int8_t disp = (int8_t)FETCH(); Wreg(CW)--; if (Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); } -OP( 0xe3, i_jcxz ) { int8_t disp = (int8_t)FETCH(); if (Wreg(CW) == 0) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); } -OP( 0xe4, i_inal ) { uint8_t port = FETCH(); Breg(AL) = read_port_byte(port); CLKS(9,9,5); } -OP( 0xe5, i_inax ) { uint8_t port = FETCH(); Wreg(AW) = read_port_word(port); CLKW(13,13,7,13,9,5,port); } -OP( 0xe6, i_outal ) { uint8_t port = FETCH(); write_port_byte(port, Breg(AL)); CLKS(8,8,3); } -OP( 0xe7, i_outax ) { uint8_t port = FETCH(); write_port_word(port, Wreg(AW)); CLKW(12,12,5,12,8,3,port); } - -OP( 0xe8, i_call_d16 ) { uint32_t tmp; tmp = FETCHWORD(); PUSH(m_ip); m_ip = (WORD)(m_ip+(int16_t)tmp); CHANGE_PC; m_icount-=24; } -OP( 0xe9, i_jmp_d16 ) { uint32_t tmp; tmp = FETCHWORD(); m_ip = (WORD)(m_ip+(int16_t)tmp); CHANGE_PC; m_icount-=15; } -OP( 0xea, i_jmp_far ) { uint32_t tmp,tmp1; tmp = FETCHWORD(); tmp1 = FETCHWORD(); Sreg(PS) = (WORD)tmp1; m_ip = (WORD)tmp; CHANGE_PC; m_icount-=27; } -OP( 0xeb, i_jmp_d8 ) { int tmp = (int)((int8_t)FETCH()); m_icount-=12; m_ip = (WORD)(m_ip+tmp); } +OP( 0xe0, i_loopne ) { int8_t disp = (int8_t)fetch(); Wreg(CW)--; if (!ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); } +OP( 0xe1, i_loope ) { int8_t disp = (int8_t)fetch(); Wreg(CW)--; if ( ZF && Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(14,14,6); } else CLKS(5,5,3); } +OP( 0xe2, i_loop ) { int8_t disp = (int8_t)fetch(); Wreg(CW)--; if (Wreg(CW)) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); } +OP( 0xe3, i_jcxz ) { int8_t disp = (int8_t)fetch(); if (Wreg(CW) == 0) { m_ip = (WORD)(m_ip+disp); /*CHANGE_PC;*/ CLKS(13,13,6); } else CLKS(5,5,3); } +OP( 0xe4, i_inal ) { uint8_t port = fetch(); Breg(AL) = read_port_byte(port); CLKS(9,9,5); } +OP( 0xe5, i_inax ) { uint8_t port = fetch(); Wreg(AW) = read_port_word(port); CLKW(13,13,7,13,9,5,port); } +OP( 0xe6, i_outal ) { uint8_t port = fetch(); write_port_byte(port, Breg(AL)); CLKS(8,8,3); } +OP( 0xe7, i_outax ) { uint8_t port = fetch(); write_port_word(port, Wreg(AW)); CLKW(12,12,5,12,8,3,port); } + +OP( 0xe8, i_call_d16 ) { uint32_t tmp; tmp = fetchword(); PUSH(m_ip); m_ip = (WORD)(m_ip+(int16_t)tmp); CHANGE_PC; m_icount-=24; } +OP( 0xe9, i_jmp_d16 ) { uint32_t tmp; tmp = fetchword(); m_ip = (WORD)(m_ip+(int16_t)tmp); CHANGE_PC; m_icount-=15; } +OP( 0xea, i_jmp_far ) { uint32_t tmp,tmp1; tmp = fetchword(); tmp1 = fetchword(); Sreg(PS) = (WORD)tmp1; m_ip = (WORD)tmp; CHANGE_PC; m_icount-=27; } +OP( 0xeb, i_jmp_d8 ) { int tmp = (int)((int8_t)fetch()); m_icount-=12; m_ip = (WORD)(m_ip+tmp); } OP( 0xec, i_inaldx ) { Breg(AL) = read_port_byte(Wreg(DW)); CLKS(8,8,5);} OP( 0xed, i_inaxdx ) { Wreg(AW) = read_port_word(Wreg(DW)); CLKW(12,12,7,12,8,5,Wreg(DW)); } OP( 0xee, i_outdxal ) { write_port_byte(Wreg(DW), Breg(AL)); CLKS(8,8,3); } @@ -615,7 +615,7 @@ OP( 0xf5, i_cmc ) { m_CarryVal = !CF; CLK(2); } OP( 0xf6, i_f6pre ) { uint32_t tmp; uint32_t uresult,uresult2; int32_t result,result2; GetModRM; tmp = GetRMByte(ModRM); switch (ModRM & 0x38) { - case 0x00: tmp &= FETCH(); m_CarryVal = m_OverVal = 0; SetSZPF_Byte(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */ + case 0x00: tmp &= fetch(); m_CarryVal = m_OverVal = 0; SetSZPF_Byte(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */ case 0x08: logerror("%06x: Undefined opcode 0xf6 0x08\n",PC()); break; case 0x10: PutbackRMByte(ModRM,~tmp); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */ case 0x18: m_CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Byte(tmp); PutbackRMByte(ModRM,tmp&0xff); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */ @@ -629,7 +629,7 @@ OP( 0xf6, i_f6pre ) { uint32_t tmp; uint32_t uresult,uresult2; int32_t result,re OP( 0xf7, i_f7pre ) { uint32_t tmp,tmp2; uint32_t uresult,uresult2; int32_t result,result2; GetModRM; tmp = GetRMWord(ModRM); switch (ModRM & 0x38) { - case 0x00: tmp2 = FETCHWORD(); tmp &= tmp2; m_CarryVal = m_OverVal = 0; SetSZPF_Word(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */ + case 0x00: tmp2 = fetchword(); tmp &= tmp2; m_CarryVal = m_OverVal = 0; SetSZPF_Word(tmp); m_icount-=(ModRM >=0xc0 )?4:11; break; /* TEST */ case 0x08: logerror("%06x: Undefined opcode 0xf7 0x08\n",PC()); break; case 0x10: PutbackRMWord(ModRM,~tmp); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NOT */ case 0x18: m_CarryVal=(tmp!=0); tmp=(~tmp)+1; SetSZPF_Word(tmp); PutbackRMWord(ModRM,tmp&0xffff); m_icount-=(ModRM >=0xc0 )?2:16; break; /* NEG */ diff --git a/src/devices/cpu/nec/necmacro.h b/src/devices/cpu/nec/necmacro.h index c97f487cc2c..582c233979f 100644 --- a/src/devices/cpu/nec/necmacro.h +++ b/src/devices/cpu/nec/necmacro.h @@ -55,8 +55,8 @@ #define JMP(flag) \ int tmp; \ - EMPTY_PREFETCH(); \ - tmp = (int)((int8_t)FETCH()); \ + EMPTY_PREfetch(); \ + tmp = (int)((int8_t)fetch()); \ if (flag) \ { \ static const uint8_t table[3]={3,10,10}; \ @@ -98,7 +98,7 @@ Breg(AL) &= 0x0F #define BITOP_BYTE \ - ModRM = FETCH(); \ + ModRM = fetch(); \ if (ModRM >= 0xc0) { \ tmp=Breg(Mod_RM.RM.b[ModRM]); \ } \ @@ -108,7 +108,7 @@ } #define BITOP_WORD \ - ModRM = FETCH(); \ + ModRM = fetch(); \ if (ModRM >= 0xc0) { \ tmp=Wreg(Mod_RM.RM.w[ModRM]); \ } \ diff --git a/src/devices/cpu/nec/necmodrm.h b/src/devices/cpu/nec/necmodrm.h index 2bc3afdfd28..ac69a0010be 100644 --- a/src/devices/cpu/nec/necmodrm.h +++ b/src/devices/cpu/nec/necmodrm.h @@ -39,10 +39,10 @@ static struct { { \ WORD val; \ if (ModRM >= 0xc0) \ - Wreg(Mod_RM.RM.w[ModRM]) = FETCHWORD(); \ + Wreg(Mod_RM.RM.w[ModRM]) = fetchword(); \ else { \ (this->*s_GetEA[ModRM])(); \ - val = FETCHWORD(); \ + val = fetchword(); \ write_mem_word( m_EA , val); \ } \ } @@ -61,10 +61,10 @@ static struct { #define PutImmRMByte(ModRM) \ { \ if (ModRM >= 0xc0) \ - Breg(Mod_RM.RM.b[ModRM])=FETCH(); \ + Breg(Mod_RM.RM.b[ModRM])=fetch(); \ else { \ (this->*s_GetEA[ModRM])(); \ - write_mem_byte( m_EA , FETCH() ); \ + write_mem_byte( m_EA , fetch() ); \ } \ } @@ -77,30 +77,30 @@ static struct { } #define DEF_br8 \ - uint32_t ModRM = FETCH(),src,dst; \ + uint32_t ModRM = fetch(),src,dst; \ src = RegByte(ModRM); \ dst = GetRMByte(ModRM) #define DEF_wr16 \ - uint32_t ModRM = FETCH(),src,dst; \ + uint32_t ModRM = fetch(),src,dst; \ src = RegWord(ModRM); \ dst = GetRMWord(ModRM) #define DEF_r8b \ - uint32_t ModRM = FETCH(),src,dst; \ + uint32_t ModRM = fetch(),src,dst; \ dst = RegByte(ModRM); \ src = GetRMByte(ModRM) #define DEF_r16w \ - uint32_t ModRM = FETCH(),src,dst; \ + uint32_t ModRM = fetch(),src,dst; \ dst = RegWord(ModRM); \ src = GetRMWord(ModRM) #define DEF_ald8 \ - uint32_t src = FETCH(); \ + uint32_t src = fetch(); \ uint32_t dst = Breg(AL) #define DEF_axd16 \ - uint32_t src = FETCH(); \ + uint32_t src = fetch(); \ uint32_t dst = Wreg(AW); \ - src += (FETCH() << 8) + src += (fetch() << 8) diff --git a/src/devices/cpu/nec/necpriv.h b/src/devices/cpu/nec/necpriv.h index 2d4cb9f6b2f..459fa5017b4 100644 --- a/src/devices/cpu/nec/necpriv.h +++ b/src/devices/cpu/nec/necpriv.h @@ -64,7 +64,7 @@ enum BREGS { /************************************************************************/ -#define CHANGE_PC do { EMPTY_PREFETCH(); } while (0) +#define CHANGE_PC do { EMPTY_PREfetch(); } while (0) #define SegBase(Seg) (Sreg(Seg) << 4) @@ -78,15 +78,13 @@ enum BREGS { /* prefetch timing */ -#define FETCH() fetch() -#define FETCHWORD() fetchword() -#define EMPTY_PREFETCH() m_prefetch_reset = 1 +#define EMPTY_PREfetch() m_prefetch_reset = 1 #define PUSH(val) { Wreg(SP) -= 2; write_mem_word(((Sreg(SS)<<4)+Wreg(SP)), val); } #define POP(var) { Wreg(SP) += 2; var = read_mem_word(((Sreg(SS)<<4) + ((Wreg(SP)-2) & 0xffff))); } -#define GetModRM uint32_t ModRM=FETCH() +#define GetModRM uint32_t ModRM=fetch() /* Cycle count macros: CLK - cycle count is the same on all processors diff --git a/src/devices/cpu/nec/v25.cpp b/src/devices/cpu/nec/v25.cpp index d70bbd224c0..7c1dfb28731 100644 --- a/src/devices/cpu/nec/v25.cpp +++ b/src/devices/cpu/nec/v25.cpp @@ -44,7 +44,7 @@ typedef uint32_t DWORD; #include "v25.h" #include "v25priv.h" -#include "nec_common.h" +#include "necdasm.h" DEFINE_DEVICE_TYPE(V25, v25_device, "v25", "V25") DEFINE_DEVICE_TYPE(V35, v35_device, "v35", "V35") @@ -142,8 +142,8 @@ uint8_t v25_common_device::fetch() uint16_t v25_common_device::fetchword() { - uint16_t r = FETCH(); - r |= (FETCH()<<8); + uint16_t r = fetch(); + r |= (fetch()<<8); return r; } @@ -419,9 +419,9 @@ void v25_common_device::execute_set_input(int irqline, int state) } } -offs_t v25_common_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *v25_common_device::create_disassembler() { - return necv_dasm_one(stream, pc, oprom, m_v25v35_decryptiontable); + return new nec_disassembler(m_v25v35_decryptiontable); } void v25_common_device::device_start() @@ -511,7 +511,7 @@ void v25_common_device::device_start() save_item(NAME(m_prefetch_reset)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_pt_in.resolve_safe(0xff); diff --git a/src/devices/cpu/nec/v25.h b/src/devices/cpu/nec/v25.h index f0ccda61517..cda729e88ef 100644 --- a/src/devices/cpu/nec/v25.h +++ b/src/devices/cpu/nec/v25.h @@ -93,9 +93,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -143,7 +141,7 @@ private: uint32_t m_IDB; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/nec/v25instr.hxx b/src/devices/cpu/nec/v25instr.hxx index 881f2044aae..e394e9ab213 100644 --- a/src/devices/cpu/nec/v25instr.hxx +++ b/src/devices/cpu/nec/v25instr.hxx @@ -1,7 +1,7 @@ // license:BSD-3-Clause // copyright-holders:Bryan McPhail, Alex W. Jackson #define GetRB \ - ModRM = FETCH(); \ + ModRM = fetch(); \ if (ModRM >= 0xc0) \ tmp = Wreg(Mod_RM.RM.w[ModRM]) & 0x7; \ else { \ @@ -43,7 +43,7 @@ } OP( 0x0f, i_pre_v25 ) { uint32_t ModRM, tmp, tmp2; - switch (FETCH()) { + switch (fetch()) { case 0x10 : BITOP_BYTE; CLKS(3,3,4); tmp2 = Breg(CL) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ case 0x11 : BITOP_WORD; CLKS(3,3,4); tmp2 = Breg(CL) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ case 0x12 : BITOP_BYTE; CLKS(5,5,4); tmp2 = Breg(CL) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ @@ -53,24 +53,24 @@ OP( 0x0f, i_pre_v25 ) { uint32_t ModRM, tmp, tmp2; case 0x16 : BITOP_BYTE; CLKS(4,4,4); tmp2 = Breg(CL) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ case 0x17 : BITOP_WORD; CLKS(4,4,4); tmp2 = Breg(CL) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ - case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (FETCH()) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ - case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (FETCH()) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ - case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (FETCH()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ - case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (FETCH()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */ - case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */ - case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */ - case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (FETCH()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ - case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (FETCH()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ + case 0x18 : BITOP_BYTE; CLKS(4,4,4); tmp2 = (fetch()) & 0x7; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ + case 0x19 : BITOP_WORD; CLKS(4,4,4); tmp2 = (fetch()) & 0xf; m_ZeroVal = (tmp & (1<<tmp2)) ? 1 : 0; m_CarryVal=m_OverVal=0; break; /* Test */ + case 0x1a : BITOP_BYTE; CLKS(6,6,4); tmp2 = (fetch()) & 0x7; tmp &= ~(1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Clr */ + case 0x1b : BITOP_WORD; CLKS(6,6,4); tmp2 = (fetch()) & 0xf; tmp &= ~(1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Clr */ + case 0x1c : BITOP_BYTE; CLKS(5,5,4); tmp2 = (fetch()) & 0x7; tmp |= (1<<tmp2); PutbackRMByte(ModRM,tmp); break; /* Set */ + case 0x1d : BITOP_WORD; CLKS(5,5,4); tmp2 = (fetch()) & 0xf; tmp |= (1<<tmp2); PutbackRMWord(ModRM,tmp); break; /* Set */ + case 0x1e : BITOP_BYTE; CLKS(5,5,4); tmp2 = (fetch()) & 0x7; BIT_NOT; PutbackRMByte(ModRM,tmp); break; /* Not */ + case 0x1f : BITOP_WORD; CLKS(5,5,4); tmp2 = (fetch()) & 0xf; BIT_NOT; PutbackRMWord(ModRM,tmp); break; /* Not */ case 0x20 : ADD4S; CLKS(7,7,2); break; case 0x22 : SUB4S; CLKS(7,7,2); break; case 0x25 : MOVSPA; CLK(16); break; case 0x26 : CMP4S; CLKS(7,7,2); break; - case 0x28 : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break; - case 0x2a : ModRM = FETCH(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break; + case 0x28 : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break; + case 0x2a : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break; case 0x2d : GetRB; nec_bankswitch(tmp); CLK(15); break; - case 0x31 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break; - case 0x33 : ModRM = FETCH(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break; + case 0x31 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break; + case 0x33 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break; case 0x91 : RETRBI; CLK(12); break; case 0x92 : FINT; CLK(2); m_no_interrupt = 1; break; case 0x94 : GetRB; TSKSW; CLK(20); break; @@ -80,5 +80,5 @@ OP( 0x0f, i_pre_v25 ) { uint32_t ModRM, tmp, tmp2; } } -OP( 0x63, i_brkn ) { nec_interrupt(FETCH(), BRKN); CLKS(50,50,24); } -OP( 0xF1, i_brks ) { nec_interrupt(FETCH(), BRKS); CLKS(50,50,24); } +OP( 0x63, i_brkn ) { nec_interrupt(fetch(), BRKN); CLKS(50,50,24); } +OP( 0xF1, i_brks ) { nec_interrupt(fetch(), BRKS); CLKS(50,50,24); } diff --git a/src/devices/cpu/nec/v25priv.h b/src/devices/cpu/nec/v25priv.h index c9022898436..eb60c8f041d 100644 --- a/src/devices/cpu/nec/v25priv.h +++ b/src/devices/cpu/nec/v25priv.h @@ -121,7 +121,7 @@ enum BREGS { /************************************************************************/ -#define CHANGE_PC do { EMPTY_PREFETCH(); } while (0) +#define CHANGE_PC do { EMPTY_PREfetch(); } while (0) #define SegBase(Seg) (Sreg(Seg) << 4) @@ -135,15 +135,13 @@ enum BREGS { /* prefetch timing */ -#define FETCH() fetch() -#define FETCHWORD() fetchword() -#define EMPTY_PREFETCH() m_prefetch_reset = 1 +#define EMPTY_PREfetch() m_prefetch_reset = 1 #define PUSH(val) { Wreg(SP) -= 2; write_mem_word(((Sreg(SS)<<4)+Wreg(SP)), val); } #define POP(var) { Wreg(SP) += 2; var = read_mem_word(((Sreg(SS)<<4) + ((Wreg(SP)-2) & 0xffff))); } -#define GetModRM uint32_t ModRM=FETCH() +#define GetModRM uint32_t ModRM=fetch() /* Cycle count macros: CLK - cycle count is the same on all processors diff --git a/src/devices/cpu/patinhofeio/patinho_feio.cpp b/src/devices/cpu/patinhofeio/patinho_feio.cpp index 6c4b84c4410..d87379cc8fb 100644 --- a/src/devices/cpu/patinhofeio/patinho_feio.cpp +++ b/src/devices/cpu/patinhofeio/patinho_feio.cpp @@ -6,6 +6,7 @@ #include "emu.h" #include "patinhofeio_cpu.h" +#include "patinho_feio_dasm.h" #include "debugger.h" #include "includes/patinhofeio.h" // FIXME: this is a dependency from devices on MAME @@ -782,8 +783,7 @@ void patinho_feio_cpu_device::execute_instruction() printf("unimplemented opcode: 0x%02X\n", m_opcode); } -offs_t patinho_feio_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *patinho_feio_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( patinho_feio ); - return CPU_DISASSEMBLE_NAME(patinho_feio)(this, stream, pc, oprom, opram, options); + return new patinho_feio_disassembler; } diff --git a/src/devices/cpu/patinhofeio/patinho_feio_dasm.cpp b/src/devices/cpu/patinhofeio/patinho_feio_dasm.cpp index c655314f348..b3f66b3ae9b 100644 --- a/src/devices/cpu/patinhofeio/patinho_feio_dasm.cpp +++ b/src/devices/cpu/patinhofeio/patinho_feio_dasm.cpp @@ -1,27 +1,32 @@ // license:GPL-2.0+ // copyright-holders:Felipe Sanches #include "emu.h" -#include "cpu/patinhofeio/patinhofeio_cpu.h" +#include "patinho_feio_dasm.h" -CPU_DISASSEMBLE(patinho_feio) +u32 patinho_feio_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t patinho_feio_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int addr, value, n, f; - switch (oprom[0] & 0xF0) { + switch (opcodes.r8(pc) & 0xF0) { case 0x00: //PLA = "Pula": Unconditionally JUMP to effective address - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PLA /%03X", addr); return 2; case 0x10: //PLAX = "Pulo indexado": Unconditionally JUMP to indexed address - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PLAX (IDX) + /%03X", addr); return 2; case 0x20: //ARM = "Armazena": Stores the contents of the // accumulator in the given 12bit address - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); if (addr==0){ util::stream_format(stream, "ARM (IDX)"); }else{ @@ -31,13 +36,13 @@ CPU_DISASSEMBLE(patinho_feio) case 0x30: //ARMX = "Armazenamento indexado": Stores the contents of the accumulator in the // given 12bit address (indexed by IDX) - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "ARMX (IDX) + /%03X", addr); return 2; case 0x40: //CAR = "Carrega": Loads the contents of the given 12bit address // into the accumulator - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); if (addr==0){ util::stream_format(stream, "CAR (IDX)"); }else{ @@ -47,39 +52,39 @@ CPU_DISASSEMBLE(patinho_feio) case 0x50: //CARX = "Carga indexada": Loads the contents of the given 12bit address // (indexed by IDX) into the accumulator - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "CARX (IDX) + /%03X", addr); return 2; case 0x60: //SOM = "Soma": Adds the contents of the given 12bit address // into the accumulator - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "SOM /%03X", addr); return 2; case 0x70: //SOMX = "Soma indexada": Adds the contents of the given 12bit address // (indexed by IDX) into the accumulator - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "SOMX (IDX) + /%03X", addr); return 2; case 0xA0: //PLAN = "Pula se ACC for negativo": Jumps to the 12bit address // if the accumulator is negative - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PLAN /%03X", addr); return 2; case 0xB0: //PLAZ = "Pula se ACC for zero": Jumps to the 12bit address // if the accumulator is zero - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PLAZ /%03X", addr); return 2; case 0xC0: - n = (oprom[0] & 0x0F); - f = (oprom[1] & 0x0F); + n = (opcodes.r8(pc) & 0x0F); + f = (opcodes.r8(pc+1) & 0x0F); n+= (n < 10) ? '0' : 'A'-10; f+= (f < 10) ? '0' : 'A'-10; - switch(oprom[1] & 0xF0) + switch(opcodes.r8(pc+1) & 0xF0) { case 0x10: util::stream_format(stream, "FNC /%c%c", n, f); return 2; case 0x20: util::stream_format(stream, "SAL /%c%c", n, f); return 2; @@ -88,11 +93,11 @@ CPU_DISASSEMBLE(patinho_feio) } break; case 0xD0: - value = oprom[1] & 0x0F; - switch (oprom[0] & 0x0F) + value = opcodes.r8(pc+1) & 0x0F; + switch (opcodes.r8(pc) & 0x0F) { case 0x01: - switch (oprom[1] & 0xF0) + switch (opcodes.r8(pc+1) & 0xF0) { case 0x00: util::stream_format(stream, "DD /%01X", value); return 2; //DD = "Deslocamento para a direita": Shift right case 0x10: util::stream_format(stream, "DDV /%01X", value); return 2; //DDV = "Deslocamento para a direita c/ V": Shift right with carry @@ -105,25 +110,25 @@ CPU_DISASSEMBLE(patinho_feio) case 0x80: util::stream_format(stream, "DDS /%01X", value); return 2; //DDS = "Deslocamento para a direita com duplicacao de sinal": Shift right with sign duplication } break; - case 0x02: util::stream_format(stream, "XOR /%02X", oprom[1]); return 2; //Logical XOR - case 0x04: util::stream_format(stream, "NAND /%02X", oprom[1]); return 2; //Logical NAND - case 0x08: util::stream_format(stream, "SOMI /%02X", oprom[1]); return 2; //SOMI = "Soma imediata": Add immediate value into accumulator - case 0x0A: util::stream_format(stream, "CARI /%02X", oprom[1]); return 2; //CARI = "Carrega imediato": Loads an immediate value into the accumulator + case 0x02: util::stream_format(stream, "XOR /%02X", opcodes.r8(pc+1)); return 2; //Logical XOR + case 0x04: util::stream_format(stream, "NAND /%02X", opcodes.r8(pc+1)); return 2; //Logical NAND + case 0x08: util::stream_format(stream, "SOMI /%02X", opcodes.r8(pc+1)); return 2; //SOMI = "Soma imediata": Add immediate value into accumulator + case 0x0A: util::stream_format(stream, "CARI /%02X", opcodes.r8(pc+1)); return 2; //CARI = "Carrega imediato": Loads an immediate value into the accumulator } break; case 0xE0: //SUS = "Subtrai um ou salta" - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "SUS /%03X", addr); return 2; case 0xF0: //PUG = "Pula e guarda" - addr = (oprom[0] & 0x0F) << 8 | oprom[1]; + addr = (opcodes.r8(pc) & 0x0F) << 8 | opcodes.r8(pc+1); util::stream_format(stream, "PUG /%03X", addr); return 2; } - switch (oprom[0]) { + switch (opcodes.r8(pc)) { case 0x80: util::stream_format(stream, "LIMPO"); return 1; case 0x81: util::stream_format(stream, "UM"); return 1; case 0x82: util::stream_format(stream, "CMP1"); return 1; diff --git a/src/devices/cpu/patinhofeio/patinho_feio_dasm.h b/src/devices/cpu/patinhofeio/patinho_feio_dasm.h new file mode 100644 index 00000000000..0d950a3689c --- /dev/null +++ b/src/devices/cpu/patinhofeio/patinho_feio_dasm.h @@ -0,0 +1,19 @@ +// license:GPL-2.0+ +// copyright-holders:Felipe Sanches + +#ifndef MAME_CPU_PATINHOFEIO_PATINHO_FEIO_DASM_H +#define MAME_CPU_PATINHOFEIO_PATINHO_FEIO_DASM_H + +#pragma once + +class patinho_feio_disassembler : public util::disasm_interface +{ +public: + patinho_feio_disassembler() = default; + virtual ~patinho_feio_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/patinhofeio/patinhofeio_cpu.h b/src/devices/cpu/patinhofeio/patinhofeio_cpu.h index 07b402871d0..008acd8e0ae 100644 --- a/src/devices/cpu/patinhofeio/patinhofeio_cpu.h +++ b/src/devices/cpu/patinhofeio/patinhofeio_cpu.h @@ -65,7 +65,7 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -121,10 +121,6 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - private: void execute_instruction(); void compute_effective_address(unsigned int addr); diff --git a/src/devices/cpu/pdp1/pdp1.cpp b/src/devices/cpu/pdp1/pdp1.cpp index 2a5368ae56f..73482e5b82d 100644 --- a/src/devices/cpu/pdp1/pdp1.cpp +++ b/src/devices/cpu/pdp1/pdp1.cpp @@ -342,6 +342,7 @@ #include "emu.h" #include "debugger.h" #include "pdp1.h" +#include "pdp1dasm.h" #define LOG 0 #define LOG_EXTRA 0 @@ -418,10 +419,9 @@ void pdp1_device::device_config_complete() } -offs_t pdp1_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *pdp1_device::create_disassembler() { - extern CPU_DISASSEMBLE( pdp1 ); - return CPU_DISASSEMBLE_NAME(pdp1)(this, stream, pc, oprom, opram, options); + return new pdp1_disassembler; } diff --git a/src/devices/cpu/pdp1/pdp1.h b/src/devices/cpu/pdp1/pdp1.h index 174317d995e..5a2df5fd91e 100644 --- a/src/devices/cpu/pdp1/pdp1.h +++ b/src/devices/cpu/pdp1/pdp1.h @@ -114,9 +114,7 @@ protected: 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/pdp1/pdp1dasm.cpp b/src/devices/cpu/pdp1/pdp1dasm.cpp index 7376b752538..9b04c91ec87 100644 --- a/src/devices/cpu/pdp1/pdp1dasm.cpp +++ b/src/devices/cpu/pdp1/pdp1dasm.cpp @@ -1,13 +1,10 @@ // license:BSD-3-Clause // copyright-holders:Raphael Nabet #include "emu.h" -#include "cpu/pdp1/pdp1.h" +#include "pdp1dasm.h" +#include "pdp1.h" -/* PDP1 registers */ -static int ib; -static int y; - -static inline void ea (void) +inline void pdp1_disassembler::ea() { /* while (1) { @@ -20,15 +17,20 @@ static inline void ea (void) #define IN if (ib) util::stream_format(stream, " i") -CPU_DISASSEMBLE(pdp1) +u32 pdp1_disassembler::opcode_alignment() const +{ + return 4; +} + +offs_t pdp1_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int md; //int etime = 0; - md = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3]; + md = opcodes.r32(pc); - y = md & 07777; - ib = (md >> 12) & 1; /* */ + int y = md & 07777; + int ib = (md >> 12) & 1; /* */ switch (md >> 13) { case pdp1_device::AND: diff --git a/src/devices/cpu/pdp1/pdp1dasm.h b/src/devices/cpu/pdp1/pdp1dasm.h new file mode 100644 index 00000000000..e5dd4b0f031 --- /dev/null +++ b/src/devices/cpu/pdp1/pdp1dasm.h @@ -0,0 +1,22 @@ +// license:BSD-3-Clause +// copyright-holders:Raphael Nabet + +#ifndef MAME_CPU_PDP1_PDP1DASM_H +#define MAME_CPU_PDP1_PDP1DASM_H + +#pragma once + +class pdp1_disassembler : public util::disasm_interface +{ +public: + pdp1_disassembler() = default; + virtual ~pdp1_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + void ea(); +}; + +#endif diff --git a/src/devices/cpu/pdp1/tx0.cpp b/src/devices/cpu/pdp1/tx0.cpp index 89355ee2ef8..376cf15a346 100644 --- a/src/devices/cpu/pdp1/tx0.cpp +++ b/src/devices/cpu/pdp1/tx0.cpp @@ -12,6 +12,7 @@ #include "emu.h" #include "tx0.h" +#include "tx0dasm.h" #include "debugger.h" #define LOG 0 @@ -1075,15 +1076,12 @@ void tx0_device::io_complete() } -offs_t tx0_8kw_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tx0_8kw_device::create_disassembler() { - extern CPU_DISASSEMBLE( tx0_8kw ); - return CPU_DISASSEMBLE_NAME(tx0_8kw)(this, stream, pc, oprom, opram, options); + return new tx0_8kw_disassembler; } - -offs_t tx0_64kw_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tx0_64kw_device::create_disassembler() { - extern CPU_DISASSEMBLE( tx0_64kw ); - return CPU_DISASSEMBLE_NAME(tx0_64kw)(this, stream, pc, oprom, opram, options); + return new tx0_64kw_disassembler; } diff --git a/src/devices/cpu/pdp1/tx0.h b/src/devices/cpu/pdp1/tx0.h index 52cc7f4091a..e9174a46413 100644 --- a/src/devices/cpu/pdp1/tx0.h +++ b/src/devices/cpu/pdp1/tx0.h @@ -67,10 +67,6 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() 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; } - protected: address_space_config m_program_config; @@ -151,7 +147,7 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: void execute_instruction_8kw(); @@ -166,7 +162,7 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: void execute_instruction_64kw(); diff --git a/src/devices/cpu/pdp1/tx0dasm.cpp b/src/devices/cpu/pdp1/tx0dasm.cpp index cda24ed930c..34d49194ed3 100644 --- a/src/devices/cpu/pdp1/tx0dasm.cpp +++ b/src/devices/cpu/pdp1/tx0dasm.cpp @@ -1,14 +1,19 @@ // license:BSD-3-Clause // copyright-holders:Raphael Nabet #include "emu.h" -#include "cpu/pdp1/tx0.h" +#include "tx0dasm.h" -CPU_DISASSEMBLE(tx0_64kw) +u32 tx0_64kw_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tx0_64kw_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int md; int x; - md = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3]; + md = opcodes.r32(pc); x = md & 0177777; switch (md >> 16) @@ -29,12 +34,17 @@ CPU_DISASSEMBLE(tx0_64kw) return 1; } -CPU_DISASSEMBLE(tx0_8kw) +u32 tx0_8kw_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tx0_8kw_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int md; int x; - md = oprom[0] << 24 | oprom[1] << 16 | oprom[2] << 8 | oprom[3]; + md = opcodes.r32(pc); x = md & 0017777; switch (md >> 13) diff --git a/src/devices/cpu/pdp1/tx0dasm.h b/src/devices/cpu/pdp1/tx0dasm.h new file mode 100644 index 00000000000..ae97e2bcc1d --- /dev/null +++ b/src/devices/cpu/pdp1/tx0dasm.h @@ -0,0 +1,29 @@ +// license:BSD-3-Clause +// copyright-holders:Raphael Nabet + +#ifndef MAME_CPU_PDP1_TX0DASM_H +#define MAME_CPU_PDP1_TX0DASM_H + +#pragma once + +class tx0_64kw_disassembler : public util::disasm_interface +{ +public: + tx0_64kw_disassembler() = default; + virtual ~tx0_64kw_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +class tx0_8kw_disassembler : public util::disasm_interface +{ +public: + tx0_8kw_disassembler() = default; + virtual ~tx0_8kw_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/pdp8/pdp8.cpp b/src/devices/cpu/pdp8/pdp8.cpp index 1a9150a236d..b3ade64fc75 100644 --- a/src/devices/cpu/pdp8/pdp8.cpp +++ b/src/devices/cpu/pdp8/pdp8.cpp @@ -9,8 +9,7 @@ #include "emu.h" #include "debugger.h" #include "pdp8.h" - -CPU_DISASSEMBLE( pdp8 ); +#include "pdp8dasm.h" #define OP ((op >> 011) & 07) @@ -148,36 +147,13 @@ void pdp8_device::state_string_export(const device_state_entry &entry, std::stri //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t pdp8_device::disasm_min_opcode_bytes() const -{ - return 2; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t pdp8_device::disasm_max_opcode_bytes() const -{ - return 2; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t pdp8_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *pdp8_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( pdp8 ); - return CPU_DISASSEMBLE_NAME(pdp8)(this, stream, pc, oprom, opram, options); + return new pdp8_disassembler; } diff --git a/src/devices/cpu/pdp8/pdp8.h b/src/devices/cpu/pdp8/pdp8.h index b21371fd181..c6dc47ce56f 100644 --- a/src/devices/cpu/pdp8/pdp8.h +++ b/src/devices/cpu/pdp8/pdp8.h @@ -40,9 +40,7 @@ public: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; diff --git a/src/devices/cpu/pdp8/pdp8dasm.cpp b/src/devices/cpu/pdp8/pdp8dasm.cpp index 5c2219af4f8..389cf11fda7 100644 --- a/src/devices/cpu/pdp8/pdp8dasm.cpp +++ b/src/devices/cpu/pdp8/pdp8dasm.cpp @@ -7,9 +7,16 @@ */ #include "emu.h" +#include "pdp8dasm.h" -static offs_t pdp8_dasm_one(std::ostream &stream, offs_t pc, uint16_t op) +u32 pdp8_disassembler::opcode_alignment() const { + return 2; +} + +offs_t pdp8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint16_t op = opcodes.r16(pc); uint8_t opcode = (op >> 011) & 07; uint16_t current_page = pc & 07600; uint16_t zero_addr = op & 0177; @@ -157,15 +164,5 @@ static offs_t pdp8_dasm_one(std::ostream &stream, offs_t pc, uint16_t op) } } - return 2 | DASMFLAG_SUPPORTED; -} - - -/*****************************************************************************/ - -CPU_DISASSEMBLE( pdp8 ) -{ - uint16_t op = (*(uint8_t *)(opram + 0) << 8) | - (*(uint8_t *)(opram + 1) << 0); - return pdp8_dasm_one(stream, pc, op); + return 2 | SUPPORTED; } diff --git a/src/devices/cpu/pdp8/pdp8dasm.h b/src/devices/cpu/pdp8/pdp8dasm.h new file mode 100644 index 00000000000..df6c92e9ddb --- /dev/null +++ b/src/devices/cpu/pdp8/pdp8dasm.h @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + First-gen DEC PDP-8 disassembler + + Written by Ryan Holtz +*/ + +#ifndef MAME_CPU_PDP8_PDP8DASM_H +#define MAME_CPU_PDP8_PDP8DASM_H + +#pragma once + +class pdp8_disassembler : public util::disasm_interface +{ +public: + pdp8_disassembler() = default; + virtual ~pdp8_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/pic16c5x/16c5xdsm.cpp b/src/devices/cpu/pic16c5x/16c5xdsm.cpp index 03cd0539c8c..4768cbb12e8 100644 --- a/src/devices/cpu/pic16c5x/16c5xdsm.cpp +++ b/src/devices/cpu/pic16c5x/16c5xdsm.cpp @@ -24,86 +24,60 @@ \**************************************************************************/ #include "emu.h" +#include "16c5xdsm.h" #include <ctype.h> -static const uint8_t *rombase; -static const uint8_t *rambase; -static offs_t pcbase; -#define READOP16(A) (rombase[(A) - pcbase] | (rombase[(A) + 1 - pcbase] << 8)) -#define READARG16(A) (rambase[(A) - pcbase] | (rambase[(A) + 1 - pcbase] << 8)) - - - -typedef unsigned char byte; -typedef unsigned short int word; - -#define FMT(a,b) a, b -#define PTRS_PER_FORMAT 2 - -static const char *const regfile[32] = { "Reg$00 (IND)", "Reg$01 (TMR)", "Reg$02 (PCL)", "Reg$03 (ST)", "Reg$04 (FSR)", "Reg$05 (PTA)", "Reg$06 (PTB)", "Reg$07 (PTC)", +const char *const pic16c5x_disassembler::regfile[32] = { "Reg$00 (IND)", "Reg$01 (TMR)", "Reg$02 (PCL)", "Reg$03 (ST)", "Reg$04 (FSR)", "Reg$05 (PTA)", "Reg$06 (PTB)", "Reg$07 (PTC)", "Reg$08", "Reg$09", "Reg$0A", "Reg$0B", "Reg$0C", "Reg$0D", "Reg$0E", "Reg$0F", "Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17", "Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F" }; -static const char *const dest[2] = { "W", "Reg" }; - -static const char *const PIC16C5xFormats[] = { - FMT("000000000000", "nop"), - FMT("000000000010", "option"), - FMT("000000000011", "sleep"), - FMT("000000000100", "clrwdt"), - FMT("000000000101", "tris Port A"), - FMT("000000000110", "tris Port B"), - FMT("000000000111", "tris Port C"), - FMT("0000001fffff", "movwf %F"), - FMT("000001000000", "clrw"), - FMT("0000011fffff", "clrf %F"), - FMT("000010dfffff", "subwf %F,%D"), - FMT("000011dfffff", "decf %F,%D"), - FMT("000100dfffff", "iorwf %F,%D"), - FMT("000101dfffff", "andwf %F,%D"), - FMT("000110dfffff", "xorwf %F,%D"), - FMT("000111dfffff", "addwf %F,%D"), - FMT("001000dfffff", "movf %F,%D"), - FMT("001001dfffff", "comf %F,%D"), - FMT("001010dfffff", "incf %F,%D"), - FMT("001011dfffff", "decfsz %F,%D"), - FMT("001100dfffff", "rrf %F,%D"), - FMT("001101dfffff", "rlf %F,%D"), - FMT("001110dfffff", "swapf %F,%D"), - FMT("001111dfffff", "incfsz %F,%D"), - FMT("0100bbbfffff", "bcf %F,%B"), - FMT("0101bbbfffff", "bsf %F,%B"), - FMT("0110bbbfffff", "btfsc %F,%B"), - FMT("0111bbbfffff", "btfss %F,%B"), - FMT("1000kkkkkkkk", "retlw %K"), - FMT("1001aaaaaaaa", "call %A"), - FMT("101aaaaaaaaa", "goto %A"), - FMT("1100kkkkkkkk", "movlw %K"), - FMT("1101kkkkkkkk", "iorlw %K"), - FMT("1110kkkkkkkk", "andlw %K"), - FMT("1111kkkkkkkk", "xorlw %K"), +const char *const pic16c5x_disassembler::dest[2] = { "W", "Reg" }; + +const char *const pic16c5x_disassembler::PIC16C5xFormats[] = { + "000000000000", "nop", + "000000000010", "option", + "000000000011", "sleep", + "000000000100", "clrwdt", + "000000000101", "tris Port A", + "000000000110", "tris Port B", + "000000000111", "tris Port C", + "0000001fffff", "movwf %F", + "000001000000", "clrw", + "0000011fffff", "clrf %F", + "000010dfffff", "subwf %F,%D", + "000011dfffff", "decf %F,%D", + "000100dfffff", "iorwf %F,%D", + "000101dfffff", "andwf %F,%D", + "000110dfffff", "xorwf %F,%D", + "000111dfffff", "addwf %F,%D", + "001000dfffff", "movf %F,%D", + "001001dfffff", "comf %F,%D", + "001010dfffff", "incf %F,%D", + "001011dfffff", "decfsz %F,%D", + "001100dfffff", "rrf %F,%D", + "001101dfffff", "rlf %F,%D", + "001110dfffff", "swapf %F,%D", + "001111dfffff", "incfsz %F,%D", + "0100bbbfffff", "bcf %F,%B", + "0101bbbfffff", "bsf %F,%B", + "0110bbbfffff", "btfsc %F,%B", + "0111bbbfffff", "btfss %F,%B", + "1000kkkkkkkk", "retlw %K", + "1001aaaaaaaa", "call %A", + "101aaaaaaaaa", "goto %A", + "1100kkkkkkkk", "movlw %K", + "1101kkkkkkkk", "iorlw %K", + "1110kkkkkkkk", "andlw %K", + "1111kkkkkkkk", "xorlw %K", nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(PIC16C5xFormats) - 1) / PTRS_PER_FORMAT) - -struct PIC16C5xOpcode { - word mask; /* instruction mask */ - word bits; /* constant bits */ - word extcode; /* value that gets extension code */ - const char *parse; /* how to parse bits */ - const char *fmt; /* instruction format */ -}; - -static PIC16C5xOpcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm16C5x(void) +pic16c5x_disassembler::pic16c5x_disassembler() { const char *p; const char *const *ops; - word mask, bits; + u16 mask, bits; int bit; int i; @@ -136,20 +110,14 @@ static void InitDasm16C5x(void) ops[0],ops[1],bit); } while (isspace((uint8_t)*p)) p++; - if (*p) Op[i].extcode = *p; - Op[i].bits = bits; - Op[i].mask = mask; - Op[i].fmt = ops[1]; - Op[i].parse = ops[0]; + Op.emplace_back(mask, bits, *p, ops[0], ops[1]); - ops += PTRS_PER_FORMAT; + ops += 2; i++; } - - OpInizialized = 1; } -CPU_DISASSEMBLE(pic16c5x) +offs_t pic16c5x_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int a, b, d, f, k; /* these can all be filled in by parsing an instruction */ int i; @@ -161,15 +129,9 @@ CPU_DISASSEMBLE(pic16c5x) const char *cp; /* character pointer in OpFormats */ uint32_t flags = 0; - rombase = oprom; - rambase = opram; - pcbase = 2*pc; - - if (!OpInizialized) InitDasm16C5x(); - op = -1; /* no matching opcode */ - code = READOP16(2*pc); - for ( i = 0; i < MAX_OPS; i++) + code = opcodes.r16(pc); + for ( i = 0; i < int(Op.size()); i++) { if ((code & Op[i].mask) == Op[i].bits) { @@ -184,14 +146,14 @@ CPU_DISASSEMBLE(pic16c5x) if (op == -1) { util::stream_format(stream, "???? dw %04Xh",code); - return cnt; + return cnt | SUPPORTED; } //buffertmp = buffer; if (Op[op].extcode) /* Actually, theres no double length opcodes */ { bit = 27; code <<= 16; - code |= READARG16(2*(pc+cnt)); + code |= params.r16(pc+cnt); cnt++; } else @@ -223,9 +185,9 @@ CPU_DISASSEMBLE(pic16c5x) /* now traverse format string */ cp = Op[op].fmt; if (!strncmp(cp, "call", 4)) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strncmp(cp, "ret", 3)) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; while (*cp) { @@ -248,5 +210,10 @@ CPU_DISASSEMBLE(pic16c5x) stream << *cp++; } } - return cnt | flags | DASMFLAG_SUPPORTED; + return cnt | flags | SUPPORTED; +} + +uint32_t pic16c5x_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/pic16c5x/16c5xdsm.h b/src/devices/cpu/pic16c5x/16c5xdsm.h new file mode 100644 index 00000000000..de3c8b4425f --- /dev/null +++ b/src/devices/cpu/pic16c5x/16c5xdsm.h @@ -0,0 +1,58 @@ +// license:BSD-3-Clause +// copyright-holders:Tony La Porta + /**************************************************************************\ + * Microchip PIC16C5x Emulator * + * * + * Copyright Tony La Porta * + * Originally written for the MAME project. * + * * + * * + * Addressing architecture is based on the Harvard addressing scheme. * + * * + * Many thanks to those involved in the i8039 Disassembler * + * as this was based on it. * + * * + * * + * * + * A Address to jump to. * + * B Bit address within an 8-bit file register. * + * D Destination select (0 = store result in W (accumulator)) * + * (1 = store result in file register) * + * F Register file address (00-1F). * + * K Literal field, constant data. * + * * + \**************************************************************************/ + +#ifndef MAME_CPU_PIC16C5X_16C5XDSM_H +#define MAME_CPU_PIC16C5X_16C5XDSM_H + +#pragma once + +class pic16c5x_disassembler : public util::disasm_interface +{ +public: + pic16c5x_disassembler(); + virtual ~pic16c5x_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct PIC16C5xOpcode { + u16 mask; /* instruction mask */ + u16 bits; /* constant bits */ + u16 extcode; /* value that gets extension code */ + const char *parse; /* how to parse bits */ + const char *fmt; /* instruction format */ + + PIC16C5xOpcode(u16 m, u16 b, u16 e, const char *p, const char *f) : mask(m), bits(b), extcode(e), parse(p), fmt(f) {} + }; + + static const char *const regfile[32]; + static const char *const dest[2]; + static const char *const PIC16C5xFormats[]; + + std::vector<PIC16C5xOpcode> Op; +}; + +#endif diff --git a/src/devices/cpu/pic16c5x/dis16c5x.cpp b/src/devices/cpu/pic16c5x/dis16c5x.cpp deleted file mode 100644 index 08c7f2657df..00000000000 --- a/src/devices/cpu/pic16c5x/dis16c5x.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Tony La Porta - /**************************************************************************\ - * Microchip PIC16C5x Emulator * - * * - * Copyright Tony La Porta * - * Originally written for the MAME project. * - * * - * * - * Notes : Data is expected to be read from source file as LSB first. * - * * - \**************************************************************************/ - -#include <stdio.h> -#include <string.h> - -#include "16c5xdsm.c" - - -unsigned char *Buffer; - - -int main(int argc,char *argv[]) -{ - int length=0, length_to_dump=0, offset=0, disasm_words=0; - int filelength=0, bytes_read; - int Counter=0; - - FILE *F; - char *String_Output; - - if(argc<2) - { - printf("\n"); - printf("PIC16C5x Disassembler 1.0 by Tony La Porta (C)2003+\n\n"); - printf("Usage: dis16c5x <input-file> [ <start-addr> [ <num-of-addr> ] ]\n"); - printf(" <input-file> source file data must be MSB first\n"); - printf(" <start-addr> starting address to disassemble from (decimal)\n"); - printf(" <num-of-addr> number of addresses to disassemble (decimal)\n"); - printf(" Precede values with 0x if HEX values preffered\n"); - exit(1); - } - - if(!(F=fopen(argv[1],"rb"))) - { - printf("\n%s: Can't open file %s\n",argv[0],argv[1]); - exit(2); - } - argv++; argc--; - if (argv[1]) - { - offset = strtol(argv[1],nullptr,0); - argv++; argc--; - } - if (argv[1]) - { - length = strtol(argv[1],nullptr,0); - argv++; argc--; - } - - fseek(F,0, SEEK_END); - filelength = ftell(F); - - length *= 2; - - if ((length > (filelength - (offset*2))) || (length == 0)) length = filelength - (offset*2); - printf("Length=%04Xh(words) Offset=$%04Xh filelength=%04Xh(words) %04Xh(bytes)\n",length/2,offset,filelength/2,filelength); - length_to_dump = length; - printf("Starting from %d, dumping %d opcodes (word size)\n",offset,length/2); - Buffer = calloc((filelength+1),sizeof(char)); - if (Buffer==nullptr) - { - printf("Out of Memory !!!"); - fclose(F); - exit(3); - } - String_Output = calloc(80,sizeof(char)); - if (String_Output==nullptr) - { - printf("Out of Memory !!!"); - free(Buffer); - fclose(F); - exit(4); - } - - if (fseek(F,0,SEEK_SET) != 0) - { - printf("Error seeking to beginning of file\n"); - free(String_Output); - free(Buffer); - fclose(F); - exit(5); - } - - Counter = offset; - bytes_read = fread(Buffer,sizeof(char),filelength,F); - if (bytes_read >= length) - { - for (; length > 0; length -= (disasm_words*2)) - { - int ii; - disasm_words = Dasm16C5x(String_Output,Counter); - printf("$%03X: ",Counter); - for (ii = 0; ii < disasm_words; ii++) - { - if (((Counter*2) + ii) > filelength) /* Past end of length to dump ? */ - { - sprintf(String_Output,"???? dw %02.2X%02.2Xh (Past end of disassembly !)",Buffer[((Counter-1)*2)+1],Buffer[((Counter-1)*2)]); - } - else - { - printf("%02.2x%02.2x ",Buffer[(Counter*2)+1],Buffer[(Counter*2)]); - } - Counter++ ; - } - for (; ii < 4; ii++) - { - printf(" "); - } - printf("\t%s\n",String_Output); - } - } - else - { - printf("ERROR length to dump was %d ", length_to_dump/2); - printf(", but bytes read from file were %d\n", bytes_read/2); - free(String_Output); - free(Buffer); - fclose(F); - exit(7); - } - free(String_Output); - free(Buffer); - fclose(F); - return(0); -} diff --git a/src/devices/cpu/pic16c5x/pic16c5x.cpp b/src/devices/cpu/pic16c5x/pic16c5x.cpp index 52a9beeac77..d92ae93d3c1 100644 --- a/src/devices/cpu/pic16c5x/pic16c5x.cpp +++ b/src/devices/cpu/pic16c5x/pic16c5x.cpp @@ -73,6 +73,7 @@ #include "emu.h" #include "pic16c5x.h" +#include "16c5xdsm.h" #include "debugger.h" @@ -183,10 +184,9 @@ device_memory_interface::space_config_vector pic16c5x_device::memory_space_confi }; } -offs_t pic16c5x_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *pic16c5x_device::create_disassembler() { - extern CPU_DISASSEMBLE( pic16c5x ); - return CPU_DISASSEMBLE_NAME(pic16c5x)(this, stream, pc, oprom, opram, options); + return new pic16c5x_disassembler; } @@ -197,7 +197,7 @@ void pic16c5x_device::update_internalram_ptr() -#define PIC16C5x_RDOP(A) (m_direct->read_word((A)<<1)) +#define PIC16C5x_RDOP(A) (m_direct->read_word(A)) #define PIC16C5x_RAM_RDMEM(A) ((uint8_t)m_data->read_byte(A)) #define PIC16C5x_RAM_WRMEM(A,V) (m_data->write_byte(A,V)) @@ -883,7 +883,7 @@ enum void pic16c5x_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_read_a.resolve_safe(0); diff --git a/src/devices/cpu/pic16c5x/pic16c5x.h b/src/devices/cpu/pic16c5x/pic16c5x.h index 593397e4847..e51ef9a1c89 100644 --- a/src/devices/cpu/pic16c5x/pic16c5x.h +++ b/src/devices/cpu/pic16c5x/pic16c5x.h @@ -133,9 +133,7 @@ protected: 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -169,7 +167,7 @@ private: int m_inst_cycles; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; // i/o handlers diff --git a/src/devices/cpu/pic16c62x/16c62xdsm.cpp b/src/devices/cpu/pic16c62x/16c62xdsm.cpp index f9fb88a88d1..69072a4ada9 100644 --- a/src/devices/cpu/pic16c62x/16c62xdsm.cpp +++ b/src/devices/cpu/pic16c62x/16c62xdsm.cpp @@ -27,93 +27,68 @@ \**************************************************************************/ #include "emu.h" -#include <ctype.h> - -static const uint8_t *rombase; -static const uint8_t *rambase; -static offs_t pcbase; -#define READOP16(A) (rombase[(A) - pcbase] | (rombase[(A) + 1 - pcbase] << 8)) -#define READARG16(A) (rambase[(A) - pcbase] | (rambase[(A) + 1 - pcbase] << 8)) - - - -typedef unsigned char byte; -typedef unsigned short int word; +#include "16c62xdsm.h" -#define FMT(a,b) a, b -#define PTRS_PER_FORMAT 2 +#include <ctype.h> /* Registers bank 0/1 */ -static const char *const regfile[32] = { "Reg$00 (INDF)", "Reg$01 (TMR0/OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (PORTA/TRISA)", "Reg$06 (PORTB/TRISB)", "Reg$07", +const char *const pic16c62x_disassembler::regfile[32] = { "Reg$00 (INDF)", "Reg$01 (TMR0/OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (PORTA/TRISA)", "Reg$06 (PORTB/TRISB)", "Reg$07", "Reg$08", "Reg$09", "Reg$0A (PCLATH)", "Reg$0B (INTCON)", "Reg$0C (PIR1/PIE1)", "Reg$0D", "Reg$0E (none/PCON)", "Reg$0F", "Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17", "Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F (CMCON/VRCON)" }; /* Registers bank 1 */ -/*static const char *const regfile1[32] = { "Reg$00 (INDF)", "Reg$01 (OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (TRISA)", "Reg$06 (TRISB)", "Reg$07", +/*const char *const regfile1[32] = { "Reg$00 (INDF)", "Reg$01 (OPTION)", "Reg$02 (PCL)", "Reg$03 (STATUS)", "Reg$04 (FSR)", "Reg$05 (TRISA)", "Reg$06 (TRISB)", "Reg$07", "Reg$08", "Reg$09", "Reg$0A (PCLATH)", "Reg$0B (INTCON)", "Reg$0C (PIE1)", "Reg$0D", "Reg$0E (PCON)", "Reg$0F", "Reg$10", "Reg$11", "Reg$12", "Reg$13", "Reg$14", "Reg$15", "Reg$16", "Reg$17", "Reg$18", "Reg$19", "Reg$1A", "Reg$1B", "Reg$1C", "Reg$1D", "Reg$1E", "Reg$1F (VRCON)" }; -static const char **regfile[2] = { regfile0, regfile1 };*/ - -static const char *const dest[2] = { "W", "Reg" }; - -static const char *const PIC16C62xFormats[] = { - FMT("0000000xx00000", "nop"), - FMT("00000000001000", "return"), - FMT("00000000001001", "retfie"), - FMT("00000001100011", "sleep"), - FMT("00000001100100", "clrwdt"), - FMT("0000001fffffff", "movwf %F"), - FMT("00000100000011", "clrw"), - FMT("0000011fffffff", "clrf %F"), - FMT("000010dfffffff", "subwf %F,%D"), - FMT("000011dfffffff", "decf %F,%D"), - FMT("000100dfffffff", "iorwf %F,%D"), - FMT("000101dfffffff", "andwf %F,%D"), - FMT("000110dfffffff", "xorwf %F,%D"), - FMT("000111dfffffff", "addwf %F,%D"), - FMT("001000dfffffff", "movf %F,%D"), - FMT("001001dfffffff", "comf %F,%D"), - FMT("001010dfffffff", "incf %F,%D"), - FMT("001011dfffffff", "decfsz %F,%D"), - FMT("001100dfffffff", "rrf %F,%D"), - FMT("001101dfffffff", "rlf %F,%D"), - FMT("001110dfffffff", "swapf %F,%D"), - FMT("001111dfffffff", "incfsz %F,%D"), - FMT("0100bbbfffffff", "bcf %F,%B"), - FMT("0101bbbfffffff", "bsf %F,%B"), - FMT("0110bbbfffffff", "btfsc %F,%B"), - FMT("0111bbbfffffff", "btfss %F,%B"), - FMT("1101xxkkkkkkkk", "retlw %K"), - FMT("100aaaaaaaaaaa", "call %A"), - FMT("101aaaaaaaaaaa", "goto %A"), - FMT("1100xxkkkkkkkk", "movlw %K"), - FMT("111000kkkkkkkk", "iorlw %K"), - FMT("111001kkkkkkkk", "andlw %K"), - FMT("111010kkkkkkkk", "xorlw %K"), - FMT("11110xkkkkkkkk", "sublw %K"), - FMT("11111xkkkkkkkk", "addlw %K"), +const char **regfile[2] = { regfile0, regfile1 };*/ + +const char *const pic16c62x_disassembler::dest[2] = { "W", "Reg" }; + +const char *const pic16c62x_disassembler::PIC16C62xFormats[] = { + "0000000xx00000", "nop", + "00000000001000", "return", + "00000000001001", "retfie", + "00000001100011", "sleep", + "00000001100100", "clrwdt", + "0000001fffffff", "movwf %F", + "00000100000011", "clrw", + "0000011fffffff", "clrf %F", + "000010dfffffff", "subwf %F,%D", + "000011dfffffff", "decf %F,%D", + "000100dfffffff", "iorwf %F,%D", + "000101dfffffff", "andwf %F,%D", + "000110dfffffff", "xorwf %F,%D", + "000111dfffffff", "addwf %F,%D", + "001000dfffffff", "movf %F,%D", + "001001dfffffff", "comf %F,%D", + "001010dfffffff", "incf %F,%D", + "001011dfffffff", "decfsz %F,%D", + "001100dfffffff", "rrf %F,%D", + "001101dfffffff", "rlf %F,%D", + "001110dfffffff", "swapf %F,%D", + "001111dfffffff", "incfsz %F,%D", + "0100bbbfffffff", "bcf %F,%B", + "0101bbbfffffff", "bsf %F,%B", + "0110bbbfffffff", "btfsc %F,%B", + "0111bbbfffffff", "btfss %F,%B", + "1101xxkkkkkkkk", "retlw %K", + "100aaaaaaaaaaa", "call %A", + "101aaaaaaaaaaa", "goto %A", + "1100xxkkkkkkkk", "movlw %K", + "111000kkkkkkkk", "iorlw %K", + "111001kkkkkkkk", "andlw %K", + "111010kkkkkkkk", "xorlw %K", + "11110xkkkkkkkk", "sublw %K", + "11111xkkkkkkkk", "addlw %K", nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(PIC16C62xFormats) - 1) / PTRS_PER_FORMAT) - -struct PIC16C62xOpcode { - word mask; /* instruction mask */ - word bits; /* constant bits */ - word extcode; /* value that gets extension code */ - const char *parse; /* how to parse bits */ - const char *fmt; /* instruction format */ -}; - -static PIC16C62xOpcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm16C5x(void) +pic16c62x_disassembler::pic16c62x_disassembler() { const char *p; const char *const *ops; - word mask, bits; + u16 mask, bits; int bit; int i; @@ -147,20 +122,15 @@ static void InitDasm16C5x(void) ops[0],ops[1],bit); } while (isspace((uint8_t)*p)) p++; - if (*p) Op[i].extcode = *p; - Op[i].bits = bits; - Op[i].mask = mask; - Op[i].fmt = ops[1]; - Op[i].parse = ops[0]; + Op.emplace_back(mask, bits, *p, ops[0], ops[1]); - ops += PTRS_PER_FORMAT; + ops += 2; i++; } - OpInizialized = 1; } -CPU_DISASSEMBLE(pic16c62x) +offs_t pic16c62x_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int a, b, d, f, k; /* these can all be filled in by parsing an instruction */ int i; @@ -172,15 +142,9 @@ CPU_DISASSEMBLE(pic16c62x) const char *cp; /* character pointer in OpFormats */ uint32_t flags = 0; - rombase = oprom; - rambase = opram; - pcbase = 2*pc; - - if (!OpInizialized) InitDasm16C5x(); - op = -1; /* no matching opcode */ - code = READOP16(2*pc); - for ( i = 0; i < MAX_OPS; i++) + code = opcodes.r16(pc); + for ( i = 0; i < int(Op.size()); i++) { if ((code & Op[i].mask) == Op[i].bits) { @@ -202,7 +166,7 @@ CPU_DISASSEMBLE(pic16c62x) { bit = 29; code <<= 16; - code |= READARG16(2*(pc+cnt)); + code |= params.r16(pc+cnt); cnt++; } else @@ -234,9 +198,9 @@ CPU_DISASSEMBLE(pic16c62x) /* now traverse format string */ cp = Op[op].fmt; if (!strncmp(cp, "call", 4)) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strncmp(cp, "ret", 3)) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; while (*cp) { @@ -259,5 +223,10 @@ CPU_DISASSEMBLE(pic16c62x) stream << *cp++; } } - return cnt | flags | DASMFLAG_SUPPORTED; + return cnt | flags | SUPPORTED; +} + +uint32_t pic16c62x_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/pic16c62x/16c62xdsm.h b/src/devices/cpu/pic16c62x/16c62xdsm.h new file mode 100644 index 00000000000..a6ae323a59f --- /dev/null +++ b/src/devices/cpu/pic16c62x/16c62xdsm.h @@ -0,0 +1,62 @@ +// license:BSD-3-Clause +// copyright-holders:Tony La Porta + /**************************************************************************\ + * Microchip PIC16C62X Emulator * + * * + * Based On * + * Microchip PIC16C5X Emulator * + * Copyright Tony La Porta * + * Originally written for the MAME project. * + * * + * * + * Addressing architecture is based on the Harvard addressing scheme. * + * * + * Many thanks to those involved in the i8039 Disassembler * + * as this was based on it. * + * * + * * + * * + * A Address to jump to. * + * B Bit address within an 8-bit file register. * + * D Destination select (0 = store result in W (accumulator)) * + * (1 = store result in file register) * + * F Register file address (00-1F). * + * K Literal field, constant data. * + * X Not used * + * * + \**************************************************************************/ + +#ifndef MAME_CPU_PIC16C62X_16C62XDSM_H +#define MAME_CPU_PIC16C62X_16C62XDSM_H + +#pragma once + +class pic16c62x_disassembler : public util::disasm_interface +{ +public: + pic16c62x_disassembler(); + virtual ~pic16c62x_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct PIC16C62xOpcode { + u16 mask; /* instruction mask */ + u16 bits; /* constant bits */ + u16 extcode; /* value that gets extension code */ + const char *parse; /* how to parse bits */ + const char *fmt; /* instruction format */ + + PIC16C62xOpcode(u16 m, u16 b, u16 e, const char *p, const char *f) : mask(m), bits(b), extcode(e), parse(p), fmt(f) {} + }; + + static const char *const regfile[32]; + static const char *const dest[2]; + static const char *const PIC16C62xFormats[]; + + std::vector<PIC16C62xOpcode> Op; + +}; + +#endif diff --git a/src/devices/cpu/pic16c62x/dis16c62x.cpp b/src/devices/cpu/pic16c62x/dis16c62x.cpp deleted file mode 100644 index 1fb91304dd2..00000000000 --- a/src/devices/cpu/pic16c62x/dis16c62x.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Tony La Porta - /**************************************************************************\ - * Microchip PIC16C62X Emulator * - * * - * Based On * - * Microchip PIC16C5X Emulator * - * Copyright Tony La Porta * - * Originally written for the MAME project. * - * * - * * - * Notes : Data is expected to be read from source file as LSB first. * - * * - \**************************************************************************/ - -#include <stdio.h> -#include <string.h> - -#include "16c62xdsm.c" - - -unsigned char *Buffer; - - -int main(int argc,char *argv[]) -{ - int length=0, length_to_dump=0, offset=0, disasm_words=0; - int filelength=0, bytes_read; - int Counter=0; - - FILE *F; - char *String_Output; - - if(argc<2) - { - printf("\n"); - printf("PIC16C5x Disassembler 1.0 by Tony La Porta (C)2003+\n\n"); - printf("Usage: dis16c5x <input-file> [ <start-addr> [ <num-of-addr> ] ]\n"); - printf(" <input-file> source file data must be MSB first\n"); - printf(" <start-addr> starting address to disassemble from (decimal)\n"); - printf(" <num-of-addr> number of addresses to disassemble (decimal)\n"); - printf(" Precede values with 0x if HEX values preffered\n"); - exit(1); - } - - if(!(F=fopen(argv[1],"rb"))) - { - printf("\n%s: Can't open file %s\n",argv[0],argv[1]); - exit(2); - } - argv++; argc--; - if (argv[1]) - { - offset = strtol(argv[1],nullptr,0); - argv++; argc--; - } - if (argv[1]) - { - length = strtol(argv[1],nullptr,0); - argv++; argc--; - } - - fseek(F,0, SEEK_END); - filelength = ftell(F); - - length *= 2; - - if ((length > (filelength - (offset*2))) || (length == 0)) length = filelength - (offset*2); - printf("Length=%04Xh(words) Offset=$%04Xh filelength=%04Xh(words) %04Xh(bytes)\n",length/2,offset,filelength/2,filelength); - length_to_dump = length; - printf("Starting from %d, dumping %d opcodes (word size)\n",offset,length/2); - Buffer = calloc((filelength+1),sizeof(char)); - if (Buffer==nullptr) - { - printf("Out of Memory !!!"); - fclose(F); - exit(3); - } - String_Output = calloc(80,sizeof(char)); - if (String_Output==nullptr) - { - printf("Out of Memory !!!"); - free(Buffer); - fclose(F); - exit(4); - } - - if (fseek(F,0,SEEK_SET) != 0) - { - printf("Error seeking to beginning of file\n"); - free(String_Output); - free(Buffer); - fclose(F); - exit(5); - } - - Counter = offset; - bytes_read = fread(Buffer,sizeof(char),filelength,F); - if (bytes_read >= length) - { - for (; length > 0; length -= (disasm_words*2)) - { - int ii; - disasm_words = Dasm16C5x(String_Output,Counter); - printf("$%03X: ",Counter); - for (ii = 0; ii < disasm_words; ii++) - { - if (((Counter*2) + ii) > filelength) /* Past end of length to dump ? */ - { - sprintf(String_Output,"???? dw %02.2X%02.2Xh (Past end of disassembly !)",Buffer[((Counter-1)*2)+1],Buffer[((Counter-1)*2)]); - } - else - { - printf("%02.2x%02.2x ",Buffer[(Counter*2)+1],Buffer[(Counter*2)]); - } - Counter++ ; - } - for (; ii < 4; ii++) - { - printf(" "); - } - printf("\t%s\n",String_Output); - } - } - else - { - printf("ERROR length to dump was %d ", length_to_dump/2); - printf(", but bytes read from file were %d\n", bytes_read/2); - free(String_Output); - free(Buffer); - fclose(F); - exit(7); - } - free(String_Output); - free(Buffer); - fclose(F); - return(0); -} diff --git a/src/devices/cpu/pic16c62x/pic16c62x.cpp b/src/devices/cpu/pic16c62x/pic16c62x.cpp index c7943ad8480..e01a7fda740 100644 --- a/src/devices/cpu/pic16c62x/pic16c62x.cpp +++ b/src/devices/cpu/pic16c62x/pic16c62x.cpp @@ -54,6 +54,7 @@ #include "emu.h" #include "pic16c62x.h" +#include "16c62xdsm.h" #include "debugger.h" @@ -158,10 +159,9 @@ pic16c622a_device::pic16c622a_device(const machine_config &mconfig, const char * } -offs_t pic16c62x_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *pic16c62x_device::create_disassembler() { - extern CPU_DISASSEMBLE( pic16c62x ); - return CPU_DISASSEMBLE_NAME(pic16c62x)(this, stream, pc, oprom, opram, options); + return new pic16c62x_disassembler; } @@ -170,7 +170,7 @@ void pic16c62x_device::update_internalram_ptr() m_internalram = (uint8_t *)m_data->get_write_ptr(0x00); } -#define PIC16C62x_RDOP(A) (m_direct->read_word((A)<<1)) +#define PIC16C62x_RDOP(A) (m_direct->read_word(A)) #define PIC16C62x_RAM_RDMEM(A) ((uint8_t)m_data->read_byte(A)) #define PIC16C62x_RAM_WRMEM(A,V) (m_data->write_byte(A,V)) #define PIC16C62x_In(Port) ((uint8_t)m_io->read_byte((Port))) @@ -867,7 +867,7 @@ void pic16c62x_device::build_opcode_table(void) void pic16c62x_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); diff --git a/src/devices/cpu/pic16c62x/pic16c62x.h b/src/devices/cpu/pic16c62x/pic16c62x.h index 0c99e0e67e1..38596be6b29 100644 --- a/src/devices/cpu/pic16c62x/pic16c62x.h +++ b/src/devices/cpu/pic16c62x/pic16c62x.h @@ -79,9 +79,7 @@ protected: 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -115,7 +113,7 @@ private: int m_inst_cycles; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; address_space *m_io; diff --git a/src/devices/cpu/powerpc/ppc.h b/src/devices/cpu/powerpc/ppc.h index dd09cce15e4..ba81a6055bb 100644 --- a/src/devices/cpu/powerpc/ppc.h +++ b/src/devices/cpu/powerpc/ppc.h @@ -268,9 +268,7 @@ protected: 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; + virtual util::disasm_interface *create_disassembler() override; /* exception types */ enum @@ -492,7 +490,7 @@ protected: int m_buffered_dma_rate[4]; /* internal stuff */ - direct_read_data *m_direct; + direct_read_data<0> *m_direct; offs_t m_codexor; uint32_t m_system_clock; uint32_t m_cpu_clock; diff --git a/src/devices/cpu/powerpc/ppc_dasm.cpp b/src/devices/cpu/powerpc/ppc_dasm.cpp index 77f01f9f552..50b015b1aff 100644 --- a/src/devices/cpu/powerpc/ppc_dasm.cpp +++ b/src/devices/cpu/powerpc/ppc_dasm.cpp @@ -16,103 +16,9 @@ */ #include "emu.h" -#include "debugger.h" +#include "ppc_dasm.h" #include "ppccom.h" -/* - * Operand Formats - * - * These convey information on what operand fields are present and how they - * ought to be printed. - * - * I'm fairly certain all of these are used, but that is not guaranteed. - */ - -enum -{ - F_NONE, // <no operands> - F_LI, // LI*4+PC if AA=0 else LI*4 - F_BCx, // BO, BI, target_addr used only by BCx - F_RT_RA_0_SIMM, // rT, rA|0, SIMM rA|0 means if rA == 0, print 0 - F_ADDIS, // rT, rA, SIMM (printed as unsigned) only used by ADDIS - F_RT_RA_SIMM, // rT, rA, SIMM - F_RA_RT_UIMM, // rA, rT, UIMM - F_CMP_SIMM, // crfD, L, A, SIMM - F_CMP_UIMM, // crfD, L, A, UIMM - F_RT_RA_0_RB, // rT, rA|0, rB - F_RT_RA_RB, // rT, rA, rB - F_RT_D_RA_0, // rT, d(rA|0) - F_RT_D_RA, // rT, d(rA) - F_RA_RT_RB, // rA, rT, rB - F_FRT_D_RA_0, // frT, d(RA|0) - F_FRT_D_RA, // frT, d(RA) - F_FRT_RA_0_RB, // frT, rA|0, rB - F_FRT_RA_RB, // frT, rA, rB - F_TWI, // TO, rA, SIMM only used by TWI instruction - F_CMP, // crfD, L, rA, rB - F_RA_RT, // rA, rT - F_RA_0_RB, // rA|0, rB - F_FRT_FRB, // frT, frB - F_FCMP, // crfD, frA, frB - F_CRFD_CRFS, // crfD, crfS - F_MCRXR, // crfD only used by MCRXR - F_RT, // rT - F_MFSR, // rT, SR only used by MFSR - F_MTSR, // SR, rT only used by MTSR - F_MFFSx, // frT only used by MFFSx - F_FCRBD, // crbD FPSCR[crbD] - F_MTFSFIx, // crfD, IMM only used by MTFSFIx - F_RB, // rB - F_TW, // TO, rA, rB only used by TW - F_RT_RA_0_NB, // rT, rA|0, NB print 32 if NB == 0 - F_SRAWIx, // rA, rT, SH only used by SRAWIx - F_BO_BI, // BO, BI - F_CRBD_CRBA_CRBB, // crbD, crbA, crbB - F_RT_SPR, // rT, SPR and TBR - F_MTSPR, // SPR, rT only used by MTSPR - F_MTCRF, // CRM, rT only used by MTCRF - F_MTFSFx, // FM, frB only used by MTFSFx - F_RT_DCR, // rT, DCR - F_MTDCR, // DCR, rT - F_RT_RA, // rT, rA - F_FRT_FRA_FRC_FRB, // frT, frA, frC, frB - F_FRT_FRA_FRB, // frT, frA, frB - F_FRT_FRA_FRC, // frT, frA, frC - F_RA_RT_SH_MB_ME, // rA, rT, SH, MB, ME - F_RLWNMx, // rT, rA, rB, MB, ME only used by RLWNMx - F_RT_RB // rT, rB -}; - -/* - * Flags - */ - -#define FL_OE (1 << 0) // if there is an OE field -#define FL_RC (1 << 1) // if there is an RC field -#define FL_LK (1 << 2) // if there is an LK field -#define FL_AA (1 << 3) // if there is an AA field -#define FL_CHECK_RA_RT (1 << 4) // assert rA!=0 and rA!=rT -#define FL_CHECK_RA (1 << 5) // assert rA!=0 -#define FL_CHECK_LSWI (1 << 6) // specific check for LSWI validity -#define FL_CHECK_LSWX (1 << 7) // specific check for LSWX validity -#define FL_SO (1 << 8) // use DASMFLAG_STEP_OUT - - -/* - * Instruction Descriptor - * - * Describes the layout of an instruction. - */ - -struct IDESCR -{ - char mnem[32]; // mnemonic - uint32_t match; // bit pattern of instruction after it has been masked - uint32_t mask; // mask of variable fields (AND with ~mask to compare w/ - // bit pattern to determine a match) - int format; // operand format - int flags; // flags -}; /* * Instruction Table @@ -121,7 +27,7 @@ struct IDESCR * and print instructions. */ -static const IDESCR itab[] = +const powerpc_disassembler::IDESCR powerpc_disassembler::itab[] = { { "add", D_OP(31)|D_XO(266), M_RT|M_RA|M_RB|M_OE|M_RC, F_RT_RA_RB, FL_OE|FL_RC }, { "addc", D_OP(31)|D_XO(10), M_RT|M_RA|M_RB|M_OE|M_RC, F_RT_RA_RB, FL_OE|FL_RC }, @@ -342,18 +248,18 @@ static const IDESCR itab[] = * Use an index of BI&3 into this table to obtain the CR field bit name. */ -static const char *const crbit[4] = { "lt", "gt", "eq", "so" }; -static const char *const crnbit[4] = { "ge", "le", "ne", "nso" }; +const char *const powerpc_disassembler::crbit[4] = { "lt", "gt", "eq", "so" }; +const char *const powerpc_disassembler::crnbit[4] = { "ge", "le", "ne", "nso" }; /* * SPR(): * - * Decode the SPR (or TBR) field and append the register name to dest. If - * no name is associated with the field value, the value itself is printed. + * Decode the SPR (or TBR) field and return the register name. If + * no name is associated with the field value, return the value itself. */ -static void SPR(char *dest, int spr_field) +std::string powerpc_disassembler::SPR(int spr_field) { int spr; @@ -371,93 +277,93 @@ static void SPR(char *dest, int spr_field) switch (spr) { /* UISA SPR register indexes */ - case SPR_XER: strcat(dest, "xer"); break; - case SPR_LR: strcat(dest, "lr"); break; - case SPR_CTR: strcat(dest, "ctr"); break; + case SPR_XER: return "xer"; + case SPR_LR: return "lr"; + case SPR_CTR: return "ctr"; /* VEA SPR register indexes */ - case SPRVEA_TBL_R: strcat(dest, "tbl"); break; - case SPRVEA_TBU_R: strcat(dest, "tbu"); break; + case SPRVEA_TBL_R: return "tbl"; + case SPRVEA_TBU_R: return "tbu"; /* OEA SPR register indexes */ - case SPROEA_DSISR: strcat(dest, "dsisr"); break; - case SPROEA_DAR: strcat(dest, "dar"); break; - case SPROEA_DEC: strcat(dest, "dec"); break; - case SPROEA_SDR1: strcat(dest, "sdr1"); break; - case SPROEA_SRR0: strcat(dest, "srr0"); break; - case SPROEA_SRR1: strcat(dest, "srr1"); break; - case SPROEA_SPRG0: strcat(dest, "sprg0"); break; - case SPROEA_SPRG1: strcat(dest, "sprg1"); break; - case SPROEA_SPRG2: strcat(dest, "sprg2"); break; - case SPROEA_SPRG3: strcat(dest, "sprg3"); break; - case SPROEA_ASR: strcat(dest, "asr"); break; - case SPROEA_EAR: strcat(dest, "ear"); break; - case SPROEA_PVR: strcat(dest, "pvr"); break; - case SPROEA_IBAT0U: strcat(dest, "ibat0u"); break; - case SPROEA_IBAT0L: strcat(dest, "ibat0l"); break; - case SPROEA_IBAT1U: strcat(dest, "ibat1u"); break; - case SPROEA_IBAT1L: strcat(dest, "ibat1l"); break; - case SPROEA_IBAT2U: strcat(dest, "ibat2u"); break; - case SPROEA_IBAT2L: strcat(dest, "ibat2l"); break; - case SPROEA_IBAT3U: strcat(dest, "ibat3u"); break; - case SPROEA_IBAT3L: strcat(dest, "ibat3l"); break; - case SPROEA_DBAT0U: strcat(dest, "dbat0u"); break; - case SPROEA_DBAT0L: strcat(dest, "dbat0l"); break; - case SPROEA_DBAT1U: strcat(dest, "dbat1u"); break; - case SPROEA_DBAT1L: strcat(dest, "dbat1l"); break; - case SPROEA_DBAT2U: strcat(dest, "dbat2u"); break; - case SPROEA_DBAT2L: strcat(dest, "dbat2l"); break; - case SPROEA_DBAT3U: strcat(dest, "dbat3u"); break; - case SPROEA_DBAT3L: strcat(dest, "dbat3l"); break; - case SPROEA_DABR: strcat(dest, "dabr/iac2"); break; // unsupported on 603e/EC603e + case SPROEA_DSISR: return "dsisr"; + case SPROEA_DAR: return "dar"; + case SPROEA_DEC: return "dec"; + case SPROEA_SDR1: return "sdr1"; + case SPROEA_SRR0: return "srr0"; + case SPROEA_SRR1: return "srr1"; + case SPROEA_SPRG0: return "sprg0"; + case SPROEA_SPRG1: return "sprg1"; + case SPROEA_SPRG2: return "sprg2"; + case SPROEA_SPRG3: return "sprg3"; + case SPROEA_ASR: return "asr"; + case SPROEA_EAR: return "ear"; + case SPROEA_PVR: return "pvr"; + case SPROEA_IBAT0U: return "ibat0u"; + case SPROEA_IBAT0L: return "ibat0l"; + case SPROEA_IBAT1U: return "ibat1u"; + case SPROEA_IBAT1L: return "ibat1l"; + case SPROEA_IBAT2U: return "ibat2u"; + case SPROEA_IBAT2L: return "ibat2l"; + case SPROEA_IBAT3U: return "ibat3u"; + case SPROEA_IBAT3L: return "ibat3l"; + case SPROEA_DBAT0U: return "dbat0u"; + case SPROEA_DBAT0L: return "dbat0l"; + case SPROEA_DBAT1U: return "dbat1u"; + case SPROEA_DBAT1L: return "dbat1l"; + case SPROEA_DBAT2U: return "dbat2u"; + case SPROEA_DBAT2L: return "dbat2l"; + case SPROEA_DBAT3U: return "dbat3u"; + case SPROEA_DBAT3L: return "dbat3l"; + case SPROEA_DABR: return "dabr/iac2"; // unsupported on 603e/EC603e /* PowerPC 603E SPR register indexes */ - case SPR603_HID0: strcat(dest, "hid0/dbsr"); break; - case SPR603_HID1: strcat(dest, "hid1"); break; - case SPR603_DMISS: strcat(dest, "dmiss"); break; - case SPR603_DCMP: strcat(dest, "dcmp"); break; - case SPR603_HASH1: strcat(dest, "hash1"); break; - case SPR603_HASH2: strcat(dest, "hash2/icdbdr"); break; - case SPR603_IMISS: strcat(dest, "imiss"); break; - case SPR603_ICMP: strcat(dest, "icmp/dear"); break; - case SPR603_RPA: strcat(dest, "rpa/evpr"); break; - case SPR603_IABR: strcat(dest, "iabr/dbcr"); break; + case SPR603_HID0: return "hid0/dbsr"; + case SPR603_HID1: return "hid1"; + case SPR603_DMISS: return "dmiss"; + case SPR603_DCMP: return "dcmp"; + case SPR603_HASH1: return "hash1"; + case SPR603_HASH2: return "hash2/icdbdr"; + case SPR603_IMISS: return "imiss"; + case SPR603_ICMP: return "icmp/dear"; + case SPR603_RPA: return "rpa/evpr"; + case SPR603_IABR: return "iabr/dbcr"; /* PowerPC 4XX SPR register indexes */ - case SPR4XX_SGR: strcat(dest, "sgr"); break; - case SPR4XX_DCWR: strcat(dest, "dcwr"); break; - case SPR4XX_PID: strcat(dest, "pid"); break; - case SPR4XX_TBHU: strcat(dest, "tbhu"); break; - case SPR4XX_TBLU: strcat(dest, "tblu"); break; -// case SPR4XX_ICDBDR: strcat(dest, "icdbdr"); break; // same as SPR603E_HASH2 -// case SPR4XX_DEAR: strcat(dest, "dear"); break; // same as SPR603E_ICMP -// case SPR4XX_EVPR: strcat(dest, "evpr"); break; // same as SPR603E_RPA - case SPR4XX_CDBCR: strcat(dest, "cdbcr"); break; - case SPR4XX_TSR: strcat(dest, "tsr"); break; - case SPR4XX_TCR: strcat(dest, "tcr"); break; - case SPR4XX_PIT: strcat(dest, "pit"); break; - case SPR4XX_TBHI: strcat(dest, "tbhi"); break; - case SPR4XX_TBLO: strcat(dest, "tblo"); break; - case SPR4XX_SRR2: strcat(dest, "srr2"); break; - case SPR4XX_SRR3: strcat(dest, "srr3"); break; -// case SPR4XX_DBSR: strcat(dest, "dbsr"); break; // same as SPR603E_HID0 -// case SPR4XX_DBCR: strcat(dest, "dbcr"); break; // same as SPR603E_IABR - case SPR4XX_IAC1: strcat(dest, "iac1"); break; -// case SPR4XX_IAC2: strcat(dest, "iac2"); break; // same as SPROEA_DABR - case SPR4XX_DAC1: strcat(dest, "dac1"); break; - case SPR4XX_DAC2: strcat(dest, "dac2"); break; - case SPR4XX_DCCR: strcat(dest, "dccr"); break; - case SPR4XX_ICCR: strcat(dest, "iccr"); break; - case SPR4XX_PBL1: strcat(dest, "pbl1"); break; - case SPR4XX_PBU1: strcat(dest, "pbu1"); break; - case SPR4XX_PBL2: strcat(dest, "pbl2"); break; - case SPR4XX_PBU2: strcat(dest, "pbu2"); break; - - default: sprintf(dest + strlen(dest), "%d", spr); break; + case SPR4XX_SGR: return "sgr"; + case SPR4XX_DCWR: return "dcwr"; + case SPR4XX_PID: return "pid"; + case SPR4XX_TBHU: return "tbhu"; + case SPR4XX_TBLU: return "tblu"; +// case SPR4XX_ICDBDR: return "icdbdr"; // same as SPR603E_HASH2 +// case SPR4XX_DEAR: return "dear"; // same as SPR603E_ICMP +// case SPR4XX_EVPR: return "evpr"; // same as SPR603E_RPA + case SPR4XX_CDBCR: return "cdbcr"; + case SPR4XX_TSR: return "tsr"; + case SPR4XX_TCR: return "tcr"; + case SPR4XX_PIT: return "pit"; + case SPR4XX_TBHI: return "tbhi"; + case SPR4XX_TBLO: return "tblo"; + case SPR4XX_SRR2: return "srr2"; + case SPR4XX_SRR3: return "srr3"; +// case SPR4XX_DBSR: return "dbsr"; // same as SPR603E_HID0 +// case SPR4XX_DBCR: return "dbcr"; // same as SPR603E_IABR + case SPR4XX_IAC1: return "iac1"; +// case SPR4XX_IAC2: return "iac2"; // same as SPROEA_DABR + case SPR4XX_DAC1: return "dac1"; + case SPR4XX_DAC2: return "dac2"; + case SPR4XX_DCCR: return "dccr"; + case SPR4XX_ICCR: return "iccr"; + case SPR4XX_PBL1: return "pbl1"; + case SPR4XX_PBU1: return "pbu1"; + case SPR4XX_PBL2: return "pbl2"; + case SPR4XX_PBU2: return "pbu2"; + + default: return util::string_format("%d", spr); } } -static void DCR(char *dest, int dcr_field) +std::string powerpc_disassembler::DCR(int dcr_field) { int dcr; @@ -474,50 +380,50 @@ static void DCR(char *dest, int dcr_field) switch (dcr) { - case 144: strcat(dest, "bear"); break; - case 145: strcat(dest, "besr"); break; - case 128: strcat(dest, "br0"); break; - case 129: strcat(dest, "br1"); break; - case 130: strcat(dest, "br2"); break; - case 131: strcat(dest, "br3"); break; - case 132: strcat(dest, "br4"); break; - case 133: strcat(dest, "br5"); break; - case 134: strcat(dest, "br6"); break; - case 135: strcat(dest, "br7"); break; - case 112: strcat(dest, "brh0"); break; - case 113: strcat(dest, "brh1"); break; - case 114: strcat(dest, "brh2"); break; - case 115: strcat(dest, "brh3"); break; - case 116: strcat(dest, "brh4"); break; - case 117: strcat(dest, "brh5"); break; - case 118: strcat(dest, "brh6"); break; - case 119: strcat(dest, "brh7"); break; - case 196: strcat(dest, "dmacc0"); break; - case 204: strcat(dest, "dmacc1"); break; - case 212: strcat(dest, "dmacc2"); break; - case 220: strcat(dest, "dmacc3"); break; - case 192: strcat(dest, "dmacr0"); break; - case 200: strcat(dest, "dmacr1"); break; - case 208: strcat(dest, "dmacr2"); break; - case 216: strcat(dest, "dmacr3"); break; - case 193: strcat(dest, "dmact0"); break; - case 201: strcat(dest, "dmact1"); break; - case 209: strcat(dest, "dmact2"); break; - case 217: strcat(dest, "dmact3"); break; - case 194: strcat(dest, "dmada0"); break; - case 202: strcat(dest, "dmada1"); break; - case 210: strcat(dest, "dmada2"); break; - case 218: strcat(dest, "dmada3"); break; - case 195: strcat(dest, "dmasa0"); break; - case 203: strcat(dest, "dmasa1"); break; - case 211: strcat(dest, "dmasa2"); break; - case 219: strcat(dest, "dmasa3"); break; - case 224: strcat(dest, "dmasr"); break; - case 66: strcat(dest, "exier"); break; - case 64: strcat(dest, "exisr"); break; - case 160: strcat(dest, "iocr"); break; - - default: sprintf(dest + strlen(dest), "%d", dcr); break; + case 144: return "bear"; + case 145: return "besr"; + case 128: return "br0"; + case 129: return "br1"; + case 130: return "br2"; + case 131: return "br3"; + case 132: return "br4"; + case 133: return "br5"; + case 134: return "br6"; + case 135: return "br7"; + case 112: return "brh0"; + case 113: return "brh1"; + case 114: return "brh2"; + case 115: return "brh3"; + case 116: return "brh4"; + case 117: return "brh5"; + case 118: return "brh6"; + case 119: return "brh7"; + case 196: return "dmacc0"; + case 204: return "dmacc1"; + case 212: return "dmacc2"; + case 220: return "dmacc3"; + case 192: return "dmacr0"; + case 200: return "dmacr1"; + case 208: return "dmacr2"; + case 216: return "dmacr3"; + case 193: return "dmact0"; + case 201: return "dmact1"; + case 209: return "dmact2"; + case 217: return "dmact3"; + case 194: return "dmada0"; + case 202: return "dmada1"; + case 210: return "dmada2"; + case 218: return "dmada3"; + case 195: return "dmasa0"; + case 203: return "dmasa1"; + case 211: return "dmasa2"; + case 219: return "dmasa3"; + case 224: return "dmasr"; + case 66: return "exier"; + case 64: return "exisr"; + case 160: return "iocr"; + + default: return util::string_format("%d", dcr); } } @@ -529,22 +435,22 @@ static void DCR(char *dest, int dcr_field) * unsigned 16-bit integer. */ -static void DecodeSigned16(char *outbuf, uint32_t op, int do_unsigned) +std::string powerpc_disassembler::DecodeSigned16(uint32_t op, int do_unsigned) { int16_t s; s = G_SIMM(op); if (do_unsigned) // sign extend to unsigned 32-bits - sprintf(outbuf, "0x%04X", (uint32_t) s); + return util::string_format("0x%04X", (uint32_t) s); else // print as signed 16 bits { if (s < 0) { s *= -1; - sprintf(outbuf, "-0x%04X", s); + return util::string_format("-0x%04X", s); } else - sprintf(outbuf, "0x%04X",s); + return util::string_format("0x%04X",s); } } @@ -554,7 +460,7 @@ static void DecodeSigned16(char *outbuf, uint32_t op, int do_unsigned) * Generate a mask from bit MB through ME (PPC-style backwards bit numbering.) */ -static uint32_t Mask(int mb, int me) +uint32_t powerpc_disassembler::Mask(int mb, int me) { uint32_t i, mask; @@ -575,76 +481,13 @@ static uint32_t Mask(int mb, int me) } /* - * Check(): - * - * Perform checks on the instruction as required by the flags. Returns 1 if - * the instruction failed. - */ - -#if 0 -static int Check(uint32_t op, int flags) -{ - int nb, rt, ra; - - if( !flags ) return 0; // nothing to check for! - - rt = G_RT(op); - ra = G_RA(op); - - if (flags & FL_CHECK_RA_RT) // invalid if rA==0 or rA==rT - { - if ((G_RA(op) == 0) || (G_RA(op) == G_RT(op))) - return 1; - } - - if (flags & FL_CHECK_RA) // invalid if rA==0 - { - if (G_RA(op) == 0) - return 1; - } - - if (flags & FL_CHECK_LSWI) - { - /* - * Check that rA is not in the range of registers to be loaded (even - * if rA == 0) - */ - - nb = G_NB(op); - - if (ra >= rt && ra <= (rt + nb - 1)) return 1; - if ((rt + nb - 1) > 31) // register wrap-around! - { - if (ra < ((rt + nb - 1) - 31)) - return 1; - } - } - - if (flags & FL_CHECK_LSWX) - { - /* - * Check that rT != rA, rT != rB, and rD and rA both do not specify - * R0. - * - * We cannot check fully whether rA or rB are in the range of - * registers specified to be loaded because that depends on XER. - */ - - if (rt == ra || rt == G_RB(op) || ((rt == 0) && (ra == 0))) - return 1; - } - - return 0; // passed checks -} -#endif -/* * Simplified(): * - * Handles all simplified instruction forms. Returns 1 if one was decoded, - * otherwise 0 to indicate disassembly should carry on as normal. + * Handles all simplified instruction forms. Returns true if one was decoded, + * otherwise false to indicate disassembly should carry on as normal. */ -static int Simplified(uint32_t op, uint32_t vpc, char *signed16, char *mnem, char *oprs) +bool powerpc_disassembler::Simplified(uint32_t op, uint32_t vpc, std::string &signed16, std::string &mnem, std::string &oprs) { uint32_t value, disp; @@ -653,96 +496,96 @@ static int Simplified(uint32_t op, uint32_t vpc, char *signed16, char *mnem, cha value |= 0xffff0000; if (op == (D_OP(24)|D_RT(0)|D_RA(0)|D_UIMM(0))) - strcat(mnem, "nop"); // ori r0,r0,0 -> nop + mnem += "nop"; // ori r0,r0,0 -> nop else if ((op & ~(M_RT|M_RA|M_RB|M_RC)) == (D_OP(31)|D_XO(444))) { if (G_RT(op) == G_RB(op)) { - strcat(mnem, "mr"); // orx rA,rT,rT -> mrx rA,rT - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d", G_RA(op), G_RT(op)); + mnem += "mr"; // orx rA,rT,rT -> mrx rA,rT + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d", G_RA(op), G_RT(op)); } else - return 0; + return false; } else if ((op & ~(M_RT|M_RA|M_RB|M_RC)) == (D_OP(31)|D_XO(124))) { if (G_RT(op) == G_RB(op)) { - strcat(mnem, "not"); // nor rA,rT,rT -> not rA,rT - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d", G_RA(op), G_RT(op)); + mnem += "not"; // nor rA,rT,rT -> not rA,rT + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d", G_RA(op), G_RT(op)); } else - return 0; + return false; } else if ((op & ~(M_RT|M_RA|M_SIMM)) == D_OP(14)) { if (G_RA(op) == 0) { - strcat(mnem, "li"); // addi rT,0,value -> li rT,value - sprintf(oprs, "r%d,0x%08X", G_RT(op), value); + mnem += "li"; // addi rT,0,value -> li rT,value + oprs = util::string_format("r%d,0x%08X", G_RT(op), value); } else - return 0; + return false; } else if ((op & ~(M_RT|M_RA|M_SIMM)) == D_OP(15)) { if (G_RA(op) == 0) { - strcat(mnem, "li"); // addis rT,0,value -> li rT,(value<<16) - sprintf(oprs, "r%d,0x%08X", G_RT(op), value << 16); + mnem += "li"; // addis rT,0,value -> li rT,(value<<16) + oprs = util::string_format("r%d,0x%08X", G_RT(op), value << 16); } else { - strcat(mnem, "addi"); // addis rT,rA,SIMM -> addi rT,rA,SIMM<<16 - sprintf(oprs, "r%d,r%d,0x%08X", G_RT(op), G_RA(op), value << 16); + mnem += "addi"; // addis rT,rA,SIMM -> addi rT,rA,SIMM<<16 + oprs = util::string_format("r%d,r%d,0x%08X", G_RT(op), G_RA(op), value << 16); } } else if ((op & ~(M_RT|M_RA|M_UIMM)) == D_OP(29)) { - strcat(mnem, "andi."); // andis. rA,rT,UIMM -> andi. rA,rT,UIMM<<16 - sprintf(oprs, "r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); + mnem += "andi."; // andis. rA,rT,UIMM -> andi. rA,rT,UIMM<<16 + oprs = util::string_format("r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); } else if ((op & ~(M_RT|M_RA|M_UIMM)) == D_OP(25)) { - strcat(mnem, "ori"); // oris rA,rT,UIMM -> ori rA,rT,UIMM<<16 - sprintf(oprs, "r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); + mnem += "ori"; // oris rA,rT,UIMM -> ori rA,rT,UIMM<<16 + oprs = util::string_format("r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); } else if ((op & ~(M_RT|M_RA|M_UIMM)) == D_OP(27)) { - strcat(mnem, "xori"); // xoris rA,rT,UIMM -> xori rA,rT,UIMM<<16 - sprintf(oprs, "r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); + mnem += "xori"; // xoris rA,rT,UIMM -> xori rA,rT,UIMM<<16 + oprs = util::string_format("r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_UIMM(op) << 16); } else if ((op & ~(M_RT|M_RA|M_SH|M_MB|M_ME|M_RC)) == D_OP(20)) { value = Mask(G_MB(op), G_ME(op)); - strcat(mnem, "rlwimi"); // rlwimi[.] rA,rT,SH,MB,ME -> rlwimi[.] rA,rT,SH,MASK - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,%d,0x%08X", G_RA(op), G_RT(op), G_SH(op), value); + mnem += "rlwimi"; // rlwimi[.] rA,rT,SH,MB,ME -> rlwimi[.] rA,rT,SH,MASK + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,%d,0x%08X", G_RA(op), G_RT(op), G_SH(op), value); } else if ((op & ~(M_RT|M_RA|M_SH|M_MB|M_ME|M_RC)) == D_OP(21)) { value = Mask(G_MB(op), G_ME(op)); if (G_SH(op) == 0) // rlwinm[.] rA,rT,0,MB,ME -> and[.] rA,rT,MASK { - strcat(mnem, "and"); - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,0x%08X", G_RA(op), G_RT(op), value); + mnem += "and"; + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,0x%08X", G_RA(op), G_RT(op), value); } else // rlwinm[.] rA,rT,SH,MASK { - strcat(mnem, "rlwinm"); - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,%d,0x%08X", G_RA(op), G_RT(op), G_SH(op), value); + mnem += "rlwinm"; + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,%d,0x%08X", G_RA(op), G_RT(op), G_SH(op), value); } } else if ((op & ~(M_RT|M_RA|M_RB|M_MB|M_ME|M_RC)) == D_OP(23)) { value = Mask(G_MB(op), G_ME(op)); - strcat(mnem, "rlwnm"); // rlwnm[.] rA,rT,SH,MB,ME -> rlwnm[.] rA,rT,SH,MASK - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_RB(op), value); + mnem += "rlwnm"; // rlwnm[.] rA,rT,SH,MB,ME -> rlwnm[.] rA,rT,SH,MASK + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,r%d,0x%08X", G_RA(op), G_RT(op), G_RB(op), value); } else if ((op & ~(M_BO|M_BI|M_BD|M_AA|M_LK)) == D_OP(16)) { @@ -753,105 +596,100 @@ static int Simplified(uint32_t op, uint32_t vpc, char *signed16, char *mnem, cha switch (G_BO(op)) { case 0x04: case 0x05: case 0x06: case 0x07: - strcat(mnem, "b"); - strcat(mnem, crnbit[G_BI(op) & 3]); + mnem += "b"; + mnem += crnbit[G_BI(op) & 3]; break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - strcat(mnem, "b"); - strcat(mnem, crbit[G_BI(op) & 3]); + mnem += "b"; + mnem += crbit[G_BI(op) & 3]; break; case 0x10: case 0x11: case 0x18: case 0x19: - strcat(mnem, "bdnz"); + mnem += "bdnz"; break; case 0x12: case 0x13: case 0x1a: case 0x1b: - strcat(mnem, "bdz"); + mnem += "bdz"; break; case 0x14: case 0x15: case 0x16: case 0x17: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - strcat(mnem, "b"); + mnem += "b"; break; default: - return 0; + return false; } - if (op & M_LK) strcat(mnem, "l"); - if (op & M_AA) strcat(mnem, "a"); + if (op & M_LK) mnem += "l"; + if (op & M_AA) mnem += "a"; if (!(G_BO(op) & 0x10) && G_BI(op) / 4 != 0) - sprintf(oprs, "cr%d,0x%08X", G_BI(op) / 4, disp + ((op & M_AA) ? 0 : vpc)); + oprs = util::string_format("cr%d,0x%08X", G_BI(op) / 4, disp + ((op & M_AA) ? 0 : vpc)); else - sprintf(oprs, "0x%08X", disp + ((op & M_AA) ? 0 : vpc)); + oprs = util::string_format("0x%08X", disp + ((op & M_AA) ? 0 : vpc)); } else if ((op & ~(M_BO|M_BI|M_LK)) == (D_OP(19)|D_XO(528)) || (op & ~(M_BO|M_BI|M_LK)) == (D_OP(19)|D_XO(16))) { switch (G_BO(op)) { case 0x04: case 0x05: case 0x06: case 0x07: - strcat(mnem, "b"); - strcat(mnem, crnbit[G_BI(op) & 3]); + mnem += "b"; + mnem += crnbit[G_BI(op) & 3]; break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: - strcat(mnem, "b"); - strcat(mnem, crbit[G_BI(op) & 3]); + mnem += "b"; + mnem += crbit[G_BI(op) & 3]; break; case 0x10: case 0x11: case 0x18: case 0x19: - strcat(mnem, "bdnz"); + mnem += "bdnz"; break; case 0x12: case 0x13: case 0x1a: case 0x1b: - strcat(mnem, "bdz"); + mnem += "bdz"; break; case 0x14: case 0x15: case 0x16: case 0x17: case 0x1c: case 0x1d: case 0x1e: case 0x1f: - strcat(mnem, "b"); + mnem += "b"; break; default: - return 0; + return false; } - strcat(mnem, (G_XO(op) == 528) ? "ctr" : "lr"); - if (op & M_LK) strcat(mnem, "l"); - if (op & M_AA) strcat(mnem, "a"); + mnem += (G_XO(op) == 528) ? "ctr" : "lr"; + if (op & M_LK) mnem += "l"; + if (op & M_AA) mnem += "a"; if (!(G_BO(op) & 0x10) && G_BI(op) / 4 != 0) - sprintf(oprs, "cr%d", G_BI(op) / 4); + oprs = util::string_format("cr%d", G_BI(op) / 4); } else if ((op & ~(M_RT|M_RA|M_RB|M_OE|M_RC)) == (D_OP(31)|D_XO(40))) { - strcat(mnem, "sub"); - if (op & M_OE) strcat(mnem, "o"); - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,r%d", G_RT(op), G_RB(op), G_RA(op)); + mnem += "sub"; + if (op & M_OE) mnem += "o"; + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,r%d", G_RT(op), G_RB(op), G_RA(op)); } else if ((op & ~(M_RT|M_RA|M_RB|M_OE|M_RC)) == (D_OP(31)|D_XO(8))) { - strcat(mnem, "subc"); - if (op & M_OE) strcat(mnem, "o"); - if (op & M_RC) strcat(mnem, "."); - sprintf(oprs, "r%d,r%d,r%d", G_RT(op), G_RB(op), G_RA(op)); + mnem += "subc"; + if (op & M_OE) mnem += "o"; + if (op & M_RC) mnem += "."; + oprs = util::string_format("r%d,r%d,r%d", G_RT(op), G_RB(op), G_RA(op)); } else - return 0; // no match + return false; // no match - return 1; + return true; } -offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) +offs_t powerpc_disassembler::dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) { - char signed16[12]; + std::string signed16, mnem, oprs; uint32_t disp; int i,j; - char mnem[200]; - char oprs[200]; - offs_t flags = DASMFLAG_SUPPORTED; - - mnem[0] = '\0'; // so we can use strcat() - oprs[0] = '\0'; + offs_t flags = SUPPORTED; /* * Decode signed 16-bit fields (SIMM and d) to spare us the work later */ - DecodeSigned16(signed16, op, 0); + signed16 = DecodeSigned16(op, 0); /* * Try simplified forms first, then real instructions @@ -859,7 +697,7 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) if( Simplified(op, pc, signed16, mnem, oprs) ) { util::stream_format(stream, "%s", mnem); - for( j = strlen(mnem); j < 10; j++ ) { + for( j = mnem.size(); j < 10; j++ ) { util::stream_format(stream, " "); } util::stream_format(stream, "%s", oprs); @@ -878,11 +716,11 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) * Base mnemonic followed be O, ., L, A */ - strcat(mnem, itab[i].mnem); - if (itab[i].flags & FL_OE) if (op & M_OE) strcat(mnem, "o"); - if (itab[i].flags & FL_RC) if (op & M_RC) strcat(mnem, "."); - if (itab[i].flags & FL_LK) if (op & M_LK) strcat(mnem, "l"); - if (itab[i].flags & FL_AA) if (op & M_AA) strcat(mnem, "a"); + mnem += itab[i].mnem; + if (itab[i].flags & FL_OE) if (op & M_OE) mnem += "o"; + if (itab[i].flags & FL_RC) if (op & M_RC) mnem += "."; + if (itab[i].flags & FL_LK) if (op & M_LK) mnem += "l"; + if (itab[i].flags & FL_AA) if (op & M_AA) mnem += "a"; /* * Print operands @@ -891,44 +729,44 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) switch (itab[i].format) { case F_RT_RA_RB: - sprintf(oprs, "r%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("r%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); break; case F_RT_RA_0_SIMM: if (G_RA(op)) - sprintf(oprs, "r%d,r%d,%s", G_RT(op), G_RA(op), signed16); + oprs = util::string_format("r%d,r%d,%s", G_RT(op), G_RA(op), signed16); else - sprintf(oprs, "r%d,0,%s", G_RT(op), signed16); + oprs = util::string_format("r%d,0,%s", G_RT(op), signed16); break; case F_ADDIS: if (G_RA(op)) - sprintf(oprs, "r%d,r%d,0x%04X", G_RT(op), G_RA(op), G_SIMM(op)); + oprs = util::string_format("r%d,r%d,0x%04X", G_RT(op), G_RA(op), G_SIMM(op)); else - sprintf(oprs, "r%d,0,0x%04X", G_RT(op), G_SIMM(op)); + oprs = util::string_format("r%d,0,0x%04X", G_RT(op), G_SIMM(op)); break; case F_RT_RA_SIMM: - sprintf(oprs, "r%d,r%d,%s", G_RT(op), G_RA(op), signed16); + oprs = util::string_format("r%d,r%d,%s", G_RT(op), G_RA(op), signed16); break; case F_RT_RA: - sprintf(oprs, "r%d,r%d", G_RT(op), G_RA(op)); + oprs = util::string_format("r%d,r%d", G_RT(op), G_RA(op)); break; case F_RA_RT_RB: - sprintf(oprs, "r%d,r%d,r%d", G_RA(op), G_RT(op), G_RB(op)); + oprs = util::string_format("r%d,r%d,r%d", G_RA(op), G_RT(op), G_RB(op)); break; case F_RA_RT_UIMM: - sprintf(oprs, "r%d,r%d,0x%04X", G_RA(op), G_RT(op), G_UIMM(op)); + oprs = util::string_format("r%d,r%d,0x%04X", G_RA(op), G_RT(op), G_UIMM(op)); break; case F_LI: disp = G_LI(op) * 4; if (disp & 0x02000000) // sign extend disp |= 0xfc000000; - sprintf(oprs, "0x%08X", disp + ((op & M_AA) ? 0 : pc)); + oprs = util::string_format("0x%08X", disp + ((op & M_AA) ? 0 : pc)); break; case F_BCx: @@ -937,213 +775,209 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) disp |= 0xffff0000; if (G_BO(op) & 0x10) // BI is ignored (don't print CR bit) - sprintf(oprs, "0x%02X,%d,0x%08X", G_BO(op), G_BI(op), disp + ((op & M_AA) ? 0 : pc)); + oprs = util::string_format("0x%02X,%d,0x%08X", G_BO(op), G_BI(op), disp + ((op & M_AA) ? 0 : pc)); else // BI gives us the condition bit - sprintf(oprs, "0x%02X,cr%d[%s],0x%08X", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3], disp + ((op & M_AA) ? 0 : pc)); + oprs = util::string_format("0x%02X,cr%d[%s],0x%08X", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3], disp + ((op & M_AA) ? 0 : pc)); break; case F_BO_BI: if (G_BO(op) & 0x10) // BI is ignored (don't print CR bit) - sprintf(oprs, "0x%02X,%d", G_BO(op), G_BI(op)); + oprs = util::string_format("0x%02X,%d", G_BO(op), G_BI(op)); else - sprintf(oprs, "0x%02X,cr%d[%s]", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3]); + oprs = util::string_format("0x%02X,cr%d[%s]", G_BO(op), G_BI(op) / 4, crbit[G_BI(op) & 3]); break; case F_CMP: if (G_L(op)) - strcat(mnem, "d"); + mnem += "d"; if (G_CRFD(op) == 0) - sprintf(oprs, "r%d,r%d", G_RA(op), G_RB(op)); + oprs = util::string_format("r%d,r%d", G_RA(op), G_RB(op)); else - sprintf(oprs, "cr%d,r%d,r%d", G_CRFD(op), G_RA(op), G_RB(op)); + oprs = util::string_format("cr%d,r%d,r%d", G_CRFD(op), G_RA(op), G_RB(op)); break; case F_CMP_SIMM: if (G_L(op)) - strcat(mnem, "d"); + mnem += "d"; if (G_CRFD(op) == 0) - sprintf(oprs, "r%d,%s", G_RA(op), signed16); + oprs = util::string_format("r%d,%s", G_RA(op), signed16); else - sprintf(oprs, "cr%d,r%d,%s", G_CRFD(op), G_RA(op), signed16); + oprs = util::string_format("cr%d,r%d,%s", G_CRFD(op), G_RA(op), signed16); break; case F_CMP_UIMM: if (G_L(op)) - strcat(mnem, "d"); + mnem += "d"; if (G_CRFD(op) == 0) - sprintf(oprs, "r%d,0x%04X", G_RA(op), G_UIMM(op)); + oprs = util::string_format("r%d,0x%04X", G_RA(op), G_UIMM(op)); else - sprintf(oprs, "cr%d,r%d,0x%04X", G_CRFD(op), G_RA(op), G_UIMM(op)); + oprs = util::string_format("cr%d,r%d,0x%04X", G_CRFD(op), G_RA(op), G_UIMM(op)); break; case F_RA_RT: - sprintf(oprs, "r%d,r%d", G_RA(op), G_RT(op)); + oprs = util::string_format("r%d,r%d", G_RA(op), G_RT(op)); break; case F_CRBD_CRBA_CRBB: - sprintf(oprs, "cr%d[%s],cr%d[%s],cr%d[%s]", G_CRBD(op) / 4, crbit[G_CRBD(op) & 3], G_CRBA(op) / 4, crbit[G_CRBA(op) & 3], G_CRBB(op) / 4, crbit[G_CRBB(op) & 3]); + oprs = util::string_format("cr%d[%s],cr%d[%s],cr%d[%s]", G_CRBD(op) / 4, crbit[G_CRBD(op) & 3], G_CRBA(op) / 4, crbit[G_CRBA(op) & 3], G_CRBB(op) / 4, crbit[G_CRBB(op) & 3]); break; case F_RA_0_RB: if (G_RA(op)) - sprintf(oprs, "r%d,r%d", G_RA(op), G_RB(op)); + oprs = util::string_format("r%d,r%d", G_RA(op), G_RB(op)); else - sprintf(oprs, "0,r%d", G_RB(op)); + oprs = util::string_format("0,r%d", G_RB(op)); break; case F_RT_RA_0_RB: if (G_RA(op)) - sprintf(oprs, "r%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("r%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); else - sprintf(oprs, "r%d,0,r%d", G_RT(op), G_RB(op)); + oprs = util::string_format("r%d,0,r%d", G_RT(op), G_RB(op)); break; case F_FRT_FRB: - sprintf(oprs, "f%d,f%d", G_RT(op), G_RB(op)); + oprs = util::string_format("f%d,f%d", G_RT(op), G_RB(op)); break; case F_FRT_FRA_FRB: - sprintf(oprs, "f%d,f%d,f%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("f%d,f%d,f%d", G_RT(op), G_RA(op), G_RB(op)); break; case F_FCMP: - sprintf(oprs, "cr%d,f%d,f%d", G_CRFD(op), G_RA(op), G_RB(op)); + oprs = util::string_format("cr%d,f%d,f%d", G_CRFD(op), G_RA(op), G_RB(op)); break; case F_FRT_FRA_FRC_FRB: - sprintf(oprs, "f%d,f%d,f%d,f%d", G_RT(op), G_RA(op), G_REGC(op), G_RB(op)); + oprs = util::string_format("f%d,f%d,f%d,f%d", G_RT(op), G_RA(op), G_REGC(op), G_RB(op)); break; case F_FRT_FRA_FRC: - sprintf(oprs, "f%d,f%d,f%d", G_RT(op), G_RA(op), G_REGC(op)); + oprs = util::string_format("f%d,f%d,f%d", G_RT(op), G_RA(op), G_REGC(op)); break; case F_RT_D_RA_0: if (G_RA(op)) - sprintf(oprs, "r%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); + oprs = util::string_format("r%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); else - sprintf(oprs, "r%d,0x%08X", G_RT(op), (uint32_t) ((int16_t) G_D(op))); + oprs = util::string_format("r%d,0x%08X", G_RT(op), (uint32_t) ((int16_t) G_D(op))); break; case F_RT_D_RA: - sprintf(oprs, "r%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); + oprs = util::string_format("r%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); break; case F_FRT_D_RA_0: if (G_RA(op)) - sprintf(oprs, "f%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); + oprs = util::string_format("f%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); else - sprintf(oprs, "f%d,0x%08X", G_RT(op), (uint32_t) ((int16_t) G_D(op))); + oprs = util::string_format("f%d,0x%08X", G_RT(op), (uint32_t) ((int16_t) G_D(op))); break; case F_FRT_D_RA: - sprintf(oprs, "f%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); + oprs = util::string_format("f%d,%s(r%d)", G_RT(op), signed16, G_RA(op)); break; case F_FRT_RA_RB: - sprintf(oprs, "f%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("f%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); break; case F_FRT_RA_0_RB: if (G_RA(op)) - sprintf(oprs, "f%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); + oprs = util::string_format("f%d,r%d,r%d", G_RT(op), G_RA(op), G_RB(op)); else - sprintf(oprs, "f%d,0,r%d", G_RT(op), G_RB(op)); + oprs = util::string_format("f%d,0,r%d", G_RT(op), G_RB(op)); break; case F_RT_RA_0_NB: if (G_RA(op)) - sprintf(oprs, "r%d,r%d,%d", G_RT(op), G_RA(op), G_NB(op) ? G_NB(op) : 32); + oprs = util::string_format("r%d,r%d,%d", G_RT(op), G_RA(op), G_NB(op) ? G_NB(op) : 32); else - sprintf(oprs, "r%d,0,%d", G_RT(op), G_NB(op) ? G_NB(op) : 32); + oprs = util::string_format("r%d,0,%d", G_RT(op), G_NB(op) ? G_NB(op) : 32); break; case F_CRFD_CRFS: - sprintf(oprs, "cr%d,cr%d", G_CRFD(op), G_CRFS(op)); + oprs = util::string_format("cr%d,cr%d", G_CRFD(op), G_CRFS(op)); break; case F_MCRXR: - sprintf(oprs, "cr%d", G_CRFD(op)); + oprs = util::string_format("cr%d", G_CRFD(op)); break; case F_RT: - sprintf(oprs, "r%d", G_RT(op)); + oprs = util::string_format("r%d", G_RT(op)); break; case F_MFFSx: - sprintf(oprs, "f%d", G_RT(op)); + oprs = util::string_format("f%d", G_RT(op)); break; case F_FCRBD: - sprintf(oprs, "fpscr[%d]", G_CRBD(op)); + oprs = util::string_format("fpscr[%d]", G_CRBD(op)); break; case F_RT_SPR: - sprintf(oprs, "r%d,", G_RT(op)); - SPR(oprs, G_SPR(op)); + oprs = util::string_format("r%d,", G_RT(op)) + SPR(G_SPR(op)); break; case F_RT_DCR: - sprintf(oprs, "r%d,", G_RT(op)); - DCR(oprs, G_DCR(op)); + oprs = util::string_format("r%d,", G_RT(op)) + DCR(G_DCR(op)); break; case F_MFSR: - sprintf(oprs, "r%d,sr%d", G_RT(op), G_SR(op)); + oprs = util::string_format("r%d,sr%d", G_RT(op), G_SR(op)); break; case F_MTCRF: - sprintf(oprs, "0x%02X,r%d", G_CRM(op), G_RT(op)); + oprs = util::string_format("0x%02X,r%d", G_CRM(op), G_RT(op)); break; case F_MTFSFx: - sprintf(oprs, "0x%02X,f%d", G_FM(op), G_RB(op)); + oprs = util::string_format("0x%02X,f%d", G_FM(op), G_RB(op)); break; case F_MTFSFIx: - sprintf(oprs, "cr%d,0x%X", G_CRFD(op), G_IMM(op)); + oprs = util::string_format("cr%d,0x%X", G_CRFD(op), G_IMM(op)); break; case F_MTSPR: - SPR(oprs, G_SPR(op)); - sprintf(oprs + strlen(oprs), ",r%d", G_RT(op)); + oprs = SPR(G_SPR(op)) + util::string_format(",r%d", G_RT(op)); break; case F_MTDCR: - DCR(oprs, G_DCR(op)); - sprintf(oprs + strlen(oprs), ",r%d", G_RT(op)); + oprs = DCR(G_DCR(op)) + util::string_format(",r%d", G_RT(op)); break; case F_MTSR: - sprintf(oprs, "sr%d,r%d", G_SR(op), G_RT(op)); + oprs = util::string_format("sr%d,r%d", G_SR(op), G_RT(op)); break; case F_RT_RB: - sprintf(oprs, "r%d,r%d", G_RT(op), G_RB(op)); + oprs = util::string_format("r%d,r%d", G_RT(op), G_RB(op)); break; case F_RA_RT_SH_MB_ME: - sprintf(oprs, "r%d,r%d,%d,%d,%d", G_RA(op), G_RT(op), G_SH(op), G_MB(op), G_ME(op)); + oprs = util::string_format("r%d,r%d,%d,%d,%d", G_RA(op), G_RT(op), G_SH(op), G_MB(op), G_ME(op)); break; case F_RLWNMx: - sprintf(oprs, "r%d,r%d,r%d,%d,%d", G_RA(op), G_RT(op), G_RB(op), G_MB(op), G_ME(op)); + oprs = util::string_format("r%d,r%d,r%d,%d,%d", G_RA(op), G_RT(op), G_RB(op), G_MB(op), G_ME(op)); break; case F_SRAWIx: - sprintf(oprs, "r%d,r%d,%d", G_RA(op), G_RT(op), G_SH(op)); + oprs = util::string_format("r%d,r%d,%d", G_RA(op), G_RT(op), G_SH(op)); break; case F_RB: - sprintf(oprs, "r%d", G_RB(op)); + oprs = util::string_format("r%d", G_RB(op)); break; case F_TW: - sprintf(oprs, "%d,r%d,r%d", G_TO(op), G_RA(op), G_RB(op)); + oprs = util::string_format("%d,r%d,r%d", G_TO(op), G_RA(op), G_RB(op)); break; case F_TWI: - sprintf(oprs, "%d,r%d,%s", G_TO(op), G_RA(op), signed16); + oprs = util::string_format("%d,r%d,%s", G_TO(op), G_RA(op), signed16); break; case F_NONE: @@ -1152,12 +986,12 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) } if ((itab[i].flags & FL_LK) && (op & M_LK)) - flags |= DASMFLAG_STEP_OVER; + flags |= STEP_OVER; else if (itab[i].flags & FL_SO) - flags |= DASMFLAG_STEP_OUT; + flags |= STEP_OUT; util::stream_format(stream, "%s", mnem); - for( j = strlen(mnem); j < 10; j++ ) { + for( j = mnem.size(); j < 10; j++ ) { util::stream_format(stream, " "); } util::stream_format(stream, "%s", oprs); @@ -1169,10 +1003,12 @@ offs_t ppc_dasm_one(std::ostream &stream, uint32_t pc, uint32_t op) return 4 | flags; } +offs_t powerpc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + return dasm_one(stream, pc, opcodes.r32(pc)); +} -CPU_DISASSEMBLE( powerpc ) +u32 powerpc_disassembler::opcode_alignment() const { - uint32_t op = *(uint32_t *)oprom; - op = big_endianize_int32(op); - return ppc_dasm_one(stream, pc, op); + return 4; } diff --git a/src/devices/cpu/powerpc/ppc_dasm.h b/src/devices/cpu/powerpc/ppc_dasm.h new file mode 100644 index 00000000000..5fab7dfe074 --- /dev/null +++ b/src/devices/cpu/powerpc/ppc_dasm.h @@ -0,0 +1,142 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/* + * disasm.c + * + * PowerPC 603e disassembler. + * + * When possible, invalid forms of instructions are checked for. To the best + * of my knowledge, all appropriate load/store instructions are checked. I'm + * not sure whether any other kinds of instructions need checking. + */ + +/* Originally written by Bart Trzynadlowski for Supermodel project + * + * PowerPC 403 opcodes and MAME conversion by Ville Linde + */ + +#ifndef MAME_CPU_POWERPC_PPC_DASM_H +#define MAME_CPU_POWERPC_PPC_DASM_H + +#pragma once + +class powerpc_disassembler : public util::disasm_interface +{ +public: + powerpc_disassembler() = default; + virtual ~powerpc_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + static offs_t dasm_one(std::ostream &stream, uint32_t pc, uint32_t op); + +private: + /* + * Operand Formats + * + * These convey information on what operand fields are present and how they + * ought to be printed. + * + * I'm fairly certain all of these are used, but that is not guaranteed. + */ + + enum + { + F_NONE, // <no operands> + F_LI, // LI*4+PC if AA=0 else LI*4 + F_BCx, // BO, BI, target_addr used only by BCx + F_RT_RA_0_SIMM, // rT, rA|0, SIMM rA|0 means if rA == 0, print 0 + F_ADDIS, // rT, rA, SIMM (printed as unsigned) only used by ADDIS + F_RT_RA_SIMM, // rT, rA, SIMM + F_RA_RT_UIMM, // rA, rT, UIMM + F_CMP_SIMM, // crfD, L, A, SIMM + F_CMP_UIMM, // crfD, L, A, UIMM + F_RT_RA_0_RB, // rT, rA|0, rB + F_RT_RA_RB, // rT, rA, rB + F_RT_D_RA_0, // rT, d(rA|0) + F_RT_D_RA, // rT, d(rA) + F_RA_RT_RB, // rA, rT, rB + F_FRT_D_RA_0, // frT, d(RA|0) + F_FRT_D_RA, // frT, d(RA) + F_FRT_RA_0_RB, // frT, rA|0, rB + F_FRT_RA_RB, // frT, rA, rB + F_TWI, // TO, rA, SIMM only used by TWI instruction + F_CMP, // crfD, L, rA, rB + F_RA_RT, // rA, rT + F_RA_0_RB, // rA|0, rB + F_FRT_FRB, // frT, frB + F_FCMP, // crfD, frA, frB + F_CRFD_CRFS, // crfD, crfS + F_MCRXR, // crfD only used by MCRXR + F_RT, // rT + F_MFSR, // rT, SR only used by MFSR + F_MTSR, // SR, rT only used by MTSR + F_MFFSx, // frT only used by MFFSx + F_FCRBD, // crbD FPSCR[crbD] + F_MTFSFIx, // crfD, IMM only used by MTFSFIx + F_RB, // rB + F_TW, // TO, rA, rB only used by TW + F_RT_RA_0_NB, // rT, rA|0, NB print 32 if NB == 0 + F_SRAWIx, // rA, rT, SH only used by SRAWIx + F_BO_BI, // BO, BI + F_CRBD_CRBA_CRBB, // crbD, crbA, crbB + F_RT_SPR, // rT, SPR and TBR + F_MTSPR, // SPR, rT only used by MTSPR + F_MTCRF, // CRM, rT only used by MTCRF + F_MTFSFx, // FM, frB only used by MTFSFx + F_RT_DCR, // rT, DCR + F_MTDCR, // DCR, rT + F_RT_RA, // rT, rA + F_FRT_FRA_FRC_FRB, // frT, frA, frC, frB + F_FRT_FRA_FRB, // frT, frA, frB + F_FRT_FRA_FRC, // frT, frA, frC + F_RA_RT_SH_MB_ME, // rA, rT, SH, MB, ME + F_RLWNMx, // rT, rA, rB, MB, ME only used by RLWNMx + F_RT_RB // rT, rB + }; + + /* + * Flags + */ + + enum + { + FL_OE = 1 << 0, // if there is an OE field + FL_RC = 1 << 1, // if there is an RC field + FL_LK = 1 << 2, // if there is an LK field + FL_AA = 1 << 3, // if there is an AA field + FL_CHECK_RA_RT = 1 << 4, // assert rA!=0 and rA!=rT + FL_CHECK_RA = 1 << 5, // assert rA!=0 + FL_CHECK_LSWI = 1 << 6, // specific check for LSWI validity + FL_CHECK_LSWX = 1 << 7, // specific check for LSWX validity + FL_SO = 1 << 8 // use STEP_OUT + }; + + /* + * Instruction Descriptor + * + * Describes the layout of an instruction. + */ + + struct IDESCR + { + char mnem[32]; // mnemonic + uint32_t match; // bit pattern of instruction after it has been masked + uint32_t mask; // mask of variable fields (AND with ~mask to compare w/ + // bit pattern to determine a match) + int format; // operand format + int flags; // flags + }; + + static const IDESCR itab[]; + static const char *const crbit[4]; + static const char *const crnbit[4]; + + static std::string SPR(int spr_field); + static std::string DCR(int dcr_field); + static std::string DecodeSigned16(uint32_t op, int do_unsigned); + static uint32_t Mask(int mb, int me); + static bool Simplified(uint32_t op, uint32_t vpc, std::string &signed16, std::string &mnem, std::string &oprs); +}; + +#endif diff --git a/src/devices/cpu/powerpc/ppccom.cpp b/src/devices/cpu/powerpc/ppccom.cpp index d9b4cf3ba96..9e4aecd3ee2 100644 --- a/src/devices/cpu/powerpc/ppccom.cpp +++ b/src/devices/cpu/powerpc/ppccom.cpp @@ -11,7 +11,7 @@ #include "emu.h" #include "ppccom.h" #include "ppcfe.h" - +#include "ppc_dasm.h" /*************************************************************************** DEBUGGING @@ -710,7 +710,7 @@ void ppc_device::device_start() m_cache_line_size = 32; m_cpu_clock = clock(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_system_clock = c_bus_frequency != 0 ? c_bus_frequency : clock(); m_dcr_read_func = read32_delegate(); m_dcr_write_func = write32_delegate(); @@ -1165,11 +1165,9 @@ void ppc_device::device_reset() CPU -------------------------------------------------*/ -offs_t ppc_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ppc_device::create_disassembler() { - uint32_t op = *(uint32_t *)oprom; - op = big_endianize_int32(op); - return ppc_dasm_one(stream, pc, op); + return new powerpc_disassembler; } diff --git a/src/devices/cpu/powerpc/ppcdrc.cpp b/src/devices/cpu/powerpc/ppcdrc.cpp index 741e75f9cc2..30ebb6740cb 100644 --- a/src/devices/cpu/powerpc/ppcdrc.cpp +++ b/src/devices/cpu/powerpc/ppcdrc.cpp @@ -19,6 +19,7 @@ #include "ppc.h" #include "ppccom.h" #include "ppcfe.h" +#include "ppc_dasm.h" #include "cpu/drcfe.h" #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" @@ -995,7 +996,7 @@ void ppc_device::static_generate_memory_accessor(int mode, int size, int iswrite /* on entry, address is in I0; data for writes is in I1; masks are in I2 */ /* on exit, read result is in I0 */ /* routine trashes I0-I3 */ - int fastxor = BYTE8_XOR_BE(0) >> (int)(space_config(AS_PROGRAM)->m_databus_width < 64); + int fastxor = BYTE8_XOR_BE(0) >> (int)(space_config(AS_PROGRAM)->m_data_width < 64); drcuml_block *block; int translate_type; int tlbreturn = 0; @@ -3316,7 +3317,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co UML_MOV(block, R32(G_RD(op)), m_flavor); // mov rd,flavor else { - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), spr); // mov [param0],spr UML_CALLC(block, (c_function)cfunc_ppccom_execute_mfspr, this); // callc ppccom_execute_mfspr,ppc UML_MOV(block, R32(G_RD(op)), mem(&m_core->param1)); // mov rd,[param1] @@ -3338,7 +3339,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co uint32_t tbr = compute_spr(G_SPR(op)); if (tbr != SPRVEA_TBL_R && tbr != SPRVEA_TBU_R) return false; - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), tbr); // mov [param0],tbr UML_CALLC(block, (c_function)cfunc_ppccom_execute_mftb, this); // callc ppccom_execute_mftb,ppc UML_MOV(block, R32(G_RD(op)), mem(&m_core->param1)); // mov rd,[param1] @@ -3383,7 +3384,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co ; // read only else { - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), spr); // mov [param0],spr UML_MOV(block, mem(&m_core->param1), R32(G_RS(op))); // mov [param1],rs UML_CALLC(block, (c_function)cfunc_ppccom_execute_mtspr, this); // callc ppccom_execute_mtspr,ppc @@ -3429,7 +3430,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co { uint32_t spr = compute_spr(G_SPR(op)); assert(m_cap & PPCCAP_4XX); - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), spr); // mov [param0],spr UML_CALLC(block, (c_function)cfunc_ppccom_execute_mfdcr, this); // callc ppccom_execute_mfdcr,ppc UML_MOV(block, R32(G_RD(op)), mem(&m_core->param1)); // mov rd,[param1] @@ -3440,7 +3441,7 @@ bool ppc_device::generate_instruction_1f(drcuml_block *block, compiler_state *co { uint32_t spr = compute_spr(G_SPR(op)); assert(m_cap & PPCCAP_4XX); - generate_update_cycles(block, compiler, desc->pc, true); // <update cycles> + generate_update_cycles(block, compiler, desc->pc, false); // <update cycles> UML_MOV(block, mem(&m_core->param0), spr); // mov [param0],spr UML_MOV(block, mem(&m_core->param1), R32(G_RS(op))); // mov [param1],rs UML_CALLC(block, (c_function)cfunc_ppccom_execute_mtdcr, this); // callc ppccom_execute_mtdcr,ppc @@ -3770,10 +3771,9 @@ void ppc_device::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32 { if (m_drcuml->logging()) { - util::ovectorstream stream; - ppc_dasm_one(stream, pc, op); - stream.put('\0'); - block->append_comment("%08X: %s", pc, &stream.vec()[0]); // comment + std::ostringstream stream; + powerpc_disassembler::dasm_one(stream, pc, op); + block->append_comment("%08X: %s", pc, stream.str()); // comment } } @@ -3961,7 +3961,7 @@ void ppc_device::log_opcode_desc(drcuml_state *drcuml, const opcode_desc *descli if (desclist->flags & OPFLAG_VIRTUAL_NOOP) buffer << "<virtual nop>"; else - ppc_dasm_one(buffer, desclist->pc, desclist->opptr.l[0]); + powerpc_disassembler::dasm_one(buffer, desclist->pc, desclist->opptr.l[0]); } else buffer << "???"; diff --git a/src/devices/cpu/pps4/pps4.cpp b/src/devices/cpu/pps4/pps4.cpp index c0b5ad60aa8..8decf412b8d 100644 --- a/src/devices/cpu/pps4/pps4.cpp +++ b/src/devices/cpu/pps4/pps4.cpp @@ -78,6 +78,7 @@ #include "emu.h" #include "pps4.h" +#include "pps4dasm.h" #include "debugger.h" @@ -139,10 +140,9 @@ void pps4_device::W(u8 data) m_SAG = 0; } -offs_t pps4_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *pps4_device::create_disassembler() { - extern CPU_DISASSEMBLE( pps4 ); - return CPU_DISASSEMBLE_NAME(pps4)(this, stream, pc, oprom, opram, options); + return new pps4_disassembler; } /** @@ -1570,7 +1570,7 @@ void pps4_device::execute_run() void pps4_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); diff --git a/src/devices/cpu/pps4/pps4.h b/src/devices/cpu/pps4/pps4.h index ef3c4dee977..fcf1d790756 100644 --- a/src/devices/cpu/pps4/pps4.h +++ b/src/devices/cpu/pps4/pps4.h @@ -82,9 +82,7 @@ protected: virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_data_config; @@ -95,7 +93,7 @@ protected: devcb_write8 m_do_cb; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/pps4/pps4dasm.cpp b/src/devices/cpu/pps4/pps4dasm.cpp index 71bf93dcb44..edb15db12b3 100644 --- a/src/devices/cpu/pps4/pps4dasm.cpp +++ b/src/devices/cpu/pps4/pps4dasm.cpp @@ -11,36 +11,9 @@ * *****************************************************************************/ #include "emu.h" +#include "pps4dasm.h" -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] - -typedef enum pps4_token_e { - t_AD, t_ADC, t_ADSK, t_ADCSK, t_ADI, - t_DC, t_AND, t_OR, t_EOR, t_COMP, - t_SC, t_RC, t_SF1, t_RF1, t_SF2, - t_RF2, t_LD, t_EX, t_EXD, t_LDI, - t_LAX, t_LXA, t_LABL, t_LBMX, t_LBUA, - t_XABL, t_XBMX, t_XAX, t_XS, t_CYS, - t_LB, t_LBL, t_INCB, t_DECB, t_T, - t_TM, t_TL, t_TML, t_SKC, t_SKZ, - t_SKBI, t_SKF1, t_SKF2, t_RTN, t_RTNSK, - t_IOL, t_DIA, t_DIB, t_DOA, t_SAG, - t_COUNT, - t_MASK = (1 << 6) - 1, - t_I3c = 1 << 6, /* immediate 3 bit constant, complemented */ - t_I4 = 1 << 7, /* immediate 4 bit constant */ - t_I4c = 1 << 8, /* immediate 4 bit constant, complemented */ - t_I4p = 1 << 9, /* immediate 4 bit offset into page 3 */ - t_I6p = 1 << 10, /* immediate 6 bit constant; address in current page */ - t_I6i = 1 << 11, /* immediate 6 bit indirect page 3 offset (16 ... 63) + followed by page 1 address */ - t_I8 = 1 << 12, /* immediate 8 bit constant (I/O port number) */ - t_I8c = 1 << 13, /* immediate 8 bit constant inverted */ - t_OVER = 1 << 14, /* Debugger step over (CALL) */ - t_OUT = 1 << 15 /* Debugger step out (RETURN) */ -} pps4_token_e; - -static const char *token_str[t_COUNT] = { +const char *pps4_disassembler::token_str[t_COUNT] = { "ad", /* add */ "adc", /* add with carry-in */ "adsk", /* add and skip on carry-out */ @@ -93,7 +66,7 @@ static const char *token_str[t_COUNT] = { "sag" /* special address generation */ }; -static const uint16_t table[] = { +const uint16_t pps4_disassembler::table[] = { /* 00 */ t_LBL | t_I8c, /* 01 */ t_TML | t_I4 | t_I8, /* 02 */ t_TML | t_I4 | t_I8, @@ -367,11 +340,16 @@ static const uint16_t table[] = { /* ff */ t_TM | t_I6i | t_OVER }; -CPU_DISASSEMBLE(pps4) +u32 pps4_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t pps4_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; unsigned PC = pc; - uint8_t op = OP(pc++); + uint8_t op = opcodes.r8(pc++); uint32_t tok = table[op]; if (0 == (tok & t_MASK)) { @@ -422,21 +400,21 @@ CPU_DISASSEMBLE(pps4) if (tok & t_I8) { // 8 bit immediate I/O port address - uint8_t arg = ARG(pc++); + uint8_t arg = params.r8(pc++); util::stream_format(stream, "%02x", arg); } if (tok & t_I8c) { // 8 bit immediate offset into page - uint16_t arg = ~ARG(pc++) & 255; + uint16_t arg = ~params.r8(pc++) & 255; util::stream_format(stream, "%02x", arg); } if (tok & t_OVER) // TL or TML - flags |= DASMFLAG_STEP_OVER; + flags |= STEP_OVER; if (tok & t_OUT) // RTN or RTNSK - flags |= DASMFLAG_STEP_OUT; + flags |= STEP_OUT; - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; } diff --git a/src/devices/cpu/pps4/pps4dasm.h b/src/devices/cpu/pps4/pps4dasm.h new file mode 100644 index 00000000000..7e0f0ab9b91 --- /dev/null +++ b/src/devices/cpu/pps4/pps4dasm.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * pps4dasm.c + * + * Rockwell PPS-4 CPU Disassembly + * + * + * TODO: double verify all opcodes with t_Ixx flags + * + *****************************************************************************/ + +#ifndef MAME_CPU_PPS4_PPS4DASM_H +#define MAME_CPU_PPS4_PPS4DASM_H + +#pragma once + +class pps4_disassembler : public util::disasm_interface +{ +public: + pps4_disassembler() = default; + virtual ~pps4_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + typedef enum pps4_token_e { + t_AD, t_ADC, t_ADSK, t_ADCSK, t_ADI, + t_DC, t_AND, t_OR, t_EOR, t_COMP, + t_SC, t_RC, t_SF1, t_RF1, t_SF2, + t_RF2, t_LD, t_EX, t_EXD, t_LDI, + t_LAX, t_LXA, t_LABL, t_LBMX, t_LBUA, + t_XABL, t_XBMX, t_XAX, t_XS, t_CYS, + t_LB, t_LBL, t_INCB, t_DECB, t_T, + t_TM, t_TL, t_TML, t_SKC, t_SKZ, + t_SKBI, t_SKF1, t_SKF2, t_RTN, t_RTNSK, + t_IOL, t_DIA, t_DIB, t_DOA, t_SAG, + t_COUNT, + t_MASK = (1 << 6) - 1, + t_I3c = 1 << 6, /* immediate 3 bit constant, complemented */ + t_I4 = 1 << 7, /* immediate 4 bit constant */ + t_I4c = 1 << 8, /* immediate 4 bit constant, complemented */ + t_I4p = 1 << 9, /* immediate 4 bit offset into page 3 */ + t_I6p = 1 << 10, /* immediate 6 bit constant; address in current page */ + t_I6i = 1 << 11, /* immediate 6 bit indirect page 3 offset (16 ... 63) + followed by page 1 address */ + t_I8 = 1 << 12, /* immediate 8 bit constant (I/O port number) */ + t_I8c = 1 << 13, /* immediate 8 bit constant inverted */ + t_OVER = 1 << 14, /* Debugger step over (CALL) */ + t_OUT = 1 << 15 /* Debugger step out (RETURN) */ + } pps4_token_e; + + static const char *token_str[t_COUNT]; + static const uint16_t table[]; + +}; + +#endif diff --git a/src/devices/cpu/psx/dismips.cpp b/src/devices/cpu/psx/dismips.cpp deleted file mode 100644 index 2551a2d56a8..00000000000 --- a/src/devices/cpu/psx/dismips.cpp +++ /dev/null @@ -1,332 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:smf -/* - * standalone MIPS disassembler by smf - * - * based on DIS68k by Aaron Giles - * - */ - -#include "emu.h" -#include "psx.h" - -extern CPU_DISASSEMBLE( r3000le ); - -static struct -{ - uint8_t id[ 8 ]; - uint32_t text; /* SCE only */ - uint32_t data; /* SCE only */ - uint32_t pc0; - uint32_t gp0; /* SCE only */ - uint32_t t_addr; - uint32_t t_size; - uint32_t d_addr; /* SCE only */ - uint32_t d_size; /* SCE only */ - uint32_t b_addr; /* SCE only */ - uint32_t b_size; /* SCE only */ - uint32_t s_addr; - uint32_t s_size; - uint32_t SavedSP; - uint32_t SavedFP; - uint32_t SavedGP; - uint32_t SavedRA; - uint32_t SavedS0; - uint8_t dummy[ 0x800 - 76 ]; -} m_psxexe_header; - -#define FORMAT_BIN ( 0 ) -#define FORMAT_PSX ( 1 ) - -#define CPU_PSX ( 0 ) -#define CPU_R3000 ( 1 ) -#define CPU_R4000 ( 2 ) - -static uint8_t *filebuf; -static uint32_t offset; -static uint8_t order[] = { 0, 1, 2, 3 }; - -static const char *const Options[]= -{ - "begin", "end", "offset", "order", "format", "cpu", 0 -}; - -static void usage (void) -{ - fprintf( stderr, - "Usage: DISMIPS [options] <filename>\n\n" - "Available options are:\n" - " -begin - Specify begin offset in file to disassemble in bytes [0]\n" - " -end - Specify end offset in file to disassemble in bytes [none]\n" - " -offset - Specify address to load program in bytes [0]\n" - " -order - Specify byte order [0123]\n" - " -format - Specify file format bin|psx [bin]\n" - " -cpu - Specify cpu psx|r3000|r4000 [psx]\n\n" - "All values should be entered in hexadecimal\n" ); - exit( 1 ); -} - -int main( int argc, char *argv[] ) -{ - FILE *f; - uint8_t i; - uint8_t j; - uint8_t n; - uint8_t p; - uint32_t begin; - uint32_t end; - uint32_t filelen; - uint32_t len; - uint32_t pc; - char buffer[ 80 ]; - char *filename; - uint32_t format; - uint32_t cpu; - - filename = nullptr; - begin = 0; - end = 0xffffffff; - format = FORMAT_BIN; - cpu = CPU_PSX; - - n = 0; - for( i = 1; i < argc; i++ ) - { - if( argv[ i ][ 0 ] != '-' ) - { - switch( n ) - { - case 0: - filename = argv[ i ]; - break; - default: - usage(); - break; - } - n++; - } - else - { - for( j = 0; Options[ j ]; j++ ) - { - if( strcmp( argv[ i ] + 1, Options[ j ] ) == 0 ) - { - break; - } - } - switch( j ) - { - case 0: - i++; - if( i > argc ) - { - usage(); - } - begin = strtoul( argv[ i ], 0, 16 ); - break; - case 1: - i++; - if( i > argc ) - { - usage(); - } - end = strtoul( argv[ i ], 0, 16 ); - break; - case 2: - i++; - if( i > argc ) - { - usage(); - } - offset = strtoul( argv[ i ], 0, 16 ); - break; - case 3: - i++; - if( i > argc ) - { - usage(); - } - if( strlen( argv[ i ] ) != 4 ) - { - usage(); - } - for( p = 0; p < 4; p++ ) - { - if( argv[ i ][ p ] < '0' || argv[ i ][ p ] > '3' ) - { - usage(); - } - order[ p ] = argv[ i ][ p ] - '0'; - } - break; - case 4: - i++; - if( i > argc ) - { - usage(); - } - if( core_stricmp( argv[ i ], "bin" ) == 0 ) - { - format = FORMAT_BIN; - } - else if( core_stricmp( argv[ i ], "psx" ) == 0 ) - { - format = FORMAT_PSX; - } - else - { - usage(); - } - break; - case 5: - i++; - if( i > argc ) - { - usage(); - } - if( core_stricmp( argv[ i ], "psx" ) == 0 ) - { - cpu = CPU_PSX; - } - else if( core_stricmp( argv[ i ], "r3000" ) == 0 ) - { - cpu = CPU_R3000; - } - else if( core_stricmp( argv[ i ], "r4000" ) == 0 ) - { - cpu = CPU_R4000; - } - else - { - usage(); - } - break; - default: - usage(); - break; - } - } - } - - if (!filename) - { - usage(); - return 1; - } - f=fopen (filename,"rb"); - if (!f) - { - printf ("Unable to open %s\n",filename); - return 2; - } - fseek (f,0,SEEK_END); - filelen=ftell (f); - - if( format == FORMAT_PSX ) - { - fseek( f, 0, SEEK_SET ); - if( fread( &m_psxexe_header, 1, sizeof( m_psxexe_header ), f ) != sizeof( m_psxexe_header ) ) - { - fprintf( stderr, "error reading ps-x exe header\n" ); - fclose( f ); - return 3; - } - if( memcmp( m_psxexe_header.id, "PS-X EXE", sizeof( m_psxexe_header.id ) ) != 0 ) - { - fprintf( stderr, "invalid ps-x exe header\n" ); - fclose( f ); - return 3; - } - printf( "_start = $%08x\n\n", m_psxexe_header.pc0 ); - if( offset == 0 ) - { - offset = m_psxexe_header.t_addr; - } - if( begin == 0 ) - { - begin = sizeof( m_psxexe_header ); - } - if( end == 0xffffffff ) - { - end = sizeof( m_psxexe_header ) + m_psxexe_header.t_size; - } - } - - fseek (f,begin,SEEK_SET); - len=(filelen>end)? (end-begin+1):(filelen-begin); - filebuf=(uint8_t *)malloc(len+16); - if (!filebuf) - { - printf ("Memory allocation error\n"); - fclose (f); - return 3; - } - memset (filebuf,0,len+16); - if (fread(filebuf,1,len,f)!=len) - { - printf ("Read error\n"); - fclose (f); - free (filebuf); - return 4; - } - fclose (f); - - pc = 0; - while( pc < len ) - { - uint8_t op0 = filebuf[ pc + order[ 0 ] ]; - uint8_t op1 = filebuf[ pc + order[ 1 ] ]; - uint8_t op2 = filebuf[ pc + order[ 2 ] ]; - uint8_t op3 = filebuf[ pc + order[ 3 ] ]; - filebuf[ pc + 0 ] = op0; - filebuf[ pc + 1 ] = op1; - filebuf[ pc + 2 ] = op2; - filebuf[ pc + 3 ] = op3; - - pc += 4; - } - - pc = 0; - while( pc < len ) - { - switch( cpu ) - { - case CPU_PSX: - i = DasmPSXCPU( nullptr, buffer, pc + offset, filebuf + pc ); - break; - case CPU_R3000: - { - cpu_device *device = nullptr; - int options = 0; - uint8_t *opram = filebuf + pc; - uint8_t *oprom = opram; - i = CPU_DISASSEMBLE_CALL( r3000le ); - } - break; - case CPU_R4000: - { - uint8_t *opram = filebuf + pc; - uint32_t op = ( opram[ 3 ] << 24 ) | ( opram[ 2 ] << 16 ) | ( opram[ 1 ] << 8 ) | ( opram[ 0 ] << 0 ); - i = dasmmips3( buffer, pc + offset, op ); - } - break; - } - - i &= DASMFLAG_LENGTHMASK; - - printf( "%08x: ", pc + offset ); - for( j = 0; j < i; j++ ) - { - printf( "%02x ", filebuf[ pc ] ); - pc++; - } - while( j < 10 ) - { - printf( " " ); - j++; - } - printf( "%s\n", buffer ); - } - free (filebuf); - return 0; -} diff --git a/src/devices/cpu/psx/dismips.mak b/src/devices/cpu/psx/dismips.mak deleted file mode 100644 index a229a305bb4..00000000000 --- a/src/devices/cpu/psx/dismips.mak +++ /dev/null @@ -1,2 +0,0 @@ -..\..\..\..\dismips.exe: dismips.cpp psxdasm.cpp ..\mips\r3kdasm.cpp ..\mips\mips3dsm.cpp ../../../lib/util/corestr.cpp - g++ -O3 -x c++ -Wall -Wno-sign-compare -I../.. -I../../../emu -I../../../osd -I../../../lib/util -I../../../lib/expat -DINLINE="static __inline__" -DSTANDALONE -DLSB_FIRST dismips.cpp psxdasm.cpp ..\mips\r3kdasm.cpp ..\mips\mips3dsm.cpp ../../../lib/util/corestr.cpp -o../../../../dismips diff --git a/src/devices/cpu/psx/psx.cpp b/src/devices/cpu/psx/psx.cpp index 36d7c1742f4..2caef37ec85 100644 --- a/src/devices/cpu/psx/psx.cpp +++ b/src/devices/cpu/psx/psx.cpp @@ -1818,7 +1818,7 @@ void psxcpu_device::device_start() { // get our address spaces m_program = &space( AS_PROGRAM ); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item( NAME( m_op ) ); save_item( NAME( m_pc ) ); @@ -2067,13 +2067,13 @@ void psxcpu_device::state_string_export( const device_state_entry &entry, std::s //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t psxcpu_device::disasm_disassemble( std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options ) +util::disasm_interface *psxcpu_device::create_disassembler() { - return DasmPSXCPU( this, stream, pc, opram ); + return new psxcpu_disassembler(this); } diff --git a/src/devices/cpu/psx/psx.h b/src/devices/cpu/psx/psx.h index da70d2c300c..641a971c2ce 100644 --- a/src/devices/cpu/psx/psx.h +++ b/src/devices/cpu/psx/psx.h @@ -17,6 +17,7 @@ #include "gte.h" #include "irq.h" #include "sio.h" +#include "psxdasm.h" //************************************************************************** // CONSTANTS @@ -140,20 +141,9 @@ enum // TYPE DEFINITIONS //************************************************************************** -class psxcpu_state -{ -public: - virtual ~psxcpu_state() { } - - virtual uint32_t pc() = 0; - virtual uint32_t delayr() = 0; - virtual uint32_t delayv() = 0; - virtual uint32_t r(int i) = 0; -}; - // ======================> psxcpu_device -class psxcpu_device : public cpu_device, psxcpu_state +class psxcpu_device : public cpu_device, psxcpu_disassembler::config { public: // static configuration helpers @@ -229,9 +219,7 @@ protected: 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 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // CPU registers uint32_t m_pc; @@ -246,7 +234,7 @@ protected: // address spaces const address_space_config m_program_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; // other internal states int m_icount; @@ -409,6 +397,4 @@ DECLARE_DEVICE_TYPE(CXD8606BQ, cxd8606bq_device) DECLARE_DEVICE_TYPE(CXD8606CQ, cxd8606cq_device) -extern unsigned DasmPSXCPU(psxcpu_state *state, std::ostream &stream, uint32_t pc, const uint8_t *opram); - #endif // MAME_CPU_PSX_PSX_H diff --git a/src/devices/cpu/psx/psxdasm.cpp b/src/devices/cpu/psx/psxdasm.cpp index 2bb38b6d407..51a62f6dc1d 100644 --- a/src/devices/cpu/psx/psxdasm.cpp +++ b/src/devices/cpu/psx/psxdasm.cpp @@ -10,25 +10,22 @@ #include "gte.h" #include "psxdefs.h" +#include "psxdasm.h" -static char *make_signed_hex_str_16( uint32_t value ) +std::string psxcpu_disassembler::make_signed_hex_str_16( uint32_t value ) { - static char s_hex[ 20 ]; - if( value & 0x8000 ) { - sprintf( s_hex, "-$%x", -value & 0xffff ); + return util::string_format("-$%x", -value & 0xffff ); } else { - sprintf( s_hex, "$%x", value & 0xffff ); + return util::string_format("$%x", value & 0xffff ); } - - return s_hex; } -static const char *const s_cpugenreg[] = +const char *const psxcpu_disassembler::s_cpugenreg[] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", @@ -36,7 +33,7 @@ static const char *const s_cpugenreg[] = "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" }; -static const char *const s_cp0genreg[] = +const char *const psxcpu_disassembler::s_cp0genreg[] = { "!Index", "!Random", "!EntryLo", "BPC", "!Context", "BDA", "TAR", "DCIC", "BadA", "BDAM", "!EntryHi", "BPCM", "SR", "Cause", "EPC", "PRId", @@ -44,7 +41,7 @@ static const char *const s_cp0genreg[] = "cp0r24", "cp0r25", "cp0r26", "cp0r27", "cp0r28", "cp0r29", "cp0r30", "cp0r31" }; -static const char *const s_cp0ctlreg[] = +const char *const psxcpu_disassembler::s_cp0ctlreg[] = { "cp0cr0", "cp0cr1", "cp0cr2", "cp0cr3", "cp0cr4", "cp0cr5", "cp0cr6", "cp0cr7", "cp0cr8", "cp0cr9", "cp0cr10", "cp0cr11", "cp0cr12", "cp0cr13", "cp0cr14", "cp0cr15", @@ -52,7 +49,7 @@ static const char *const s_cp0ctlreg[] = "cp0cr24", "cp0cr25", "cp0cr26", "cp0cr27", "cp0cr28", "cp0cr29", "cp0cr30", "cp0cr31" }; -static const char *const s_cp1genreg[] = +const char *const psxcpu_disassembler::s_cp1genreg[] = { "cp1r0", "cp1r1", "cp1r2", "cp1r3", "cp1r4", "cp1r5", "cp1r6", "cp1r7", "cp1r8", "cp1r9", "cp1r10", "cp1r11", "cp1r12", "cp1r13", "cp1r14", "cp1r15", @@ -60,7 +57,7 @@ static const char *const s_cp1genreg[] = "cp1r23", "cp1r24", "cp1r25", "cp1r26", "cp1r27", "cp1r28", "cp1r29", "cp1r30" }; -static const char *const s_cp1ctlreg[] = +const char *const psxcpu_disassembler::s_cp1ctlreg[] = { "cp1cr0", "cp1cr1", "cp1cr2", "cp1cr3", "cp1cr4", "cp1cr5", "cp1cr6", "cp1cr7", "cp1cr8", "cp1cr9", "cp1cr10", "cp1cr11", "cp1cr12", "cp1cr13", "cp1cr14", "cp1cr15", @@ -68,7 +65,7 @@ static const char *const s_cp1ctlreg[] = "cp1cr24", "cp1cr25", "cp1cr26", "cp1cr27", "cp1cr28", "cp1cr29", "cp1cr30", "cp1cr31" }; -static const char *const s_cp2genreg[] = +const char *const psxcpu_disassembler::s_cp2genreg[] = { "vxy0", "vz0", "vxy1", "vz1", "vxy2", "vz2", "rgb", "otz", "ir0", "ir1", "ir2", "ir3", "sxy0", "sxy1", "sxy2", "sxyp", @@ -76,7 +73,7 @@ static const char *const s_cp2genreg[] = "mac0", "mac1", "mac2", "mac3", "irgb", "orgb", "lzcs", "lzcr" }; -static const char *const s_cp2ctlreg[] = +const char *const psxcpu_disassembler::s_cp2ctlreg[] = { "r11r12", "r13r21", "r22r23", "r31r32", "r33", "trx", "try", "trz", "l11l12", "l13l21", "l22l23", "l31l32", "l33", "rbk", "gbk", "bbk", @@ -84,7 +81,7 @@ static const char *const s_cp2ctlreg[] = "ofx", "ofy", "h", "dqa", "dqb", "zsf3", "zsf4", "flag" }; -static const char *const s_cp3genreg[] = +const char *const psxcpu_disassembler::s_cp3genreg[] = { "cp3r0", "cp3r1", "cp3r2", "cp3r3", "cp3r4", "cp3r5", "cp3r6", "cp3r7", "cp3r8", "cp3r9", "cp3r10", "cp3r11", "cp3r12", "cp3r13", "cp3r14", "cp3r15", @@ -92,7 +89,7 @@ static const char *const s_cp3genreg[] = "cp3r23", "cp3r24", "cp3r25", "cp3r26", "cp3r27", "cp3r28", "cp3r29", "cp3r30" }; -static const char *const s_cp3ctlreg[] = +const char *const psxcpu_disassembler::s_cp3ctlreg[] = { "cp3cr0", "cp3cr1", "cp3cr2", "cp3cr3", "cp3cr4", "cp3cr5", "cp3cr6", "cp3cr7", "cp3cr8", "cp3cr9", "cp3cr10", "cp3cr11", "cp3cr12", "cp3cr13", "cp3cr14", "cp3cr15", @@ -100,101 +97,96 @@ static const char *const s_cp3ctlreg[] = "cp3cr24", "cp3cr25", "cp3cr26", "cp3cr27", "cp3cr28", "cp3cr29", "cp3cr30", "cp3cr31" }; -static const char *const s_gtesf[] = +const char *const psxcpu_disassembler::s_gtesf[] = { " sf=0", " sf=12" }; -static const char *const s_gtemx[] = +const char *const psxcpu_disassembler::s_gtemx[] = { "rm", "lm", "cm", "0" }; -static const char *const s_gtev[] = +const char *const psxcpu_disassembler::s_gtev[] = { "v0", "v1", "v2", "ir" }; -static const char *const s_gtecv[] = +const char *const psxcpu_disassembler::s_gtecv[] = { "tr", "bk", "fc", "0" }; -static const char *const s_gtelm[] = +const char *const psxcpu_disassembler::s_gtelm[] = { " lm=s16", " lm=u15" }; -static char *effective_address( psxcpu_state *state, uint32_t pc, uint32_t op ) +std::string psxcpu_disassembler::effective_address( uint32_t pc, uint32_t op ) { - static char s_address[ 30 ]; - - if( state != nullptr && state->pc() == pc ) + if( m_config && m_config->pc() == pc ) { - sprintf( s_address, "%s(%s) ; 0x%08x", make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ], - (uint32_t)( state->r( INS_RS( op ) ) + (int16_t)INS_IMMEDIATE( op ) ) ); - return s_address; + return util::string_format("%s(%s) ; 0x%08x", make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ], + (uint32_t)( m_config->r( INS_RS( op ) ) + (int16_t)INS_IMMEDIATE( op ) ) ); } - sprintf( s_address, "%s(%s)", make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] ); - return s_address; + return util::string_format("%s(%s)", make_signed_hex_str_16( INS_IMMEDIATE( op ) ), s_cpugenreg[ INS_RS( op ) ] ); } -static uint32_t relative_address( psxcpu_state *state, uint32_t pc, uint32_t op ) +uint32_t psxcpu_disassembler::relative_address( uint32_t pc, uint32_t op ) { uint32_t nextpc = pc + 4; - if( state != nullptr && state->pc() == pc && state->delayr() == PSXCPU_DELAYR_PC ) + if( m_config && m_config->pc() == pc && m_config->delayr() == PSXCPU_DELAYR_PC ) { - nextpc = state->delayv(); + nextpc = m_config->delayv(); } return nextpc + ( PSXCPU_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ); } -static uint32_t jump_address( psxcpu_state *state, uint32_t pc, uint32_t op ) +uint32_t psxcpu_disassembler::jump_address( uint32_t pc, uint32_t op ) { uint32_t nextpc = pc + 4; - if( state != nullptr && state->pc() == pc && state->delayr() == PSXCPU_DELAYR_PC ) + if( m_config && m_config->pc() == pc && m_config->delayr() == PSXCPU_DELAYR_PC ) { - nextpc = state->delayv(); + nextpc = m_config->delayv(); } return ( nextpc & 0xf0000000 ) + ( INS_TARGET( op ) << 2 ); } -static uint32_t fetch_op( const uint8_t *opram ) -{ - return ( opram[ 3 ] << 24 ) | ( opram[ 2 ] << 16 ) | ( opram[ 1 ] << 8 ) | ( opram[ 0 ] << 0 ); -} - -static char *upper_address( uint32_t op, const uint8_t *opram ) +std::string psxcpu_disassembler::upper_address( uint32_t op, offs_t pos, const data_buffer &opcodes ) { - static char s_address[ 20 ]; - uint32_t nextop = fetch_op( opram ); + uint32_t nextop = opcodes.r32( pos ); if( INS_OP( nextop ) == OP_ORI && INS_RT( op ) == INS_RS( nextop ) ) { - sprintf( s_address, "$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) | INS_IMMEDIATE( nextop ) ); + return util::string_format("$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) | INS_IMMEDIATE( nextop ) ); } else if( INS_OP( nextop ) == OP_ADDIU && INS_RT( op ) == INS_RS( nextop ) ) { - sprintf( s_address, "$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) + (int16_t) INS_IMMEDIATE( nextop ) ); + return util::string_format("$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) + (int16_t) INS_IMMEDIATE( nextop ) ); } else { - sprintf( s_address, "$%04x", INS_IMMEDIATE( op ) ); + return util::string_format("$%04x", INS_IMMEDIATE( op ) ); } +} + +psxcpu_disassembler::psxcpu_disassembler(config *conf) : m_config(conf) +{ +} - return s_address; +u32 psxcpu_disassembler::opcode_alignment() const +{ + return 4; } -unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, const uint8_t *opram ) +offs_t psxcpu_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t op; - const uint8_t *oldopram; uint32_t flags = 0; - - oldopram = opram; - op = fetch_op( opram ); - opram += 4; + offs_t pos = pc; + op = opcodes.r32( pos ); + pos += 4; std::streampos current_pos = stream.tellp(); @@ -233,20 +225,20 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con util::stream_format( stream, "jr %s", s_cpugenreg[ INS_RS( op ) ] ); if( INS_RS( op ) == 31 ) { - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } break; case FUNCT_JALR: util::stream_format( stream, "jalr %s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ] ); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); + flags = STEP_OVER | step_over_extra( 1 ); break; case FUNCT_SYSCALL: util::stream_format( stream, "syscall $%05x", INS_CODE( op ) ); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case FUNCT_BREAK: util::stream_format( stream, "break $%05x", INS_CODE( op ) ); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case FUNCT_MFHI: util::stream_format( stream, "mfhi %s", s_cpugenreg[ INS_RD( op ) ] ); @@ -310,45 +302,45 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con case RT_BLTZ: if( INS_RT( op ) == RT_BLTZAL ) { - util::stream_format( stream, "bltzal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); + util::stream_format( stream, "bltzal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( pc, op ) ); + flags = STEP_OVER | step_over_extra( 1 ); } else { - util::stream_format( stream, "bltz %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "bltz %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( pc, op ) ); } break; case RT_BGEZ: if( INS_RT( op ) == RT_BGEZAL ) { - util::stream_format( stream, "bgezal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); + util::stream_format( stream, "bgezal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( pc, op ) ); + flags = STEP_OVER | step_over_extra( 1 ); } else { - util::stream_format( stream, "bgez %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "bgez %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( pc, op ) ); } break; } break; case OP_J: - util::stream_format( stream, "j $%08x", jump_address( state, pc, op ) ); + util::stream_format( stream, "j $%08x", jump_address( pc, op ) ); break; case OP_JAL: - util::stream_format( stream, "jal $%08x", jump_address( state, pc, op ) ); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); + util::stream_format( stream, "jal $%08x", jump_address( pc, op ) ); + flags = STEP_OVER | step_over_extra( 1 ); break; case OP_BEQ: - util::stream_format( stream, "beq %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "beq %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( pc, op ) ); break; case OP_BNE: - util::stream_format( stream, "bne %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "bne %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( pc, op ) ); break; case OP_BLEZ: - util::stream_format( stream, "blez %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "blez %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( pc, op ) ); break; case OP_BGTZ: - util::stream_format( stream, "bgtz %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); + util::stream_format( stream, "bgtz %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( pc, op ) ); break; case OP_ADDI: util::stream_format( stream, "addi %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); @@ -372,7 +364,7 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con util::stream_format( stream, "xori %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) ); break; case OP_LUI: - util::stream_format( stream, "lui %s,%s", s_cpugenreg[ INS_RT( op ) ], upper_address( op, opram ) ); + util::stream_format( stream, "lui %s,%s", s_cpugenreg[ INS_RT( op ) ], upper_address( op, pos, opcodes ) ); break; case OP_COP0: switch( INS_RS( op ) ) @@ -394,10 +386,10 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con switch( INS_BC( op ) ) { case BC_BCF: - util::stream_format( stream, "bc0f $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc0f $%08x", relative_address( pc, op ) ); break; case BC_BCT: - util::stream_format( stream, "bc0t $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc0t $%08x", relative_address( pc, op ) ); break; } break; @@ -451,10 +443,10 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con switch( INS_BC( op ) ) { case BC_BCF: - util::stream_format( stream, "bc1f $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc1f $%08x", relative_address( pc, op ) ); break; case BC_BCT: - util::stream_format( stream, "bc1t $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc1t $%08x", relative_address( pc, op ) ); break; } break; @@ -488,10 +480,10 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con switch( INS_BC( op ) ) { case BC_BCF: - util::stream_format( stream, "bc2f $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc2f $%08x", relative_address( pc, op ) ); break; case BC_BCT: - util::stream_format( stream, "bc2t $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc2t $%08x", relative_address( pc, op ) ); break; } break; @@ -598,10 +590,10 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con switch( INS_BC( op ) ) { case BC_BCF: - util::stream_format( stream, "bc3f $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc3f $%08x", relative_address( pc, op ) ); break; case BC_BCT: - util::stream_format( stream, "bc3t $%08x", relative_address( state, pc, op ) ); + util::stream_format( stream, "bc3t $%08x", relative_address( pc, op ) ); break; } break; @@ -616,64 +608,64 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con } break; case OP_LB: - util::stream_format( stream, "lb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LH: - util::stream_format( stream, "lh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWL: - util::stream_format( stream, "lwl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LW: - util::stream_format( stream, "lw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LBU: - util::stream_format( stream, "lbu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lbu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LHU: - util::stream_format( stream, "lhu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lhu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWR: - util::stream_format( stream, "lwr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SB: - util::stream_format( stream, "sb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "sb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SH: - util::stream_format( stream, "sh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "sh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWL: - util::stream_format( stream, "swl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SW: - util::stream_format( stream, "sw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "sw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWR: - util::stream_format( stream, "swr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWC0: - util::stream_format( stream, "lwc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWC1: - util::stream_format( stream, "lwc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWC2: - util::stream_format( stream, "lwc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_LWC3: - util::stream_format( stream, "lwc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "lwc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWC0: - util::stream_format( stream, "swc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWC1: - util::stream_format( stream, "swc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWC2: - util::stream_format( stream, "swc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; case OP_SWC3: - util::stream_format( stream, "swc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); + util::stream_format( stream, "swc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( pc, op ) ); break; } @@ -683,11 +675,5 @@ unsigned DasmPSXCPU( psxcpu_state *state, std::ostream &stream, uint32_t pc, con util::stream_format(stream, "dw $%08x", op); } - return ( opram - oldopram ) | flags | DASMFLAG_SUPPORTED; -} - - -CPU_DISASSEMBLE( psxcpu_generic ) -{ - return DasmPSXCPU( nullptr, stream, pc, opram ); + return ( pos - pc ) | flags | SUPPORTED; } diff --git a/src/devices/cpu/psx/psxdasm.h b/src/devices/cpu/psx/psxdasm.h new file mode 100644 index 00000000000..d3a6199616e --- /dev/null +++ b/src/devices/cpu/psx/psxdasm.h @@ -0,0 +1,56 @@ +// license:BSD-3-Clause +// copyright-holders:smf +/* + * PSXCPU disassembler for the MAME project written by smf + * + */ + +#ifndef MAME_CPU_PSX_PSXDASM_H +#define MAME_CPU_PSX_PSXDASM_H + +#pragma once + +class psxcpu_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + + virtual uint32_t pc() = 0; + virtual uint32_t delayr() = 0; + virtual uint32_t delayv() = 0; + virtual uint32_t r(int i) = 0; + }; + + psxcpu_disassembler(config *conf = nullptr); + virtual ~psxcpu_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const s_cpugenreg[]; + static const char *const s_cp0genreg[]; + static const char *const s_cp0ctlreg[]; + static const char *const s_cp1genreg[]; + static const char *const s_cp1ctlreg[]; + static const char *const s_cp2genreg[]; + static const char *const s_cp2ctlreg[]; + static const char *const s_cp3genreg[]; + static const char *const s_cp3ctlreg[]; + static const char *const s_gtesf[]; + static const char *const s_gtemx[]; + static const char *const s_gtev[]; + static const char *const s_gtecv[]; + static const char *const s_gtelm[]; + + std::string make_signed_hex_str_16( uint32_t value ); + std::string effective_address( uint32_t pc, uint32_t op ); + uint32_t relative_address( uint32_t pc, uint32_t op ); + uint32_t jump_address( uint32_t pc, uint32_t op ); + std::string upper_address( uint32_t op, offs_t pos, const data_buffer &opcodes ); + + config *m_config; +}; + +#endif diff --git a/src/devices/cpu/rsp/rsp.cpp b/src/devices/cpu/rsp/rsp.cpp index 6565fa6924d..51e880d53d9 100644 --- a/src/devices/cpu/rsp/rsp.cpp +++ b/src/devices/cpu/rsp/rsp.cpp @@ -17,6 +17,7 @@ #include "rspdefs.h" +#include "rsp_dasm.h" DEFINE_DEVICE_TYPE(RSP, rsp_device, "rsp", "RSP") @@ -150,10 +151,9 @@ device_memory_interface::space_config_vector rsp_device::memory_space_config() c }; } -offs_t rsp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *rsp_device::create_disassembler() { - extern CPU_DISASSEMBLE( rsp ); - return CPU_DISASSEMBLE_NAME( rsp )(this, stream, pc, oprom, opram, options); + return new rsp_disassembler; } void rsp_device::rsp_add_imem(uint32_t *base) @@ -319,10 +319,10 @@ void rsp_device::unimplemented_opcode(uint32_t op) { if ((machine().debug_flags & DEBUG_FLAG_ENABLED) != 0) { - util::ovectorstream string; - rsp_dasm_one(string, m_ppc, op); - string.put('\0'); - osd_printf_debug("%08X: %s\n", m_ppc, &string.vec()[0]); + std::ostringstream string; + rsp_disassembler rspd; + rspd.dasm_one(string, m_ppc, op); + osd_printf_debug("%08X: %s\n", m_ppc, string.str().c_str()); } #if SAVE_DISASM @@ -378,7 +378,7 @@ void rsp_device::device_start() m_exec_output = fopen("rsp_execute.txt", "wt"); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); resolve_cb(); if (m_isdrc) @@ -747,13 +747,13 @@ void rsp_device::execute_run() int i, l; static uint32_t prev_regs[32]; - util::ovectorstream string; - rsp_dasm_one(string, m_ppc, op); - string.put('\0'); + rsp_disassembler rspd; + std::ostringstream string; + rspd.dasm_one(string, m_ppc, op); - fprintf(m_exec_output, "%08X: %s", m_ppc, &string.vec()[0]); + fprintf(m_exec_output, "%08X: %s", m_ppc, string.str().c_str()); - l = string.vec().size() - 1; + l = string.str().size(); if (l < 36) { for (i=l; i < 36; i++) diff --git a/src/devices/cpu/rsp/rsp.h b/src/devices/cpu/rsp/rsp.h index cf1a7019f92..5f7b9ccb001 100644 --- a/src/devices/cpu/rsp/rsp.h +++ b/src/devices/cpu/rsp/rsp.h @@ -160,9 +160,7 @@ protected: 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; + virtual util::disasm_interface *create_disassembler() override; void unimplemented_opcode(uint32_t op); @@ -238,7 +236,7 @@ private: address_space *m_program; protected: - direct_read_data *m_direct; + direct_read_data<0> *m_direct; private: std::unique_ptr<rsp_cop2> m_cop2; @@ -299,7 +297,4 @@ private: DECLARE_DEVICE_TYPE(RSP, rsp_device) -extern offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op); - - #endif // MAME_CPU_RSP_RSP_H diff --git a/src/devices/cpu/rsp/rsp_dasm.cpp b/src/devices/cpu/rsp/rsp_dasm.cpp index 1222c0023a4..dec44596d45 100644 --- a/src/devices/cpu/rsp/rsp_dasm.cpp +++ b/src/devices/cpu/rsp/rsp_dasm.cpp @@ -7,8 +7,9 @@ */ #include "emu.h" +#include "rsp_dasm.h" -/*static const char *const reg[32] = +/*const char *const rsp_disassembler::reg[32] = { "0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", @@ -17,7 +18,7 @@ }; */ -static const char *const reg[32] = +const char *const rsp_disassembler::reg[32] = { "$0", "$at", "$v0", "$v1", "$a0", "$a1", "$a2", "$a3", "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", @@ -25,7 +26,7 @@ static const char *const reg[32] = "$t8", "$t9", "$k0", "$k1", "$gp", "$sp", "$fp", "$ra" }; -static const char *const vreg[32] = +const char *const rsp_disassembler::vreg[32] = { " v0", " v1", " v2", " v3", " v4", " v5", " v6", " v7", " v8", " v9", "v10", "v11", "v12", "v13", "v14", "v15", @@ -33,7 +34,7 @@ static const char *const vreg[32] = "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31" }; -static const char *const cop0_regs[32] = +const char *const rsp_disassembler::cop0_regs[32] = { "SP_MEM_ADDR", "SP_DRAM_ADDR", "SP_RD_LEN", "SP_WR_LEN", "SP_STATUS", "SP_DMA_FULL", "SP_DMA_BUSY", "SP_SEMAPHORE", @@ -45,36 +46,34 @@ static const char *const cop0_regs[32] = "???", "???", "???", "???" }; -static const char *const element[16] = +const char *const rsp_disassembler::element[16] = { "", "[???]", "[00224466]", "[11335577]", "[00004444]", "[11115555]", "[22226666]", "[33337777]", "[00000000]", "[11111111]", "[22222222]", "[33333333]", "[44444444]", "[55555555]", "[66666666]", "[77777777]" }; -static const char *const element2[16] = +const char *const rsp_disassembler::element2[16] = { "01234567", "????????", "00224466", "11335577", "00004444", "11115555", "22226666", "33337777", "00000000", "11111111", "22222222", "33333333", "44444444", "55555555", "66666666", "77777777" }; -static inline char *signed_imm16(uint32_t op) +inline std::string rsp_disassembler::signed_imm16(uint32_t op) { - static char temp[10]; int16_t value = op & 0xffff; if (value < 0) { - sprintf(temp, "-$%04x", -value); + return util::string_format("-$%04x", -value); } else { - sprintf(temp, "$%04x", value); + return util::string_format("$%04x", value); } - return temp; } -static void disasm_cop0(std::ostream &stream, uint32_t op) +void rsp_disassembler::disasm_cop0(std::ostream &stream, uint32_t op) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -88,7 +87,7 @@ static void disasm_cop0(std::ostream &stream, uint32_t op) } } -static void disasm_cop2(std::ostream &stream, uint32_t op) +void rsp_disassembler::disasm_cop2(std::ostream &stream, uint32_t op) { int rt = (op >> 16) & 31; int rd = (op >> 11) & 31; @@ -175,7 +174,7 @@ static void disasm_cop2(std::ostream &stream, uint32_t op) } } -static void disasm_lwc2(std::ostream &stream, uint32_t op) +void rsp_disassembler::disasm_lwc2(std::ostream &stream, uint32_t op) { int dest = (op >> 16) & 0x1f; int base = (op >> 21) & 0x1f; @@ -202,7 +201,7 @@ static void disasm_lwc2(std::ostream &stream, uint32_t op) } } -static void disasm_swc2(std::ostream &stream, uint32_t op) +void rsp_disassembler::disasm_swc2(std::ostream &stream, uint32_t op) { int dest = (op >> 16) & 0x1f; int base = (op >> 21) & 0x1f; @@ -229,7 +228,12 @@ static void disasm_swc2(std::ostream &stream, uint32_t op) } } -offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) +u32 rsp_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t rsp_disassembler::dasm_one(std::ostream &stream, offs_t pc, u32 op) { int rs = (op >> 21) & 31; int rt = (op >> 16) & 31; @@ -260,7 +264,7 @@ offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) case 0x04: util::stream_format(stream, "sllv %s, %s, %s", reg[rd], reg[rt], reg[rs]); break; case 0x06: util::stream_format(stream, "srlv %s, %s, %s", reg[rd], reg[rt], reg[rs]); break; case 0x07: util::stream_format(stream, "srav %s, %s, %s", reg[rd], reg[rt], reg[rs]); break; - case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = DASMFLAG_STEP_OUT; break; + case 0x08: util::stream_format(stream, "jr %s", reg[rs]); if (rs == 31) flags = STEP_OUT; break; case 0x09: { if (rd == 31) @@ -271,10 +275,10 @@ offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) { util::stream_format(stream, "jalr %s, %s", reg[rs], reg[rd]); } - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; } - case 0x0d: util::stream_format(stream, "break"); flags = DASMFLAG_STEP_OVER; break; + case 0x0d: util::stream_format(stream, "break"); flags = STEP_OVER; break; case 0x20: util::stream_format(stream, "add %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x21: util::stream_format(stream, "addu %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; case 0x22: util::stream_format(stream, "sub %s, %s, %s", reg[rd], reg[rs], reg[rt]); break; @@ -338,14 +342,11 @@ offs_t rsp_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) default: util::stream_format(stream, "???"); break; } - return 4 | flags | DASMFLAG_SUPPORTED; + return 4 | flags | SUPPORTED; } -/*****************************************************************************/ - -CPU_DISASSEMBLE( rsp ) +offs_t rsp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t op = *(uint32_t *)opram; - op = big_endianize_int32(op); - return rsp_dasm_one(stream, pc, op); + u32 op = opcodes.r32(pc); + return dasm_one(stream, pc, op); } diff --git a/src/devices/cpu/rsp/rsp_dasm.h b/src/devices/cpu/rsp/rsp_dasm.h new file mode 100644 index 00000000000..72dcdaae5e6 --- /dev/null +++ b/src/devices/cpu/rsp/rsp_dasm.h @@ -0,0 +1,38 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde, Ryan Holtz +/* + Nintendo/SGI RSP Disassembler + + Written by Ville Linde +*/ + +#ifndef MAME_CPU_RSP_RSP_DASM_H +#define MAME_CPU_RSP_RSP_DASM_H + +#pragma once + +class rsp_disassembler : public util::disasm_interface +{ +public: + rsp_disassembler() = default; + virtual ~rsp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + offs_t dasm_one(std::ostream &stream, offs_t pc, u32 op); + +private: + static const char *const reg[32]; + static const char *const vreg[32]; + static const char *const cop0_regs[32]; + static const char *const element[16]; + static const char *const element2[16]; + inline std::string signed_imm16(uint32_t op); + void disasm_cop0(std::ostream &stream, uint32_t op); + void disasm_cop2(std::ostream &stream, uint32_t op); + void disasm_lwc2(std::ostream &stream, uint32_t op); + void disasm_swc2(std::ostream &stream, uint32_t op); +}; + +#endif diff --git a/src/devices/cpu/rsp/rspcp2d.cpp b/src/devices/cpu/rsp/rspcp2d.cpp index 7152d6cbe59..47972b54747 100644 --- a/src/devices/cpu/rsp/rspcp2d.cpp +++ b/src/devices/cpu/rsp/rspcp2d.cpp @@ -13,6 +13,7 @@ #include "rspcp2d.h" #include "rsp.h" +#include "rsp_dasm.h" #include "rspcp2.h" #include "cpu/drcfe.h" @@ -138,8 +139,9 @@ void rsp_cop2_drc::cfunc_unimplemented_opcode() const uint32_t ppc = m_rsp.m_ppc; if ((m_machine.debug_flags & DEBUG_FLAG_ENABLED) != 0) { + rsp_disassembler rspd; std::ostringstream stream; - rsp_dasm_one(stream, ppc, m_rspcop2_state->op); + rspd.dasm_one(stream, ppc, m_rspcop2_state->op); const std::string stream_string = stream.str(); osd_printf_debug("%08X: %s\n", ppc, stream_string.c_str()); } diff --git a/src/devices/cpu/rsp/rspdrc.cpp b/src/devices/cpu/rsp/rspdrc.cpp index cdc10338571..3c7a1f2efab 100644 --- a/src/devices/cpu/rsp/rspdrc.cpp +++ b/src/devices/cpu/rsp/rspdrc.cpp @@ -20,6 +20,7 @@ #include "emu.h" #include "rsp.h" +#include "rsp_dasm.h" #include "rspfe.h" #include "rspcp2.h" @@ -34,8 +35,6 @@ using namespace uml; -CPU_DISASSEMBLE( rsp ); - /*************************************************************************** CONSTANTS ***************************************************************************/ @@ -1288,9 +1287,9 @@ void rsp_device::log_add_disasm_comment(drcuml_block *block, uint32_t pc, uint32 { if (m_drcuml->logging()) { - util::ovectorstream buffer; - rsp_dasm_one(buffer, pc, op); - buffer.put('\0'); - block->append_comment("%08X: %s", pc, &buffer.vec()[0]); // comment + rsp_disassembler rspd; + std::ostringstream buffer; + rspd.dasm_one(buffer, pc, op); + block->append_comment("%08X: %s", pc, buffer.str()); // comment } } diff --git a/src/devices/cpu/s2650/2650dasm.cpp b/src/devices/cpu/s2650/2650dasm.cpp index 872de095a3b..38f325e02c1 100644 --- a/src/devices/cpu/s2650/2650dasm.cpp +++ b/src/devices/cpu/s2650/2650dasm.cpp @@ -10,859 +10,543 @@ **************************************************************************/ #include "emu.h" - -static const uint8_t *rambase; -static offs_t pcbase; - -#define readarg(A) (rambase[(A) - pcbase]) - -/* Set this to 1 to disassemble using Z80 style mnemonics */ -#define HJB 0 - -/* Set this to 1 to give names to condition codes and flag bits */ -#define MNEMO 1 +#include "2650dasm.h" /* handy table to build relative offsets from HR (holding register) */ -static const int rel[0x100] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, +const int s2650_disassembler::rel[0x100] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49, -48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33, -32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17, -16,-15,-14,-13,-12,-11,-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -64,-63,-62,-61,-60,-59,-58,-57,-56,-55,-54,-53,-52,-51,-50,-49, -48,-47,-46,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35,-34,-33, -32,-31,-30,-29,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17, -16,-15,-14,-13,-12,-11,-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, }; -typedef char* (*callback) (int addr); -static callback find_symbol = nullptr; - -static char *SYM(int addr) +std::string s2650_disassembler::SYM(int addr) { - static char buff[8+1]; - char * s = nullptr; - - if (find_symbol) s = (*find_symbol)(addr); - if (s) return s; - - sprintf(buff, "$%04x", addr); - return buff; + return util::string_format("$%04x", addr); } /* format an immediate */ -static char *IMM(int pc) +std::string s2650_disassembler::IMM(offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - - sprintf(buff, "$%02x", readarg(pc)); - return buff; + return util::string_format("$%02x", params.r8(pc)); } -#if MNEMO -static const char cc[4] = { 'z', 'p', 'm', 'a' }; +const char s2650_disassembler::cc[4] = { 'z', 'p', 'm', 'a' }; + +void s2650_disassembler::add(std::string &buf, std::string str) +{ + if(!buf.empty()) + buf += '+'; + buf += str; +} /* format an immediate for PSL */ -static char *IMM_PSL(int pc) +std::string s2650_disassembler::IMM_PSL(offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - char *p = buff; - int v = readarg(pc); + u8 v = params.r8(pc); if (v == 0xff) { - p += sprintf(p, "all"); + return "all"; + } else { + std::string buff; switch (v & 0xc0) { - case 0x40: p += sprintf(p, "p+"); break; - case 0x80: p += sprintf(p, "m+"); break; - case 0xc0: p += sprintf(p, "cc+"); break; + case 0x40: add(buff, "p"); break; + case 0x80: add(buff, "m"); break; + case 0xc0: add(buff, "cc"); break; } if (v & 0x20) /* inter digit carry */ - p += sprintf(p, "idc+"); + add(buff, "idc"); if (v & 0x10) /* register select */ - p += sprintf(p, "rs+"); + add(buff, "rs"); if (v & 0x08) /* with carry */ - p += sprintf(p, "wc+"); + add(buff, "wc"); if (v & 0x04) /* overflow */ - p += sprintf(p, "ovf+"); + add(buff, "ovf"); if (v & 0x02) /* 2's complement comparisons */ - p += sprintf(p, "com+"); + add(buff, "com"); if (v & 0x01) /* carry */ - p += sprintf(p, "c+"); - if (p > buff) - *--p = '\0'; + add(buff, "c"); + return buff; } - return buff; } /* format an immediate for PSU (processor status upper) */ -static char *IMM_PSU(int pc) +std::string s2650_disassembler::IMM_PSU(offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - char *p = buff; - int v = readarg(pc); + int v = params.r8(pc); if (v == 0xff) { - p += sprintf(p, "all"); + return "all"; } else { + std::string buff; if (v & 0x80) /* sense input */ - p += sprintf(p, "si+"); + add(buff, "si"); if (v & 0x40) /* flag output */ - p += sprintf(p, "fo+"); + add(buff, "fo"); if (v & 0x20) /* interrupt inhibit */ - p += sprintf(p, "ii+"); + add(buff, "ii"); if (v & 0x10) /* unused bit 4 */ - p += sprintf(p, "4+"); + add(buff, "4"); if (v & 0x08) /* unused bit 3 */ - p += sprintf(p, "3+"); + add(buff, "3"); if (v & 0x04) /* stack pointer bit 2 */ - p += sprintf(p, "sp2+"); + add(buff, "sp2"); if (v & 0x02) /* stack pointer bit 1 */ - p += sprintf(p, "sp1+"); + add(buff, "sp1"); if (v & 0x01) /* stack pointer bit 0 */ - p += sprintf(p, "sp0+"); - if (p > buff) - *--p = '\0'; + add(buff, "sp0"); + return buff; } - return buff; } -#else -static const char cc[4] = { '0', '1', '2', '3' }; -#define IMM_PSL IMM -#define IMM_PSU IMM -#endif /* format an relative address */ -static char *REL(int pc) +std::string s2650_disassembler::REL(offs_t pc, const data_buffer ¶ms) { -static char buff[32]; -int o = readarg(pc); - sprintf(buff, "%s%s", (o&0x80)?"*":"", SYM((pc&0x6000)+((pc+1+rel[o])&0x1fff))); - return buff; + int o = params.r8(pc); + return util::string_format("%s%s", (o&0x80)?"*":"", SYM((pc&0x6000)+((pc+1+rel[o])&0x1fff))); } /* format an relative address (implicit page 0) */ -static char *REL0(int pc) +std::string s2650_disassembler::REL0(offs_t pc, const data_buffer ¶ms) { -static char buff[32]; -int o = readarg(pc); - sprintf(buff, "%s%s", (o&0x80)?"*":"", SYM((rel[o]) & 0x1fff)); - return buff; + int o = params.r8(pc); + return util::string_format("%s%s", (o&0x80)?"*":"", SYM((rel[o]) & 0x1fff)); } /* format a destination register and an absolute address */ -static char *ABS(int load, int r, int pc) +std::string s2650_disassembler::ABS(int load, int r, offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - int h = readarg(pc); - int l = readarg((pc&0x6000)+((pc+1)&0x1fff)); + int h = params.r8(pc); + int l = params.r8((pc&0x6000)+((pc+1)&0x1fff)); int a = (pc & 0x6000) + ((h & 0x1f) << 8) + l; -#if HJB - if (load) { - switch (h >> 5) { - case 0: sprintf(buff, "r%d,(%s)", r, SYM(a)); break; - case 1: sprintf(buff, "r0,(%s,r%d++)", SYM(a), r); break; - case 2: sprintf(buff, "r0,(%s,r%d--)", SYM(a), r); break; - case 3: sprintf(buff, "r0,(%s,r%d)", SYM(a), r); break; - case 4: sprintf(buff, "r%d,*(%s)", r, SYM(a)); break; - case 5: sprintf(buff, "r0,*(%s,r%d++)", SYM(a), r); break; - case 6: sprintf(buff, "r0,*(%s,r%d--)", SYM(a), r); break; - case 7: sprintf(buff, "r0,*(%s,r%d)", SYM(a), r); break; + if (m_config->get_z80_mnemonics_mode()) { + if (load) { + switch (h >> 5) { + case 0: return util::string_format("r%d,(%s)", r, SYM(a)); + case 1: return util::string_format("r0,(%s,r%d++)", SYM(a), r); + case 2: return util::string_format("r0,(%s,r%d--)", SYM(a), r); + case 3: return util::string_format("r0,(%s,r%d)", SYM(a), r); + case 4: return util::string_format("r%d,*(%s)", r, SYM(a)); + case 5: return util::string_format("r0,*(%s,r%d++)", SYM(a), r); + case 6: return util::string_format("r0,*(%s,r%d--)", SYM(a), r); + case 7: return util::string_format("r0,*(%s,r%d)", SYM(a), r); + } + } else { + switch (h >> 5) { + case 0: return util::string_format("(%s),r%d", SYM(a), r); + case 1: return util::string_format("(%s,r%d++),r0", SYM(a), r); + case 2: return util::string_format("(%s,r%d--),r0", SYM(a), r); + case 3: return util::string_format("(%s,r%d),r0", SYM(a), r); + case 4: return util::string_format("*(%s),r%d", SYM(a), r); + case 5: return util::string_format("*(%s,r%d++),r0", SYM(a), r); + case 6: return util::string_format("*(%s,r%d--),r0", SYM(a), r); + case 7: return util::string_format("*(%s,r%d),r0", SYM(a), r); + } } } else { switch (h >> 5) { - case 0: sprintf(buff, "(%s),r%d", SYM(a), r); break; - case 1: sprintf(buff, "(%s,r%d++),r0", SYM(a), r); break; - case 2: sprintf(buff, "(%s,r%d--),r0", SYM(a), r); break; - case 3: sprintf(buff, "(%s,r%d),r0", SYM(a), r); break; - case 4: sprintf(buff, "*(%s),r%d", SYM(a), r); break; - case 5: sprintf(buff, "*(%s,r%d++),r0", SYM(a), r); break; - case 6: sprintf(buff, "*(%s,r%d--),r0", SYM(a), r); break; - case 7: sprintf(buff, "*(%s,r%d),r0", SYM(a), r); break; + case 0: return util::string_format("%d %s", r, SYM(a)); + case 1: return util::string_format("0 %s,r%d+", SYM(a), r); + case 2: return util::string_format("0 %s,r%d-", SYM(a), r); + case 3: return util::string_format("0 %s,r%d", SYM(a), r); + case 4: return util::string_format("%d *%s", r, SYM(a)); + case 5: return util::string_format("0 *%s,r%d+", SYM(a), r); + case 6: return util::string_format("0 *%s,r%d-", SYM(a), r); + case 7: return util::string_format("0 *%s,r%d", SYM(a), r); } } -#else - switch (h >> 5) { - case 0: sprintf(buff, "%d %s", r, SYM(a)); break; - case 1: sprintf(buff, "0 %s,r%d+", SYM(a), r); break; - case 2: sprintf(buff, "0 %s,r%d-", SYM(a), r); break; - case 3: sprintf(buff, "0 %s,r%d", SYM(a), r); break; - case 4: sprintf(buff, "%d *%s", r, SYM(a)); break; - case 5: sprintf(buff, "0 *%s,r%d+", SYM(a), r); break; - case 6: sprintf(buff, "0 *%s,r%d-", SYM(a), r); break; - case 7: sprintf(buff, "0 *%s,r%d", SYM(a), r); break; - } -#endif - return buff; + return ""; } /* format an (branch) absolute address */ -static char *ADR(int pc) +std::string s2650_disassembler::ADR(offs_t pc, const data_buffer ¶ms) { - static char buff[32]; - int h = readarg(pc); - int l = readarg((pc&0x6000)+((pc+1)&0x1fff)); + int h = params.r8(pc); + int l = params.r8((pc&0x6000)+((pc+1)&0x1fff)); int a = ((h & 0x7f) << 8) + l; if (h & 0x80) - sprintf(buff, "*%s", SYM(a)); + return util::string_format("*%s", SYM(a)); else - sprintf(buff, "%s", SYM(a)); - return buff; + return util::string_format("%s", SYM(a)); +} + +s2650_disassembler::s2650_disassembler(config *conf) : m_config(conf) +{ } /* disassemble one instruction at PC into buff. return byte size of instr */ -CPU_DISASSEMBLE(s2650) +offs_t s2650_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; int PC = pc; - int op = oprom[0]; + int op = opcodes.r8(pc); int rv = op & 3; - rambase = opram; - pcbase = PC; + bool z80 = m_config->get_z80_mnemonics_mode(); pc += 1; switch (op) { case 0x00: case 0x01: case 0x02: case 0x03: -#if HJB - util::stream_format(stream, "ld r0,r%d", rv); -#else - util::stream_format(stream, "lodz,%d", rv); -#endif + util::stream_format(stream, z80 ? "ld r0,r%d" : "lodz,%d", rv); break; case 0x04: case 0x05: case 0x06: case 0x07: -#if HJB - util::stream_format(stream, "ld r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "lodi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "ld r%d,%s" : "lodi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x08: case 0x09: case 0x0a: case 0x0b: -#if HJB - util::stream_format(stream, "ld r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "lodr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "ld r%d,(%s)" : "lodr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x0c: case 0x0d: case 0x0e: case 0x0f: -#if HJB - util::stream_format(stream, "ld %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "loda,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "ld %s" : "loda,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x10: case 0x11: -#if HJB - util::stream_format(stream, "**** $%02X",op); -#else - util::stream_format(stream, "**** $%02X",op); -#endif + util::stream_format(stream, z80 ? "**** $%02X" : "**** $%02X",op); break; case 0x12: -#if HJB - util::stream_format(stream, "ld r0,psu"); -#else - util::stream_format(stream, "spsu"); -#endif + util::stream_format(stream, z80 ? "ld r0,psu" : "spsu"); break; case 0x13: -#if HJB - util::stream_format(stream, "ld r0,psl"); -#else - util::stream_format(stream, "spsl"); -#endif + util::stream_format(stream, z80 ? "ld r0,psl" : "spsl"); break; case 0x14: case 0x15: case 0x16: case 0x17: -#if HJB - if (rv == 3) - util::stream_format(stream, "ret"); - else - util::stream_format(stream, "ret %c", cc[rv]); -#else - util::stream_format(stream, "retc %c", cc[rv]); -#endif - flags = DASMFLAG_STEP_OUT; + if (z80) { + if (rv == 3) + util::stream_format(stream, "ret"); + else + util::stream_format(stream, "ret %c", cc[rv]); + } else + util::stream_format(stream, "retc %c", cc[rv]); + flags = STEP_OUT; break; case 0x18: case 0x19: case 0x1a: case 0x1b: -#if HJB - if (rv == 3) - util::stream_format(stream, "jr %s", REL(pc)); - else - util::stream_format(stream, "jr %c,%s", cc[rv], REL(pc)); -#else - util::stream_format(stream, "bctr,%c %s", cc[rv], REL(pc)); -#endif + if (z80) { + if (rv == 3) + util::stream_format(stream, "jr %s", REL(pc, params)); + else + util::stream_format(stream, "jr %c,%s", cc[rv], REL(pc, params)); + } else + util::stream_format(stream, "bctr,%c %s", cc[rv], REL(pc, params)); pc+=1; break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: -#if HJB - if (rv == 3) - util::stream_format(stream, "jp %s", ADR(pc)); - else - util::stream_format(stream, "jp %c,%s", cc[rv], ADR(pc)); -#else - util::stream_format(stream, "bcta,%c %s", cc[rv], ADR(pc)); -#endif + if (z80) { + if (rv == 3) + util::stream_format(stream, "jp %s", ADR(pc, params)); + else + util::stream_format(stream, "jp %c,%s", cc[rv], ADR(pc, params)); + } else + util::stream_format(stream, "bcta,%c %s", cc[rv], ADR(pc, params)); pc+=2; break; case 0x20: case 0x21: case 0x22: case 0x23: -#if HJB - util::stream_format(stream, "xor r0,r%d", rv); -#else - util::stream_format(stream, "eorz,%d", rv); -#endif + util::stream_format(stream, z80 ? "xor r0,r%d" : "eorz,%d", rv); break; case 0x24: case 0x25: case 0x26: case 0x27: -#if HJB - util::stream_format(stream, "xor r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "eori,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "xor r%d,%s" : "eori,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x28: case 0x29: case 0x2a: case 0x2b: -#if HJB - util::stream_format(stream, "xor r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "eorr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "xor r%d,(%s)" : "eorr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x2c: case 0x2d: case 0x2e: case 0x2f: -#if HJB - util::stream_format(stream, "xor %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "eora,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "xor %s" : "eora,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x30: case 0x31: case 0x32: case 0x33: -#if HJB - util::stream_format(stream, "in r%d,(ctrl)", rv); -#else - util::stream_format(stream, "redc,%d", rv); -#endif + util::stream_format(stream, z80 ? "in r%d,(ctrl)" : "redc,%d", rv); break; case 0x34: case 0x35: case 0x36: case 0x37: -#if HJB - if (rv == 3) - util::stream_format(stream, "iret"); - else - util::stream_format(stream, "iret %c", cc[rv]); -#else - util::stream_format(stream, "rete %c", cc[rv]); -#endif - flags = DASMFLAG_STEP_OUT; + if (z80) { + if (rv == 3) + util::stream_format(stream, "iret"); + else + util::stream_format(stream, "iret %c", cc[rv]); + } else + util::stream_format(stream, "rete %c", cc[rv]); + flags = STEP_OUT; break; case 0x38: case 0x39: case 0x3a: case 0x3b: -#if HJB - if (rv == 3) - util::stream_format(stream, "calr %s", REL(pc)); - else - util::stream_format(stream, "calr %c,%s", cc[rv], REL(pc)); -#else - util::stream_format(stream, "bstr,%c %s", cc[rv], REL(pc)); -#endif + if (z80) { + if (rv == 3) + util::stream_format(stream, "calr %s", REL(pc, params)); + else + util::stream_format(stream, "calr %c,%s", cc[rv], REL(pc, params)); + } else + util::stream_format(stream, "bstr,%c %s", cc[rv], REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x3c: case 0x3d: case 0x3e: case 0x3f: -#if HJB - if (rv == 3) - util::stream_format(stream, "call %s", ADR(pc)); - else - util::stream_format(stream, "call %c,%s", cc[rv], ADR(pc)); -#else - util::stream_format(stream, "bsta,%c %s", cc[rv], ADR(pc)); -#endif + if (z80) { + if (rv == 3) + util::stream_format(stream, "call %s", ADR(pc, params)); + else + util::stream_format(stream, "call %c,%s", cc[rv], ADR(pc, params)); + } else + util::stream_format(stream, "bsta,%c %s", cc[rv], ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x40: util::stream_format(stream, "halt"); break; case 0x41: case 0x42: case 0x43: -#if HJB - util::stream_format(stream, "and r0,r%d", rv); -#else - util::stream_format(stream, "andz,%d", rv); -#endif + util::stream_format(stream, z80 ? "and r0,r%d" : "andz,%d", rv); break; case 0x44: case 0x45: case 0x46: case 0x47: -#if HJB - util::stream_format(stream, "and r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "andi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "and r%d,%s" : "andi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x48: case 0x49: case 0x4a: case 0x4b: -#if HJB - util::stream_format(stream, "and r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "andr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "and r%d,(%s)" : "andr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x4c: case 0x4d: case 0x4e: case 0x4f: -#if HJB - util::stream_format(stream, "and %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "anda,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "and %s" : "anda,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x50: case 0x51: case 0x52: case 0x53: -#if HJB - util::stream_format(stream, "ror r%d", rv); -#else - util::stream_format(stream, "rrr,%d", rv); -#endif + util::stream_format(stream, z80 ? "ror r%d" : "rrr,%d", rv); break; case 0x54: case 0x55: case 0x56: case 0x57: -#if HJB - util::stream_format(stream, "in r%d,(%s)", rv, IMM(pc)); -#else - util::stream_format(stream, "rede,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "in r%d,(%s)" : "rede,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x58: case 0x59: case 0x5a: case 0x5b: -#if HJB - util::stream_format(stream, "jrnz r%d,%s", rv, REL(pc)); -#else - util::stream_format(stream, "brnr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "jrnz r%d,%s" : "brnr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x5c: case 0x5d: case 0x5e: case 0x5f: -#if HJB - util::stream_format(stream, "jpnz r%d,%s", rv, ADR(pc)); -#else - util::stream_format(stream, "brna,%d %s", rv, ADR(pc)); -#endif + util::stream_format(stream, z80 ? "jpnz r%d,%s" : "brna,%d %s", rv, ADR(pc, params)); pc+=2; break; case 0x60: case 0x61: case 0x62: case 0x63: -#if HJB - util::stream_format(stream, "or r0,r%d", rv); -#else - util::stream_format(stream, "iorz,%d", rv); -#endif + util::stream_format(stream, z80 ? "or r0,r%d" : "iorz,%d", rv); break; case 0x64: case 0x65: case 0x66: case 0x67: -#if HJB - util::stream_format(stream, "or r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "iori,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "or r%d,%s" : "iori,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x68: case 0x69: case 0x6a: case 0x6b: -#if HJB - util::stream_format(stream, "or r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "iorr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "or r%d,(%s)" : "iorr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x6c: case 0x6d: case 0x6e: case 0x6f: -#if HJB - util::stream_format(stream, "or %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "iora,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "or %s" : "iora,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x70: case 0x71: case 0x72: case 0x73: -#if HJB - util::stream_format(stream, "in r%d,(data)", rv); -#else - util::stream_format(stream, "redd,%d", rv); -#endif + util::stream_format(stream, z80 ? "in r%d,(data)" : "redd,%d", rv); break; case 0x74: -#if HJB - util::stream_format(stream, "res psu,%s", IMM_PSU(pc)); -#else - util::stream_format(stream, "cpsu %s", IMM_PSU(pc)); -#endif + util::stream_format(stream, z80 ? "res psu,%s" : "cpsu %s", IMM_PSU(pc, params)); pc+=1; break; case 0x75: -#if HJB - util::stream_format(stream, "res psl,%s", IMM_PSL(pc)); -#else - util::stream_format(stream, "cpsl %s", IMM_PSL(pc)); -#endif + util::stream_format(stream, z80 ? "res psl,%s" : "cpsl %s", IMM_PSL(pc, params)); pc+=1; break; case 0x76: -#if HJB - util::stream_format(stream, "set psu,%s", IMM_PSU(pc)); -#else - util::stream_format(stream, "ppsu %s", IMM_PSU(pc)); -#endif + util::stream_format(stream, z80 ? "set psu,%s" : "ppsu %s", IMM_PSU(pc, params)); pc+=1; break; case 0x77: -#if HJB - util::stream_format(stream, "set psl,%s", IMM_PSL(pc)); -#else - util::stream_format(stream, "ppsl %s", IMM_PSL(pc)); -#endif + util::stream_format(stream, z80 ? "set psl,%s" : "ppsl %s", IMM_PSL(pc, params)); pc+=1; break; case 0x78: case 0x79: case 0x7a: case 0x7b: -#if HJB - util::stream_format(stream, "call r%d-nz,%s", rv, REL(pc)); -#else - util::stream_format(stream, "bsnr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "call r%d-nz,%s" : "bsnr,%d %s", rv, REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x7c: case 0x7d: case 0x7e: case 0x7f: -#if HJB - util::stream_format(stream, "call r%d-nz,%s", rv, ADR(pc)); -#else - util::stream_format(stream, "bsna,%d %s", rv, ADR(pc)); -#endif + util::stream_format(stream, z80 ? "call r%d-nz,%s" : "bsna,%d %s", rv, ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x80: case 0x81: case 0x82: case 0x83: -#if HJB - util::stream_format(stream, "add r0,r%d", rv); -#else - util::stream_format(stream, "addz,%d", rv); -#endif + util::stream_format(stream, z80 ? "add r0,r%d" : "addz,%d", rv); break; case 0x84: case 0x85: case 0x86: case 0x87: -#if HJB - util::stream_format(stream, "add r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "addi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "add r%d,%s" : "addi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0x88: case 0x89: case 0x8a: case 0x8b: -#if HJB - util::stream_format(stream, "add r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "addr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "add r%d,(%s)" : "addr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0x8c: case 0x8d: case 0x8e: case 0x8f: -#if HJB - util::stream_format(stream, "add %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "adda,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "add %s" : "adda,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0x90: case 0x91: -#if HJB - util::stream_format(stream, "**** $%02X",op); -#else - util::stream_format(stream, "**** $%02X",op); -#endif + util::stream_format(stream, z80 ? "**** $%02X" : "**** $%02X",op); break; case 0x92: -#if HJB - util::stream_format(stream, "ld psu,r0"); -#else - util::stream_format(stream, "lpsu"); -#endif + util::stream_format(stream, z80 ? "ld psu,r0" : "lpsu"); break; case 0x93: -#if HJB - util::stream_format(stream, "ld psl,r0"); -#else - util::stream_format(stream, "lpsl"); -#endif + util::stream_format(stream, z80 ? "ld psl,r0" : "lpsl"); break; case 0x94: case 0x95: case 0x96: case 0x97: -#if HJB - util::stream_format(stream, "daa r%d", rv); -#else - util::stream_format(stream, "dar,%d", rv); -#endif + util::stream_format(stream, z80 ? "daa r%d" : "dar,%d", rv); break; case 0x98: case 0x99: case 0x9a: -#if HJB - util::stream_format(stream, "jr n%c,%s", cc[rv], REL(pc)); -#else - util::stream_format(stream, "bcfr,%c %s", cc[rv], REL(pc)); -#endif + util::stream_format(stream, z80 ? "jr n%c,%s" : "bcfr,%c %s", cc[rv], REL(pc, params)); pc+=1; break; case 0x9b: -#if HJB - util::stream_format(stream, "jr0 %s", REL0(pc)); -#else - util::stream_format(stream, "zbrr %s", REL0(pc)); -#endif + util::stream_format(stream, z80 ? "jr0 %s" : "zbrr %s", REL0(pc, params)); pc+=1; break; case 0x9c: case 0x9d: case 0x9e: -#if HJB - util::stream_format(stream, "jp n%c,%s", cc[rv], ADR(pc)); -#else - util::stream_format(stream, "bcfa,%c %s", cc[rv], ADR(pc)); -#endif + util::stream_format(stream, z80 ? "jp n%c,%s" : "bcfa,%c %s", cc[rv], ADR(pc, params)); pc+=2; break; case 0x9f: -#if HJB - util::stream_format(stream, "jp %s+r3", ADR(pc)); -#else - util::stream_format(stream, "bxa %s", ADR(pc)); -#endif + util::stream_format(stream, z80 ? "jp %s+r3" : "bxa %s", ADR(pc, params)); pc+=2; break; case 0xa0: case 0xa1: case 0xa2: case 0xa3: -#if HJB - util::stream_format(stream, "sub r0,r%d", rv); -#else - util::stream_format(stream, "subz,%d", rv); -#endif + util::stream_format(stream, z80 ? "sub r0,r%d" : "subz,%d", rv); break; case 0xa4: case 0xa5: case 0xa6: case 0xa7: -#if HJB - util::stream_format(stream, "sub r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "subi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "sub r%d,%s" : "subi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0xa8: case 0xa9: case 0xaa: case 0xab: -#if HJB - util::stream_format(stream, "sub r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "subr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "sub r%d,(%s)" : "subr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0xac: case 0xad: case 0xae: case 0xaf: -#if HJB - util::stream_format(stream, "sub %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "suba,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "sub %s" : "suba,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0xb0: case 0xb1: case 0xb2: case 0xb3: -#if HJB - util::stream_format(stream, "out (ctrl),r%d", rv); -#else - util::stream_format(stream, "wrtc,%d", rv); -#endif + util::stream_format(stream, z80 ? "out (ctrl),r%d" : "wrtc,%d", rv); break; case 0xb4: -#if HJB - util::stream_format(stream, "bit psu,%s", IMM_PSU(pc)); -#else - util::stream_format(stream, "tpsu %s", IMM_PSU(pc)); -#endif + util::stream_format(stream, z80 ? "bit psu,%s" : "tpsu %s", IMM_PSU(pc, params)); pc+=1; break; case 0xb5: -#if HJB - util::stream_format(stream, "bit psl,%s", IMM_PSL(pc)); -#else - util::stream_format(stream, "tpsl %s", IMM_PSL(pc)); -#endif + util::stream_format(stream, z80 ? "bit psl,%s" : "tpsl %s", IMM_PSL(pc, params)); pc+=1; break; case 0xb6: case 0xb7: -#if HJB - util::stream_format(stream, "**** $%02X",op); -#else - util::stream_format(stream, "**** $%02X",op); -#endif + util::stream_format(stream, z80 ? "**** $%02X" : "**** $%02X",op); break; case 0xb8: case 0xb9: case 0xba: -#if HJB - util::stream_format(stream, "calr n%c,%s", cc[rv], REL(pc)); -#else - util::stream_format(stream, "bsfr,%c %s", cc[rv], REL(pc)); -#endif + util::stream_format(stream, z80 ? "calr n%c,%s" : "bsfr,%c %s", cc[rv], REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xbb: -#if HJB - util::stream_format(stream, "cal0 %s", REL0(pc)); -#else - util::stream_format(stream, "zbsr %s", REL0(pc)); -#endif + util::stream_format(stream, z80 ? "cal0 %s" : "zbsr %s", REL0(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xbc: case 0xbd: case 0xbe: -#if HJB - util::stream_format(stream, "call n%c,%s", cc[rv], ADR(pc)); -#else - util::stream_format(stream, "bsfa,%c %s", cc[rv], ADR(pc)); -#endif + util::stream_format(stream, z80 ? "call n%c,%s" : "bsfa,%c %s", cc[rv], ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xbf: -#if HJB - util::stream_format(stream, "call %s+r3", ADR(pc)); -#else - util::stream_format(stream, "bsxa %s", ADR(pc)); -#endif + util::stream_format(stream, z80 ? "call %s+r3" : "bsxa %s", ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xc0: util::stream_format(stream, "nop"); break; case 0xc1: case 0xc2: case 0xc3: -#if HJB - util::stream_format(stream, "ld r%d,r0", rv); -#else - util::stream_format(stream, "strz,%d", rv); -#endif + util::stream_format(stream, z80 ? "ld r%d,r0" : "strz,%d", rv); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: -#if HJB - util::stream_format(stream, "**** $%02X",op); -#else - util::stream_format(stream, "**** $%02X",op); -#endif + util::stream_format(stream, z80 ? "**** $%02X" : "**** $%02X",op); break; case 0xc8: case 0xc9: case 0xca: case 0xcb: -#if HJB - util::stream_format(stream, "ld (%s),r%d", REL(pc), rv); -#else - util::stream_format(stream, "strr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "ld (%s),r%d" : "strr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0xcc: case 0xcd: case 0xce: case 0xcf: -#if HJB - util::stream_format(stream, "ld %s", ABS(0,rv,pc)); -#else - util::stream_format(stream, "stra,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "ld %s" : "stra,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: -#if HJB - util::stream_format(stream, "rol r%d", rv); -#else - util::stream_format(stream, "rrl,%d", rv); -#endif + util::stream_format(stream, z80 ? "rol r%d" : "rrl,%d", rv); break; case 0xd4: case 0xd5: case 0xd6: case 0xd7: -#if HJB - util::stream_format(stream, "out (%s),r%d", IMM(pc), rv); -#else - util::stream_format(stream, "wrte,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "out (%s),r%d" : "wrte,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0xd8: case 0xd9: case 0xda: case 0xdb: -#if HJB - util::stream_format(stream, "ijnz r%d,%s", rv, REL(pc)); -#else - util::stream_format(stream, "birr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "ijnz r%d,%s" : "birr,%d %s", rv, REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xdc: case 0xdd: case 0xde: case 0xdf: -#if HJB - util::stream_format(stream, "ijnz r%d,%s", rv, ADR(pc)); -#else - util::stream_format(stream, "bira,%d %s", rv, ADR(pc)); -#endif + util::stream_format(stream, z80 ? "ijnz r%d,%s" : "bira,%d %s", rv, ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: -#if HJB - util::stream_format(stream, "cp r0,%d", rv); -#else - util::stream_format(stream, "comz,%d", rv); -#endif + util::stream_format(stream, z80 ? "cp r0,%d" : "comz,%d", rv); break; case 0xe4: case 0xe5: case 0xe6: case 0xe7: -#if HJB - util::stream_format(stream, "cp r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "comi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "cp r%d,%s" : "comi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0xe8: case 0xe9: case 0xea: case 0xeb: -#if HJB - util::stream_format(stream, "cp r%d,(%s)", rv, REL(pc)); -#else - util::stream_format(stream, "comr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "cp r%d,(%s)" : "comr,%d %s", rv, REL(pc, params)); pc+=1; break; case 0xec: case 0xed: case 0xee: case 0xef: -#if HJB - util::stream_format(stream, "cp %s", ABS(1,rv,pc)); -#else - util::stream_format(stream, "coma,%s", ABS(1,rv,pc)); -#endif + util::stream_format(stream, z80 ? "cp %s" : "coma,%s", ABS(1,rv,pc, params)); pc+=2; break; case 0xf0: case 0xf1: case 0xf2: case 0xf3: -#if HJB - util::stream_format(stream, "out (data),r%d", rv); -#else - util::stream_format(stream, "wrtd,%d", rv); -#endif + util::stream_format(stream, z80 ? "out (data),r%d" : "wrtd,%d", rv); break; case 0xf4: case 0xf5: case 0xf6: case 0xf7: -#if HJB - util::stream_format(stream, "test r%d,%s", rv, IMM(pc)); -#else - util::stream_format(stream, "tmi,%d %s", rv, IMM(pc)); -#endif + util::stream_format(stream, z80 ? "test r%d,%s" : "tmi,%d %s", rv, IMM(pc, params)); pc+=1; break; case 0xf8: case 0xf9: case 0xfa: case 0xfb: -#if HJB - util::stream_format(stream, "djnz r%d,%s", rv, REL(pc)); -#else - util::stream_format(stream, "bdrr,%d %s", rv, REL(pc)); -#endif + util::stream_format(stream, z80 ? "djnz r%d,%s" : "bdrr,%d %s", rv, REL(pc, params)); pc+=1; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0xfc: case 0xfd: case 0xfe: case 0xff: -#if HJB - util::stream_format(stream, "djnz r%d,%s", rv, ADR(pc)); -#else - util::stream_format(stream, "bdra,%d %s", rv, ADR(pc)); -#endif + util::stream_format(stream, z80 ? "djnz r%d,%s" : "bdra,%d %s", rv, ADR(pc, params)); pc+=2; - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; +} + +u32 s2650_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/s2650/2650dasm.h b/src/devices/cpu/s2650/2650dasm.h new file mode 100644 index 00000000000..bf9523255cc --- /dev/null +++ b/src/devices/cpu/s2650/2650dasm.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/*************************************************************************** + * + * Portable Signetics 2650 disassembler + * + * Written by J. Buchmueller (pullmoll@t-online.de) + * for the MAME project + * + **************************************************************************/ + +#ifndef MAME_CPU_S2650_2650DASM_H +#define MAME_CPU_S2650_2650DASM_H + +#pragma once + +class s2650_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + virtual bool get_z80_mnemonics_mode() const = 0; + }; + + s2650_disassembler(config *conf); + virtual ~s2650_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const int rel[0x100]; + static const char cc[4]; + + void add(std::string &buf, std::string str); + std::string SYM(int addr); + std::string IMM(offs_t pc, const data_buffer ¶ms); + std::string IMM_PSL(offs_t pc, const data_buffer ¶ms); + std::string IMM_PSU(offs_t pc, const data_buffer ¶ms); + std::string REL(offs_t pc, const data_buffer ¶ms); + std::string REL0(offs_t pc, const data_buffer ¶ms); + std::string ABS(int load, int r, offs_t pc, const data_buffer ¶ms); + std::string ADR(offs_t pc, const data_buffer ¶ms); + + config *m_config; +}; + +#endif diff --git a/src/devices/cpu/s2650/s2650.cpp b/src/devices/cpu/s2650/s2650.cpp index 2afc7c5b261..7b452907e03 100644 --- a/src/devices/cpu/s2650/s2650.cpp +++ b/src/devices/cpu/s2650/s2650.cpp @@ -42,13 +42,16 @@ s2650_device::s2650_device(const machine_config &mconfig, const char *tag, devic memset(m_reg, 0x00, sizeof(m_reg)); } - -offs_t s2650_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +bool s2650_device::get_z80_mnemonics_mode() const { - extern CPU_DISASSEMBLE( s2650 ); - return CPU_DISASSEMBLE_NAME(s2650)(this, stream, pc, oprom, opram, options); + // Needs to become configurable live + return false; } +util::disasm_interface *s2650_device::create_disassembler() +{ + return new s2650_disassembler(this); +} device_memory_interface::space_config_vector s2650_device::memory_space_config() const { @@ -823,7 +826,7 @@ void s2650_device::device_start() m_flag_handler.resolve_safe(); m_intack_handler.resolve_safe(); - m_direct = &space(AS_PROGRAM).direct(); + m_direct = space(AS_PROGRAM).direct<0>(); save_item(NAME(m_ppc)); save_item(NAME(m_page)); diff --git a/src/devices/cpu/s2650/s2650.h b/src/devices/cpu/s2650/s2650.h index 4fd297b694a..e329831690c 100644 --- a/src/devices/cpu/s2650/s2650.h +++ b/src/devices/cpu/s2650/s2650.h @@ -5,6 +5,7 @@ #pragma once +#include "2650dasm.h" #define S2650_SENSE_LINE INPUT_LINE_IRQ1 @@ -35,7 +36,7 @@ DECLARE_DEVICE_TYPE(S2650, s2650_device) #define MCFG_S2650_INTACK_HANDLER(_devcb) \ devcb = &s2650_device::set_intack_handler(*device, DEVCB_##_devcb); -class s2650_device : public cpu_device + class s2650_device : public cpu_device, public s2650_disassembler::config { public: // construction/destruction @@ -68,9 +69,8 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_z80_mnemonics_mode() const override; private: address_space_config m_program_config; @@ -95,7 +95,7 @@ private: uint8_t m_irq_state; int m_icount; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; // For debugger uint16_t m_debugger_temp; diff --git a/src/devices/cpu/saturn/saturn.cpp b/src/devices/cpu/saturn/saturn.cpp index 2368c16ef19..480f10a8c1f 100644 --- a/src/devices/cpu/saturn/saturn.cpp +++ b/src/devices/cpu/saturn/saturn.cpp @@ -64,11 +64,16 @@ device_memory_interface::space_config_vector saturn_device::memory_space_config( }; } +bool saturn_device::get_nonstandard_mnemonics_mode() const +{ + // Needs to become configurable live + return false; +} + -offs_t saturn_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *saturn_device::create_disassembler() { - extern CPU_DISASSEMBLE( saturn ); - return CPU_DISASSEMBLE_NAME(saturn)(this, stream, pc, oprom, opram, options); + return new saturn_disassembler(this); } @@ -88,7 +93,7 @@ offs_t saturn_device::disasm_disassemble(std::ostream &stream, offs_t pc, const void saturn_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_out_func.resolve_safe(); m_in_func.resolve_safe(0); diff --git a/src/devices/cpu/saturn/saturn.h b/src/devices/cpu/saturn/saturn.h index d73745a31fb..bd49ad18806 100644 --- a/src/devices/cpu/saturn/saturn.h +++ b/src/devices/cpu/saturn/saturn.h @@ -32,6 +32,7 @@ HP38G 09/??/95 1LT8 Yorke #pragma once +#include "saturnds.h" #define SATURN_INT_NONE 0 #define SATURN_INT_IRQ 1 @@ -72,7 +73,7 @@ enum saturn_device::set_rsi_func(*device, DEVCB_##_rsi); -class saturn_device : public cpu_device +class saturn_device : public cpu_device, public saturn_disassembler::config { public: // construction/destruction @@ -109,9 +110,8 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 20; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + virtual bool get_nonstandard_mnemonics_mode() const override; private: address_space_config m_program_config; @@ -149,7 +149,7 @@ typedef uint8_t Saturn64[16]; int m_monitor_id; int m_monitor_in; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; int64_t m_debugger_temp; diff --git a/src/devices/cpu/saturn/saturnds.cpp b/src/devices/cpu/saturn/saturnds.cpp index a71aec2cbf6..6d3b2767f7f 100644 --- a/src/devices/cpu/saturn/saturnds.cpp +++ b/src/devices/cpu/saturn/saturnds.cpp @@ -9,19 +9,7 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" - -#include "saturn.h" - -#define SATURN_HP_MNEMONICS - -#if defined SATURN_HP_MNEMONICS -// class/hp mnemonics -static int set=0; -#else -// readable/normal mnemonics -static int set=1; -#endif +#include "saturnds.h" #define P "P" #define WP "WP" @@ -33,551 +21,382 @@ static int set=1; #define W "W" #define A "A" -static const char *const adr_b[]= +const char *const saturn_disassembler::adr_b[]= { P, WP, XS, X, S, M, B, W }; -static const char *const adr_af[]= +const char *const saturn_disassembler::adr_af[]= { P, WP, XS, X, S, M, B, W, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, A }; -static const char *const adr_a[]= +const char *const saturn_disassembler::adr_a[]= { P, WP, XS, X, S, M, B, W }; -static const char number_2_hex[]= +const char saturn_disassembler::number_2_hex[]= { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; -#define SATURN_PEEKOP_DIS8(v) v = (int8_t)( oprom[pos] | ( oprom[pos+1] << 4 ) ); pos+= 2; +#define SATURN_PEEKOP_DIS8(v) v = (int8_t)( opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) ); pos+= 2; -#define SATURN_PEEKOP_DIS12(v) v = oprom[pos] | ( oprom[pos+1] << 4 ) | ( oprom[pos+2] << 8 ); \ +#define SATURN_PEEKOP_DIS12(v) v = opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) | ( opcodes.r8(pos+2) << 8 ); \ pos += 3; \ if ( v & 0x0800 ) v = -0x1000 + v; -#define SATURN_PEEKOP_DIS16(v) v = (int16_t)( oprom[pos] | ( oprom[pos+1] << 4 ) | ( oprom[pos+2] << 8 ) | ( oprom[pos+3] << 12 ) ); pos += 4; - -#define SATURN_PEEKOP_ADR(v) v = oprom[pos] | ( oprom[pos+1] << 4 ) | ( oprom[pos+2] << 8 ) | ( oprom[pos+3] << 12 ) | ( oprom[pos+4] << 16 ); pos += 5; - - -// don't split branch and return, source relies on this ordering -enum MNEMONICS -{ - Return, ReturnSetXM, ReturnSetCarry, ReturnClearCarry, ReturnFromInterrupt, - jump3,jump4,jump, - call3,call4,call, - branchCarrySet, returnCarrySet, - branchCarryClear, returnCarryClear, - - outCS, outC, inA, inC, - unconfig, config, Cid, shutdown, cp1, reset, buscc, - CcopyP, PcopyC, sreq, CswapP, - - inton, AloadImm, buscb, - clearAbit, setAbit, - branchAbitclear, returnAbitclear, - branchAbitset, returnAbitset, - clearCbit, setCbit, - branchCbitclear, returnCbitclear, - branchCbitset, returnCbitset, - PCloadA, buscd, PCloadC, intoff, rsi, - - jumpA, jumpC, PCcopyA, PCcopyC, AcopyPC, CcopyPC, - - clearHST, - branchHSTclear, returnHSTclear, - - clearBitST, setBitST, - branchSTclear, returnSTclear, - branchSTset, returnSTset, - - - branchPdiffers, returnPdiffers, - branchPequals, returnPequals, - - branchAequalsB, returnAequalsB, - branchBequalsC, returnBequalsC, - branchAequalsC, returnAequalsC, - branchCequalsD, returnCequalsD, - branchAdiffersB, returnAdiffersB, - branchBdiffersC, returnBdiffersC, - branchAdiffersC, returnAdiffersC, - branchCdiffersD, returnCdiffersD, - branchAzero, returnAzero, - branchBzero, returnBzero, - branchCzero, returnCzero, - branchDzero, returnDzero, - branchAnotzero, returnAnotzero, - branchBnotzero, returnBnotzero, - branchCnotzero, returnCnotzero, - branchDnotzero, returnDnotzero, - - branchAgreaterB, returnAgreaterB, - branchBgreaterC, returnBgreaterC, - branchCgreaterA, returnCgreaterA, - branchDgreaterC, returnDgreaterC, - branchAlowerB, returnAlowerB, - branchBlowerC, returnBlowerC, - branchClowerA, returnClowerA, - branchDlowerC, returnDlowerC, - branchAnotlowerB, returnAnotlowerB, - branchBnotlowerC, returnBnotlowerC, - branchCnotlowerA, returnCnotlowerA, - branchDnotlowerC, returnDnotlowerC, - branchAnotgreaterB, returnAnotgreaterB, - branchBnotgreaterC, returnBnotgreaterC, - branchCnotgreaterA, returnCnotgreaterA, - branchDnotgreaterC, returnDnotgreaterC, - - SetHexMode, SetDecMode, - PushC, PopC, - - D0loadImm2, D0loadImm4, D0loadImm5, - D1loadImm2, D1loadImm4, D1loadImm5, - PloadImm, CloadImm, - - clearST, - CcopyST, STcopyC, - swapCST, - - incP, decP, - - R0copyA, R1copyA, R2copyA, R3copyA, R4copyA, - R0copyC, R1copyC, R2copyC, R3copyC, R4copyC, - - AcopyR0, AcopyR1, AcopyR2, AcopyR3, AcopyR4, - CcopyR0, CcopyR1, CcopyR2, CcopyR3, CcopyR4, - - D0copyA, D1copyA, D0copyC, D1copyC, - D0copyAShort, D1copyAShort, D0copyCShort, D1copyCShort, // other class mnemonic - - SwapAR0, SwapAR1, SwapAR2, SwapAR3, SwapAR4, - SwapCR0, SwapCR1, SwapCR2, SwapCR3, SwapCR4, - - SwapAD0, SwapAD1, SwapCD0, SwapCD1, - SwapAD0Short, SwapAD1Short, SwapCD0Short, SwapCD1Short, // other class mnemonic - - D0storeA, D1storeA, D0storeC, D1storeC, - AloadD0, AloadD1, CloadD0, CloadD1, - - D0addImm, D1addImm, D0subImm, D1subImm, - AaddImm, BaddImm, CaddImm, DaddImm, - AsubImm, BsubImm, CsubImm, DsubImm, - - AandB, BandC, CandA, DandC, BandA, CandB, AandC, CandD, - AorB, BorC, CorA, DorC, BorA, CorB, AorC, CorD, - - Ashiftrightbit, Bshiftrightbit, Cshiftrightbit, Dshiftrightbit, - - AshiftleftCarry, BshiftleftCarry, CshiftleftCarry, DshiftleftCarry, - AshiftrightCarry, BshiftrightCarry, CshiftrightCarry, DshiftrightCarry, - - AaddB, BaddC, CaddA, DaddC, AaddA, BaddB, CaddC, DaddD, - BaddA, CaddB, AaddC, CaddD, decA, decB, decC, decD, - - AsubB, BsubC, CsubA, DsubC, incA, incB, incC, incD, - BsubA, CsubB, AsubC, CsubD, AsubnB, BsubnC, CsubnA, DsubnC, - - clearA, clearB, clearC, clearD, - AcopyB, BcopyC, CcopyA, DcopyC, BcopyA, CcopyB, AcopyC, CcopyD, - AswapB, BswapC, CswapA, DswapC, - - Ashiftleft, Bshiftleft, Cshiftleft, Dshiftleft, - Ashiftright, Bshiftright, Cshiftright, Dshiftright, - negateA, negateB, negateC, negateD, - notA, notB, notC, notD - -}; - -static const struct { - const char *name[2]; -} mnemonics[]={ - { { "rtn", "RET" } }, - { { "rtnsXM", "RETSETXM" } }, - { { "rtnsC", "RETSETC" } }, - { { "rtncC", "RETCLRC" } }, - { { "rti", "RETI" } }, - { { "goto %05x", "JUMP.3 %05x" } }, - { { "goto %05x", "JUMP.4 %05x" } }, - { { "goto %05x", "JUMP %05x" } }, - { { "gosub %05x", "CALL.3 %05x" } }, - { { "gosub %05x", "CALL.4 %05x" } }, - { { "gosub %05x", "CALL %05x" } }, - { { "goC %05x", "BRCS %05x" } }, - { { "rtnC", "RETCS" } }, - { { "gonC %05x", "BRCC %05x" } }, - { { "rtnnC", "RETCC" } }, - - { { "OUT=CS", "OUT.S C" } }, - { { "OUT=C", "OUT.X C" } }, - { { "A=IN", "IN.4 A" } }, - { { "C=IN", "IN.4 C" } }, - { { "uncnfg", "UNCNFG" } }, - { { "config", "CONFIG" } }, - { { "C=id", "MOVE.A ID,C" } }, - { { "!shutdn", "!SHUTDN" } }, - { { "C+P+1", "ADD.A P+1,C" } }, - { { "reset", "RESET" } }, - { { "!buscc", "!BUSCC" } }, - { { "C=P %x", "MOVE.1 P,C,%x" } }, - { { "P=C %x", "MOVE.1 C,%x,P" } }, - { { "!sreq?", "!SREQ" } }, - { { "CPex %x", "SWAP.1 P,C,%x" } }, - - { { "!inton", "!INTON" } }, - { { "LA %-2x %s", "MOVE.P%-2x %s,A" } }, - { { "!buscb", "!BUSCB" } }, - { { "Abit=0 %x", "CLRB %x,A" } }, - { { "Abit=1 %x", "SETB %x,A" } }, - { { "?Abit=0 %x,%05x", "BRBC %x,A,%05x" } }, - { { "?Abit=0 %x,rtn", "RETBC %x,A" } }, - { { "?Abit=1 %x,%05x", "BRBS %x,A,%05x" } }, - { { "?Abit=1 %x,rtn", "RETBS %x,A" } }, - { { "Cbit=0 %x", "CLRB %x,C" } }, - { { "Cbit=1 %x", "SETB %x,C" } }, - { { "?Cbit=0 %x,%05x", "BRBC %x,C,%05x" } }, - { { "?Cbit=0 %x,rtn", "RETBC %x,C" } }, - { { "?Cbit=1 %x,%05x", "BRBS %x,C,%05x" } }, - { { "?Cbit=1 %x,rtn", "RETBS %x,C" } }, - { { "PC=(A)", "JUMP.A @A" } }, - { { "!buscd", "!BUSCD" } }, - { { "PC=(C)", "JUMP.A @C" } }, - { { "!intoff", "!INTOFF" } }, - { { "!rsi", "!RSI" } }, - - { { "PC=A", "JUMP.A A" } }, - { { "PC=C", "JUMP.A C" } }, - { { "A=PC", "MOVE.A PC,A" } }, - { { "C=PC", "MOVE.A PC,C" } }, - { { "APCex", "SWAP.A A,PC" } }, - { { "CPCex", "SWAP.A C,PC" } }, - - { { "HST=0 %x", "CLRHST %x" } }, - { { "?HST=0 %x,%05x", "BRBCHST %x,%05x" } }, - { { "?HST=0 %x,rtn", "RETBCHST %x" } }, - { { "ST=0 %x", "CLRB %x,ST" } }, - { { "ST=1 %x", "SETB %x,ST" } }, - { { "?ST=0 %x,%05x", "BRBC ST,%x,%05x" } }, - { { "?ST=0 %x,rtn", "RETBC ST,%x" } }, - { { "?ST=1 %x,%05x", "BRBS ST,%x,%05x" } }, - { { "?ST=1 %x,rtn", "RETBS ST,%x" } }, - { { "?P# %x,%05x", "BRNE P,%x,%05x" } }, - { { "?P# %x,rtn", "RETNE P,%x" } }, - { { "?P= %x,%05x", "BREQ P,%x,%05x" } }, - { { "?P= %x,rtn", "RETEQ P,%x" } }, - - { { "?A=B %s,%05x", "BREQ.%-2s A,B,%05x" } }, - { { "?A=B %s,rtn", "RETEQ.%-2s A,B" } }, - { { "?B=C %s,%05x", "BREQ.%-2s B,C,%05x" } }, - { { "?B=C %s,rtn", "RETEQ.%-2s B,C" } }, - { { "?A=C %s,%05x", "BREQ.%-2s A,C,%05x" } }, - { { "?A=C %s,rtn", "RETEQ.%-2s A,C" } }, - { { "?C=D %s,%05x", "BREQ.%-2s C,D,%05x" } }, - { { "?C=D %s,rtn", "RETEQ.%-2s C,D" } }, - { { "?A#B %s,%05x", "BRNE.%-2s A,B,%05x" } }, - { { "?A#B %s,rtn", "RETNE.%-2s A,B" } }, - { { "?B#C %s,%05x", "BRNE.%-2s B,C,%05x" } }, - { { "?B#C %s,rtn", "RETNE.%-2s B,C" } }, - { { "?A#C %s,%05x", "BRNE.%-2s A,C,%05x" } }, - { { "?A#C %s,rtn", "RETNE.%-2s A,C" } }, - { { "?C#D %s,%05x", "BRNE.%-2s C,D,%05x" } }, - { { "?C#D %s,rtn", "RETNE.%-2s C,D" } }, - { { "?A=0 %s,%05x", "BRZ.%-2s A,%05x" } }, - { { "?A=0 %s,rtn", "RETZ.%-2s A" } }, - { { "?B=0 %s,%05x", "BRZ.%-2s B,%05x" } }, - { { "?B=0 %s,rtn", "RETZ.%-2s B" } }, - { { "?C=0 %s,%05x", "BRZ.%-2s C,%05x" } }, - { { "?C=0 %s,rtn", "RETZ.%-2s C" } }, - { { "?D=0 %s,%05x", "BRZ.%-2s D,%05x" } }, - { { "?D=0 %s,rtn", "RETZ.%-2s D" } }, - { { "?A#0 %s,%05x", "BRNZ.%-2s A,%05x" } }, - { { "?A#0 %s,rtn", "RETNZ.%-2s A" } }, - { { "?B#0 %s,%05x", "BRNZ.%-2s B,%05x" } }, - { { "?B#0 %s,rtn", "RETNZ.%-2s B" } }, - { { "?C#0 %s,%05x", "BRNZ.%-2s C,%05x" } }, - { { "?C#0 %s,rtn", "RETNZ.%-2s C" } }, - { { "?D#0 %s,%05x", "BRNZ.%-2s D,%05x" } }, - { { "?D#0 %s,rtn", "RETNZ.%-2s D" } }, - - { { "?A>B %s,%05x", "BRGT.%-2s A,B,%05x" } }, - { { "?A>B %s,rtn", "RETGT.%-2s A,B" } }, - { { "?B>C %s,%05x", "BRGT.%-2s B,C,%05x" } }, - { { "?B>C %s,rtn", "RETGT.%-2s B,C" } }, - { { "?C>A %s,%05x", "BRGT.%-2s C,A,%05x" } }, - { { "?C>A %s,rtn", "RETGT.%-2s C,A" } }, - { { "?D>C %s,%05x", "BRGT.%-2s D,C,%05x" } }, - { { "?D>C %s,rtn", "RETGT.%-2s D,C" } }, - { { "?A<B %s,%05x", "BRLT.%-2s A,B,%05x" } }, - { { "?A<B %s,rtn", "RETLT.%-2s A,B" } }, - { { "?B<C %s,%05x", "BRLT.%-2s B,C,%05x" } }, - { { "?B<C %s,rtn", "RETLT.%-2s B,C" } }, - { { "?C<A %s,%05x", "BRLT.%-2s C,A,%05x" } }, - { { "?C<A %s,rtn", "RETLT.%-2s C,A" } }, - { { "?D<C %s,%05x", "BRLT.%-2s D,C,%05x" } }, - { { "?D<C %s,rtn", "RETLT.%-2s D,C" } }, - { { "?A>=B %s,%05x", "BRGE.%-2s A,B,%05x" } }, - { { "?A>=B %s,rtn", "RETGE.%-2s A,B" } }, - { { "?B>=C %s,%05x", "BRGE.%-2s B,C,%05x" } }, - { { "?B>=C %s,rtn", "RETGE.%-2s B,C" } }, - { { "?C>=A %s,%05x", "BRGE.%-2s C,A,%05x" } }, - { { "?C>=A %s,rtn", "RETGE.%-2s C,A" } }, - { { "?D>=C %s,%05x", "BRGE.%-2s D,C,%05x" } }, - { { "?D>=C %s,rtn", "RETGE.%-2s D,C" } }, - { { "?A<=B %s,%05x", "BRLE.%-2s A,B,%05x" } }, - { { "?A<=B %s,rtn", "RETLE.%-2s A,B" } }, - { { "?B<=C %s,%05x", "BRLE.%-2s B,C,%05x" } }, - { { "?B<=C %s,rtn", "RETLE.%-2s B,C" } }, - { { "?C<=A %s,%05x", "BRLE.%-2s C,A,%05x" } }, - { { "?C<=A %s,rtn", "RETLE.%-2s C,A" } }, - { { "?D<=C %s,%05x", "BRLE.%-2s D,C,%05x" } }, - { { "?D<=C %s,rtn", "RETLE.%-2s D,C" } }, - - { { "sethex", "SETHEX" } }, - { { "setdec", "SETDEC" } }, - { { "RSTK=C", "PUSH.A C" } }, - { { "C=RSTK", "POP.A C" } }, +#define SATURN_PEEKOP_DIS16(v) v = (int16_t)( opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) | ( opcodes.r8(pos+2) << 8 ) | ( opcodes.r8(pos+3) << 12 ) ); pos += 4; + +#define SATURN_PEEKOP_ADR(v) v = opcodes.r8(pos) | ( opcodes.r8(pos+1) << 4 ) | ( opcodes.r8(pos+2) << 8 ) | ( opcodes.r8(pos+3) << 12 ) | ( opcodes.r8(pos+4) << 16 ); pos += 5; + + +const char *const saturn_disassembler::mnemonics[][2] = { + { "rtn", "RET" }, + { "rtnsXM", "RETSETXM" }, + { "rtnsC", "RETSETC" }, + { "rtncC", "RETCLRC" }, + { "rti", "RETI" }, + { "goto %05x", "JUMP.3 %05x" }, + { "goto %05x", "JUMP.4 %05x" }, + { "goto %05x", "JUMP %05x" }, + { "gosub %05x", "CALL.3 %05x" }, + { "gosub %05x", "CALL.4 %05x" }, + { "gosub %05x", "CALL %05x" }, + { "goC %05x", "BRCS %05x" }, + { "rtnC", "RETCS" }, + { "gonC %05x", "BRCC %05x" }, + { "rtnnC", "RETCC" }, + + { "OUT=CS", "OUT.S C" }, + { "OUT=C", "OUT.X C" }, + { "A=IN", "IN.4 A" }, + { "C=IN", "IN.4 C" }, + { "uncnfg", "UNCNFG" }, + { "config", "CONFIG" }, + { "C=id", "MOVE.A ID,C" }, + { "!shutdn", "!SHUTDN" }, + { "C+P+1", "ADD.A P+1,C" }, + { "reset", "RESET" }, + { "!buscc", "!BUSCC" }, + { "C=P %x", "MOVE.1 P,C,%x" }, + { "P=C %x", "MOVE.1 C,%x,P" }, + { "!sreq?", "!SREQ" }, + { "CPex %x", "SWAP.1 P,C,%x" }, + + { "!inton", "!INTON" }, + { "LA %-2x %s", "MOVE.P%-2x %s,A" }, + { "!buscb", "!BUSCB" }, + { "Abit=0 %x", "CLRB %x,A" }, + { "Abit=1 %x", "SETB %x,A" }, + { "?Abit=0 %x,%05x", "BRBC %x,A,%05x" }, + { "?Abit=0 %x,rtn", "RETBC %x,A" }, + { "?Abit=1 %x,%05x", "BRBS %x,A,%05x" }, + { "?Abit=1 %x,rtn", "RETBS %x,A" }, + { "Cbit=0 %x", "CLRB %x,C" }, + { "Cbit=1 %x", "SETB %x,C" }, + { "?Cbit=0 %x,%05x", "BRBC %x,C,%05x" }, + { "?Cbit=0 %x,rtn", "RETBC %x,C" }, + { "?Cbit=1 %x,%05x", "BRBS %x,C,%05x" }, + { "?Cbit=1 %x,rtn", "RETBS %x,C" }, + { "PC=(A)", "JUMP.A @A" }, + { "!buscd", "!BUSCD" }, + { "PC=(C)", "JUMP.A @C" }, + { "!intoff", "!INTOFF" }, + { "!rsi", "!RSI" }, + + { "PC=A", "JUMP.A A" }, + { "PC=C", "JUMP.A C" }, + { "A=PC", "MOVE.A PC,A" }, + { "C=PC", "MOVE.A PC,C" }, + { "APCex", "SWAP.A A,PC" }, + { "CPCex", "SWAP.A C,PC" }, + + { "HST=0 %x", "CLRHST %x" }, + { "?HST=0 %x,%05x", "BRBCHST %x,%05x" }, + { "?HST=0 %x,rtn", "RETBCHST %x" }, + { "ST=0 %x", "CLRB %x,ST" }, + { "ST=1 %x", "SETB %x,ST" }, + { "?ST=0 %x,%05x", "BRBC ST,%x,%05x" }, + { "?ST=0 %x,rtn", "RETBC ST,%x" }, + { "?ST=1 %x,%05x", "BRBS ST,%x,%05x" }, + { "?ST=1 %x,rtn", "RETBS ST,%x" }, + { "?P# %x,%05x", "BRNE P,%x,%05x" }, + { "?P# %x,rtn", "RETNE P,%x" }, + { "?P= %x,%05x", "BREQ P,%x,%05x" }, + { "?P= %x,rtn", "RETEQ P,%x" }, + + { "?A=B %s,%05x", "BREQ.%-2s A,B,%05x" }, + { "?A=B %s,rtn", "RETEQ.%-2s A,B" }, + { "?B=C %s,%05x", "BREQ.%-2s B,C,%05x" }, + { "?B=C %s,rtn", "RETEQ.%-2s B,C" }, + { "?A=C %s,%05x", "BREQ.%-2s A,C,%05x" }, + { "?A=C %s,rtn", "RETEQ.%-2s A,C" }, + { "?C=D %s,%05x", "BREQ.%-2s C,D,%05x" }, + { "?C=D %s,rtn", "RETEQ.%-2s C,D" }, + { "?A#B %s,%05x", "BRNE.%-2s A,B,%05x" }, + { "?A#B %s,rtn", "RETNE.%-2s A,B" }, + { "?B#C %s,%05x", "BRNE.%-2s B,C,%05x" }, + { "?B#C %s,rtn", "RETNE.%-2s B,C" }, + { "?A#C %s,%05x", "BRNE.%-2s A,C,%05x" }, + { "?A#C %s,rtn", "RETNE.%-2s A,C" }, + { "?C#D %s,%05x", "BRNE.%-2s C,D,%05x" }, + { "?C#D %s,rtn", "RETNE.%-2s C,D" }, + { "?A=0 %s,%05x", "BRZ.%-2s A,%05x" }, + { "?A=0 %s,rtn", "RETZ.%-2s A" }, + { "?B=0 %s,%05x", "BRZ.%-2s B,%05x" }, + { "?B=0 %s,rtn", "RETZ.%-2s B" }, + { "?C=0 %s,%05x", "BRZ.%-2s C,%05x" }, + { "?C=0 %s,rtn", "RETZ.%-2s C" }, + { "?D=0 %s,%05x", "BRZ.%-2s D,%05x" }, + { "?D=0 %s,rtn", "RETZ.%-2s D" }, + { "?A#0 %s,%05x", "BRNZ.%-2s A,%05x" }, + { "?A#0 %s,rtn", "RETNZ.%-2s A" }, + { "?B#0 %s,%05x", "BRNZ.%-2s B,%05x" }, + { "?B#0 %s,rtn", "RETNZ.%-2s B" }, + { "?C#0 %s,%05x", "BRNZ.%-2s C,%05x" }, + { "?C#0 %s,rtn", "RETNZ.%-2s C" }, + { "?D#0 %s,%05x", "BRNZ.%-2s D,%05x" }, + { "?D#0 %s,rtn", "RETNZ.%-2s D" }, + + { "?A>B %s,%05x", "BRGT.%-2s A,B,%05x" }, + { "?A>B %s,rtn", "RETGT.%-2s A,B" }, + { "?B>C %s,%05x", "BRGT.%-2s B,C,%05x" }, + { "?B>C %s,rtn", "RETGT.%-2s B,C" }, + { "?C>A %s,%05x", "BRGT.%-2s C,A,%05x" }, + { "?C>A %s,rtn", "RETGT.%-2s C,A" }, + { "?D>C %s,%05x", "BRGT.%-2s D,C,%05x" }, + { "?D>C %s,rtn", "RETGT.%-2s D,C" }, + { "?A<B %s,%05x", "BRLT.%-2s A,B,%05x" }, + { "?A<B %s,rtn", "RETLT.%-2s A,B" }, + { "?B<C %s,%05x", "BRLT.%-2s B,C,%05x" }, + { "?B<C %s,rtn", "RETLT.%-2s B,C" }, + { "?C<A %s,%05x", "BRLT.%-2s C,A,%05x" }, + { "?C<A %s,rtn", "RETLT.%-2s C,A" }, + { "?D<C %s,%05x", "BRLT.%-2s D,C,%05x" }, + { "?D<C %s,rtn", "RETLT.%-2s D,C" }, + { "?A>=B %s,%05x", "BRGE.%-2s A,B,%05x" }, + { "?A>=B %s,rtn", "RETGE.%-2s A,B" }, + { "?B>=C %s,%05x", "BRGE.%-2s B,C,%05x" }, + { "?B>=C %s,rtn", "RETGE.%-2s B,C" }, + { "?C>=A %s,%05x", "BRGE.%-2s C,A,%05x" }, + { "?C>=A %s,rtn", "RETGE.%-2s C,A" }, + { "?D>=C %s,%05x", "BRGE.%-2s D,C,%05x" }, + { "?D>=C %s,rtn", "RETGE.%-2s D,C" }, + { "?A<=B %s,%05x", "BRLE.%-2s A,B,%05x" }, + { "?A<=B %s,rtn", "RETLE.%-2s A,B" }, + { "?B<=C %s,%05x", "BRLE.%-2s B,C,%05x" }, + { "?B<=C %s,rtn", "RETLE.%-2s B,C" }, + { "?C<=A %s,%05x", "BRLE.%-2s C,A,%05x" }, + { "?C<=A %s,rtn", "RETLE.%-2s C,A" }, + { "?D<=C %s,%05x", "BRLE.%-2s D,C,%05x" }, + { "?D<=C %s,rtn", "RETLE.%-2s D,C" }, + + { "sethex", "SETHEX" }, + { "setdec", "SETDEC" }, + { "RSTK=C", "PUSH.A C" }, + { "C=RSTK", "POP.A C" }, // load immediate - { { "D0= %02x", "MOVE.2 %02x,D0" } }, - { { "D0= %04x", "MOVE.4 %04x,D0" } }, - { { "D0= %05x", "MOVE.5 %05x,D0" } }, + { "D0= %02x", "MOVE.2 %02x,D0" }, + { "D0= %04x", "MOVE.4 %04x,D0" }, + { "D0= %05x", "MOVE.5 %05x,D0" }, - { { "D1= %02x", "MOVE.2 %02x,D1" } }, - { { "D1= %04x", "MOVE.4 %04x,D1" } }, - { { "D1= %05x", "MOVE.5 %05x,D1" } }, + { "D1= %02x", "MOVE.2 %02x,D1" }, + { "D1= %04x", "MOVE.4 %04x,D1" }, + { "D1= %05x", "MOVE.5 %05x,D1" }, - { { "P= %x", "MOVE %x,P" } }, - { { "lC %-2x %s", "MOVE.P%-2x %s,C" } }, + { "P= %x", "MOVE %x,P" }, + { "lC %-2x %s", "MOVE.P%-2x %s,C" }, - { { "clrST", "CLR.X ST" } }, - { { "C=ST", "MOVE.X ST,C" } }, - { { "ST=C", "MOVE.X C,ST" } }, - { { "CSTex", "SWAP.X C,ST" } }, + { "clrST", "CLR.X ST" }, + { "C=ST", "MOVE.X ST,C" }, + { "ST=C", "MOVE.X C,ST" }, + { "CSTex", "SWAP.X C,ST" }, - { { "P=P+1", "INC P" } }, - { { "P=P-1", "DEC P" } }, + { "P=P+1", "INC P" }, + { "P=P-1", "DEC P" }, // copy - { { "R0=A %s", "MOVE.%-2s A,R0" } }, - { { "R1=A %s", "MOVE.%-2s A,R1" } }, - { { "R2=A %s", "MOVE.%-2s A,R2" } }, - { { "R3=A %s", "MOVE.%-2s A,R3" } }, - { { "R4=A %s", "MOVE.%-2s A,R4" } }, - - { { "R0=C %s", "MOVE.%-2s C,R0" } }, - { { "R1=C %s", "MOVE.%-2s C,R1" } }, - { { "R2=C %s", "MOVE.%-2s C,R2" } }, - { { "R3=C %s", "MOVE.%-2s C,R3" } }, - { { "R4=C %s", "MOVE.%-2s C,R4" } }, - - { { "A=R0 %s", "MOVE.%-2s R0,A" } }, - { { "A=R1 %s", "MOVE.%-2s R1,A" } }, - { { "A=R2 %s", "MOVE.%-2s R2,A" } }, - { { "A=R3 %s", "MOVE.%-2s R3,A" } }, - { { "A=R4 %s", "MOVE.%-2s R4,A" } }, - - { { "C=R0 %s", "MOVE.%-2s R0,C" } }, - { { "C=R1 %s", "MOVE.%-2s R1,C" } }, - { { "C=R2 %s", "MOVE.%-2s R2,C" } }, - { { "C=R3 %s", "MOVE.%-2s R3,C" } }, - { { "C=R4 %s", "MOVE.%-2s R4,C" } }, - - { { "D0=A", "MOVE.A A,D0" } }, - { { "D1=A", "MOVE.A A,D1" } }, - { { "D0=C", "MOVE.A C,D0" } }, - { { "D1=C", "MOVE.A C,D1" } }, - { { "D0=As", "MOVE.S A,D0" } }, - { { "D1=As", "MOVE.S A,D1" } }, - { { "D0=Cs", "MOVE.S C,D0" } }, - { { "D1=Cs", "MOVE.S C,D1" } }, + { "R0=A %s", "MOVE.%-2s A,R0" }, + { "R1=A %s", "MOVE.%-2s A,R1" }, + { "R2=A %s", "MOVE.%-2s A,R2" }, + { "R3=A %s", "MOVE.%-2s A,R3" }, + { "R4=A %s", "MOVE.%-2s A,R4" }, + + { "R0=C %s", "MOVE.%-2s C,R0" }, + { "R1=C %s", "MOVE.%-2s C,R1" }, + { "R2=C %s", "MOVE.%-2s C,R2" }, + { "R3=C %s", "MOVE.%-2s C,R3" }, + { "R4=C %s", "MOVE.%-2s C,R4" }, + + { "A=R0 %s", "MOVE.%-2s R0,A" }, + { "A=R1 %s", "MOVE.%-2s R1,A" }, + { "A=R2 %s", "MOVE.%-2s R2,A" }, + { "A=R3 %s", "MOVE.%-2s R3,A" }, + { "A=R4 %s", "MOVE.%-2s R4,A" }, + + { "C=R0 %s", "MOVE.%-2s R0,C" }, + { "C=R1 %s", "MOVE.%-2s R1,C" }, + { "C=R2 %s", "MOVE.%-2s R2,C" }, + { "C=R3 %s", "MOVE.%-2s R3,C" }, + { "C=R4 %s", "MOVE.%-2s R4,C" }, + + { "D0=A", "MOVE.A A,D0" }, + { "D1=A", "MOVE.A A,D1" }, + { "D0=C", "MOVE.A C,D0" }, + { "D1=C", "MOVE.A C,D1" }, + { "D0=As", "MOVE.S A,D0" }, + { "D1=As", "MOVE.S A,D1" }, + { "D0=Cs", "MOVE.S C,D0" }, + { "D1=Cs", "MOVE.S C,D1" }, // swap operations - { { "AR0ex %s", "SWAP.%-2s A,R0" } }, - { { "AR1ex %s", "SWAP.%-2s A,R1" } }, - { { "AR2ex %s", "SWAP.%-2s A,R2" } }, - { { "AR3ex %s", "SWAP.%-2s A,R3" } }, - { { "AR4ex %s", "SWAP.%-2s A,R4" } }, - - { { "CR0ex %s", "SWAP.%-2s C,R0" } }, - { { "CR1ex %s", "SWAP.%-2s C,R1" } }, - { { "CR2ex %s", "SWAP.%-2s C,R2" } }, - { { "CR3ex %s", "SWAP.%-2s C,R3" } }, - { { "CR4ex %s", "SWAP.%-2s C,R4" } }, - - { { "AD0ex", "SWAP.A A,D0" } }, - { { "AD1ex", "SWAP.A A,D1" } }, - { { "CD0ex", "SWAP.A C,D0" } }, - { { "CD1ex", "SWAP.A C,D1" } }, - { { "AD0xs", "SWAP.S A,D0" } }, - { { "AD1xs", "SWAP.S A,D1" } }, - { { "CD0xs", "SWAP.S C,D0" } }, - { { "CD1xs", "SWAP.S C,D1" } }, + { "AR0ex %s", "SWAP.%-2s A,R0" }, + { "AR1ex %s", "SWAP.%-2s A,R1" }, + { "AR2ex %s", "SWAP.%-2s A,R2" }, + { "AR3ex %s", "SWAP.%-2s A,R3" }, + { "AR4ex %s", "SWAP.%-2s A,R4" }, + + { "CR0ex %s", "SWAP.%-2s C,R0" }, + { "CR1ex %s", "SWAP.%-2s C,R1" }, + { "CR2ex %s", "SWAP.%-2s C,R2" }, + { "CR3ex %s", "SWAP.%-2s C,R3" }, + { "CR4ex %s", "SWAP.%-2s C,R4" }, + + { "AD0ex", "SWAP.A A,D0" }, + { "AD1ex", "SWAP.A A,D1" }, + { "CD0ex", "SWAP.A C,D0" }, + { "CD1ex", "SWAP.A C,D1" }, + { "AD0xs", "SWAP.S A,D0" }, + { "AD1xs", "SWAP.S A,D1" }, + { "CD0xs", "SWAP.S C,D0" }, + { "CD1xs", "SWAP.S C,D1" }, // store - { { "Dat0=A %s", "MOVE.%-2s A,@D0" } }, - { { "Dat1=A %s", "MOVE.%-2s A,@D0" } }, - { { "Dat0=C %s", "MOVE.%-2s C,@D0" } }, - { { "Dat1=C %s", "MOVE.%-2s C,@D0" } }, + { "Dat0=A %s", "MOVE.%-2s A,@D0" }, + { "Dat1=A %s", "MOVE.%-2s A,@D0" }, + { "Dat0=C %s", "MOVE.%-2s C,@D0" }, + { "Dat1=C %s", "MOVE.%-2s C,@D0" }, // load - { { "A=Dat0 %s", "MOVE.%-2s @D0,A" } }, - { { "A=Dat1 %s", "MOVE.%-2s @D0,A" } }, - { { "C=Dat0 %s", "MOVE.%-2s @D0,C" } }, - { { "C=Dat1 %s", "MOVE.%-2s @D0,C" } }, + { "A=Dat0 %s", "MOVE.%-2s @D0,A" }, + { "A=Dat1 %s", "MOVE.%-2s @D0,A" }, + { "C=Dat0 %s", "MOVE.%-2s @D0,C" }, + { "C=Dat1 %s", "MOVE.%-2s @D0,C" }, // add/sub immediate - { { "D0=D0+ %x", "ADD.A %x,D0" } }, - { { "D1=D1+ %x", "ADD.A %x,D1" } }, - { { "D0=D0- %x", "SUB.A %x,D0" } }, - { { "D1=D1- %x", "SUB.A %x,D1" } }, - - { { "A=A+ %s,%x", "ADD.%-2s %x,A" } }, - { { "B=B+ %s,%x", "ADD.%-2s %x,B" } }, - { { "C=C+ %s,%x", "ADD.%-2s %x,C" } }, - { { "D=D+ %s,%x", "ADD.%-2s %x,D" } }, - { { "A=A- %s,%x", "SUB.%-2s %x,A" } }, - { { "B=B- %s,%x", "SUB.%-2s %x,B" } }, - { { "C=C- %s,%x", "SUB.%-2s %x,C" } }, - { { "D=D- %s,%x", "SUB.%-2s %x,D" } }, - - { { "A=A&B %s", "AND.%-2s B,A" } }, - { { "B=B&C %s", "AND.%-2s C,B" } }, - { { "C=C&A %s", "AND.%-2s A,C" } }, - { { "D=D&C %s", "AND.%-2s C,D" } }, - { { "B=B&A %s", "AND.%-2s A,B" } }, - { { "C=C&B %s", "AND.%-2s B,C" } }, - { { "A=A&C %s", "AND.%-2s C,A" } }, - { { "C=C&D %s", "AND.%-2s D,C" } }, - - { { "A=A!B %s", "OR.%-2s B,A" } }, - { { "B=B!C %s", "OR.%-2s C,B" } }, - { { "C=C!A %s", "OR.%-2s A,C" } }, - { { "D=D!C %s", "OR.%-2s C,D" } }, - { { "B=B!A %s", "OR.%-2s A,B" } }, - { { "C=C!B %s", "OR.%-2s B,C" } }, - { { "A=A!C %s", "OR.%-2s C,A" } }, - { { "C=C!D %s", "OR.%-2s D,C" } }, - - { { "Asrb %s", "SRB.%-2s A" } }, - { { "Bsrb %s", "SRB.%-2s B" } }, - { { "Csrb %s", "SRB.%-2s C" } }, - { { "Dsrb %s", "SRB.%-2s D" } }, - - { { "Aslc %s", "RLN.%-2s A" } }, - { { "Bslc %s", "RLN.%-2s B" } }, - { { "Cslc %s", "RLN.%-2s C" } }, - { { "Dslc %s", "RLN.%-2s D" } }, - { { "Asrc %s", "RRN.%-2s A" } }, - { { "Bsrc %s", "RRN.%-2s B" } }, - { { "Csrc %s", "RRN.%-2s C" } }, - { { "Dsrc %s", "RRN.%-2s D" } }, - - { { "A=A+B %s", "ADD.%-2s B,A" } }, - { { "B=B+C %s", "ADD.%-2s C,B" } }, - { { "C=C+A %s", "ADD.%-2s A,C" } }, - { { "D=D+C %s", "ADD.%-2s C,D" } }, - { { "A=A+A %s", "ADD.%-2s A,A" } }, - { { "B=B+B %s", "ADD.%-2s B,B" } }, - { { "C=C+C %s", "ADD.%-2s C,C" } }, - { { "D=D+C %s", "ADD.%-2s D,D" } }, - { { "B=B+A %s", "ADD.%-2s A,B" } }, - { { "C=C+B %s", "ADD.%-2s B,C" } }, - { { "A=A+C %s", "ADD.%-2s C,A" } }, - { { "C=C+D %s", "ADD.%-2s D,C" } }, - { { "A=A-1 %s", "DEC.%-2s A" } }, - { { "B=B-1 %s", "DEC.%-2s B" } }, - { { "C=C-1 %s", "DEC.%-2s C" } }, - { { "D=D-1 %s", "DEC.%-2s D" } }, - - { { "A=A-B %s", "ADD.%-2s B,A" } }, - { { "B=B-C %s", "ADD.%-2s C,B" } }, - { { "C=C-A %s", "ADD.%-2s A,C" } }, - { { "D=D-C %s", "ADD.%-2s C,D" } }, - { { "A=A+1 %s", "INC.%-2s A" } }, - { { "B=B+1 %s", "INC.%-2s B" } }, - { { "C=C+1 %s", "INC.%-2s C" } }, - { { "D=D+1 %s", "INC.%-2s D" } }, - { { "B=B-A %s", "SUB.%-2s A,B" } }, - { { "C=C-B %s", "SUB.%-2s B,C" } }, - { { "A=A-C %s", "SUB.%-2s C,A" } }, - { { "C=C-D %s", "SUB.%-2s D,C" } }, - { { "A=B-A %s", "SUBN.%-2s B,A" } }, - { { "B=C-B %s", "SUBN.%-2s C,B" } }, - { { "C=A-C %s", "SUBN.%-2s A,C" } }, - { { "D=C-D %s", "SUBN.%-2s C,D" } }, - - { { "A=0 %s", "CLR.%-2s A" } }, - { { "B=0 %s", "CLR.%-2s B" } }, - { { "C=0 %s", "CLR.%-2s C" } }, - { { "D=0 %s", "CLR.%-2s D" } }, - { { "A=B %s", "MOVE.%-2s B,A" } }, - { { "B=C %s", "MOVE.%-2s C,B" } }, - { { "C=A %s", "MOVE.%-2s A,C" } }, - { { "D=C %s", "MOVE.%-2s C,D" } }, - { { "B=A %s", "MOVE.%-2s A,B" } }, - { { "C=B %s", "MOVE.%-2s B,C" } }, - { { "A=C %s", "MOVE.%-2s C,A" } }, - { { "C=D %s", "MOVE.%-2s D,C" } }, - { { "ABex %s", "SWAP.%-2s A,B" } }, - { { "BCex %s", "SWAP.%-2s B,C" } }, - { { "ACex %s", "SWAP.%-2s A,C" } }, - { { "CDex %s", "SWAP.%-2s C,D" } }, - - { { "Asl %s", "SLN.%-2s A" } }, - { { "Bsl %s", "SLN.%-2s B" } }, - { { "Csl %s", "SLN.%-2s C" } }, - { { "Dsl %s", "SLN.%-2s D" } }, - { { "Asr %s", "SRN.%-2s A" } }, - { { "Bsr %s", "SRN.%-2s B" } }, - { { "Csr %s", "SRN.%-2s C" } }, - { { "Dsr %s", "SRN.%-2s D" } }, - { { "A=-A %s", "NEG.%-2s A" } }, - { { "B=-B %s", "NEG.%-2s B" } }, - { { "C=-C %s", "NEG.%-2s C" } }, - { { "D=-D %s", "NEG.%-2s D" } }, - { { "A=-A-1 %s", "NOT.%-2s A" } }, - { { "B=-B-1 %s", "NOT.%-2s B" } }, - { { "C=-C-1 %s", "NOT.%-2s C" } }, - { { "D=-D-1 %s", "NOT.%-2s D" } } - + { "D0=D0+ %x", "ADD.A %x,D0" }, + { "D1=D1+ %x", "ADD.A %x,D1" }, + { "D0=D0- %x", "SUB.A %x,D0" }, + { "D1=D1- %x", "SUB.A %x,D1" }, + + { "A=A+ %s,%x", "ADD.%-2s %x,A" }, + { "B=B+ %s,%x", "ADD.%-2s %x,B" }, + { "C=C+ %s,%x", "ADD.%-2s %x,C" }, + { "D=D+ %s,%x", "ADD.%-2s %x,D" }, + { "A=A- %s,%x", "SUB.%-2s %x,A" }, + { "B=B- %s,%x", "SUB.%-2s %x,B" }, + { "C=C- %s,%x", "SUB.%-2s %x,C" }, + { "D=D- %s,%x", "SUB.%-2s %x,D" }, + + { "A=A&B %s", "AND.%-2s B,A" }, + { "B=B&C %s", "AND.%-2s C,B" }, + { "C=C&A %s", "AND.%-2s A,C" }, + { "D=D&C %s", "AND.%-2s C,D" }, + { "B=B&A %s", "AND.%-2s A,B" }, + { "C=C&B %s", "AND.%-2s B,C" }, + { "A=A&C %s", "AND.%-2s C,A" }, + { "C=C&D %s", "AND.%-2s D,C" }, + + { "A=A!B %s", "OR.%-2s B,A" }, + { "B=B!C %s", "OR.%-2s C,B" }, + { "C=C!A %s", "OR.%-2s A,C" }, + { "D=D!C %s", "OR.%-2s C,D" }, + { "B=B!A %s", "OR.%-2s A,B" }, + { "C=C!B %s", "OR.%-2s B,C" }, + { "A=A!C %s", "OR.%-2s C,A" }, + { "C=C!D %s", "OR.%-2s D,C" }, + + { "Asrb %s", "SRB.%-2s A" }, + { "Bsrb %s", "SRB.%-2s B" }, + { "Csrb %s", "SRB.%-2s C" }, + { "Dsrb %s", "SRB.%-2s D" }, + + { "Aslc %s", "RLN.%-2s A" }, + { "Bslc %s", "RLN.%-2s B" }, + { "Cslc %s", "RLN.%-2s C" }, + { "Dslc %s", "RLN.%-2s D" }, + { "Asrc %s", "RRN.%-2s A" }, + { "Bsrc %s", "RRN.%-2s B" }, + { "Csrc %s", "RRN.%-2s C" }, + { "Dsrc %s", "RRN.%-2s D" }, + + { "A=A+B %s", "ADD.%-2s B,A" }, + { "B=B+C %s", "ADD.%-2s C,B" }, + { "C=C+A %s", "ADD.%-2s A,C" }, + { "D=D+C %s", "ADD.%-2s C,D" }, + { "A=A+A %s", "ADD.%-2s A,A" }, + { "B=B+B %s", "ADD.%-2s B,B" }, + { "C=C+C %s", "ADD.%-2s C,C" }, + { "D=D+C %s", "ADD.%-2s D,D" }, + { "B=B+A %s", "ADD.%-2s A,B" }, + { "C=C+B %s", "ADD.%-2s B,C" }, + { "A=A+C %s", "ADD.%-2s C,A" }, + { "C=C+D %s", "ADD.%-2s D,C" }, + { "A=A-1 %s", "DEC.%-2s A" }, + { "B=B-1 %s", "DEC.%-2s B" }, + { "C=C-1 %s", "DEC.%-2s C" }, + { "D=D-1 %s", "DEC.%-2s D" }, + + { "A=A-B %s", "ADD.%-2s B,A" }, + { "B=B-C %s", "ADD.%-2s C,B" }, + { "C=C-A %s", "ADD.%-2s A,C" }, + { "D=D-C %s", "ADD.%-2s C,D" }, + { "A=A+1 %s", "INC.%-2s A" }, + { "B=B+1 %s", "INC.%-2s B" }, + { "C=C+1 %s", "INC.%-2s C" }, + { "D=D+1 %s", "INC.%-2s D" }, + { "B=B-A %s", "SUB.%-2s A,B" }, + { "C=C-B %s", "SUB.%-2s B,C" }, + { "A=A-C %s", "SUB.%-2s C,A" }, + { "C=C-D %s", "SUB.%-2s D,C" }, + { "A=B-A %s", "SUBN.%-2s B,A" }, + { "B=C-B %s", "SUBN.%-2s C,B" }, + { "C=A-C %s", "SUBN.%-2s A,C" }, + { "D=C-D %s", "SUBN.%-2s C,D" }, + + { "A=0 %s", "CLR.%-2s A" }, + { "B=0 %s", "CLR.%-2s B" }, + { "C=0 %s", "CLR.%-2s C" }, + { "D=0 %s", "CLR.%-2s D" }, + { "A=B %s", "MOVE.%-2s B,A" }, + { "B=C %s", "MOVE.%-2s C,B" }, + { "C=A %s", "MOVE.%-2s A,C" }, + { "D=C %s", "MOVE.%-2s C,D" }, + { "B=A %s", "MOVE.%-2s A,B" }, + { "C=B %s", "MOVE.%-2s B,C" }, + { "A=C %s", "MOVE.%-2s C,A" }, + { "C=D %s", "MOVE.%-2s D,C" }, + { "ABex %s", "SWAP.%-2s A,B" }, + { "BCex %s", "SWAP.%-2s B,C" }, + { "ACex %s", "SWAP.%-2s A,C" }, + { "CDex %s", "SWAP.%-2s C,D" }, + + { "Asl %s", "SLN.%-2s A" }, + { "Bsl %s", "SLN.%-2s B" }, + { "Csl %s", "SLN.%-2s C" }, + { "Dsl %s", "SLN.%-2s D" }, + { "Asr %s", "SRN.%-2s A" }, + { "Bsr %s", "SRN.%-2s B" }, + { "Csr %s", "SRN.%-2s C" }, + { "Dsr %s", "SRN.%-2s D" }, + { "A=-A %s", "NEG.%-2s A" }, + { "B=-B %s", "NEG.%-2s B" }, + { "C=-C %s", "NEG.%-2s C" }, + { "D=-D %s", "NEG.%-2s D" }, + { "A=-A-1 %s", "NOT.%-2s A" }, + { "B=-B-1 %s", "NOT.%-2s B" }, + { "C=-C-1 %s", "NOT.%-2s C" }, + { "D=-D-1 %s", "NOT.%-2s D" } }; -enum opcode_sel -{ - Complete=-1, - Illegal, - Opcode0, Opcode0E, Opcode0Ea, - Opcode1, Opcode10, Opcode11, Opcode12, Opcode13, Opcode14, Opcode15, - Opcode8, Opcode80, Opcode808, Opcode8081, - Opcode81, Opcode818, Opcode818a, Opcode819, Opcode819a, - Opcode81A, Opcode81Aa, Opcode81Aa0,Opcode81Aa1, Opcode81Aa2, Opcode81B, - Opcode8A, Opcode8B, - Opcode9, Opcode9a, Opcode9b, - OpcodeA, OpcodeAa, OpcodeAb, - OpcodeB, OpcodeBa, OpcodeBb, - OpcodeC, - OpcodeD, - OpcodeE, - OpcodeF -}; - -enum opcode_adr -{ - AdrNone, - AdrAF, AdrA, AdrB, AdrCount, - BranchReturn, TestBranchRet, ImmBranch, - ABranchReturn, // address field A - xBranchReturn, // address field specified in previous opcode entry - Imm, ImmCount, ImmCload, Imm2, Imm4, Imm5, - Dis3, Dis3Call, Dis4, Dis4Call, Abs, - FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, FieldA, - AdrImmCount -}; -struct OPCODE -{ - opcode_sel sel; - opcode_adr adr; - MNEMONICS mnemonic; -}; -static const char *field_2_string(int adr_enum) +const char *saturn_disassembler::field_2_string(int adr_enum) { switch (adr_enum) { case FieldP: return P; @@ -593,7 +412,7 @@ static const char *field_2_string(int adr_enum) return nullptr; } -static const OPCODE opcodes[][0x10]= { +const saturn_disassembler::OPCODE saturn_disassembler::opcs[][0x10]= { { // first digit { Opcode0 }, @@ -805,7 +624,7 @@ static const OPCODE opcodes[][0x10]= { { Complete, AdrNone, inA }, { Complete, AdrNone, inC }, { Complete, AdrNone, unconfig }, - { Complete, AdrNone, config }, + { Complete, AdrNone, xconfig }, { Complete, AdrNone, Cid }, { Complete, AdrNone, shutdown }, { Opcode808 }, @@ -1258,31 +1077,42 @@ static const OPCODE opcodes[][0x10]= { } }; -static const int field_adr_af[]= +const int saturn_disassembler::field_adr_af[]= { FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, 0, 0, 0, 0, 0, 0, 0, FieldA }; -static const int field_adr_a[]= +const int saturn_disassembler::field_adr_a[]= { FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW}; -static const int field_adr_b[]= +const int saturn_disassembler::field_adr_b[]= { FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW }; -CPU_DISASSEMBLE(saturn) +saturn_disassembler::saturn_disassembler(config *conf) : m_config(conf) +{ +} + +u32 saturn_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t saturn_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int adr=0; int cont=1; // operation still not complete disassembled char bin[10]; int binsize=0; // protocollizing fetched nibbles char number[17]; - const OPCODE *level=opcodes[0]; //pointer to current digit + const OPCODE *level=opcs[0]; //pointer to current digit int op; // currently fetched nibble - int pos = 0; + offs_t pos = pc; int i,c,v; + int mnemonics_bank = m_config->get_nonstandard_mnemonics_mode() ? 1 : 0; + while (cont) { - op = oprom[pos++] & 0xf; + op = opcodes.r8(pos++) & 0xf; level+=op; switch (level->sel) { case Illegal: @@ -1316,155 +1146,155 @@ CPU_DISASSEMBLE(saturn) cont=0; switch (level->adr==AdrNone?adr:level->adr) { case AdrNone: - stream << mnemonics[level->mnemonic].name[set]; + stream << mnemonics[level->mnemonic][mnemonics_bank]; break; case Imm: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], oprom[pos++]); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], opcodes.r8(pos++)); break; case ImmCount: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], oprom[pos++]+1); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], opcodes.r8(pos++)+1); break; case AdrImmCount: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], field_2_string(adr), oprom[pos++]+1); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], field_2_string(adr), opcodes.r8(pos++)+1); break; case AdrCount: // mnemonics have string %s for address field - snprintf(number,sizeof(number),"%x",oprom[pos++]+1); - util::stream_format(stream, mnemonics[level->mnemonic].name[set], number); + snprintf(number,sizeof(number),"%x",opcodes.r8(pos++)+1); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], number); break; case Imm2: - v=oprom[pos++]; - v|=oprom[pos++]<<4; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], v); + v=opcodes.r8(pos++); + v|=opcodes.r8(pos++)<<4; + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v); break; case Imm4: - v=oprom[pos++]; - v|=oprom[pos++]<<4; - v|=oprom[pos++]<<8; - v|=oprom[pos++]<<12; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], v); + v=opcodes.r8(pos++); + v|=opcodes.r8(pos++)<<4; + v|=opcodes.r8(pos++)<<8; + v|=opcodes.r8(pos++)<<12; + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v); break; case Imm5: - v=oprom[pos++]; - v|=oprom[pos++]<<4; - v|=oprom[pos++]<<8; - v|=oprom[pos++]<<12; - v|=oprom[pos++]<<16; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], v); + v=opcodes.r8(pos++); + v|=opcodes.r8(pos++)<<4; + v|=opcodes.r8(pos++)<<8; + v|=opcodes.r8(pos++)<<12; + v|=opcodes.r8(pos++)<<16; + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v); break; case ImmCload: - c=i=oprom[pos++] & 0xf; + c=i=opcodes.r8(pos++) & 0xf; number[i+1]=0; - for (;i>=0; i--) number[i]=number_2_hex[oprom[pos++] & 0xf]; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c+1, number); + for (;i>=0; i--) number[i]=number_2_hex[opcodes.r8(pos++) & 0xf]; + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c+1, number); break; case Dis3: SATURN_PEEKOP_DIS12(v); c=(pc+pos-3+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Dis3Call: SATURN_PEEKOP_DIS12(v); c=(pc+pos+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Dis4: SATURN_PEEKOP_DIS16(v); c=(pc+pos-4+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Dis4Call: SATURN_PEEKOP_DIS16(v); c=(pc+pos+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c ); break; case Abs: SATURN_PEEKOP_ADR(v); - util::stream_format(stream, mnemonics[level->mnemonic].name[set], v ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], v ); break; case BranchReturn: SATURN_PEEKOP_DIS8(v); if (v==0) { - stream << mnemonics[level->mnemonic+1].name[set]; + stream << mnemonics[level->mnemonic+1][mnemonics_bank]; } else { c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], c); } break; case ABranchReturn: SATURN_PEEKOP_DIS8(v); if (v==0) { - util::stream_format(stream, mnemonics[level->mnemonic+1].name[set], A); + util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], A); } else { c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], A, c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], A, c); } break; case xBranchReturn: SATURN_PEEKOP_DIS8(v); if (v==0) { - util::stream_format(stream, mnemonics[level->mnemonic+1].name[set], field_2_string(adr)); + util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], field_2_string(adr)); } else { c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], field_2_string(adr), c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], field_2_string(adr), c); } break; case TestBranchRet: - i=oprom[pos++]; + i=opcodes.r8(pos++); SATURN_PEEKOP_DIS8(v); if (v==0) { - util::stream_format(stream, mnemonics[level->mnemonic+1].name[set], i); + util::stream_format(stream, mnemonics[level->mnemonic+1][mnemonics_bank], i); } else { c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], i, c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], i, c); } break; case ImmBranch: - i=oprom[pos++]; + i=opcodes.r8(pos++); SATURN_PEEKOP_DIS8(v); c=(pc+pos-2+v)&0xfffff; - util::stream_format(stream, mnemonics[level->mnemonic].name[set], i, c); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], i, c); break; case FieldP: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], P ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], P ); break; case FieldWP: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], WP ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], WP ); break; case FieldXS: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], XS ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], XS ); break; case FieldX: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], X ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], X ); break; case FieldS: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], S ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], S ); break; case FieldM: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], M ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], M ); break; case FieldB: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], B ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], B ); break; case FieldA: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], A ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], A ); break; case FieldW: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], W ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], W ); break; case AdrA: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], adr_a[oprom[pos++] & 0x7] ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_a[opcodes.r8(pos++) & 0x7] ); break; case AdrAF: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], adr_af[oprom[pos++] & 0xf] ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_af[opcodes.r8(pos++) & 0xf] ); break; case AdrB: - util::stream_format(stream, mnemonics[level->mnemonic].name[set], adr_b[oprom[pos++] & 0x7] ); + util::stream_format(stream, mnemonics[level->mnemonic][mnemonics_bank], adr_b[opcodes.r8(pos++) & 0x7] ); break; } break; } - level = opcodes[level->sel]; + level = opcs[level->sel]; } - return pos; + return pos - pc; } diff --git a/src/devices/cpu/saturn/saturnds.h b/src/devices/cpu/saturn/saturnds.h new file mode 100644 index 00000000000..676f59ff290 --- /dev/null +++ b/src/devices/cpu/saturn/saturnds.h @@ -0,0 +1,215 @@ +// license:BSD-3-Clause +// copyright-holders:Peter Trauner,Antoine Mine +/***************************************************************************** + * + * saturnds.c + * portable saturn emulator interface + * (hp calculators) + * + *****************************************************************************/ + +#ifndef MAME_CPU_SATURN_SATURNDS_H +#define MAME_CPU_SATURN_SATURNDS_H + +#pragma once + +class saturn_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + virtual bool get_nonstandard_mnemonics_mode() const = 0; + }; + + saturn_disassembler(config *conf); + virtual ~saturn_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // don't split branch and return, source relies on this ordering + enum MNEMONICS + { + Return, ReturnSetXM, ReturnSetCarry, ReturnClearCarry, ReturnFromInterrupt, + jump3,jump4,jump, + call3,call4,call, + branchCarrySet, returnCarrySet, + branchCarryClear, returnCarryClear, + + outCS, outC, inA, inC, + unconfig, xconfig, Cid, shutdown, cp1, reset, buscc, + CcopyP, PcopyC, sreq, CswapP, + + inton, AloadImm, buscb, + clearAbit, setAbit, + branchAbitclear, returnAbitclear, + branchAbitset, returnAbitset, + clearCbit, setCbit, + branchCbitclear, returnCbitclear, + branchCbitset, returnCbitset, + PCloadA, buscd, PCloadC, intoff, rsi, + + jumpA, jumpC, PCcopyA, PCcopyC, AcopyPC, CcopyPC, + + clearHST, + branchHSTclear, returnHSTclear, + + clearBitST, setBitST, + branchSTclear, returnSTclear, + branchSTset, returnSTset, + + branchPdiffers, returnPdiffers, + branchPequals, returnPequals, + + branchAequalsB, returnAequalsB, + branchBequalsC, returnBequalsC, + branchAequalsC, returnAequalsC, + branchCequalsD, returnCequalsD, + branchAdiffersB, returnAdiffersB, + branchBdiffersC, returnBdiffersC, + branchAdiffersC, returnAdiffersC, + branchCdiffersD, returnCdiffersD, + branchAzero, returnAzero, + branchBzero, returnBzero, + branchCzero, returnCzero, + branchDzero, returnDzero, + branchAnotzero, returnAnotzero, + branchBnotzero, returnBnotzero, + branchCnotzero, returnCnotzero, + branchDnotzero, returnDnotzero, + + branchAgreaterB, returnAgreaterB, + branchBgreaterC, returnBgreaterC, + branchCgreaterA, returnCgreaterA, + branchDgreaterC, returnDgreaterC, + branchAlowerB, returnAlowerB, + branchBlowerC, returnBlowerC, + branchClowerA, returnClowerA, + branchDlowerC, returnDlowerC, + branchAnotlowerB, returnAnotlowerB, + branchBnotlowerC, returnBnotlowerC, + branchCnotlowerA, returnCnotlowerA, + branchDnotlowerC, returnDnotlowerC, + branchAnotgreaterB, returnAnotgreaterB, + branchBnotgreaterC, returnBnotgreaterC, + branchCnotgreaterA, returnCnotgreaterA, + branchDnotgreaterC, returnDnotgreaterC, + + SetHexMode, SetDecMode, + PushC, PopC, + + D0loadImm2, D0loadImm4, D0loadImm5, + D1loadImm2, D1loadImm4, D1loadImm5, + PloadImm, CloadImm, + + clearST, + CcopyST, STcopyC, + swapCST, + + incP, decP, + + R0copyA, R1copyA, R2copyA, R3copyA, R4copyA, + R0copyC, R1copyC, R2copyC, R3copyC, R4copyC, + + AcopyR0, AcopyR1, AcopyR2, AcopyR3, AcopyR4, + CcopyR0, CcopyR1, CcopyR2, CcopyR3, CcopyR4, + + D0copyA, D1copyA, D0copyC, D1copyC, + D0copyAShort, D1copyAShort, D0copyCShort, D1copyCShort, // other class mnemonic + + SwapAR0, SwapAR1, SwapAR2, SwapAR3, SwapAR4, + SwapCR0, SwapCR1, SwapCR2, SwapCR3, SwapCR4, + + SwapAD0, SwapAD1, SwapCD0, SwapCD1, + SwapAD0Short, SwapAD1Short, SwapCD0Short, SwapCD1Short, // other class mnemonic + + D0storeA, D1storeA, D0storeC, D1storeC, + AloadD0, AloadD1, CloadD0, CloadD1, + + D0addImm, D1addImm, D0subImm, D1subImm, + AaddImm, BaddImm, CaddImm, DaddImm, + AsubImm, BsubImm, CsubImm, DsubImm, + + AandB, BandC, CandA, DandC, BandA, CandB, AandC, CandD, + AorB, BorC, CorA, DorC, BorA, CorB, AorC, CorD, + + Ashiftrightbit, Bshiftrightbit, Cshiftrightbit, Dshiftrightbit, + + AshiftleftCarry, BshiftleftCarry, CshiftleftCarry, DshiftleftCarry, + AshiftrightCarry, BshiftrightCarry, CshiftrightCarry, DshiftrightCarry, + + AaddB, BaddC, CaddA, DaddC, AaddA, BaddB, CaddC, DaddD, + BaddA, CaddB, AaddC, CaddD, decA, decB, decC, decD, + + AsubB, BsubC, CsubA, DsubC, incA, incB, incC, incD, + BsubA, CsubB, AsubC, CsubD, AsubnB, BsubnC, CsubnA, DsubnC, + + clearA, clearB, clearC, clearD, + AcopyB, BcopyC, CcopyA, DcopyC, BcopyA, CcopyB, AcopyC, CcopyD, + AswapB, BswapC, CswapA, DswapC, + + Ashiftleft, Bshiftleft, Cshiftleft, Dshiftleft, + Ashiftright, Bshiftright, Cshiftright, Dshiftright, + negateA, negateB, negateC, negateD, + notA, notB, notC, notD + }; + + enum opcode_sel + { + Complete=-1, + Illegal, + Opcode0, Opcode0E, Opcode0Ea, + Opcode1, Opcode10, Opcode11, Opcode12, Opcode13, Opcode14, Opcode15, + Opcode8, Opcode80, Opcode808, Opcode8081, + Opcode81, Opcode818, Opcode818a, Opcode819, Opcode819a, + Opcode81A, Opcode81Aa, Opcode81Aa0,Opcode81Aa1, Opcode81Aa2, Opcode81B, + Opcode8A, Opcode8B, + Opcode9, Opcode9a, Opcode9b, + OpcodeA, OpcodeAa, OpcodeAb, + OpcodeB, OpcodeBa, OpcodeBb, + OpcodeC, + OpcodeD, + OpcodeE, + OpcodeF + }; + + enum opcode_adr + { + AdrNone, + AdrAF, AdrA, AdrB, AdrCount, + BranchReturn, TestBranchRet, ImmBranch, + ABranchReturn, // address field A + xBranchReturn, // address field specified in previous opcode entry + Imm, ImmCount, ImmCload, Imm2, Imm4, Imm5, + Dis3, Dis3Call, Dis4, Dis4Call, Abs, + FieldP, FieldWP, FieldXS, FieldX, FieldS, FieldM, FieldB, FieldW, FieldA, + AdrImmCount + }; + + struct OPCODE + { + opcode_sel sel; + opcode_adr adr; + MNEMONICS mnemonic; + }; + + config *m_config; + + static const char *const adr_b[]; + static const char *const adr_af[]; + static const char *const adr_a[]; + static const char number_2_hex[]; + + static const char *const mnemonics[][2]; + static const OPCODE opcs[][0x10]; + + static const int field_adr_af[]; + static const int field_adr_a[]; + static const int field_adr_b[]; + + const char *field_2_string(int adr_enum); + +}; + +#endif diff --git a/src/devices/cpu/sc61860/sc61860.cpp b/src/devices/cpu/sc61860/sc61860.cpp index a4f82ccdedc..7277cbc444c 100644 --- a/src/devices/cpu/sc61860/sc61860.cpp +++ b/src/devices/cpu/sc61860/sc61860.cpp @@ -19,7 +19,7 @@ #include "emu.h" #include "sc61860.h" - +#include "scdasm.h" #include "debugger.h" @@ -69,11 +69,9 @@ device_memory_interface::space_config_vector sc61860_device::memory_space_config }; } - -offs_t sc61860_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *sc61860_device::create_disassembler() { - extern CPU_DISASSEMBLE( sc61860 ); - return CPU_DISASSEMBLE_NAME(sc61860)(this, stream, pc, oprom, opram, options); + return new sc61860_disassembler; } @@ -112,7 +110,7 @@ void sc61860_device::device_start() m_2ms_tick_timer->adjust(attotime::from_hz(500), 0, attotime::from_hz(500)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_reset.resolve(); m_brk.resolve(); m_x.resolve(); diff --git a/src/devices/cpu/sc61860/sc61860.h b/src/devices/cpu/sc61860/sc61860.h index de7653b73be..3b9e6745e4d 100644 --- a/src/devices/cpu/sc61860/sc61860.h +++ b/src/devices/cpu/sc61860/sc61860.h @@ -109,9 +109,7 @@ protected: 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 1; } - 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -137,7 +135,7 @@ private: emu_timer *m_2ms_tick_timer; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; uint8_t m_ram[0x100]; // internal special ram, should be 0x60, 0x100 to avoid memory corruption for now diff --git a/src/devices/cpu/sc61860/scdasm.cpp b/src/devices/cpu/sc61860/scdasm.cpp index 050dfaa3b1d..8b14a920d62 100644 --- a/src/devices/cpu/sc61860/scdasm.cpp +++ b/src/devices/cpu/sc61860/scdasm.cpp @@ -11,9 +11,7 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" - -#include "sc61860.h" +#include "scdasm.h" /* new: @@ -67,21 +65,7 @@ ex exchange */ - -enum Adr -{ - Ill, - Imp, - Imm, ImmW, - RelP, RelM, - Abs, - Ptc, - Etc, - Cal, - Lp -}; - -static const struct { const char *mnemonic; Adr adr; } table[]={ +const sc61860_disassembler::opcode sc61860_disassembler::table[]={ { "LII", Imm }, { "LIJ", Imm }, { "LIA", Imm }, { "LIB", Imm }, { "IX", Imp }, { "DX", Imp }, { "IY", Imp }, { "DY", Imp }, { "MVW", Imp }, { "EXW", Imp }, { "MVB", Imp }, { "EXB", Imp }, @@ -152,10 +136,15 @@ static const struct { const char *mnemonic; Adr adr; } table[]={ { nullptr }, { nullptr }, { nullptr }, { nullptr }, { nullptr }, { nullptr }, { nullptr }, { nullptr }, }; -CPU_DISASSEMBLE(sc61860) +u32 sc61860_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t sc61860_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint8_t *base_oprom = oprom; - int oper=*(oprom++); + offs_t pos = pc; + int oper=opcodes.r8(pos++); int t; uint16_t adr; @@ -167,32 +156,32 @@ CPU_DISASSEMBLE(sc61860) switch(oper&0xe0) { case 0xe0: util::stream_format(stream,"%-6s%04x",table[oper&0xe0].mnemonic, - *(oprom++)|((oper&0x1f)<<8)); + opcodes.r8(pos++)|((oper&0x1f)<<8)); break; default: switch (table[oper].adr) { case Ill: util::stream_format(stream,"?%02x",oper);break; case Imp: util::stream_format(stream,"%s",table[oper].mnemonic); break; - case Imm: util::stream_format(stream,"%-6s%02x",table[oper].mnemonic, *(oprom++)); break; + case Imm: util::stream_format(stream,"%-6s%02x",table[oper].mnemonic, opcodes.r8(pos++)); break; case ImmW: - adr=(oprom[0]<<8)|oprom[1];oprom+=2; + adr=opcodes.r16(pos); pos+=2; util::stream_format(stream,"%-6s%04x",table[oper].mnemonic, adr); break; case Abs: - adr=(oprom[0]<<8)|oprom[1];oprom+=2; + adr=opcodes.r16(pos); pos+=2; util::stream_format(stream,"%-6s%04x",table[oper].mnemonic, adr); break; case RelM: - adr=pc-*(oprom++); + adr=pc-opcodes.r8(pos++); util::stream_format(stream,"%-6s%04x",table[oper].mnemonic, adr&0xffff); break; case RelP: - adr=pc+*(oprom++); + adr=pc+opcodes.r8(pos++); util::stream_format(stream,"%-6s%04x",table[oper].mnemonic, adr&0xffff); break; case Ptc: - t=*(oprom++); - adr=(oprom[0]<<8)|oprom[1];oprom+=2; + t=opcodes.r8(pos++); + adr=opcodes.r16(pos); pos+=2; util::stream_format(stream,"%-6s%02x,%04x",table[oper].mnemonic,t, adr); break; case Etc: @@ -206,5 +195,5 @@ CPU_DISASSEMBLE(sc61860) } break; } - return oprom - base_oprom; + return pos - pc; } diff --git a/src/devices/cpu/sc61860/scdasm.h b/src/devices/cpu/sc61860/scdasm.h new file mode 100644 index 00000000000..575106ac2c8 --- /dev/null +++ b/src/devices/cpu/sc61860/scdasm.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:Peter Trauner +/***************************************************************************** + * + * scdasm.c + * portable sharp 61860 emulator interface + * (sharp pocket computers) + * + * Copyright Peter Trauner, all rights reserved. + * + *****************************************************************************/ + +#ifndef MAME_CPU_SC61860_SCDASM_H +#define MAME_CPU_SC61860_SCDASM_H + +#pragma once + +class sc61860_disassembler : public util::disasm_interface +{ +public: + sc61860_disassembler() = default; + virtual ~sc61860_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum Adr + { + Ill, + Imp, + Imm, ImmW, + RelP, RelM, + Abs, + Ptc, + Etc, + Cal, + Lp + }; + + struct opcode { + const char *mnemonic; + Adr adr; + }; + + static const opcode table[]; + +}; + +#endif diff --git a/src/devices/cpu/scmp/scmp.cpp b/src/devices/cpu/scmp/scmp.cpp index 94bcb3fcf6c..f85ca4d1ba5 100644 --- a/src/devices/cpu/scmp/scmp.cpp +++ b/src/devices/cpu/scmp/scmp.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "scmp.h" +#include "scmpdasm.h" #include "debugger.h" @@ -54,10 +55,9 @@ ins8060_device::ins8060_device(const machine_config &mconfig, const char *tag, d } -offs_t scmp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *scmp_device::create_disassembler() { - extern CPU_DISASSEMBLE( scmp ); - return CPU_DISASSEMBLE_NAME(scmp)(this, stream, pc, oprom, opram, options); + return new scmp_disassembler; } @@ -502,7 +502,7 @@ void scmp_device::device_start() } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); /* resolve callbacks */ m_flag_out_func.resolve_safe(); diff --git a/src/devices/cpu/scmp/scmp.h b/src/devices/cpu/scmp/scmp.h index 553af2dad0f..1ca7c699af5 100644 --- a/src/devices/cpu/scmp/scmp.h +++ b/src/devices/cpu/scmp/scmp.h @@ -54,9 +54,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -70,7 +68,7 @@ private: uint8_t m_SR; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; devcb_write8 m_flag_out_func; diff --git a/src/devices/cpu/scmp/scmpdasm.cpp b/src/devices/cpu/scmp/scmpdasm.cpp index 2f77afc519d..1a906218a38 100644 --- a/src/devices/cpu/scmp/scmpdasm.cpp +++ b/src/devices/cpu/scmp/scmpdasm.cpp @@ -9,21 +9,24 @@ *****************************************************************************/ #include "emu.h" +#include "scmpdasm.h" -#define OP(A) oprom[(A) - PC] -#define ARG(A) opram[(A) - PC] +u32 scmp_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(scmp) +offs_t scmp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned PC = pc; - uint8_t op = OP(pc++); + uint8_t op = opcodes.r8(pc++); uint8_t ptr = op & 3; if (BIT(op,7)) { // two bytes instructions char as[10]; char aspr[10]; - uint8_t arg = ARG(pc); pc++; + uint8_t arg = params.r8(pc); pc++; if (arg==0x80) { sprintf(as,"E"); } else { diff --git a/src/devices/cpu/scmp/scmpdasm.h b/src/devices/cpu/scmp/scmpdasm.h new file mode 100644 index 00000000000..915f74ee848 --- /dev/null +++ b/src/devices/cpu/scmp/scmpdasm.h @@ -0,0 +1,26 @@ +// license:BSD-3-Clause +// copyright-holders:Miodrag Milanovic +/***************************************************************************** + * + * scmpdasm.c + * + * National Semiconductor SC/MP CPU Disassembly + * + *****************************************************************************/ + +#ifndef MAME_CPU_SCMP_SCMPDASM_H +#define MAME_CPU_SCMP_SCMPDASM_H + +#pragma once + +class scmp_disassembler : public util::disasm_interface +{ +public: + scmp_disassembler() = default; + virtual ~scmp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/score/score.cpp b/src/devices/cpu/score/score.cpp index f346fd93dc1..7f4eaff51dd 100644 --- a/src/devices/cpu/score/score.cpp +++ b/src/devices/cpu/score/score.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "debugger.h" #include "score.h" +#include "scoredsm.h" //************************************************************************** @@ -72,7 +73,7 @@ void score7_cpu_device::device_start() { // find address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); // set our instruction counter m_icountptr = &m_icount; @@ -1348,3 +1349,8 @@ void score7_cpu_device::unemulated_op(const char * op) { fatalerror("%s: unemulated %s (PC=0x%08x)\n", tag(), op, m_ppc); } + +util::disasm_interface *score7_cpu_device::create_disassembler() +{ + return new score7_disassembler; +} diff --git a/src/devices/cpu/score/score.h b/src/devices/cpu/score/score.h index 48d832f3ada..392e2aaa4ac 100644 --- a/src/devices/cpu/score/score.h +++ b/src/devices/cpu/score/score.h @@ -54,9 +54,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - 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; + virtual util::disasm_interface *create_disassembler() override; private: // helpers @@ -73,9 +71,6 @@ private: void check_irq(); void gen_exception(int cause, uint32_t param = 0); - offs_t disasm(std::ostream &stream, offs_t pc, uint32_t opcode); - void disasm32(std::ostream &stream, offs_t pc, uint32_t opcode); - void disasm16(std::ostream &stream, offs_t pc, uint16_t opcode); void unemulated_op(const char * op); // 32-bit opcodes @@ -113,7 +108,7 @@ private: address_space_config m_program_config; address_space * m_program; - direct_read_data * m_direct; + direct_read_data<0> * m_direct; // internal state int m_icount; @@ -130,19 +125,6 @@ private: typedef void (score7_cpu_device::*op_handler)(); static const op_handler s_opcode32_table[4*8]; static const op_handler s_opcode16_table[8]; - - // mnemonics - static const char *const m_cond[16]; - static const char *const m_tcs[4]; - static const char *const m_rix1_op[8]; - static const char *const m_rix2_op[8]; - static const char *const m_r2_op[16]; - static const char *const m_i1_op[8]; - static const char *const m_i2_op[8]; - static const char *const m_ls_op[8]; - static const char *const m_i1a_op[8]; - static const char *const m_i1b_op[8]; - static const char *const m_cr_op[2]; }; DECLARE_DEVICE_TYPE(SCORE7, score7_cpu_device) diff --git a/src/devices/cpu/score/scoredsm.cpp b/src/devices/cpu/score/scoredsm.cpp index d4b5ddbf78a..5e5b6b4e8ac 100644 --- a/src/devices/cpu/score/scoredsm.cpp +++ b/src/devices/cpu/score/scoredsm.cpp @@ -7,23 +7,29 @@ ******************************************************************************/ #include "emu.h" -#include "score.h" +#include "scoredsm.h" #include "scorem.h" -const char *const score7_cpu_device::m_cond[16] = { "cs", "cc", "gtu", "leu", "eq", "ne", "gt", "le", "ge", "lt", "mi", "pl", "vs", "vc", "cnz", "" }; -const char *const score7_cpu_device::m_tcs[4] = { "teq", "tmi", "", ""}; -const char *const score7_cpu_device::m_rix1_op[8] = { "lw" ,"lh" ,"lhu" ,"lb" ,"sw" ,"sh" ,"lbu" ,"sb" }; -const char *const score7_cpu_device::m_rix2_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" }; -const char *const score7_cpu_device::m_r2_op[16] = { "add", "sub", "neg", "cmp", "and", "or", "not", "xor", "lw", "lh", "pop", "lbu", "sw", "sh", "push", "sb" }; -const char *const score7_cpu_device::m_i1_op[8] = { "addi", "", "cmpi", "", "andi", "ori", "ldi", "" }; -const char *const score7_cpu_device::m_i2_op[8] = { "addis", "", "cmpis", "", "andis", "oris", "ldis", "" }; -const char *const score7_cpu_device::m_ls_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" }; -const char *const score7_cpu_device::m_i1a_op[8] = { "addei", "slli", "sdbbp", "srli", "bitclr", "bitset", "bittst", "" }; -const char *const score7_cpu_device::m_i1b_op[8] = { "lwp", "lhp", "", "lbup", "swp", "shp", "", "sbp" }; -const char *const score7_cpu_device::m_cr_op[2] = { "mtcr", "mfcr" }; +const char *const score7_disassembler::m_cond[16] = { "cs", "cc", "gtu", "leu", "eq", "ne", "gt", "le", "ge", "lt", "mi", "pl", "vs", "vc", "cnz", "" }; +const char *const score7_disassembler::m_tcs[4] = { "teq", "tmi", "", ""}; +const char *const score7_disassembler::m_rix1_op[8] = { "lw" ,"lh" ,"lhu" ,"lb" ,"sw" ,"sh" ,"lbu" ,"sb" }; +const char *const score7_disassembler::m_rix2_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" }; +const char *const score7_disassembler::m_r2_op[16] = { "add", "sub", "neg", "cmp", "and", "or", "not", "xor", "lw", "lh", "pop", "lbu", "sw", "sh", "push", "sb" }; +const char *const score7_disassembler::m_i1_op[8] = { "addi", "", "cmpi", "", "andi", "ori", "ldi", "" }; +const char *const score7_disassembler::m_i2_op[8] = { "addis", "", "cmpis", "", "andis", "oris", "ldis", "" }; +const char *const score7_disassembler::m_ls_op[8] = { "lw", "lh", "lhu", "lb", "sw", "sh", "lbu", "sb" }; +const char *const score7_disassembler::m_i1a_op[8] = { "addei", "slli", "sdbbp", "srli", "bitclr", "bitset", "bittst", "" }; +const char *const score7_disassembler::m_i1b_op[8] = { "lwp", "lhp", "", "lbup", "swp", "shp", "", "sbp" }; +const char *const score7_disassembler::m_cr_op[2] = { "mtcr", "mfcr" }; +int32_t score7_disassembler::sign_extend(uint32_t data, uint8_t len) +{ + data &= (1 << len) - 1; + uint32_t sign = 1 << (len - 1); + return (data ^ sign) - sign; +} -void score7_cpu_device::disasm32(std::ostream &stream, offs_t pc, uint32_t opcode) +void score7_disassembler::disasm32(std::ostream &stream, offs_t pc, uint32_t opcode) { switch((opcode >> 25) & 0x1f) { @@ -178,7 +184,7 @@ void score7_cpu_device::disasm32(std::ostream &stream, offs_t pc, uint32_t opcod } } -void score7_cpu_device::disasm16(std::ostream &stream, offs_t pc, uint16_t opcode) +void score7_disassembler::disasm16(std::ostream &stream, offs_t pc, uint16_t opcode) { switch((opcode >> 12) & 0x07) { @@ -252,7 +258,7 @@ void score7_cpu_device::disasm16(std::ostream &stream, offs_t pc, uint16_t opcod } } -offs_t score7_cpu_device::disasm(std::ostream &stream, offs_t pc, uint32_t opcode) +offs_t score7_disassembler::disasm(std::ostream &stream, offs_t pc, uint32_t opcode) { uint8_t p = (pc & 0x02) ? 0 : (((opcode>>30) & 2) | ((opcode>>15) & 1)); @@ -278,13 +284,16 @@ offs_t score7_cpu_device::disasm(std::ostream &stream, offs_t pc, uint32_t opcod //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t score7_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +offs_t score7_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t opcode = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); + return disasm(stream, pc, opcodes.r32(pc)); +} - return disasm(stream, pc, opcode); +u32 score7_disassembler::opcode_alignment() const +{ + return 2; } diff --git a/src/devices/cpu/score/scoredsm.h b/src/devices/cpu/score/scoredsm.h new file mode 100644 index 00000000000..a9f870d2b42 --- /dev/null +++ b/src/devices/cpu/score/scoredsm.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/****************************************************************************** + + Sunplus Technology S+core disassembler + +******************************************************************************/ + +#ifndef MAME_CPU_SCORE_SCOREDSM_H +#define MAME_CPU_SCORE_SCOREDSM_H + +#pragma once + +class score7_disassembler : public util::disasm_interface +{ +public: + score7_disassembler() = default; + virtual ~score7_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + // mnemonics + static const char *const m_cond[16]; + static const char *const m_tcs[4]; + static const char *const m_rix1_op[8]; + static const char *const m_rix2_op[8]; + static const char *const m_r2_op[16]; + static const char *const m_i1_op[8]; + static const char *const m_i2_op[8]; + static const char *const m_ls_op[8]; + static const char *const m_i1a_op[8]; + static const char *const m_i1b_op[8]; + static const char *const m_cr_op[2]; + + int32_t sign_extend(uint32_t data, uint8_t len); + offs_t disasm(std::ostream &stream, offs_t pc, uint32_t opcode); + void disasm32(std::ostream &stream, offs_t pc, uint32_t opcode); + void disasm16(std::ostream &stream, offs_t pc, uint16_t opcode); +}; + +#endif diff --git a/src/devices/cpu/scudsp/scudsp.cpp b/src/devices/cpu/scudsp/scudsp.cpp index 5c2d64e6082..b61c4aedf6d 100644 --- a/src/devices/cpu/scudsp/scudsp.cpp +++ b/src/devices/cpu/scudsp/scudsp.cpp @@ -92,6 +92,7 @@ #include "emu.h" #include "scudsp.h" +#include "scudspdasm.h" #include "debugger.h" @@ -124,10 +125,10 @@ DEFINE_DEVICE_TYPE(SCUDSP, scudsp_cpu_device, "scudsp", "Sega SCUDSP") #define FLAGS_MASK 0x06ff8000 #define INSTA_DMA 1 -#define scudsp_readop(A) m_program->read_dword(A << 2) -#define scudsp_writeop(A, B) m_program->write_dword(A << 2, B) -#define scudsp_readmem(A,MD) m_data->read_dword((A | (MD << 6)) << 2) -#define scudsp_writemem(A,MD,B) m_data->write_dword((A | (MD << 6)) << 2, B) +#define scudsp_readop(A) m_program->read_dword(A) +#define scudsp_writeop(A, B) m_program->write_dword(A, B) +#define scudsp_readmem(A,MD) m_data->read_dword(A | (MD << 6)) +#define scudsp_writemem(A,MD,B) m_data->write_dword(A | (MD << 6), B) uint32_t scudsp_cpu_device::scudsp_get_source_mem_reg_value( uint32_t mode ) { @@ -1050,8 +1051,7 @@ void scudsp_cpu_device::state_string_export(const device_state_entry &entry, std } -offs_t scudsp_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *scudsp_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( scudsp ); - return CPU_DISASSEMBLE_NAME(scudsp)(this, stream, pc, oprom, opram, options); + return new scudsp_disassembler; } diff --git a/src/devices/cpu/scudsp/scudsp.h b/src/devices/cpu/scudsp/scudsp.h index f0ae8df33de..866a98f7df0 100644 --- a/src/devices/cpu/scudsp/scudsp.h +++ b/src/devices/cpu/scudsp/scudsp.h @@ -88,9 +88,7 @@ protected: 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; + virtual util::disasm_interface *create_disassembler() override; devcb_write_line m_out_irq_cb; devcb_read16 m_in_dma_cb; @@ -157,7 +155,4 @@ private: DECLARE_DEVICE_TYPE(SCUDSP, scudsp_cpu_device) - -CPU_DISASSEMBLE( scudsp ); - #endif // MAME_CPU_SCUDSP_SCUDSP_H diff --git a/src/devices/cpu/scudsp/scudspdasm.cpp b/src/devices/cpu/scudsp/scudspdasm.cpp index 584073aceca..a29712a0448 100644 --- a/src/devices/cpu/scudsp/scudspdasm.cpp +++ b/src/devices/cpu/scudsp/scudspdasm.cpp @@ -1,10 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Angelo Salese, Mariusz Wojcieszek #include "emu.h" -#include "debugger.h" -#include "scudsp.h" +#include "scudspdasm.h" -static const char *const ALU_Commands[] = +const char *const scudsp_disassembler::ALU_Commands[] = { " ", /* 0000 */ "AND ", /* 0001 */ @@ -24,7 +23,7 @@ static const char *const ALU_Commands[] = "RL8 ", /* 1111 */ }; -static const char *const X_Commands[] = +const char *const scudsp_disassembler::X_Commands[] = { "", /* 000 */ "", /* 001 */ /* NOP? check instruction @ 0x0B */ @@ -33,7 +32,7 @@ static const char *const X_Commands[] = "MOV %s,X", /* 100 */ }; -static const char *const Y_Commands[] = +const char *const scudsp_disassembler::Y_Commands[] = { "", /* 000 */ "CLR A", /* 001 */ @@ -42,7 +41,7 @@ static const char *const Y_Commands[] = "MOV %s,Y", /* 100 */ }; -static const char *const D1_Commands[] = +const char *const scudsp_disassembler::D1_Commands[] = { "", /* 00 */ "MOV %I8,%d", /* 01 */ @@ -50,7 +49,7 @@ static const char *const D1_Commands[] = "MOV %S,%d", /* 11 */ }; -static const char *const SourceMemory[] = +const char *const scudsp_disassembler::SourceMemory[] = { "M0", /* 000 */ "M1", /* 001 */ @@ -62,7 +61,7 @@ static const char *const SourceMemory[] = "MC3", /* 111 */ }; -static const char *const SourceMemory2[] = +const char *const scudsp_disassembler::SourceMemory2[] = { "M0", /* 0000 */ "M1", /* 0001 */ @@ -82,7 +81,7 @@ static const char *const SourceMemory2[] = "???", /* 1111 */ }; -static const char *const DestMemory[] = +const char *const scudsp_disassembler::DestMemory[] = { "MC0", /* 0000 */ "MC1", /* 0001 */ @@ -102,7 +101,7 @@ static const char *const DestMemory[] = "CT3", /* 1111 */ }; -static const char *const DestDMAMemory[] = +const char *const scudsp_disassembler::DestDMAMemory[] = { "M0", /* 000 */ "M1", /* 001 */ @@ -114,19 +113,19 @@ static const char *const DestDMAMemory[] = "???", /* 111 */ }; -static const char *const MVI_Command[] = +const char *const scudsp_disassembler::MVI_Command[] = { "MVI %I,%d", /* 0 */ "MVI %I,%d,%f", /* 1 */ }; -static const char *const JMP_Command[] = +const char *const scudsp_disassembler::JMP_Command[] = { "JMP %IA", "JMP %f,%IA", }; -static const char *const DMA_Command[] = +const char *const scudsp_disassembler::DMA_Command[] = { "DMA%H%A D0,%M,%I", "DMA%H%A %s,D0,%I", @@ -135,8 +134,9 @@ static const char *const DMA_Command[] = }; -static void scudsp_dasm_prefix( const char* format, char* buffer, uint32_t *data ) +std::string scudsp_disassembler::scudsp_dasm_prefix( const char* format, uint32_t *data ) { + std::string result; for ( ; *format; format++ ) { if ( *format == '%' ) @@ -145,104 +145,82 @@ static void scudsp_dasm_prefix( const char* format, char* buffer, uint32_t *data { case 'H': if ( *data ) - { - strcpy( buffer, "H" ); - } - else - { - *buffer = 0; - } + result += 'H'; break; case 'A': if ( *data == 0 ) - { - strcpy( buffer, "0" ); - } - else if ( *data == 1 ) - { - *buffer = 0; - } - else - { - sprintf( buffer, "%d", 1 << (*data - 1) ); - } + result += '0'; + else if ( *data != 1 ) + result += util::string_format("%d", 1 << (*data - 1) ); break; case 's': - strcpy( buffer, SourceMemory[ *data & 0x7 ] ); + result += SourceMemory[ *data & 0x7 ]; break; case 'd': - strcpy( buffer, DestMemory[ *data & 0xf ] ); + result += DestMemory[ *data & 0xf ]; break; case 'S': - strcpy( buffer, SourceMemory2[ *data & 0xf ] ); + result += SourceMemory2[ *data & 0xf ]; break; case 'I': ++format; if ( *format == '8' ) - { - sprintf( buffer, "#$%x", *data ); - } + result += util::string_format("#$%x", *data ); else if ( *format == 'A' ) - { - sprintf( buffer, "$%X", *data ); - } + result += util::string_format("$%X", *data ); else { --format; - sprintf( buffer, "#$%X", *data ); + result += util::string_format("#$%X", *data ); } break; case 'f': if ( !(*data & 0x20) ) - { - strcpy( buffer, "N" ); - buffer++; - } + result += 'N'; switch( *data & 0xf ) { case 0x3: - strcpy( buffer, "ZS" ); + result += "ZS"; break; case 0x2: - strcpy( buffer, "S" ); + result += 'S'; break; case 0x4: - strcpy( buffer, "C" ); + result += 'C'; break; case 0x8: - strcpy( buffer, "T0" ); + result += "T0"; break; case 0x1: - strcpy( buffer, "Z" ); + result += 'Z'; break; default: - strcpy( buffer, "?" ); + result += '?'; break; } break; case 'M': - strcpy( buffer, DestDMAMemory[ *data ] ); + result += DestDMAMemory[ *data ]; break; } data++; - buffer += strlen( buffer ); } else - { - *buffer++ = *format; - } + result += *format; } - *buffer = 0; + return result; } +u32 scudsp_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(scudsp) +offs_t scudsp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - uint32_t op = oprom[0]<<24|oprom[1]<<16|oprom[2]<<8|oprom[3]<<0; + uint32_t op = opcodes.r32(pc); unsigned size = 1; -// const char *sym, *sym2; - char temp_buffer[64]; uint32_t data[4]; switch( op >> 30 ) @@ -260,31 +238,15 @@ CPU_DISASSEMBLE(scudsp) /* X-Bus */ data[0] = (op & 0x700000) >> 20; if ( op & 0x2000000 ) - { - scudsp_dasm_prefix( X_Commands[ 4 ], temp_buffer, data ); - } - else - { - *temp_buffer = 0; - } - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( X_Commands[ 4 ], data ); - scudsp_dasm_prefix( X_Commands[ (op & 0x1800000) >> 23 ], temp_buffer, data ); - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( X_Commands[ (op & 0x1800000) >> 23 ], data ); data[0] = (op & 0x1C000 ) >> 14 ; if ( op & 0x80000 ) - { - scudsp_dasm_prefix( Y_Commands[4], temp_buffer, data ); - } - else - { - *temp_buffer = 0; - } - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( Y_Commands[4], data ); - scudsp_dasm_prefix( Y_Commands[ (op & 0x60000) >> 17 ], temp_buffer, data ); - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( Y_Commands[ (op & 0x60000) >> 17 ], data ); /* D1-Bus */ switch( (op & 0x3000) >> 12 ) @@ -299,8 +261,7 @@ CPU_DISASSEMBLE(scudsp) break; } - scudsp_dasm_prefix( D1_Commands[ (op & 0x3000) >> 12 ], temp_buffer, data); - util::stream_format(stream, "%s", temp_buffer); + stream << scudsp_dasm_prefix( D1_Commands[ (op & 0x3000) >> 12 ], data); break; case 2: if ( (op & 0x2000000) ) @@ -308,15 +269,13 @@ CPU_DISASSEMBLE(scudsp) data[0] = op & 0x7FFFF; data[1] = (op & 0x3C000000) >> 26; data[2] = (op & 0x3F80000 ) >> 19; - scudsp_dasm_prefix( MVI_Command[1], temp_buffer, data); /* TODO: bad mem*/ - stream << temp_buffer; + stream << scudsp_dasm_prefix( MVI_Command[1], data); /* TODO: bad mem*/ } else { data[0] = op & 0x1FFFFFF; data[1] = (op & 0x3C000000) >> 26; - scudsp_dasm_prefix( MVI_Command[0], temp_buffer, data ); /* TODO: bad mem*/ - stream << temp_buffer; + stream << scudsp_dasm_prefix( MVI_Command[0], data ); /* TODO: bad mem*/ } break; case 3: @@ -327,22 +286,19 @@ CPU_DISASSEMBLE(scudsp) data[1] = (op & 0x38000) >> 15; /* A */ data[2] = (op & 0x700) >> 8; /* Mem */ data[3] = (op & 0xff); - scudsp_dasm_prefix( DMA_Command[(op & 0x3000) >> 12], temp_buffer, data ); - stream << temp_buffer; + stream << scudsp_dasm_prefix( DMA_Command[(op & 0x3000) >> 12], data ); break; case 1: if ( op & 0x3F80000 ) { data[0] = (op & 0x3F80000) >> 19; data[1] = op & 0xff; - scudsp_dasm_prefix( JMP_Command[1], temp_buffer, data ); - stream << temp_buffer; + stream << scudsp_dasm_prefix( JMP_Command[1], data ); } else { data[0] = op & 0xff; - scudsp_dasm_prefix( JMP_Command[0], temp_buffer, data ); - stream << temp_buffer; + stream << scudsp_dasm_prefix( JMP_Command[0], data ); } break; case 2: diff --git a/src/devices/cpu/scudsp/scudspdasm.h b/src/devices/cpu/scudsp/scudspdasm.h new file mode 100644 index 00000000000..7f86d0366aa --- /dev/null +++ b/src/devices/cpu/scudsp/scudspdasm.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese, Mariusz Wojcieszek + +#ifndef MAME_CPU_SCUDSP_SCUDSPDASM_H +#define MAME_CPU_SCUDSP_SCUDSPDASM_H + +#pragma once + +class scudsp_disassembler : public util::disasm_interface +{ +public: + scudsp_disassembler() = default; + virtual ~scudsp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const ALU_Commands[]; + static const char *const X_Commands[]; + static const char *const Y_Commands[]; + static const char *const D1_Commands[]; + static const char *const SourceMemory[]; + static const char *const SourceMemory2[]; + static const char *const DestMemory[]; + static const char *const DestDMAMemory[]; + static const char *const MVI_Command[]; + static const char *const JMP_Command[]; + static const char *const DMA_Command[]; + std::string scudsp_dasm_prefix( const char* format, uint32_t *data ); +}; + +#endif diff --git a/src/devices/cpu/se3208/se3208.cpp b/src/devices/cpu/se3208/se3208.cpp index 45bb8a30c45..fb188002bd8 100644 --- a/src/devices/cpu/se3208/se3208.cpp +++ b/src/devices/cpu/se3208/se3208.cpp @@ -2,6 +2,7 @@ // copyright-holders:ElSemi #include "emu.h" #include "se3208.h" +#include "se3208dis.h" #include "debugger.h" @@ -1720,7 +1721,7 @@ void se3208_device::device_reset() m_ER = 0; m_PPC = 0; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_PC=SE3208_Read32(0); m_SR=0; m_IRQ=CLEAR_LINE; @@ -1785,7 +1786,7 @@ void se3208_device::device_start() BuildTable(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); save_item(NAME(m_R)); save_item(NAME(m_PC)); @@ -1847,8 +1848,7 @@ void se3208_device::execute_set_input( int line, int state ) m_IRQ=state; } -offs_t se3208_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *se3208_device::create_disassembler() { - extern CPU_DISASSEMBLE( se3208 ); - return CPU_DISASSEMBLE_NAME(se3208)(this, stream, pc, oprom, opram, options); + return new se3208_disassembler; } diff --git a/src/devices/cpu/se3208/se3208.h b/src/devices/cpu/se3208/se3208.h index 69cddd0175b..a9fe4249922 100644 --- a/src/devices/cpu/se3208/se3208.h +++ b/src/devices/cpu/se3208/se3208.h @@ -39,9 +39,7 @@ protected: 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -56,7 +54,7 @@ private: uint32_t m_PPC; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; uint8_t m_IRQ; uint8_t m_NMI; diff --git a/src/devices/cpu/se3208/se3208dis.cpp b/src/devices/cpu/se3208/se3208dis.cpp index ca7d3761d61..0ce74883cae 100644 --- a/src/devices/cpu/se3208/se3208dis.cpp +++ b/src/devices/cpu/se3208/se3208dis.cpp @@ -1,22 +1,13 @@ // license:BSD-3-Clause // copyright-holders:ElSemi #include "emu.h" -#include "debugger.h" -#include "se3208.h" - - -static struct -{ - uint32_t PC; - uint32_t SR; - uint32_t ER; -} Context; +#include "se3208dis.h" #define FLAG_E 0x0800 -#define CLRFLAG(f) Context.SR&=~(f); -#define SETFLAG(f) Context.SR|=(f); -#define TESTFLAG(f) (Context.SR&(f)) +#define CLRFLAG(f) SR&=~(f); +#define SETFLAG(f) SR|=(f); +#define TESTFLAG(f) (SR&(f)) #define EXTRACT(val,sbit,ebit) (((val)>>sbit)&((1<<((ebit-sbit)+1))-1)) #define SEX8(val) ((val&0x80)?(val|0xFFFFFF00):(val&0xFF)) @@ -25,8 +16,8 @@ static struct #define ZEX16(val) ((val)&0xFFFF) #define SEX(bits,val) ((val)&(1<<(bits-1))?((val)|(~((1<<bits)-1))):(val&((1<<bits)-1))) -typedef uint32_t (*_OP)(uint16_t Opcode, std::ostream &stream); -#define INST(a) static uint32_t a(uint16_t Opcode, std::ostream &stream) +#define INST(a) uint32_t se3208_disassembler::a(uint16_t Opcode, std::ostream &stream) + INST(INVALIDOP) @@ -42,7 +33,7 @@ INST(LDB) uint32_t SrcDst=EXTRACT(Opcode,8,10); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LDB (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -60,7 +51,7 @@ INST(STB) uint32_t SrcDst=EXTRACT(Opcode,8,10); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "STB %%R%d,(%%R%d,0x%x)",SrcDst,Index,Offset); @@ -80,7 +71,7 @@ INST(LDS) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LDS (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -100,7 +91,7 @@ INST(STS) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "STS %%R%d,(%%R%d,0x%x)",SrcDst,Index,Offset); @@ -120,7 +111,7 @@ INST(LD) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LD (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -140,7 +131,7 @@ INST(ST) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "ST %%R%d,(%%R%d,0x%x)",SrcDst,Index,Offset); @@ -158,7 +149,7 @@ INST(LDBU) uint32_t SrcDst=EXTRACT(Opcode,8,10); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LDBU (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -178,7 +169,7 @@ INST(LDSU) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); if(Index) util::stream_format(stream, "LDSU (%%R%d,0x%x),%%R%d",Index,Offset,SrcDst); @@ -195,12 +186,12 @@ INST(LERI) uint32_t Imm=EXTRACT(Opcode,0,13); if(TESTFLAG(FLAG_E)) - Context.ER=(EXTRACT(Context.ER,0,17)<<14)|Imm; + ER=(EXTRACT(ER,0,17)<<14)|Imm; else - Context.ER=SEX(14,Imm); + ER=SEX(14,Imm); - //util::stream_format(stream, "LERI 0x%x\t\tER=%08X",Imm,Context.ER); - util::stream_format(stream, "LERI 0x%x",Imm/*,Context.ER*/); + //util::stream_format(stream, "LERI 0x%x\t\tER=%08X",Imm,ER); + util::stream_format(stream, "LERI 0x%x",Imm/*,ER*/); SETFLAG(FLAG_E); return 0; @@ -214,7 +205,7 @@ INST(LDSP) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LD (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -230,7 +221,7 @@ INST(STSP) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "ST %%R%d,(%%SP,0x%x)",SrcDst,Offset); @@ -306,7 +297,7 @@ INST(POP) if(Ret) strcat(str,"\n"); stream << str; - return Ret ? DASMFLAG_STEP_OUT : 0; + return Ret ? STEP_OUT : 0; } INST(LEATOSP) @@ -315,7 +306,7 @@ INST(LEATOSP) uint32_t Index=EXTRACT(Opcode,3,5); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); else Offset=SEX(4,Offset); @@ -334,7 +325,7 @@ INST(LEAFROMSP) uint32_t Index=EXTRACT(Opcode,3,5); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); else Offset=SEX(4,Offset); @@ -351,7 +342,7 @@ INST(LEASPTOSP) Offset<<=2; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,23)<<8)|(Offset&0xff); + Offset=(EXTRACT(ER,0,23)<<8)|(Offset&0xff); else Offset=SEX(10,Offset); @@ -380,7 +371,7 @@ INST(LDI) uint32_t Imm=EXTRACT(Opcode,0,7); if(TESTFLAG(FLAG_E)) - Imm=(EXTRACT(Context.ER,0,27)<<4)|(Imm&0xf); + Imm=(EXTRACT(ER,0,27)<<4)|(Imm&0xf); else Imm=SEX8(Imm); @@ -396,7 +387,7 @@ INST(LDBSP) uint32_t SrcDst=EXTRACT(Opcode,4,6); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LDB (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -410,7 +401,7 @@ INST(STBSP) uint32_t SrcDst=EXTRACT(Opcode,4,6); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "STB %%R%d,(%%SP,0x%x)",SrcDst,Offset); @@ -426,7 +417,7 @@ INST(LDSSP) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LDS (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -442,7 +433,7 @@ INST(STSSP) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "STS %%R%d,(%%SP,0x%x)",SrcDst,Offset); @@ -456,7 +447,7 @@ INST(LDBUSP) uint32_t SrcDst=EXTRACT(Opcode,4,6); if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LDBU (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -472,7 +463,7 @@ INST(LDSUSP) Offset<<=1; if(TESTFLAG(FLAG_E)) - Offset=(EXTRACT(Context.ER,0,27)<<4)|(Offset&0xf); + Offset=(EXTRACT(ER,0,27)<<4)|(Offset&0xf); util::stream_format(stream, "LDSU (%%SP,0x%x),%%R%d",Offset,SrcDst); @@ -488,7 +479,7 @@ INST(ADDI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -506,7 +497,7 @@ INST(SUBI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -525,7 +516,7 @@ INST(ADCI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -543,7 +534,7 @@ INST(SBCI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -561,7 +552,7 @@ INST(ANDI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -579,7 +570,7 @@ INST(ORI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -597,7 +588,7 @@ INST(XORI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -614,7 +605,7 @@ INST(CMPI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -631,7 +622,7 @@ INST(TSTI) uint32_t Imm2=Imm; if(TESTFLAG(FLAG_E)) - Imm2=(EXTRACT(Context.ER,0,27)<<4)|(Imm2&0xf); + Imm2=(EXTRACT(ER,0,27)<<4)|(Imm2&0xf); else Imm2=SEX(4,Imm2); @@ -756,14 +747,14 @@ INST(CALL) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "CALL 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "CALL 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); - return DASMFLAG_STEP_OVER; + return STEP_OVER; } INST(JV) @@ -772,11 +763,11 @@ INST(JV) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JV 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JV 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -788,11 +779,11 @@ INST(JNV) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JNV 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JNV 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -804,11 +795,11 @@ INST(JC) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JC 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JC 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -820,11 +811,11 @@ INST(JNC) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JNC 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JNC 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -836,11 +827,11 @@ INST(JP) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JP 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JP 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -852,11 +843,11 @@ INST(JM) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JM 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JM 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -868,11 +859,11 @@ INST(JNZ) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JNZ 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JNZ 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -884,11 +875,11 @@ INST(JZ) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JZ 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JZ 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -900,11 +891,11 @@ INST(JGE) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JGE 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JGE 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -916,11 +907,11 @@ INST(JLE) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JLE 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JLE 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -932,11 +923,11 @@ INST(JHI) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JHI 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JHI 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -948,11 +939,11 @@ INST(JLS) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JLS 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JLS 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -964,11 +955,11 @@ INST(JGT) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JGT 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JGT 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -980,11 +971,11 @@ INST(JLT) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JLT 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JLT 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -998,11 +989,11 @@ INST(JMP) uint32_t Offset2; if(TESTFLAG(FLAG_E)) - Offset2=(EXTRACT(Context.ER,0,22)<<8)|Offset; + Offset2=(EXTRACT(ER,0,22)<<8)|Offset; else Offset2=SEX(8,Offset); Offset2<<=1; - util::stream_format(stream, "JMP 0x%x",Context.PC+2+Offset2); + util::stream_format(stream, "JMP 0x%x",PC+2+Offset2); CLRFLAG(FLAG_E); return 0; @@ -1025,7 +1016,7 @@ INST(CALLR) util::stream_format(stream, "CALLR %%R%d",Src); CLRFLAG(FLAG_E); - return DASMFLAG_STEP_OVER; + return STEP_OVER; } INST(ASR) @@ -1144,7 +1135,7 @@ INST(MVFC) return 0; } -static _OP DecodeOp(uint16_t Opcode) +se3208_disassembler::_OP se3208_disassembler::DecodeOp(uint16_t Opcode) { switch(EXTRACT(Opcode,14,15)) { @@ -1154,38 +1145,38 @@ static _OP DecodeOp(uint16_t Opcode) switch(Op) { case 0x0: - return LDB; + return &se3208_disassembler::LDB; case 0x1: - return LDS; + return &se3208_disassembler::LDS; case 0x2: - return LD; + return &se3208_disassembler::LD; case 0x3: - return LDBU; + return &se3208_disassembler::LDBU; case 0x4: - return STB; + return &se3208_disassembler::STB; case 0x5: - return STS; + return &se3208_disassembler::STS; case 0x6: - return ST; + return &se3208_disassembler::ST; case 0x7: - return LDSU; + return &se3208_disassembler::LDSU; } } break; case 0x1: - return LERI; + return &se3208_disassembler::LERI; case 0x2: { switch(EXTRACT(Opcode,11,13)) { case 0: - return LDSP; + return &se3208_disassembler::LDSP; case 1: - return STSP; + return &se3208_disassembler::STSP; case 2: - return PUSH; + return &se3208_disassembler::PUSH; case 3: - return POP; + return &se3208_disassembler::POP; case 4: case 5: case 6: @@ -1201,30 +1192,30 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,6,8)) { case 0: - return ADDI; + return &se3208_disassembler::ADDI; case 1: - return ADCI; + return &se3208_disassembler::ADCI; case 2: - return SUBI; + return &se3208_disassembler::SUBI; case 3: - return SBCI; + return &se3208_disassembler::SBCI; case 4: - return ANDI; + return &se3208_disassembler::ANDI; case 5: - return ORI; + return &se3208_disassembler::ORI; case 6: - return XORI; + return &se3208_disassembler::XORI; case 7: switch(EXTRACT(Opcode,0,2)) { case 0: - return CMPI; + return &se3208_disassembler::CMPI; case 1: - return TSTI; + return &se3208_disassembler::TSTI; case 2: - return LEATOSP; + return &se3208_disassembler::LEATOSP; case 3: - return LEAFROMSP; + return &se3208_disassembler::LEAFROMSP; } break; } @@ -1239,30 +1230,30 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,6,8)) { case 0: - return ADD; + return &se3208_disassembler::ADD; case 1: - return ADC; + return &se3208_disassembler::ADC; case 2: - return SUB; + return &se3208_disassembler::SUB; case 3: - return SBC; + return &se3208_disassembler::SBC; case 4: - return AND; + return &se3208_disassembler::AND; case 5: - return OR; + return &se3208_disassembler::OR; case 6: - return XOR; + return &se3208_disassembler::XOR; case 7: switch(EXTRACT(Opcode,0,2)) { case 0: - return CMP; + return &se3208_disassembler::CMP; case 1: - return TST; + return &se3208_disassembler::TST; case 2: - return MOV; + return &se3208_disassembler::MOV; case 3: - return NEG; + return &se3208_disassembler::NEG; } break; } @@ -1271,42 +1262,42 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,8,11)) { case 0x0: - return JNV; + return &se3208_disassembler::JNV; case 0x1: - return JV; + return &se3208_disassembler::JV; case 0x2: - return JP; + return &se3208_disassembler::JP; case 0x3: - return JM; + return &se3208_disassembler::JM; case 0x4: - return JNZ; + return &se3208_disassembler::JNZ; case 0x5: - return JZ; + return &se3208_disassembler::JZ; case 0x6: - return JNC; + return &se3208_disassembler::JNC; case 0x7: - return JC; + return &se3208_disassembler::JC; case 0x8: - return JGT; + return &se3208_disassembler::JGT; case 0x9: - return JLT; + return &se3208_disassembler::JLT; case 0xa: - return JGE; + return &se3208_disassembler::JGE; case 0xb: - return JLE; + return &se3208_disassembler::JLE; case 0xc: - return JHI; + return &se3208_disassembler::JHI; case 0xd: - return JLS; + return &se3208_disassembler::JLS; case 0xe: - return JMP; + return &se3208_disassembler::JMP; case 0xf: - return CALL; + return &se3208_disassembler::CALL; } break; case 2: if(Opcode&(1<<11)) - return LDI; + return &se3208_disassembler::LDI; else //SP Ops { if(Opcode&(1<<10)) @@ -1314,24 +1305,24 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,7,9)) { case 0: - return LDBSP; + return &se3208_disassembler::LDBSP; case 1: - return LDSSP; + return &se3208_disassembler::LDSSP; case 3: - return LDBUSP; + return &se3208_disassembler::LDBUSP; case 4: - return STBSP; + return &se3208_disassembler::STBSP; case 5: - return STSSP; + return &se3208_disassembler::STSSP; case 7: - return LDSUSP; + return &se3208_disassembler::LDSUSP; } } else { if(Opcode&(1<<9)) { - return LEASPTOSP; + return &se3208_disassembler::LEASPTOSP; } else { @@ -1343,21 +1334,21 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,4,7)) { case 0: - return EXTB; + return &se3208_disassembler::EXTB; case 1: - return EXTS; + return &se3208_disassembler::EXTS; case 8: - return JR; + return &se3208_disassembler::JR; case 9: - return CALLR; + return &se3208_disassembler::CALLR; case 10: - return SET; + return &se3208_disassembler::SET; case 11: - return CLR; + return &se3208_disassembler::CLR; case 12: - return SWI; + return &se3208_disassembler::SWI; case 13: - return HALT; + return &se3208_disassembler::HALT; } } } @@ -1374,40 +1365,45 @@ static _OP DecodeOp(uint16_t Opcode) switch(EXTRACT(Opcode,3,4)) { case 0: - return ASR; + return &se3208_disassembler::ASR; case 1: - return LSR; + return &se3208_disassembler::LSR; case 2: - return ASL; + return &se3208_disassembler::ASL; //case 3: - // return LSL; + // return &se3208_disassembler::LSL; } break; case 4: - return MULS; + return &se3208_disassembler::MULS; case 6: if(Opcode&(1<<3)) - return MVFC; + return &se3208_disassembler::MVFC; else - return MVTC; + return &se3208_disassembler::MVTC; } break; } break; } - return INVALIDOP; + return &se3208_disassembler::INVALIDOP; } -CPU_DISASSEMBLE(se3208) +u32 se3208_disassembler::opcode_alignment() const +{ + return 2; +} + +offs_t se3208_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint16_t Opcode; CLRFLAG(FLAG_E); - Context.ER=0; + ER=0; - Context.PC=pc; - Opcode=oprom[0] | (oprom[1] << 8); - return 2 | ((*DecodeOp(Opcode))(Opcode, stream)) | DASMFLAG_SUPPORTED; + PC=pc; + Opcode=opcodes.r16(pc); + return 2 | ((this->*DecodeOp(Opcode))(Opcode, stream)) | SUPPORTED; } diff --git a/src/devices/cpu/se3208/se3208dis.h b/src/devices/cpu/se3208/se3208dis.h new file mode 100644 index 00000000000..ffe66c602c7 --- /dev/null +++ b/src/devices/cpu/se3208/se3208dis.h @@ -0,0 +1,103 @@ +// license:BSD-3-Clause +// copyright-holders:ElSemi + +#ifndef MAME_CPU_SE3208_SE3208DIS_H +#define MAME_CPU_SE3208_SE3208DIS_H + +#pragma once + +class se3208_disassembler : public util::disasm_interface +{ +public: + se3208_disassembler() = default; + virtual ~se3208_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + typedef uint32_t (se3208_disassembler::*_OP)(uint16_t Opcode, std::ostream &stream); + + uint32_t INVALIDOP(uint16_t Opcode, std::ostream &stream); + uint32_t LDB(uint16_t Opcode, std::ostream &stream); + uint32_t STB(uint16_t Opcode, std::ostream &stream); + uint32_t LDS(uint16_t Opcode, std::ostream &stream); + uint32_t STS(uint16_t Opcode, std::ostream &stream); + uint32_t LD(uint16_t Opcode, std::ostream &stream); + uint32_t ST(uint16_t Opcode, std::ostream &stream); + uint32_t LDBU(uint16_t Opcode, std::ostream &stream); + uint32_t LDSU(uint16_t Opcode, std::ostream &stream); + uint32_t LERI(uint16_t Opcode, std::ostream &stream); + uint32_t LDSP(uint16_t Opcode, std::ostream &stream); + uint32_t STSP(uint16_t Opcode, std::ostream &stream); + uint32_t PUSH(uint16_t Opcode, std::ostream &stream); + uint32_t POP(uint16_t Opcode, std::ostream &stream); + uint32_t LEATOSP(uint16_t Opcode, std::ostream &stream); + uint32_t LEAFROMSP(uint16_t Opcode, std::ostream &stream); + uint32_t LEASPTOSP(uint16_t Opcode, std::ostream &stream); + uint32_t MOV(uint16_t Opcode, std::ostream &stream); + uint32_t LDI(uint16_t Opcode, std::ostream &stream); + uint32_t LDBSP(uint16_t Opcode, std::ostream &stream); + uint32_t STBSP(uint16_t Opcode, std::ostream &stream); + uint32_t LDSSP(uint16_t Opcode, std::ostream &stream); + uint32_t STSSP(uint16_t Opcode, std::ostream &stream); + uint32_t LDBUSP(uint16_t Opcode, std::ostream &stream); + uint32_t LDSUSP(uint16_t Opcode, std::ostream &stream); + uint32_t ADDI(uint16_t Opcode, std::ostream &stream); + uint32_t SUBI(uint16_t Opcode, std::ostream &stream); + uint32_t ADCI(uint16_t Opcode, std::ostream &stream); + uint32_t SBCI(uint16_t Opcode, std::ostream &stream); + uint32_t ANDI(uint16_t Opcode, std::ostream &stream); + uint32_t ORI(uint16_t Opcode, std::ostream &stream); + uint32_t XORI(uint16_t Opcode, std::ostream &stream); + uint32_t CMPI(uint16_t Opcode, std::ostream &stream); + uint32_t TSTI(uint16_t Opcode, std::ostream &stream); + uint32_t ADD(uint16_t Opcode, std::ostream &stream); + uint32_t SUB(uint16_t Opcode, std::ostream &stream); + uint32_t ADC(uint16_t Opcode, std::ostream &stream); + uint32_t SBC(uint16_t Opcode, std::ostream &stream); + uint32_t AND(uint16_t Opcode, std::ostream &stream); + uint32_t OR(uint16_t Opcode, std::ostream &stream); + uint32_t XOR(uint16_t Opcode, std::ostream &stream); + uint32_t CMP(uint16_t Opcode, std::ostream &stream); + uint32_t TST(uint16_t Opcode, std::ostream &stream); + uint32_t MULS(uint16_t Opcode, std::ostream &stream); + uint32_t NEG(uint16_t Opcode, std::ostream &stream); + uint32_t CALL(uint16_t Opcode, std::ostream &stream); + uint32_t JV(uint16_t Opcode, std::ostream &stream); + uint32_t JNV(uint16_t Opcode, std::ostream &stream); + uint32_t JC(uint16_t Opcode, std::ostream &stream); + uint32_t JNC(uint16_t Opcode, std::ostream &stream); + uint32_t JP(uint16_t Opcode, std::ostream &stream); + uint32_t JM(uint16_t Opcode, std::ostream &stream); + uint32_t JNZ(uint16_t Opcode, std::ostream &stream); + uint32_t JZ(uint16_t Opcode, std::ostream &stream); + uint32_t JGE(uint16_t Opcode, std::ostream &stream); + uint32_t JLE(uint16_t Opcode, std::ostream &stream); + uint32_t JHI(uint16_t Opcode, std::ostream &stream); + uint32_t JLS(uint16_t Opcode, std::ostream &stream); + uint32_t JGT(uint16_t Opcode, std::ostream &stream); + uint32_t JLT(uint16_t Opcode, std::ostream &stream); + uint32_t JMP(uint16_t Opcode, std::ostream &stream); + uint32_t JR(uint16_t Opcode, std::ostream &stream); + uint32_t CALLR(uint16_t Opcode, std::ostream &stream); + uint32_t ASR(uint16_t Opcode, std::ostream &stream); + uint32_t LSR(uint16_t Opcode, std::ostream &stream); + uint32_t ASL(uint16_t Opcode, std::ostream &stream); + uint32_t EXTB(uint16_t Opcode, std::ostream &stream); + uint32_t EXTS(uint16_t Opcode, std::ostream &stream); + uint32_t SET(uint16_t Opcode, std::ostream &stream); + uint32_t CLR(uint16_t Opcode, std::ostream &stream); + uint32_t SWI(uint16_t Opcode, std::ostream &stream); + uint32_t HALT(uint16_t Opcode, std::ostream &stream); + uint32_t MVTC(uint16_t Opcode, std::ostream &stream); + uint32_t MVFC(uint16_t Opcode, std::ostream &stream); + + _OP DecodeOp(uint16_t Opcode); + + uint32_t PC; + uint32_t SR; + uint32_t ER; +}; + +#endif diff --git a/src/devices/cpu/sh/sh.cpp b/src/devices/cpu/sh/sh.cpp index cfdd919227b..f89f260c322 100644 --- a/src/devices/cpu/sh/sh.cpp +++ b/src/devices/cpu/sh/sh.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "sh.h" +#include "sh_dasm.h" void sh_common_execution::device_start() { @@ -2229,7 +2230,10 @@ void sh_common_execution::log_opcode_desc(drcuml_state *drcuml, const opcode_des if (desclist->flags & OPFLAG_VIRTUAL_NOOP) stream << "<virtual nop>"; else - DasmSH2(stream, desclist->pc, desclist->opptr.w[0]); + { + sh_disassembler sh2d(false); + sh2d.dasm_one(stream, desclist->pc, desclist->opptr.w[0]); + } } else stream << "???"; @@ -2259,8 +2263,9 @@ void sh_common_execution::log_add_disasm_comment(drcuml_block *block, uint32_t p { if (m_drcuml->logging()) { + sh_disassembler sh2d(false); std::ostringstream stream; - DasmSH2(stream, pc, op); + sh2d.dasm_one(stream, pc, op); block->append_comment("%08X: %s", pc, stream.str().c_str()); } } diff --git a/src/devices/cpu/sh/sh.h b/src/devices/cpu/sh/sh.h index 87b6ca9d311..1e41d74385b 100644 --- a/src/devices/cpu/sh/sh.h +++ b/src/devices/cpu/sh/sh.h @@ -99,8 +99,6 @@ #define R32(reg) m_regmap[reg] -extern unsigned DasmSH2(std::ostream &stream, unsigned pc, uint16_t opcode); - enum { SH4_PC = 1, SH_SR, SH4_PR, SH4_GBR, SH4_VBR, SH4_DBR, SH4_MACH, SH4_MACL, @@ -349,7 +347,7 @@ public: void sh2drc_add_fastram(offs_t start, offs_t end, uint8_t readonly, void *base); - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_program; std::unique_ptr<drcuml_state> m_drcuml; /* DRC UML generator state */ diff --git a/src/devices/cpu/sh/sh2.cpp b/src/devices/cpu/sh/sh2.cpp index 9a9b28b306d..3d565fb3519 100644 --- a/src/devices/cpu/sh/sh2.cpp +++ b/src/devices/cpu/sh/sh2.cpp @@ -95,7 +95,7 @@ #include "emu.h" #include "sh2.h" #include "sh2comn.h" - +#include "sh_dasm.h" #include "debugger.h" //#define VERBOSE 1 @@ -200,13 +200,11 @@ device_memory_interface::space_config_vector sh2_device::memory_space_config() c }; } -offs_t sh2_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *sh2_device::create_disassembler() { - extern CPU_DISASSEMBLE( sh2 ); - return CPU_DISASSEMBLE_NAME( sh2 )(this, stream, pc, oprom, opram, options); + return new sh_disassembler(false); } - uint8_t sh2_device::RB(offs_t A) { if((A & 0xf0000000) == 0 || (A & 0xf0000000) == 0x20000000) @@ -443,7 +441,7 @@ void sh2_device::device_start() m_ftcsr_read_cb.bind_relative_to(*owner()); m_decrypted_program = has_space(AS_OPCODES) ? &space(AS_OPCODES) : &space(AS_PROGRAM); - m_direct = &m_decrypted_program->direct(); + m_direct = m_decrypted_program->direct<0>(); m_internal = &space(AS_PROGRAM); save_item(NAME(m_cpu_off)); diff --git a/src/devices/cpu/sh/sh2.h b/src/devices/cpu/sh/sh2.h index 3ea520b74ea..7c15b82d5e4 100644 --- a/src/devices/cpu/sh/sh2.h +++ b/src/devices/cpu/sh/sh2.h @@ -109,9 +109,8 @@ protected: 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + address_space *m_decrypted_program; private: diff --git a/src/devices/cpu/sh/sh4.cpp b/src/devices/cpu/sh/sh4.cpp index 37f989eae56..e4e4429c132 100644 --- a/src/devices/cpu/sh/sh4.cpp +++ b/src/devices/cpu/sh/sh4.cpp @@ -30,14 +30,10 @@ #include "sh4comn.h" #include "sh3comn.h" #include "sh4tmu.h" - +#include "sh_dasm.h" #include "debugger.h" -CPU_DISASSEMBLE( sh4 ); -CPU_DISASSEMBLE( sh4be ); - - DEFINE_DEVICE_TYPE(SH3LE, sh3_device, "sh3le", "SH-3 (little)") DEFINE_DEVICE_TYPE(SH3BE, sh3be_device, "sh3be", "SH-3 (big)") DEFINE_DEVICE_TYPE(SH4LE, sh4_device, "sh4le", "SH-4 (little)") @@ -144,27 +140,9 @@ sh4be_device::sh4be_device(const machine_config &mconfig, const char *tag, devic } -offs_t sh34_base_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *sh34_base_device::create_disassembler() { - extern CPU_DISASSEMBLE( sh4 ); - - return CPU_DISASSEMBLE_NAME(sh4)(this, stream, pc, oprom, opram, options); -} - - -offs_t sh3be_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( sh4be ); - - return CPU_DISASSEMBLE_NAME(sh4be)(this, stream, pc, oprom, opram, options); -} - - -offs_t sh4be_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( sh4be ); - - return CPU_DISASSEMBLE_NAME(sh4be)(this, stream, pc, oprom, opram, options); + return new sh_disassembler(true); } @@ -1633,6 +1611,7 @@ void sh34_base_device::device_reset() m_sh2_state->sleep_mode = 0; m_sh4_mmu_enabled = 0; + m_cache_dirty = true; } /*------------------------------------------------- @@ -2076,7 +2055,7 @@ void sh34_base_device::device_start() m_internal = &space(AS_PROGRAM); m_program = &space(AS_PROGRAM); m_io = &space(AS_IO); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); sh4_default_exception_priorities(); m_irln = 15; m_test_irq = 0; @@ -2597,8 +2576,6 @@ static void cfunc_CHECKIRQ(void *param) { ((sh34_base_device *)param)->func_CHEC void sh34_base_device::generate_update_cycles(drcuml_block *block, compiler_state *compiler, uml::parameter param, bool allow_exception) { - /* TODO: this is likely wrong? - I've not seen it called when compiler->checkints is true */ - /* check full interrupts if pending */ if (compiler->checkints) { @@ -2606,7 +2583,7 @@ void sh34_base_device::generate_update_cycles(drcuml_block *block, compiler_stat /* param is pc + 2 (the opcode after the current one) as we're calling from opcode handlers here that will point to the current opcode instead - but I believe the exception functoin requires it to point to the next one so update the + but I believe the exception function requires it to point to the next one so update the local copy of the PC variable here for that? */ UML_MOV(block, mem(&m_sh2_state->pc), param); @@ -3028,7 +3005,7 @@ bool sh34_base_device::generate_group_0_STCDBR(drcuml_block *block, compiler_sta } void sh34_base_device::func_RTE() { RTE(); } -static void cfunc_RTE(void *param) { ((sh34_base_device *)param)->func_RTE(); }; +static void cfunc_RTE(void *param) { ((sh34_base_device *)param)->func_RTE(); }; bool sh34_base_device::generate_group_0_RTE(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, uint16_t opcode, int in_delay_slot, uint32_t ovrpc) { @@ -3036,6 +3013,9 @@ bool sh34_base_device::generate_group_0_RTE(drcuml_block *block, compiler_state save_fast_iregs(block); UML_CALLC(block, cfunc_RTE, this); load_fast_iregs(block); + + compiler->checkints = true; + UML_MOV(block, mem(&m_sh2_state->pc), mem(&m_sh2_state->m_delay)); generate_update_cycles(block, compiler, mem(&m_sh2_state->ea), true); // <subtract cycles> UML_HASHJMP(block, 0, mem(&m_sh2_state->pc), *m_nocode); // and jump to the "resume PC" @@ -3065,6 +3045,9 @@ bool sh34_base_device::generate_group_4_LDCSR(drcuml_block *block, compiler_stat UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); UML_CALLC(block, cfunc_LDCSR, this); load_fast_iregs(block); + + compiler->checkints = true; + return true; } @@ -3077,6 +3060,11 @@ bool sh34_base_device::generate_group_4_LDCMSR(drcuml_block *block, compiler_sta UML_MOV(block, mem(&m_sh2_state->arg0), desc->opptr.w[0]); UML_CALLC(block, cfunc_LDCMSR, this); load_fast_iregs(block); + + compiler->checkints = true; + if (!in_delay_slot) + generate_update_cycles(block, compiler, desc->pc + 2, true); + return true; } diff --git a/src/devices/cpu/sh/sh4.h b/src/devices/cpu/sh/sh4.h index 22a52c0c0f3..6f3c37e862a 100644 --- a/src/devices/cpu/sh/sh4.h +++ b/src/devices/cpu/sh/sh4.h @@ -316,9 +316,7 @@ protected: 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_io_config; @@ -810,7 +808,6 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; }; @@ -839,7 +836,6 @@ public: protected: virtual void execute_run() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; }; class sh4_frontend : public sh_frontend diff --git a/src/devices/cpu/sh/sh_dasm.cpp b/src/devices/cpu/sh/sh_dasm.cpp index b52c6969f65..a2e6dd67496 100644 --- a/src/devices/cpu/sh/sh_dasm.cpp +++ b/src/devices/cpu/sh/sh_dasm.cpp @@ -1,13 +1,14 @@ // license:BSD-3-Clause // copyright-holders:Juergen Buchmueller, R. Belmont #include "emu.h" -#include "debugger.h" -#include "sh2.h" +#include "sh_dasm.h" #define SIGNX8(x) (((int32_t)(x) << 24) >> 24) #define SIGNX12(x) (((int32_t)(x) << 20) >> 20) +#define Rn ((opcode>>8)&15) +#define Rm ((opcode>>4)&15) -static const char *const regname[16] = { +const char *const sh_disassembler::regname[16] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10","R11","R12","R13","R14", // The old SH2 dasm used 'SP' here, the old SH4 used 'R15' @@ -15,7 +16,7 @@ static const char *const regname[16] = { "R15" }; -static uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) { uint32_t flags = 0; switch(opcode & 0x3f) @@ -37,7 +38,7 @@ static uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) break; case 0x0B: stream << "RTS"; - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x12: util::stream_format(stream, "STS GBR,%s", regname[Rn]); @@ -71,7 +72,7 @@ static uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) break; case 0x2B: stream << "RTE"; - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; default: switch(opcode & 15) @@ -129,13 +130,13 @@ static uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode) return flags; } -static uint32_t op0001(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0001(std::ostream &stream, uint32_t pc, uint16_t opcode) { util::stream_format(stream, "MOV.L %s,@($%02X,%s)", regname[Rm], (opcode & 15) * 4, regname[Rn]); return 0; } -static uint32_t op0010(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0010(std::ostream &stream, uint32_t pc, uint16_t opcode) { switch (opcode & 15) { @@ -191,7 +192,7 @@ static uint32_t op0010(std::ostream &stream, uint32_t pc, uint16_t opcode) return 0; } -static uint32_t op0011(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0011(std::ostream &stream, uint32_t pc, uint16_t opcode) { switch (opcode & 15) { @@ -247,7 +248,7 @@ static uint32_t op0011(std::ostream &stream, uint32_t pc, uint16_t opcode) return 0; } -static uint32_t op0100(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0100(std::ostream &stream, uint32_t pc, uint16_t opcode) { uint32_t flags = 0; switch(opcode & 0x3F) @@ -287,7 +288,7 @@ static uint32_t op0100(std::ostream &stream, uint32_t pc, uint16_t opcode) break; case 0x0b: util::stream_format(stream, "JSR %s", regname[Rn]); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; case 0x0e: util::stream_format(stream, "LDC %s,SR", regname[Rn]); @@ -376,13 +377,13 @@ static uint32_t op0100(std::ostream &stream, uint32_t pc, uint16_t opcode) return flags; } -static uint32_t op0101(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0101(std::ostream &stream, uint32_t pc, uint16_t opcode) { util::stream_format(stream, "MOV.L @($%02X,%s),%s", (opcode & 15) * 4, regname[Rm], regname[Rn]); return 0; } -static uint32_t op0110(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0110(std::ostream &stream, uint32_t pc, uint16_t opcode) { switch(opcode & 0xF) @@ -439,13 +440,13 @@ static uint32_t op0110(std::ostream &stream, uint32_t pc, uint16_t opcode) return 0; } -static uint32_t op0111(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0111(std::ostream &stream, uint32_t pc, uint16_t opcode) { util::stream_format(stream, "ADD #$%02X,%s", opcode & 0xff, regname[Rn]); return 0; } -static uint32_t op1000(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1000(std::ostream &stream, uint32_t pc, uint16_t opcode) { switch((opcode >> 8) & 15) { @@ -482,25 +483,25 @@ static uint32_t op1000(std::ostream &stream, uint32_t pc, uint16_t opcode) return 0; } -static uint32_t op1001(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1001(std::ostream &stream, uint32_t pc, uint16_t opcode) { util::stream_format(stream, "MOV.W @($%04X,PC),%s [%08X]", (opcode & 0xff) * 2, regname[Rn], pc+((opcode & 0xff) * 2)+2); return 0; } -static uint32_t op1010(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1010(std::ostream &stream, uint32_t pc, uint16_t opcode) { util::stream_format(stream, "BRA $%08X", SIGNX12(opcode & 0xfff) * 2 + pc + 2); return 0; } -static uint32_t op1011(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1011(std::ostream &stream, uint32_t pc, uint16_t opcode) { util::stream_format(stream, "BSR $%08X", SIGNX12(opcode & 0xfff) * 2 + pc + 2); - return DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + return STEP_OVER | step_over_extra(1); } -static uint32_t op1100(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1100(std::ostream &stream, uint32_t pc, uint16_t opcode) { uint32_t flags = 0; switch((opcode >> 8) & 15) @@ -516,7 +517,7 @@ static uint32_t op1100(std::ostream &stream, uint32_t pc, uint16_t opcode) break; case 3: util::stream_format(stream, "TRAPA #$%02X", opcode & 0xff); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 4: util::stream_format(stream, "MOV.B @($%02X,GBR),R0", opcode & 0xff); @@ -558,61 +559,29 @@ static uint32_t op1100(std::ostream &stream, uint32_t pc, uint16_t opcode) return flags; } -static uint32_t op1101(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1101(std::ostream &stream, uint32_t pc, uint16_t opcode) { util::stream_format(stream, "MOV.L @($%04X,PC),%s [%08X]", (opcode & 0xff) * 4, regname[Rn], ((pc + 2) & ~3) + (opcode & 0xff) * 4); return 0; } -static uint32_t op1110(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1110(std::ostream &stream, uint32_t pc, uint16_t opcode) { util::stream_format(stream, "MOV #$%02X,%s", (opcode & 0xff), regname[Rn]); return 0; } -static uint32_t op1111(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1111(std::ostream &stream, uint32_t pc, uint16_t opcode) { util::stream_format(stream, "unknown $%04X", opcode); return 0; } -unsigned DasmSH2(std::ostream &stream, unsigned pc, uint16_t opcode) -{ - uint32_t flags; - - pc += 2; - - switch ((opcode >> 12) & 15) - { - case 0: flags = op0000(stream, pc, opcode); break; - case 1: flags = op0001(stream, pc, opcode); break; - case 2: flags = op0010(stream, pc, opcode); break; - case 3: flags = op0011(stream, pc, opcode); break; - case 4: flags = op0100(stream, pc, opcode); break; - case 5: flags = op0101(stream, pc, opcode); break; - case 6: flags = op0110(stream, pc, opcode); break; - case 7: flags = op0111(stream, pc, opcode); break; - case 8: flags = op1000(stream, pc, opcode); break; - case 9: flags = op1001(stream, pc, opcode); break; - case 10: flags = op1010(stream, pc, opcode); break; - case 11: flags = op1011(stream, pc, opcode); break; - case 12: flags = op1100(stream, pc, opcode); break; - case 13: flags = op1101(stream, pc, opcode); break; - case 14: flags = op1110(stream, pc, opcode); break; - default: flags = op1111(stream, pc, opcode); break; - } - return 2 | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(sh2) -{ - return DasmSH2(stream, pc, (oprom[0] << 8) | oprom[1]); -} /* SH4 specifics */ -static uint32_t op0000_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0000_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) { uint32_t flags = 0; switch (opcode & 0xF) @@ -739,14 +708,14 @@ static uint32_t op0000_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) { case 0x00: stream << "RTS"; - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x10: stream << "SLEEP"; break; case 0x20: stream << "RTE"; - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; } break; @@ -767,7 +736,7 @@ static uint32_t op0000_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) } -static uint32_t op0100_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op0100_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) { uint32_t flags = 0; switch (opcode & 0xF) @@ -978,7 +947,7 @@ static uint32_t op0100_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) { case 0x00: util::stream_format(stream, "JSR %s", regname[Rn]); - flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1); + flags = STEP_OVER | step_over_extra(1); break; case 0x10: util::stream_format(stream, "TAS %s", regname[Rn]); @@ -1026,7 +995,7 @@ static uint32_t op0100_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) } -static uint32_t op1111_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) +uint32_t sh_disassembler::op1111_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) { switch (opcode & 0xf) { @@ -1149,40 +1118,73 @@ static uint32_t op1111_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode) return 0; } -unsigned DasmSH4(std::ostream &stream, unsigned pc, uint16_t opcode) +offs_t sh_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + u16 opcode = opcodes.r16(pc); + return dasm_one(stream, pc, opcode); +} + +offs_t sh_disassembler::dasm_one(std::ostream &stream, offs_t pc, u16 opcode) { uint32_t flags; pc += 2; - switch ((opcode >> 12) & 15) + if (m_is_sh34) { - case 0: flags = op0000_sh34(stream, pc, opcode); break; - case 1: flags = op0001(stream, pc, opcode); break; - case 2: flags = op0010(stream, pc, opcode); break; - case 3: flags = op0011(stream, pc, opcode); break; - case 4: flags = op0100_sh34(stream, pc, opcode); break; - case 5: flags = op0101(stream, pc, opcode); break; - case 6: flags = op0110(stream, pc, opcode); break; - case 7: flags = op0111(stream, pc, opcode); break; - case 8: flags = op1000(stream, pc, opcode); break; - case 9: flags = op1001(stream, pc, opcode); break; - case 10: flags = op1010(stream, pc, opcode); break; - case 11: flags = op1011(stream, pc, opcode); break; - case 12: flags = op1100(stream, pc, opcode); break; - case 13: flags = op1101(stream, pc, opcode); break; - case 14: flags = op1110(stream, pc, opcode); break; - default: flags = op1111_sh34(stream, pc, opcode); break; + switch ((opcode >> 12) & 15) + { + case 0: flags = op0000_sh34(stream, pc, opcode); break; + case 1: flags = op0001(stream, pc, opcode); break; + case 2: flags = op0010(stream, pc, opcode); break; + case 3: flags = op0011(stream, pc, opcode); break; + case 4: flags = op0100_sh34(stream, pc, opcode); break; + case 5: flags = op0101(stream, pc, opcode); break; + case 6: flags = op0110(stream, pc, opcode); break; + case 7: flags = op0111(stream, pc, opcode); break; + case 8: flags = op1000(stream, pc, opcode); break; + case 9: flags = op1001(stream, pc, opcode); break; + case 10: flags = op1010(stream, pc, opcode); break; + case 11: flags = op1011(stream, pc, opcode); break; + case 12: flags = op1100(stream, pc, opcode); break; + case 13: flags = op1101(stream, pc, opcode); break; + case 14: flags = op1110(stream, pc, opcode); break; + default: flags = op1111_sh34(stream, pc, opcode); break; + } } - return 2 | flags | DASMFLAG_SUPPORTED; + else + { + switch ((opcode >> 12) & 15) + { + case 0: flags = op0000(stream, pc, opcode); break; + case 1: flags = op0001(stream, pc, opcode); break; + case 2: flags = op0010(stream, pc, opcode); break; + case 3: flags = op0011(stream, pc, opcode); break; + case 4: flags = op0100(stream, pc, opcode); break; + case 5: flags = op0101(stream, pc, opcode); break; + case 6: flags = op0110(stream, pc, opcode); break; + case 7: flags = op0111(stream, pc, opcode); break; + case 8: flags = op1000(stream, pc, opcode); break; + case 9: flags = op1001(stream, pc, opcode); break; + case 10: flags = op1010(stream, pc, opcode); break; + case 11: flags = op1011(stream, pc, opcode); break; + case 12: flags = op1100(stream, pc, opcode); break; + case 13: flags = op1101(stream, pc, opcode); break; + case 14: flags = op1110(stream, pc, opcode); break; + default: flags = op1111(stream, pc, opcode); break; + } + } + + return 2 | flags | SUPPORTED; } -CPU_DISASSEMBLE(sh4) + +u32 sh_disassembler::opcode_alignment() const { - return DasmSH4(stream, pc, (oprom[1] << 8) | oprom[0]); + return 2; } -CPU_DISASSEMBLE(sh4be) +sh_disassembler::sh_disassembler(bool is_sh34) : m_is_sh34(is_sh34) { - return DasmSH4(stream, pc, (oprom[0] << 8) | oprom[1]); } + diff --git a/src/devices/cpu/sh/sh_dasm.h b/src/devices/cpu/sh/sh_dasm.h new file mode 100644 index 00000000000..52d6b2eb723 --- /dev/null +++ b/src/devices/cpu/sh/sh_dasm.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller, R. Belmont + +#ifndef MAME_CPU_SH_SHDASM_H +#define MAME_CPU_SH_SHDASM_H + +#pragma once + +class sh_disassembler : public util::disasm_interface +{ +public: + sh_disassembler(bool is_sh34); + virtual ~sh_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + offs_t dasm_one(std::ostream &stream, offs_t pc, u16 opcode); + +private: + static const char *const regname[16]; + uint32_t op0000(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0001(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0010(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0011(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0100(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0101(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0110(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0111(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1000(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1001(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1010(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1011(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1100(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1101(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1110(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1111(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0000_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op0100_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode); + uint32_t op1111_sh34(std::ostream &stream, uint32_t pc, uint16_t opcode); + + bool m_is_sh34; +}; + +#endif diff --git a/src/devices/cpu/sharc/sharc.cpp b/src/devices/cpu/sharc/sharc.cpp index b8f3b104eb0..c85a915a2f7 100644 --- a/src/devices/cpu/sharc/sharc.cpp +++ b/src/devices/cpu/sharc/sharc.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "sharc.h" #include "sharcfe.h" +#include "sharcdsm.h" #include "debugger.h" @@ -96,10 +97,9 @@ device_memory_interface::space_config_vector adsp21062_device::memory_space_conf }; } -offs_t adsp21062_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *adsp21062_device::create_disassembler() { - extern CPU_DISASSEMBLE( sharc ); - return CPU_DISASSEMBLE_NAME(sharc)(this, stream, pc, oprom, opram, options); + return new sharc_disassembler; } void adsp21062_device::enable_recompiler() @@ -400,7 +400,7 @@ void adsp21062_device::external_iop_write(uint32_t address, uint32_t data) else { osd_printf_debug("SHARC IOP write %08X, %08X\n", address, data); - m_data->write_dword(address << 2, data); + m_data->write_dword(address, data); } } @@ -1031,7 +1031,7 @@ void adsp21062_device::execute_run() debugger_instruction_hook(this, m_core->pc); - m_core->opcode = m_program->read_qword(m_core->pc << 3); + m_core->opcode = m_program->read_qword(m_core->pc); // handle looping if (m_core->pc == m_core->laddr.addr) diff --git a/src/devices/cpu/sharc/sharc.h b/src/devices/cpu/sharc/sharc.h index 806b3053ee4..d4a56e1d525 100644 --- a/src/devices/cpu/sharc/sharc.h +++ b/src/devices/cpu/sharc/sharc.h @@ -220,10 +220,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - static constexpr uint32_t OPCODE_BYTES = 8; // actually 6, but emulation requires padding to 64 bits - virtual uint32_t disasm_min_opcode_bytes() const override { return OPCODE_BYTES; } - virtual uint32_t disasm_max_opcode_bytes() const override { return OPCODE_BYTES; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: struct alignas(16) SHARC_DAG diff --git a/src/devices/cpu/sharc/sharcdrc.cpp b/src/devices/cpu/sharc/sharcdrc.cpp index b8ab1a1f975..c21a1c2e997 100644 --- a/src/devices/cpu/sharc/sharcdrc.cpp +++ b/src/devices/cpu/sharc/sharcdrc.cpp @@ -307,34 +307,28 @@ void adsp21062_device::static_generate_memory_accessor(MEM_ACCESSOR_TYPE type, c switch (type) { case MEM_ACCESSOR_PM_READ48: - UML_SHL(block, I1, I1, 3); UML_DREAD(block, I0, I1, SIZE_QWORD, SPACE_PROGRAM); break; case MEM_ACCESSOR_PM_WRITE48: - UML_SHL(block, I1, I1, 3); UML_DWRITE(block, I1, I0, SIZE_QWORD, SPACE_PROGRAM); UML_MOV(block, mem(&m_core->force_recompile), 1); break; case MEM_ACCESSOR_PM_READ32: - UML_SHL(block, I1, I1, 3); UML_READ(block, I0, I1, SIZE_DWORD, SPACE_PROGRAM); break; case MEM_ACCESSOR_PM_WRITE32: - UML_SHL(block, I1, I1, 3); UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_PROGRAM); UML_MOV(block, mem(&m_core->force_recompile), 1); break; case MEM_ACCESSOR_DM_READ32: - UML_SHL(block, I1, I1, 2); UML_READ(block, I0, I1, SIZE_DWORD, SPACE_DATA); break; case MEM_ACCESSOR_DM_WRITE32: - UML_SHL(block, I1, I1, 2); UML_WRITE(block, I1, I0, SIZE_DWORD, SPACE_DATA); break; } diff --git a/src/devices/cpu/sharc/sharcdsm.cpp b/src/devices/cpu/sharc/sharcdsm.cpp index 7d570c13e87..ebab8add599 100644 --- a/src/devices/cpu/sharc/sharcdsm.cpp +++ b/src/devices/cpu/sharc/sharcdsm.cpp @@ -9,8 +9,76 @@ #include "emu.h" #include "sharcdsm.h" -static uint32_t (* sharcdasm_table[256])(uint32_t, uint64_t); -static int dasm_table_built = 0; +const char sharc_disassembler::ureg_names[256][16] = +{ + "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", + "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", + "I0", "I1", "I2", "I3", "I4", "I5", "I6", "I7", + "I8", "I9", "I10", "I11", "I12", "I13", "I14", "I15", + "M0", "M1", "M2", "M3", "M4", "M5", "M6", "M7", + "M8", "M9", "M10", "M11", "M12", "M13", "M14", "M15", + "L0", "L1", "L2", "L3", "L4", "L5", "L6", "L7", + "L8", "L9", "L10", "L11", "L12", "L13", "L14", "L15", + "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", + "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "FADDR", "DADDR", "???", "PC", "PCSTK", "PCSTKP", "LADDR", "CURLCNTR", + "LCNTR", "???", "???", "???", "???", "???", "???", "???", + "USTAT1", "USTAT2", "???", "???", "???", "???", "???", "???", + "???", "IRPTL", "MODE2", "MODE1", "ASTAT", "IMASK", "STKY", "IMASKP", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "PX", "PX1", "PX2", "TPERIOD", "TCOUNT", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???" +}; + +const char sharc_disassembler::bopnames[8][8] = +{ + "SET", "CLEAR", "TOGGLE", "???", "TEST", "XOR", "???", "???" +}; + +const char sharc_disassembler::condition_codes_if[32][32] = +{ + "EQ", "LT", "LE", "AC", + "AV", "MV", "MS", "SV", + "SZ", "FLAG0_IN", "FLAG1_IN", "FLAG2_IN", + "FLAG3_IN", "TF", "BM", "NOT LCE", + "NE", "GE", "GT", "NOT AC", + "NOT AV", "NOT MV", "NOT MS", "NOT SV", + "NOT SZ", "NOT FLAG0_IN", "NOT FLAG1_IN", "NOT FLAG2_IN", + "NOT FLAG3_IN", "NOT TF", "NBM", "" +}; + +const char sharc_disassembler::condition_codes_do[32][32] = +{ + "EQ", "LT", "LE", "AC", + "AV", "MV", "MS", "SV", + "SZ", "FLAG0_IN", "FLAG1_IN", "FLAG2_IN", + "FLAG3_IN", "TF", "BM", "LCE", + "NE", "GE", "GT", "NOT AC", + "NOT AV", "NOT MV", "NOT MS", "NOT SV", + "NOT SZ", "NOT FLAG0_IN", "NOT FLAG1_IN", "NOT FLAG2_IN", + "NOT FLAG3_IN", "NOT TF", "NBM", "FOREVER" +}; + +const char sharc_disassembler::mr_regnames[16][8] = +{ + "MR0F", "MR1F", "MR2F", "MR0B", "MR1B", "MR2B", "???", "???", + "???", "???", "???", "???", "???", "???", "???", "???" +}; #define GET_UREG(x) (ureg_names[x]) #define GET_SREG(x) (GET_UREG(0x70 | (x & 0xf))) @@ -28,19 +96,7 @@ static int dasm_table_built = 0; #define SIGN_EXTEND24(x) ((x & 0x800000) ? (0xff000000 | x) : x) -static char *output; -static void ATTR_PRINTF(1,2) print(const char *fmt, ...) -{ - va_list vl; - - va_start(vl, fmt); - output += vsprintf(output, fmt, vl); - va_end(vl); -} - - - -static void compute(uint32_t opcode) +void sharc_disassembler::compute(std::ostream &stream, uint32_t opcode) { int op = (opcode >> 12) & 0xff; int cu = (opcode >> 20) & 0x3; @@ -61,41 +117,41 @@ static void compute(uint32_t opcode) switch(multiop) { - case 0x04: print("R%d = R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x05: print("R%d = R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x06: print("R%d = R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x08: print("MRF = MRF + R%d * R%d (SSF), R%d = R%d + R%d", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x09: print("MRF = MRF + R%d * R%d (SSF), R%d = R%d - R%d", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x0a: print("MRF = MRF + R%d * R%d (SSF), R%d = (R%d + R%d)/2", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x0c: print("R%d = MRF + R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x0d: print("R%d = MRF + R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x0e: print("R%d = MRF + R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x10: print("MRF = MRF - R%d * R%d (SSF), R%d = R%d + R%d", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x11: print("MRF = MRF - R%d * R%d (SSF), R%d = R%d - R%d", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x12: print("MRF = MRF - R%d * R%d (SSF), R%d = (R%d + R%d)/2", rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x14: print("R%d = MRF - R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x15: print("R%d = MRF - R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x16: print("R%d = MRF - R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x18: print("F%d = F%d * F%d, F%d = F%d + F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x19: print("F%d = F%d * F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1a: print("F%d = F%d * F%d, F%d = FLOAT F%d BY F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1b: print("F%d = F%d * F%d, F%d = FIX F%d BY F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1c: print("F%d = F%d * F%d, F%d = (F%d + F%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1d: print("F%d = F%d * F%d, F%d = ABS F%d", rm, rxm, rym+4, ra, rxa+8); break; - case 0x1e: print("F%d = F%d * F%d, F%d = MAX(F%d, F%d)", rm, rxm, rym+4, ra, rxa+8, rya+12); break; - case 0x1f: print("F%d = F%d * F%d, F%d = MIN(F%d, F%d)", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x04: util::stream_format(stream, "R%d = R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x05: util::stream_format(stream, "R%d = R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x06: util::stream_format(stream, "R%d = R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x08: util::stream_format(stream, "MRF = MRF + R%d * R%d (SSF), R%d = R%d + R%d", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x09: util::stream_format(stream, "MRF = MRF + R%d * R%d (SSF), R%d = R%d - R%d", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x0a: util::stream_format(stream, "MRF = MRF + R%d * R%d (SSF), R%d = (R%d + R%d)/2", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x0c: util::stream_format(stream, "R%d = MRF + R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x0d: util::stream_format(stream, "R%d = MRF + R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x0e: util::stream_format(stream, "R%d = MRF + R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x10: util::stream_format(stream, "MRF = MRF - R%d * R%d (SSF), R%d = R%d + R%d", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x11: util::stream_format(stream, "MRF = MRF - R%d * R%d (SSF), R%d = R%d - R%d", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x12: util::stream_format(stream, "MRF = MRF - R%d * R%d (SSF), R%d = (R%d + R%d)/2", rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x14: util::stream_format(stream, "R%d = MRF - R%d * R%d (SSFR), R%d = R%d + R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x15: util::stream_format(stream, "R%d = MRF - R%d * R%d (SSFR), R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x16: util::stream_format(stream, "R%d = MRF - R%d * R%d (SSFR), R%d = (R%d + R%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x18: util::stream_format(stream, "F%d = F%d * F%d, F%d = F%d + F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x19: util::stream_format(stream, "F%d = F%d * F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1a: util::stream_format(stream, "F%d = F%d * F%d, F%d = FLOAT F%d BY F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1b: util::stream_format(stream, "F%d = F%d * F%d, F%d = FIX F%d BY F%d", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1c: util::stream_format(stream, "F%d = F%d * F%d, F%d = (F%d + F%d)/2", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1d: util::stream_format(stream, "F%d = F%d * F%d, F%d = ABS F%d", rm, rxm, rym+4, ra, rxa+8); break; + case 0x1e: util::stream_format(stream, "F%d = F%d * F%d, F%d = MAX(F%d, F%d)", rm, rxm, rym+4, ra, rxa+8, rya+12); break; + case 0x1f: util::stream_format(stream, "F%d = F%d * F%d, F%d = MIN(F%d, F%d)", rm, rxm, rym+4, ra, rxa+8, rya+12); break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: { - print("R%d = R%d * R%d (SSFR), R%d = R%d + R%d, R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12); + util::stream_format(stream, "R%d = R%d * R%d (SSFR), R%d = R%d + R%d, R%d = R%d - R%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12); break; } case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: { - print("F%d = F%d * F%d, F%d = F%d + F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12); + util::stream_format(stream, "F%d = F%d * F%d, F%d = F%d + F%d, F%d = F%d - F%d", rm, rxm, rym+4, ra, rxa+8, rya+12, (opcode >> 16) & 0xf, rxa+8, rya+12); break; } @@ -103,20 +159,20 @@ static void compute(uint32_t opcode) { int rk = (opcode >> 8) & 0xf; int ai = (opcode >> 12) & 0xf; - print("R%d = %s", rk, mr_regnames[ai]); + util::stream_format(stream, "R%d = %s", rk, mr_regnames[ai]); break; } case 0x01: { int rk = (opcode >> 8) & 0xf; int ai = (opcode >> 12) & 0xf; - print("%s = R%d", mr_regnames[ai], rk); + util::stream_format(stream, "%s = R%d", mr_regnames[ai], rk); break; } default: { - print("??? (COMPUTE, MULTIOP)"); + util::stream_format(stream, "??? (COMPUTE, MULTIOP)"); break; } } @@ -133,68 +189,68 @@ static void compute(uint32_t opcode) switch(op) { /* Fixed-point */ - case 0x01: print("R%d = R%d + R%d", rn, rx, ry); break; - case 0x02: print("R%d = R%d - R%d", rn, rx, ry); break; - case 0x05: print("R%d = R%d + R%d + CI", rn, rx, ry); break; - case 0x06: print("R%d = R%d - R%d + CI - 1", rn, rx, ry); break; - case 0x09: print("R%d = (R%d + R%d)/2", rn, rx, ry); break; - case 0x0a: print("COMP(R%d, R%d)", rx, ry); break; - case 0x25: print("R%d = R%d + CI", rn, rx); break; - case 0x26: print("R%d = R%d + CI - 1", rn, rx); break; - case 0x29: print("R%d = R%d + 1", rn, rx); break; - case 0x2a: print("R%d = R%d - 1", rn, rx); break; - case 0x22: print("R%d = -R%d", rn, rx); break; - case 0x30: print("R%d = ABS R%d", rn, rx); break; - case 0x21: print("R%d = PASS R%d", rn, rx); break; - case 0x40: print("R%d = R%d AND R%d", rn, rx, ry); break; - case 0x41: print("R%d = R%d OR R%d", rn, rx, ry); break; - case 0x42: print("R%d = R%d XOR R%d", rn, rx, ry); break; - case 0x43: print("R%d = NOT R%d", rn, rx); break; - case 0x61: print("R%d = MIN(R%d, R%d)", rn, rx, ry); break; - case 0x62: print("R%d = MAX(R%d, R%d)", rn, rx, ry); break; - case 0x63: print("R%d = CLIP R%d BY R%d", rn, rx, ry); break; + case 0x01: util::stream_format(stream, "R%d = R%d + R%d", rn, rx, ry); break; + case 0x02: util::stream_format(stream, "R%d = R%d - R%d", rn, rx, ry); break; + case 0x05: util::stream_format(stream, "R%d = R%d + R%d + CI", rn, rx, ry); break; + case 0x06: util::stream_format(stream, "R%d = R%d - R%d + CI - 1", rn, rx, ry); break; + case 0x09: util::stream_format(stream, "R%d = (R%d + R%d)/2", rn, rx, ry); break; + case 0x0a: util::stream_format(stream, "COMP(R%d, R%d)", rx, ry); break; + case 0x25: util::stream_format(stream, "R%d = R%d + CI", rn, rx); break; + case 0x26: util::stream_format(stream, "R%d = R%d + CI - 1", rn, rx); break; + case 0x29: util::stream_format(stream, "R%d = R%d + 1", rn, rx); break; + case 0x2a: util::stream_format(stream, "R%d = R%d - 1", rn, rx); break; + case 0x22: util::stream_format(stream, "R%d = -R%d", rn, rx); break; + case 0x30: util::stream_format(stream, "R%d = ABS R%d", rn, rx); break; + case 0x21: util::stream_format(stream, "R%d = PASS R%d", rn, rx); break; + case 0x40: util::stream_format(stream, "R%d = R%d AND R%d", rn, rx, ry); break; + case 0x41: util::stream_format(stream, "R%d = R%d OR R%d", rn, rx, ry); break; + case 0x42: util::stream_format(stream, "R%d = R%d XOR R%d", rn, rx, ry); break; + case 0x43: util::stream_format(stream, "R%d = NOT R%d", rn, rx); break; + case 0x61: util::stream_format(stream, "R%d = MIN(R%d, R%d)", rn, rx, ry); break; + case 0x62: util::stream_format(stream, "R%d = MAX(R%d, R%d)", rn, rx, ry); break; + case 0x63: util::stream_format(stream, "R%d = CLIP R%d BY R%d", rn, rx, ry); break; /* Floating-point */ - case 0x81: print("F%d = F%d + F%d", rn, rx, ry); break; - case 0x82: print("F%d = F%d - F%d", rn, rx, ry); break; - case 0x91: print("F%d = ABS(F%d + F%d)", rn, rx, ry); break; - case 0x92: print("F%d = ABS(F%d - F%d)", rn, rx, ry); break; - case 0x89: print("F%d = (F%d + F%d)/2", rn, rx, ry); break; - case 0x8a: print("COMP(F%d, F%d)", rx, ry); break; - case 0xa2: print("F%d = -F%d", rn, rx); break; - case 0xb0: print("F%d = ABS F%d", rn, rx); break; - case 0xa1: print("F%d = PASS F%d", rn, rx); break; - case 0xa5: print("F%d = RND R%d", rn, rx); break; - case 0xbd: print("F%d = SCALB F%d BY R%d", rn, rx, ry); break; - case 0xad: print("R%d = MANT F%d", rn, rx); break; - case 0xc1: print("R%d = LOGB F%d", rn, rx); break; - case 0xd9: print("R%d = FIX F%d BY R%d", rn, rx, ry); break; - case 0xc9: print("R%d = FIX F%d", rn, rx); break; - case 0xdd: print("R%d = TRUNC F%d BY R%d", rn, rx, ry); break; - case 0xcd: print("R%d = TRUNC F%d", rn, rx); break; - case 0xda: print("F%d = FLOAT R%d BY R%d", rn, rx, ry); break; - case 0xca: print("F%d = FLOAT R%d", rn, rx); break; - case 0xc4: print("F%d = RECIPS F%d", rn, rx); break; - case 0xc5: print("F%d = RSQRTS F%d", rn, rx); break; - case 0xe0: print("F%d = F%d COPYSIGN F%d", rn, rx, ry); break; - case 0xe1: print("F%d = MIN(F%d, F%d)", rn, rx, ry); break; - case 0xe2: print("F%d = MAX(F%d, F%d)", rn, rx, ry); break; - case 0xe3: print("F%d = CLIP F%d BY F%d", rn, rx, ry); break; + case 0x81: util::stream_format(stream, "F%d = F%d + F%d", rn, rx, ry); break; + case 0x82: util::stream_format(stream, "F%d = F%d - F%d", rn, rx, ry); break; + case 0x91: util::stream_format(stream, "F%d = ABS(F%d + F%d)", rn, rx, ry); break; + case 0x92: util::stream_format(stream, "F%d = ABS(F%d - F%d)", rn, rx, ry); break; + case 0x89: util::stream_format(stream, "F%d = (F%d + F%d)/2", rn, rx, ry); break; + case 0x8a: util::stream_format(stream, "COMP(F%d, F%d)", rx, ry); break; + case 0xa2: util::stream_format(stream, "F%d = -F%d", rn, rx); break; + case 0xb0: util::stream_format(stream, "F%d = ABS F%d", rn, rx); break; + case 0xa1: util::stream_format(stream, "F%d = PASS F%d", rn, rx); break; + case 0xa5: util::stream_format(stream, "F%d = RND R%d", rn, rx); break; + case 0xbd: util::stream_format(stream, "F%d = SCALB F%d BY R%d", rn, rx, ry); break; + case 0xad: util::stream_format(stream, "R%d = MANT F%d", rn, rx); break; + case 0xc1: util::stream_format(stream, "R%d = LOGB F%d", rn, rx); break; + case 0xd9: util::stream_format(stream, "R%d = FIX F%d BY R%d", rn, rx, ry); break; + case 0xc9: util::stream_format(stream, "R%d = FIX F%d", rn, rx); break; + case 0xdd: util::stream_format(stream, "R%d = TRUNC F%d BY R%d", rn, rx, ry); break; + case 0xcd: util::stream_format(stream, "R%d = TRUNC F%d", rn, rx); break; + case 0xda: util::stream_format(stream, "F%d = FLOAT R%d BY R%d", rn, rx, ry); break; + case 0xca: util::stream_format(stream, "F%d = FLOAT R%d", rn, rx); break; + case 0xc4: util::stream_format(stream, "F%d = RECIPS F%d", rn, rx); break; + case 0xc5: util::stream_format(stream, "F%d = RSQRTS F%d", rn, rx); break; + case 0xe0: util::stream_format(stream, "F%d = F%d COPYSIGN F%d", rn, rx, ry); break; + case 0xe1: util::stream_format(stream, "F%d = MIN(F%d, F%d)", rn, rx, ry); break; + case 0xe2: util::stream_format(stream, "F%d = MAX(F%d, F%d)", rn, rx, ry); break; + case 0xe3: util::stream_format(stream, "F%d = CLIP F%d BY F%d", rn, rx, ry); break; case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: { - print("R%d = R%d + R%d, R%d = R%d - R%d", ra, rx, ry, rs, rx, ry); + util::stream_format(stream, "R%d = R%d + R%d, R%d = R%d - R%d", ra, rx, ry, rs, rx, ry); break; } case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: { - print("F%d = F%d + F%d, F%d = F%d - F%d", ra, rx, ry, rs, rx, ry); + util::stream_format(stream, "F%d = F%d + F%d, F%d = F%d - F%d", ra, rx, ry, rs, rx, ry); break; } default: { - print("??? (COMPUTE, ALU)"); + util::stream_format(stream, "??? (COMPUTE, ALU)"); break; } } @@ -207,44 +263,44 @@ static void compute(uint32_t opcode) case 1: { if( op == 0x30 ) { - print("F%d = F%d * F%d", rn, rx, ry); + util::stream_format(stream, "F%d = F%d * F%d", rn, rx, ry); return; } switch((op >> 1) & 0x3) { case 0: - case 1: print("R%d = ", rn); break; - case 2: print("MRF = "); break; - case 3: print("MRB = "); break; + case 1: util::stream_format(stream, "R%d = ", rn); break; + case 2: util::stream_format(stream, "MRF = "); break; + case 3: util::stream_format(stream, "MRB = "); break; } switch((op >> 6) & 0x3) { case 0: switch((op >> 4) & 0x3) { - case 0: print("SAT %s", (op & 0x2) ? "MRB" : "MRF"); break; + case 0: util::stream_format(stream, "SAT %s", (op & 0x2) ? "MRB" : "MRF"); break; case 1: if (op & 0x8) { - print("RND %s", (op & 0x2) ? "MRB" : "MRF"); + util::stream_format(stream, "RND %s", (op & 0x2) ? "MRB" : "MRF"); } else { - print("0"); + util::stream_format(stream, "0"); } break; } break; case 1: - print("R%d * R%d", rx, ry); break; + util::stream_format(stream, "R%d * R%d", rx, ry); break; case 2: - print("%s +(R%d * R%d)", (op & 0x2) ? "MRB" : "MRF", rx, ry); break; + util::stream_format(stream, "%s +(R%d * R%d)", (op & 0x2) ? "MRB" : "MRF", rx, ry); break; case 3: - print("%s -(R%d * R%d)", (op & 0x2) ? "MRB" : "MRF", rx, ry); break; + util::stream_format(stream, "%s -(R%d * R%d)", (op & 0x2) ? "MRB" : "MRF", rx, ry); break; } break; } @@ -256,50 +312,50 @@ static void compute(uint32_t opcode) { switch(op) { - case 0x00: print("R%d = LSHIFT R%d BY R%d", rn, rx, ry); break; - case 0x20: print("R%d = R%d OR LSHIFT R%d BY R%d", rn, rn, rx, ry); break; - case 0x04: print("R%d = ASHIFT R%d BY R%d", rn, rx, ry); break; - case 0x24: print("R%d = R%d OR ASHIFT R%d BY R%d", rn, rn, rx, ry); break; - case 0x08: print("R%d = ROT R%d BY R%d", rn, rx, ry); break; - case 0xc4: print("R%d = BCLR R%d BY R%d", rn, rx, ry); break; - case 0xc0: print("R%d = BSET R%d BY R%d", rn, rx, ry); break; - case 0xc8: print("R%d = BTGL R%d BY R%d", rn, rx, ry); break; - case 0xcc: print("BTST R%d BY R%d", rx, ry); break; - case 0x44: print("R%d = FDEP R%d BY R%d", rn, rx, ry); break; - case 0x64: print("R%d = R%d OR FDEP R%d BY R%d", rn, rn, rx, ry); break; - case 0x4c: print("R%d = FDEP R%d BY R%d (SE)", rn, rx, ry); break; - case 0x6c: print("R%d = R%d OR FDEP R%d BY R%d (SE)", rn, rn, rx, ry); break; - case 0x40: print("R%d = FEXT R%d BY R%d", rn, rx, ry); break; - case 0x48: print("R%d = FEXT R%d BY R%d (SE)", rn, rx, ry); break; - case 0x80: print("R%d = EXP R%d", rn, rx); break; - case 0x84: print("R%d = EXP R%d (EX)", rn, rx); break; - case 0x88: print("R%d = LEFTZ R%d", rn, rx); break; - case 0x8c: print("R%d = LEFTO R%d", rn, rx); break; - case 0x90: print("R%d = FPACK F%d", rn, rx); break; - case 0x94: print("F%d = FUNPACK R%d", rn, rx); break; - default: print("??? (COMPUTE, SHIFT)"); break; + case 0x00: util::stream_format(stream, "R%d = LSHIFT R%d BY R%d", rn, rx, ry); break; + case 0x20: util::stream_format(stream, "R%d = R%d OR LSHIFT R%d BY R%d", rn, rn, rx, ry); break; + case 0x04: util::stream_format(stream, "R%d = ASHIFT R%d BY R%d", rn, rx, ry); break; + case 0x24: util::stream_format(stream, "R%d = R%d OR ASHIFT R%d BY R%d", rn, rn, rx, ry); break; + case 0x08: util::stream_format(stream, "R%d = ROT R%d BY R%d", rn, rx, ry); break; + case 0xc4: util::stream_format(stream, "R%d = BCLR R%d BY R%d", rn, rx, ry); break; + case 0xc0: util::stream_format(stream, "R%d = BSET R%d BY R%d", rn, rx, ry); break; + case 0xc8: util::stream_format(stream, "R%d = BTGL R%d BY R%d", rn, rx, ry); break; + case 0xcc: util::stream_format(stream, "BTST R%d BY R%d", rx, ry); break; + case 0x44: util::stream_format(stream, "R%d = FDEP R%d BY R%d", rn, rx, ry); break; + case 0x64: util::stream_format(stream, "R%d = R%d OR FDEP R%d BY R%d", rn, rn, rx, ry); break; + case 0x4c: util::stream_format(stream, "R%d = FDEP R%d BY R%d (SE)", rn, rx, ry); break; + case 0x6c: util::stream_format(stream, "R%d = R%d OR FDEP R%d BY R%d (SE)", rn, rn, rx, ry); break; + case 0x40: util::stream_format(stream, "R%d = FEXT R%d BY R%d", rn, rx, ry); break; + case 0x48: util::stream_format(stream, "R%d = FEXT R%d BY R%d (SE)", rn, rx, ry); break; + case 0x80: util::stream_format(stream, "R%d = EXP R%d", rn, rx); break; + case 0x84: util::stream_format(stream, "R%d = EXP R%d (EX)", rn, rx); break; + case 0x88: util::stream_format(stream, "R%d = LEFTZ R%d", rn, rx); break; + case 0x8c: util::stream_format(stream, "R%d = LEFTO R%d", rn, rx); break; + case 0x90: util::stream_format(stream, "R%d = FPACK F%d", rn, rx); break; + case 0x94: util::stream_format(stream, "F%d = FUNPACK R%d", rn, rx); break; + default: util::stream_format(stream, "??? (COMPUTE, SHIFT)"); break; } break; } default: { - print("??? (COMPUTE)"); + util::stream_format(stream, "??? (COMPUTE)"); break; } } } } -static void get_if_condition(int cond) +void sharc_disassembler::get_if_condition(std::ostream &stream, int cond) { if (cond != 31) { - print("IF %s, ", condition_codes_if[cond]); + util::stream_format(stream, "IF %s, ", condition_codes_if[cond]); } } -static void pm_dm_ureg(int g, int d, int i, int m, int ureg, int update) +void sharc_disassembler::pm_dm_ureg(std::ostream &stream, int g, int d, int i, int m, int ureg, int update) { if (update) // post-modify { @@ -307,22 +363,22 @@ static void pm_dm_ureg(int g, int d, int i, int m, int ureg, int update) { if (g) { - print("PM(%s, %s) = %s", GET_DAG2_I(i), GET_DAG2_M(m), GET_UREG(ureg)); + util::stream_format(stream, "PM(%s, %s) = %s", GET_DAG2_I(i), GET_DAG2_M(m), GET_UREG(ureg)); } else { - print("DM(%s, %s) = %s", GET_DAG1_I(i), GET_DAG1_M(m), GET_UREG(ureg)); + util::stream_format(stream, "DM(%s, %s) = %s", GET_DAG1_I(i), GET_DAG1_M(m), GET_UREG(ureg)); } } else { if (g) { - print("%s = PM(%s, %s)", GET_UREG(ureg), GET_DAG2_I(i), GET_DAG2_M(m)); + util::stream_format(stream, "%s = PM(%s, %s)", GET_UREG(ureg), GET_DAG2_I(i), GET_DAG2_M(m)); } else { - print("%s = DM(%s, %s)", GET_UREG(ureg), GET_DAG1_I(i), GET_DAG1_M(m)); + util::stream_format(stream, "%s = DM(%s, %s)", GET_UREG(ureg), GET_DAG1_I(i), GET_DAG1_M(m)); } } @@ -333,28 +389,28 @@ static void pm_dm_ureg(int g, int d, int i, int m, int ureg, int update) { if (g) { - print("PM(%s, %s) = %s", GET_DAG2_M(m), GET_DAG2_I(i), GET_UREG(ureg)); + util::stream_format(stream, "PM(%s, %s) = %s", GET_DAG2_M(m), GET_DAG2_I(i), GET_UREG(ureg)); } else { - print("DM(%s, %s) = %s", GET_DAG1_M(m), GET_DAG1_I(i), GET_UREG(ureg)); + util::stream_format(stream, "DM(%s, %s) = %s", GET_DAG1_M(m), GET_DAG1_I(i), GET_UREG(ureg)); } } else { if (g) { - print("%s = PM(%s, %s)", GET_UREG(ureg), GET_DAG2_M(m), GET_DAG2_I(i)); + util::stream_format(stream, "%s = PM(%s, %s)", GET_UREG(ureg), GET_DAG2_M(m), GET_DAG2_I(i)); } else { - print("%s = DM(%s, %s)", GET_UREG(ureg), GET_DAG1_M(m), GET_DAG1_I(i)); + util::stream_format(stream, "%s = DM(%s, %s)", GET_UREG(ureg), GET_DAG1_M(m), GET_DAG1_I(i)); } } } } -static void pm_dm_imm_dreg(int g, int d, int i, int data, int dreg, int update) +void sharc_disassembler::pm_dm_imm_dreg(std::ostream &stream, int g, int d, int i, int data, int dreg, int update) { const char *sign = ""; if (data & 0x20) @@ -369,22 +425,22 @@ static void pm_dm_imm_dreg(int g, int d, int i, int data, int dreg, int update) { if (g) { - print("PM(%s, %s0x%02X) = %s", GET_DAG2_I(i), sign, data, GET_DREG(dreg)); + util::stream_format(stream, "PM(%s, %s0x%02X) = %s", GET_DAG2_I(i), sign, data, GET_DREG(dreg)); } else { - print("DM(%s, %s0x%02X) = %s", GET_DAG1_I(i), sign, data, GET_DREG(dreg)); + util::stream_format(stream, "DM(%s, %s0x%02X) = %s", GET_DAG1_I(i), sign, data, GET_DREG(dreg)); } } else { if (g) { - print("%s = PM(%s, %s0x%02X)", GET_DREG(dreg), GET_DAG2_I(i), sign, data); + util::stream_format(stream, "%s = PM(%s, %s0x%02X)", GET_DREG(dreg), GET_DAG2_I(i), sign, data); } else { - print("%s = DM(%s, %s0x%02X)", GET_DREG(dreg), GET_DAG1_I(i), sign, data); + util::stream_format(stream, "%s = DM(%s, %s0x%02X)", GET_DREG(dreg), GET_DAG1_I(i), sign, data); } } } @@ -394,54 +450,54 @@ static void pm_dm_imm_dreg(int g, int d, int i, int data, int dreg, int update) { if (g) { - print("PM(%s0x%02X, %s) = %s", sign, data, GET_DAG2_I(i), GET_DREG(dreg)); + util::stream_format(stream, "PM(%s0x%02X, %s) = %s", sign, data, GET_DAG2_I(i), GET_DREG(dreg)); } else { - print("DM(%s0x%02X, %s) = %s", sign, data, GET_DAG1_I(i), GET_DREG(dreg)); + util::stream_format(stream, "DM(%s0x%02X, %s) = %s", sign, data, GET_DAG1_I(i), GET_DREG(dreg)); } } else { if (g) { - print("%s = PM(%s0x%02X, %s)", GET_DREG(dreg), sign, data, GET_DAG2_I(i)); + util::stream_format(stream, "%s = PM(%s0x%02X, %s)", GET_DREG(dreg), sign, data, GET_DAG2_I(i)); } else { - print("%s = DM(%s0x%02X, %s)", GET_DREG(dreg), sign, data, GET_DAG1_I(i)); + util::stream_format(stream, "%s = DM(%s0x%02X, %s)", GET_DREG(dreg), sign, data, GET_DAG1_I(i)); } } } } -static void pm_dm_dreg(int g, int d, int i, int m, int dreg) +void sharc_disassembler::pm_dm_dreg(std::ostream &stream, int g, int d, int i, int m, int dreg) { if (d) { if (g) { - print("PM(%s, %s) = %s", GET_DAG2_I(i), GET_DAG2_M(m), GET_DREG(dreg)); + util::stream_format(stream, "PM(%s, %s) = %s", GET_DAG2_I(i), GET_DAG2_M(m), GET_DREG(dreg)); } else { - print("DM(%s, %s) = %s", GET_DAG1_I(i), GET_DAG1_M(m), GET_DREG(dreg)); + util::stream_format(stream, "DM(%s, %s) = %s", GET_DAG1_I(i), GET_DAG1_M(m), GET_DREG(dreg)); } } else { if (g) { - print("%s = PM(%s, %s)", GET_DREG(dreg), GET_DAG2_I(i), GET_DAG2_M(m)); + util::stream_format(stream, "%s = PM(%s, %s)", GET_DREG(dreg), GET_DAG2_I(i), GET_DAG2_M(m)); } else { - print("%s = DM(%s, %s)", GET_DREG(dreg), GET_DAG1_I(i), GET_DAG1_M(m)); + util::stream_format(stream, "%s = DM(%s, %s)", GET_DREG(dreg), GET_DAG1_I(i), GET_DAG1_M(m)); } } } -static void shiftop(int shift, int data, int rn, int rx) +void sharc_disassembler::shiftop(std::ostream &stream, int shift, int data, int rn, int rx) { int8_t data8 = data & 0xff; int bit6 = data & 0x3f; @@ -449,36 +505,32 @@ static void shiftop(int shift, int data, int rn, int rx) switch(shift) { - case 0x00: print("R%d = LSHIFT R%d BY %d", rn, rx, data8); break; - case 0x08: print("R%d = R%d OR LSHIFT R%d BY %d", rn, rn, rx, data8); break; - case 0x01: print("R%d = ASHIFT R%d BY %d", rn, rx, data8); break; - case 0x09: print("R%d = R%d OR ASHIFT R%d BY %d", rn, rn, rx, data8); break; - case 0x02: print("R%d = ROT R%d BY %d", rn, rx, data8); break; - case 0x31: print("R%d = BCLR R%d BY %d", rn, rx, data8); break; - case 0x30: print("R%d = BSET R%d BY %d", rn, rx, data8); break; - case 0x32: print("R%d = BTGL R%d BY %d", rn, rx, data8); break; - case 0x33: print("BTST R%d BY %d", rx, data8); break; - case 0x11: print("R%d = FDEP R%d BY %d:%d", rn, rx, bit6, len); break; - case 0x19: print("R%d = R%d OR FDEP R%d BY %d:%d", rn, rn, rx, bit6, len); break; - case 0x13: print("R%d = FDEP R%d BY %d:%d (SE)", rn, rx, bit6, len); break; - case 0x1b: print("R%d = R%d OR FDEP R%d BY %d:%d (SE)", rn, rn, rx, bit6, len); break; - case 0x10: print("R%d = FEXT R%d BY %d:%d", rn, rx, bit6, len); break; - case 0x12: print("R%d = FEXT R%d BY %d:%d (SE)", rn, rx, bit6, len); break; - case 0x20: print("R%d = EXP R%d", rn, rx); break; - case 0x21: print("R%d = EXP R%d (EX)", rn, rx); break; - case 0x22: print("R%d = LEFTZ R%d", rn, rx); break; - case 0x23: print("R%d = LEFTO R%d", rn, rx); break; - case 0x24: print("R%d = FPACK F%d", rn, rx); break; - case 0x25: print("F%d = FUNPACK R%d", rn, rx); break; - default: print("??? (SHIFTOP)"); break; + case 0x00: util::stream_format(stream, "R%d = LSHIFT R%d BY %d", rn, rx, data8); break; + case 0x08: util::stream_format(stream, "R%d = R%d OR LSHIFT R%d BY %d", rn, rn, rx, data8); break; + case 0x01: util::stream_format(stream, "R%d = ASHIFT R%d BY %d", rn, rx, data8); break; + case 0x09: util::stream_format(stream, "R%d = R%d OR ASHIFT R%d BY %d", rn, rn, rx, data8); break; + case 0x02: util::stream_format(stream, "R%d = ROT R%d BY %d", rn, rx, data8); break; + case 0x31: util::stream_format(stream, "R%d = BCLR R%d BY %d", rn, rx, data8); break; + case 0x30: util::stream_format(stream, "R%d = BSET R%d BY %d", rn, rx, data8); break; + case 0x32: util::stream_format(stream, "R%d = BTGL R%d BY %d", rn, rx, data8); break; + case 0x33: util::stream_format(stream, "BTST R%d BY %d", rx, data8); break; + case 0x11: util::stream_format(stream, "R%d = FDEP R%d BY %d:%d", rn, rx, bit6, len); break; + case 0x19: util::stream_format(stream, "R%d = R%d OR FDEP R%d BY %d:%d", rn, rn, rx, bit6, len); break; + case 0x13: util::stream_format(stream, "R%d = FDEP R%d BY %d:%d (SE)", rn, rx, bit6, len); break; + case 0x1b: util::stream_format(stream, "R%d = R%d OR FDEP R%d BY %d:%d (SE)", rn, rn, rx, bit6, len); break; + case 0x10: util::stream_format(stream, "R%d = FEXT R%d BY %d:%d", rn, rx, bit6, len); break; + case 0x12: util::stream_format(stream, "R%d = FEXT R%d BY %d:%d (SE)", rn, rx, bit6, len); break; + case 0x20: util::stream_format(stream, "R%d = EXP R%d", rn, rx); break; + case 0x21: util::stream_format(stream, "R%d = EXP R%d (EX)", rn, rx); break; + case 0x22: util::stream_format(stream, "R%d = LEFTZ R%d", rn, rx); break; + case 0x23: util::stream_format(stream, "R%d = LEFTO R%d", rn, rx); break; + case 0x24: util::stream_format(stream, "R%d = FPACK F%d", rn, rx); break; + case 0x25: util::stream_format(stream, "F%d = FUNPACK R%d", rn, rx); break; + default: util::stream_format(stream, "??? (SHIFTOP)"); break; } } - - - - -static uint32_t dasm_compute_dreg_dmpm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_dreg_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int dmi = (opcode >> 41) & 0x7; int dmm = (opcode >> 38) & 0x7; @@ -492,42 +544,42 @@ static uint32_t dasm_compute_dreg_dmpm(uint32_t pc, uint64_t opcode) if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } if (dmd) { - print("DM(%s, %s) = R%d, ", GET_DAG1_I(dmi), GET_DAG1_M(dmm), dmdreg); + util::stream_format(stream, "DM(%s, %s) = R%d, ", GET_DAG1_I(dmi), GET_DAG1_M(dmm), dmdreg); } else { - print("R%d = DM(%s, %s), ", dmdreg, GET_DAG1_I(dmi), GET_DAG1_M(dmm)); + util::stream_format(stream, "R%d = DM(%s, %s), ", dmdreg, GET_DAG1_I(dmi), GET_DAG1_M(dmm)); } if (pmd) { - print("PM(%s, %s) = R%d", GET_DAG2_I(pmi), GET_DAG2_M(pmm), pmdreg); + util::stream_format(stream, "PM(%s, %s) = R%d", GET_DAG2_I(pmi), GET_DAG2_M(pmm), pmdreg); } else { - print("R%d = PM(%s, %s)", pmdreg, GET_DAG2_I(pmi), GET_DAG2_M(pmm)); + util::stream_format(stream, "R%d = PM(%s, %s)", pmdreg, GET_DAG2_I(pmi), GET_DAG2_M(pmm)); } return 0; } -static uint32_t dasm_compute(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int comp = opcode & 0x7fffff; if (comp) { - get_if_condition(cond); - compute(comp); + get_if_condition(stream, cond); + compute(stream, comp); } return 0; } -static uint32_t dasm_compute_uregdmpm_regmod(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_uregdmpm_regmod(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 32) & 0x1; @@ -538,17 +590,17 @@ static uint32_t dasm_compute_uregdmpm_regmod(uint32_t pc, uint64_t opcode) int ureg = (opcode >> 23) & 0xff; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } - pm_dm_ureg(g,d,i,m, ureg, u); + pm_dm_ureg(stream, g,d,i,m, ureg, u); return 0; } -static uint32_t dasm_compute_dregdmpm_immmod(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_dregdmpm_immmod(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 40) & 0x1; @@ -559,34 +611,34 @@ static uint32_t dasm_compute_dregdmpm_immmod(uint32_t pc, uint64_t opcode) int data = (opcode >> 27) & 0x3f; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } - pm_dm_imm_dreg(g,d,i, data, dreg, u); + pm_dm_imm_dreg(stream, g,d,i, data, dreg, u); return 0; } -static uint32_t dasm_compute_ureg_ureg(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_ureg_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 31) & 0x1f; int uregs = (opcode >> 36) & 0xff; int uregd = (opcode >> 23) & 0xff; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } - print("%s = %s", GET_UREG(uregd), GET_UREG(uregs)); + util::stream_format(stream, "%s = %s", GET_UREG(uregd), GET_UREG(uregs)); return 0; } -static uint32_t dasm_immshift_dregdmpm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immshift_dregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 32) & 0x1; @@ -599,14 +651,14 @@ static uint32_t dasm_immshift_dregdmpm(uint32_t pc, uint64_t opcode) int dreg = (opcode >> 23) & 0xf; int data = (((opcode >> 27) & 0xf) << 8) | ((opcode >> 8) & 0xff); - get_if_condition(cond); - shiftop(shift, data, rn, rx); - print(", "); - pm_dm_dreg(g,d,i,m, dreg); + get_if_condition(stream, cond); + shiftop(stream, shift, data, rn, rx); + util::stream_format(stream, ", "); + pm_dm_dreg(stream, g,d,i,m, dreg); return 0; } -static uint32_t dasm_immshift_dregdmpm_nodata(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immshift_dregdmpm_nodata(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int rn = (opcode >> 4) & 0xf; @@ -614,12 +666,12 @@ static uint32_t dasm_immshift_dregdmpm_nodata(uint32_t pc, uint64_t opcode) int shift = (opcode >> 16) & 0x3f; int data = (((opcode >> 27) & 0xf) << 8) | ((opcode >> 8) & 0xff); - get_if_condition(cond); - shiftop(shift, data, rn, rx); + get_if_condition(stream, cond); + shiftop(stream, shift, data, rn, rx); return 0; } -static uint32_t dasm_compute_modify(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_compute_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) { int cond = (opcode >> 33) & 0x1f; int g = (opcode >> 38) & 0x7; @@ -627,17 +679,17 @@ static uint32_t dasm_compute_modify(uint32_t pc, uint64_t opcode) int m = (opcode >> 27) & 0x7; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } - print("MODIFY(I%d, M%d)", (g ? 8+i : i), (g ? 8+m : m)); + util::stream_format(stream, "MODIFY(I%d, M%d)", (g ? 8+i : i), (g ? 8+m : m)); return 0; } -static uint32_t dasm_direct_jump(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_direct_jump(std::ostream &stream, uint32_t pc, uint64_t opcode) { int j = (opcode >> 26) & 0x1; int cond = (opcode >> 33) & 0x1f; @@ -645,37 +697,37 @@ static uint32_t dasm_direct_jump(uint32_t pc, uint64_t opcode) uint32_t addr = opcode & 0xffffff; uint32_t flags = 0; - get_if_condition(cond); + get_if_condition(stream, cond); if (opcode & 0x8000000000U) { - print("CALL"); - flags = DASMFLAG_STEP_OVER; + util::stream_format(stream, "CALL"); + flags = STEP_OVER; } else { - print("JUMP"); + util::stream_format(stream, "JUMP"); } if (opcode & 0x10000000000U) /* PC-relative branch */ { - print(" (0x%08X)", pc + SIGN_EXTEND24(addr)); + util::stream_format(stream, " (0x%08X)", pc + SIGN_EXTEND24(addr)); } else /* Indirect branch */ { - print(" (0x%08X)", addr); + util::stream_format(stream, " (0x%08X)", addr); } if (j) { - print(" (DB)"); + util::stream_format(stream, " (DB)"); } if (ci) { - print(" (CI)"); + util::stream_format(stream, " (CI)"); } return flags; } -static uint32_t dasm_indirect_jump_compute(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_indirect_jump_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) { int b = (opcode >> 39) & 0x1; int j = (opcode >> 26) & 0x1; @@ -688,48 +740,48 @@ static uint32_t dasm_indirect_jump_compute(uint32_t pc, uint64_t opcode) int comp = opcode & 0x7fffff; uint32_t flags = 0; - get_if_condition(cond); + get_if_condition(stream, cond); if (b) { - print("CALL"); - flags = DASMFLAG_STEP_OVER; + util::stream_format(stream, "CALL"); + flags = STEP_OVER; } else { - print("JUMP"); + util::stream_format(stream, "JUMP"); } if (opcode & 0x10000000000U) /* PC-relative branch */ { - print(" (0x%08X)", pc + SIGN_EXTEND6(reladdr)); + util::stream_format(stream, " (0x%08X)", pc + SIGN_EXTEND6(reladdr)); } else /* Indirect branch */ { - print(" (%s, %s)", GET_DAG2_M(pmm), GET_DAG2_I(pmi)); + util::stream_format(stream, " (%s, %s)", GET_DAG2_M(pmm), GET_DAG2_I(pmi)); } if (j) { - print(" (DB)"); + util::stream_format(stream, " (DB)"); } if (ci) { - print(" (CI)"); + util::stream_format(stream, " (CI)"); } if (comp) { - print(", "); + util::stream_format(stream, ", "); if (e) { - print("ELSE "); + util::stream_format(stream, "ELSE "); } - compute(comp); + compute(stream, comp); } return flags; } -static uint32_t dasm_indirect_jump_compute_dregdm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_indirect_jump_compute_dregdm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int d = (opcode >> 44) & 0x1; int cond = (opcode >> 33) & 0x1f; @@ -741,36 +793,36 @@ static uint32_t dasm_indirect_jump_compute_dregdm(uint32_t pc, uint64_t opcode) int dreg = (opcode >> 23) & 0xf; int comp = opcode & 0x7fffff; - get_if_condition(cond); - print("JUMP"); + get_if_condition(stream, cond); + util::stream_format(stream, "JUMP"); if (opcode & 0x200000000000U) /* PC-relative branch */ { - print(" (0x%08X)", pc + SIGN_EXTEND6(reladdr)); + util::stream_format(stream, " (0x%08X)", pc + SIGN_EXTEND6(reladdr)); } else /* Indirect branch */ { - print(" (%s, %s)", GET_DAG2_M(pmm), GET_DAG2_I(pmi)); + util::stream_format(stream, " (%s, %s)", GET_DAG2_M(pmm), GET_DAG2_I(pmi)); } - print(", ELSE "); + util::stream_format(stream, ", ELSE "); if (comp) { - compute(comp); - print(", "); + compute(stream, comp); + util::stream_format(stream, ", "); } if (d) { - print("%s = DM(%s, %s)", GET_DREG(dreg), GET_DAG1_I(dmi), GET_DAG1_M(dmm)); + util::stream_format(stream, "%s = DM(%s, %s)", GET_DREG(dreg), GET_DAG1_I(dmi), GET_DAG1_M(dmm)); } else { - print("DM(%s, %s) = %s", GET_DAG1_I(dmi), GET_DAG1_M(dmm), GET_DREG(dreg)); + util::stream_format(stream, "DM(%s, %s) = %s", GET_DAG1_I(dmi), GET_DAG1_M(dmm), GET_DREG(dreg)); } return 0; } -static uint32_t dasm_rts_compute(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_rts_compute(std::ostream &stream, uint32_t pc, uint64_t opcode) { int j = (opcode >> 26) & 0x1; int e = (opcode >> 25) & 0x1; @@ -778,40 +830,40 @@ static uint32_t dasm_rts_compute(uint32_t pc, uint64_t opcode) int cond = (opcode >> 33) & 0x1f; int comp = opcode & 0x7fffff; - get_if_condition(cond); + get_if_condition(stream, cond); if (opcode & 0x10000000000U) { - print("RTI"); + util::stream_format(stream, "RTI"); } else { - print("RTS"); + util::stream_format(stream, "RTS"); } if (j) { - print(" (DB)"); + util::stream_format(stream, " (DB)"); } if (lr) { - print(" (LR)"); + util::stream_format(stream, " (LR)"); } if (comp) { - print(", "); + util::stream_format(stream, ", "); if (e) { - print("ELSE "); + util::stream_format(stream, "ELSE "); } - compute(comp); + compute(stream, comp); } - return DASMFLAG_STEP_OUT; + return STEP_OUT; } -static uint32_t dasm_do_until_counter(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_do_until_counter(std::ostream &stream, uint32_t pc, uint64_t opcode) { int data = (opcode >> 24) & 0xffff; int ureg = (opcode >> 32) & 0xff; @@ -819,27 +871,27 @@ static uint32_t dasm_do_until_counter(uint32_t pc, uint64_t opcode) if (opcode & 0x10000000000U) /* Loop counter from universal register */ { - print("LCNTR = %s, ", GET_UREG(ureg)); - print("DO (0x%08X)", pc + SIGN_EXTEND24(addr)); + util::stream_format(stream, "LCNTR = %s, ", GET_UREG(ureg)); + util::stream_format(stream, "DO (0x%08X)", pc + SIGN_EXTEND24(addr)); } else /* Loop counter from immediate */ { - print("LCNTR = 0x%04X, ", data); - print("DO (0x%08X) UNTIL LCE", pc + SIGN_EXTEND24(addr)); + util::stream_format(stream, "LCNTR = 0x%04X, ", data); + util::stream_format(stream, "DO (0x%08X) UNTIL LCE", pc + SIGN_EXTEND24(addr)); } return 0; } -static uint32_t dasm_do_until(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_do_until(std::ostream &stream, uint32_t pc, uint64_t opcode) { int term = (opcode >> 33) & 0x1f; uint32_t addr = opcode & 0xffffff; - print("DO (0x%08X) UNTIL %s", pc + SIGN_EXTEND24(addr), condition_codes_do[term]); + util::stream_format(stream, "DO (0x%08X) UNTIL %s", pc + SIGN_EXTEND24(addr), condition_codes_do[term]); return 0; } -static uint32_t dasm_immmove_uregdmpm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_uregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int d = (opcode >> 40) & 0x1; int g = (opcode >> 41) & 0x1; @@ -850,28 +902,28 @@ static uint32_t dasm_immmove_uregdmpm(uint32_t pc, uint64_t opcode) { if (d) { - print("PM(0x%08X) = %s", addr, GET_UREG(ureg)); + util::stream_format(stream, "PM(0x%08X) = %s", addr, GET_UREG(ureg)); } else { - print("%s = PM(0x%08X)", GET_UREG(ureg), addr); + util::stream_format(stream, "%s = PM(0x%08X)", GET_UREG(ureg), addr); } } else { if (d) { - print("DM(0x%08X) = %s", addr, GET_UREG(ureg)); + util::stream_format(stream, "DM(0x%08X) = %s", addr, GET_UREG(ureg)); } else { - print("%s = DM(0x%08X)", GET_UREG(ureg), addr); + util::stream_format(stream, "%s = DM(0x%08X)", GET_UREG(ureg), addr); } } return 0; } -static uint32_t dasm_immmove_uregdmpm_indirect(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_uregdmpm_indirect(std::ostream &stream, uint32_t pc, uint64_t opcode) { int d = (opcode >> 40) & 0x1; int g = (opcode >> 44) & 0x1; @@ -883,28 +935,28 @@ static uint32_t dasm_immmove_uregdmpm_indirect(uint32_t pc, uint64_t opcode) { if (d) { - print("PM(0x%08X, %s) = %s", addr, GET_DAG2_I(i), GET_UREG(ureg)); + util::stream_format(stream, "PM(0x%08X, %s) = %s", addr, GET_DAG2_I(i), GET_UREG(ureg)); } else { - print("%s = PM(0x%08X, %s)", GET_UREG(ureg), addr, GET_DAG2_I(i)); + util::stream_format(stream, "%s = PM(0x%08X, %s)", GET_UREG(ureg), addr, GET_DAG2_I(i)); } } else { if (d) { - print("DM(0x%08X, %s) = %s", addr, GET_DAG1_I(i), GET_UREG(ureg)); + util::stream_format(stream, "DM(0x%08X, %s) = %s", addr, GET_DAG1_I(i), GET_UREG(ureg)); } else { - print("%s = DM(0x%08X, %s)", GET_UREG(ureg), addr, GET_DAG1_I(i)); + util::stream_format(stream, "%s = DM(0x%08X, %s)", GET_UREG(ureg), addr, GET_DAG1_I(i)); } } return 0; } -static uint32_t dasm_immmove_immdata_dmpm(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_immdata_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode) { int g = (opcode >> 37) & 0x1; int i = (opcode >> 41) & 0x7; @@ -913,38 +965,38 @@ static uint32_t dasm_immmove_immdata_dmpm(uint32_t pc, uint64_t opcode) if (g) { - print("PM(%s, %s) = 0x%08X", GET_DAG2_I(i), GET_DAG2_M(m), data); + util::stream_format(stream, "PM(%s, %s) = 0x%08X", GET_DAG2_I(i), GET_DAG2_M(m), data); } else { - print("DM(%s, %s) = 0x%08X", GET_DAG1_I(i), GET_DAG1_M(m), data); + util::stream_format(stream, "DM(%s, %s) = 0x%08X", GET_DAG1_I(i), GET_DAG1_M(m), data); } return 0; } -static uint32_t dasm_immmove_immdata_ureg(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_immmove_immdata_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode) { int ureg = (opcode >> 32) & 0xff; uint32_t data = opcode & 0xffffffff; - print("%s = 0x%08X", GET_UREG(ureg), data); + util::stream_format(stream, "%s = 0x%08X", GET_UREG(ureg), data); return 0; } -static uint32_t dasm_sysreg_bitop(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_sysreg_bitop(std::ostream &stream, uint32_t pc, uint64_t opcode) { int bop = (opcode >> 37) & 0x7; int sreg = (opcode >> 32) & 0xf; uint32_t data = opcode & 0xffffffff; - print("BIT "); - print("%s ", bopnames[bop]); - print("%s ", GET_SREG(sreg)); - print("0x%08X", data); + util::stream_format(stream, "BIT "); + util::stream_format(stream, "%s ", bopnames[bop]); + util::stream_format(stream, "%s ", GET_SREG(sreg)); + util::stream_format(stream, "0x%08X", data); return 0; } -static uint32_t dasm_ireg_modify(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_ireg_modify(std::ostream &stream, uint32_t pc, uint64_t opcode) { int g = (opcode >> 38) & 0x1; int i = (opcode >> 32) & 0x7; @@ -954,28 +1006,28 @@ static uint32_t dasm_ireg_modify(uint32_t pc, uint64_t opcode) { if (g) { - print("BITREV (%s, 0x%08X)", GET_DAG2_I(i), data); + util::stream_format(stream, "BITREV (%s, 0x%08X)", GET_DAG2_I(i), data); } else { - print("BITREV (%s, 0x%08X)", GET_DAG1_I(i), data); + util::stream_format(stream, "BITREV (%s, 0x%08X)", GET_DAG1_I(i), data); } } else /* without bit-reverse */ { if (g) { - print("MODIFY (%s, 0x%08X)", GET_DAG2_I(i), data); + util::stream_format(stream, "MODIFY (%s, 0x%08X)", GET_DAG2_I(i), data); } else { - print("MODIFY (%s, 0x%08X)", GET_DAG1_I(i), data); + util::stream_format(stream, "MODIFY (%s, 0x%08X)", GET_DAG1_I(i), data); } } return 0; } -static uint32_t dasm_misc(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_misc(std::ostream &stream, uint32_t pc, uint64_t opcode) { int bits = (opcode >> 33) & 0x7f; int lpu = (opcode >> 39) & 0x1; @@ -988,171 +1040,169 @@ static uint32_t dasm_misc(uint32_t pc, uint64_t opcode) if (lpu) { - print("PUSH LOOP"); + util::stream_format(stream, "PUSH LOOP"); if (bits & 0x3f) { - print(", "); + util::stream_format(stream, ", "); } } if (lpo) { - print("POP LOOP"); + util::stream_format(stream, "POP LOOP"); if (bits & 0x1f) { - print(", "); + util::stream_format(stream, ", "); } } if (spu) { - print("PUSH STS"); + util::stream_format(stream, "PUSH STS"); if (bits & 0xf) { - print(", "); + util::stream_format(stream, ", "); } } if (spo) { - print("POP STS"); + util::stream_format(stream, "POP STS"); if (bits & 0x7) { - print(", "); + util::stream_format(stream, ", "); } } if (ppu) { - print("PUSH PCSTK"); + util::stream_format(stream, "PUSH PCSTK"); if (bits & 0x3) { - print(", "); + util::stream_format(stream, ", "); } } if (ppo) { - print("POP PCSTK"); + util::stream_format(stream, "POP PCSTK"); if (bits & 0x1) { - print(", "); + util::stream_format(stream, ", "); } } if (fc) { - print("FLUSH CACHE"); + util::stream_format(stream, "FLUSH CACHE"); } return 0; } -static uint32_t dasm_idlenop(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_idlenop(std::ostream &stream, uint32_t pc, uint64_t opcode) { if (opcode & 0x8000000000U) { - print("IDLE"); + util::stream_format(stream, "IDLE"); } else { - print("NOP"); + util::stream_format(stream, "NOP"); } return 0; } -#ifdef UNUSED_FUNCTION -static uint32_t dasm_cjump_rframe(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_cjump_rframe(std::ostream &stream, uint32_t pc, uint64_t opcode) { /* TODO */ if (opcode & 0x10000000000U) /* RFRAME */ { - print("TODO: RFRAME"); + util::stream_format(stream, "TODO: RFRAME"); } else { - print("TODO: CJUMP"); + util::stream_format(stream, "TODO: CJUMP"); } return 0; } -#endif -static uint32_t dasm_invalid(uint32_t pc, uint64_t opcode) +uint32_t sharc_disassembler::dasm_invalid(std::ostream &stream, uint32_t pc, uint64_t opcode) { - print("?"); + util::stream_format(stream, "?"); return 0; } -static const SHARC_DASM_OP sharc_dasm_ops[] = +const sharc_disassembler::SHARC_DASM_OP sharc_disassembler::sharc_dasm_ops[] = { // |0 0 1| - { 0xe000, 0x2000, dasm_compute_dreg_dmpm }, + { 0xe000, 0x2000, &sharc_disassembler::dasm_compute_dreg_dmpm }, // |0 0 0|0 0 0 0 1| - { 0xff00, 0x0100, dasm_compute }, + { 0xff00, 0x0100, &sharc_disassembler::dasm_compute }, // |0 1 0| - { 0xe000, 0x4000, dasm_compute_uregdmpm_regmod }, + { 0xe000, 0x4000, &sharc_disassembler::dasm_compute_uregdmpm_regmod }, // |0 1 1|0| - { 0xf000, 0x6000, dasm_compute_dregdmpm_immmod }, + { 0xf000, 0x6000, &sharc_disassembler::dasm_compute_dregdmpm_immmod }, // |0 1 1|1| - { 0xf000, 0x7000, dasm_compute_ureg_ureg }, + { 0xf000, 0x7000, &sharc_disassembler::dasm_compute_ureg_ureg }, // |1 0 0|0| - { 0xf000, 0x8000, dasm_immshift_dregdmpm }, + { 0xf000, 0x8000, &sharc_disassembler::dasm_immshift_dregdmpm }, // |0 0 0|0 0 0 1 0| - { 0xff00, 0x0200, dasm_immshift_dregdmpm_nodata }, + { 0xff00, 0x0200, &sharc_disassembler::dasm_immshift_dregdmpm_nodata }, // |0 0 0|0 0 1 0 0| - { 0xff00, 0x0400, dasm_compute_modify }, + { 0xff00, 0x0400, &sharc_disassembler::dasm_compute_modify }, // |0 0 0|0 0 1 1 x| - { 0xfe00, 0x0600, dasm_direct_jump }, + { 0xfe00, 0x0600, &sharc_disassembler::dasm_direct_jump }, // |0 0 0|0 1 0 0 x| - { 0xfe00, 0x0800, dasm_indirect_jump_compute }, + { 0xfe00, 0x0800, &sharc_disassembler::dasm_indirect_jump_compute }, // |1 1 x| - { 0xc000, 0xc000, dasm_indirect_jump_compute_dregdm }, + { 0xc000, 0xc000, &sharc_disassembler::dasm_indirect_jump_compute_dregdm }, // |0 0 0|0 1 0 1 x| - { 0xfe00, 0x0a00, dasm_rts_compute }, + { 0xfe00, 0x0a00, &sharc_disassembler::dasm_rts_compute }, // |0 0 0|0 1 1 0 x| - { 0xfe00, 0x0c00, dasm_do_until_counter }, + { 0xfe00, 0x0c00, &sharc_disassembler::dasm_do_until_counter }, // |0 0 0|0 1 1 1 0| - { 0xff00, 0x0e00, dasm_do_until }, + { 0xff00, 0x0e00, &sharc_disassembler::dasm_do_until }, // |0 0 0|1 0 0|x|x| - { 0xfc00, 0x1000, dasm_immmove_uregdmpm }, + { 0xfc00, 0x1000, &sharc_disassembler::dasm_immmove_uregdmpm }, // |1 0 1|x|x x x|x| - { 0xe000, 0xa000, dasm_immmove_uregdmpm_indirect }, + { 0xe000, 0xa000, &sharc_disassembler::dasm_immmove_uregdmpm_indirect }, // |1 0 0|1| - { 0xf000, 0x9000, dasm_immmove_immdata_dmpm }, + { 0xf000, 0x9000, &sharc_disassembler::dasm_immmove_immdata_dmpm }, // |0 0 0|0 1 1 1 1| - { 0xff00, 0x0f00, dasm_immmove_immdata_ureg }, + { 0xff00, 0x0f00, &sharc_disassembler::dasm_immmove_immdata_ureg }, // |0 0 0|1 0 1 0 0| - { 0xff00, 0x1400, dasm_sysreg_bitop }, + { 0xff00, 0x1400, &sharc_disassembler::dasm_sysreg_bitop }, // |0 0 0|1 0 1 1 0| - { 0xff00, 0x1600, dasm_ireg_modify }, + { 0xff00, 0x1600, &sharc_disassembler::dasm_ireg_modify }, // |0 0 0|1 0 1 1 1| - { 0xff00, 0x1700, dasm_misc }, + { 0xff00, 0x1700, &sharc_disassembler::dasm_misc }, // |0 0 0|0 0 0 0 0| - { 0xff00, 0x0000, dasm_idlenop }, + { 0xff00, 0x0000, &sharc_disassembler::dasm_idlenop }, }; -static void build_dasm_table(void) +sharc_disassembler::sharc_disassembler() { int i, j; int num_ops = sizeof(sharc_dasm_ops) / sizeof(SHARC_DASM_OP); for (i=0; i < 256; i++) { - sharcdasm_table[i] = dasm_invalid; + sharcdasm_table[i] = &sharc_disassembler::dasm_invalid; } for (i=0; i < 256; i++) @@ -1163,7 +1213,7 @@ static void build_dasm_table(void) { if ((sharc_dasm_ops[j].op_mask & op) == sharc_dasm_ops[j].op_bits) { - if (sharcdasm_table[i] != dasm_invalid) + if (sharcdasm_table[i] != &sharc_disassembler::dasm_invalid) { fatalerror("build_dasm_table: table already filled! (i=%04X, j=%d)\n", i, j); } @@ -1176,45 +1226,15 @@ static void build_dasm_table(void) } } -static uint32_t sharc_dasm_one(std::ostream &stream, offs_t pc, uint64_t opcode) +offs_t sharc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - #define DEFAULT_DASM_WIDTH (64) - - char dasm_buffer[2000]; - int i; + u64 opcode = opcodes.r64(pc); int op = (opcode >> 40) & 0xff; - uint32_t flags; - - if (!dasm_table_built) - { - build_dasm_table(); - dasm_table_built = 1; - } - memset(dasm_buffer, 0, sizeof(dasm_buffer)); - - /* set buffer for print */ - output = dasm_buffer; - - flags = (*sharcdasm_table[op])(pc, opcode); - - for (i=0; i < DEFAULT_DASM_WIDTH && dasm_buffer[i]; i++) - { - stream << dasm_buffer[i]; - } - return flags; + return 1 | (this->*sharcdasm_table[op])(stream, pc, opcode) | SUPPORTED; } - -CPU_DISASSEMBLE( sharc ) +u32 sharc_disassembler::opcode_alignment() const { - uint64_t op; - uint32_t flags; - - op = ((uint64_t)oprom[0] << 0) | ((uint64_t)oprom[1] << 8) | - ((uint64_t)oprom[2] << 16) | ((uint64_t)oprom[3] << 24) | - ((uint64_t)oprom[4] << 32) | ((uint64_t)oprom[5] << 40); - - flags = sharc_dasm_one(stream, pc, op); - return 1 | flags | DASMFLAG_SUPPORTED; + return 1; } diff --git a/src/devices/cpu/sharc/sharcdsm.h b/src/devices/cpu/sharc/sharcdsm.h index e4a52e94ea6..f752a133d6a 100644 --- a/src/devices/cpu/sharc/sharcdsm.h +++ b/src/devices/cpu/sharc/sharcdsm.h @@ -1,79 +1,68 @@ // license:BSD-3-Clause // copyright-holders:Ville Linde -static const char ureg_names[256][16] = -{ - "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", - "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", - "I0", "I1", "I2", "I3", "I4", "I5", "I6", "I7", - "I8", "I9", "I10", "I11", "I12", "I13", "I14", "I15", - "M0", "M1", "M2", "M3", "M4", "M5", "M6", "M7", - "M8", "M9", "M10", "M11", "M12", "M13", "M14", "M15", - "L0", "L1", "L2", "L3", "L4", "L5", "L6", "L7", - "L8", "L9", "L10", "L11", "L12", "L13", "L14", "L15", - "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", - "B8", "B9", "B10", "B11", "B12", "B13", "B14", "B15", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "FADDR", "DADDR", "???", "PC", "PCSTK", "PCSTKP", "LADDR", "CURLCNTR", - "LCNTR", "???", "???", "???", "???", "???", "???", "???", - "USTAT1", "USTAT2", "???", "???", "???", "???", "???", "???", - "???", "IRPTL", "MODE2", "MODE1", "ASTAT", "IMASK", "STKY", "IMASKP", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "PX", "PX1", "PX2", "TPERIOD", "TCOUNT", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???" -}; -static const char bopnames[8][8] = -{ - "SET", "CLEAR", "TOGGLE", "???", "TEST", "XOR", "???", "???" -}; +#ifndef MAME_CPU_SHARC_SHARCDSM_H +#define MAME_CPU_SHARC_SHARCDSM_H -static const char condition_codes_if[32][32] = -{ - "EQ", "LT", "LE", "AC", - "AV", "MV", "MS", "SV", - "SZ", "FLAG0_IN", "FLAG1_IN", "FLAG2_IN", - "FLAG3_IN", "TF", "BM", "NOT LCE", - "NE", "GE", "GT", "NOT AC", - "NOT AV", "NOT MV", "NOT MS", "NOT SV", - "NOT SZ", "NOT FLAG0_IN", "NOT FLAG1_IN", "NOT FLAG2_IN", - "NOT FLAG3_IN", "NOT TF", "NBM", "" -}; +#pragma once -static const char condition_codes_do[32][32] = +class sharc_disassembler : public util::disasm_interface { - "EQ", "LT", "LE", "AC", - "AV", "MV", "MS", "SV", - "SZ", "FLAG0_IN", "FLAG1_IN", "FLAG2_IN", - "FLAG3_IN", "TF", "BM", "LCE", - "NE", "GE", "GT", "NOT AC", - "NOT AV", "NOT MV", "NOT MS", "NOT SV", - "NOT SZ", "NOT FLAG0_IN", "NOT FLAG1_IN", "NOT FLAG2_IN", - "NOT FLAG3_IN", "NOT TF", "NBM", "FOREVER" -}; +public: + sharc_disassembler(); + virtual ~sharc_disassembler() = default; -static const char mr_regnames[16][8] = -{ - "MR0F", "MR1F", "MR2F", "MR0B", "MR1B", "MR2B", "???", "???", - "???", "???", "???", "???", "???", "???", "???", "???" -}; + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; -struct SHARC_DASM_OP -{ - uint32_t op_mask; - uint32_t op_bits; - uint32_t (* handler)(uint32_t, uint64_t); +private: + struct SHARC_DASM_OP + { + uint32_t op_mask; + uint32_t op_bits; + uint32_t (sharc_disassembler::*handler)(std::ostream &, uint32_t, uint64_t); + }; + + static const char ureg_names[256][16]; + static const char bopnames[8][8]; + static const char condition_codes_if[32][32]; + static const char condition_codes_do[32][32]; + static const char mr_regnames[16][8]; + static const SHARC_DASM_OP sharc_dasm_ops[]; + + uint32_t (sharc_disassembler::*sharcdasm_table[256])(std::ostream &, uint32_t, uint64_t); + + void compute(std::ostream &stream, uint32_t opcode); + void get_if_condition(std::ostream &stream, int cond); + void pm_dm_ureg(std::ostream &stream, int g, int d, int i, int m, int ureg, int update); + void pm_dm_imm_dreg(std::ostream &stream, int g, int d, int i, int data, int dreg, int update); + void pm_dm_dreg(std::ostream &stream, int g, int d, int i, int m, int dreg); + void shiftop(std::ostream &stream, int shift, int data, int rn, int rx); + + uint32_t dasm_compute_dreg_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute_uregdmpm_regmod(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute_dregdmpm_immmod(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute_ureg_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immshift_dregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immshift_dregdmpm_nodata(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_compute_modify(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_direct_jump(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_indirect_jump_compute(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_indirect_jump_compute_dregdm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_rts_compute(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_do_until_counter(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_do_until(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immmove_uregdmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immmove_uregdmpm_indirect(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immmove_immdata_dmpm(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_immmove_immdata_ureg(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_sysreg_bitop(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_ireg_modify(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_misc(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_idlenop(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_cjump_rframe(std::ostream &stream, uint32_t pc, uint64_t opcode); + uint32_t dasm_invalid(std::ostream &stream, uint32_t pc, uint64_t opcode); }; + +#endif diff --git a/src/devices/cpu/sharc/sharcmem.hxx b/src/devices/cpu/sharc/sharcmem.hxx index b297799c036..73bfa0e69f0 100644 --- a/src/devices/cpu/sharc/sharcmem.hxx +++ b/src/devices/cpu/sharc/sharcmem.hxx @@ -4,30 +4,30 @@ uint32_t adsp21062_device::pm_read32(uint32_t address) { - return m_program->read_dword(address << 3); + return m_program->read_dword(address); } void adsp21062_device::pm_write32(uint32_t address, uint32_t data) { - m_program->write_dword(address << 3, data); + m_program->write_dword(address, data); } uint64_t adsp21062_device::pm_read48(uint32_t address) { - return m_program->read_qword(address << 3); + return m_program->read_qword(address); } void adsp21062_device::pm_write48(uint32_t address, uint64_t data) { - m_program->write_qword(address << 3, data); + m_program->write_qword(address, data); } uint32_t adsp21062_device::dm_read32(uint32_t address) { - return m_data->read_dword(address << 2); + return m_data->read_dword(address); } void adsp21062_device::dm_write32(uint32_t address, uint32_t data) { - m_data->write_dword(address << 2, data); + m_data->write_dword(address, data); } diff --git a/src/devices/cpu/sharc/sharcops.hxx b/src/devices/cpu/sharc/sharcops.hxx index af1beed292b..8e7a03d974e 100644 --- a/src/devices/cpu/sharc/sharcops.hxx +++ b/src/devices/cpu/sharc/sharcops.hxx @@ -2721,9 +2721,5 @@ void adsp21062_device::sharcop_idle() void adsp21062_device::sharcop_unimplemented() { - extern CPU_DISASSEMBLE(sharc); - std::ostringstream dasm; - CPU_DISASSEMBLE_NAME(sharc)(nullptr, dasm, m_core->pc, nullptr, nullptr, 0); - osd_printf_debug("SHARC: %08X: %s\n", m_core->pc, dasm.str().c_str()); fatalerror("SHARC: Unimplemented opcode %04X%08X at %08X\n", (uint16_t)(m_core->opcode >> 32), (uint32_t)(m_core->opcode), m_core->pc); } diff --git a/src/devices/cpu/sm510/sm500.h b/src/devices/cpu/sm510/sm500.h index a7b9b336220..25349ecb1f2 100644 --- a/src/devices/cpu/sm510/sm500.h +++ b/src/devices/cpu/sm510/sm500.h @@ -87,7 +87,7 @@ protected: virtual void device_start() override; virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one() override; virtual void get_opcode_param() override; virtual void clock_melody() override; @@ -155,7 +155,7 @@ public: protected: sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_pins, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one() override; virtual int get_trs_field() override { return 1; } }; diff --git a/src/devices/cpu/sm510/sm500core.cpp b/src/devices/cpu/sm510/sm500core.cpp index daf60275680..d32fd935e4a 100644 --- a/src/devices/cpu/sm510/sm500core.cpp +++ b/src/devices/cpu/sm510/sm500core.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "sm500.h" +#include "sm510d.h" #include "debugger.h" @@ -48,10 +49,9 @@ sm500_device::sm500_device(const machine_config &mconfig, device_type type, cons // disasm -offs_t sm500_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm500_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm500); - return CPU_DISASSEMBLE_NAME(sm500)(this, stream, pc, oprom, opram, options); + return new sm500_disassembler; } diff --git a/src/devices/cpu/sm510/sm510.h b/src/devices/cpu/sm510/sm510.h index cb963e87fa8..5d44799864d 100644 --- a/src/devices/cpu/sm510/sm510.h +++ b/src/devices/cpu/sm510/sm510.h @@ -17,7 +17,7 @@ #define MCFG_SM510_READ_K_CB(_devcb) \ devcb = &sm510_base_device::set_read_k_callback(*device, DEVCB_##_devcb); // when in halt state, any K input going High can wake up the CPU, -// driver is required to use execute_set_input(SM510_INPUT_LINE_K, state) +// driver is required to use set_input_line(SM510_INPUT_LINE_K, state) #define SM510_INPUT_LINE_K 0 // 1-bit BA(aka alpha) input pin (pull-up) @@ -153,10 +153,6 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - address_space_config m_program_config; address_space_config m_data_config; address_space *m_program; @@ -321,7 +317,7 @@ public: sm510_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one() override; virtual void get_opcode_param() override; @@ -342,7 +338,7 @@ protected: virtual void device_post_load() override { notify_clock_changed(); } virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void execute_one() override; virtual void get_opcode_param() override; diff --git a/src/devices/cpu/sm510/sm510base.cpp b/src/devices/cpu/sm510/sm510base.cpp index bbf87000d3f..58b16abd11f 100644 --- a/src/devices/cpu/sm510/sm510base.cpp +++ b/src/devices/cpu/sm510/sm510base.cpp @@ -12,7 +12,6 @@ TODO: - source organiziation between files is a mess - - proper support for LFSR program counter in debugger - LCD bs pin blink mode via Y register (0.5s off, 0.5s on) - wake up after CEND doesn't work right diff --git a/src/devices/cpu/sm510/sm510core.cpp b/src/devices/cpu/sm510/sm510core.cpp index fe422988459..3540a07168f 100644 --- a/src/devices/cpu/sm510/sm510core.cpp +++ b/src/devices/cpu/sm510/sm510core.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "sm510.h" +#include "sm510d.h" #include "debugger.h" @@ -41,10 +42,9 @@ sm510_device::sm510_device(const machine_config &mconfig, const char *tag, devic // disasm -offs_t sm510_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm510_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm510); - return CPU_DISASSEMBLE_NAME(sm510)(this, stream, pc, oprom, opram, options); + return new sm510_disassembler; } diff --git a/src/devices/cpu/sm510/sm510d.cpp b/src/devices/cpu/sm510/sm510d.cpp index 4ec634b4771..186efde5cbc 100644 --- a/src/devices/cpu/sm510/sm510d.cpp +++ b/src/devices/cpu/sm510/sm510d.cpp @@ -7,40 +7,12 @@ */ #include "emu.h" -#include "debugger.h" -#include "sm510.h" +#include "sm510d.h" // common lookup tables -enum e_mnemonics -{ - // SM510 common - mILL /* 0! */, mEXT, - mLB, mLBL, mSBM, mEXBLA, mINCB, mDECB, - mATPL, mRTN0, mRTN1, mTL, mTML, mTM, mT, - mEXC, mBDC, mEXCI, mEXCD, mLDA, mLAX, mPTW, mWR, mWS, - mKTA, mATBP, mATX, mATL, mATFC, mATR, - mADD, mADD11, mADX, mCOMA, mROT, mRC, mSC, - mTB, mTC, mTAM, mTMI, mTA0, mTABL, mTIS, mTAL, mTF1, mTF4, - mRM, mSM, - mPRE, mSME, mRME, mTMEL, - mSKIP, mCEND, mIDIV, mDR, mDTA, mCLKLO, mCLKHI, - - // SM500 common - mCOMCB, mRTN, mRTNS, mSSR, mTR, mTRS, mRBM, - mADDC, mPDTW, mTW, mDTW, - mATS, mEXKSA, mEXKFA, - mRMF, mSMF, mCOMCN, - mTA, mTM2, mTG, - - // SM590 aliases - mNOP, mCCTRL, mINBL, mDEBL, mXBLA, mADCS, mTR7, - // SM590 uniques - mTAX, mLBLX, mMTR, mSTR, mINBM, mDEBM, mRTA, mBLTA, mEXAX, mTBA, mADS, mADC, mLBMX, mTLS -}; - -static const char *const s_mnemonics[] = +const char *const sm510_common_disassembler::s_mnemonics[] = { "?", "", "LB", "LBL", "SBM", "EXBLA", "INCB", "DECB", @@ -67,7 +39,7 @@ static const char *const s_mnemonics[] = }; // number of bits per opcode parameter, 8 or larger means 2-byte opcode -static const u8 s_bits[] = +const u8 sm510_common_disassembler::s_bits[] = { 0, 8, 4, 8, 0, 0, 0, 0, @@ -93,42 +65,39 @@ static const u8 s_bits[] = 4, 4, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2+8 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 sm510_common_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, - 0, _OUT, _OUT, 0, _OVER, _OVER, 0, + 0, STEP_OUT, STEP_OUT, 0, STEP_OVER, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, _OVER, 0, 0, 0, 0, 0, + 0, STEP_OVER, 0, 0, 0, 0, 0, // - 0, _OUT, _OUT, 0, 0, _OVER, 0, + 0, STEP_OUT, STEP_OUT, 0, 0, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // - 0, 0, 0, 0, 0, 0, _OVER, + 0, 0, 0, 0, 0, 0, STEP_OVER, // - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _OVER + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, STEP_OVER }; // common disasm -static offs_t sm510_common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended, std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram) +offs_t sm510_common_disassembler::common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended, std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, const u8 pclen) { // get raw opcode - u8 op = oprom[0]; + u8 op = opcodes.r8(pc); u8 instr = lut_mnemonic[op]; int len = 1; @@ -137,7 +106,19 @@ static offs_t sm510_common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended u16 param = mask; if (bits >= 8) { - param = oprom[1]; + if (pclen == 6) + { + int feed = ((pc >> 1 ^ pc) & 1) ? 0 : 0x20; + pc = feed | (pc >> 1 & 0x1f) | (pc & ~0x3f); + } + else if (pclen == 7) + { + int feed = ((pc >> 1 ^ pc) & 1) ? 0 : 0x40; + pc = feed | (pc >> 1 & 0x3f) | (pc & ~0x7f); + } + else + abort(); + param = params.r8(pc); len++; } @@ -169,13 +150,13 @@ static offs_t sm510_common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended } } - return len | s_flags[instr] | DASMFLAG_SUPPORTED; + return len | s_flags[instr] |SUPPORTED; } // SM510 disasm -static const u8 sm510_mnemonic[0x100] = +const u8 sm510_disassembler::sm510_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mSKIP, mATBP, mSBM, mATPL, mRM, mRM, mRM, mRM, mADD, mADD11,mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0 @@ -199,15 +180,15 @@ static const u8 sm510_mnemonic[0x100] = mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM // F }; -CPU_DISASSEMBLE(sm510) +offs_t sm510_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - return sm510_common_disasm(sm510_mnemonic, nullptr, stream, pc, oprom, opram); + return common_disasm(sm510_mnemonic, nullptr, stream, pc, opcodes, params, 6); } // SM511 disasm -static const u8 sm511_mnemonic[0x100] = +const u8 sm511_disassembler::sm511_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mROT, mDTA, mSBM, mATPL, mRM, mRM, mRM, mRM, mADD, mADD11,mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0 @@ -231,25 +212,25 @@ static const u8 sm511_mnemonic[0x100] = mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM, mTM // F }; -static const u8 sm511_extended[0x10] = +const u8 sm511_disassembler::sm511_extended[0x10] = { mRME, mSME, mTMEL, mATFC, mBDC, mATBP, mCLKHI,mCLKLO,0, 0, 0, 0, 0, 0, 0, 0 // 60 3 }; -CPU_DISASSEMBLE(sm511) +offs_t sm511_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { // create extended opcode table u8 ext[0x100]; memset(ext, 0, 0x100); memcpy(ext + 0x30, sm511_extended, 0x10); - return sm510_common_disasm(sm511_mnemonic, ext, stream, pc, oprom, opram); + return common_disasm(sm511_mnemonic, ext, stream, pc, opcodes, params, 6); } // SM500 disasm -static const u8 sm500_mnemonic[0x100] = +const u8 sm500_disassembler::sm500_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mSKIP, mATR, mEXKSA,mATBP, mRM, mRM, mRM, mRM, mADD, mADDC, mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0 @@ -273,25 +254,25 @@ static const u8 sm500_mnemonic[0x100] = mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS // F }; -static const u8 sm500_extended[0x10] = +const u8 sm500_disassembler::sm500_extended[0x10] = { mCEND, 0, 0, 0, mDTA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 5E 0 }; -CPU_DISASSEMBLE(sm500) +offs_t sm500_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { // create extended opcode table u8 ext[0x100]; memset(ext, 0, 0x100); memcpy(ext + 0x00, sm500_extended, 0x10); - return sm510_common_disasm(sm500_mnemonic, ext, stream, pc, oprom, opram); + return common_disasm(sm500_mnemonic, ext, stream, pc, opcodes, params, 6); } // SM5A disasm -static const u8 sm5a_mnemonic[0x100] = +const u8 sm5a_disassembler::sm5a_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mSKIP, mATR, mSBM, mATBP, mRM, mRM, mRM, mRM, mADD, mADDC, mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0 @@ -315,25 +296,25 @@ static const u8 sm5a_mnemonic[0x100] = mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS, mTRS // F }; -static const u8 sm5a_extended[0x10] = +const u8 sm5a_disassembler::sm5a_extended[0x10] = { mCEND, 0, 0, 0, mDTA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 5E 0 }; -CPU_DISASSEMBLE(sm5a) +offs_t sm5a_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { // create extended opcode table u8 ext[0x100]; memset(ext, 0, 0x100); memcpy(ext + 0x00, sm5a_extended, 0x10); - return sm510_common_disasm(sm5a_mnemonic, ext, stream, pc, oprom, opram); + return common_disasm(sm5a_mnemonic, ext, stream, pc, opcodes, params, 6); } // SM590 disasm -static const u8 sm590_mnemonic[0x100] = +const u8 sm590_disassembler::sm590_mnemonic[0x100] = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ mNOP, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, // 0 @@ -358,7 +339,90 @@ static const u8 sm590_mnemonic[0x100] = }; -CPU_DISASSEMBLE(sm590) +offs_t sm590_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + return common_disasm(sm590_mnemonic, nullptr, stream, pc, opcodes, params, 7); +} + +u32 sm510_common_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 sm510_common_disassembler::interface_flags() const +{ + return NONLINEAR_PC|PAGED2LEVEL; +} + +u32 sm510_common_disassembler::page_address_bits() const +{ + return 6; +} + +u32 sm510_common_disassembler::page2_address_bits() const +{ + return 4; +} + +offs_t sm510_common_disassembler::pc_linear_to_real(offs_t pc) const +{ + static const u8 l2r[64] = { + 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x1f, 0x2f, 0x37, 0x3b, 0x3d, 0x1e, 0x0f, 0x27, 0x33, 0x39, + 0x1c, 0x2e, 0x17, 0x2b, 0x35, 0x1a, 0x0d, 0x06, 0x03, 0x21, 0x10, 0x28, 0x34, 0x3a, 0x1d, 0x0e, + 0x07, 0x23, 0x31, 0x18, 0x2c, 0x36, 0x1b, 0x2d, 0x16, 0x0b, 0x25, 0x12, 0x09, 0x04, 0x22, 0x11, + 0x08, 0x24, 0x32, 0x19, 0x0c, 0x26, 0x13, 0x29, 0x14, 0x2a, 0x15, 0x0a, 0x05, 0x02, 0x01, 0x3f, + }; + return (pc & ~0x3f) | l2r[pc & 0x3f]; +} + +offs_t sm510_common_disassembler::pc_real_to_linear(offs_t pc) const +{ + static const u8 r2l[64] = { + 0x00, 0x3e, 0x3d, 0x18, 0x2d, 0x3c, 0x17, 0x20, 0x30, 0x2c, 0x3b, 0x29, 0x34, 0x16, 0x1f, 0x0c, + 0x1a, 0x2f, 0x2b, 0x36, 0x38, 0x3a, 0x28, 0x12, 0x23, 0x33, 0x15, 0x26, 0x10, 0x1e, 0x0b, 0x06, + 0x01, 0x19, 0x2e, 0x21, 0x31, 0x2a, 0x35, 0x0d, 0x1b, 0x37, 0x39, 0x13, 0x24, 0x27, 0x11, 0x07, + 0x02, 0x22, 0x32, 0x0e, 0x1c, 0x14, 0x25, 0x08, 0x03, 0x0f, 0x1d, 0x09, 0x04, 0x0a, 0x05, 0x3f, + }; + return (pc & ~0x3f) | r2l[pc & 0x3f]; +} + +u32 sm590_disassembler::page_address_bits() const +{ + return 7; +} + +u32 sm590_disassembler::page2_address_bits() const +{ + return 2; +} + +offs_t sm590_disassembler::pc_linear_to_real(offs_t pc) const +{ + static const u8 l2r[128] = { + 0x00, 0x40, 0x60, 0x70, 0x78, 0x7c, 0x7e, 0x3f, 0x5f, 0x6f, 0x77, 0x7b, 0x7d, 0x3e, 0x1f, 0x4f, + 0x67, 0x73, 0x79, 0x3c, 0x5e, 0x2f, 0x57, 0x6b, 0x75, 0x3a, 0x1d, 0x0e, 0x07, 0x43, 0x61, 0x30, + 0x58, 0x6c, 0x76, 0x3b, 0x5d, 0x2e, 0x17, 0x4b, 0x65, 0x32, 0x19, 0x0c, 0x46, 0x23, 0x51, 0x28, + 0x54, 0x6a, 0x35, 0x1a, 0x0d, 0x06, 0x03, 0x41, 0x20, 0x50, 0x68, 0x74, 0x7a, 0x3d, 0x1e, 0x0f, + 0x47, 0x63, 0x71, 0x38, 0x5c, 0x6e, 0x37, 0x5b, 0x6d, 0x36, 0x1b, 0x4d, 0x26, 0x13, 0x49, 0x24, + 0x52, 0x29, 0x14, 0x4a, 0x25, 0x12, 0x09, 0x04, 0x42, 0x21, 0x10, 0x48, 0x64, 0x72, 0x39, 0x1c, + 0x4e, 0x27, 0x53, 0x69, 0x34, 0x5a, 0x2d, 0x16, 0x0b, 0x45, 0x22, 0x11, 0x08, 0x44, 0x62, 0x31, + 0x18, 0x4c, 0x66, 0x33, 0x59, 0x2c, 0x56, 0x2b, 0x55, 0x2a, 0x15, 0x0a, 0x05, 0x02, 0x01, 0x7f, + }; + return (pc & ~0x7f) | l2r[pc & 0x7f]; +} + +offs_t sm590_disassembler::pc_real_to_linear(offs_t pc) const { - return sm510_common_disasm(sm590_mnemonic, nullptr, stream, pc, oprom, opram); + static const u8 r2l[128] = { + 0x00, 0x7e, 0x7d, 0x36, 0x57, 0x7c, 0x35, 0x1c, 0x6c, 0x56, 0x7b, 0x68, 0x2b, 0x34, 0x1b, 0x3f, + 0x5a, 0x6b, 0x55, 0x4d, 0x52, 0x7a, 0x67, 0x26, 0x70, 0x2a, 0x33, 0x4a, 0x5f, 0x1a, 0x3e, 0x0e, + 0x38, 0x59, 0x6a, 0x2d, 0x4f, 0x54, 0x4c, 0x61, 0x2f, 0x51, 0x79, 0x77, 0x75, 0x66, 0x25, 0x15, + 0x1f, 0x6f, 0x29, 0x73, 0x64, 0x32, 0x49, 0x46, 0x43, 0x5e, 0x19, 0x23, 0x13, 0x3d, 0x0d, 0x07, + 0x01, 0x37, 0x58, 0x1d, 0x6d, 0x69, 0x2c, 0x40, 0x5b, 0x4e, 0x53, 0x27, 0x71, 0x4b, 0x60, 0x0f, + 0x39, 0x2e, 0x50, 0x62, 0x30, 0x78, 0x76, 0x16, 0x20, 0x74, 0x65, 0x47, 0x44, 0x24, 0x14, 0x08, + 0x02, 0x1e, 0x6e, 0x41, 0x5c, 0x28, 0x72, 0x10, 0x3a, 0x63, 0x31, 0x17, 0x21, 0x48, 0x45, 0x09, + 0x03, 0x42, 0x5d, 0x11, 0x3b, 0x18, 0x22, 0x0a, 0x04, 0x12, 0x3c, 0x0b, 0x05, 0x0c, 0x06, 0x7f, + }; + return (pc & ~0x7f) | r2l[pc & 0x7f]; } + diff --git a/src/devices/cpu/sm510/sm510d.h b/src/devices/cpu/sm510/sm510d.h new file mode 100644 index 00000000000..899b8815334 --- /dev/null +++ b/src/devices/cpu/sm510/sm510d.h @@ -0,0 +1,131 @@ +// license:BSD-3-Clause +// copyright-holders:hap, Jonathan Gevaryahu +/* + + Sharp SM5xx MCU family disassembler + +*/ + +#ifndef MAME_CPU_SM510_SM510D_H +#define MAME_CPU_SM510_SM510D_H + +#pragma once + +class sm510_common_disassembler : public util::disasm_interface +{ +public: + sm510_common_disassembler() = default; + virtual ~sm510_common_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual u32 page2_address_bits() const override; + virtual offs_t pc_linear_to_real(offs_t pc) const override; + virtual offs_t pc_real_to_linear(offs_t pc) const override; + +protected: + enum e_mnemonics + { + // SM510 common + mILL /* 0! */, mEXT, + mLB, mLBL, mSBM, mEXBLA, mINCB, mDECB, + mATPL, mRTN0, mRTN1, mTL, mTML, mTM, mT, + mEXC, mBDC, mEXCI, mEXCD, mLDA, mLAX, mPTW, mWR, mWS, + mKTA, mATBP, mATX, mATL, mATFC, mATR, + mADD, mADD11, mADX, mCOMA, mROT, mRC, mSC, + mTB, mTC, mTAM, mTMI, mTA0, mTABL, mTIS, mTAL, mTF1, mTF4, + mRM, mSM, + mPRE, mSME, mRME, mTMEL, + mSKIP, mCEND, mIDIV, mDR, mDTA, mCLKLO, mCLKHI, + + // SM500 common + mCOMCB, mRTN, mRTNS, mSSR, mTR, mTRS, mRBM, + mADDC, mPDTW, mTW, mDTW, + mATS, mEXKSA, mEXKFA, + mRMF, mSMF, mCOMCN, + mTA, mTM2, mTG, + + // SM590 aliases + mNOP, mCCTRL, mINBL, mDEBL, mXBLA, mADCS, mTR7, + // SM590 uniques + mTAX, mLBLX, mMTR, mSTR, mINBM, mDEBM, mRTA, mBLTA, mEXAX, mTBA, mADS, mADC, mLBMX, mTLS + }; + + static const char *const s_mnemonics[]; + static const u8 s_bits[]; + static const u32 s_flags[]; + + offs_t common_disasm(const u8 *lut_mnemonic, const u8 *lut_extended, std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, const u8 pclen); +}; + +class sm510_disassembler : public sm510_common_disassembler +{ +public: + sm510_disassembler() = default; + virtual ~sm510_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const u8 sm510_mnemonic[0x100]; + +}; + +class sm511_disassembler : public sm510_common_disassembler +{ +public: + sm511_disassembler() = default; + virtual ~sm511_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const u8 sm511_mnemonic[0x100]; + static const u8 sm511_extended[0x10]; +}; + +class sm500_disassembler : public sm510_common_disassembler +{ +public: + sm500_disassembler() = default; + virtual ~sm500_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const u8 sm500_mnemonic[0x100]; + static const u8 sm500_extended[0x10]; +}; + +class sm5a_disassembler : public sm510_common_disassembler +{ +public: + sm5a_disassembler() = default; + virtual ~sm5a_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const u8 sm5a_mnemonic[0x100]; + static const u8 sm5a_extended[0x10]; +}; + +class sm590_disassembler : public sm510_common_disassembler +{ +public: + sm590_disassembler() = default; + virtual ~sm590_disassembler() = default; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + virtual u32 page_address_bits() const override; + virtual u32 page2_address_bits() const override; + virtual offs_t pc_linear_to_real(offs_t pc) const override; + virtual offs_t pc_real_to_linear(offs_t pc) const override; + +private: + static const u8 sm590_mnemonic[0x100]; +}; + +#endif diff --git a/src/devices/cpu/sm510/sm511core.cpp b/src/devices/cpu/sm510/sm511core.cpp index 8ba41c19089..200740ee3e6 100644 --- a/src/devices/cpu/sm510/sm511core.cpp +++ b/src/devices/cpu/sm510/sm511core.cpp @@ -15,6 +15,7 @@ #include "emu.h" #include "sm510.h" +#include "sm510d.h" #include "debugger.h" @@ -43,10 +44,9 @@ ADDRESS_MAP_END // disasm -offs_t sm511_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm511_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm511); - return CPU_DISASSEMBLE_NAME(sm511)(this, stream, pc, oprom, opram, options); + return new sm511_disassembler; } diff --git a/src/devices/cpu/sm510/sm590.h b/src/devices/cpu/sm510/sm590.h index bdefb277207..c91b9287d63 100644 --- a/src/devices/cpu/sm510/sm590.h +++ b/src/devices/cpu/sm510/sm590.h @@ -101,7 +101,7 @@ protected: sm590_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual bool wake_me_up() override; virtual void init_divider() override { } virtual void init_lcd_driver() override { } diff --git a/src/devices/cpu/sm510/sm590core.cpp b/src/devices/cpu/sm510/sm590core.cpp index 63544bf503f..c04e40d7461 100644 --- a/src/devices/cpu/sm510/sm590core.cpp +++ b/src/devices/cpu/sm510/sm590core.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "sm590.h" +#include "sm510d.h" #include "debugger.h" @@ -70,11 +71,9 @@ sm590_device::sm590_device(const machine_config &mconfig, device_type type, cons } -// disasm -offs_t sm590_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm590_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm590); - return CPU_DISASSEMBLE_NAME(sm590)(this, stream, pc, oprom, opram, options); + return new sm590_disassembler; } diff --git a/src/devices/cpu/sm510/sm5acore.cpp b/src/devices/cpu/sm510/sm5acore.cpp index 1fd23887227..427918fe1c1 100644 --- a/src/devices/cpu/sm510/sm5acore.cpp +++ b/src/devices/cpu/sm510/sm5acore.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "sm500.h" +#include "sm510d.h" #include "debugger.h" @@ -63,14 +64,12 @@ kb1013vk12_device::kb1013vk12_device(const machine_config &mconfig, const char * // disasm -offs_t sm5a_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *sm5a_device::create_disassembler() { - extern CPU_DISASSEMBLE(sm5a); - return CPU_DISASSEMBLE_NAME(sm5a)(this, stream, pc, oprom, opram, options); + return new sm5a_disassembler; } - //------------------------------------------------- // execute //------------------------------------------------- diff --git a/src/devices/cpu/sm8500/sm8500.cpp b/src/devices/cpu/sm8500/sm8500.cpp index 654cc0d0db0..74d10aae658 100644 --- a/src/devices/cpu/sm8500/sm8500.cpp +++ b/src/devices/cpu/sm8500/sm8500.cpp @@ -21,6 +21,7 @@ they are internally. #include "emu.h" #include "sm8500.h" +#include "sm8500d.h" #include "debugger.h" @@ -348,10 +349,9 @@ void sm8500_cpu_device::process_interrupts() } -offs_t sm8500_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *sm8500_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( sm8500 ); - return CPU_DISASSEMBLE_NAME(sm8500)(this, stream, pc, oprom, opram, options); + return new sm8500_disassembler; } diff --git a/src/devices/cpu/sm8500/sm8500.h b/src/devices/cpu/sm8500/sm8500.h index 485d3a70ad8..ac9aea3fe82 100644 --- a/src/devices/cpu/sm8500/sm8500.h +++ b/src/devices/cpu/sm8500/sm8500.h @@ -74,9 +74,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 5; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; inline void get_sp(); uint8_t mem_readbyte(uint32_t offset) const; diff --git a/src/devices/cpu/sm8500/sm8500d.cpp b/src/devices/cpu/sm8500/sm8500d.cpp index 1b8b7dd2392..3d6139ef8ed 100644 --- a/src/devices/cpu/sm8500/sm8500d.cpp +++ b/src/devices/cpu/sm8500/sm8500d.cpp @@ -10,31 +10,9 @@ Sharp sm8500 CPU disassembly *******************************************************************/ #include "emu.h" -#include "debugger.h" -#include "sm8500.h" +#include "sm8500d.h" -enum e_mnemonics -{ - zADC=0, zADCW, zADD, zADDW, zAND, zANDW, zBAND, zBBC, zBBS, - zBCLR, zBCMP, zBMOV, zBOR, zBR, zBTST, zBSET, zBXOR, zCALL, zCALS, zCLR, - zCLRC, zCMP, zCMPW, zCOM, zCOMC, zDA, zDBNZ, zDEC, - zDECW, zDI, zDIV, zEI, zEXTS, zHALT, zINC, zINCW, - zIRET, zJMP, zMOV, zMOVM, zMOVW, zMULT, zNEG, zNOP, zOR, - zORW, zPOP, zPOPW, zPUSH, zPUSHW, zRET, zRL, zRLC, - zRR, zRRC, zSBC, zSBCW, zSETC, zSLL, zSRA, zSRL, zSTOP, - zSUB, zSUBW, zSWAP, zXOR, zXORW, zMOVPS0, zINVLD, zDM, -/* unknowns */ -z5A, z5B, - -/* more complicated instructions */ -z1A, z1B, z4F -}; - -/* instructions not found: -5A, 5B, -*/ - -static const char *const s_mnemonic[] = +const char *const sm8500_disassembler::s_mnemonic[] = { "adc", "adcw", "add", "addw", "and", "andw", "band", "bbc", "bbs", "bclr", "bcmp", "bmov", "bor", "br", "btst", "bset", "bxor", "call", "cals", "clr", @@ -51,45 +29,29 @@ static const char *const s_mnemonic[] = "comp1A", "comp1B", "comp4F", }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t s_flags[] = { +const uint32_t sm8500_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, _OVER, _OVER, 0, - 0, 0, 0, 0, 0, 0, _OVER, 0, - 0, 0, 0, 0, 0, _OVER, 0, 0, - _OUT, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, _OUT, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, STEP_OVER, STEP_OVER, 0, + 0, 0, 0, 0, 0, 0, STEP_OVER, 0, + 0, 0, 0, 0, 0, STEP_OVER, 0, 0, + STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -struct sm8500dasm -{ - uint8_t mnemonic; - uint8_t arguments; -}; - -static const char *const sm8500_cond[16] = { +const char *const sm8500_disassembler::sm8500_cond[16] = { "F", "LT", "LE", "ULE", "OV", "MI", "Z", "C", "T", "GE", "GT", "UGT", "NOV", "PL", "NZ", "NC" }; -static const uint8_t sm8500_b2w[8] = { +const uint8_t sm8500_disassembler::sm8500_b2w[8] = { 0, 8, 2, 10, 4, 12, 6, 14 }; -enum e_addrmodes { - AM_R=1, AM_rr, AM_r1, AM_S, AM_rmb, AM_mbr, AM_Ri, AM_rmw, AM_mwr, AM_smw, AM_mws, - AM_Sw, AM_iR, AM_rbr, AM_riw, AM_cjp, AM_rib, AM_pi, AM_cbr, AM_i, AM_ii, - AM_ss, AM_RR, AM_2, AM_SS, AM_bR, AM_Rbr, AM_Rb, AM_rR, AM_Rr, AM_Rii, AM_RiR, - AM_riB, AM_iS, AM_CALS, AM_bid, AM_1A, AM_1B, AM_4F -}; - -static const sm8500dasm mnemonic[256] = { +const sm8500_disassembler::sm8500dasm sm8500_disassembler::mnemonic[256] = { /* 00 - 0F */ {zCLR, AM_R}, {zNEG,AM_R}, {zCOM,AM_R}, {zRR,AM_R}, {zRL, AM_R}, {zRRC,AM_R}, {zRLC,AM_R}, {zSRL,AM_R}, @@ -173,16 +135,21 @@ static const sm8500dasm mnemonic[256] = { }; -CPU_DISASSEMBLE(sm8500) +u32 sm8500_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t sm8500_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const sm8500dasm *instr; uint8_t op; int8_t offset; uint16_t ea; uint16_t ea2; - int pos = 0; + offs_t pos = pc; - op = oprom[pos++]; + op = opcodes.r8(pos++); instr = &mnemonic[op]; @@ -193,34 +160,34 @@ CPU_DISASSEMBLE(sm8500) } switch( instr->arguments ) { case AM_R: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh", ea); break; case AM_iR: - util::stream_format(stream, "R%02Xh, $%02X", oprom[pos + 1], oprom[pos + 0]); + util::stream_format(stream, "R%02Xh, $%02X", opcodes.r8(pos+1), opcodes.r8(pos)); pos += 2; break; case AM_iS: - util::stream_format(stream, "RR%02Xh, $%02X", oprom[pos + 1], oprom[pos + 0]); + util::stream_format(stream, "RR%02Xh, $%02X", opcodes.r8(pos+1), opcodes.r8(pos)); pos += 2; break; case AM_Sw: - ea2 = oprom[pos++]; - ea = oprom[pos++] << 8; - ea += oprom[pos++]; + ea2 = opcodes.r8(pos++); + ea = opcodes.r8(pos++) << 8; + ea += opcodes.r8(pos++); util::stream_format(stream, "RR%02Xh, $%04X", ea2, ea); break; case AM_rib: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh, $%02X", op & 0x07, ea); break; case AM_riw: - ea = oprom[pos++] << 8; - ea += oprom[pos++]; + ea = opcodes.r8(pos++) << 8; + ea += opcodes.r8(pos++); util::stream_format(stream, "rr%02Xh, $%04X", sm8500_b2w[op & 0x07], ea); break; case AM_rmb: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh,", ( ea >> 3 ) & 0x07); switch( ea & 0xC0 ) { case 0x00: @@ -228,7 +195,7 @@ CPU_DISASSEMBLE(sm8500) case 0x40: util::stream_format(stream, "(r%02Xh)+", ea & 0x07); break; case 0x80: - ea2 = oprom[pos++]; + ea2 = opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%02X(r%02Xh)", ea2, ea & 0x07); } else { @@ -240,14 +207,14 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_mbr: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "@r%02Xh", ea & 0x07); break; case 0x40: util::stream_format(stream, "(r%02Xh)+", ea & 0x07); break; case 0x80: - ea2 = oprom[pos++]; + ea2 = opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%02X(r%02Xh)", ea2, ea & 0x07); } else { @@ -260,7 +227,7 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, ",r%02Xh", ( ea >> 3 ) & 0x07); break; case AM_rmw: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh,", ( ea >> 3 ) & 0x07); switch( ea & 0xC0 ) { case 0x00: @@ -268,8 +235,8 @@ CPU_DISASSEMBLE(sm8500) case 0x40: util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break; case 0x80: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]); } else { @@ -281,15 +248,15 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_mwr: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "@rr%02Xh", sm8500_b2w[ea & 0x07]); break; case 0x40: util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break; case 0x80: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]); } else { @@ -302,7 +269,7 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, ",r%02Xh", ( ea >> 3 ) & 0x07); break; case AM_smw: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "rr%02Xh,", sm8500_b2w[( ea >> 3 ) & 0x07]); switch( ea & 0xC0 ) { case 0x00: @@ -310,8 +277,8 @@ CPU_DISASSEMBLE(sm8500) case 0x40: util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break; case 0x80: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]); } else { @@ -323,15 +290,15 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_mws: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "@rr%02Xh", sm8500_b2w[ea & 0x07]); break; case 0x40: util::stream_format(stream, "(rr%02Xh)+", sm8500_b2w[ea & 0x07]); break; case 0x80: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x07 ) { util::stream_format(stream, "$%04X(rr%02Xh)", ea2, sm8500_b2w[ea & 0x07]); } else { @@ -344,20 +311,20 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, ",rr%02Xh", sm8500_b2w[( ea >> 3 ) & 0x07]); break; case AM_cbr: - offset = (int8_t) oprom[pos++]; + offset = (int8_t) opcodes.r8(pos++); util::stream_format(stream, "%s,$%04X", sm8500_cond[ op & 0x0F ], pc + pos + offset); break; case AM_rbr: - offset = (int8_t) oprom[pos++]; + offset = (int8_t) opcodes.r8(pos++); util::stream_format(stream, "r%02Xh,$%04X", op & 0x07, pc + pos + offset); break; case AM_cjp: - ea = oprom[pos++] << 8; - ea += oprom[pos++]; + ea = opcodes.r8(pos++) << 8; + ea += opcodes.r8(pos++); util::stream_format(stream, "%s,$%04X", sm8500_cond[ op & 0x0F], ea); break; case AM_rr: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xc0 ) { case 0x00: util::stream_format(stream, "r%02Xh,r%02Xh", (ea >> 3 ) & 0x07, ea & 0x07); @@ -370,7 +337,7 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_r1: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "@r%02Xh", (ea >> 3 ) & 0x07); @@ -383,29 +350,29 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_S: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "RR%02Xh", ea); break; case AM_pi: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh, $%02X", 0x10 + (op & 0x07), ea); break; case AM_Ri: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,$%02X", ea, ea2); break; case AM_i: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case AM_ii: - ea = oprom[pos++] << 8; - ea += oprom[pos++]; + ea = opcodes.r8(pos++) << 8; + ea += opcodes.r8(pos++); util::stream_format(stream, "$%04X", ea); break; case AM_ss: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "rr%02Xh,rr%02Xh", sm8500_b2w[( ea >> 3 ) & 0x07], sm8500_b2w[ea & 0x07]); break; @@ -418,18 +385,18 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_RR: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,R%02Xh", ea2, ea); break; case AM_2: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "rr%02Xh", sm8500_b2w[ea & 0x07]); break; case 0x40: - ea2 = oprom[pos++] << 8; - ea2 += oprom[pos++]; + ea2 = opcodes.r8(pos++) << 8; + ea2 += opcodes.r8(pos++); if ( ea & 0x38 ) { util::stream_format(stream, "@$%04X(r%02Xh)", ea2, ( ea >> 3 ) & 0x07); } else { @@ -443,13 +410,13 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_SS: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); util::stream_format(stream, "RR%02Xh,RR%02Xh", ea2, ea); break; case AM_bR: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "BF,R%02Xh,#%d", ea2, ea & 0x07); break; @@ -462,41 +429,41 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_Rbr: - ea = oprom[pos++]; - offset = (int8_t) oprom[pos++]; + ea = opcodes.r8(pos++); + offset = (int8_t) opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,#%d,$%04X", ea, op & 0x07, pc + pos + offset); break; case AM_Rb: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,#%d", ea, op&0x07); break; case AM_rR: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "r%02Xh,R%02Xh", op & 0x07, ea); break; case AM_Rr: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,r%02Xh", ea, op & 0x07); break; case AM_Rii: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,", ea); - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%02X,", ea); - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case AM_RiR: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh,", ea); - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%02X,", ea); - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "R%02Xh", ea); break; case AM_riB: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); switch( ea & 0xC0 ) { case 0x00: util::stream_format(stream, "#%2x(r%02Xh),#%d", ea2, ea >> 3, ea & 0x07); @@ -510,23 +477,23 @@ CPU_DISASSEMBLE(sm8500) } break; case AM_CALS: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); util::stream_format(stream, "$%04X", 0x1000 | ( ( op & 0x0f ) << 8 ) | ea); break; case AM_bid: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); if ( ea & 0x38 ) { util::stream_format(stream, "$%02X(r%02Xh)", ea2, ( ea >> 3 ) & 0x07); } else { util::stream_format(stream, "$%04X", 0xFF00 + ea2); } util::stream_format(stream, ",#%d,", ea & 0x07); - offset = (int8_t) oprom[pos++]; + offset = (int8_t) opcodes.r8(pos++); util::stream_format(stream, "$%04X", pc + pos + offset); break; case AM_1A: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0x07 ) { case 0x00: util::stream_format(stream, "%-4s ", s_mnemonic[ zCLR ]); break; case 0x01: util::stream_format(stream, "%-4s ", s_mnemonic[ zNEG ]); break; @@ -540,7 +507,7 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, "@r%02Xh", ( ea >> 3 ) & 0x07); break; case AM_1B: - ea = oprom[pos++]; + ea = opcodes.r8(pos++); switch( ea & 0x07 ) { case 0x00: util::stream_format(stream, "%-4s ", s_mnemonic[ zINC ]); break; case 0x01: util::stream_format(stream, "%-4s ", s_mnemonic[ zDEC ]); break; @@ -554,8 +521,8 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, "@r%02Xh", ( ea >> 3 ) & 0x07); break; case AM_4F: - ea = oprom[pos++]; - ea2 = oprom[pos++]; + ea = opcodes.r8(pos++); + ea2 = opcodes.r8(pos++); switch( ea & 0xc0 ) { case 0x00: util::stream_format(stream, "%-4s ", s_mnemonic[ zBCMP ]); break; case 0x40: util::stream_format(stream, "%-4s ", s_mnemonic[ zBAND ]); break; @@ -577,5 +544,5 @@ CPU_DISASSEMBLE(sm8500) util::stream_format(stream, "%s", s_mnemonic[ instr->mnemonic ]); } - return pos | s_flags[instr->mnemonic] | DASMFLAG_SUPPORTED; + return (pos - pc) | s_flags[instr->mnemonic] | SUPPORTED; } diff --git a/src/devices/cpu/sm8500/sm8500d.h b/src/devices/cpu/sm8500/sm8500d.h new file mode 100644 index 00000000000..8d425b86c19 --- /dev/null +++ b/src/devices/cpu/sm8500/sm8500d.h @@ -0,0 +1,68 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/******************************************************************* + +sm8500d.c +Sharp sm8500 CPU disassembly + + + +*******************************************************************/ + +#ifndef MAME_CPU_SM8500_SM8500D_H +#define MAME_CPU_SM8500_SM8500D_H + +#pragma once + +class sm8500_disassembler : public util::disasm_interface +{ +public: + sm8500_disassembler() = default; + virtual ~sm8500_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + zADC=0, zADCW, zADD, zADDW, zAND, zANDW, zBAND, zBBC, zBBS, + zBCLR, zBCMP, zBMOV, zBOR, zBR, zBTST, zBSET, zBXOR, zCALL, zCALS, zCLR, + zCLRC, zCMP, zCMPW, zCOM, zCOMC, zDA, zDBNZ, zDEC, + zDECW, zDI, zDIV, zEI, zEXTS, zHALT, zINC, zINCW, + zIRET, zJMP, zMOV, zMOVM, zMOVW, zMULT, zNEG, zNOP, zOR, + zORW, zPOP, zPOPW, zPUSH, zPUSHW, zRET, zRL, zRLC, + zRR, zRRC, zSBC, zSBCW, zSETC, zSLL, zSRA, zSRL, zSTOP, + zSUB, zSUBW, zSWAP, zXOR, zXORW, zMOVPS0, zINVLD, zDM, + /* unknowns */ + z5A, z5B, + + /* more complicated instructions */ + z1A, z1B, z4F + }; + + /* instructions not found: + 5A, 5B, + */ + + enum e_addrmodes { + AM_R=1, AM_rr, AM_r1, AM_S, AM_rmb, AM_mbr, AM_Ri, AM_rmw, AM_mwr, AM_smw, AM_mws, + AM_Sw, AM_iR, AM_rbr, AM_riw, AM_cjp, AM_rib, AM_pi, AM_cbr, AM_i, AM_ii, + AM_ss, AM_RR, AM_2, AM_SS, AM_bR, AM_Rbr, AM_Rb, AM_rR, AM_Rr, AM_Rii, AM_RiR, + AM_riB, AM_iS, AM_CALS, AM_bid, AM_1A, AM_1B, AM_4F + }; + + struct sm8500dasm + { + uint8_t mnemonic; + uint8_t arguments; + }; + + static const char *const s_mnemonic[]; + static const uint32_t s_flags[]; + static const char *const sm8500_cond[16]; + static const uint8_t sm8500_b2w[8]; + static const sm8500dasm mnemonic[256]; +}; + +#endif diff --git a/src/devices/cpu/sparc/mb86901.cpp b/src/devices/cpu/sparc/mb86901.cpp index 1f6430835f4..bf3023d8f97 100644 --- a/src/devices/cpu/sparc/mb86901.cpp +++ b/src/devices/cpu/sparc/mb86901.cpp @@ -43,7 +43,6 @@ const int mb86901_device::NWINDOWS = 7; mb86901_device::mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cpu_device(mconfig, MB86901, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, 32, 32) - , m_dasm(this, 7) { } @@ -257,7 +256,7 @@ void mb86901_device::device_start() state_add(SPARC_WIM, "WIM", m_wim).formatstr("%08X"); state_add(SPARC_TBR, "TBR", m_tbr).formatstr("%08X"); state_add(SPARC_Y, "Y", m_y).formatstr("%08X"); - state_add(SPARC_ANNUL, "ANNUL", m_annul).formatstr("%01d"); + state_add(SPARC_ANNUL, "ANNUL", m_annul).formatstr("%01u"); state_add(SPARC_ICC, "icc", m_icc).formatstr("%4s"); state_add(SPARC_CWP, "CWP", m_cwp).formatstr("%2d"); char regname[3] = "g0"; @@ -286,12 +285,12 @@ void mb86901_device::device_start() state_add(SPARC_I0 + i, regname, m_dbgregs[16+i]).formatstr("%08X"); } - state_add(SPARC_EC, "EC", m_ec).formatstr("%1d"); - state_add(SPARC_EF, "EF", m_ef).formatstr("%1d"); - state_add(SPARC_ET, "ET", m_et).formatstr("%1d"); + state_add(SPARC_EC, "EC", m_ec).formatstr("%1u"); + state_add(SPARC_EF, "EF", m_ef).formatstr("%1u"); + state_add(SPARC_ET, "ET", m_et).formatstr("%1u"); state_add(SPARC_PIL, "PIL", m_pil).formatstr("%2d"); - state_add(SPARC_S, "S", m_s).formatstr("%1d"); - state_add(SPARC_PS, "PS", m_ps).formatstr("%1d"); + state_add(SPARC_S, "S", m_s).formatstr("%1u"); + state_add(SPARC_PS, "PS", m_ps).formatstr("%1u"); char rname[5]; for (int i = 0; i < 120; i++) @@ -520,36 +519,15 @@ void mb86901_device::state_string_export(const device_state_entry &entry, std::s //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t mb86901_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t mb86901_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t mb86901_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *mb86901_device::create_disassembler() { - uint32_t op = *reinterpret_cast<const uint32_t *>(oprom); - return m_dasm.dasm(stream, pc, big_endianize_int32(op)); + auto dasm = new sparc_disassembler(this, 7); + m_asi_desc_adder(dasm); + return dasm; } diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h index 5355a2ed005..8d91183ee1a 100644 --- a/src/devices/cpu/sparc/sparc.h +++ b/src/devices/cpu/sparc/sparc.h @@ -20,9 +20,9 @@ // TODO: when there are more SPARC CPUs, move setter to a base class #define MCFG_SPARC_ADD_ASI_DESC(desc) \ - mb86901_device::add_asi_desc(*device, desc); + mb86901_device::add_asi_desc(*device, [](sparc_disassembler *dasm) { dasm->add_asi_desc(desc); }); -class mb86901_device : public cpu_device, protected sparc_debug_state +class mb86901_device : public cpu_device, protected sparc_disassembler::config { public: mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -43,9 +43,7 @@ public: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -53,7 +51,7 @@ public: uint8_t get_asi() { return m_asi; } uint32_t pc() { return m_pc; } - template<typename T> static void add_asi_desc(device_t &device, const T &desc) { return downcast<mb86901_device &>(device).add_asi_desc(desc); } + static void add_asi_desc(device_t &device, std::function<void (sparc_disassembler *)> f) { downcast<mb86901_device &>(device).m_asi_desc_adder = f; } #if LOG_FCODES void enable_log_fcodes(bool enable) { m_log_fcodes = enable; } @@ -62,8 +60,6 @@ public: #endif protected: - template<typename T> void add_asi_desc(const T &desc) { m_dasm.add_asi_desc(desc); } - void update_gpr_pointers(); void execute_add(uint32_t op); @@ -213,7 +209,6 @@ protected: // debugger helpers uint32_t m_dbgregs[24]; - sparc_disassembler m_dasm; // address spaces address_space *m_program; @@ -230,6 +225,8 @@ protected: // processor configuration static const int NWINDOWS; + + std::function<void (sparc_disassembler *)> m_asi_desc_adder; }; // device type definition diff --git a/src/devices/cpu/sparc/sparcdasm.cpp b/src/devices/cpu/sparc/sparcdasm.cpp index 296c987a467..584b5ab427a 100644 --- a/src/devices/cpu/sparc/sparcdasm.cpp +++ b/src/devices/cpu/sparc/sparcdasm.cpp @@ -17,10 +17,10 @@ namespace { int32_t get_disp19(uint32_t op) { return DISP19; } int32_t get_disp22(uint32_t op) { return DISP19; } - const char *bicc_comment(const sparc_debug_state *state, bool use_cc, offs_t pc, uint32_t op) + const char *bicc_comment(const sparc_disassembler::config *conf, bool use_cc, offs_t pc, uint32_t op) { - if (!state || (state->get_translated_pc() != pc)) return nullptr; - auto const cc((use_cc && (BRCC & 0x2)) ? state->get_xcc() : state->get_icc()); + if (!conf || (conf->get_translated_pc() != pc)) return nullptr; + auto const cc((use_cc && (BRCC & 0x2)) ? conf->get_xcc() : conf->get_icc()); switch (COND) { case 0x0: return "will fall through"; @@ -42,10 +42,10 @@ namespace { } return nullptr; } - const char *bfcc_comment(const sparc_debug_state *state, bool use_cc, offs_t pc, uint32_t op) + const char *bfcc_comment(const sparc_disassembler::config *conf, bool use_cc, offs_t pc, uint32_t op) { - if (!state || (state->get_translated_pc() != pc)) return nullptr; - auto const fcc(state->get_fcc(use_cc ? BRCC : 0)); + if (!conf || (conf->get_translated_pc() != pc)) return nullptr; + auto const fcc(conf->get_fcc(use_cc ? BRCC : 0)); switch (COND) { case 0x0: return "will fall through"; @@ -67,10 +67,10 @@ namespace { } return nullptr; } - const char *bpr_comment(const sparc_debug_state *state, bool use_cc, offs_t pc, uint32_t op) + const char *bpr_comment(const sparc_disassembler::config *conf, bool use_cc, offs_t pc, uint32_t op) { - if (!state || (state->get_translated_pc() != pc)) return nullptr; - const int64_t reg(state->get_reg_r(RS1)); + if (!conf || (conf->get_translated_pc() != pc)) return nullptr; + const int64_t reg(conf->get_reg_r(RS1)); switch (COND) { case 1: return (reg == 0) ? "will branch" : "will fall through"; @@ -610,12 +610,12 @@ inline void sparc_disassembler::pad_op_field(std::ostream &stream, std::streampo stream << ' '; } -sparc_disassembler::sparc_disassembler(const sparc_debug_state *state, unsigned version) - : sparc_disassembler(state, version, vis_none) +sparc_disassembler::sparc_disassembler(const config *conf, unsigned version) + : sparc_disassembler(conf, version, vis_none) { } -sparc_disassembler::sparc_disassembler(const sparc_debug_state *state, unsigned version, vis_level vis) +sparc_disassembler::sparc_disassembler(const config *conf, unsigned version, vis_level vis) : m_version(version) , m_vis_level(vis) , m_op_field_width(9) @@ -722,6 +722,15 @@ sparc_disassembler::sparc_disassembler(const sparc_debug_state *state, unsigned } } +u32 sparc_disassembler::opcode_alignment() const +{ + return 4; +} + +offs_t sparc_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + return dasm(stream, pc, opcodes.r32(pc)); +} offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) const { @@ -742,10 +751,10 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co default: return dasm_branch(stream, pc, op); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 1: util::stream_format(stream, "%-*s%%pc%c0x%08x ! 0x%08x", m_op_field_width, "call", (DISP30 < 0) ? '-' : '+', std::abs(DISP30), pc + DISP30); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 2: switch (OP3) { @@ -754,7 +763,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (SIMM13 == 1) util::stream_format(stream, "%-*s%s", m_op_field_width, "inc", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "inc", SIMM13, REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x02: @@ -763,13 +772,13 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (USEIMM) util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "mov", SIMM13, REG_NAMES[RD]); else if (RS2 == 0) util::stream_format(stream, "%-*s%s", m_op_field_width, "clr", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "mov", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if (RS1 == RD) { if (USEIMM) util::stream_format(stream, "%-*s0x%08x,%s", m_op_field_width, "bset", SIMM13, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "bset", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x03: @@ -777,7 +786,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (USEIMM) util::stream_format(stream, "%-*s0x%08x,%s", m_op_field_width, "btog", SIMM13, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "btog", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x04: @@ -787,7 +796,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (SIMM13 == 1) util::stream_format(stream, "%-*s%s", m_op_field_width, "dec", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "dec", SIMM13, REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else @@ -796,7 +805,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (RS2 == RD) util::stream_format(stream, "%-*s%s", m_op_field_width, "neg", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "neg", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } break; @@ -805,7 +814,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (USEIMM) util::stream_format(stream, "%-*s0x%08x,%s", m_op_field_width, "bclr", SIMM13, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "bclr", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x07: @@ -813,7 +822,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (RS1 == RD) util::stream_format(stream, "%-*s%s", m_op_field_width, "not", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "not", REG_NAMES[RS1], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x10: @@ -821,14 +830,14 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (SIMM13 == 1) util::stream_format(stream, "%-*s%s", m_op_field_width, "inccc", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "inccc", SIMM13, REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x12: if (!USEIMM && (RS1 == 0) && (RD == 0)) { util::stream_format(stream, "%-*s%s", m_op_field_width, "tst", REG_NAMES[RS2]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x14: @@ -836,7 +845,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (SIMM13 == 1) util::stream_format(stream, "%-*s%s", m_op_field_width, "deccc", REG_NAMES[RD]); else util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "deccc", SIMM13, REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x25: @@ -851,7 +860,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (m_version <= 8) { util::stream_format(stream, "%-*s%%psr,%s", m_op_field_width, "rd", REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x2a: @@ -860,13 +869,13 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (V9_PRIV_REG_NAMES[RS1]) { util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "rdpr", V9_PRIV_REG_NAMES[RS1], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else { util::stream_format(stream, "%-*s%%wim,%s", m_op_field_width, "rd", REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x2b: @@ -875,13 +884,13 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (!USEIMM) { util::stream_format(stream, "flushw"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else { util::stream_format(stream, "%-*s%%tbr,%s", m_op_field_width, "rd", REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x2c: @@ -891,7 +900,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { if (USEIMM) util::stream_format(stream, "%-*s%d,%s", m_op_field_width, "popc", SIMM13, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "popc", REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x2f: @@ -905,10 +914,10 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { case 0: util::stream_format(stream, "saved"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 1: util::stream_format(stream, "restored"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else @@ -923,7 +932,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (USEIMM) util::stream_format(stream, "%-*s%s,0x%08x,%%psr", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); else util::stream_format(stream, "%-*s%s,%s,%%psr", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x32: @@ -935,7 +944,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (!USEIMM) util::stream_format(stream, "%-*s%s,%s,%s", m_op_field_width, "wrpr", REG_NAMES[RS1], REG_NAMES[RS2], V9_PRIV_REG_NAMES[RD]); else if (RS1 == 0) util::stream_format(stream, "%-*s0x%08x,%s", m_op_field_width, "wrpr", SIMM13, V9_PRIV_REG_NAMES[RD]); else util::stream_format(stream, "%-*s%s,0x%08x,%s", m_op_field_width, "wrpr", REG_NAMES[RS1], SIMM13, V9_PRIV_REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else @@ -950,7 +959,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (USEIMM) util::stream_format(stream, "%-*s%s,0x%08x,%%wim", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); else util::stream_format(stream, "%-*s%s,%s,%%wim", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x33: @@ -966,7 +975,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co if (USEIMM) util::stream_format(stream, "%-*s%s,0x%08x,%%tbr", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); else util::stream_format(stream, "%-*s%s,%s,%%tbr", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x34: @@ -989,21 +998,21 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { util::stream_format(stream, "%-*s", m_op_field_width, "flush"); dasm_address(stream, op); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x3c: if (!USEIMM && (RS1 == RS2) && (RS2 == RD) && (RD == 0)) { util::stream_format(stream, "save"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x3d: if (!USEIMM && (RS1 == RS2) && (RS2 == RD) && (RD == 0)) { util::stream_format(stream, "restore"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x3e: @@ -1011,8 +1020,8 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co { switch (RD) { - case 0: util::stream_format(stream, "done"); return 4 | DASMFLAG_SUPPORTED; - case 1: util::stream_format(stream, "retry"); return 4 | DASMFLAG_SUPPORTED; + case 0: util::stream_format(stream, "done"); return 4 | SUPPORTED; + case 1: util::stream_format(stream, "retry"); return 4 | SUPPORTED; } } break; @@ -1039,7 +1048,7 @@ offs_t sparc_disassembler::dasm(std::ostream &stream, offs_t pc, uint32_t op) co else util::stream_format(stream, "%-*s%s,%d,%s", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], SIMM13, REG_NAMES[RD]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } break; @@ -1072,7 +1081,7 @@ offs_t sparc_disassembler::dasm_invalid(std::ostream &stream, offs_t pc, uint32_ { util::stream_format(stream, "op=%x op3=%02x i=%01x rd=%d", OP, OP3, USEIMM, RD); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1089,10 +1098,10 @@ offs_t sparc_disassembler::dasm_branch(std::ostream &stream, offs_t pc, uint32_t if (OP2 == 3) util::stream_format(stream, "%s,", REG_NAMES[RS1]); const int32_t disp(desc.get_disp(op)); util::stream_format(stream, "%%pc%c0x%0*x ! 0x%08x", (disp < 0) ? '-' : '+', desc.disp_width, std::abs(disp), pc + disp); - //const char * const comment(desc.get_comment ? desc.get_comment(m_state, desc.use_cc, pc, op) : nullptr); + //const char * const comment(desc.get_comment ? desc.get_comment(m_config, desc.use_cc, pc, op) : nullptr); //if (comment) util::stream_format(stream, " - %s", comment); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1117,7 +1126,7 @@ offs_t sparc_disassembler::dasm_shift(std::ostream &stream, offs_t pc, uint32_t { util::stream_format(stream, "%-*s%s,%s,%s", m_op_field_width, mnemonic, REG_NAMES[RS1], REG_NAMES[RS2], REG_NAMES[RD]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1126,14 +1135,14 @@ offs_t sparc_disassembler::dasm_read_state_reg(std::ostream &stream, offs_t pc, if (RS1 == 0) { util::stream_format(stream, "%-*s%%y,%s", m_op_field_width, "rd", REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if ((m_version == 8) || ((m_version >= 9) && !USEIMM)) { if (!USEIMM && (RS1 == 15) && (RD == 0)) { util::stream_format(stream, "stbar"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else { @@ -1144,7 +1153,7 @@ offs_t sparc_disassembler::dasm_read_state_reg(std::ostream &stream, offs_t pc, util::stream_format(stream, "%-*s%s,%s", m_op_field_width, "rd", it->second.read_name, REG_NAMES[RD]); else util::stream_format(stream, "%-*s%%asr%d,%s ! %s", m_op_field_width, "rd", RS1, REG_NAMES[RD], (RS1 < 16) ? "reserved" : "implementation-dependent"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } } @@ -1166,7 +1175,7 @@ offs_t sparc_disassembler::dasm_read_state_reg(std::ostream &stream, offs_t pc, if (mask & 1) util::stream_format(stream, "#MemIssue%s", (mask >> 1) ? "|" : ""); mask >>= 1; if (mask & 1) util::stream_format(stream, "#Sync"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } return dasm_invalid(stream, pc, op); } @@ -1186,14 +1195,14 @@ offs_t sparc_disassembler::dasm_write_state_reg(std::ostream &stream, offs_t pc, if (USEIMM) util::stream_format(stream, "%-*s%s,%08x,%%y", m_op_field_width, "wr", REG_NAMES[RS1], SIMM13); else util::stream_format(stream, "%-*s%s,%s,%%y", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if (m_version >= 8) { if ((m_version >= 9) && USEIMM && (RS1 == 0) && (RD == 15)) { util::stream_format(stream, "%-*s%d", m_op_field_width, "sir", SIMM13); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else { @@ -1227,7 +1236,7 @@ offs_t sparc_disassembler::dasm_write_state_reg(std::ostream &stream, offs_t pc, else util::stream_format(stream, "%-*s%s,%s,%%asr%d ! %s", m_op_field_width, "wr", REG_NAMES[RS1], REG_NAMES[RS2], RD, comment); } } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } } @@ -1247,7 +1256,7 @@ offs_t sparc_disassembler::dasm_move_cond(std::ostream &stream, offs_t pc, uint3 else util::stream_format(stream, "%s,%s,%s", MOVCC_CC_NAMES[MOVCC], REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } offs_t sparc_disassembler::dasm_move_reg_cond(std::ostream &stream, offs_t pc, uint32_t op) const @@ -1259,7 +1268,7 @@ offs_t sparc_disassembler::dasm_move_reg_cond(std::ostream &stream, offs_t pc, u else util::stream_format(stream, "%-*s%s,%s,%s", m_op_field_width, MOVE_INT_COND_MNEMONICS[RCOND], REG_NAMES[RS1], REG_NAMES[RS2], REG_NAMES[RD]); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1272,7 +1281,7 @@ offs_t sparc_disassembler::dasm_fpop1(std::ostream &stream, offs_t pc, uint32_t util::stream_format(stream, "%-*s%%f%d,%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, freg(RS1, it->second.rs1_shift), freg(RS2, it->second.rs2_shift), freg(RD, it->second.rd_shift)); else util::stream_format(stream, "%-*s%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, freg(RS2, it->second.rs2_shift), freg(RD, it->second.rd_shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1296,7 +1305,7 @@ offs_t sparc_disassembler::dasm_fpop2(std::ostream &stream, offs_t pc, uint32_t util::stream_format(stream, "%s%s", mnemonic, MOVCC_COND_NAMES[MOVCOND | ((OPFCC << 2) & 16)]); pad_op_field(stream, start_position); util::stream_format(stream, "%s,%%f%d,%%f%d", MOVCC_CC_NAMES[OPFCC], freg(RS2, shift), freg(RD, shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } @@ -1308,18 +1317,18 @@ offs_t sparc_disassembler::dasm_fpop2(std::ostream &stream, offs_t pc, uint32_t if (it->second.int_rs1) { util::stream_format(stream, "%-*s%s,%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, REG_NAMES[RS1], freg(RS2, it->second.shift), freg(RD, it->second.shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if (RD < 4) { util::stream_format(stream, "%-*s%%fcc%d,%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, RD, freg(RS1, it->second.shift), freg(RS2, it->second.shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else if (!it->second.int_rs1) { util::stream_format(stream, "%-*s%%f%d,%%f%d", m_op_field_width, it->second.mnemonic, freg(RS1, it->second.shift), freg(RS2, it->second.shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } @@ -1348,7 +1357,7 @@ offs_t sparc_disassembler::dasm_impdep1(std::ostream &stream, offs_t pc, uint32_ dasm_vis_arg(stream, args, it->second.rs2, RS2); } dasm_vis_arg(stream, args, it->second.rd, RD); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } switch (OPF) @@ -1357,7 +1366,7 @@ offs_t sparc_disassembler::dasm_impdep1(std::ostream &stream, offs_t pc, uint32_ if (m_vis_level >= vis_2) { util::stream_format(stream, "%-*s0x%x", m_op_field_width, "siam", IAMODE); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x151: @@ -1366,7 +1375,7 @@ offs_t sparc_disassembler::dasm_impdep1(std::ostream &stream, offs_t pc, uint32_ { const bool shift(OPF == 0x152); util::stream_format(stream, "%-*s%%fcc%d,%%f%d,%%f%d", m_op_field_width, (shift) ? "flcmpd" : "flcmps", RD & 3, freg(RS1, shift), freg(RS2, shift)); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; } @@ -1390,7 +1399,7 @@ offs_t sparc_disassembler::dasm_jmpl(std::ostream &stream, offs_t pc, uint32_t o if ((RD != 0) && (RD != 15)) util::stream_format(stream, ",%s", REG_NAMES[RD]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1398,7 +1407,7 @@ offs_t sparc_disassembler::dasm_return(std::ostream &stream, offs_t pc, uint32_t { util::stream_format(stream, "%-*s", m_op_field_width, (m_version >= 9) ? "return" : "rett"); dasm_address(stream, op); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1431,7 +1440,7 @@ offs_t sparc_disassembler::dasm_tcc(std::ostream &stream, offs_t pc, uint32_t op else if (RS2 == 0) util::stream_format(stream, "%s", REG_NAMES[RS1]); else util::stream_format(stream, "%s,%s", REG_NAMES[RS1], REG_NAMES[RS2]); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } @@ -1447,7 +1456,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o util::stream_format(stream, "%-*s[", m_op_field_width, (RD == 1) ? "ldx" : "ld"); dasm_address(stream, op); util::stream_format(stream, "],%%fsr"); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } else if ((RD == 3) && (m_vis_level >= vis_3b)) { @@ -1462,7 +1471,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o util::stream_format(stream, "%-*s%%fsr,[", m_op_field_width, (RD == 1) ? "stx" : "st"); dasm_address(stream, op); stream << ']'; - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } break; case 0x3c: // Compare and swap word in alternate space @@ -1488,7 +1497,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o util::stream_format(stream, ",%s,%s", REG_NAMES[RS2], REG_NAMES[RD]); if (print_asi) dasm_asi_comment(stream, op); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 0x2d: // Prefetch data case 0x3d: // Prefetch data from alternate space { @@ -1501,7 +1510,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o else util::stream_format(stream, ",0x%02x", RD); if (OP3 == 0x3d) dasm_asi_comment(stream, op); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } else @@ -1513,19 +1522,19 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o util::stream_format(stream, "%-*s[", m_op_field_width, "ld"); dasm_address(stream, op); util::stream_format(stream, "],%%%csr", (OP3 == 0x31) ? 'c' : 'f'); - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 0x25: // Store Floating-point State Register case 0x35: // Store Coprocessor State Register util::stream_format(stream, "%-*s%%%csr,[", m_op_field_width, "st", (OP3 == 0x35) ? 'c' : 'f'); dasm_address(stream, op); stream << ']'; - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; case 0x26: // Store Floating-point deferred-trap Queue case 0x36: // Store Coprocessor deferred-trap Queue util::stream_format(stream, "%-*s%%%cq,[", m_op_field_width, "std", (OP3 == 0x36) ? 'c' : 'f'); dasm_address(stream, op); stream << ']'; - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } } @@ -1566,7 +1575,7 @@ offs_t sparc_disassembler::dasm_ldst(std::ostream &stream, offs_t pc, uint32_t o } if (it->second.alternate) dasm_asi_comment(stream, op); } - return 4 | DASMFLAG_SUPPORTED; + return 4 | SUPPORTED; } diff --git a/src/devices/cpu/sparc/sparcdasm.h b/src/devices/cpu/sparc/sparcdasm.h index f5643a0e87b..f6f0e7bc27d 100644 --- a/src/devices/cpu/sparc/sparcdasm.h +++ b/src/devices/cpu/sparc/sparcdasm.h @@ -11,24 +11,21 @@ #include <map> - -class sparc_debug_state +class sparc_disassembler : public util::disasm_interface { public: - virtual uint64_t get_reg_r(unsigned index) const = 0; - virtual uint64_t get_translated_pc() const = 0; - virtual uint8_t get_icc() const = 0; - virtual uint8_t get_xcc() const = 0; - virtual uint8_t get_fcc(unsigned index) const = 0; // ?><= - -protected: - ~sparc_debug_state() { } -}; + struct config + { + public: + virtual ~config() = default; + virtual uint64_t get_reg_r(unsigned index) const = 0; + virtual uint64_t get_translated_pc() const = 0; + virtual uint8_t get_icc() const = 0; + virtual uint8_t get_xcc() const = 0; + virtual uint8_t get_fcc(unsigned index) const = 0; // ?><= + }; -class sparc_disassembler -{ -public: enum vis_level { vis_none, vis_1, vis_2, vis_2p, vis_3, vis_3b }; struct asi_desc @@ -58,8 +55,8 @@ public: }; typedef std::map<uint8_t, prftch_desc> prftch_desc_map; - sparc_disassembler(const sparc_debug_state *state, unsigned version); - sparc_disassembler(const sparc_debug_state *state, unsigned version, vis_level vis); + sparc_disassembler(const config *conf, unsigned version); + sparc_disassembler(const config *conf, unsigned version, vis_level vis); template <typename T> void add_state_reg_desc(const T &desc) { @@ -106,13 +103,16 @@ public: } } + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + offs_t dasm(std::ostream &stream, offs_t pc, uint32_t op) const; private: struct branch_desc { int32_t (*get_disp)(uint32_t op); - const char * (*get_comment)(const sparc_debug_state *state, bool use_cc, offs_t pc, uint32_t op); + const char * (*get_comment)(const config *conf, bool use_cc, offs_t pc, uint32_t op); int disp_width; bool use_pred, use_cc; const char *reg_cc[4]; @@ -238,7 +238,7 @@ private: static const vis_op_desc_map::value_type VIS3_OP_DESC[]; static const vis_op_desc_map::value_type VIS3B_OP_DESC[]; - //const sparc_debug_state *m_state; + //const config *m_config; unsigned m_version; vis_level m_vis_level; int m_op_field_width; diff --git a/src/devices/cpu/spc700/spc700.cpp b/src/devices/cpu/spc700/spc700.cpp index cb44ce03c19..07390f03969 100644 --- a/src/devices/cpu/spc700/spc700.cpp +++ b/src/devices/cpu/spc700/spc700.cpp @@ -1353,9 +1353,9 @@ void spc700_device::execute_set_input( int inptnum, int state ) #include "spc700ds.h" -offs_t spc700_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *spc700_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(spc700)(this, stream, pc, oprom, opram, options); + return new spc700_disassembler; } //int dump_flag = 0; diff --git a/src/devices/cpu/spc700/spc700.h b/src/devices/cpu/spc700/spc700.h index 161ebea347c..6af60c16d8e 100644 --- a/src/devices/cpu/spc700/spc700.h +++ b/src/devices/cpu/spc700/spc700.h @@ -33,9 +33,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/spc700/spc700ds.cpp b/src/devices/cpu/spc700/spc700ds.cpp index de7accc7cb8..9f220b02e26 100644 --- a/src/devices/cpu/spc700/spc700ds.cpp +++ b/src/devices/cpu/spc700/spc700ds.cpp @@ -15,39 +15,7 @@ All rights reserved. #include "emu.h" #include "spc700ds.h" - - -struct spc700_opcode_struct -{ - unsigned char name; - unsigned char args[2]; -}; - -enum -{ - IMP , A , X , Y , YA , SP , PSW , C , REL , UPAG, IMM , XI , - XII , YI , DP , DPX , DPY , DPI , DXI , DIY , ABS , ABX , ABY , AXI , N0 , - N1 , N2 , N3 , N4 , N5 , N6 , N7 , N8 , N9 , N10 , N11 , N12 , - N13 , N14 , N15 , DP0 , DP1 , DP2 , DP3 , DP4 , DP5 , DP6 , DP7 , MEMN, - MEMI -}; - - -enum -{ - ADC , ADDW , AND , AND1 , ASL , BBC , BBS , BCC , - BCS , BEQ , BMI , BNE , BPL , BRA , BRK , BVC , - BVS , CALL , CBNE , CLR1 , CLRC , CLRP , CLRV , CMP , - CMPW , DAA , DAS , DBNZ , DEC , DECW , DI , DIV , - EI , EOR , EOR1 , INC , INCW , JMP , LSR , MOV , - MOV1 , MOVW , MUL , NOP , NOT1 , NOTQ , NOTC , OR , - OR1 , PCALL , POP , PUSH , RET , RETI , ROL , ROR , - SBC , SET1 , SETC , SETP , SLEEP , STOP , SUBW , TCALL , - TCLR1 , TSET1 , XCN -}; - - -static const char *const g_opnames[] = +const char *const spc700_disassembler::g_opnames[] = { "ADC ", "ADDW ", "AND ", "AND1 ", "ASL ", "BBC ", "BBS ", "BCC ", "BCS ", "BEQ ", "BMI ", "BNE ", "BPL ", "BRA ", "BRK ", "BVC ", @@ -60,7 +28,7 @@ static const char *const g_opnames[] = "TCLR1", "TSET1", "XCN " }; -static const spc700_opcode_struct g_opcodes[256] = +const spc700_disassembler::spc700_opcode_struct spc700_disassembler::g_opcodes[256] = { /* 00 */ {NOP , {IMP , IMP }}, /* 01 */ {TCALL , {N0 , IMP }}, @@ -320,45 +288,44 @@ static const spc700_opcode_struct g_opcodes[256] = /* FF */ {STOP , {IMP , IMP }}, }; -static unsigned int g_pc; -static const uint8_t *rombase; +inline unsigned int spc700_disassembler::read_8_immediate(offs_t &pc, const data_buffer &opcodes) +{ + return opcodes.r8(pc++); +} -static inline unsigned int read_8_immediate(void) +inline unsigned int spc700_disassembler::read_16_immediate(offs_t &pc, const data_buffer &opcodes) { - g_pc++; - return *rombase++; + u16 r = opcodes.r16(pc); + pc += 2; + return r; } -static inline unsigned int read_16_immediate(void) +u32 spc700_disassembler::opcode_alignment() const { - unsigned int result; - g_pc += 2; - result = *rombase++; - return result | (*rombase++ << 8); + return 1; } -CPU_DISASSEMBLE(spc700) +offs_t spc700_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const spc700_opcode_struct* opcode; uint32_t flags = 0; int var; int i; + offs_t base_pc = pc; - g_pc = pc; - rombase = oprom; - opcode = g_opcodes + read_8_immediate(); + opcode = g_opcodes + read_8_immediate(pc, opcodes); stream << g_opnames[opcode->name] << " "; if (opcode->name == CALL) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (opcode->name == RET || opcode->name == RETI) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; if (opcode->args[0] == DP && (opcode->args[1] == DP || opcode->args[1] == IMM)) { - int src = read_8_immediate(); - int dst = read_8_immediate(); + int src = read_8_immediate(pc, opcodes); + int dst = read_8_immediate(pc, opcodes); util::stream_format(stream, "$%02x,%s$%02x", dst, (opcode->args[1] == IMM ? "#" : ""), src); } else for(i=0;i<2;i++) @@ -378,22 +345,22 @@ CPU_DISASSEMBLE(spc700) case SP: util::stream_format(stream, "SP"); break; case PSW: util::stream_format(stream, "PSW"); break; case C: util::stream_format(stream, "C"); break; - case REL: util::stream_format(stream, "%04x", ((g_pc + (char)read_8_immediate())&0xffff)); break; - case UPAG: util::stream_format(stream, "$%02x", read_8_immediate()); break; - case IMM: util::stream_format(stream, "#$%02x", read_8_immediate()); break; + case REL: util::stream_format(stream, "%04x", ((pc + (char)read_8_immediate(pc, opcodes))&0xffff)); break; + case UPAG: util::stream_format(stream, "$%02x", read_8_immediate(pc, opcodes)); break; + case IMM: util::stream_format(stream, "#$%02x", read_8_immediate(pc, opcodes)); break; case XI: util::stream_format(stream, "(X)"); break; case XII: util::stream_format(stream, "(X)+"); break; case YI: util::stream_format(stream, "(Y)"); break; - case DP: util::stream_format(stream, "$%02x", read_8_immediate()); break; - case DPX: util::stream_format(stream, "$%02x+X", read_8_immediate()); break; - case DPY: util::stream_format(stream, "$%02x+Y", read_8_immediate()); break; - case DPI: util::stream_format(stream, "($%02x)", read_8_immediate()); break; - case DXI: util::stream_format(stream, "($%02x+X)", read_8_immediate()); break; - case DIY: util::stream_format(stream, "($%02x)+Y", read_8_immediate()); break; - case ABS: util::stream_format(stream, "$%04x", read_16_immediate()); break; - case ABX: util::stream_format(stream, "$%04x+X", read_16_immediate()); break; - case ABY: util::stream_format(stream, "$%04x+Y", read_16_immediate()); break; - case AXI: util::stream_format(stream, "($%04x+X)", read_16_immediate()); break; + case DP: util::stream_format(stream, "$%02x", read_8_immediate(pc, opcodes)); break; + case DPX: util::stream_format(stream, "$%02x+X", read_8_immediate(pc, opcodes)); break; + case DPY: util::stream_format(stream, "$%02x+Y", read_8_immediate(pc, opcodes)); break; + case DPI: util::stream_format(stream, "($%02x)", read_8_immediate(pc, opcodes)); break; + case DXI: util::stream_format(stream, "($%02x+X)", read_8_immediate(pc, opcodes)); break; + case DIY: util::stream_format(stream, "($%02x)+Y", read_8_immediate(pc, opcodes)); break; + case ABS: util::stream_format(stream, "$%04x", read_16_immediate(pc, opcodes)); break; + case ABX: util::stream_format(stream, "$%04x+X", read_16_immediate(pc, opcodes)); break; + case ABY: util::stream_format(stream, "$%04x+Y", read_16_immediate(pc, opcodes)); break; + case AXI: util::stream_format(stream, "($%04x+X)", read_16_immediate(pc, opcodes)); break; case N0: util::stream_format(stream, "0"); break; case N1: util::stream_format(stream, "1"); break; case N2: util::stream_format(stream, "2"); break; @@ -410,23 +377,23 @@ CPU_DISASSEMBLE(spc700) case N13: util::stream_format(stream, "13"); break; case N14: util::stream_format(stream, "14"); break; case N15: util::stream_format(stream, "15"); break; - case DP0: util::stream_format(stream, "$%02x.0", read_8_immediate()); break; - case DP1: util::stream_format(stream, "$%02x.1", read_8_immediate()); break; - case DP2: util::stream_format(stream, "$%02x.2", read_8_immediate()); break; - case DP3: util::stream_format(stream, "$%02x.3", read_8_immediate()); break; - case DP4: util::stream_format(stream, "$%02x.4", read_8_immediate()); break; - case DP5: util::stream_format(stream, "$%02x.5", read_8_immediate()); break; - case DP6: util::stream_format(stream, "$%02x.6", read_8_immediate()); break; - case DP7: util::stream_format(stream, "$%02x.7", read_8_immediate()); break; + case DP0: util::stream_format(stream, "$%02x.0", read_8_immediate(pc, opcodes)); break; + case DP1: util::stream_format(stream, "$%02x.1", read_8_immediate(pc, opcodes)); break; + case DP2: util::stream_format(stream, "$%02x.2", read_8_immediate(pc, opcodes)); break; + case DP3: util::stream_format(stream, "$%02x.3", read_8_immediate(pc, opcodes)); break; + case DP4: util::stream_format(stream, "$%02x.4", read_8_immediate(pc, opcodes)); break; + case DP5: util::stream_format(stream, "$%02x.5", read_8_immediate(pc, opcodes)); break; + case DP6: util::stream_format(stream, "$%02x.6", read_8_immediate(pc, opcodes)); break; + case DP7: util::stream_format(stream, "$%02x.7", read_8_immediate(pc, opcodes)); break; case MEMN: - var = read_16_immediate(); + var = read_16_immediate(pc, opcodes); util::stream_format(stream, "%04x.%d", var&0x1fff, var>>13); break; case MEMI: - var = read_16_immediate(); + var = read_16_immediate(pc, opcodes); util::stream_format(stream, "/%04x.%d", var&0x1fff, var>>13); break; } } - return (g_pc - pc) | flags | DASMFLAG_SUPPORTED; + return (pc - base_pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/spc700/spc700ds.h b/src/devices/cpu/spc700/spc700ds.h index e2135526363..fdd7bbeba7b 100644 --- a/src/devices/cpu/spc700/spc700ds.h +++ b/src/devices/cpu/spc700/spc700ds.h @@ -17,8 +17,49 @@ All rights reserved. */ +class spc700_disassembler : public util::disasm_interface +{ +public: + spc700_disassembler() = default; + virtual ~spc700_disassembler() = default; -CPU_DISASSEMBLE( spc700 ); + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct spc700_opcode_struct + { + unsigned char name; + unsigned char args[2]; + }; + + enum + { + IMP , A , X , Y , YA , SP , PSW , C , REL , UPAG, IMM , XI , + XII , YI , DP , DPX , DPY , DPI , DXI , DIY , ABS , ABX , ABY , AXI , N0 , + N1 , N2 , N3 , N4 , N5 , N6 , N7 , N8 , N9 , N10 , N11 , N12 , + N13 , N14 , N15 , DP0 , DP1 , DP2 , DP3 , DP4 , DP5 , DP6 , DP7 , MEMN, + MEMI + }; + + enum + { + ADC , ADDW , AND , AND1 , ASL , BBC , BBS , BCC , + BCS , BEQ , BMI , BNE , BPL , BRA , BRK , BVC , + BVS , CALL , CBNE , CLR1 , CLRC , CLRP , CLRV , CMP , + CMPW , DAA , DAS , DBNZ , DEC , DECW , DI , DIV , + EI , EOR , EOR1 , INC , INCW , JMP , LSR , MOV , + MOV1 , MOVW , MUL , NOP , NOT1 , NOTQ , NOTC , OR , + OR1 , PCALL , POP , PUSH , RET , RETI , ROL , ROR , + SBC , SET1 , SETC , SETP , SLEEP , STOP , SUBW , TCALL , + TCLR1 , TSET1 , XCN + }; + + static const char *const g_opnames[]; + static const spc700_opcode_struct g_opcodes[256]; + static inline unsigned int read_8_immediate(offs_t &pc, const data_buffer &opcodes); + static inline unsigned int read_16_immediate(offs_t &pc, const data_buffer &opcodes); +}; #endif /* __SPC700DS_H__ */ diff --git a/src/devices/cpu/ssem/ssem.cpp b/src/devices/cpu/ssem/ssem.cpp index 69c6ce66571..6cfffaef83d 100644 --- a/src/devices/cpu/ssem/ssem.cpp +++ b/src/devices/cpu/ssem/ssem.cpp @@ -9,8 +9,7 @@ #include "emu.h" #include "debugger.h" #include "ssem.h" - -CPU_DISASSEMBLE( ssem ); +#include "ssemdasm.h" #define SSEM_DISASM_ON_UNIMPL 0 @@ -160,36 +159,13 @@ void ssem_device::state_string_export(const device_state_entry &entry, std::stri //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t ssem_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t ssem_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t ssem_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ssem_device::create_disassembler() { - extern CPU_DISASSEMBLE( ssem ); - return CPU_DISASSEMBLE_NAME(ssem)(this, stream, pc, oprom, opram, options); + return new ssem_disassembler; } diff --git a/src/devices/cpu/ssem/ssem.h b/src/devices/cpu/ssem/ssem.h index b9485678a18..c6e396307f1 100644 --- a/src/devices/cpu/ssem/ssem.h +++ b/src/devices/cpu/ssem/ssem.h @@ -41,9 +41,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; @@ -82,6 +80,4 @@ enum SSEM_HALT }; -CPU_DISASSEMBLE( ssem ); - #endif // MAME_CPU_SSEM_SSEM_H diff --git a/src/devices/cpu/ssem/ssemdasm.cpp b/src/devices/cpu/ssem/ssemdasm.cpp index 8ad79f96d8c..43adb44510b 100644 --- a/src/devices/cpu/ssem/ssemdasm.cpp +++ b/src/devices/cpu/ssem/ssemdasm.cpp @@ -7,8 +7,9 @@ */ #include "emu.h" +#include "ssemdasm.h" -static inline uint32_t reverse(uint32_t v) +inline uint32_t ssem_disassembler::reverse(uint32_t v) { // Taken from http://www-graphics.stanford.edu/~seander/bithacks.html#ReverseParallel // swap odd and even bits @@ -25,8 +26,14 @@ static inline uint32_t reverse(uint32_t v) return v; } -static offs_t ssem_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) +u32 ssem_disassembler::opcode_alignment() const { + return 4; +} + +offs_t ssem_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint32_t op = opcodes.r32(pc); uint8_t instr = (reverse(op) >> 13) & 7; uint8_t addr = reverse(op) & 0x1f; @@ -59,16 +66,5 @@ static offs_t ssem_dasm_one(std::ostream &stream, offs_t pc, uint32_t op) break; } - return 4 | DASMFLAG_SUPPORTED; -} - -/*****************************************************************************/ - -CPU_DISASSEMBLE( ssem ) -{ - uint32_t op = (*(uint8_t *)(opram + 0) << 24) | - (*(uint8_t *)(opram + 1) << 16) | - (*(uint8_t *)(opram + 2) << 8) | - (*(uint8_t *)(opram + 3) << 0); - return ssem_dasm_one(stream, pc, op); + return 4 | SUPPORTED; } diff --git a/src/devices/cpu/ssem/ssemdasm.h b/src/devices/cpu/ssem/ssemdasm.h new file mode 100644 index 00000000000..a83e38c6f8f --- /dev/null +++ b/src/devices/cpu/ssem/ssemdasm.h @@ -0,0 +1,28 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/* + Manchester Small-Scale Experimental Machine (SSEM) disassembler + + Written by Ryan Holtz +*/ + +#ifndef MAME_CPU_SSEM_SSEMDASM_H +#define MAME_CPU_SSEM_SSEMDASM_H + +#pragma once + +class ssem_disassembler : public util::disasm_interface +{ +public: + ssem_disassembler() = default; + virtual ~ssem_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static inline uint32_t reverse(uint32_t v); + +}; + +#endif diff --git a/src/devices/cpu/ssp1601/ssp1601.cpp b/src/devices/cpu/ssp1601/ssp1601.cpp index 0ee9139cc1c..b19766b72c5 100644 --- a/src/devices/cpu/ssp1601/ssp1601.cpp +++ b/src/devices/cpu/ssp1601/ssp1601.cpp @@ -18,6 +18,7 @@ #include "emu.h" #include "ssp1601.h" +#include "ssp1601d.h" #include "debugger.h" @@ -44,8 +45,8 @@ #define PPC m_ppc.w.h -#define FETCH() m_direct->read_word(rPC++ << 1) -#define PROGRAM_WORD(a) m_program->read_word((a) << 1) +#define FETCH() m_direct->read_word(rPC++) +#define PROGRAM_WORD(a) m_program->read_word(a) #define GET_PPC_OFFS() PPC #define REG_READ(r) (((r) <= 4) ? m_gr[r].w.h : (this->*reg_read_handlers[r])(r)) @@ -209,10 +210,9 @@ device_memory_interface::space_config_vector ssp1601_device::memory_space_config } -offs_t ssp1601_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ssp1601_device::create_disassembler() { - extern CPU_DISASSEMBLE( ssp1601 ); - return CPU_DISASSEMBLE_NAME(ssp1601)(this, stream, pc, oprom, opram, options); + return new ssp1601_disassembler; } @@ -522,7 +522,7 @@ void ssp1601_device::device_start() m_gr[0].w.h = 0xffff; // constant reg m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_io = &space(AS_IO); state_add( SSP_R0, "REG0", m_gr[0].w.h).formatstr("%04X"); diff --git a/src/devices/cpu/ssp1601/ssp1601.h b/src/devices/cpu/ssp1601/ssp1601.h index 55a1184b5bb..a44615b16f3 100644 --- a/src/devices/cpu/ssp1601/ssp1601.h +++ b/src/devices/cpu/ssp1601/ssp1601.h @@ -43,9 +43,7 @@ protected: 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 2; } - 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -74,7 +72,7 @@ private: int m_g_cycles; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_io; void update_P(); diff --git a/src/devices/cpu/ssp1601/ssp1601d.cpp b/src/devices/cpu/ssp1601/ssp1601d.cpp index 465dd657d90..5b9f3c6ac27 100644 --- a/src/devices/cpu/ssp1601/ssp1601d.cpp +++ b/src/devices/cpu/ssp1601/ssp1601d.cpp @@ -9,10 +9,10 @@ */ #include "emu.h" -#include "debugger.h" +#include "ssp1601d.h" -static const char *const reg[16] = +const char *const ssp1601_disassembler::reg[16] = { "-", "X", "Y", "A", "ST", "STACK", "PC", "P", @@ -20,22 +20,22 @@ static const char *const reg[16] = "EXT4", "EXT5", "EXT6", "AL" }; -static const char *const rij[8] = +const char *const ssp1601_disassembler::rij[8] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" }; -static const char *const modifier[4] = +const char *const ssp1601_disassembler::modifier[4] = { "", "+!", "-", "+" }; -static const char *const modifier_sf[4] = +const char *const ssp1601_disassembler::modifier_sf[4] = { "|00", "|01", "|10", "|11" }; -static const char *const cond[16] = +const char *const ssp1601_disassembler::cond[16] = { "always", "RESERVED", "gpi0", "gpi1", "l", "z", "ov", "n", @@ -43,18 +43,18 @@ static const char *const cond[16] = "RESERVED", "RESERVED", "RESERVED", "RESERVED", }; -static const char *const acc_op[8] = +const char *const ssp1601_disassembler::acc_op[8] = { "ror", "rol", "shr", "shl", "inc", "dec", "neg", "abs" }; // pag. 81 uses different addresses! -static const char *const flag_op[16] = +const char *const ssp1601_disassembler::flag_op[16] = { "?", "?", "resl", "setl", "resie", "setie", "?", "?", "resop", "setop", "?", "?", "?", "?", "res", "set" }; -static const char *const arith_ops[8] = +const char *const ssp1601_disassembler::arith_ops[8] = { "", "add", "", "cmp", "add", "and", "or", "eor" }; @@ -68,27 +68,24 @@ static const char *const arith_ops[8] = #define MODIFIER_LOW MODIFIER((op >> 2) & 3, op&3) #define MODIFIER_HIGH MODIFIER((op >> 6) & 3, (op >> 4)&3) -#define READ_OP_DASM(p) ((base_oprom[p] << 8) | base_oprom[(p) + 1]) - -static char *get_cond(int op) +std::string ssp1601_disassembler::get_cond(int op) { - static char scond[16]; - if (op&0xf0) sprintf(scond, "%s=%i", cond[(op >> 4) & 0xf], BIT_B); - else sprintf(scond, "%s", cond[(op >> 4) & 0xf]); - return scond; + if (op&0xf0) return util::string_format("%s=%i", cond[(op >> 4) & 0xf], BIT_B); + else return util::string_format("%s", cond[(op >> 4) & 0xf]); } +u32 ssp1601_disassembler::opcode_alignment() const +{ + return 1; +} -static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *oprom) +offs_t ssp1601_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint8_t *base_oprom; uint16_t op; int size = 1; int flags = 0; - base_oprom = oprom; - - op = READ_OP_DASM(0); + op = opcodes.r16(pc); switch (op >> 9) { @@ -102,7 +99,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o { // ret util::stream_format(stream, "ret"); - flags |= DASMFLAG_STEP_OUT; + flags |= STEP_OUT; } else { @@ -128,7 +125,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o // ldi d, imm case 0x04: - util::stream_format(stream, "ld %s, %X", reg[(op >> 4) & 0xf], READ_OP_DASM(2)); + util::stream_format(stream, "ld %s, %X", reg[(op >> 4) & 0xf], opcodes.r16(pc+1)); size = 2; break; @@ -139,7 +136,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o // ldi (ri), imm case 0x06: - util::stream_format(stream, "ld (%s%s), %X", RIJ, MODIFIER_LOW, READ_OP_DASM(2)); + util::stream_format(stream, "ld (%s%s), %X", RIJ, MODIFIER_LOW, opcodes.r16(pc+1)); size = 2; break; @@ -203,7 +200,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o case 0x54: case 0x64: case 0x74: - util::stream_format(stream, "%si A, %X", arith_ops[op >> 13], READ_OP_DASM(2)); + util::stream_format(stream, "%si A, %X", arith_ops[op >> 13], opcodes.r16(pc+1)); size = 2; break; @@ -244,8 +241,8 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o // call cond, addr case 0x24: - util::stream_format(stream, "call %s, %X", get_cond(op), READ_OP_DASM(2)); - flags |= DASMFLAG_STEP_OVER; + util::stream_format(stream, "call %s, %X", get_cond(op), opcodes.r16(pc+1)); + flags |= STEP_OVER; size = 2; break; @@ -256,7 +253,7 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o // bra cond, addr case 0x26: - util::stream_format(stream, "bra %s, %X", get_cond(op), READ_OP_DASM(2)); + util::stream_format(stream, "bra %s, %X", get_cond(op), opcodes.r16(pc+1)); size = 2; break; @@ -285,14 +282,5 @@ static unsigned dasm_ssp1601(std::ostream &stream, unsigned pc, const uint8_t *o break; } - return size | flags | DASMFLAG_SUPPORTED; -} - -// vim:ts=4 - -CPU_DISASSEMBLE( ssp1601 ) -{ - //ssp1601_state_t *ssp1601_state = get_safe_token(device); - - return dasm_ssp1601(stream, pc, oprom); + return size | flags | SUPPORTED; } diff --git a/src/devices/cpu/ssp1601/ssp1601d.h b/src/devices/cpu/ssp1601/ssp1601d.h new file mode 100644 index 00000000000..9c868a5d308 --- /dev/null +++ b/src/devices/cpu/ssp1601/ssp1601d.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:Pierpaolo Prazzoli,Grazvydas Ignotas +/* + + SSP1601 disassembler + written by Pierpaolo Prazzoli + updated for SSP1601 by Grazvydas Ignotas + +*/ + +#ifndef MAME_CPU_SSP1601_SSP1601DASM_H +#define MAME_CPU_SSP1601_SSP1601DASM_H + +#pragma once + +class ssp1601_disassembler : public util::disasm_interface +{ +public: + ssp1601_disassembler() = default; + virtual ~ssp1601_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const reg[16]; + static const char *const rij[8]; + static const char *const modifier[4]; + static const char *const modifier_sf[4]; + static const char *const cond[16]; + static const char *const acc_op[8]; + static const char *const flag_op[16]; + static const char *const arith_ops[8]; + static std::string get_cond(int op); +}; + +#endif diff --git a/src/devices/cpu/superfx/sfx_dasm.cpp b/src/devices/cpu/superfx/sfx_dasm.cpp index a4e2855480f..58139452ea2 100644 --- a/src/devices/cpu/superfx/sfx_dasm.cpp +++ b/src/devices/cpu/superfx/sfx_dasm.cpp @@ -1,10 +1,24 @@ // license:BSD-3-Clause // copyright-holders:Ryan Holtz #include "emu.h" -#include "superfx.h" +#include "sfx_dasm.h" -offs_t superfx_dasm_one(std::ostream &stream, offs_t pc, uint8_t op, uint8_t param0, uint8_t param1, uint16_t alt) +superfx_disassembler::superfx_disassembler(config *conf) : m_config(conf) { +} + +u32 superfx_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t superfx_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint8_t op = opcodes.r8(pc); + uint8_t param0 = opcodes.r8(pc+1); + uint8_t param1 = opcodes.r8(pc+2); + uint16_t alt = m_config->get_alt(); + uint8_t bytes_consumed = 1; switch(op) @@ -409,5 +423,5 @@ offs_t superfx_dasm_one(std::ostream &stream, offs_t pc, uint8_t op, uint8_t par break; } - return bytes_consumed | DASMFLAG_SUPPORTED; + return bytes_consumed | SUPPORTED; } diff --git a/src/devices/cpu/superfx/sfx_dasm.h b/src/devices/cpu/superfx/sfx_dasm.h new file mode 100644 index 00000000000..4bd324c9e9d --- /dev/null +++ b/src/devices/cpu/superfx/sfx_dasm.h @@ -0,0 +1,36 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz + +#ifndef MAME_CPU_SUPERFX_SFX_DASM_H +#define MAME_CPU_SUPERFX_SFX_DASM_H + +#pragma once + +class superfx_disassembler : public util::disasm_interface +{ +public: + enum { + SUPERFX_SFR_ALT = 0x0300, // ALT Mode, both bits + SUPERFX_SFR_ALT0 = 0x0000, // ALT Mode, no bits + SUPERFX_SFR_ALT1 = 0x0100, // ALT Mode, bit 0 + SUPERFX_SFR_ALT2 = 0x0200, // ALT Mode, bit 1 + SUPERFX_SFR_ALT3 = 0x0300 // ALT Mode, both bits (convenience dupe) + }; + + struct config { + virtual ~config() = default; + + virtual u16 get_alt() const = 0; + }; + + superfx_disassembler(config *conf); + virtual ~superfx_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + config *m_config; +}; + +#endif diff --git a/src/devices/cpu/superfx/superfx.cpp b/src/devices/cpu/superfx/superfx.cpp index 2879a6faeaf..1e203a0a1f3 100644 --- a/src/devices/cpu/superfx/superfx.cpp +++ b/src/devices/cpu/superfx/superfx.cpp @@ -1445,12 +1445,12 @@ void superfx_device::execute_run() } } -offs_t superfx_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +u16 superfx_device::get_alt() const { - uint8_t op = *(uint8_t *)(opram + 0); - uint8_t param0 = *(uint8_t *)(opram + 1); - uint8_t param1 = *(uint8_t *)(opram + 2); - uint16_t alt = m_sfr & SUPERFX_SFR_ALT; + return m_sfr & SUPERFX_SFR_ALT; +} - return superfx_dasm_one(stream, pc, op, param0, param1, alt); +util::disasm_interface *superfx_device::create_disassembler() +{ + return new superfx_disassembler(this); } diff --git a/src/devices/cpu/superfx/superfx.h b/src/devices/cpu/superfx/superfx.h index 172c51eb65b..0bd060bb5fa 100644 --- a/src/devices/cpu/superfx/superfx.h +++ b/src/devices/cpu/superfx/superfx.h @@ -5,6 +5,7 @@ #pragma once +#include "sfx_dasm.h" enum { @@ -92,7 +93,7 @@ enum devcb = &superfx_device::set_out_irq_func(*device, DEVCB_##_devcb); -class superfx_device : public cpu_device +class superfx_device : public cpu_device, public superfx_disassembler::config { public: // construction/destruction @@ -107,6 +108,8 @@ public: int access_ram(); int access_rom(); + virtual u16 get_alt() const override; + protected: // device-level overrides virtual void device_start() override; @@ -126,9 +129,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -216,6 +217,4 @@ private: DECLARE_DEVICE_TYPE(SUPERFX, superfx_device) -offs_t superfx_dasm_one(std::ostream &stream, offs_t pc, uint8_t op, uint8_t param0, uint8_t param1, uint16_t alt); - #endif // MAME_CPU_SUPERFX_SUPERFX_H diff --git a/src/devices/cpu/t11/t11.cpp b/src/devices/cpu/t11/t11.cpp index dba6241b553..1747c79b64a 100644 --- a/src/devices/cpu/t11/t11.cpp +++ b/src/devices/cpu/t11/t11.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "t11.h" +#include "t11dasm.h" #include "debugger.h" @@ -260,7 +261,7 @@ void t11_device::device_start() m_initial_pc = initial_pc[c_initial_mode >> 13]; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_out_reset_func.resolve_safe(); save_item(NAME(m_ppc.w.l)); @@ -422,9 +423,7 @@ void t11_device::execute_run() } while (m_icount > 0); } - -offs_t t11_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *t11_device::create_disassembler() { - extern CPU_DISASSEMBLE( t11 ); - return CPU_DISASSEMBLE_NAME(t11)(this, stream, pc, oprom, opram, options); + return new t11_disassembler; } diff --git a/src/devices/cpu/t11/t11.h b/src/devices/cpu/t11/t11.h index 47db0a9b144..27f1177b03f 100644 --- a/src/devices/cpu/t11/t11.h +++ b/src/devices/cpu/t11/t11.h @@ -66,9 +66,7 @@ protected: 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -82,7 +80,7 @@ protected: uint8_t m_irq_state; int m_icount; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; devcb_write_line m_out_reset_func; inline int ROPCODE(); diff --git a/src/devices/cpu/t11/t11dasm.cpp b/src/devices/cpu/t11/t11dasm.cpp index b1936566f9c..c99789163ac 100644 --- a/src/devices/cpu/t11/t11dasm.cpp +++ b/src/devices/cpu/t11/t11dasm.cpp @@ -10,17 +10,18 @@ */ #include "emu.h" -#include "debugger.h" -#include "t11.h" +#include "t11dasm.h" -static const char *const regs[8] = { "R0", "R1", "R2", "R3", "R4", "R5", "SP", "PC" }; +const char *const t11_disassembler::regs[8] = { "R0", "R1", "R2", "R3", "R4", "R5", "SP", "PC" }; -static const uint8_t *rombase; -static offs_t pcbase; - -#define PARAM_WORD(v) ((v) = rombase[pc - pcbase] | (rombase[pc + 1 - pcbase] << 8), pc += 2) +u16 t11_disassembler::r16p(offs_t &pc, const data_buffer &opcodes) +{ + u16 r = opcodes.r16(pc); + pc += 2; + return r; +} -static unsigned MakeEA (char *ea, int lo, unsigned pc, int width) +std::string t11_disassembler::MakeEA (int lo, offs_t &pc, int width, const data_buffer &opcodes) { int reg, pm; @@ -31,71 +32,67 @@ static unsigned MakeEA (char *ea, int lo, unsigned pc, int width) switch ((lo >> 3) & 7) { case 0: - sprintf (ea, "%s", regs[reg]); + return util::string_format ("%s", regs[reg]); break; case 1: - sprintf (ea, "(%s)", regs[reg]); + return util::string_format ("(%s)", regs[reg]); break; case 2: if (reg == 7) { - PARAM_WORD (pm); - sprintf (ea, "#$%0*X", width, pm & ((width == 2) ? 0xff : 0xffff)); + pm = r16p(pc, opcodes); + return util::string_format ("#$%0*X", width, pm & ((width == 2) ? 0xff : 0xffff)); } else { - sprintf (ea, "(%s)+", regs[reg]); + return util::string_format ("(%s)+", regs[reg]); } break; case 3: if (reg == 7) { - PARAM_WORD (pm); - sprintf (ea, "$%04X", pm &= 0xffff); + pm = r16p(pc, opcodes); + return util::string_format ( "$%04X", pm &= 0xffff); } else { - sprintf (ea, "@(%s)+", regs[reg]); + return util::string_format ("@(%s)+", regs[reg]); } break; case 4: - sprintf (ea, "-(%s)", regs[reg]); + return util::string_format ("-(%s)", regs[reg]); break; case 5: - sprintf (ea, "@-(%s)", regs[reg]); + return util::string_format ("@-(%s)", regs[reg]); break; case 6: - PARAM_WORD (pm); - sprintf(ea, "%s$%X(%s)", + pm = r16p(pc, opcodes); + return util::string_format ("%s$%X(%s)", (pm&0x8000)?"-":"", (pm&0x8000)?-(signed short)pm:pm, regs[reg]); break; case 7: - PARAM_WORD (pm); - sprintf(ea, "@%s$%X(%s)", + pm = r16p(pc, opcodes); + return util::string_format ("@%s$%X(%s)", (pm&0x8000)?"-":"", (pm&0x8000)?-(signed short)pm:pm, regs[reg]); break; } - - return pc; + return ""; } -CPU_DISASSEMBLE(t11) +offs_t t11_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - char ea1[32], ea2[32]; - unsigned PC = pc; + offs_t PC = pc; uint16_t op, lo, hi, addr; int16_t offset; uint32_t flags = 0; + std::string ea1, ea2; - rombase = oprom; - pcbase = pc; - - PARAM_WORD(op); + op = r16p(pc, opcodes); lo = op & 077; hi = (op >> 6) & 077; @@ -106,7 +103,7 @@ CPU_DISASSEMBLE(t11) { case 0x00: util::stream_format(stream, "HALT"); break; case 0x01: util::stream_format(stream, "WAIT"); break; - case 0x02: util::stream_format(stream, "RTI"); flags = DASMFLAG_STEP_OUT; break; + case 0x02: util::stream_format(stream, "RTI"); flags = STEP_OUT; break; case 0x03: util::stream_format(stream, "BPT"); break; case 0x04: util::stream_format(stream, "IOT"); break; case 0x05: util::stream_format(stream, "RESET"); break; @@ -115,7 +112,7 @@ CPU_DISASSEMBLE(t11) } break; case 0x0040: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "JMP %s", ea1); break; case 0x0080: @@ -126,7 +123,7 @@ CPU_DISASSEMBLE(t11) util::stream_format(stream, "RTS"); else util::stream_format(stream, "RTS %s", regs[lo & 7]); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 040: case 050: @@ -157,7 +154,7 @@ CPU_DISASSEMBLE(t11) } break; case 0x00c0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "SWAB %s", ea1); break; case 0x0100: case 0x0140: case 0x0180: case 0x01c0: @@ -190,66 +187,66 @@ CPU_DISASSEMBLE(t11) break; case 0x0800: case 0x0840: case 0x0880: case 0x08c0: case 0x0900: case 0x0940: case 0x0980: case 0x09c0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); if ( (hi & 7) == 7 ) util::stream_format(stream, "JSR %s", ea1); else util::stream_format(stream, "JSR %s,%s", regs[hi & 7], ea1); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x0a00: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "CLR %s", ea1); break; case 0x0a40: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "COM %s", ea1); break; case 0x0a80: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "INC %s", ea1); break; case 0x0ac0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "DEC %s", ea1); break; case 0x0b00: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "NEG %s", ea1); break; case 0x0b40: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ADC %s", ea1); break; case 0x0b80: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "SBC %s", ea1); break; case 0x0bc0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "TST %s", ea1); break; case 0x0c00: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ROR %s", ea1); break; case 0x0c40: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ROL %s", ea1); break; case 0x0c80: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ASR %s", ea1); break; case 0x0cc0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ASL %s", ea1); break; /* case 0x0d00: util::stream_format(stream, "MARK #$%X", lo); break;*/ case 0x0dc0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "SXT %s", ea1); break; case 0x1000: case 0x1040: case 0x1080: case 0x10c0: case 0x1100: case 0x1140: case 0x1180: case 0x11c0: @@ -260,8 +257,8 @@ CPU_DISASSEMBLE(t11) case 0x1a00: case 0x1a40: case 0x1a80: case 0x1ac0: case 0x1b00: case 0x1b40: case 0x1b80: case 0x1bc0: case 0x1c00: case 0x1c40: case 0x1c80: case 0x1cc0: case 0x1d00: case 0x1d40: case 0x1d80: case 0x1dc0: case 0x1e00: case 0x1e40: case 0x1e80: case 0x1ec0: case 0x1f00: case 0x1f40: case 0x1f80: case 0x1fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); if (lo == 046) /* MOV src,-(SP) */ util::stream_format(stream, "PUSH %s", ea1); else @@ -278,8 +275,8 @@ CPU_DISASSEMBLE(t11) case 0x2a00: case 0x2a40: case 0x2a80: case 0x2ac0: case 0x2b00: case 0x2b40: case 0x2b80: case 0x2bc0: case 0x2c00: case 0x2c40: case 0x2c80: case 0x2cc0: case 0x2d00: case 0x2d40: case 0x2d80: case 0x2dc0: case 0x2e00: case 0x2e40: case 0x2e80: case 0x2ec0: case 0x2f00: case 0x2f40: case 0x2f80: case 0x2fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "CMP %s,%s", ea1, ea2); break; case 0x3000: case 0x3040: case 0x3080: case 0x30c0: case 0x3100: case 0x3140: case 0x3180: case 0x31c0: @@ -290,8 +287,8 @@ CPU_DISASSEMBLE(t11) case 0x3a00: case 0x3a40: case 0x3a80: case 0x3ac0: case 0x3b00: case 0x3b40: case 0x3b80: case 0x3bc0: case 0x3c00: case 0x3c40: case 0x3c80: case 0x3cc0: case 0x3d00: case 0x3d40: case 0x3d80: case 0x3dc0: case 0x3e00: case 0x3e40: case 0x3e80: case 0x3ec0: case 0x3f00: case 0x3f40: case 0x3f80: case 0x3fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "BIT %s,%s", ea1, ea2); break; case 0x4000: case 0x4040: case 0x4080: case 0x40c0: case 0x4100: case 0x4140: case 0x4180: case 0x41c0: @@ -302,8 +299,8 @@ CPU_DISASSEMBLE(t11) case 0x4a00: case 0x4a40: case 0x4a80: case 0x4ac0: case 0x4b00: case 0x4b40: case 0x4b80: case 0x4bc0: case 0x4c00: case 0x4c40: case 0x4c80: case 0x4cc0: case 0x4d00: case 0x4d40: case 0x4d80: case 0x4dc0: case 0x4e00: case 0x4e40: case 0x4e80: case 0x4ec0: case 0x4f00: case 0x4f40: case 0x4f80: case 0x4fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "BIC %s,%s", ea1, ea2); break; case 0x5000: case 0x5040: case 0x5080: case 0x50c0: case 0x5100: case 0x5140: case 0x5180: case 0x51c0: @@ -314,8 +311,8 @@ CPU_DISASSEMBLE(t11) case 0x5a00: case 0x5a40: case 0x5a80: case 0x5ac0: case 0x5b00: case 0x5b40: case 0x5b80: case 0x5bc0: case 0x5c00: case 0x5c40: case 0x5c80: case 0x5cc0: case 0x5d00: case 0x5d40: case 0x5d80: case 0x5dc0: case 0x5e00: case 0x5e40: case 0x5e80: case 0x5ec0: case 0x5f00: case 0x5f40: case 0x5f80: case 0x5fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "BIS %s,%s", ea1, ea2); break; case 0x6000: case 0x6040: case 0x6080: case 0x60c0: case 0x6100: case 0x6140: case 0x6180: case 0x61c0: @@ -326,13 +323,13 @@ CPU_DISASSEMBLE(t11) case 0x6a00: case 0x6a40: case 0x6a80: case 0x6ac0: case 0x6b00: case 0x6b40: case 0x6b80: case 0x6bc0: case 0x6c00: case 0x6c40: case 0x6c80: case 0x6cc0: case 0x6d00: case 0x6d40: case 0x6d80: case 0x6dc0: case 0x6e00: case 0x6e40: case 0x6e80: case 0x6ec0: case 0x6f00: case 0x6f40: case 0x6f80: case 0x6fc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "ADD %s,%s", ea1, ea2); break; case 0x7800: case 0x7840: case 0x7880: case 0x78c0: case 0x7900: case 0x7940: case 0x7980: case 0x79c0: - pc = MakeEA (ea1, lo, pc, 4); + ea1 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "XOR %s,%s", regs[hi & 7], ea1); break; @@ -381,59 +378,59 @@ CPU_DISASSEMBLE(t11) break; case 0x8a00: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "CLRB %s", ea1); break; case 0x8a40: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "COMB %s", ea1); break; case 0x8a80: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "INCB %s", ea1); break; case 0x8ac0: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "DECB %s", ea1); break; case 0x8b00: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "NEGB %s", ea1); break; case 0x8b40: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "ADCB %s", ea1); break; case 0x8b80: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "SBCB %s", ea1); break; case 0x8bc0: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "TSTB %s", ea1); break; case 0x8c00: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "RORB %s", ea1); break; case 0x8c40: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "ROLB %s", ea1); break; case 0x8c80: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "ASRB %s", ea1); break; case 0x8cc0: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "ASLB %s", ea1); break; case 0x8d00: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "MTPS %s", ea1); break; case 0x8dc0: - pc = MakeEA (ea1, lo, pc, 2); + ea1 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "MFPS %s", ea1); break; case 0x9000: case 0x9040: case 0x9080: case 0x90c0: case 0x9100: case 0x9140: case 0x9180: case 0x91c0: @@ -444,8 +441,8 @@ CPU_DISASSEMBLE(t11) case 0x9a00: case 0x9a40: case 0x9a80: case 0x9ac0: case 0x9b00: case 0x9b40: case 0x9b80: case 0x9bc0: case 0x9c00: case 0x9c40: case 0x9c80: case 0x9cc0: case 0x9d00: case 0x9d40: case 0x9d80: case 0x9dc0: case 0x9e00: case 0x9e40: case 0x9e80: case 0x9ec0: case 0x9f00: case 0x9f40: case 0x9f80: case 0x9fc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "MOVB %s,%s", ea1, ea2); break; case 0xa000: case 0xa040: case 0xa080: case 0xa0c0: case 0xa100: case 0xa140: case 0xa180: case 0xa1c0: @@ -456,8 +453,8 @@ CPU_DISASSEMBLE(t11) case 0xaa00: case 0xaa40: case 0xaa80: case 0xaac0: case 0xab00: case 0xab40: case 0xab80: case 0xabc0: case 0xac00: case 0xac40: case 0xac80: case 0xacc0: case 0xad00: case 0xad40: case 0xad80: case 0xadc0: case 0xae00: case 0xae40: case 0xae80: case 0xaec0: case 0xaf00: case 0xaf40: case 0xaf80: case 0xafc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "CMPB %s,%s", ea1, ea2); break; case 0xb000: case 0xb040: case 0xb080: case 0xb0c0: case 0xb100: case 0xb140: case 0xb180: case 0xb1c0: @@ -468,8 +465,8 @@ CPU_DISASSEMBLE(t11) case 0xba00: case 0xba40: case 0xba80: case 0xbac0: case 0xbb00: case 0xbb40: case 0xbb80: case 0xbbc0: case 0xbc00: case 0xbc40: case 0xbc80: case 0xbcc0: case 0xbd00: case 0xbd40: case 0xbd80: case 0xbdc0: case 0xbe00: case 0xbe40: case 0xbe80: case 0xbec0: case 0xbf00: case 0xbf40: case 0xbf80: case 0xbfc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "BITB %s,%s", ea1, ea2); break; case 0xc000: case 0xc040: case 0xc080: case 0xc0c0: case 0xc100: case 0xc140: case 0xc180: case 0xc1c0: @@ -480,8 +477,8 @@ CPU_DISASSEMBLE(t11) case 0xca00: case 0xca40: case 0xca80: case 0xcac0: case 0xcb00: case 0xcb40: case 0xcb80: case 0xcbc0: case 0xcc00: case 0xcc40: case 0xcc80: case 0xccc0: case 0xcd00: case 0xcd40: case 0xcd80: case 0xcdc0: case 0xce00: case 0xce40: case 0xce80: case 0xcec0: case 0xcf00: case 0xcf40: case 0xcf80: case 0xcfc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "BICB %s,%s", ea1, ea2); break; case 0xd000: case 0xd040: case 0xd080: case 0xd0c0: case 0xd100: case 0xd140: case 0xd180: case 0xd1c0: @@ -492,8 +489,8 @@ CPU_DISASSEMBLE(t11) case 0xda00: case 0xda40: case 0xda80: case 0xdac0: case 0xdb00: case 0xdb40: case 0xdb80: case 0xdbc0: case 0xdc00: case 0xdc40: case 0xdc80: case 0xdcc0: case 0xdd00: case 0xdd40: case 0xdd80: case 0xddc0: case 0xde00: case 0xde40: case 0xde80: case 0xdec0: case 0xdf00: case 0xdf40: case 0xdf80: case 0xdfc0: - pc = MakeEA (ea1, hi, pc, 2); - pc = MakeEA (ea2, lo, pc, 2); + ea1 = MakeEA (hi, pc, 2, opcodes); + ea2 = MakeEA (lo, pc, 2, opcodes); util::stream_format(stream, "BISB %s,%s", ea1, ea2); break; case 0xe000: case 0xe040: case 0xe080: case 0xe0c0: case 0xe100: case 0xe140: case 0xe180: case 0xe1c0: @@ -504,8 +501,8 @@ CPU_DISASSEMBLE(t11) case 0xea00: case 0xea40: case 0xea80: case 0xeac0: case 0xeb00: case 0xeb40: case 0xeb80: case 0xebc0: case 0xec00: case 0xec40: case 0xec80: case 0xecc0: case 0xed00: case 0xed40: case 0xed80: case 0xedc0: case 0xee00: case 0xee40: case 0xee80: case 0xeec0: case 0xef00: case 0xef40: case 0xef80: case 0xefc0: - pc = MakeEA (ea1, hi, pc, 4); - pc = MakeEA (ea2, lo, pc, 4); + ea1 = MakeEA (hi, pc, 4, opcodes); + ea2 = MakeEA (lo, pc, 4, opcodes); util::stream_format(stream, "SUB %s,%s", ea1, ea2); break; @@ -514,5 +511,10 @@ CPU_DISASSEMBLE(t11) break; } - return (pc - PC) | flags | DASMFLAG_SUPPORTED; + return (pc - PC) | flags | SUPPORTED; +} + +u32 t11_disassembler::opcode_alignment() const +{ + return 2; } diff --git a/src/devices/cpu/t11/t11dasm.h b/src/devices/cpu/t11/t11dasm.h new file mode 100644 index 00000000000..4d51dd75777 --- /dev/null +++ b/src/devices/cpu/t11/t11dasm.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/* + * A T11 disassembler + * + * Note: this is probably not the most efficient disassembler in the world :-) + * + * This code written by Aaron Giles (agiles@sirius.com) for the MAME project + * + */ + +#ifndef MAME_CPU_T11_T11DASM_H +#define MAME_CPU_T11_T11DASM_H + +#pragma once + +class t11_disassembler : public util::disasm_interface +{ +public: + t11_disassembler() = default; + virtual ~t11_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const regs[8]; + u16 r16p(offs_t &pc, const data_buffer &opcodes); + std::string MakeEA (int lo, offs_t &pc, int width, const data_buffer &opcodes); + +}; + +#endif diff --git a/src/devices/cpu/tlcs870/tlcs870.cpp b/src/devices/cpu/tlcs870/tlcs870.cpp index c24b41da744..4488ccee744 100644 --- a/src/devices/cpu/tlcs870/tlcs870.cpp +++ b/src/devices/cpu/tlcs870/tlcs870.cpp @@ -16,86 +16,9 @@ #include "emu.h" #include "tlcs870.h" +#include "tlcs870d.h" #include "debugger.h" - -// di, ei, j, and test are just 'alias' opcodes -static const char *const op_names[] = { - "??", - "call", "callp", "callv", "clr", "cpl", - "daa", "das", "dec", /*"di",*/ "div", - /*"ei",*/ - "inc", - /*"j",*/ "jp", "jr", "jrs", - "ld", "ldw", - "mcmp", "mul", - "nop", - "pop", "push", - "ret", "reti", "retn", "rolc", "rold", "rorc", "rord", - "set", "shlc", "shrc", "swap", "swi", - /*"test",*/ "xch", - // ALU operations - "addc", - "add", - "subb", - "sub", - "and", - "xor", - "or", - "cmp", -}; - - - - -static const char *const reg8[] = { - "A", - "W", - "C", - "B", - "E", - "D", - "L", - "H" -}; - -static const char *const type_x[] = { - "(x)", - "(PC+A)", - "(DE)", - "(HL)", - "(HL+d)", - "(HL+C)", - "(HL+)", - "(-HL)", -}; - -static const char *const conditions[] = { - "EQ/Z", - "NE/NZ", - "LT/CS", - "GE/CC", - "LE", - "GT", - "T", - "F", -}; - -static const char *const reg16[] = { - "WA", - "BC", - "DE", - "HL" -}; - -#ifdef UNUSED_DEFINTION -static const char *const reg16p[] = { - "DE", - "HL" -}; -#endif - - #define IS16BIT 0x80 #define BITPOS 0x40 #define BITPOS_INDIRECT 0x20 @@ -2336,71 +2259,6 @@ bool tlcs870_device::stream_arg(std::ostream &stream, uint32_t pc, const char *p return false; } -void tlcs870_device::disasm_disassemble_param(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, int type, uint16_t val) -{ - int basetype = type & MODE_MASK; - - if (basetype==ADDR_IN_IMM_X) util::stream_format(stream, " ($%02x)", val); // direct - if (basetype==ADDR_IN_PC_PLUS_REG_A) util::stream_format(stream, " %s", type_x[1]); - if (basetype==ADDR_IN_DE) util::stream_format(stream, " %s", type_x[2]); - if (basetype==ADDR_IN_HL) util::stream_format(stream, " %s", type_x[3]); - if (basetype==ADDR_IN_HL_PLUS_IMM_D) util::stream_format(stream, " (HL+$%04x)", val); // todo, sign extend - if (basetype==ADDR_IN_HL_PLUS_REG_C) util::stream_format(stream, " %s", type_x[5]); - if (basetype==ADDR_IN_HLINC) util::stream_format(stream, " %s", type_x[6]); - if (basetype==ADDR_IN_DECHL) util::stream_format(stream, " %s", type_x[7]); - - if (basetype==REG_8BIT) - { - if (type&IS16BIT) util::stream_format(stream, " %s", reg16[val&3]); - else util::stream_format(stream, " %s", reg8[val & 7]); - } - - if (basetype==CONDITIONAL) util::stream_format(stream, " %s", conditions[val]); - if (basetype==(STACKPOINTER & MODE_MASK)) util::stream_format(stream, " SP"); - if (basetype==REGISTERBANK) util::stream_format(stream, " RBS"); - if (basetype==PROGRAMSTATUSWORD) util::stream_format(stream, " PSW"); - if (basetype==MEMVECTOR_16BIT) util::stream_format(stream, " ($%04x)", val); - if (basetype==ABSOLUTE_VAL_8) - { - if (type&IS16BIT) util::stream_format(stream, "$%04x", val); - else util::stream_format(stream, "$%02x", val); - } - - if (basetype == (CARRYFLAG & MODE_MASK)) - { - util::stream_format(stream, " CF"); - } - else if (type&BITPOS) - { - if (type & BITPOS_INDIRECT) util::stream_format(stream, ".BIT_%s", reg8[m_bitpos&7]); - else util::stream_format(stream, ".BIT_%d", m_bitpos); - } -} - -offs_t tlcs870_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - m_addr = pc; - - decode(); - - util::stream_format (stream, "%-5s", op_names[ m_op ] ); - - if (m_param1_type) - { - disasm_disassemble_param(stream, pc, oprom, opram, options, m_param1_type, m_param1); - } - - if (m_param2_type) - { - if (m_param1_type) util::stream_format(stream, ","); - - disasm_disassemble_param(stream, pc, oprom, opram, options, m_param2_type, m_param2); - - } - - return (m_addr - pc) | DASMFLAG_SUPPORTED; -} - void tlcs870_device::execute_set_input(int inputnum, int state) { #if 0 @@ -3305,3 +3163,8 @@ void tlcs870_device::state_string_export(const device_state_entry &entry, std::s } } + +util::disasm_interface *tlcs870_device::create_disassembler() +{ + return new tlcs870_disassembler; +} diff --git a/src/devices/cpu/tlcs870/tlcs870.h b/src/devices/cpu/tlcs870/tlcs870.h index ea57533e122..ae05b38193f 100644 --- a/src/devices/cpu/tlcs870/tlcs870.h +++ b/src/devices/cpu/tlcs870/tlcs870.h @@ -106,11 +106,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual void disasm_disassemble_param(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options, int type, uint16_t val); - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; - + virtual util::disasm_interface *create_disassembler() override; uint32_t m_debugger_temp; diff --git a/src/devices/cpu/tlcs870/tlcs870d.cpp b/src/devices/cpu/tlcs870/tlcs870d.cpp new file mode 100644 index 00000000000..0017caab950 --- /dev/null +++ b/src/devices/cpu/tlcs870/tlcs870d.cpp @@ -0,0 +1,2264 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/************************************************************************************************************* + + Toshiba TLCS-870 Series MCUs + + The TLCS-870/X expands on this instruction set using the same base encoding. + + The TLCS-870/C appears to have a completely different encoding. + + loosely baesd on the tlcs90 core by Luca Elia + +*************************************************************************************************************/ + +#include "emu.h" +#include "tlcs870d.h" + +#define IS16BIT 0x80 +#define BITPOS 0x40 +#define BITPOS_INDIRECT 0x20 + +#define ABSOLUTE_VAL_8 0x01 +#define REG_8BIT 0x02 +#define CONDITIONAL 0x03 +#define STACKPOINTER (0x04 | IS16BIT) // this is a 16-bit reg +#define CARRYFLAG (0x5 | BITPOS) // also flag as BITPOS since it's a bit operation? +#define MEMVECTOR_16BIT 0x6 +#define REGISTERBANK 0x7 +#define PROGRAMSTATUSWORD 0x8 + +#define ABSOLUTE_VAL_16 (ABSOLUTE_VAL_8|IS16BIT) +#define REG_16BIT (REG_8BIT|IS16BIT) + +#define ADDR_IN_BASE 0x10 +#define ADDR_IN_IMM_X (ADDR_IN_BASE+0x0) +#define ADDR_IN_PC_PLUS_REG_A (ADDR_IN_BASE+0x1) +#define ADDR_IN_DE (ADDR_IN_BASE+0x2) +#define ADDR_IN_HL (ADDR_IN_BASE+0x3) +#define ADDR_IN_HL_PLUS_IMM_D (ADDR_IN_BASE+0x4) +#define ADDR_IN_HL_PLUS_REG_C (ADDR_IN_BASE+0x5) +#define ADDR_IN_HLINC (ADDR_IN_BASE+0x6) +#define ADDR_IN_DECHL (ADDR_IN_BASE+0x7) + +#define MODE_MASK 0x1f + +#define FLAG_J (0x80) +#define FLAG_Z (0x40) +#define FLAG_C (0x20) +#define FLAG_H (0x10) + +u32 tlcs870_disassembler::opcode_alignment() const +{ + return 1; +} + + +uint8_t tlcs870_disassembler::READ8() +{ + uint8_t b0 = m_opcodes->r8( m_addr++ ); + m_addr &= 0xffff; + return b0; +} + +uint16_t tlcs870_disassembler::READ16() +{ + uint8_t b0 = READ8(); + return b0 | (READ8() << 8); +} + +// di, ei, j, and test are just 'alias' opcodes +const char *const tlcs870_disassembler::op_names[] = { + "??", + "call", "callp", "callv", "clr", "cpl", + "daa", "das", "dec", /*"di",*/ "div", + /*"ei",*/ + "inc", + /*"j",*/ "jp", "jr", "jrs", + "ld", "ldw", + "mcmp", "mul", + "nop", + "pop", "push", + "ret", "reti", "retn", "rolc", "rold", "rorc", "rord", + "set", "shlc", "shrc", "swap", "swi", + /*"test",*/ "xch", + // ALU operations + "addc", + "add", + "subb", + "sub", + "and", + "xor", + "or", + "cmp", +}; + + + + +const char *const tlcs870_disassembler::reg8[] = { + "A", + "W", + "C", + "B", + "E", + "D", + "L", + "H" +}; + +const char *const tlcs870_disassembler::type_x[] = { + "(x)", + "(PC+A)", + "(DE)", + "(HL)", + "(HL+d)", + "(HL+C)", + "(HL+)", + "(-HL)", +}; + +const char *const tlcs870_disassembler::conditions[] = { + "EQ/Z", + "NE/NZ", + "LT/CS", + "GE/CC", + "LE", + "GT", + "T", + "F", +}; + +const char *const tlcs870_disassembler::reg16[] = { + "WA", + "BC", + "DE", + "HL" +}; + +const char *const tlcs870_disassembler::reg16p[] = { + "DE", + "HL" +}; + +void tlcs870_disassembler::decode() +{ + m_op = 0; + m_param1_type = 0; + m_param1 = 0; + m_param2_type = 0; + m_param2 = 0; + m_bitpos = 0; + m_cycles = 1; + m_flagsaffected = 0; // needed to signal which flags to change and which to leave alone in some cases (LD operations at least) + + uint8_t b0; + uint8_t b1; + + int tmppc = m_addr; + + b0 = READ8(); + + + switch (b0) + { + case 0x00: + m_op = NOP; + // NOP; + break; + + case 0x01: + // SWAP A + m_op = SWAP; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x02: + // MUL W,A + m_op = MUL; + + m_param1_type = REG_8BIT; + m_param1 = 1; // W + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + break; + + case 0x03: + // DIV WA,C + m_op = DIV; + + m_param1_type = REG_16BIT; + m_param1 = 0; // WA + + m_param2_type = REG_8BIT; + m_param2 = 2; // C + break; + + case 0x04: + // RETI + m_op = RETI; + break; + + case 0x05: + // RET + m_op = RET; + break; + + case 0x06: + // POP PSW + m_op = POP; + m_param1_type = PROGRAMSTATUSWORD; + break; + + case 0x07: + // PUSH PSW: + m_op = PUSH; + m_param1_type = PROGRAMSTATUSWORD; + break; + + case 0x08: + case 0x09: + // unused? + break; + + case 0x0a: + // DAA A + m_op = DAA; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x0b: + // DAS A + m_op = DAS; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x0c: + // CLR CF + m_op = CLR; + + m_param1_type = CARRYFLAG; // 16-bit register + //m_param1 = 0; + break; + + case 0x0d: + // SET CF + m_op = SET; + + m_param1_type = CARRYFLAG; // 16-bit register + //m_param1 = 0; + break; + + case 0x0e: + // CPL CF + m_op = CPL; + + m_param1_type = CARRYFLAG; // 16-bit register + //m_param1 = 0; + break; + + case 0x0f: + // LD RBS,n + m_op = LD; // Flags / Cycles 1--- / 2 + m_flagsaffected |= FLAG_J; + + m_param1_type = REGISTERBANK; // 4-bit register + //m_param1 = 0; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + + break; + + case 0x10: + case 0x11: + case 0x12: + case 0x13: + // INC rr + m_op = INC; + + m_param1_type = REG_16BIT; // 16-bit register + m_param1 = b0&3; + + break; + + case 0x14: + case 0x15: + case 0x16: + case 0x17: + // LD rr,mn + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_16BIT; // 16-bit register + m_param1 = b0&3; + + m_param2_type = ABSOLUTE_VAL_16; // absolute value + m_param2 = READ16(); // 16-bit + + break; + + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + // DEC rr + m_op = DEC; + + m_param1_type = REG_16BIT; // 16-bit register + m_param1 = b0&3; + + break; + + case 0x1c: + // SHLC A + m_op = SHLC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x1d: + // SHRC A + m_op = SHRC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x1e: + // ROLC A + m_op = ROLC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x1f: + // RORC A + m_op = RORC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x20: + // INC (x) + m_op = INC; + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + break; + + case 0x21: + // INC (HL) + m_op = INC; + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + break; + + case 0x22: + // LD A,(x) + m_op = LD; // Flags / Cycles 1Z-- / 3 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = ADDR_IN_IMM_X; + m_param2 = READ8(); + break; + + case 0x23: + // LD A,(HL) + m_op = LD; // Flags / Cycles 1Z-- / 2 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = ADDR_IN_HL; + //m_param2 = 0; + break; + + case 0x24: + // LDW (x),mn + m_op = LDW; + m_param1_type = ADDR_IN_IMM_X; // 8-bit memory address + m_param1 = READ8(); + + m_param2_type = ABSOLUTE_VAL_16; // absolute value + m_param2 = READ16(); + break; + + case 0x25: + // LDW (HL),mn + m_op = LDW; + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + + m_param2_type = ABSOLUTE_VAL_16; + m_param2 = READ16(); + break; + + + case 0x26: + // LD (x),(y) // Flags / Cycles 1Z-- / 5 + m_op = LD; + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param2_type = ADDR_IN_IMM_X; + m_param2 = READ8(); + + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + break; + + case 0x27: + // unused + break; + + case 0x28: + // DEC (x) + m_op = DEC; + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + break; + + case 0x29: + // DEC (HL) + m_op = DEC; + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + break; + + case 0x2a: + // LD (x),A // Flags / Cycles 1Z-- / 3 + m_op = LD; + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + + break; + + case 0x2b: + // LD (HL),A // Flags / Cycles 1--- / 2 + m_op = LD; + m_flagsaffected |= FLAG_J; + + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + break; + + case 0x2c: + // LD (x),n + m_op = LD; // Flags / Cycles 1--- / 4 + m_flagsaffected |= FLAG_J; + + m_param1_type = ADDR_IN_IMM_X; // 8-bit memory address + m_param1 = READ8(); + + m_param2_type = ABSOLUTE_VAL_8; // absolute value + m_param2 = READ8(); + + break; + + case 0x2d: + // LD (HL),n + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param1_type = ADDR_IN_HL; // memory address in 16-bit register + //m_param1 = 3; // (HL) + + m_param2_type = ABSOLUTE_VAL_8; // absolute value + m_param2 = READ8(); + + break; + + case 0x2e: + // CLR (x) + m_op = CLR; + m_param1_type = ADDR_IN_IMM_X; // 8-bit memory address + m_param1 = READ8(); + + break; + + case 0x2f: + // CLR (HL) + m_op = CLR; + m_param1_type = ADDR_IN_HL; // memory address in 16-bit register + //m_param1 = 3; // (HL) + + break; + + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + // LD r,n + + m_op = LD; // Flags / Cycles 1--- / 2 + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_8BIT; // 8-bit register register + m_param1 = b0&7; + + m_param2_type = ABSOLUTE_VAL_8; // absolute value + m_param2 = READ8(); + + + break; + + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + break; + + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + // SET (x).b + b1 = READ8(); +#if 0 + // this is just an alias + if ((b0 == 0x40) && (b1 == 0x3a)) + { + // EI 'Assembler expansion machine instruction' + break; + } +#endif + m_op = SET; + + m_param1_type = ADDR_IN_IMM_X | BITPOS; + m_param1 = b1; + m_bitpos = b0 & 7; + + break; + + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + // CLR (x).b + b1 = READ8(); +#if 0 + // this is just an alias + if ((b0 == 0x48) && (b1 == 0x3a)) + { + // DI 'Assembler expansion machine instruction' + break; + } +#endif + m_op = CLR; + + m_param1_type = ADDR_IN_IMM_X | BITPOS; + m_param1 = b1; + m_bitpos = b0 & 7; + + break; + + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + // LD A,r 0101 0rrr + m_op = LD; // Flags / Cycles 1Z-- / 1 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = REG_8BIT; + m_param2 = b0 & 0x7; + + break; + + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: + // LD r,A 0101 1rrr + m_op = LD; // Flags / Cycles 1Z-- / 1 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + break; + + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + // INC r + m_op = INC; + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + break; + + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + // DEC r + m_op = DEC; + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + // (ALU OP) A,n + m_op = (b0 & 0x7)+ALU_ADDC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + + break; + + case 0x78: + case 0x79: + case 0x7a: + case 0x7b: + case 0x7c: + case 0x7d: + case 0x7e: + case 0x7f: + // (ALU OP) A,(x) + m_op = (b0 & 0x7)+ALU_ADDC; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + + m_param2_type = ADDR_IN_IMM_X; + m_param2 = READ8(); + + break; + + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + { + // JRS T,a + m_op = JRS; + + m_param1_type = CONDITIONAL; + m_param1 = 6; + + m_param2_type = ABSOLUTE_VAL_16; + + int val = b0 & 0x1f; + if (val & 0x10) val -= 0x20; + + m_param2 = tmppc + 2 + val; + + break; + } + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + { + // JRS F,a + m_op = JRS; + + m_param1_type = CONDITIONAL; + m_param1 = 7; + + m_param2_type = ABSOLUTE_VAL_16; + + int val = b0 & 0x1f; + if (val & 0x10) val -= 0x20; + + m_param2 = tmppc + 2 + val; + + break; + } + + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + // CALLV n + m_op = CALLV; + + m_param1_type = MEMVECTOR_16BIT; + + m_param1 = 0xffc0 + ((b0 & 0xf) * 2); + + break; + + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + { + // JR cc,a + + m_op = JR; + + m_param1_type = CONDITIONAL; + m_param1 = b0 & 0x7; + + m_param2_type = ABSOLUTE_VAL_16; + + int val = READ8(); + if (val & 0x80) val -= 0x100; + + m_param2 = tmppc+ 2 + val; + + break; + } + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + // LD CF, (x).b aka TEST (x).b + m_op = LD; // Flags / Cycles %-*- / 4 + m_flagsaffected |= FLAG_J | FLAG_C; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = ADDR_IN_IMM_X | BITPOS; + m_param2 = READ8(); + m_bitpos = b0 & 0x7; + break; + + case 0xe0: + // src prefix + decode_source(ADDR_IN_BASE+(b0&0x7), READ8()); + break; + + case 0xe1: + case 0xe2: + case 0xe3: + decode_source(ADDR_IN_BASE+(b0&0x7), 0); + break; + + case 0xe4: + decode_source(ADDR_IN_BASE+(b0&0x7), READ8()); + break; + + case 0xe5: + case 0xe6: + case 0xe7: + decode_source(ADDR_IN_BASE+(b0&0x7), 0); + break; + + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + // register prefix: g/gg + decode_register_prefix(b0); + break; + + case 0xf0: // 1111 0000 xxxx xxxx 0101 0rrr + // destination memory prefix (dst) + m_param1_type = ADDR_IN_BASE+(b0&0x7); + m_param1 = READ8(); + decode_dest(b0); + break; + + case 0xf2: // 1111 001p 0101 0rrr + case 0xf3: // 1111 001p 0101 0rrr + // destination memory prefix (dst) + m_param1_type = ADDR_IN_BASE+(b0&0x7); + decode_dest(b0); + break; + + + case 0xf4: // 1111 0100 dddd dddd 0101 0rrr + // destination memory prefix (dst) + m_param1_type = ADDR_IN_BASE+(b0&0x7); + m_param1 = READ8(); + decode_dest(b0); + break; + + case 0xf6: // 1110 0110 0101 0rrr + case 0xf7: // 1111 0111 0101 0rrr + // destination memory prefix (dst) + m_param1_type = ADDR_IN_BASE+(b0&0x7); + decode_dest(b0); + break; + + case 0xf1: + case 0xf5: + // invalid dst memory prefix + break; + + + case 0xf8: + case 0xf9: + // unused + break; + + case 0xfa: + // LD SP,mn + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param1_type = STACKPOINTER; + //m_param1 = 0; + + m_param2_type = ABSOLUTE_VAL_16; + m_param2 = READ16(); + + break; + + case 0xfb: + { + // JR a + m_op = JR; + + m_param2_type = ABSOLUTE_VAL_16; + + int val = READ8(); + if (val & 0x80) val -= 0x100; + + m_param2 = tmppc + 2 + val; + + break; + } + + break; + + case 0xfc: + // CALL mn + m_op = CALL; + + m_param1_type = ABSOLUTE_VAL_16; + m_param1 = READ16(); + break; + + case 0xfd: + // CALLP n + m_op = CALLP; + + m_param1_type = ABSOLUTE_VAL_16; + m_param1 = READ8()+0xff00; + + break; + + case 0xfe: + // JP mn + m_op = JP; + + m_param2_type = ABSOLUTE_VAL_16; + m_param2 = READ16(); + + break; + + case 0xff: + // SWI + m_op = SWI; + + break; + } +} + +// e8 - ef use this table +void tlcs870_disassembler::decode_register_prefix(uint8_t b0) +{ + uint8_t bx; + + bx = READ8(); + + switch (bx) + { + case 0x00: + // nothing + break; + + case 0x01: + // SWAP g + m_op = SWAP; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + break; + + case 0x02: + // MUL ggG, ggL + m_op = MUL; + + m_param1_type = REG_16BIT; // odd syntax + m_param1 = b0 & 0x3; + break; + + case 0x03: + // DIV gg,C + m_op = DIV; + m_param1_type = REG_16BIT; + m_param1 = b0 & 3; + + m_param2_type = REG_8BIT; + m_param2 = 2; // C + + break; + + case 0x04: + // with E8 only + // RETN + if (b0 == 0xe8) + { + m_op = RETN; + } + + break; + + case 0x05: + break; + + case 0x06: + // POP gg + m_op = POP; + m_param1_type = REG_16BIT; + m_param1 = b0 & 3; + // b0 & 4 = invalid? + + break; + + case 0x07: + // PUSH gg + m_op = PUSH; + m_param1_type = REG_16BIT; + m_param1 = b0 & 3; + // b0 & 4 = invalid? + + break; + + case 0x08: + case 0x09: + break; + + case 0x0a: + // DAA g + m_op = DAA; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x0b: + // DAS g + m_op = DAS; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + break; + + case 0x10: + case 0x11: + case 0x12: + case 0x13: + // XCH rr,gg + m_op = XCH; + + m_param1_type = REG_16BIT; + m_param1 = bx & 0x3; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 0x3; + break; + + case 0x14: + case 0x15: + case 0x16: + case 0x17: + // LD rr,gg + m_op = LD; // Flags / Cycles 1--- / 2 + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_16BIT; + m_param1 = bx & 0x3; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 0x3; + + break; + + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + break; + + case 0x1c: + // SHLC g + m_op = SHLC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x1d: + // SHRC g + m_op = SHRC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x1e: + // ROLC g + m_op = ROLC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x1f: + // RORC g + m_op = RORC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + break; + + case 0x20: + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + case 0x2c: + case 0x2d: + case 0x2e: + case 0x2f: + break; + + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + // (ALU OP) WA,gg + m_op = (bx & 0x7)+ALU_ADDC; + + m_param1_type = REG_16BIT; + m_param1 = 0; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 3; + // b0 & 4 would be invalid? + + + break; + + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + // (ALU OP) gg,mn + m_op = (bx & 0x7)+ALU_ADDC; + + m_param1_type = REG_16BIT; + m_param1 = b0 & 0x3; + + m_param2_type = ABSOLUTE_VAL_16; // absolute value + m_param2 = READ16(); // 16-bit + + break; + + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + // SET g.b + m_op = SET; + + m_param1_type = REG_8BIT | BITPOS; + m_param1 = b0 & 0x7; + m_bitpos = bx & 0x7; + + + break; + + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + // CLR g.b + m_op = CLR; + + m_param1_type = REG_8BIT | BITPOS; + m_param1 = b0 & 0x7; + m_bitpos = bx & 0x7; + + break; + + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + break; + + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: + // LD r,g + m_op = LD; // Flags / Cycles 1Z-- / 2 + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = bx & 0x7; + + m_param2_type = REG_8BIT; + m_param2 = b0 & 0x7; + break; + + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + // (ALU OP) A,g + m_op = (bx & 0x7)+ALU_ADDC; + + m_param2_type = REG_8BIT; + m_param2 = b0 & 0x7; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + // (ALU OP) g,A + m_op = (bx & 0x7)+ALU_ADDC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + m_param2_type = REG_8BIT; + m_param2 = 0; // A + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + // (ALU OP) g,n + m_op = (bx & 0x7)+ALU_ADDC; + + m_param1_type = REG_8BIT; + m_param1 = b0 & 0x7; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + + + break; + + case 0x78: + case 0x79: + case 0x7a: + case 0x7b: + case 0x7c: + case 0x7d: + case 0x7e: + case 0x7f: + break; + + + case 0x80: + case 0x81: + break; + + case 0x82: + case 0x83: + // SET (pp).g + m_op = SET; + m_param1_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_param1 = 0; + m_bitpos = b0 & 7; + break; + + case 0x84: + case 0x85: + case 0x86: + case 0x87: + break; + + case 0x88: + case 0x89: + break; + + case 0x8a: + case 0x8b: + // CLR (pp).g + m_op = CLR; + m_param1_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_param1 = 0; + m_bitpos = b0 & 7; + break; + + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + break; + + + case 0x90: + case 0x91: + break; + + case 0x92: + case 0x93: + // CPL (pp).g + m_op = CPL; + m_param1_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_param1 = 0; + m_bitpos = b0 & 7; + break; + + case 0x94: + case 0x95: + case 0x96: + case 0x97: + break; + + case 0x9a: + case 0x9b: + // LD (pp).g,CF + m_op = LD; // Flags / Cycles 1--- / 5 + m_flagsaffected |= FLAG_J; + + m_param1_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_para1 = 0; + m_bitpos = b0 & 7; + + m_param2_type = CARRYFLAG; + //m_param2 = 0; + break; + + case 0x9c: + case 0x9d: + break; + + case 0x9e: + case 0x9f: + // LD CF,(pp).g aka TEST (pp).g + m_op = LD; // Flags / Cycles %-*- / 4 + m_flagsaffected |= FLAG_J | FLAG_C; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = (ADDR_IN_DE+(bx&1)) | BITPOS | BITPOS_INDIRECT; + //m_param2 = 0; + m_bitpos = b0 & 7; + break; + + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + break; + + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + break; + + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + // CPL g.b + m_op = CPL; + + m_param1_type = REG_8BIT | BITPOS; + m_param1 = b0 & 0x7; + m_bitpos = bx & 0x7; + break; + + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + // LD g.b,CF + m_op = LD; // Flags / Cycles 1--- / 2 + m_flagsaffected |= FLAG_J; + + m_param2_type = CARRYFLAG; + //m_param2 = 0; + + m_param1_type = REG_8BIT | BITPOS; + m_param1 = b0 & 0x7; + m_bitpos = bx & 0x7; + + break; + + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + // XOR CF,g.b + m_op = ALU_XOR; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = REG_8BIT | BITPOS; + m_param2 = b0 & 0x7; + m_bitpos = bx & 0x7; + + break; + + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + // LD CF,g.b aka TEST g.b + m_op = LD; // Flags / Cycles %-*- / 2 + m_flagsaffected |= FLAG_J | FLAG_C; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = REG_8BIT | BITPOS; + m_param2 = b0 & 0x7; + m_bitpos = bx & 0x7; + + break; + + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + break; + + case 0xf0: + case 0xf1: + case 0xf2: + case 0xf3: + case 0xf4: + case 0xf5: + case 0xf6: + case 0xf7: + break; + + case 0xf8: + case 0xf9: + break; + + case 0xfa: + // LD SP,gg + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 3; + // b0 & 4 would be invalid? + + m_param1_type = STACKPOINTER; + // m_param1 = 0; + + break; + + case 0xfb: + // LD gg,SP + m_op = LD; // Flags / Cycles 1--- / 3 + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_16BIT; + m_param1 = b0 & 3; + // b0 & 4 would be invalid? + + m_param2_type = STACKPOINTER; + // m_param2 = 0; + break; + + case 0xfc: + // CALL gg + m_op = CALL; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 3; + // b0 & 4 would be invalid? + + break; + + case 0xfd: + break; + + case 0xfe: + // JP gg + m_op = JP; + + m_param2_type = REG_16BIT; + m_param2 = b0 & 3; + // b0 & 4 would be invalid? + + break; + + case 0xff: + break; + + } + +} + +// e0 - e7 use this table +void tlcs870_disassembler::decode_source(int type, uint16_t val) +{ + uint8_t bx; + + bx = READ8(); + + switch (bx) + { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + break; + + case 0x08: + // ROLD A,(src) + m_op = ROLD; + m_param2_type = type; + m_param2 = val; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x09: + // RORD A,(src) + m_op = RORD; + m_param2_type = type; + m_param2 = val; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + + case 0x10: + case 0x11: + case 0x12: + case 0x13: + // see dst + break; + + case 0x14: + case 0x15: + case 0x16: + case 0x17: + // LD rr, (src) + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param1_type = REG_16BIT; + m_param1 = bx & 0x3; + + m_param2_type = type | IS16BIT; + m_param2 = val; + break; + + case 0x18: + case 0x19: + case 0x1a: + case 0x1b: + case 0x1c: + case 0x1d: + case 0x1e: + case 0x1f: + break; + + case 0x20: + // INC (src) + m_op = INC; + m_param1_type = type; + m_param1 = val; + + break; + + case 0x21: + case 0x22: + case 0x23: + case 0x24: + case 0x25: + break; + + case 0x26: // invalid if (src) is also (x) ? (not specified) + // LD (x),(src) + m_op = LD; // Flags / Cycles 1U-- / x + m_flagsaffected |= FLAG_J /*| FLAG_Z*/; // Z is undefined! + + m_param1_type = ADDR_IN_IMM_X; + m_param1 = READ8(); + + m_param2_type = type; + m_param2 = val; + break; + + case 0x27: + // LD (HL),(src) + m_op = LD; // Flags / Cycles 1Z-- / x + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = ADDR_IN_HL; + //m_param1 = 0; + + m_param2_type = type; + m_param2 = val; + break; + + + case 0x28: + // DEC (src) + m_op = DEC; + m_param1_type = type; + m_param1 = val; + + break; + + case 0x29: + case 0x2a: + case 0x2b: + case 0x2c: + case 0x2d: + case 0x2e: + break; + + case 0x2f: + // MCMP (src), n + m_op = MCMP; + m_param1_type = type; + m_param1 = val; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + break; + + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39: + case 0x3a: + case 0x3b: + case 0x3c: + case 0x3d: + case 0x3e: + case 0x3f: + break; + + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + // SET (src).b + m_op = SET; + + m_param1_type = type | BITPOS; + m_param1 = val; + m_bitpos = bx & 0x7; + break; + + case 0x48: + case 0x49: + case 0x4a: + case 0x4b: + case 0x4c: + case 0x4d: + case 0x4e: + case 0x4f: + // CLR (src).b + m_op = CLR; + + m_param1_type = type | BITPOS; + m_param1 = val; + m_bitpos = bx & 0x7; + break; + + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + // see dst + break; + + case 0x58: + case 0x59: + case 0x5a: + case 0x5b: + case 0x5c: + case 0x5d: + case 0x5e: + case 0x5f: + // LD r, (src) + m_op = LD; // Flags / Cycles 1Z-- / x + m_flagsaffected |= FLAG_J | FLAG_Z; + + m_param1_type = REG_8BIT; + m_param1 = bx & 0x7; + + m_param2_type = type; + m_param2 = val; + break; + + case 0x60: + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66: + case 0x67: + // (ALU OP) (src), (HL) + m_op = (bx & 0x7)+ALU_ADDC; + m_param1_type = type; + m_param1 = val; + + m_param2_type = ADDR_IN_HL; + //m_param2 = 0; + break; + + case 0x68: + case 0x69: + case 0x6a: + case 0x6b: + case 0x6c: + case 0x6d: + case 0x6e: + case 0x6f: + break; + + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: + // (ALU OP) (src), n + m_op = (bx & 0x7)+ALU_ADDC; + m_param1_type = type; + m_param1 = val; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + break; + + case 0x78: + case 0x79: + case 0x7a: + case 0x7b: + case 0x7c: + case 0x7d: + case 0x7e: + case 0x7f: + // (ALU OP) A, (src) + + m_op = (bx & 0x7)+ALU_ADDC; + m_param2_type = type; + m_param2 = val; + + m_param1_type = REG_8BIT; + m_param1 = 0; // A + break; + + case 0x80: + case 0x81: + case 0x82: + case 0x83: + case 0x84: + case 0x85: + case 0x86: + case 0x87: + case 0x88: + case 0x89: + case 0x8a: + case 0x8b: + case 0x8c: + case 0x8d: + case 0x8e: + case 0x8f: + break; + + case 0x90: + case 0x91: + case 0x92: + case 0x93: + case 0x94: + case 0x95: + case 0x96: + case 0x97: + case 0x98: + case 0x99: + case 0x9a: + case 0x9b: + case 0x9c: + case 0x9d: + case 0x9e: + case 0x9f: + break; + + case 0xa0: + case 0xa1: + case 0xa2: + case 0xa3: + case 0xa4: + case 0xa5: + case 0xa6: + case 0xa7: + break; + + case 0xa8: + case 0xa9: + case 0xaa: + case 0xab: + case 0xac: + case 0xad: + case 0xae: + case 0xaf: + // XCH r,(src) + m_op = XCH; + + m_param1_type = REG_8BIT; + m_param1 = bx & 0x7; + + m_param2_type = type; + m_param2 = val; + break; + + + case 0xb0: + case 0xb1: + case 0xb2: + case 0xb3: + case 0xb4: + case 0xb5: + case 0xb6: + case 0xb7: + case 0xb8: + case 0xb9: + case 0xba: + case 0xbb: + case 0xbc: + case 0xbd: + case 0xbe: + case 0xbf: + break; + + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + // CPL (src).b + m_op = CPL; + + m_param1_type = type | BITPOS; + m_param1 = val; + m_bitpos = bx & 0x7; + break; + + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + // LD (src).b,CF + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param1_type = type | BITPOS; + m_param1 = val; + m_bitpos = bx & 0x7; + + m_param2_type = CARRYFLAG; + //m_param2 = 0; + break; + + + case 0xd0: + case 0xd1: + case 0xd2: + case 0xd3: + case 0xd4: + case 0xd5: + case 0xd6: + case 0xd7: + // XOR CF,(src).b + m_op = ALU_XOR; + m_param1_type = CARRYFLAG; + //m_param1 = 0; + + m_param2_type = type | BITPOS; + m_param2 = val; + m_bitpos = bx & 0x7; + break; + + case 0xd8: + case 0xd9: + case 0xda: + case 0xdb: + case 0xdc: + case 0xdd: + case 0xde: + case 0xdf: + // LD CF,(src).b aka TEST (src).b + m_op = LD; // Flags / Cycles %-*- / x + m_flagsaffected |= FLAG_J | FLAG_C; + + m_param2_type = type | BITPOS; + m_param2 = val; + m_bitpos = bx & 0x7; + + m_param1_type = CARRYFLAG; + //m_param1 = 0; + break; + + + case 0xe0: + case 0xe1: + case 0xe2: + case 0xe3: + case 0xe4: + case 0xe5: + case 0xe6: + case 0xe7: + case 0xe8: + case 0xe9: + case 0xea: + case 0xeb: + case 0xec: + case 0xed: + case 0xee: + case 0xef: + break; + + case 0xf0: + case 0xf1: + case 0xf2: + case 0xf3: + case 0xf4: + case 0xf5: + case 0xf6: + case 0xf7: + break; + + case 0xf8: + case 0xf9: + case 0xfa: + case 0xfb: + case 0xfc: + // CALL (src) + m_op = CALL; + m_param1_type = type; + m_param1 = val; + break; + + case 0xfd: + break; + + case 0xfe: + // JP (src) + m_op = JP; + m_param2_type = type | IS16BIT; + m_param2 = val; + break; + + case 0xff: + break; + } +} + +// f0 - f7 use this table +// note, same table is shown as above in manual, there's no overlap between src/dest, but they're not compatible +void tlcs870_disassembler::decode_dest(uint8_t b0) +{ + uint8_t bx; + + bx = READ8(); + + switch (bx) + { + case 0x10: + case 0x11: + case 0x12: + case 0x13: + // LD (dst),rr // (dst) can only be (x) (pp) or (HL+d) ? not (HL+) or (-HL) ? + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param1_type |= IS16BIT; + + + m_param2_type = REG_16BIT; + m_param2 = bx&0x3; + break; + + case 0x2c: + // LD (dst),n // (dst) can only be (DE), (HL+), (-HL), or (HL+d) because (x) and (HL) are redundant encodings? + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param2_type = ABSOLUTE_VAL_8; + m_param2 = READ8(); + break; + + case 0x50: + case 0x51: + case 0x52: + case 0x53: + case 0x54: + case 0x55: + case 0x56: + case 0x57: + // LD (dst),r + m_op = LD; // Flags / Cycles 1--- / x + m_flagsaffected |= FLAG_J; + + m_param2_type = REG_8BIT; + m_param2 = bx&0x7; + break; + + default: + break; + } +} + +void tlcs870_disassembler::disassemble_param(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, int type, uint16_t val) +{ + int basetype = type & MODE_MASK; + + if (basetype==ADDR_IN_IMM_X) util::stream_format(stream, " ($%02x)", val); // direct + if (basetype==ADDR_IN_PC_PLUS_REG_A) util::stream_format(stream, " %s", type_x[1]); + if (basetype==ADDR_IN_DE) util::stream_format(stream, " %s", type_x[2]); + if (basetype==ADDR_IN_HL) util::stream_format(stream, " %s", type_x[3]); + if (basetype==ADDR_IN_HL_PLUS_IMM_D) util::stream_format(stream, " (HL+$%04x)", val); // todo, sign extend + if (basetype==ADDR_IN_HL_PLUS_REG_C) util::stream_format(stream, " %s", type_x[5]); + if (basetype==ADDR_IN_HLINC) util::stream_format(stream, " %s", type_x[6]); + if (basetype==ADDR_IN_DECHL) util::stream_format(stream, " %s", type_x[7]); + + if (basetype==REG_8BIT) + { + if (type&IS16BIT) util::stream_format(stream, " %s", reg16[val&3]); + else util::stream_format(stream, " %s", reg8[val & 7]); + } + + if (basetype==CONDITIONAL) util::stream_format(stream, " %s", conditions[val]); + if (basetype==(STACKPOINTER & MODE_MASK)) util::stream_format(stream, " SP"); + if (basetype==REGISTERBANK) util::stream_format(stream, " RBS"); + if (basetype==PROGRAMSTATUSWORD) util::stream_format(stream, " PSW"); + if (basetype==MEMVECTOR_16BIT) util::stream_format(stream, " ($%04x)", val); + if (basetype==ABSOLUTE_VAL_8) + { + if (type&IS16BIT) util::stream_format(stream, "$%04x", val); + else util::stream_format(stream, "$%02x", val); + } + + if (basetype == (CARRYFLAG & MODE_MASK)) + { + util::stream_format(stream, " CF"); + } + else if (type&BITPOS) + { + if (type & BITPOS_INDIRECT) util::stream_format(stream, ".BIT_%s", reg8[m_bitpos&7]); + else util::stream_format(stream, ".BIT_%d", m_bitpos); + } +} + +offs_t tlcs870_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + m_addr = pc; + m_opcodes = &opcodes; + + decode(); + + util::stream_format (stream, "%-5s", op_names[ m_op ] ); + + if (m_param1_type) + { + disassemble_param(stream, pc, opcodes, params, m_param1_type, m_param1); + } + + if (m_param2_type) + { + if (m_param1_type) util::stream_format(stream, ","); + + disassemble_param(stream, pc, opcodes, params, m_param2_type, m_param2); + + } + + return (m_addr - pc) | SUPPORTED; +} diff --git a/src/devices/cpu/tlcs870/tlcs870d.h b/src/devices/cpu/tlcs870/tlcs870d.h new file mode 100644 index 00000000000..64f0de84090 --- /dev/null +++ b/src/devices/cpu/tlcs870/tlcs870d.h @@ -0,0 +1,88 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood +/************************************************************************************************************* + + Toshiba TLCS-870 Series MCUs + + The TLCS-870/X expands on this instruction set using the same base encoding. + + The TLCS-870/C appears to have a completely different encoding. + + loosely baesd on the tlcs90 core by Luca Elia + +*************************************************************************************************************/ + +#ifndef MAME_CPU_TLCS870_TLCS870D_H +#define MAME_CPU_TLCS870_TLCS870D_H + +#pragma once + +class tlcs870_disassembler : public util::disasm_interface +{ +public: + tlcs870_disassembler() = default; + virtual ~tlcs870_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum _e_op { + UNKNOWN = 0x00, + CALL, CALLP, CALLV, CLR, CPL, + DAA, DAS, DEC, /*DI,*/ DIV, + /*EI,*/ + INC, + /*J,*/ JP, JR, JRS, + LD, LDW, + MCMP, MUL, + NOP, + POP, PUSH, + RET, RETI, RETN, ROLC, ROLD, RORC, RORD, + SET, SHLC, SHRC, SWAP, SWI, + /*TEST,*/ XCH, + + ALU_ADDC, + ALU_ADD, + ALU_SUBB, + ALU_SUB, + ALU_AND, + ALU_XOR, + ALU_OR, + ALU_CMP + }; + + static const char *const op_names[]; + static const char *const reg8[]; + static const char *const type_x[]; + static const char *const conditions[]; + static const char *const reg16[]; + static const char *const reg16p[]; + + uint16_t m_op; + int m_param2_type; + uint16_t m_param2; + + int m_param1_type; + uint16_t m_param1; + + uint8_t m_bitpos; + uint8_t m_flagsaffected; + uint8_t m_cycles; + + uint32_t m_addr; + + const data_buffer *m_opcodes; + + inline uint8_t READ8(); + inline uint16_t READ16(); + + void decode(); + void decode_register_prefix(uint8_t b0); + void decode_source(int type, uint16_t val); + void decode_dest(uint8_t b0); + + void disassemble_param(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, int type, uint16_t val); +}; + +#endif diff --git a/src/devices/cpu/tlcs90/tlcs90.cpp b/src/devices/cpu/tlcs90/tlcs90.cpp index 777ecf3b412..593e454605f 100644 --- a/src/devices/cpu/tlcs90/tlcs90.cpp +++ b/src/devices/cpu/tlcs90/tlcs90.cpp @@ -15,8 +15,7 @@ #include "emu.h" #include "debugger.h" #include "tlcs90.h" - -static const char *const op_names[] = { "??", "nop", "ex", "exx", "ld", "ldw", "lda", "ldi", "ldir", "ldd", "lddr", "cpi", "cpir", "cpd", "cpdr", "push", "pop", "jp", "jr", "call", "callr", "ret", "reti", "halt", "di", "ei", "swi", "daa", "cpl", "neg", "ldar", "rcf", "scf", "ccf", "tset", "bit", "set", "res", "inc", "dec", "incx", "decx", "incw", "decw", "add", "adc", "sub", "sbc", "and", "xor", "or", "cp", "rlc", "rrc", "rl", "rr", "sla", "sra", "sll", "srl", "rld", "rrd", "djnz", "mul", "div" }; +#include "tlcs90d.h" ALLOW_SAVE_TYPE(tlcs90_device::e_mode); // allow save_item on a non-fundamental type @@ -29,6 +28,19 @@ DEFINE_DEVICE_TYPE(TMP91641, tmp91641_device, "tmp91641", "TMP91641") DEFINE_DEVICE_TYPE(TMP90PH44, tmp90ph44_device, "tmp90ph44", "TMP90PH44") +#define T90_IOBASE 0xffc0 + +enum e_ir +{ + T90_P0=T90_IOBASE, T90_P1, T90_P01CR_IRFL, T90_IRFH, T90_P2, T90_P2CR, T90_P3, T90_P3CR, + T90_P4, T90_P4CR, T90_P5, T90_SMMOD, T90_P6, T90_P7, T90_P67CR, T90_SMCR, + T90_P8, T90_P8CR, T90_WDMOD, T90_WDCR, T90_TREG0, T90_TREG1, T90_TREG2, T90_TREG3, + T90_TCLK, T90_TFFCR, T90_TMOD, T90_TRUN, T90_CAP1L, T90_CAP1H, T90_CAP2L, T90_CAL2H, + T90_TREG4L, T90_TREG4H, T90_TREG5L, T90_TREG5H, T90_T4MOD, T90_T4FFCR, T90_INTEL, T90_INTEH, + T90_DMAEH, T90_SCMOD, T90_SCCR, T90_SCBUF, T90_BX, T90_BY, T90_ADREG, T90_ADMOD +}; + + static ADDRESS_MAP_START(tmp90840_mem, AS_PROGRAM, 8, tlcs90_device) AM_RANGE( 0x0000, 0x1fff ) AM_ROM // 8KB ROM (internal) AM_RANGE( 0xfec0, 0xffbf ) AM_RAM // 256b RAM (internal) @@ -141,9 +153,6 @@ enum { #define F m_af.b.l -static const char *const r8_names[] = { "b", "c", "d", "e", "h", "l", "a" }; -static const char *const r16_names[] = { "bc", "de", "hl", "??", "ix", "iy", "sp", "af", "af'", "pc" }; - // Condition Codes #define FLS 0x0 @@ -185,8 +194,6 @@ static uint8_t SZP[256]; /* zero, sign and parity flags */ static uint8_t SZHV_inc[256]; /* zero, sign, half carry and overflow flags INC r8 */ static uint8_t SZHV_dec[256]; /* zero, sign, half carry and overflow flags DEC r8 */ -static const char *const cc_names[] = { "f", "lt", "le", "ule", "ov", "mi", "z", "c", "", "ge", "gt", "ugt", "nov", "pl", "nz", "nc" }; - // Opcodes #define OP_16 0x80 @@ -996,76 +1003,6 @@ void tlcs90_device::decode() OP( UNKNOWN,2 ) NONE( 1 ) NONE( 2 ) } -static const char *const ir_names[] = { - "P0", "P1", "P01CR/IRFL", "IRFH", "P2", "P2CR", "P3", "P3CR", - "P4", "P4CR", "P5", "SMMOD", "P6", "P7", "P67CR", "SMCR", - "P8", "P8CR", "WDMOD", "WDCR", "TREG0", "TREG1", "TREG2", "TREG3", - "TCLK", "TFFCR", "TMOD", "TRUN", "CAP1L", "CAP1H", "CAP2L", "CAL2H", - "TREG4L", "TREG4H", "TREG5L", "TREG5H", "T4MOD", "T4FFCR", "INTEL", "INTEH", - "DMAEH", "SCMOD", "SCCR", "SCBUF", "BX", "BY", "ADREG", "ADMOD" -}; - -const char *tlcs90_device::internal_registers_names(uint16_t x) -{ - int ir = x - T90_IOBASE; - if ( ir >= 0 && ir < ARRAY_LENGTH(ir_names) ) - return ir_names[ir]; - return nullptr; -} -bool tlcs90_device::stream_arg(std::ostream &stream, uint32_t pc, const char *pre, const e_mode mode, const uint16_t r, const uint16_t rb) -{ - const char *reg_name; - switch ( mode ) - { - case e_mode::NONE: return false; - - case e_mode::BIT8: util::stream_format(stream, "%s%d", pre, r ); return true; - case e_mode::I8: util::stream_format(stream, "%s$%02X", pre, r ); return true; - case e_mode::D8: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7f)-(r&0x80))&0xffff ); return true; - case e_mode::I16: util::stream_format(stream, "%s$%04X", pre, r ); return true; - case e_mode::D16: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7fff)-(r&0x8000))&0xffff ); return true; - case e_mode::MI16: - reg_name = internal_registers_names(r); - if (reg_name) - util::stream_format(stream, "%s(%s)", pre, reg_name); - else - util::stream_format(stream, "%s($%04X)", pre, r ); - return true; - case e_mode::R8: util::stream_format(stream, "%s%s", pre, r8_names[r] ); return true; - case e_mode::R16: util::stream_format(stream, "%s%s", pre, r16_names[r] ); return true; - case e_mode::MR16: util::stream_format(stream, "%s(%s)", pre, r16_names[r] ); return true; - - case e_mode::MR16R8: util::stream_format(stream, "%s(%s+%s)", pre, r16_names[r], r8_names[rb] ); return true; - case e_mode::MR16D8: util::stream_format(stream, "%s(%s%c$%02X)", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true; - - case e_mode::CC: util::stream_format(stream, "%s%s", pre, cc_names[r] ); return true; - - case e_mode::R16R8: util::stream_format(stream, "%s%s+%s", pre, r16_names[r], r8_names[rb] ); return true; - case e_mode::R16D8: util::stream_format(stream, "%s%s%c$%02X", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true; - - default: - fatalerror("%04x: unimplemented addr mode = %d\n",pc,std::underlying_type_t<e_mode>(mode)); - } - - // never executed - return false; -} - -offs_t tlcs90_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - m_addr = pc; - - decode(); - m_op &= ~OP_16; - - util::stream_format (stream, "%-5s", op_names[ m_op ] ); // strlen("callr") == 5 - bool streamed = stream_arg (stream, pc, " ", m_mode1, m_r1, m_r1b ); - stream_arg (stream, pc, streamed ?",":"", m_mode2, m_r2, m_r2b ); - - return (m_addr - pc) | DASMFLAG_SUPPORTED; -} - - uint16_t tlcs90_device::r8( const uint16_t r ) { switch( r ) @@ -2055,7 +1992,22 @@ void tlcs90_device::device_reset() dedicated input ports and CPU registers remain unchanged, but PC IFF BX BY = 0, A undefined */ - memset(m_internal_registers, 0, sizeof(m_internal_registers)); + + std::fill(std::begin(m_port_latch), std::end(m_port_latch), 0); + m_p4cr = 0; + m_p67cr = 0; + m_p8cr = 0; + m_smmod = 0; + + m_ixbase = 0; + m_iybase = 0; + + m_tmod = 0; + m_tclk = 0; + m_trun = 0; + m_t4mod = 0; + std::fill(std::begin(m_treg_8bit), std::end(m_treg_8bit), 0); + std::fill(std::begin(m_treg_16bit), std::end(m_treg_16bit), 0); } void tlcs90_device::execute_burn(int32_t cycles) @@ -2337,32 +2289,47 @@ FFED BX R/W Reset Description READ8_MEMBER( tlcs90_device::t90_internal_registers_r ) { - uint8_t data = m_internal_registers[offset]; switch ( T90_IOBASE + offset ) { case T90_P3: // 7,4,1,0 - return (data & 0x6c) | (m_port_read_cb[3]() & 0x93); + return (m_port_latch[3] & 0x6c) | (m_port_read_cb[3]() & 0x93); case T90_P4: // only output - return data & 0x0f; + return m_port_latch[4] & 0x0f; case T90_P5: return (m_port_read_cb[5]() & 0x3f); case T90_P6: - return (data & 0xf0) | (m_port_read_cb[6]() & 0x0f); + return (m_port_latch[6] & 0xf0) | (m_port_read_cb[6]() & 0x0f); case T90_P7: - return (data & 0xf0) | (m_port_read_cb[7]() & 0x0f); + return (m_port_latch[7] & 0xf0) | (m_port_read_cb[7]() & 0x0f); case T90_P8: // 2,1,0 - return (data & 0x08) | (m_port_read_cb[8]() & 0x07); + return (m_port_latch[8] & 0x08) | (m_port_read_cb[8]() & 0x07); case T90_BX: + return 0xf0 | (m_ixbase >> 16); + case T90_BY: - return 0xf0 | data; + return 0xf0 | (m_iybase >> 16); + + case T90_TMOD: + return m_tmod; + + case T90_TCLK: + return m_tclk; + + case T90_TRUN: + return m_trun; + + case T90_T4MOD: + return m_t4mod; } - return data; + + logerror("Read from unimplemented SFR at %04X\n", T90_IOBASE + offset); + return 0; } void tlcs90_device::t90_start_timer(int i) @@ -2372,7 +2339,7 @@ void tlcs90_device::t90_start_timer(int i) m_timer_value[i] = 0; - switch((m_internal_registers[ T90_TMOD - T90_IOBASE ] >> (i * 2)) & 0x03) + switch((m_tmod >> (i * 2)) & 0x03) { case 0: // 8-bit mode @@ -2388,7 +2355,7 @@ void tlcs90_device::t90_start_timer(int i) return; } - switch((m_internal_registers[ T90_TCLK - T90_IOBASE ] >> (i * 2)) & 0x03) + switch((m_tclk >> (i * 2)) & 0x03) { case 0: if (i & 1) logerror("%04X: CPU Timer %d clocked by Timer %d match signal\n", m_pc.w.l, i,i-1); else logerror("%04X: CPU Timer %d, unsupported TCLK = 0\n", m_pc.w.l, i); @@ -2414,11 +2381,11 @@ void tlcs90_device::t90_start_timer4() m_timer4_value = 0; - switch(m_internal_registers[ T90_T4MOD - T90_IOBASE ] & 0x03) + switch(m_t4mod & 0x03) { case 1: prescaler = 1; break; case 2: prescaler = 16; break; - default: logerror("%04X: CPU Timer 4, unsupported T4MOD = %d\n", m_pc.w.l,m_internal_registers[ T90_T4MOD - T90_IOBASE ] & 0x03); + default: logerror("%04X: CPU Timer 4, unsupported T4MOD = %d\n", m_pc.w.l,m_t4mod & 0x03); return; } @@ -2447,12 +2414,12 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer_callback ) int i = param; int mask = 0x20 | (1 << i); - if ( (m_internal_registers[ T90_TRUN - T90_IOBASE ] & mask) != mask ) + if ( (m_trun & mask) != mask ) return; timer_fired = 0; - mode = (m_internal_registers[ T90_TMOD - T90_IOBASE ] >> ((i & ~1) + 2)) & 0x03; + mode = (m_tmod >> ((i & ~1) + 2)) & 0x03; // Match switch (mode) { @@ -2462,7 +2429,7 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer_callback ) // TODO: hmm... case 0x00: // 8bit m_timer_value[i]++; - if ( m_timer_value[i] == m_internal_registers[ T90_TREG0+i - T90_IOBASE ] ) + if ( m_timer_value[i] == m_treg_8bit[i] ) timer_fired = 1; break; @@ -2471,8 +2438,8 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer_callback ) break; m_timer_value[i]++; if(m_timer_value[i] == 0) m_timer_value[i+1]++; - if(m_timer_value[i+1] == m_internal_registers[ T90_TREG0+i+1 - T90_IOBASE ]) - if(m_timer_value[i] == m_internal_registers[ T90_TREG0+i - T90_IOBASE ]) + if(m_timer_value[i+1] == m_treg_8bit[i+1]) + if(m_timer_value[i] == m_treg_8bit[i]) timer_fired = 1; break; } @@ -2486,7 +2453,7 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer_callback ) case 0x00: // 8bit if(i & 1) break; - if ( (m_internal_registers[ T90_TCLK - T90_IOBASE ] & (0x0C << (i * 2))) == 0 ) // T0/T1 match signal clocks T1/T3 + if ( (m_tclk & (0x0C << (i * 2))) == 0 ) // T0/T1 match signal clocks T1/T3 t90_timer_callback(ptr, i+1); break; case 0x01: // 16bit, only can happen for i=0,2 @@ -2508,16 +2475,16 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer4_callback ) // Match - if ( m_timer4_value == (m_internal_registers[ T90_TREG4L - T90_IOBASE ] + (m_internal_registers[ T90_TREG4H - T90_IOBASE ] << 8)) ) + if ( m_timer4_value == m_treg_16bit[0] ) { // logerror("CPU Timer 4 matches TREG4\n"); set_irq_line(INTT4, 1); } - if ( m_timer4_value == (m_internal_registers[ T90_TREG5L - T90_IOBASE ] + (m_internal_registers[ T90_TREG5H - T90_IOBASE ] << 8)) ) + if ( m_timer4_value == m_treg_16bit[1] ) { // logerror("CPU Timer 4 matches TREG5\n"); set_irq_line(INTT5, 1); - if (m_internal_registers[ T90_T4MOD - T90_IOBASE ] & 0x04) + if (m_t4mod & 0x04) m_timer4_value = 0; } @@ -2532,13 +2499,58 @@ TIMER_CALLBACK_MEMBER( tlcs90_device::t90_timer4_callback ) WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) { uint8_t out_mask; - uint8_t old = m_internal_registers[offset]; + switch ( T90_IOBASE + offset ) { + case T90_TMOD: + m_tmod = data; + break; + + case T90_TCLK: + m_tclk = data; + break; + + case T90_TREG0: + m_treg_8bit[0] = data; + break; + + case T90_TREG1: + m_treg_8bit[1] = data; + break; + + case T90_TREG2: + m_treg_8bit[2] = data; + break; + + case T90_TREG3: + m_treg_8bit[3] = data; + break; + + case T90_T4MOD: + m_t4mod = data; + break; + + case T90_TREG4L: + m_treg_16bit[0] = (m_treg_16bit[0] & 0xff00) | data; + break; + + case T90_TREG4H: + m_treg_16bit[0] = (m_treg_16bit[0] & 0x00ff) | (data << 8); + break; + + case T90_TREG5L: + m_treg_16bit[1] = (m_treg_16bit[1] & 0xff00) | data; + break; + + case T90_TREG5H: + m_treg_16bit[1] = (m_treg_16bit[1] & 0x00ff) | (data << 8); + break; + case T90_TRUN: { int i; uint8_t mask; + uint8_t old = m_trun; // Timers 0-3 for (i = 0; i < 4; i++) { @@ -2557,6 +2569,8 @@ WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) if ( (data & mask) == mask ) t90_start_timer4(); else t90_stop_timer4(); } + + m_trun = data; break; } @@ -2590,24 +2604,29 @@ WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) ((data & 0x01) ? (1 << INTT1) : 0) ; break; + case T90_IRFH: + if (data >= int(INTSWI) + 2 && data < int(INTMAX) + 2) + m_irq_state &= ~(1 << (data - 2)); + break; + case T90_P3: - data &= 0x6c; - m_port_write_cb[3](data); + m_port_latch[3] = data & 0x6c; + m_port_write_cb[3](m_port_latch[3]); break; case T90_P4: - data &= 0x0f; - out_mask = (~m_internal_registers[ T90_P4CR - T90_IOBASE ]) & 0x0f; + m_port_latch[4] = data & 0x0f; + out_mask = ~m_p4cr & 0x0f; if (out_mask) { - data &= out_mask; - m_port_write_cb[4](data); + m_port_write_cb[4](m_port_latch[4] & out_mask); } break; case T90_P6: - out_mask = m_internal_registers[ T90_P67CR - T90_IOBASE ] & 0x0f; - switch (m_internal_registers[ T90_SMMOD - T90_IOBASE ] & 0x03) + m_port_latch[6] = data & 0x0f; + out_mask = m_p67cr & 0x0f; + switch (m_smmod & 0x03) { case 1: data &= ~0x01; @@ -2622,14 +2641,14 @@ WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) if (out_mask) { - data &= out_mask; - m_port_write_cb[6](data); + m_port_write_cb[6](m_port_latch[6] & out_mask); } break; case T90_P7: - out_mask = (m_internal_registers[ T90_P67CR - T90_IOBASE ] & 0xf0) >> 4; - switch ((m_internal_registers[ T90_SMMOD - T90_IOBASE ]>>4) & 0x03) + m_port_latch[7] = data & 0x0f; + out_mask = m_p67cr >> 4; + switch ((m_smmod >> 4) & 0x03) { case 1: data &= ~0x01; @@ -2644,29 +2663,47 @@ WRITE8_MEMBER( tlcs90_device::t90_internal_registers_w ) if (out_mask) { - data &= out_mask; - m_port_write_cb[7](data); + m_port_write_cb[7](m_port_latch[7] & out_mask); } break; case T90_P8: - data &= 0x0f; - out_mask = (~m_internal_registers[ T90_P8CR - T90_IOBASE ]) & 0x08; + m_port_latch[8] = data & 0x0f; + out_mask = ~m_p8cr & 0x08; if (out_mask) { - data &= out_mask; - m_port_write_cb[8](data); + m_port_write_cb[8](m_port_latch[8] & out_mask); } break; + case T90_P4CR: + m_p4cr = data; + break; + + case T90_P67CR: + m_p67cr = data; + break; + + case T90_P8CR: + m_p8cr = data; + break; + + case T90_SMMOD: + m_smmod = data; + break; + case T90_BX: m_ixbase = (data & 0xf) << 16; break; + case T90_BY: m_iybase = (data & 0xf) << 16; break; + + default: + logerror("Write to unimplemented SFR at %04X\n", T90_IOBASE + offset); + break; } - m_internal_registers[offset] = data; } @@ -2696,12 +2733,22 @@ void tlcs90_device::device_start() save_item(NAME(m_irq_mask)); save_item(NAME(m_extra_cycles)); - save_item(NAME(m_internal_registers)); + save_item(NAME(m_port_latch)); + save_item(NAME(m_p4cr)); + save_item(NAME(m_p67cr)); + save_item(NAME(m_p8cr)); + save_item(NAME(m_smmod)); save_item(NAME(m_ixbase)); save_item(NAME(m_iybase)); save_item(NAME(m_timer_value)); save_item(NAME(m_timer4_value)); + save_item(NAME(m_tmod)); + save_item(NAME(m_tclk)); + save_item(NAME(m_trun)); + save_item(NAME(m_treg_8bit)); + save_item(NAME(m_t4mod)); + save_item(NAME(m_treg_16bit)); // Work registers save_item(NAME(m_op)); @@ -2745,7 +2792,6 @@ void tlcs90_device::device_start() m_halt = m_after_EI = 0; m_irq_state = m_irq_mask = 0; m_extra_cycles = 0; - memset(m_internal_registers, 0, sizeof(m_internal_registers)); m_ixbase = m_iybase = 0; m_timer_value[0] = m_timer_value[1] = m_timer_value[2] = m_timer_value[3] = 0; m_timer4_value = 0; @@ -2811,3 +2857,8 @@ void tlcs90_device::state_string_export(const device_state_entry &entry, std::st break; } } + +util::disasm_interface *tlcs90_device::create_disassembler() +{ + return new tlcs90_disassembler; +} diff --git a/src/devices/cpu/tlcs90/tlcs90.h b/src/devices/cpu/tlcs90/tlcs90.h index 6677ff7e628..589eae3025c 100644 --- a/src/devices/cpu/tlcs90/tlcs90.h +++ b/src/devices/cpu/tlcs90/tlcs90.h @@ -63,18 +63,6 @@ devcb = &tlcs90_device::set_port_write_cb(*device, 8, DEVCB_##_devcb); -#define T90_IOBASE 0xffc0 - -enum e_ir -{ - T90_P0=T90_IOBASE, T90_P1, T90_P01CR_IRFL, T90_IRFH, T90_P2, T90_P2CR, T90_P3, T90_P3CR, - T90_P4, T90_P4CR, T90_P5, T90_SMMOD, T90_P6, T90_P7, T90_P67CR, T90_SMCR, - T90_P8, T90_P8CR, T90_WDMOD, T90_WDCR, T90_TREG0, T90_TREG1, T90_TREG2, T90_TREG3, - T90_TCLK, T90_TFFCR, T90_TMOD, T90_TRUN, T90_CAP1L, T90_CAP1H, T90_CAP2L, T90_CAL2H, - T90_TREG4L, T90_TREG4H, T90_TREG5L, T90_TREG5H, T90_T4MOD, T90_T4FFCR, T90_INTEL, T90_INTEH, - T90_DMAEH, T90_SCMOD, T90_SCCR, T90_SCBUF, T90_BX, T90_BY, T90_ADREG, T90_ADMOD -}; - enum tlcs90_e_irq { INTSWI = 0, INTNMI, INTWD, INT0, INTT0, INTT1, INTT2, INTT3, INTT4, INT1, INTT5, INT2, INTRX, INTTX, INTMAX }; DECLARE_ENUM_INCDEC_OPERATORS(tlcs90_e_irq) @@ -131,9 +119,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: enum class e_mode : u8 { @@ -156,7 +142,14 @@ private: address_space *m_program; int m_icount; int m_extra_cycles; // extra cycles for interrupts - uint8_t m_internal_registers[48]; + + uint8_t m_port_latch[MAX_PORTS]; + + uint8_t m_p4cr; + uint8_t m_p67cr; + uint8_t m_p8cr; + uint8_t m_smmod; + uint32_t m_ixbase,m_iybase; // Timers: 4 x 8-bit + 1 x 16-bit @@ -164,6 +157,12 @@ private: uint8_t m_timer_value[4]; uint16_t m_timer4_value; attotime m_timer_period; + uint8_t m_tmod; + uint8_t m_tclk; + uint8_t m_trun; + uint8_t m_treg_8bit[4]; + uint8_t m_t4mod; + uint16_t m_treg_16bit[2]; // Work registers uint8_t m_op; @@ -189,8 +188,6 @@ private: inline uint8_t READ8(); inline uint16_t READ16(); void decode(); - const char *internal_registers_names(uint16_t x); - bool stream_arg(std::ostream &stream, uint32_t pc, const char *pre, const e_mode mode, const uint16_t r, const uint16_t rb); inline uint16_t r8( const uint16_t r ); inline void w8( const uint16_t r, uint16_t value ); inline uint16_t r16( const uint16_t r ); diff --git a/src/devices/cpu/tlcs90/tlcs90d.cpp b/src/devices/cpu/tlcs90/tlcs90d.cpp new file mode 100644 index 00000000000..66787e84528 --- /dev/null +++ b/src/devices/cpu/tlcs90/tlcs90d.cpp @@ -0,0 +1,952 @@ +// license:BSD-3-Clause +// copyright-holders:Luca Elia +/************************************************************************************************************* + + Toshiba TLCS-90 Series MCU's + + emulation by Luca Elia, based on the Z80 core by Juergen Buchmueller + + ChangeLog: + + 20150517 Fixed TRUN bit masking (timers start/stop handling) [Rainer Keuchel] + +*************************************************************************************************************/ + +#include "emu.h" +#include "tlcs90d.h" + +const char *const tlcs90_disassembler::op_names[] = { "??", "nop", "ex", "exx", "ld", "ldw", "lda", "ldi", "ldir", "ldd", "lddr", "cpi", "cpir", "cpd", "cpdr", "push", "pop", "jp", "jr", "call", "callr", "ret", "reti", "halt", "di", "ei", "swi", "daa", "cpl", "neg", "ldar", "rcf", "scf", "ccf", "tset", "bit", "set", "res", "inc", "dec", "incx", "decx", "incw", "decw", "add", "adc", "sub", "sbc", "and", "xor", "or", "cp", "rlc", "rrc", "rl", "rr", "sla", "sra", "sll", "srl", "rld", "rrd", "djnz", "mul", "div" }; + +const char *const tlcs90_disassembler::r8_names[] = { "b", "c", "d", "e", "h", "l", "a" }; +const char *const tlcs90_disassembler::r16_names[] = { "bc", "de", "hl", "??", "ix", "iy", "sp", "af", "af'", "pc" }; + +const char *const tlcs90_disassembler::cc_names[] = { "f", "lt", "le", "ule", "ov", "mi", "z", "c", "", "ge", "gt", "ugt", "nov", "pl", "nz", "nc" }; + +u32 tlcs90_disassembler::opcode_alignment() const +{ + return 1; +} + +const char *const tlcs90_disassembler::ir_names[] = { + "P0", "P1", "P01CR/IRFL", "IRFH", "P2", "P2CR", "P3", "P3CR", + "P4", "P4CR", "P5", "SMMOD", "P6", "P7", "P67CR", "SMCR", + "P8", "P8CR", "WDMOD", "WDCR", "TREG0", "TREG1", "TREG2", "TREG3", + "TCLK", "TFFCR", "TMOD", "TRUN", "CAP1L", "CAP1H", "CAP2L", "CAL2H", + "TREG4L", "TREG4H", "TREG5L", "TREG5H", "T4MOD", "T4FFCR", "INTEL", "INTEH", + "DMAEH", "SCMOD", "SCCR", "SCBUF", "BX", "BY", "ADREG", "ADMOD" +}; + +#define T90_IOBASE 0xffc0 + +const char *tlcs90_disassembler::internal_registers_names(uint16_t x) +{ + // FIXME: TMP90PH44 and many other models have completely different SFR maps + int ir = x - T90_IOBASE; + if ( ir >= 0 && ir < ARRAY_LENGTH(ir_names) ) + return ir_names[ir]; + return nullptr; +} + +#define B 0 +#define C 1 +#define D 2 +#define E 3 +#define H 4 +#define L 5 +#define A 6 + +#define BC 0 +#define DE 1 +#define HL 2 +// 3 +#define IX 4 +#define IY 5 +#define SP 6 + +#define AF 7 +#define AF2 8 +#define PC 9 + +#define FLS 0x0 +#define LT 0x1 +#define LE 0x2 +#define ULE 0x3 +#define OV 0x4 +#define PE 0x4 +#define MI 0x5 +#define Z 0x6 +#define EQ 0x6 +#define CR 0x7 +#define ULT 0x7 +#define T 0x8 +#define GE 0x9 +#define GT 0xa +#define UGT 0xb +#define NOV 0xc +#define PO 0xc +#define PL 0xd +#define NZ 0xe +#define NE 0xe +#define NC 0xf +#define UGE 0xf + +#define CF 0x01 +#define NF 0x02 +#define PF 0x04 +#define VF PF +#define XCF 0x08 +#define HF 0x10 +#define IF 0x20 +#define ZF 0x40 +#define SF 0x80 + +#define OP( X,CT ) m_op = X; +#define OP16( X,CT ) m_op = X; + +#define OPCC( X,CF,CT ) m_op = X; +#define OPCC16( X,CF,CT ) m_op = X; + +#define BIT8( N,I ) m_mode##N = e_mode::BIT8; m_r##N = I; +#define I8( N,I ) m_mode##N = e_mode::I8; m_r##N = I; +#define D8( N,I ) m_mode##N = e_mode::D8; m_r##N = I; +#define I16( N,I ) m_mode##N = e_mode::I16; m_r##N = I; +#define D16( N,I ) m_mode##N = e_mode::D16; m_r##N = I; +#define R8( N,R ) m_mode##N = e_mode::R8; m_r##N = R; +#define R16( N,R ) m_mode##N = e_mode::R16; m_r##N = R; +#define Q16( N,R ) m_mode##N = e_mode::R16; m_r##N = R; if (m_r##N == SP) m_r##N = AF; +#define MI16( N,I ) m_mode##N = e_mode::MI16; m_r##N = I; +#define MR16( N,R ) m_mode##N = e_mode::MR16; m_r##N = R; +#define MR16D8( N,R,I ) m_mode##N = e_mode::MR16D8; m_r##N = R; m_r##N##b = I; +#define MR16R8( N,R,g ) m_mode##N = e_mode::MR16R8; m_r##N = R; m_r##N##b = g; +#define NONE( N ) m_mode##N = e_mode::NONE; +#define CC( N,cc ) m_mode##N = e_mode::CC; m_r##N = cc; +#define R16D8( N,R,I ) m_mode##N = e_mode::R16D8; m_r##N = R; m_r##N##b = I; +#define R16R8( N,R,g ) m_mode##N = e_mode::R16R8; m_r##N = R; m_r##N##b = g; + +uint8_t tlcs90_disassembler::READ8() +{ + uint8_t b0 = m_opcodes->r8( m_addr++ ); + m_addr &= 0xffff; + return b0; +} +uint16_t tlcs90_disassembler::READ16() +{ + uint8_t b0 = READ8(); + return b0 | (READ8() << 8); +} + +void tlcs90_disassembler::decode() +{ + uint8_t b0, b1, b2, b3; + uint16_t imm16; + + b0 = READ8(); + + switch ( b0 ) + { + case 0x00: + OP( NOP,2 ) NONE( 1 ) NONE( 2 ) return; // NOP + + case 0x01: + OP( HALT,4 ) NONE( 1 ) NONE( 2 ) return; // HALT + case 0x02: + OP( DI,2 ) NONE( 1 ) NONE( 2 ) return; // DI + case 0x03: + OP( EI,2 ) NONE( 1 ) NONE( 2 ) return; // EI + + case 0x07: + OPCC( INCX,6,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // INCX ($FF00+n) + + case 0x08: + OP( EX,2 ) R16( 1, DE ) R16( 2, HL ) return; // EX DE,HL + case 0x09: + OP( EX,2 ) R16( 1, AF ) R16( 2, AF2 ) return; // EX AF,AF' + case 0x0a: + OP( EXX,2 ) NONE( 1 ) NONE( 2 ) return; // EXX + + case 0x0b: + OP( DAA,4 ) R8( 1, A ) NONE( 2 ) return; // DAA A + + case 0x0c: + OP( RCF,2 ) NONE( 1 ) NONE( 2 ) return; // RCF + case 0x0d: + OP( SCF,2 ) NONE( 1 ) NONE( 2 ) return; // SCF + case 0x0e: + OP( CCF,2 ) NONE( 1 ) NONE( 2 ) return; // CCF + + case 0x0f: + OPCC( DECX,6,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // DECX ($FF00+n) + + case 0x10: + OP( CPL,2 ) R8( 1, A ) NONE( 2 ) return; // CPL A + case 0x11: + OP( NEG,2 ) R8( 1, A ) NONE( 2 ) return; // NEG A + + case 0x12: // MUL HL,n + case 0x13: // DIV HL,n + OP( MUL+b0-0x12,16) R16( 1, HL ) I8( 2, READ8() ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,6 ) R16( 1, IX+b0-0x14 ) I16( 2, READ16() ) return; // ADD ix,mn + + case 0x17: + OP( LDAR,8 ) R16( 1, HL ) D16( 2, READ16() ) return; // LDAR HL,+cd + + case 0x18: + OP( DJNZ,10 ) D8( 1, READ8() ) NONE( 2 ) return; // DJNZ +d + case 0x19: + OP16( DJNZ,10 ) R16( 1, BC ) D8( 2, READ8() ) return; // DJNZ BC,+d + + case 0x1a: + OPCC( JP,8,8 ) CC( 1, T ) I16( 2, READ16() ) return; // JP T,mn + case 0x1b: + OPCC16( JR,10,10 ) CC( 1, T ) D16( 2, READ16() ) return; // JR T,+cd + + case 0x1c: + OPCC( CALL,14,14 ) CC( 1, T ) I16( 2, READ16() ) return; // CALL T,mn + case 0x1d: + OP( CALLR,16 ) D16( 1, READ16() ) NONE( 2 ) return; // CALLR +cd + + case 0x1e: + OPCC( RET,10,10 ) CC( 1, T ) NONE( 2 ) return; // RET T + case 0x1f: + OP( RETI,14 ) NONE( 1 ) NONE( 2 ) return; // RETI + + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,2 ) R8( 1, A ) R8( 2, b0 - 0x20 ) return; // LD A,r + + case 0x27: + OP( LD,8 ) R8( 1, A ) MI16( 2, 0xFF00|READ8() ) return; // LD A,($FF00+n) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,2 ) R8( 1, b0 - 0x28 ) R8( 2, A ) return; // LD r,A + + case 0x2f: + OP( LD,8 ) MI16( 1, 0xFF00|READ8() ) R8( 2, A ) return; // LD ($FF00+n), A + + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: + OP( LD,4 ) R8( 1, b0 - 0x30 ) I8( 2, READ8() ) return; // LD r,n + + case 0x37: + OP( LD,10 ) MI16( 1, 0xFF00|READ8() ) I8( 2, READ8() ) return; // LD ($FF00+w),n + + case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e: + OP16( LD,6 ) R16( 1, b0 - 0x38 ) I16( 2, READ16() ) return; // LD rr,nn + + case 0x3f: + OP( LDW,14 ) MI16( 1, 0xFF00|READ8() ) I16( 2, READ16() ) return; // LDW ($FF00+w),mn + + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,4 ) R16( 1, HL ) R16( 2, b0 - 0x40 ) return; // LD HL,rr + + case 0x47: + OP16( LD,10 ) R16( 1, HL ) MI16( 2, 0xFF00|READ8() ) return; // LD HL,($FF00+n) + + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,4 ) R16( 1, b0 - 0x48 ) R16( 2, HL ) return; // LD rr,HL + + case 0x4f: + OP16( LD,10 ) MI16( 1, 0xFF00|READ8() ) R16( 2, HL ) return; // LD ($FF00+n), HL + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( PUSH,8 ) Q16( 1, b0 - 0x50 ) NONE( 2 ) return; // PUSH qq + case 0x58: case 0x59: case 0x5a: /*case 0x5b:*/ case 0x5c: case 0x5d: case 0x5e: + OP( POP,10 ) Q16( 1, b0 - 0x58 ) NONE( 2 ) return; // POP qq + + case 0x60: // ADD A,($FF00+n) + case 0x61: // ADC A,($FF00+n) + case 0x62: // SUB A,($FF00+n) + case 0x63: // SBC A,($FF00+n) + case 0x64: // AND A,($FF00+n) + case 0x65: // XOR A,($FF00+n) + case 0x66: // OR A,($FF00+n) + case 0x67: // CP A,($FF00+n) + OP( ADD+b0-0x60,8 ) R8( 1, A ) MI16( 2, 0xFF00|READ8() ) return; + + case 0x68: // ADD A,n + case 0x69: // ADC A,n + case 0x6a: // SUB A,n + case 0x6b: // SBC A,n + case 0x6c: // AND A,n + case 0x6d: // XOR A,n + case 0x6e: // OR A,n + case 0x6f: // CP A,n + OP( ADD+b0-0x68,4 ) R8( 1, A ) I8( 2, READ8() ) return; + + case 0x70: // ADD HL,($FF00+n) + case 0x71: // ADC HL,($FF00+n) + case 0x72: // SUB HL,($FF00+n) + case 0x73: // SBC HL,($FF00+n) + case 0x74: // AND HL,($FF00+n) + case 0x75: // XOR HL,($FF00+n) + case 0x76: // OR HL,($FF00+n) + case 0x77: // CP HL,($FF00+n) + OP16( ADD+b0-0x70,10 ) R16( 1, HL ) MI16( 2, 0xFF00|READ8() ) return; + + case 0x78: // ADD HL,mn + case 0x79: // ADC HL,mn + case 0x7a: // SUB HL,mn + case 0x7b: // SBC HL,mn + case 0x7c: // AND HL,mn + case 0x7d: // XOR HL,mn + case 0x7e: // OR HL,mn + case 0x7f: // CP HL,mn + OP16( ADD+b0-0x78,6 ) R16( 1, HL ) I16( 2, READ16() ) return; + + case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: + OP( INC,2 ) R8( 1, b0 - 0x80 ) NONE( 2 ) return; // INC r + case 0x87: + OP( INC,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // INC ($FF00+n) + + case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: + OP( DEC,2 ) R8( 1, b0 - 0x88 ) NONE( 2 ) return; // DEC r + case 0x8f: + OP( DEC,10 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // DEC ($FF00+n) + + case 0x90: case 0x91: case 0x92: /*case 0x93:*/ case 0x94: case 0x95: case 0x96: + OP16( INC,4 ) R16( 1, b0 - 0x90 ) NONE( 2 ) return; // INC rr + case 0x97: + OP( INCW,14 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // INCW ($FF00+n) + case 0x98: case 0x99: case 0x9a: /*case 0x9b:*/ case 0x9c: case 0x9d: case 0x9e: + OP16( DEC,4 ) R16( 1, b0 - 0x98 ) NONE( 2 ) return; // DEC rr + case 0x9f: + OP( DECW,14 ) MI16( 1, 0xFF00|READ8() ) NONE( 2 ) return; // DECW ($FF00+n) + + case 0xa0: // RLC A + case 0xa1: // RRC A + case 0xa2: // RL A + case 0xa3: // RR A + case 0xa4: // SLA A + case 0xa5: // SRA A + case 0xa6: // SLL A + case 0xa7: // SRL A + OP( RLC+b0-0xa0,2 ) R8( 1, A ) NONE( 2 ) return; + + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,8 ) BIT8( 1, b0 - 0xa8 ) MI16( 2, 0xFF00|READ8() ) return; // BIT b,($FF00+n) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,12 ) BIT8( 1, b0 - 0xb0 ) MI16( 2, 0xFF00|READ8() ) return; // RES b,($FF00+n) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,12 ) BIT8( 1, b0 - 0xb8 ) MI16( 2, 0xFF00|READ8() ) return; // SET b,($FF00+n) + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JR,4,8 ) CC( 1, b0 - 0xc0 ) D8( 2, READ8() ) return; // JR cc,+d + + case 0xe0: case 0xe1: case 0xe2: /*case 0xe3:*/ case 0xe4: case 0xe5: case 0xe6: + b1 = READ8(); + switch ( b1 ) { + case 0x10: // RLD (gg) + case 0x11: // RRD (gg) + OP( RLD+b1-0x10,12 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; + + case 0x12: // MUL HL,(gg) + case 0x13: // DIV HL,(gg) + OP( MUL+b1-0x12,18 ) R16( 1, HL ) MR16( 2, b0 - 0xe0 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,8 ) R16( 1, IX+b1-0x14 ) MR16( 2, b0 - 0xe0 ) return; // ADD ix,(gg) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,6 ) R8( 1, b1 - 0x28 ) MR16( 2, b0 - 0xe0 ) return; // LD r,(gg) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,8 ) R16( 1, b1 - 0x48 ) MR16( 2, b0 - 0xe0 ) return; // LD rr,(gg) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,14 ) MR16( 1, b0 - 0xe0 ) R16( 2, b1 - 0x50 ) return; // EX (gg),rr + + case 0x60: // ADD A,(gg) + case 0x61: // ADC A,(gg) + case 0x62: // SUB A,(gg) + case 0x63: // SBC A,(gg) + case 0x64: // AND A,(gg) + case 0x65: // XOR A,(gg) + case 0x66: // OR A,(gg) + case 0x67: // CP A,(gg) + OP( ADD+b1-0x60,6 ) R8( 1, A ) MR16( 2, b0 - 0xe0 ) return; + + case 0x70: // ADD HL,(gg) + case 0x71: // ADC HL,(gg) + case 0x72: // SUB HL,(gg) + case 0x73: // SBC HL,(gg) + case 0x74: // AND HL,(gg) + case 0x75: // XOR HL,(gg) + case 0x76: // OR HL,(gg) + case 0x77: // CP HL,(gg) + OP16( ADD+b1-0x70,8 ) R16( 1, HL ) MR16( 2, b0 - 0xe0 ) return; + + case 0x87: + OP( INC,8 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // INC (gg) + case 0x8f: + OP( DEC,8 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // DEC (gg) + + case 0x97: + OP( INCW,12 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // INCW (gg) + case 0x9f: + OP( DECW,12 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; // DECW (gg) + + case 0xa0: // RLC (gg) + case 0xa1: // RRC (gg) + case 0xa2: // RL (gg) + case 0xa3: // RR (gg) + case 0xa4: // SLA (gg) + case 0xa5: // SRA (gg) + case 0xa6: // SLL (gg) + case 0xa7: // SRL (gg) + OP( RLC+b1-0xa0,8 ) MR16( 1, b0 - 0xe0 ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,12 ) BIT8( 1, b1 - 0x18 ) MR16( 2, b0 - 0xe0 ) return; // TSET b,(gg) + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,6 ) BIT8( 1, b1 - 0xa8 ) MR16( 2, b0 - 0xe0 ) return; // BIT b,(gg) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,10 ) BIT8( 1, b1 - 0xb0 ) MR16( 2, b0 - 0xe0 ) return; // RES b,(gg) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,10 ) BIT8( 1, b1 - 0xb8 ) MR16( 2, b0 - 0xe0 ) return; // SET b,(gg) + } break; + case 0xe3: + imm16 = READ16(); + b3 = READ8(); + switch ( b3 ) { + case 0x10: // RLD (mn) + case 0x11: // RRD (mn) + OP( RLD+b3-0x10,16 ) MI16( 1, imm16 ) NONE( 2 ) return; + + case 0x12: // MUL HL,(mn) + case 0x13: // DIV HL,(mn) + OP( MUL+b3-0x12,22 ) R16( 1, HL ) MI16( 2, imm16 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,12 ) R16( 1, IX+b3-0x14 ) MI16( 2, imm16 ) return; // ADD ix,(mn) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,10 ) R8( 1, b3 - 0x28 ) MI16( 2, imm16 ) return; // LD r,(mn) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,12 ) R16( 1, b3 - 0x48 ) MI16( 2, imm16 ) return; // LD rr,(mn) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,18 ) MI16( 1, imm16 ) R16( 2, b3 - 0x50 ) return; // EX (mn),rr + + case 0x60: // ADD A,(mn) + case 0x61: // ADC A,(mn) + case 0x62: // SUB A,(mn) + case 0x63: // SBC A,(mn) + case 0x64: // AND A,(mn) + case 0x65: // XOR A,(mn) + case 0x66: // OR A,(mn) + case 0x67: // CP A,(mn) + OP( ADD+b3-0x60,10 ) R8( 1, A ) MI16( 2, imm16 ) return; + + case 0x70: // ADD HL,(mn) + case 0x71: // ADC HL,(mn) + case 0x72: // SUB HL,(mn) + case 0x73: // SBC HL,(mn) + case 0x74: // AND HL,(mn) + case 0x75: // XOR HL,(mn) + case 0x76: // OR HL,(mn) + case 0x77: // CP HL,(mn) + OP16( ADD+b3-0x70,12 ) R16( 1, HL ) MI16( 2, imm16 ) return; + + case 0x87: + OP( INC,12 ) MI16( 1, imm16 ) NONE( 2 ) return; // INC (mn) + case 0x8f: + OP( DEC,12 ) MI16( 1, imm16 ) NONE( 2 ) return; // DEC (mn) + + case 0x97: + OP( INCW,16 ) MI16( 1, imm16 ) NONE( 2 ) return; // INCW (mn) + case 0x9f: + OP( DECW,16 ) MI16( 1, imm16 ) NONE( 2 ) return; // DECW (mn) + + case 0xa0: // RLC (mn) + case 0xa1: // RRC (mn) + case 0xa2: // RL (mn) + case 0xa3: // RR (mn) + case 0xa4: // SLA (mn) + case 0xa5: // SRA (mn) + case 0xa6: // SLL (mn) + case 0xa7: // SRL (mn) + OP( RLC+b3-0xa0,12 ) MI16( 1, imm16 ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,16 ) BIT8( 1, b3 - 0x18 ) MI16( 2, imm16 ) return; // TSET b,(mn) + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,10 ) BIT8( 1, b3 - 0xa8 ) MI16( 2, imm16 ) return; // BIT b,(mn) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,14 ) BIT8( 1, b3 - 0xb0 ) MI16( 2, imm16 ) return; // RES b,(mn) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,14 ) BIT8( 1, b3 - 0xb8 ) MI16( 2, imm16 ) return; // SET b,(mn) + } break; + + case 0xe7: + b1 = READ8(); + b2 = READ8(); + switch ( b2 ) { + case 0x10: // RLD ($FF00+n) + case 0x11: // RRD ($FF00+n) + OP( RLD+b2-0x10,14 ) MI16( 1, 0xFF00|b1 ) NONE( 2 ) return; + + case 0x12: // MUL HL,($FF00+n) + case 0x13: // DIV HL,($FF00+n) + OP( MUL+b2-0x12,20 ) R16( 1, HL ) MI16( 2, 0xFF00|b1 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,10 ) R16( 1, IX+b2-0x14 ) MI16( 2, 0xFF00|b1 ) return; // ADD ix,($FF00+n) + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,14 ) BIT8( 1, b2 - 0x18 ) MI16( 2, 0xFF00|b1 ) return; // TSET b,($FF00+n) + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,8 ) R8( 1, b2 - 0x28 ) MI16( 2, 0xFF00|b1 ) return; // LD r,($FF00+n) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,10 ) R16( 1, b2 - 0x48 ) MI16( 2, 0xFF00|b1 ) return; // LD rr,($FF00+n) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,16 ) MI16( 1, 0xFF00|b1 ) R16( 2, b2 - 0x50 ) return; // EX ($FF00+n),rr + + case 0xa0: // RLC ($FF00+n) + case 0xa1: // RRC ($FF00+n) + case 0xa2: // RL ($FF00+n) + case 0xa3: // RR ($FF00+n) + case 0xa4: // SLA ($FF00+n) + case 0xa5: // SRA ($FF00+n) + case 0xa6: // SLL ($FF00+n) + case 0xa7: // SRL ($FF00+n) + OP( RLC+b2-0xa0,10 ) MI16( 1, 0xFF00|b1 ) NONE( 2 ) return; + } break; + + case 0xe8: case 0xe9: case 0xea: /*case 0xeb:*/ case 0xec: case 0xed: case 0xee: + b1 = READ8(); + switch ( b1 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,6 ) MR16( 1, b0 - 0xe8 ) R8( 2, b1 - 0x20 ) return; // LD (gg),r + case 0x37: + OP( LD,8 ) MR16( 1, b0 - 0xe8 ) I8( 2, READ8() ) return; // LD (gg),n + case 0x3f: + OP( LDW,12 ) MR16( 1, b0 - 0xe8 ) I16( 2, READ16() ) return; // LDW (gg),mn + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,8 ) MR16( 1, b0 - 0xe8 ) R16( 2, b1 - 0x40 ) return; // LD (gg),rr + + case 0x68: // ADD (gg),n + case 0x69: // ADC (gg),n + case 0x6a: // SUB (gg),n + case 0x6b: // SBC (gg),n + case 0x6c: // AND (gg),n + case 0x6d: // XOR (gg),n + case 0x6e: // OR (gg),n + OP( ADD+b1-0x68,10 ) MR16( 1, b0 - 0xe8 ) I8( 2, READ8() ) return; + case 0x6f: // CP (gg),n + OP( CP,8 ) MR16( 1, b0 - 0xe8 ) I8( 2, READ8() ) return; + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JP,6,8 ) CC( 1, b1 - 0xc0 ) R16( 2, b0 - 0xe8 ) return; // JP [cc,]gg + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + OPCC( CALL,6,14 ) CC( 1, b1 - 0xd0 ) R16( 2, b0 - 0xe8 ) return; // CALL [cc,]gg + } break; + case 0xeb: + imm16 = READ16(); + b3 = READ8(); + switch ( b3 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,10 ) MI16( 1, imm16 ) R8( 2, b3 - 0x20 ) return; // LD (mn),r + case 0x37: + OP( LD,12 ) MI16( 1, imm16 ) I8( 2, READ8() ) return; // LD (vw),n + case 0x3f: + OP( LDW,16 ) MI16( 1, imm16 ) I16( 2, READ16() ) return; // LDW (vw),mn + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,12 ) MI16( 1, imm16 ) R16( 2, b3 - 0x40 ) return; // LD (mn),rr + + case 0x68: // ADD (vw),n + case 0x69: // ADC (vw),n + case 0x6a: // SUB (vw),n + case 0x6b: // SBC (vw),n + case 0x6c: // AND (vw),n + case 0x6d: // XOR (vw),n + case 0x6e: // OR (vw),n + OP( ADD+b3-0x68,14 ) MI16( 1, imm16 ) I8( 2, READ8() ) return; + case 0x6f: // CP (vw),n + OP( ADD+b3-0x68,12 ) MI16( 1, imm16 ) I8( 2, READ8() ) return; + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JP,10,12 ) CC( 1, b3 - 0xc0 ) I16( 2, imm16 ) return; // JP cc,mn + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + OPCC( CALL,10,18 ) CC( 1, b3 - 0xd0 ) I16( 2, imm16 ) return; // CALL cc,mn + } break; + + case 0xef: + b1 = READ8(); + b2 = READ8(); + switch ( b2 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,8 ) MI16( 1, 0xFF00|b1 ) R8( 2, b2 - 0x20 ) return; // LD ($FF00+n),r + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,10 ) MI16( 1, 0xFF00|b1 ) R16( 2, b2 - 0x40 ) return; // LD ($FF00+n),rr + + case 0x68: // ADD ($FF00+w),n + case 0x69: // ADC ($FF00+w),n + case 0x6a: // SUB ($FF00+w),n + case 0x6b: // SBC ($FF00+w),n + case 0x6c: // AND ($FF00+w),n + case 0x6d: // XOR ($FF00+w),n + case 0x6e: // OR ($FF00+w),n + OP( ADD+b2-0x68,12 ) MI16( 1, 0xFF00|b1 ) I8( 2, READ8() ) return; + case 0x6f: // CP ($FF00+w),n + OP( ADD+b2-0x68,10 ) MI16( 1, 0xFF00|b1 ) I8( 2, READ8() ) return; + } break; + + case 0xf0: case 0xf1: case 0xf2: + b1 = READ8(); + b2 = READ8(); + switch ( b2 ) { + case 0x10: // RLD (ix+d) + case 0x11: // RRD (ix+d) + OP( RLD+b2-0x10,16 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; + + case 0x12: // MUL HL,(ix+d) + case 0x13: // DIV HL,(ix+d) + OP( MUL+b2-0x12,22 ) R16( 1, HL ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,12 ) R16( 1, IX+b2-0x14 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // ADD ix,(jx+d) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,10 ) R8( 1, b2 - 0x28 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // LD r,(ix+d) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,12 ) R16( 1, b2 - 0x48 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // LD rr,(ix+d) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,18 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) R16( 2, b2 - 0x50 ) return; // EX (ix+d),rr + + case 0x60: // ADD A,(ix+d) + case 0x61: // ADC A,(ix+d) + case 0x62: // SUB A,(ix+d) + case 0x63: // SBC A,(ix+d) + case 0x64: // AND A,(ix+d) + case 0x65: // XOR A,(ix+d) + case 0x66: // OR A,(ix+d) + case 0x67: // CP A,(ix+d) + OP( ADD+b2-0x60,10 ) R8( 1, A ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; + + case 0x70: // ADD HL,(ix+d) + case 0x71: // ADC HL,(ix+d) + case 0x72: // SUB HL,(ix+d) + case 0x73: // SBC HL,(ix+d) + case 0x74: // AND HL,(ix+d) + case 0x75: // XOR HL,(ix+d) + case 0x76: // OR HL,(ix+d) + case 0x77: // CP HL,(ix+d) + OP16( ADD+b2-0x70,12 ) R16( 1, HL ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; + + case 0x87: + OP( INC,12 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // INC (ix+d) + case 0x8f: + OP( DEC,12 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // DEC (ix+d) + + case 0x97: + OP( INCW,16 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // INCW (ix+d) + case 0x9f: + OP( DECW,16 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; // DECW (ix+d) + + case 0xa0: // RLC (ix+d) + case 0xa1: // RRC (ix+d) + case 0xa2: // RL (ix+d) + case 0xa3: // RR (ix+d) + case 0xa4: // SLA (ix+d) + case 0xa5: // SRA (ix+d) + case 0xa6: // SLL (ix+d) + case 0xa7: // SRL (ix+d) + OP( RLC+b2-0xa0,12 ) MR16D8( 1, IX + b0 - 0xf0, b1 ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,16 ) BIT8( 1, b2 - 0x18 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // TSET b,(ix+d) + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,10 ) BIT8( 1, b2 - 0xa8 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // BIT b,(ix+d) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,14 ) BIT8( 1, b2 - 0xb0 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // RES b,(ix+d) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,14 ) BIT8( 1, b2 - 0xb8 ) MR16D8( 2, IX + b0 - 0xf0, b1 ) return; // SET b,(ix+d) + } break; + + case 0xf3: + b1 = READ8(); + switch ( b1 ) { + case 0x10: // RLD (HL+A) + case 0x11: // RRD (HL+A) + OP( RLD+b1-0x10,20 ) MR16R8( 1, HL, A ) NONE( 2 ) return; + + case 0x12: // MUL HL,(HL+A) + case 0x13: // DIV HL,(HL+A) + OP( MUL+b1-0x12,26 ) R16( 1, HL ) MR16R8( 2, HL, A ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,16 ) R16( 1, IX+b1-0x14 ) MR16R8( 2, HL, A ) return; // ADD ix,(HL+A) + + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: + OP( LD,14 ) R8( 1, b1 - 0x28 ) MR16R8( 2, HL, A ) return; // LD r,(HL+A) + case 0x48: case 0x49: case 0x4a: /*case 0x4b:*/ case 0x4c: case 0x4d: case 0x4e: + OP16( LD,16 ) R16( 1, b1 - 0x48 ) MR16R8( 2, HL, A ) return; // LD rr,(HL+A) + + case 0x50: case 0x51: case 0x52: /*case 0x53:*/ case 0x54: case 0x55: case 0x56: + OP( EX,22 ) MR16R8( 1, HL, A ) R16( 2, b1 - 0x50 ) return; // EX (HL+A),rr + + case 0x60: // ADD A,(HL+A) + case 0x61: // ADC A,(HL+A) + case 0x62: // SUB A,(HL+A) + case 0x63: // SBC A,(HL+A) + case 0x64: // AND A,(HL+A) + case 0x65: // XOR A,(HL+A) + case 0x66: // OR A,(HL+A) + case 0x67: // CP A,(HL+A) + OP( ADD+b1-0x60,14 ) R8( 1, A ) MR16R8( 2, HL, A ) return; + + case 0x70: // ADD HL,(HL+A) + case 0x71: // ADC HL,(HL+A) + case 0x72: // SUB HL,(HL+A) + case 0x73: // SBC HL,(HL+A) + case 0x74: // AND HL,(HL+A) + case 0x75: // XOR HL,(HL+A) + case 0x76: // OR HL,(HL+A) + case 0x77: // CP HL,(HL+A) + OP16( ADD+b1-0x70,16 ) R16( 1, HL ) MR16R8( 2, HL, A ) return; + + case 0x87: + OP( INC,16 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // INC (HL+A) + case 0x8f: + OP( DEC,16 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // DEC (HL+A) + + case 0x97: + OP( INCW,20 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // INCW (HL+A) + case 0x9f: + OP( DECW,20 ) MR16R8( 1, HL, A ) NONE( 2 ) return; // DECW (HL+A) + + case 0xa0: // RLC (HL+A) + case 0xa1: // RRC (HL+A) + case 0xa2: // RL (HL+A) + case 0xa3: // RR (HL+A) + case 0xa4: // SLA (HL+A) + case 0xa5: // SRA (HL+A) + case 0xa6: // SLL (HL+A) + case 0xa7: // SRL (HL+A) + OP( RLC+b1-0xa0,16 ) MR16R8( 1, HL, A ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,20 ) BIT8( 1, b1 - 0x18 ) MR16R8( 2, HL, A ) return; // TSET b,(HL+A) + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,14 ) BIT8( 1, b1 - 0xa8 ) MR16R8( 2, HL, A ) return; // BIT b,(HL+A) + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,18 ) BIT8( 1, b1 - 0xb0 ) MR16R8( 2, HL, A ) return; // RES b,(HL+A) + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,18 ) BIT8( 1, b1 - 0xb8 ) MR16R8( 2, HL, A ) return; // SET b,(HL+A) + } break; + + case 0xf4: case 0xf5: case 0xf6: + b1 = READ8(); + b2 = READ8(); + switch ( b2 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,10 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) R8( 2, b2 - 0x20 ) return; // LD (ix+d),r + case 0x37: + OP( LD,12 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) I8( 2, READ8() ) return; // LD (ix+d),n + case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e: + OP( LDA,10 ) R16( 1, b2 - 0x38 ) R16D8( 2, IX + b0 - 0xf4, b1 ) return; // LDA rr,ix+d + case 0x3f: + OP( LDW,16 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) I16( 2, READ16() ) return; // LDW (ix+d),mn + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,12 ) MR16D8( 1, IX + b0 - 0xf4, b1 ) R16( 2, b2 - 0x40 ) return; // LD (ix+d),rr + + case 0x68: // ADD (ix+d),n + case 0x69: // ADC (ix+d),n + case 0x6a: // SUB (ix+d),n + case 0x6b: // SBC (ix+d),n + case 0x6c: // AND (ix+d),n + case 0x6d: // XOR (ix+d),n + case 0x6e: // OR (ix+d),n + OP( ADD+b2-0x68,14) MR16D8( 1, IX + b0 - 0xf4, b1 ) I8( 2, READ8() ) return; + case 0x6f: // CP (ix+d),n + OP( ADD+b2-0x68,12) MR16D8( 1, IX + b0 - 0xf4, b1 ) I8( 2, READ8() ) return; + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JP,10,12 ) CC( 1, b2 - 0xc0 ) R16D8( 2, IX + b0 - 0xf4, b1 ) return; // JP [cc,]ix+d + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + OPCC( CALL,10,18 ) CC( 1, b2 - 0xd0 ) R16D8( 2, IX + b0 - 0xf4, b1 ) return; // CALL [cc,]ix+d + } break; + + case 0xf7: + b1 = READ8(); + switch ( b1 ) { + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: + OP( LD,14 ) MR16R8( 1, HL, A ) R8( 2, b1 - 0x20 ) return; // LD (HL+A),r + case 0x37: + OP( LD,16 ) MR16R8( 1, HL, A ) I8( 2, READ8() ) return; // LD (HL+A),n + case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e: + OP( LDA,14 ) R16( 1, b1 - 0x38 ) R16R8( 2, HL, A ) return; // LDA rr,HL+A + case 0x3f: + OP( LDW,20 ) MR16R8( 1, HL, A ) I16( 2, READ16() ) return; // LDW (HL+A),mn + case 0x40: case 0x41: case 0x42: /*case 0x43:*/ case 0x44: case 0x45: case 0x46: + OP16( LD,16 ) MR16R8( 1, HL, A ) R16( 2, b1 - 0x40 ) return; // LD (HL+A),rr + + case 0x68: // ADD (HL+A),n + case 0x69: // ADC (HL+A),n + case 0x6a: // SUB (HL+A),n + case 0x6b: // SBC (HL+A),n + case 0x6c: // AND (HL+A),n + case 0x6d: // XOR (HL+A),n + case 0x6e: // OR (HL+A),n + OP( ADD+b1-0x68,18) MR16R8( 1, HL, A ) I8( 2, READ8() ) return; + case 0x6f: // CP (HL+A),n + OP( ADD+b1-0x68,16) MR16R8( 1, HL, A ) I8( 2, READ8() ) return; + + case 0xc0: case 0xc1: case 0xc2: case 0xc3: case 0xc4: case 0xc5: case 0xc6: case 0xc7: + case 0xc8: case 0xc9: case 0xca: case 0xcb: case 0xcc: case 0xcd: case 0xce: case 0xcf: + OPCC( JP,14,16 ) CC( 1, b1 - 0xc0 ) R16R8( 2, HL, A ) return; // JP [cc,]HL+A + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + OPCC( CALL,14,22 ) CC( 1, b1 - 0xd0 ) R16R8( 2, HL, A ) return; // CALL [cc,]HL+A + } break; + + case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: + b1 = READ8(); + switch ( b1 ) { + case 0x12: // MUL HL,g + case 0x13: // DIV HL,g + OP( MUL+b1-0x12,18) R16( 1, HL ) R8( 2, b0 - 0xf8 ) return; + + case 0x14: case 0x15: case 0x16: + OP16( ADD,8 ) R16( 1, IX+b1-0x14 ) R16( 2, b0 - 0xf8 ) return; // ADD ix,gg + + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: + OP( LD,4 ) R8( 1, b1 - 0x30 ) R8( 2, b0 - 0xf8 ) return; // LD r,g + case 0x38: case 0x39: case 0x3a: /*case 0x3b:*/ case 0x3c: case 0x3d: case 0x3e: + OP16( LD,6 ) R16( 1, b1 - 0x38 ) R16( 2, b0 - 0xf8 ) return; // LD rr,gg + + case 0x58: // LDI + case 0x59: // LDIR + case 0x5a: // LDD + case 0x5b: // LDDR + case 0x5c: // CPI + case 0x5d: // CPIR + case 0x5e: // CPD + case 0x5f: // CPDR + if (b0 == 0xfe) { + OPCC( LDI+b1-0x58,14,18 ) NONE( 1 ) NONE( 2 ) return; + } + + case 0x60: // ADD A,g + case 0x61: // ADC A,g + case 0x62: // SUB A,g + case 0x63: // SBC A,g + case 0x64: // AND A,g + case 0x65: // XOR A,g + case 0x66: // OR A,g + case 0x67: // CP A,g + OP( ADD+b1-0x60,4 ) R8( 1, A ) R8( 2, b0 - 0xf8 ) return; + + case 0x68: // ADD g,n + case 0x69: // ADC g,n + case 0x6a: // SUB g,n + case 0x6b: // SBC g,n + case 0x6c: // AND g,n + case 0x6d: // XOR g,n + case 0x6e: // OR g,n + case 0x6f: // CP g,n + OP( ADD+b1-0x68,6 ) R8( 1, b0 - 0xf8 ) I8( 2, READ8() ) return; + + case 0x70: // ADD HL,gg + case 0x71: // ADC HL,gg + case 0x72: // SUB HL,gg + case 0x73: // SBC HL,gg + case 0x74: // AND HL,gg + case 0x75: // XOR HL,gg + case 0x76: // OR HL,gg + case 0x77: // CP HL,gg + OP16( ADD+b1-0x70,8 ) R16( 1, HL ) R16( 2, b0 - 0xf8 ) return; + + case 0xa0: // RLC g + case 0xa1: // RRC g + case 0xa2: // RL g + case 0xa3: // RR g + case 0xa4: // SLA g + case 0xa5: // SRA g + case 0xa6: // SLL g + case 0xa7: // SRL g + OP( RLC+b1-0xa0,4 ) R8( 1, b0 - 0xf8 ) NONE( 2 ) return; + + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + OP( TSET,8 ) BIT8( 1, b1 - 0x18 ) R8( 2, b0 - 0xf8 ) return; // TSET b,g + case 0xa8: case 0xa9: case 0xaa: case 0xab: case 0xac: case 0xad: case 0xae: case 0xaf: + OP( BIT,4 ) BIT8( 1, b1 - 0xa8 ) R8( 2, b0 - 0xf8 ) return; // BIT b,g + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + OP( RES,4 ) BIT8( 1, b1 - 0xb0 ) R8( 2, b0 - 0xf8 ) return; // RES b,g + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + OP( SET,4 ) BIT8( 1, b1 - 0xb8 ) R8( 2, b0 - 0xf8 ) return; // SET b,g + + case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7: + case 0xd8: case 0xd9: case 0xda: case 0xdb: case 0xdc: case 0xdd: case 0xde: case 0xdf: + if (b0 == 0xfe) { + OPCC( RET,6,14 ) CC( 1, b1 - 0xd0 ) NONE( 2 ) return; // RET cc + } + } break; + + case 0xff: + OP( SWI,20 ) NONE( 1 ) NONE( 2 ) return; // SWI + } + + OP( UNKNOWN,2 ) NONE( 1 ) NONE( 2 ) +} + +bool tlcs90_disassembler::stream_arg(std::ostream &stream, uint32_t pc, const char *pre, const e_mode mode, const uint16_t r, const uint16_t rb) +{ + const char *reg_name; + switch ( mode ) + { + case e_mode::NONE: return false; + + case e_mode::BIT8: util::stream_format(stream, "%s%d", pre, r ); return true; + case e_mode::I8: util::stream_format(stream, "%s$%02X", pre, r ); return true; + case e_mode::D8: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7f)-(r&0x80))&0xffff ); return true; + case e_mode::I16: util::stream_format(stream, "%s$%04X", pre, r ); return true; + case e_mode::D16: util::stream_format(stream, "%s$%04X", pre, (pc+2+(r&0x7fff)-(r&0x8000))&0xffff ); return true; + case e_mode::MI16: + reg_name = internal_registers_names(r); + if (reg_name) + util::stream_format(stream, "%s(%s)", pre, reg_name); + else + util::stream_format(stream, "%s($%04X)", pre, r ); + return true; + case e_mode::R8: util::stream_format(stream, "%s%s", pre, r8_names[r] ); return true; + case e_mode::R16: util::stream_format(stream, "%s%s", pre, r16_names[r] ); return true; + case e_mode::MR16: util::stream_format(stream, "%s(%s)", pre, r16_names[r] ); return true; + + case e_mode::MR16R8: util::stream_format(stream, "%s(%s+%s)", pre, r16_names[r], r8_names[rb] ); return true; + case e_mode::MR16D8: util::stream_format(stream, "%s(%s%c$%02X)", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true; + + case e_mode::CC: util::stream_format(stream, "%s%s", pre, cc_names[r] ); return true; + + case e_mode::R16R8: util::stream_format(stream, "%s%s+%s", pre, r16_names[r], r8_names[rb] ); return true; + case e_mode::R16D8: util::stream_format(stream, "%s%s%c$%02X", pre, r16_names[r], (rb&0x80)?'-':'+', (rb&0x80)?((rb^0xff)+1):rb ); return true; + + default: + fatalerror("%04x: unimplemented addr mode = %d\n",pc,std::underlying_type_t<e_mode>(mode)); + } + + // never executed + return false; +} + +offs_t tlcs90_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + m_addr = pc; + m_opcodes = &opcodes; + + decode(); + + util::stream_format (stream, "%-5s", op_names[ m_op ] ); // strlen("callr") == 5 + bool streamed = stream_arg (stream, pc, " ", m_mode1, m_r1, m_r1b ); + stream_arg (stream, pc, streamed ?",":"", m_mode2, m_r2, m_r2b ); + + return (m_addr - pc) | SUPPORTED; +} diff --git a/src/devices/cpu/tlcs90/tlcs90d.h b/src/devices/cpu/tlcs90/tlcs90d.h new file mode 100644 index 00000000000..8db7509512c --- /dev/null +++ b/src/devices/cpu/tlcs90/tlcs90d.h @@ -0,0 +1,65 @@ +// license:BSD-3-Clause +// copyright-holders:Luca Elia +/************************************************************************************************************* + + Toshiba TLCS-90 Series MCU's + + emulation by Luca Elia, based on the Z80 core by Juergen Buchmueller + + ChangeLog: + + 20150517 Fixed TRUN bit masking (timers start/stop handling) [Rainer Keuchel] + +*************************************************************************************************************/ + +#ifndef MAME_CPU_TLCS90_TLCS90D_H +#define MAME_CPU_TLCS90_TLCS90D_H + +#pragma once + +class tlcs90_disassembler : public util::disasm_interface +{ +public: + tlcs90_disassembler() = default; + virtual ~tlcs90_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum _e_op { UNKNOWN, NOP, EX, EXX, LD, LDW, LDA, LDI, LDIR, LDD, LDDR, CPI, CPIR, CPD, CPDR, PUSH, POP, JP, JR, CALL, CALLR, RET, RETI, HALT, DI, EI, SWI, DAA, CPL, NEG, LDAR, RCF, SCF, CCF, TSET, BIT, SET, RES, INC, DEC, INCX, DECX, INCW, DECW, ADD, ADC, SUB, SBC, AND, XOR, OR, CP, RLC, RRC, RL, RR, SLA, SRA, SLL, SRL, RLD, RRD, DJNZ, MUL, DIV }; + + enum class e_mode : u8 { + NONE, BIT8, CC, + I8, D8, R8, + I16, D16, R16, + MI16, MR16, MR16D8, MR16R8, + R16D8, R16R8 + }; + + static const char *const op_names[]; + static const char *const r8_names[]; + static const char *const r16_names[]; + static const char *const cc_names[]; + static const char *const ir_names[]; + + uint8_t m_op; + + e_mode m_mode1; + uint16_t m_r1,m_r1b; + + e_mode m_mode2; + uint16_t m_r2,m_r2b; + + offs_t m_addr; + const data_buffer *m_opcodes; + + inline uint8_t READ8(); + inline uint16_t READ16(); + void decode(); + + bool stream_arg(std::ostream &stream, uint32_t pc, const char *pre, const e_mode mode, const uint16_t r, const uint16_t rb); + const char *internal_registers_names(uint16_t x); +}; + +#endif diff --git a/src/devices/cpu/tlcs900/dasm900.cpp b/src/devices/cpu/tlcs900/dasm900.cpp index 64c8c6ba099..b700bf6341a 100644 --- a/src/devices/cpu/tlcs900/dasm900.cpp +++ b/src/devices/cpu/tlcs900/dasm900.cpp @@ -7,36 +7,9 @@ Toshiba TLCS-900/H disassembly *******************************************************************/ #include "emu.h" -#include "debugger.h" -#include "tlcs900.h" +#include "dasm900.h" -enum e_mnemonics -{ - M_ADC, M_ADD, M_AND, M_ANDCF, M_BIT, M_BS1B, - M_BS1F, M_CALL, M_CALR, M_CCF, M_CHG, M_CP, - M_CPD, M_CPDW, M_CPDR, M_CPDRW, M_CPI, M_CPIR, - M_CPIRW, M_CPIW, M_CPL, M_DAA, M_DB, M_DEC, - M_DECF, M_DECW, M_DIV, M_DIVS, M_DJNZ, M_EI, - M_EX, M_EXTS, M_EXTZ, M_HALT, M_INC, M_INCF, - M_INCW, M_JP, M_JR, M_JRL, M_LD, M_LDA, - M_LDC, M_LDCF, M_LDD, M_LDDR, M_LDDRW, M_LDDW, - M_LDF, M_LDI, M_LDIR, M_LDIRW, M_LDIW, M_LDW, - M_LDX, M_LINK, M_MAX, M_MDEC1, M_MDEC2, M_MDEC4, - M_MINC1, M_MINC2, M_MINC4, M_MIRR, M_MUL, M_MULA, - M_MULS, M_NEG, M_NOP, M_NORMAL, M_OR, M_ORCF, - M_PAA, M_POP, M_POPW, M_PUSH, M_PUSHW, M_RCF, - M_RES, M_RET, M_RETD, M_RETI, M_RL, M_RLC, - M_RLCW, M_RLD, M_RLW, M_RR, M_RRC, M_RRCW, - M_RRD, M_RRW, M_SBC, M_SCC, M_SCF, M_SET, - M_SLA, M_SLAW, M_SLL, M_SLLW, M_SRA, M_SRAW, - M_SRL, M_SRLW, M_STCF, M_SUB, M_SWI, M_TSET, - M_UNLK, M_XOR, M_XORCF, M_ZCF, - M_80, M_88, M_90, M_98, M_A0, M_A8, M_B0, M_B8, - M_C0, oC8, M_D0, oD8, M_E0, M_E8, M_F0 -}; - - -static const char *const s_mnemonic[] = +const char *const tlcs900_disassembler::s_mnemonic[] = { "adc", "add", "and", "andcf", "bit", "bs1b", "bs1f", "call", "calr", "ccf", "chg", "cp", @@ -62,43 +35,7 @@ static const char *const s_mnemonic[] = }; -enum e_operand -{ - O_NONE, - O_A, /* current register set register A */ - O_C8, /* current register set byte */ - O_C16, /* current register set word */ - O_C32, /* current register set long word */ - O_MC16, /* current register set mul/div register word */ - O_CC, /* condition */ - O_CR8, /* byte control register */ - O_CR16, /* word control register */ - O_CR32, /* long word control register */ - O_D8, /* byte displacement */ - O_D16, /* word displacement */ - O_F, /* F register */ - O_I3, /* immediate 3 bit (part of last byte) */ - O_I8, /* immediate byte */ - O_I16, /* immediate word */ - O_I24, /* immediate 3 byte address */ - O_I32, /* immediate long word */ - O_M, /* memory location (defined by extension) */ - O_M8, /* (8) */ - O_M16, /* (i16) */ - O_R, /* register */ - O_SR /* status register */ -}; - - -struct tlcs900inst -{ - e_mnemonics mnemonic; - e_operand operand1; - e_operand operand2; -}; - - -static const tlcs900inst mnemonic_80[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_80[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -182,7 +119,7 @@ static const tlcs900inst mnemonic_80[256] = }; -static const tlcs900inst mnemonic_88[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_88[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -266,7 +203,7 @@ static const tlcs900inst mnemonic_88[256] = }; -static const tlcs900inst mnemonic_90[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_90[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -350,7 +287,7 @@ static const tlcs900inst mnemonic_90[256] = }; -static const tlcs900inst mnemonic_98[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_98[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -434,7 +371,7 @@ static const tlcs900inst mnemonic_98[256] = }; -static const tlcs900inst mnemonic_a0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_a0[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -518,7 +455,7 @@ static const tlcs900inst mnemonic_a0[256] = }; -static const tlcs900inst mnemonic_b0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_b0[256] = { /* 00 - 1F */ { M_LD, O_M, O_I8 }, { M_DB, O_NONE, O_NONE }, { M_LD, O_M, O_I16 }, { M_DB, O_NONE, O_NONE }, @@ -602,7 +539,7 @@ static const tlcs900inst mnemonic_b0[256] = }; -static const tlcs900inst mnemonic_b8[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_b8[256] = { /* 00 - 1F */ { M_LD, O_M, O_I8 }, { M_DB, O_NONE, O_NONE }, { M_LD, O_M, O_I16 }, { M_DB, O_NONE, O_NONE }, @@ -686,7 +623,7 @@ static const tlcs900inst mnemonic_b8[256] = }; -static const tlcs900inst mnemonic_c0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_c0[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -771,7 +708,7 @@ static const tlcs900inst mnemonic_c0[256] = /* TODO: M_MUL_O_I8, M_MULS_O_I8, M_DIV_O_I8, M_DIVS_O_i8 need to be fixed */ -static const tlcs900inst mnemonic_c8[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_c8[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_LD, O_R, O_I8 }, @@ -855,7 +792,7 @@ static const tlcs900inst mnemonic_c8[256] = }; -static const tlcs900inst mnemonic_d0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_d0[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -939,7 +876,7 @@ static const tlcs900inst mnemonic_d0[256] = }; -static const tlcs900inst mnemonic_d8[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_d8[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_LD, O_R, O_I16 }, @@ -1023,7 +960,7 @@ static const tlcs900inst mnemonic_d8[256] = }; -static const tlcs900inst mnemonic_e0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_e0[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, @@ -1107,7 +1044,7 @@ static const tlcs900inst mnemonic_e0[256] = }; -static const tlcs900inst mnemonic_e8[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_e8[256] = { /* 00 - 1F */ { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_DB, O_NONE, O_NONE }, { M_LD, O_R, O_I32 }, @@ -1191,7 +1128,7 @@ static const tlcs900inst mnemonic_e8[256] = }; -static const tlcs900inst mnemonic_f0[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic_f0[256] = { /* 00 - 1F */ { M_LD, O_M, O_I8 }, { M_DB, O_NONE, O_NONE }, { M_LD, O_M, O_I16 }, { M_DB, O_NONE, O_NONE }, @@ -1275,7 +1212,7 @@ static const tlcs900inst mnemonic_f0[256] = }; -static const tlcs900inst mnemonic[256] = +const tlcs900_disassembler::tlcs900inst tlcs900_disassembler::mnemonic[256] = { /* 00 - 1F */ { M_NOP, O_NONE, O_NONE }, { M_NORMAL, O_NONE, O_NONE }, { M_PUSH, O_SR, O_NONE }, { M_POP, O_SR, O_NONE }, @@ -1360,11 +1297,11 @@ static const tlcs900inst mnemonic[256] = -static const char *const s_reg8[8] = { "W", "A", "B", "C", "D", "E", "H", "L" }; -static const char *const s_reg16[8] = { "WA", "BC", "DE", "HL", "IX", "IY", "IZ", "SP" }; -static const char *const s_reg32[8] = { "XWA", "XBC", "XDE", "XHL", "XIX", "XIY", "XIZ", "XSP" }; -static const char *const s_mulreg16[8] = { "??", "WA", "??", "BC", "??", "DE", "??", "HL" }; -static const char *const s_allreg8[256] = +const char *const tlcs900_disassembler::s_reg8[8] = { "W", "A", "B", "C", "D", "E", "H", "L" }; +const char *const tlcs900_disassembler::s_reg16[8] = { "WA", "BC", "DE", "HL", "IX", "IY", "IZ", "SP" }; +const char *const tlcs900_disassembler::s_reg32[8] = { "XWA", "XBC", "XDE", "XHL", "XIX", "XIY", "XIZ", "XSP" }; +const char *const tlcs900_disassembler::s_mulreg16[8] = { "??", "WA", "??", "BC", "??", "DE", "??", "HL" }; +const char *const tlcs900_disassembler::s_allreg8[256] = { "RA0" ,"RW0" ,"QA0" ,"QW0" ,"RC0" ,"RB0" ,"QC0" ,"QB0" ,"RE0" ,"RD0" ,"QE0" ,"QD0" ,"RL0" ,"RH0" ,"QL0" ,"QH0" , "RA1" ,"RW1" ,"QA1" ,"QW1" ,"RC1" ,"RB1" ,"QC1" ,"QB1" ,"RE1" ,"RD1" ,"QE1" ,"QD1" ,"RL1" ,"RH1" ,"QL1" ,"QH1" , @@ -1385,7 +1322,7 @@ static const char *const s_allreg8[256] = }; -static const char *const s_allreg16[256] = +const char *const tlcs900_disassembler::s_allreg16[256] = { "RWA0","r01W","QWA0","r03W","RBC0","r05W","QBC0","r07W","RDE0","r09W","QDE0","r0BW","RHL0","r0DW","QHL0","r0FW", "RWA1","r11W","QWA1","r13W","RBC1","r15W","QBC1","r17W","RDE1","r19W","QDE1","r1BW","RHL1","r1DW","QHL1","r1FW", @@ -1406,7 +1343,7 @@ static const char *const s_allreg16[256] = }; -static const char *const s_allreg32[256] = +const char *const tlcs900_disassembler::s_allreg32[256] = { "XWA0","XWA0","XWA0","r03L","XBC0","XBC0","XBC0","r07L","XDE0","XDE0","XDE0","r0BL","XHL0","XHL0","XHL0","r0FL", "XWA1","XWA1","XWA1","r13L","XBC1","XBC1","XBC1","r17L","XDE1","XDE1","XDE1","r1BL","XHL1","XHL1","XHL1","r1FL", @@ -1427,22 +1364,27 @@ static const char *const s_allreg32[256] = }; -static const char *const s_cond[16] = +const char *const tlcs900_disassembler::s_cond[16] = { "F","LT","LE","ULE","PE/OV","M/MI","Z","C","T","GE","GT","UGT","PO/NOV","P/PL","NZ","NC" }; -CPU_DISASSEMBLE(tlcs900) +u32 tlcs900_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tlcs900_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const tlcs900inst *dasm; std::string buf; uint8_t op, op1; uint32_t imm; int flags = 0; - int pos = 0; + offs_t pos = pc; - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic[ op ]; @@ -1454,53 +1396,53 @@ CPU_DISASSEMBLE(tlcs900) case M_80: buf = string_format("%s", s_reg32[op & 0x07]); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_80[ op ]; break; case M_88: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+0x%02x", s_reg32[op & 0x07], imm); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_88[ op ]; break; case M_90: buf = string_format("%s", s_reg32[op & 0x07]); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_90[ op ]; break; case M_98: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+0x%02x", s_reg32[op & 0x07], imm); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_98[ op ]; break; case M_A0: buf = string_format("%s", s_reg32[op & 0x07]); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_a0[ op ]; break; case M_A8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+0x%02x", s_reg32[op & 0x07], imm); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_a0[ op ]; break; case M_B0: buf = string_format("%s", s_reg32[op & 0x07]); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_b0[ op ]; break; case M_B8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+0x%02x", s_reg32[op & 0x07], imm); - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_b8[ op ]; break; @@ -1508,25 +1450,25 @@ CPU_DISASSEMBLE(tlcs900) switch( op & 0x07 ) { case 0x00: /* 0xC0 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("0x%02x", imm); break; case 0x01: /* 0xC1 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%04x", imm); break; case 0x02: /* 0xC2 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); buf = string_format("0x%06x", imm); break; case 0x03: /* 0xC3 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm & 0x03 ) { case 0x00: @@ -1535,8 +1477,8 @@ CPU_DISASSEMBLE(tlcs900) case 0x01: op = imm; - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("%s+0x%04x", s_allreg32[op], imm); break; @@ -1548,20 +1490,20 @@ CPU_DISASSEMBLE(tlcs900) switch( imm ) { case 0x03: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg8[op1]); break; case 0x07: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg16[op1]); break; case 0x13: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%06x", pc + pos + (int16_t)imm); break; } @@ -1570,16 +1512,16 @@ CPU_DISASSEMBLE(tlcs900) break; case 0x04: /* 0xC4 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("-%s", s_allreg32[imm]); break; case 0x05: /* 0xC5 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+", s_allreg32[imm]); break; } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_c0[ op ]; break; @@ -1590,10 +1532,10 @@ CPU_DISASSEMBLE(tlcs900) } else { - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s", s_allreg8[imm]); } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_c8[ op ]; break; @@ -1601,25 +1543,25 @@ CPU_DISASSEMBLE(tlcs900) switch( op & 0x07 ) { case 0x00: /* 0xD0 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("0x%02x", imm); break; case 0x01: /* 0xD1 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%04x", imm); break; case 0x02: /* 0xD2 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); buf = string_format("0x%06x", imm); break; case 0x03: /* 0xD3 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm & 0x03 ) { case 0x00: @@ -1628,8 +1570,8 @@ CPU_DISASSEMBLE(tlcs900) case 0x01: op = imm; - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("%s+0x%04x", s_allreg32[op], imm); break; @@ -1641,20 +1583,20 @@ CPU_DISASSEMBLE(tlcs900) switch( imm ) { case 0x03: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg8[op1]); break; case 0x07: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg16[op1]); break; case 0x13: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%06x", pc + pos + (int16_t)imm); break; } @@ -1663,16 +1605,16 @@ CPU_DISASSEMBLE(tlcs900) break; case 0x04: /* 0xD4 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("-%s", s_allreg32[imm]); break; case 0x05: /* 0xD5 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+", s_allreg32[imm]); break; } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_d0[ op ]; break; @@ -1683,11 +1625,11 @@ CPU_DISASSEMBLE(tlcs900) } else { - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s", s_allreg16[imm]); } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_d8[ op ]; break; @@ -1695,25 +1637,25 @@ CPU_DISASSEMBLE(tlcs900) switch( op & 0x07 ) { case 0x00: /* 0xE0 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("0x%02x", imm); break; case 0x01: /* 0xE1 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%04x", imm); break; case 0x02: /* 0xE2 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); buf = string_format("0x%06x", imm); break; case 0x03: /* 0xE3 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm & 0x03 ) { case 0x00: @@ -1722,8 +1664,8 @@ CPU_DISASSEMBLE(tlcs900) case 0x01: op = imm; - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("%s+0x%04x", s_allreg32[op], imm); break; @@ -1735,20 +1677,20 @@ CPU_DISASSEMBLE(tlcs900) switch( imm ) { case 0x03: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg8[op1]); break; case 0x07: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg16[op1]); break; case 0x13: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%06x", pc + pos + (int16_t)imm); break; } @@ -1757,16 +1699,16 @@ CPU_DISASSEMBLE(tlcs900) break; case 0x04: /* 0xE4 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("-%s", s_allreg32[imm]); break; case 0x05: /* 0xE5 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+", s_allreg32[imm]); break; } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_e0[ op ]; break; @@ -1777,10 +1719,10 @@ CPU_DISASSEMBLE(tlcs900) } else { - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s", s_allreg32[imm]); } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_e8[ op ]; break; @@ -1788,25 +1730,25 @@ CPU_DISASSEMBLE(tlcs900) switch( op & 0x07 ) { case 0x00: /* 0xF0 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("0x%02x", imm); break; case 0x01: /* 0xF1 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%04x", imm); break; case 0x02: /* 0xF2 */ - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); buf = string_format("0x%06x", imm); break; case 0x03: /* 0xF3 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm & 0x03 ) { case 0x00: @@ -1815,8 +1757,8 @@ CPU_DISASSEMBLE(tlcs900) case 0x01: op = imm; - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("%s+0x%04x", s_allreg32[op], imm); break; @@ -1828,20 +1770,20 @@ CPU_DISASSEMBLE(tlcs900) switch( imm ) { case 0x03: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg8[op1]); break; case 0x07: - op = oprom[ pos++ ]; - op1 = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); + op1 = opcodes.r8( pos++ ); buf = string_format("%s+%s", s_allreg32[op], s_allreg16[op1]); break; case 0x13: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); buf = string_format("0x%06x", pc + pos + (int16_t)imm); break; } @@ -1850,16 +1792,16 @@ CPU_DISASSEMBLE(tlcs900) break; case 0x04: /* 0xF4 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("-%s", s_allreg32[imm]); break; case 0x05: /* 0xF5 */ - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); buf = string_format("%s+", s_allreg32[imm]); break; } - op = oprom[ pos++ ]; + op = opcodes.r8( pos++ ); dasm = &mnemonic_f0[ op ]; break; } @@ -1873,12 +1815,12 @@ CPU_DISASSEMBLE(tlcs900) break; case M_CALL: case M_CALR: - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case M_RET: case M_RETD: case M_RETI: - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; } @@ -1912,7 +1854,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x22: @@ -1934,7 +1876,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR16: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x20: @@ -1956,7 +1898,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR32: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x00: @@ -1990,13 +1932,13 @@ CPU_DISASSEMBLE(tlcs900) break; case O_D8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, " 0x%06x", ( pc + pos + (int8_t)imm ) & 0xFFFFFF); break; case O_D16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, " 0x%06x", ( pc + pos + (int16_t)imm ) & 0xFFFFFF); break; @@ -2009,28 +1951,28 @@ CPU_DISASSEMBLE(tlcs900) break; case O_I8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, " 0x%02x", imm); break; case O_I16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, " 0x%04x", imm); break; case O_I24: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); util::stream_format(stream, " 0x%06x", imm); break; case O_I32: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); - imm = imm | (oprom[ pos++ ] << 24); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); + imm = imm | (opcodes.r8( pos++ ) << 24); util::stream_format(stream, "0x%08x", imm); break; @@ -2049,13 +1991,13 @@ CPU_DISASSEMBLE(tlcs900) break; case O_M8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, " (0x%02x)", imm); break; case O_M16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, " (0x%04x)", imm); break; @@ -2098,7 +2040,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x22: @@ -2120,7 +2062,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR16: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x20: @@ -2142,7 +2084,7 @@ CPU_DISASSEMBLE(tlcs900) break; case O_CR32: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); switch( imm ) { case 0x00: @@ -2176,13 +2118,13 @@ CPU_DISASSEMBLE(tlcs900) break; case O_D8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, ",0x%06x", ( pc + pos + (int8_t)imm ) & 0xFFFFFF); break; case O_D16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, ",0x%06x", ( pc + pos + (int16_t)imm ) & 0xFFFFFF); break; @@ -2195,28 +2137,28 @@ CPU_DISASSEMBLE(tlcs900) break; case O_I8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, ",0x%02x", imm); break; case O_I16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, ",0x%04x", imm); break; case O_I24: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); util::stream_format(stream, ",0x%06x", imm); break; case O_I32: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); - imm = imm | (oprom[ pos++ ] << 16); - imm = imm | (oprom[ pos++ ] << 24); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); + imm = imm | (opcodes.r8( pos++ ) << 16); + imm = imm | (opcodes.r8( pos++ ) << 24); util::stream_format(stream, ",0x%08x", imm); break; @@ -2235,13 +2177,13 @@ CPU_DISASSEMBLE(tlcs900) break; case O_M8: - imm = oprom[ pos++ ]; + imm = opcodes.r8( pos++ ); util::stream_format(stream, ",(0x%02x)", imm); break; case O_M16: - imm = oprom[ pos++ ]; - imm = imm | (oprom[ pos++ ] << 8); + imm = opcodes.r8( pos++ ); + imm = imm | (opcodes.r8( pos++ ) << 8); util::stream_format(stream, ",(0x%04x)", imm); break; @@ -2254,5 +2196,5 @@ CPU_DISASSEMBLE(tlcs900) break; } - return pos | flags | DASMFLAG_SUPPORTED; + return (pos - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/tlcs900/dasm900.h b/src/devices/cpu/tlcs900/dasm900.h new file mode 100644 index 00000000000..8fb067a299a --- /dev/null +++ b/src/devices/cpu/tlcs900/dasm900.h @@ -0,0 +1,111 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/******************************************************************* + +Toshiba TLCS-900/H disassembly + +*******************************************************************/ + +#ifndef MAME_CPU_TLCS900_DASM900_H +#define MAME_CPU_TLCS900_DASM900_H + +#pragma once + +class tlcs900_disassembler : public util::disasm_interface +{ +public: + tlcs900_disassembler() = default; + virtual ~tlcs900_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + M_ADC, M_ADD, M_AND, M_ANDCF, M_BIT, M_BS1B, + M_BS1F, M_CALL, M_CALR, M_CCF, M_CHG, M_CP, + M_CPD, M_CPDW, M_CPDR, M_CPDRW, M_CPI, M_CPIR, + M_CPIRW, M_CPIW, M_CPL, M_DAA, M_DB, M_DEC, + M_DECF, M_DECW, M_DIV, M_DIVS, M_DJNZ, M_EI, + M_EX, M_EXTS, M_EXTZ, M_HALT, M_INC, M_INCF, + M_INCW, M_JP, M_JR, M_JRL, M_LD, M_LDA, + M_LDC, M_LDCF, M_LDD, M_LDDR, M_LDDRW, M_LDDW, + M_LDF, M_LDI, M_LDIR, M_LDIRW, M_LDIW, M_LDW, + M_LDX, M_LINK, M_MAX, M_MDEC1, M_MDEC2, M_MDEC4, + M_MINC1, M_MINC2, M_MINC4, M_MIRR, M_MUL, M_MULA, + M_MULS, M_NEG, M_NOP, M_NORMAL, M_OR, M_ORCF, + M_PAA, M_POP, M_POPW, M_PUSH, M_PUSHW, M_RCF, + M_RES, M_RET, M_RETD, M_RETI, M_RL, M_RLC, + M_RLCW, M_RLD, M_RLW, M_RR, M_RRC, M_RRCW, + M_RRD, M_RRW, M_SBC, M_SCC, M_SCF, M_SET, + M_SLA, M_SLAW, M_SLL, M_SLLW, M_SRA, M_SRAW, + M_SRL, M_SRLW, M_STCF, M_SUB, M_SWI, M_TSET, + M_UNLK, M_XOR, M_XORCF, M_ZCF, + M_80, M_88, M_90, M_98, M_A0, M_A8, M_B0, M_B8, + M_C0, oC8, M_D0, oD8, M_E0, M_E8, M_F0 + }; + + enum e_operand + { + O_NONE, + O_A, /* current register set register A */ + O_C8, /* current register set byte */ + O_C16, /* current register set word */ + O_C32, /* current register set long word */ + O_MC16, /* current register set mul/div register word */ + O_CC, /* condition */ + O_CR8, /* byte control register */ + O_CR16, /* word control register */ + O_CR32, /* long word control register */ + O_D8, /* byte displacement */ + O_D16, /* word displacement */ + O_F, /* F register */ + O_I3, /* immediate 3 bit (part of last byte) */ + O_I8, /* immediate byte */ + O_I16, /* immediate word */ + O_I24, /* immediate 3 byte address */ + O_I32, /* immediate long word */ + O_M, /* memory location (defined by extension) */ + O_M8, /* (8) */ + O_M16, /* (i16) */ + O_R, /* register */ + O_SR /* status register */ + }; + + struct tlcs900inst + { + e_mnemonics mnemonic; + e_operand operand1; + e_operand operand2; + }; + + static const char *const s_mnemonic[]; + static const tlcs900inst mnemonic_80[256]; + static const tlcs900inst mnemonic_88[256]; + static const tlcs900inst mnemonic_90[256]; + static const tlcs900inst mnemonic_98[256]; + static const tlcs900inst mnemonic_a0[256]; + static const tlcs900inst mnemonic_b0[256]; + static const tlcs900inst mnemonic_b8[256]; + static const tlcs900inst mnemonic_c0[256]; + static const tlcs900inst mnemonic_c8[256]; + static const tlcs900inst mnemonic_d0[256]; + static const tlcs900inst mnemonic_d8[256]; + static const tlcs900inst mnemonic_e0[256]; + static const tlcs900inst mnemonic_e8[256]; + static const tlcs900inst mnemonic_f0[256]; + static const tlcs900inst mnemonic[256]; + + static const char *const s_reg8[8]; + static const char *const s_reg16[8]; + static const char *const s_reg32[8]; + static const char *const s_mulreg16[8]; + static const char *const s_allreg8[256]; + static const char *const s_allreg16[256]; + static const char *const s_allreg32[256]; + static const char *const s_cond[16]; + +}; + +#endif diff --git a/src/devices/cpu/tlcs900/tlcs900.cpp b/src/devices/cpu/tlcs900/tlcs900.cpp index 69eef7121e0..26e1678078d 100644 --- a/src/devices/cpu/tlcs900/tlcs900.cpp +++ b/src/devices/cpu/tlcs900/tlcs900.cpp @@ -17,6 +17,7 @@ TODO: #include "emu.h" #include "tlcs900.h" +#include "dasm900.h" #include "debugger.h" @@ -148,10 +149,9 @@ void tmp95c063_device::device_config_complete() } -offs_t tlcs900h_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tlcs900h_device::create_disassembler() { - extern CPU_DISASSEMBLE( tlcs900 ); - return CPU_DISASSEMBLE_NAME(tlcs900)(this, stream, pc, oprom, opram, options); + return new tlcs900_disassembler; } diff --git a/src/devices/cpu/tlcs900/tlcs900.h b/src/devices/cpu/tlcs900/tlcs900.h index 28552bd3c17..0fbedad0f23 100644 --- a/src/devices/cpu/tlcs900/tlcs900.h +++ b/src/devices/cpu/tlcs900/tlcs900.h @@ -72,9 +72,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 7; } /* FIXME */ - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; protected: int m_am8_16; diff --git a/src/devices/cpu/tms1000/tms0270.cpp b/src/devices/cpu/tms1000/tms0270.cpp index 3e66a4cf9bd..1db3bab8da2 100644 --- a/src/devices/cpu/tms1000/tms0270.cpp +++ b/src/devices/cpu/tms1000/tms0270.cpp @@ -23,7 +23,7 @@ DEFINE_DEVICE_TYPE(TMS0270, tms0270_cpu_device, "tms0270", "TMS0270") // 40-pin // internal memory maps static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device) - AM_RANGE(0x000, 0xfff) AM_ROM + AM_RANGE(0x000, 0x7ff) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START(data_144x4, AS_DATA, 8, tms1k_base_device) @@ -34,7 +34,7 @@ ADDRESS_MAP_END // device definitions tms0270_cpu_device::tms0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : tms0980_cpu_device(mconfig, TMS0270, tag, owner, clock, 16 /* o pins */, 16 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4)) + : tms0980_cpu_device(mconfig, TMS0270, tag, owner, clock, 16 /* o pins */, 16 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 11 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4)) , m_read_ctl(*this) , m_write_ctl(*this) , m_write_pdc(*this) diff --git a/src/devices/cpu/tms1000/tms0980.cpp b/src/devices/cpu/tms1000/tms0980.cpp index 3059ff7b1d1..622d8ca5be4 100644 --- a/src/devices/cpu/tms1000/tms0980.cpp +++ b/src/devices/cpu/tms1000/tms0980.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "tms0980.h" +#include "tms1k_dasm.h" #include "debugger.h" // TMS0980 @@ -31,7 +32,7 @@ DEFINE_DEVICE_TYPE(TMS1980, tms1980_cpu_device, "tms1980", "TMS1980") // 28-pin // internal memory maps static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device) - AM_RANGE(0x000, 0xfff) AM_ROM + AM_RANGE(0x000, 0x7ff) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START(data_144x4, AS_DATA, 8, tms1k_base_device) @@ -42,7 +43,7 @@ ADDRESS_MAP_END // device definitions tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : tms0980_cpu_device(mconfig, TMS0980, tag, owner, clock, 8 /* o pins */, 9 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4)) + : tms0980_cpu_device(mconfig, TMS0980, tag, owner, clock, 8 /* o pins */, 9 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 11 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_144x4)) { } @@ -52,7 +53,7 @@ tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, device_typ } tms1980_cpu_device::tms1980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : tms0980_cpu_device(mconfig, TMS1980, tag, owner, clock, 7, 10, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_144x4)) + : tms0980_cpu_device(mconfig, TMS1980, tag, owner, clock, 7, 10, 7, 9, 4, 11, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_144x4)) { } @@ -84,10 +85,9 @@ MACHINE_CONFIG_END // disasm -offs_t tms0980_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *tms0980_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(tms0980); - return CPU_DISASSEMBLE_NAME(tms0980)(this, stream, pc, oprom, opram, options); + return new tms0980_disassembler; } @@ -173,8 +173,8 @@ u32 tms0980_cpu_device::read_micro() void tms0980_cpu_device::read_opcode() { - debugger_instruction_hook(this, m_rom_address << 1); - m_opcode = m_program->read_word(m_rom_address << 1) & 0x1ff; + debugger_instruction_hook(this, m_rom_address); + m_opcode = m_program->read_word(m_rom_address) & 0x1ff; m_c4 = BITSWAP8(m_opcode,7,6,5,4,0,1,2,3) & 0xf; // opcode operand is bitswapped for most opcodes m_fixed = m_fixed_decode[m_opcode]; diff --git a/src/devices/cpu/tms1000/tms0980.h b/src/devices/cpu/tms1000/tms0980.h index c258eadc12b..2a4fa810008 100644 --- a/src/devices/cpu/tms1000/tms0980.h +++ b/src/devices/cpu/tms1000/tms0980.h @@ -29,9 +29,7 @@ protected: virtual void device_add_mconfig(machine_config &config) override; - virtual u32 disasm_min_opcode_bytes() const override { return 2; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual u8 read_k_input() override; virtual void set_cki_bus() override; diff --git a/src/devices/cpu/tms1000/tms1000.cpp b/src/devices/cpu/tms1000/tms1000.cpp index 55ac2a01d8c..ce21213a1d2 100644 --- a/src/devices/cpu/tms1000/tms1000.cpp +++ b/src/devices/cpu/tms1000/tms1000.cpp @@ -2,17 +2,19 @@ // copyright-holders:hap /* - TMS1000 family - TMS1000, TMS1070, TMS1040, TMS1200, TMS1700, TMS1730, + TMS1000 family - TMS1000, TMS1000C, TMS1070, TMS1040, TMS1200, TMS1700, TMS1730, and second source Motorola MC141000, MC141200. TODO: - add TMS1270 (10 O pins, how does that work?) - - add TMS1000C, TMS1200C (CMOS, and 3-level stack) + - add TMS1200C (has L input pins like TMS1600) + - add TMS1000C-specific mpla */ #include "emu.h" #include "tms1000.h" +#include "tms1k_dasm.h" #include "debugger.h" // TMS1000 @@ -31,6 +33,17 @@ DEFINE_DEVICE_TYPE(TMS1200, tms1200_cpu_device, "tms1200", "TMS1200") // 40-p DEFINE_DEVICE_TYPE(TMS1700, tms1700_cpu_device, "tms1700", "TMS1700") // 28-pin DIP, RAM/ROM size halved, 9 R pins DEFINE_DEVICE_TYPE(TMS1730, tms1730_cpu_device, "tms1730", "TMS1730") // 20-pin DIP, same die as TMS1700, package has less pins: 6 R pins, 5 O pins (output PLA is still 8-bit, O1,O3,O5 unused) +// CMOS versions (3-level stack, HALT pin) +// - RAM at top-left, ROM at top-right(rotate CCW) +// - ROM ordering is different: +// * row select is linear (0-63) +// * bit select is 7-0 instead of 0-7 +// * page select doesn't flip in the middle +// - 32-term mpla at bottom-right, different order +// - 32-term opla at bottom-left, ordered O7-O0(0 or 1), and A8,4,2,1,S +DEFINE_DEVICE_TYPE(TMS1000C, tms1000c_cpu_device, "tms1000c", "TMS1000C") // 28-pin SDIP, 10 R pins + +// 2nd source Motorola chips DEFINE_DEVICE_TYPE(MC141000, mc141000_cpu_device, "mc141000", "MC141000") // CMOS, pin-compatible with TMS1000(reverse polarity) DEFINE_DEVICE_TYPE(MC141200, mc141200_cpu_device, "mc141200", "MC141200") // CMOS, 40-pin DIP, 16 R pins @@ -90,6 +103,11 @@ tms1730_cpu_device::tms1730_cpu_device(const machine_config &mconfig, const char { } +tms1000c_cpu_device::tms1000c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : tms1000_cpu_device(mconfig, TMS1000C, tag, owner, clock, 8, 10, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4)) +{ +} + mc141000_cpu_device::mc141000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : tms1000_cpu_device(mconfig, MC141000, tag, owner, clock, 8, 11, 6, 8, 2, 10, ADDRESS_MAP_NAME(program_10bit_8), 6, ADDRESS_MAP_NAME(data_64x4)) { @@ -102,7 +120,7 @@ mc141200_cpu_device::mc141200_cpu_device(const machine_config &mconfig, const ch // machine configs - MACHINE_CONFIG_MEMBER(tms1000_cpu_device::device_add_mconfig) +MACHINE_CONFIG_MEMBER(tms1000_cpu_device::device_add_mconfig) // microinstructions PLA, output PLA MCFG_PLA_ADD("mpla", 8, 16, 30) @@ -111,11 +129,21 @@ mc141200_cpu_device::mc141200_cpu_device(const machine_config &mconfig, const ch MCFG_PLA_FILEFORMAT(BERKELEY) MACHINE_CONFIG_END +MACHINE_CONFIG_MEMBER(tms1000c_cpu_device::device_add_mconfig) + + // microinstructions PLA, output PLA + //MCFG_PLA_ADD("mpla", 8, 16, 32) + MCFG_PLA_ADD("mpla", 8, 16, 30) + MCFG_PLA_FILEFORMAT(BERKELEY) + MCFG_PLA_ADD("opla", 5, 8, 32) + MCFG_PLA_FILEFORMAT(BERKELEY) +MACHINE_CONFIG_END + + // disasm -offs_t tms1000_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *tms1000_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(tms1000); - return CPU_DISASSEMBLE_NAME(tms1000)(this, stream, pc, oprom, opram, options); + return new tms1000_disassembler; } diff --git a/src/devices/cpu/tms1000/tms1000.h b/src/devices/cpu/tms1000/tms1000.h index ae85b7ed579..d5f53c890b6 100644 --- a/src/devices/cpu/tms1000/tms1000.h +++ b/src/devices/cpu/tms1000/tms1000.h @@ -26,8 +26,7 @@ protected: virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; - - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; }; class tms1070_cpu_device : public tms1000_cpu_device @@ -63,6 +62,21 @@ public: }; +class tms1000c_cpu_device : public tms1000_cpu_device +{ +public: + tms1000c_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual void op_br() override { op_br3(); } // 3-level stack + virtual void op_call() override { op_call3(); } // " + virtual void op_retn() override { op_retn3(); } // " +}; + + class mc141000_cpu_device : public tms1000_cpu_device { public: @@ -77,6 +91,7 @@ public: DECLARE_DEVICE_TYPE(TMS1000, tms1000_cpu_device) +DECLARE_DEVICE_TYPE(TMS1000C, tms1000c_cpu_device) DECLARE_DEVICE_TYPE(TMS1070, tms1070_cpu_device) DECLARE_DEVICE_TYPE(TMS1040, tms1040_cpu_device) DECLARE_DEVICE_TYPE(TMS1200, tms1200_cpu_device) diff --git a/src/devices/cpu/tms1000/tms1100.cpp b/src/devices/cpu/tms1000/tms1100.cpp index a67f1261512..8f329a3c725 100644 --- a/src/devices/cpu/tms1000/tms1100.cpp +++ b/src/devices/cpu/tms1000/tms1100.cpp @@ -4,10 +4,14 @@ TMS1000 family - TMS1100, TMS1170, TMS1300, TMS1370 + TODO: + - add TMS1100C when needed + */ #include "emu.h" #include "tms1100.h" +#include "tms1k_dasm.h" #include "debugger.h" // TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM @@ -55,13 +59,11 @@ tms1370_cpu_device::tms1370_cpu_device(const machine_config &mconfig, const char // disasm -offs_t tms1100_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *tms1100_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(tms1100); - return CPU_DISASSEMBLE_NAME(tms1100)(this, stream, pc, oprom, opram, options); + return new tms1100_disassembler; } - // device_reset void tms1100_cpu_device::device_reset() { diff --git a/src/devices/cpu/tms1000/tms1100.h b/src/devices/cpu/tms1000/tms1100.h index 26a3ffbc578..86a0028a3aa 100644 --- a/src/devices/cpu/tms1000/tms1100.h +++ b/src/devices/cpu/tms1000/tms1100.h @@ -25,7 +25,7 @@ protected: // overrides virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void op_setr() override; virtual void op_rstr() override; diff --git a/src/devices/cpu/tms1000/tms1400.cpp b/src/devices/cpu/tms1000/tms1400.cpp index 470136a16e5..4c392ec7599 100644 --- a/src/devices/cpu/tms1000/tms1400.cpp +++ b/src/devices/cpu/tms1000/tms1400.cpp @@ -88,58 +88,3 @@ void tms1400_cpu_device::device_reset() // small differences in 00-3f area m_fixed_decode[0x0b] = F_TPC; } - - -// opcode deviations -void tms1400_cpu_device::op_br() -{ - // BR/BL: conditional branch - if (m_status) - { - m_pa = m_pb; // don't care about clatch - m_ca = m_cb; - m_pc = m_opcode & m_pc_mask; - } -} - -void tms1400_cpu_device::op_call() -{ - // CALL/CALLL: conditional call - if (m_status) - { - // 3-level stack, mask clatch 3 bits (no need to mask others) - m_clatch = (m_clatch << 1 | 1) & 7; - - m_sr = m_sr << m_pc_bits | m_pc; - m_pc = m_opcode & m_pc_mask; - - m_ps = m_ps << 4 | m_pa; - m_pa = m_pb; - - m_cs = m_cs << 2 | m_ca; - m_ca = m_cb; - } - else - { - m_pb = m_pa; - m_cb = m_ca; - } -} - -void tms1400_cpu_device::op_retn() -{ - // RETN: return from subroutine - if (m_clatch & 1) - { - m_clatch >>= 1; - - m_pc = m_sr & m_pc_mask; - m_sr >>= m_pc_bits; - - m_pa = m_pb = m_ps & 0xf; - m_ps >>= 4; - - m_ca = m_cb = m_cs & 3; - m_cs >>= 2; - } -} diff --git a/src/devices/cpu/tms1000/tms1400.h b/src/devices/cpu/tms1000/tms1400.h index 59462360457..e6213f028fc 100644 --- a/src/devices/cpu/tms1000/tms1400.h +++ b/src/devices/cpu/tms1000/tms1400.h @@ -26,9 +26,9 @@ protected: virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; - virtual void op_br() override; - virtual void op_call() override; - virtual void op_retn() override; + virtual void op_br() override { op_br3(); } // 3-level stack + virtual void op_call() override { op_call3(); } // " + virtual void op_retn() override { op_retn3(); } // " virtual void op_setr() override { tms1k_base_device::op_setr(); } // no anomaly with MSB of X register virtual void op_rstr() override { tms1k_base_device::op_rstr(); } // " diff --git a/src/devices/cpu/tms1000/tms1k_base.cpp b/src/devices/cpu/tms1000/tms1k_base.cpp index 985784570e8..bfbf6eab8af 100644 --- a/src/devices/cpu/tms1000/tms1k_base.cpp +++ b/src/devices/cpu/tms1000/tms1k_base.cpp @@ -5,8 +5,7 @@ TMS1000 family - base/shared TODO: - - fix debugger disasm view - - INIT pin + - accurate INIT pin (currently, just use INPUT_LINE_RESET) The TMS0980 and TMS1000-family MCU cores are very similar. The TMS0980 has a @@ -72,7 +71,7 @@ unknown cycle: CME, SSE, SSS tms1k_base_device::tms1k_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 o_pins, u8 r_pins, u8 pc_bits, u8 byte_bits, u8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) : cpu_device(mconfig, type, tag, owner, clock) - , m_program_config("program", ENDIANNESS_BIG, byte_bits > 8 ? 16 : 8, prgwidth, 0, program) + , m_program_config("program", ENDIANNESS_BIG, byte_bits > 8 ? 16 : 8, prgwidth, byte_bits > 8 ? -1 : 0, program) , m_data_config("data", ENDIANNESS_BIG, 8, datawidth, 0, data) , m_mpla(*this, "mpla") , m_ipla(*this, "ipla") @@ -145,6 +144,7 @@ void tms1k_base_device::device_start() m_r = 0; m_o = 0; m_o_index = 0; + m_halt = false; m_cki_bus = 0; m_c4 = 0; m_p = 0; @@ -184,6 +184,7 @@ void tms1k_base_device::device_start() save_item(NAME(m_r)); save_item(NAME(m_o)); save_item(NAME(m_o_index)); + save_item(NAME(m_halt)); save_item(NAME(m_cki_bus)); save_item(NAME(m_c4)); save_item(NAME(m_p)); @@ -225,6 +226,14 @@ void tms1k_base_device::device_start() m_icountptr = &m_icount; } +device_memory_interface::space_config_vector tms1k_base_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_DATA, &m_data_config) + }; +} + //------------------------------------------------- @@ -260,13 +269,6 @@ void tms1k_base_device::device_reset() m_power_off(0); } -device_memory_interface::space_config_vector tms1k_base_device::memory_space_config() const -{ - return space_config_vector { - std::make_pair(AS_PROGRAM, &m_program_config), - std::make_pair(AS_DATA, &m_data_config) - }; -} //------------------------------------------------- @@ -306,6 +308,15 @@ void tms1k_base_device::read_opcode() // i/o handling //------------------------------------------------- +void tms1k_base_device::execute_set_input(int line, int state) +{ + if (line != TMS1XXX_INPUT_LINE_HALT) + return; + + // HALT pin (CMOS only) + m_halt = bool(state); +} + void tms1k_base_device::write_o_output(u8 index) { // a hardcoded table is supported if the output pla is unknown @@ -405,6 +416,62 @@ void tms1k_base_device::op_retn() } +// TMS1400/TMS1000C 3-level stack version + +void tms1k_base_device::op_br3() +{ + // BR/BL: conditional branch + if (m_status) + { + m_pa = m_pb; // don't care about clatch + m_ca = m_cb; + m_pc = m_opcode & m_pc_mask; + } +} + +void tms1k_base_device::op_call3() +{ + // CALL/CALLL: conditional call + if (m_status) + { + // mask clatch 3 bits (no need to mask others) + m_clatch = (m_clatch << 1 | 1) & 7; + + m_sr = m_sr << m_pc_bits | m_pc; + m_pc = m_opcode & m_pc_mask; + + m_ps = m_ps << 4 | m_pa; + m_pa = m_pb; + + m_cs = m_cs << 2 | m_ca; + m_ca = m_cb; + } + else + { + m_pb = m_pa; + m_cb = m_ca; + } +} + +void tms1k_base_device::op_retn3() +{ + // RETN: return from subroutine + if (m_clatch & 1) + { + m_clatch >>= 1; + + m_pc = m_sr & m_pc_mask; + m_sr >>= m_pc_bits; + + m_pa = m_pb = m_ps & 0xf; + m_ps >>= 4; + + m_ca = m_cb = m_cs & 3; + m_cs >>= 2; + } +} + + // handle other: // TMS1000/common @@ -542,9 +609,17 @@ void tms1k_base_device::op_sbl() void tms1k_base_device::execute_run() { - do + while (m_icount > 0) { m_icount--; + + if (m_halt) + { + // not running (output pins remain unchanged) + m_icount = 0; + return; + } + switch (m_subcycle) { case 0: @@ -667,6 +742,7 @@ void tms1k_base_device::execute_run() // execute: br/call 1/2 break; } + m_subcycle = (m_subcycle + 1) % 6; - } while (m_icount > 0); + } } diff --git a/src/devices/cpu/tms1000/tms1k_base.h b/src/devices/cpu/tms1000/tms1k_base.h index b8cd7e2a589..b5e75ec77d2 100644 --- a/src/devices/cpu/tms1000/tms1k_base.h +++ b/src/devices/cpu/tms1000/tms1k_base.h @@ -38,6 +38,9 @@ #define MCFG_TMS1XXX_POWER_OFF_CB(_devcb) \ devcb = &tms1k_base_device::set_power_off_callback(*device, DEVCB_##_devcb); +// HALT input pin on CMOS chips (use set_input_line) +#define TMS1XXX_INPUT_LINE_HALT 0 + // pinout reference @@ -93,6 +96,27 @@ public: u8 debug_peek_o_index() { return m_o_index; } // get output PLA index, for debugging (don't use in emulation) +protected: + // construction/destruction + tms1k_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 o_pins, u8 r_pins, u8 pc_bits, u8 byte_bits, u8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // device_execute_interface overrides + virtual u32 execute_min_cycles() const override { return 1; } + virtual u32 execute_max_cycles() const override { return 6; } + virtual u32 execute_input_lines() const override { return 1; } + virtual void execute_set_input(int line, int state) override; + virtual void execute_run() override; + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + // device_state_interface overrides + virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; + // microinstructions enum { @@ -151,30 +175,6 @@ public: F_XDA = (1<<20) }; -protected: - // construction/destruction - tms1k_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 o_pins, u8 r_pins, u8 pc_bits, u8 byte_bits, u8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); - - // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - - // device_execute_interface overrides - virtual u32 execute_min_cycles() const override { return 1; } - virtual u32 execute_max_cycles() const override { return 6; } - virtual u32 execute_input_lines() const override { return 1; } - virtual void execute_run() override; - - // device_memory_interface overrides - virtual space_config_vector memory_space_config() const override; - - // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 1; } - - // device_state_interface overrides - virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - void next_pc(); virtual void write_o_output(u8 index); @@ -186,6 +186,9 @@ protected: virtual void op_br(); virtual void op_call(); virtual void op_retn(); + virtual void op_br3(); + virtual void op_call3(); + virtual void op_retn3(); virtual void op_sbit(); virtual void op_rbit(); @@ -215,50 +218,51 @@ protected: optional_device<pla_device> m_opla; optional_device<pla_device> m_spla; - u8 m_pc; // 6 or 7-bit program counter - u32 m_sr; // 6 or 7-bit subroutine return register(s) - u8 m_pa; // 4-bit page address register - u8 m_pb; // 4-bit page buffer register - u16 m_ps; // 4-bit page subroutine register(s) - u8 m_a; // 4-bit accumulator - u8 m_x; // 2,3,or 4-bit RAM X register - u8 m_y; // 4-bit RAM Y register - u8 m_ca; // chapter address register - u8 m_cb; // chapter buffer register - u16 m_cs; // chapter subroutine register(s) - u16 m_r; - u16 m_o; - u8 m_cki_bus; - u8 m_c4; - u8 m_p; // 4-bit adder p(lus)-input - u8 m_n; // 4-bit adder n(egative)-input - u8 m_adder_out; // adder result - u8 m_carry_in; // adder carry-in bit - u8 m_carry_out; // adder carry-out bit - u8 m_status; - u8 m_status_latch; - u8 m_eac; // end around carry bit - u8 m_clatch; // call latch bit(s) - u8 m_add; // add latch bit - u8 m_bl; // branch latch bit - - u8 m_ram_in; - u8 m_dam_in; - int m_ram_out; // signed! - u8 m_ram_address; - u16 m_rom_address; - u16 m_opcode; - u32 m_fixed; - u32 m_micro; - int m_subcycle; - int m_icount; - u8 m_o_index; - - u8 m_o_pins; // how many O pins - u8 m_r_pins; // how many R pins - u8 m_pc_bits; // how many program counter bits - u8 m_byte_bits; // how many bits per 'byte' - u8 m_x_bits; // how many X register bits + u8 m_pc; // 6 or 7-bit program counter + u32 m_sr; // 6 or 7-bit subroutine return register(s) + u8 m_pa; // 4-bit page address register + u8 m_pb; // 4-bit page buffer register + u16 m_ps; // 4-bit page subroutine register(s) + u8 m_a; // 4-bit accumulator + u8 m_x; // 2,3,or 4-bit RAM X register + u8 m_y; // 4-bit RAM Y register + u8 m_ca; // chapter address register + u8 m_cb; // chapter buffer register + u16 m_cs; // chapter subroutine register(s) + u16 m_r; + u16 m_o; + u8 m_cki_bus; + u8 m_c4; + u8 m_p; // 4-bit adder p(lus)-input + u8 m_n; // 4-bit adder n(egative)-input + u8 m_adder_out; // adder result + u8 m_carry_in; // adder carry-in bit + u8 m_carry_out; // adder carry-out bit + u8 m_status; + u8 m_status_latch; + u8 m_eac; // end around carry bit + u8 m_clatch; // call latch bit(s) + u8 m_add; // add latch bit + u8 m_bl; // branch latch bit + + u8 m_ram_in; + u8 m_dam_in; + int m_ram_out; // signed! + u8 m_ram_address; + u16 m_rom_address; + u16 m_opcode; + u32 m_fixed; + u32 m_micro; + int m_subcycle; + int m_icount; + u8 m_o_index; + bool m_halt; // halt pin state + + u8 m_o_pins; // how many O pins + u8 m_r_pins; // how many R pins + u8 m_pc_bits; // how many program counter bits + u8 m_byte_bits; // how many bits per 'byte' + u8 m_x_bits; // how many X register bits address_space *m_program; address_space *m_data; diff --git a/src/devices/cpu/tms1000/tms1k_dasm.cpp b/src/devices/cpu/tms1000/tms1k_dasm.cpp index f0afd660470..1cd05a57ab3 100644 --- a/src/devices/cpu/tms1000/tms1k_dasm.cpp +++ b/src/devices/cpu/tms1000/tms1k_dasm.cpp @@ -7,23 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "tms1k_base.h" +#include "tms1k_dasm.h" - -enum e_mnemonics -{ - zILL = 0, - zA10AAC, zA6AAC, zA8AAC, zAC1AC, zACACC, zACNAA, zALEC, zALEM, zAMAAC, zBRANCH, zCALL, zCCLA, - zCLA, zCLO, zCOMC, zCOMX, zCOMX8, zCPAIZ, zCTMDYN, zDAN, zDMAN, zDMEA, zDNAA, - zDYN, zIA, zIMAC, zIYC, zKNEZ, zLDP, zLDX2, zLDX3, zLDX4, zMNEA, zMNEZ, - zNDMEA, zOFF, zRBIT, zREAC, zRETN, zRSTR, zSAL, zSAMAN, zSBIT, - zSBL, zSEAC, zSETR, zTAM, zTAMACS, zTAMDYN, zTAMIY, zTAMIYC, zTAMZA, - zTAY, zTBIT, zTCMIY, zTCY, zTDO, zTKA, zTKM, zTMA, - zTMY, zTYA, zXDA, zXMA, zYMCY, zYNEA, zYNEC -}; - -static const char *const s_mnemonic[] = +const char *const tms1000_base_disassembler::s_mnemonic[] = { "?", "A10AAC", "A6AAC", "A8AAC", "AC1AC", "ACACC", "ACNAA", "ALEC", "ALEM", "AMAAC", "BRANCH", "CALL", "CCLA", @@ -35,29 +21,19 @@ static const char *const s_mnemonic[] = "TMY", "TYA", "XDA", "XMA", "YMCY", "YNEA", "YNEC" }; - -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 tms1000_base_disassembler::s_flags[] = { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _OVER, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, STEP_OVER, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, _OUT, 0, 0, 0, 0, + 0, 0, 0, 0, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -enum e_addressing -{ - zB0 = 0, zI2, zI3, zI4, zB7 -}; - -static const u8 s_addressing[] = +const u8 tms1000_base_disassembler::s_addressing[] = { zB0, zB0, zB0, zB0, zI4, zI4, zI4, zI4, zB0, zB0, zB7, zB7, zB0, @@ -73,7 +49,7 @@ static const u8 s_addressing[] = // opcode luts -static const u8 tms1000_mnemonic[256] = +const u8 tms1000_disassembler::tms1000_mnemonic[256] = { /* 0x00 */ zCOMX, zA8AAC, zYNEA, zTAM, zTAMZA, zA10AAC, zA6AAC, zDAN, zTKA, zKNEZ, zTDO, zCLO, zRSTR, zSETR, zIA, zRETN, // 0 @@ -97,7 +73,7 @@ static const u8 tms1000_mnemonic[256] = }; -static const u8 tms1100_mnemonic[256] = +const u8 tms1100_disassembler::tms1100_mnemonic[256] = { /* 0x00 */ zMNEA, zALEM, zYNEA, zXMA, zDYN, zIYC, zAMAAC, zDMAN, zTKA, zCOMX, zTDO, zCOMC, zRSTR, zSETR, zKNEZ, zRETN, // 0 @@ -121,7 +97,7 @@ static const u8 tms1100_mnemonic[256] = }; -static const u8 tms0980_mnemonic[512] = +const u8 tms0980_disassembler::tms0980_mnemonic[512] = { /* 0x000 */ zCOMX, zALEM, zYNEA, zXMA, zDYN, zIYC, zCLA, zDMAN, zTKA, zMNEA, zTKM, 0, 0, zSETR, zKNEZ, 0, // 0 @@ -163,7 +139,7 @@ static const u8 tms0980_mnemonic[512] = }; -static const u8 tp0320_mnemonic[512] = +const u8 tp0320_disassembler::tp0320_mnemonic[512] = { /* 0x000 */ 0, zALEM, zYNEA, zXMA, zDYN, zIYC, zCLA, zDMAN, zTKA, zMNEA, zTKM, 0, 0, zSETR, zKNEZ, 0, // 0 @@ -208,31 +184,27 @@ static const u8 tp0320_mnemonic[512] = // disasm -static const u8 i2_value[4] = +const u8 tms1000_base_disassembler::i2_value[4] = { 0, 2, 1, 3 }; -static const u8 i3_value[8] = +const u8 tms1000_base_disassembler::i3_value[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; -static const u8 i4_value[16] = +const u8 tms1000_base_disassembler::i4_value[16] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf }; -static offs_t tms1k_dasm(std::ostream &stream, const u8 *oprom, const u8 *lut_mnemonic, u16 opcode_mask) +offs_t tms1000_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - // get current opcode - int pos = 0; - u16 op = oprom[pos++]; - if (opcode_mask & 0x100) - op = (op << 8 | oprom[pos++]) & 0x1ff; + u16 op = m_opcode_9bits ? opcodes.r16(pc) & 0x1ff : opcodes.r8(pc); // convert to mnemonic/param - u16 instr = lut_mnemonic[op]; + u16 instr = m_lut_mnemonic[op]; util::stream_format(stream, "%-8s ", s_mnemonic[instr]); switch( s_addressing[instr] ) @@ -247,35 +219,90 @@ static offs_t tms1k_dasm(std::ostream &stream, const u8 *oprom, const u8 *lut_mn util::stream_format(stream, "%d", i4_value[op & 0x0f]); break; case zB7: - if (opcode_mask & 0x100) - util::stream_format(stream, "$%02X", op << 1 & 0xfe); - else - util::stream_format(stream, "$%02X", op & 0x3f); + util::stream_format(stream, "$%02X", op & (m_opcode_9bits ? 0x7f : 0x3f)); break; default: break; } - return pos | s_flags[instr] | DASMFLAG_SUPPORTED; + return 1 | s_flags[instr] | SUPPORTED; } +tms1000_disassembler::tms1000_disassembler() : tms1000_base_disassembler(tms1000_mnemonic, false, 6) +{ +} -CPU_DISASSEMBLE(tms1000) +tms1100_disassembler::tms1100_disassembler() : tms1000_base_disassembler(tms1100_mnemonic, false, 6) { - return tms1k_dasm(stream, oprom, tms1000_mnemonic, 0xff); } -CPU_DISASSEMBLE(tms1100) +tms0980_disassembler::tms0980_disassembler() : tms1000_base_disassembler(tms0980_mnemonic, true, 7) { - return tms1k_dasm(stream, oprom, tms1100_mnemonic, 0xff); } -CPU_DISASSEMBLE(tms0980) +tp0320_disassembler::tp0320_disassembler() : tms1000_base_disassembler(tp0320_mnemonic, true, 7) { - return tms1k_dasm(stream, oprom, tms0980_mnemonic, 0x1ff); } -CPU_DISASSEMBLE(tp0320) +tms1000_base_disassembler::tms1000_base_disassembler(const u8 *lut_mnemonic, bool opcode_9bits, int pc_bits) : m_lut_mnemonic(lut_mnemonic), m_opcode_9bits(opcode_9bits), m_pc_bits(pc_bits) { - return tms1k_dasm(stream, oprom, tp0320_mnemonic, 0x1ff); } + +offs_t tms1000_base_disassembler::pc_linear_to_real(offs_t pc) const +{ + switch(m_pc_bits) { + case 6: { + static const u8 l2r6[64] = { + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x3e, 0x3d, 0x3b, 0x37, 0x2f, 0x1e, 0x3c, 0x39, 0x33, + 0x27, 0x0e, 0x1d, 0x3a, 0x35, 0x2b, 0x16, 0x2c, 0x18, 0x30, 0x21, 0x02, 0x05, 0x0b, 0x17, 0x2e, + 0x1c, 0x38, 0x31, 0x23, 0x06, 0x0d, 0x1b, 0x36, 0x2d, 0x1a, 0x34, 0x29, 0x12, 0x24, 0x08, 0x11, + 0x22, 0x04, 0x09, 0x13, 0x26, 0x0c, 0x19, 0x32, 0x25, 0x0a, 0x15, 0x2a, 0x14, 0x28, 0x10, 0x20, + }; + return (pc & ~0x3f) | l2r6[pc & 0x3f]; + } + case 7: { + static const u8 l2r7[128] = { + 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0x7e, 0x7d, 0x7b, 0x77, 0x6f, 0x5f, 0x3e, 0x7c, + 0x79, 0x73, 0x67, 0x4f, 0x1e, 0x3d, 0x7a, 0x75, 0x6b, 0x57, 0x2e, 0x5c, 0x38, 0x70, 0x61, 0x43, + 0x06, 0x0d, 0x1b, 0x37, 0x6e, 0x5d, 0x3a, 0x74, 0x69, 0x53, 0x26, 0x4c, 0x18, 0x31, 0x62, 0x45, + 0x0a, 0x15, 0x2b, 0x56, 0x2c, 0x58, 0x30, 0x60, 0x41, 0x02, 0x05, 0x0b, 0x17, 0x2f, 0x5e, 0x3c, + 0x78, 0x71, 0x63, 0x47, 0x0e, 0x1d, 0x3b, 0x76, 0x6d, 0x5b, 0x36, 0x6c, 0x59, 0x32, 0x64, 0x49, + 0x12, 0x25, 0x4a, 0x14, 0x29, 0x52, 0x24, 0x48, 0x10, 0x21, 0x42, 0x04, 0x09, 0x13, 0x27, 0x4e, + 0x1c, 0x39, 0x72, 0x65, 0x4b, 0x16, 0x2d, 0x5a, 0x34, 0x68, 0x51, 0x22, 0x44, 0x08, 0x11, 0x23, + 0x46, 0x0c, 0x19, 0x33, 0x66, 0x4d, 0x1a, 0x35, 0x6a, 0x55, 0x2a, 0x54, 0x28, 0x50, 0x20, 0x40, + }; + return (pc & ~0x7f) | l2r7[pc & 0x7f]; + } + } + return 0; +} + +offs_t tms1000_base_disassembler::pc_real_to_linear(offs_t pc) const +{ + switch(m_pc_bits) { + case 6: { + static const u8 r2l6[64] = { + 0x00, 0x01, 0x1b, 0x02, 0x31, 0x1c, 0x24, 0x03, 0x2e, 0x32, 0x39, 0x1d, 0x35, 0x25, 0x11, 0x04, + 0x3e, 0x2f, 0x2c, 0x33, 0x3c, 0x3a, 0x16, 0x1e, 0x18, 0x36, 0x29, 0x26, 0x20, 0x12, 0x0c, 0x05, + 0x3f, 0x1a, 0x30, 0x23, 0x2d, 0x38, 0x34, 0x10, 0x3d, 0x2b, 0x3b, 0x15, 0x17, 0x28, 0x1f, 0x0b, + 0x19, 0x22, 0x37, 0x0f, 0x2a, 0x14, 0x27, 0x0a, 0x21, 0x0e, 0x13, 0x09, 0x0d, 0x08, 0x07, 0x06, + }; + return (pc & ~0x3f) | r2l6[pc & 0x3f]; + } + case 7: { + static const u8 r2l7[128] = { + 0x00, 0x01, 0x39, 0x02, 0x5b, 0x3a, 0x20, 0x03, 0x6d, 0x5c, 0x30, 0x3b, 0x71, 0x21, 0x44, 0x04, + 0x58, 0x6e, 0x50, 0x5d, 0x53, 0x31, 0x65, 0x3c, 0x2c, 0x72, 0x76, 0x22, 0x60, 0x45, 0x14, 0x05, + 0x7e, 0x59, 0x6b, 0x6f, 0x56, 0x51, 0x2a, 0x5e, 0x7c, 0x54, 0x7a, 0x32, 0x34, 0x66, 0x1a, 0x3d, + 0x36, 0x2d, 0x4d, 0x73, 0x68, 0x77, 0x4a, 0x23, 0x1c, 0x61, 0x26, 0x46, 0x3f, 0x15, 0x0e, 0x06, + 0x7f, 0x38, 0x5a, 0x1f, 0x6c, 0x2f, 0x70, 0x43, 0x57, 0x4f, 0x52, 0x64, 0x2b, 0x75, 0x5f, 0x13, + 0x7d, 0x6a, 0x55, 0x29, 0x7b, 0x79, 0x33, 0x19, 0x35, 0x4c, 0x67, 0x49, 0x1b, 0x25, 0x3e, 0x0d, + 0x37, 0x1e, 0x2e, 0x42, 0x4e, 0x63, 0x74, 0x12, 0x69, 0x28, 0x78, 0x18, 0x4b, 0x48, 0x24, 0x0c, + 0x1d, 0x41, 0x62, 0x11, 0x27, 0x17, 0x47, 0x0b, 0x40, 0x10, 0x16, 0x0a, 0x0f, 0x09, 0x08, 0x07, + }; + return (pc & ~0x7f) | r2l7[pc & 0x7f]; + } + } + return 0; +} + diff --git a/src/devices/cpu/tms1000/tms1k_dasm.h b/src/devices/cpu/tms1000/tms1k_dasm.h new file mode 100644 index 00000000000..64e9e6f5082 --- /dev/null +++ b/src/devices/cpu/tms1000/tms1k_dasm.h @@ -0,0 +1,100 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol, hap +/* + + TMS0980/TMS1000-family disassembler + +*/ + +#ifndef MAME_CPU_TMS1000_TMS1K_DASM_H +#define MAME_CPU_TMS1000_TMS1K_DASM_H + +#pragma once + +class tms1000_base_disassembler : public util::disasm_interface +{ +public: + tms1000_base_disassembler(const u8 *lut_mnemonic, bool opcode_9bits, int pc_bits); + virtual ~tms1000_base_disassembler() = default; + + virtual u32 opcode_alignment() const override { return 1; } + virtual u32 interface_flags() const override { return NONLINEAR_PC | PAGED; } + virtual u32 page_address_bits() const override { return m_pc_bits; } + virtual offs_t pc_linear_to_real(offs_t pc) const override; + virtual offs_t pc_real_to_linear(offs_t pc) const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + enum e_mnemonics + { + zILL = 0, + zA10AAC, zA6AAC, zA8AAC, zAC1AC, zACACC, zACNAA, zALEC, zALEM, zAMAAC, zBRANCH, zCALL, zCCLA, + zCLA, zCLO, zCOMC, zCOMX, zCOMX8, zCPAIZ, zCTMDYN, zDAN, zDMAN, zDMEA, zDNAA, + zDYN, zIA, zIMAC, zIYC, zKNEZ, zLDP, zLDX2, zLDX3, zLDX4, zMNEA, zMNEZ, + zNDMEA, zOFF, zRBIT, zREAC, zRETN, zRSTR, zSAL, zSAMAN, zSBIT, + zSBL, zSEAC, zSETR, zTAM, zTAMACS, zTAMDYN, zTAMIY, zTAMIYC, zTAMZA, + zTAY, zTBIT, zTCMIY, zTCY, zTDO, zTKA, zTKM, zTMA, + zTMY, zTYA, zXDA, zXMA, zYMCY, zYNEA, zYNEC + }; + + enum e_addressing + { + zB0 = 0, zI2, zI3, zI4, zB7 + }; + + static const char *const s_mnemonic[]; + static const u32 s_flags[]; + static const u8 s_addressing[]; + static const u8 i2_value[4]; + static const u8 i3_value[8]; + static const u8 i4_value[16]; + + const u8 *m_lut_mnemonic; + bool m_opcode_9bits; + int m_pc_bits; +}; + +class tms1000_disassembler : public tms1000_base_disassembler +{ +public: + tms1000_disassembler(); + virtual ~tms1000_disassembler() = default; + +protected: + static const u8 tms1000_mnemonic[256]; +}; + +class tms1100_disassembler : public tms1000_base_disassembler +{ +public: + tms1100_disassembler(); + virtual ~tms1100_disassembler() = default; + + virtual u32 interface_flags() const override { return NONLINEAR_PC | PAGED2LEVEL; } + virtual u32 page2_address_bits() const override { return 4; } + +protected: + static const u8 tms1100_mnemonic[256]; +}; + +class tms0980_disassembler : public tms1000_base_disassembler +{ +public: + tms0980_disassembler(); + virtual ~tms0980_disassembler() = default; + +protected: + static const u8 tms0980_mnemonic[512]; +}; + +class tp0320_disassembler : public tms1000_base_disassembler +{ +public: + tp0320_disassembler(); + virtual ~tp0320_disassembler() = default; + +protected: + static const u8 tp0320_mnemonic[512]; +}; + +#endif diff --git a/src/devices/cpu/tms1000/tp0320.cpp b/src/devices/cpu/tms1000/tp0320.cpp index 02e961f6473..64ebdb3365a 100644 --- a/src/devices/cpu/tms1000/tp0320.cpp +++ b/src/devices/cpu/tms1000/tp0320.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "tp0320.h" +#include "tms1k_dasm.h" #include "debugger.h" // TP0320 is TI's first CMOS MCU with integrated LCD controller, the die is still very similar to TMS0980 @@ -27,7 +28,7 @@ DEFINE_DEVICE_TYPE(TP0320, tp0320_cpu_device, "tp0320", "TP0320") // 28-pin SDIP // internal memory maps static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1k_base_device) - AM_RANGE(0x000, 0xfff) AM_ROM + AM_RANGE(0x000, 0x7ff) AM_ROM ADDRESS_MAP_END static ADDRESS_MAP_START(data_192x4, AS_DATA, 8, tms1k_base_device) @@ -38,7 +39,7 @@ ADDRESS_MAP_END // device definitions tp0320_cpu_device::tp0320_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : tms0980_cpu_device(mconfig, TP0320, tag, owner, clock, 7 /* o pins */, 10 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 12 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_192x4)) + : tms0980_cpu_device(mconfig, TP0320, tag, owner, clock, 7 /* o pins */, 10 /* r pins */, 7 /* pc bits */, 9 /* byte width */, 4 /* x width */, 11 /* prg width */, ADDRESS_MAP_NAME(program_11bit_9), 8 /* data width */, ADDRESS_MAP_NAME(data_192x4)) { } @@ -55,10 +56,9 @@ MACHINE_CONFIG_END // disasm -offs_t tp0320_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *tp0320_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(tp0320); - return CPU_DISASSEMBLE_NAME(tp0320)(this, stream, pc, oprom, opram, options); + return new tp0320_disassembler; } diff --git a/src/devices/cpu/tms1000/tp0320.h b/src/devices/cpu/tms1000/tp0320.h index e740ae83320..9b23155f1c4 100644 --- a/src/devices/cpu/tms1000/tp0320.h +++ b/src/devices/cpu/tms1000/tp0320.h @@ -26,7 +26,7 @@ protected: virtual u32 decode_fixed(u16 op) override { return 0; } // not yet virtual u32 decode_micro(u8 sel) override; virtual void device_reset() override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void device_add_mconfig(machine_config &config) override; }; diff --git a/src/devices/cpu/tms32010/32010dsm.cpp b/src/devices/cpu/tms32010/32010dsm.cpp index 040a24b11b6..a1dfade63b4 100644 --- a/src/devices/cpu/tms32010/32010dsm.cpp +++ b/src/devices/cpu/tms32010/32010dsm.cpp @@ -25,153 +25,130 @@ \**************************************************************************/ #include "emu.h" -#include "debugger.h" +#include "32010dsm.h" #include <ctype.h> -#include "tms32010.h" +const char *const tms32010_disassembler::arith[4] = { "*" , "*-" , "*+" , "??" } ; +const char *const tms32010_disassembler::nextar[4] = { ",AR0" , ",AR1" , "" , "" } ; - -typedef unsigned char byte; -typedef unsigned short int word; - -#define FMT(a,b) a, b -#define PTRS_PER_FORMAT 2 - -static const char *const arith[4] = { "*" , "*-" , "*+" , "??" } ; -static const char *const nextar[4] = { ",AR0" , ",AR1" , "" , "" } ; - - -static const char *const TMS32010Formats[] = { - FMT("0000ssss0aaaaaaa", "add %A%S"), - FMT("0000ssss10mmn00n", "add %M%S%N"), - FMT("0001ssss0aaaaaaa", "sub %A%S"), - FMT("0001ssss10mmn00n", "sub %M%S%N"), - FMT("0010ssss0aaaaaaa", "lac %A%S"), - FMT("0010ssss10mmn00n", "lac %M%S%N"), - FMT("0011000r0aaaaaaa", "sar %R,%A"), - FMT("0011000r10mmn00n", "sar %R%M%N"), - FMT("0011100r0aaaaaaa", "lar %R,%A"), - FMT("0011100r10mmn00n", "lar %R%M%N"), - FMT("01000ppp0aaaaaaa", "in %A,%P"), - FMT("01000ppp10mmn00n", "in %M,%P%N"), - FMT("01001ppp0aaaaaaa", "out %A,%P"), - FMT("01001ppp10mmn00n", "out %M,%P%N"), - FMT("01010sss0aaaaaaa", "sacl %A"), /* This instruction has a shift but */ - FMT("01010sss10mmn00n", "sacl %M%N"), /* is documented as not performed */ - FMT("01011sss0aaaaaaa", "sach %A%S"), - FMT("01011sss10mmn00n", "sach %M%S%N"), - FMT("011000000aaaaaaa", "addh %A"), - FMT("0110000010mmn00n", "addh %M%N"), - FMT("011000010aaaaaaa", "adds %A"), - FMT("0110000110mmn00n", "adds %M%N"), - FMT("011000100aaaaaaa", "subh %A"), - FMT("0110001010mmn00n", "subh %M%N"), - FMT("011000110aaaaaaa", "subs %A"), - FMT("0110001110mmn00n", "subs %M%N"), - FMT("011001000aaaaaaa", "subc %A"), - FMT("0110010010mmn00n", "subc %M%N"), - FMT("011001010aaaaaaa", "zalh %A"), - FMT("0110010110mmn00n", "zalh %M%N"), - FMT("011001100aaaaaaa", "zals %A"), - FMT("0110011010mmn00n", "zals %M%N"), - FMT("011001110aaaaaaa", "tblr %A"), - FMT("0110011110mmn00n", "tblr %M%N"), - FMT("011010001000000k", "larp %K"), - FMT("011010000aaaaaaa", "mar %A"), /* Actually this is executed as a NOP */ -/* FMT("0110100010mmn00n", "mar %M%N"), */ +const char *const tms32010_disassembler::TMS32010Formats[] = { + "0000ssss0aaaaaaa", "add %A%S", + "0000ssss10mmn00n", "add %M%S%N", + "0001ssss0aaaaaaa", "sub %A%S", + "0001ssss10mmn00n", "sub %M%S%N", + "0010ssss0aaaaaaa", "lac %A%S", + "0010ssss10mmn00n", "lac %M%S%N", + "0011000r0aaaaaaa", "sar %R,%A", + "0011000r10mmn00n", "sar %R%M%N", + "0011100r0aaaaaaa", "lar %R,%A", + "0011100r10mmn00n", "lar %R%M%N", + "01000ppp0aaaaaaa", "in %A,%P", + "01000ppp10mmn00n", "in %M,%P%N", + "01001ppp0aaaaaaa", "out %A,%P", + "01001ppp10mmn00n", "out %M,%P%N", + "01010sss0aaaaaaa", "sacl %A", /* This instruction has a shift but */ + "01010sss10mmn00n", "sacl %M%N", /* is documented as not performed */ + "01011sss0aaaaaaa", "sach %A%S", + "01011sss10mmn00n", "sach %M%S%N", + "011000000aaaaaaa", "addh %A", + "0110000010mmn00n", "addh %M%N", + "011000010aaaaaaa", "adds %A", + "0110000110mmn00n", "adds %M%N", + "011000100aaaaaaa", "subh %A", + "0110001010mmn00n", "subh %M%N", + "011000110aaaaaaa", "subs %A", + "0110001110mmn00n", "subs %M%N", + "011001000aaaaaaa", "subc %A", + "0110010010mmn00n", "subc %M%N", + "011001010aaaaaaa", "zalh %A", + "0110010110mmn00n", "zalh %M%N", + "011001100aaaaaaa", "zals %A", + "0110011010mmn00n", "zals %M%N", + "011001110aaaaaaa", "tblr %A", + "0110011110mmn00n", "tblr %M%N", + "011010001000000k", "larp %K", + "011010000aaaaaaa", "mar %A", /* Actually this is executed as a NOP */ +/* "0110100010mmn00n", "mar %M%N", */ /* MAR indirect has been expanded out to all its variations because one of */ /* its opcodes is the same as LARP (actually performs the same function) */ - FMT("0110100010001000", "mar *"), - FMT("0110100010001001", "mar *"), - FMT("0110100010010000", "mar *-,AR0"), - FMT("0110100010010001", "mar *-,AR1"), - FMT("0110100010011000", "mar *-"), - FMT("0110100010011001", "mar *-"), - FMT("0110100010100000", "mar *+,AR0"), - FMT("0110100010100001", "mar *+,AR1"), - FMT("0110100010101000", "mar *+"), - FMT("0110100010101001", "mar *+"), - FMT("0110100010110000", "mar ??,AR0"), - FMT("0110100010110001", "mar ??,AR1"), - FMT("0110100010111000", "mar ??"), - FMT("0110100010111001", "mar ??"), + "0110100010001000", "mar *", + "0110100010001001", "mar *", + "0110100010010000", "mar *-,AR0", + "0110100010010001", "mar *-,AR1", + "0110100010011000", "mar *-", + "0110100010011001", "mar *-", + "0110100010100000", "mar *+,AR0", + "0110100010100001", "mar *+,AR1", + "0110100010101000", "mar *+", + "0110100010101001", "mar *+", + "0110100010110000", "mar ??,AR0", + "0110100010110001", "mar ??,AR1", + "0110100010111000", "mar ??", + "0110100010111001", "mar ??", - FMT("011010010aaaaaaa", "dmov %A"), - FMT("0110100110mmn00n", "dmov %M%N"), - FMT("011010100aaaaaaa", "lt %A"), - FMT("0110101010mmn00n", "lt %M%N"), - FMT("011010110aaaaaaa", "ltd %A"), - FMT("0110101110mmn00n", "ltd %M%N"), - FMT("011011000aaaaaaa", "lta %A"), - FMT("0110110010mmn00n", "lta %M%N"), - FMT("011011010aaaaaaa", "mpy %A"), - FMT("0110110110mmn00n", "mpy %M%N"), - FMT("011011100000000k", "ldpk %K"), - FMT("011011110aaaaaaa", "ldp %A"), - FMT("0110111110mmn00n", "ldp %M%N"), - FMT("0111000rdddddddd", "lark %R,%D"), - FMT("011110000aaaaaaa", "xor %A"), - FMT("0111100010mmn00n", "xor %M%N"), - FMT("011110010aaaaaaa", "and %A"), - FMT("0111100110mmn00n", "and %M%N"), - FMT("011110100aaaaaaa", "or %A"), - FMT("0111101010mmn00n", "or %M%N"), - FMT("011110110aaaaaaa", "lst %A"), - FMT("0111101110mmn00n", "lst %M%N"), - FMT("011111000aaaaaaa", "sst %A"), - FMT("0111110010mmn00n", "sst %M%N"), - FMT("011111010aaaaaaa", "tblw %A"), - FMT("0111110110mmn00n", "tblw %M%N"), - FMT("01111110dddddddd", "lack %D"), - FMT("0111111110000000", "nop"), /* 7F80 */ - FMT("0111111110000001", "dint"), - FMT("0111111110000010", "eint"), - FMT("0111111110001000", "abs"), /* 7F88 */ - FMT("0111111110001001", "zac"), - FMT("0111111110001010", "rovm"), - FMT("0111111110001011", "sovm"), - FMT("0111111110001100", "cala"), - FMT("0111111110001101", "ret"), - FMT("0111111110001110", "pac"), - FMT("0111111110001111", "apac"), - FMT("0111111110010000", "spac"), - FMT("0111111110011100", "push"), - FMT("0111111110011101", "pop"), /* 7F9D */ - FMT("100wwwwwwwwwwwww", "mpyk %W"), - FMT("1111010000000000bbbbbbbbbbbbbbbb", "banz %B"), - FMT("1111010100000000bbbbbbbbbbbbbbbb", "bv %B"), - FMT("1111011000000000bbbbbbbbbbbbbbbb", "bioz %B"), - FMT("1111100000000000bbbbbbbbbbbbbbbb", "call %B"), - FMT("1111100100000000bbbbbbbbbbbbbbbb", "b %B"), - FMT("1111101000000000bbbbbbbbbbbbbbbb", "blz %B"), - FMT("1111101100000000bbbbbbbbbbbbbbbb", "blez %B"), - FMT("1111110000000000bbbbbbbbbbbbbbbb", "bgz %B"), - FMT("1111110100000000bbbbbbbbbbbbbbbb", "bgez %B"), - FMT("1111111000000000bbbbbbbbbbbbbbbb", "bnz %B"), - FMT("1111111100000000bbbbbbbbbbbbbbbb", "bz %B"), + "011010010aaaaaaa", "dmov %A", + "0110100110mmn00n", "dmov %M%N", + "011010100aaaaaaa", "lt %A", + "0110101010mmn00n", "lt %M%N", + "011010110aaaaaaa", "ltd %A", + "0110101110mmn00n", "ltd %M%N", + "011011000aaaaaaa", "lta %A", + "0110110010mmn00n", "lta %M%N", + "011011010aaaaaaa", "mpy %A", + "0110110110mmn00n", "mpy %M%N", + "011011100000000k", "ldpk %K", + "011011110aaaaaaa", "ldp %A", + "0110111110mmn00n", "ldp %M%N", + "0111000rdddddddd", "lark %R,%D", + "011110000aaaaaaa", "xor %A", + "0111100010mmn00n", "xor %M%N", + "011110010aaaaaaa", "and %A", + "0111100110mmn00n", "and %M%N", + "011110100aaaaaaa", "or %A", + "0111101010mmn00n", "or %M%N", + "011110110aaaaaaa", "lst %A", + "0111101110mmn00n", "lst %M%N", + "011111000aaaaaaa", "sst %A", + "0111110010mmn00n", "sst %M%N", + "011111010aaaaaaa", "tblw %A", + "0111110110mmn00n", "tblw %M%N", + "01111110dddddddd", "lack %D", + "0111111110000000", "nop", /* 7F80 */ + "0111111110000001", "dint", + "0111111110000010", "eint", + "0111111110001000", "abs", /* 7F88 */ + "0111111110001001", "zac", + "0111111110001010", "rovm", + "0111111110001011", "sovm", + "0111111110001100", "cala", + "0111111110001101", "ret", + "0111111110001110", "pac", + "0111111110001111", "apac", + "0111111110010000", "spac", + "0111111110011100", "push", + "0111111110011101", "pop", /* 7F9D */ + "100wwwwwwwwwwwww", "mpyk %W", + "1111010000000000bbbbbbbbbbbbbbbb", "banz %B", + "1111010100000000bbbbbbbbbbbbbbbb", "bv %B", + "1111011000000000bbbbbbbbbbbbbbbb", "bioz %B", + "1111100000000000bbbbbbbbbbbbbbbb", "call %B", + "1111100100000000bbbbbbbbbbbbbbbb", "b %B", + "1111101000000000bbbbbbbbbbbbbbbb", "blz %B", + "1111101100000000bbbbbbbbbbbbbbbb", "blez %B", + "1111110000000000bbbbbbbbbbbbbbbb", "bgz %B", + "1111110100000000bbbbbbbbbbbbbbbb", "bgez %B", + "1111111000000000bbbbbbbbbbbbbbbb", "bnz %B", + "1111111100000000bbbbbbbbbbbbbbbb", "bz %B", nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(TMS32010Formats) - 1) / PTRS_PER_FORMAT) - -struct TMS32010Opcode { - word mask; /* instruction mask */ - word bits; /* constant bits */ - word extcode; /* value that gets extension code */ - const char *parse; /* how to parse bits */ - const char *fmt; /* instruction format */ -}; - -static TMS32010Opcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm32010(void) +tms32010_disassembler::tms32010_disassembler() { const char *p; const char *const *ops; - word mask, bits; + u16 mask, bits; int bit; int i; @@ -209,20 +186,14 @@ static void InitDasm32010(void) ops[0],ops[1],bit); } while (isspace((uint8_t)*p)) p++; - if (*p) Op[i].extcode = *p; - Op[i].bits = bits; - Op[i].mask = mask; - Op[i].fmt = ops[1]; - Op[i].parse = ops[0]; + Op.emplace_back(mask, bits, *p, ops[0], ops[1]); - ops += PTRS_PER_FORMAT; + ops += 2; i++; } - - OpInizialized = 1; } -CPU_DISASSEMBLE(tms32010) +offs_t tms32010_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; int a, b, d, k, m, n, p, r, s, w; /* these can all be filled in by parsing an instruction */ @@ -234,11 +205,9 @@ CPU_DISASSEMBLE(tms32010) //char *buffertmp; const char *cp; /* character pointer in OpFormats */ - if (!OpInizialized) InitDasm32010(); - op = -1; /* no matching opcode */ - code = (oprom[0] << 8) | oprom[1]; - for ( i = 0; i < MAX_OPS; i++) + code = opcodes.r16(pc); + for ( i = 0; i < int(Op.size()); i++) { if ((code & Op[i].mask) == Op[i].bits) { @@ -253,14 +222,14 @@ CPU_DISASSEMBLE(tms32010) if (op == -1) { util::stream_format(stream, "dw %04Xh *(invalid op)", code); - return cnt | DASMFLAG_SUPPORTED; + return cnt | SUPPORTED; } //buffertmp = buffer; if (Op[op].extcode) { bit = 31; code <<= 16; - code |= (opram[2] << 8) | opram[3]; + code |= opcodes.r16(pc+1); cnt++; } else @@ -298,9 +267,9 @@ CPU_DISASSEMBLE(tms32010) cp = Op[op].fmt; if (!strncmp(cp, "cal", 3)) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strncmp(cp, "ret", 3)) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; while (*cp) { @@ -330,5 +299,11 @@ CPU_DISASSEMBLE(tms32010) stream << *cp++; } } - return cnt | flags | DASMFLAG_SUPPORTED; + return cnt | flags | SUPPORTED; } + +u32 tms32010_disassembler::opcode_alignment() const +{ + return 1; +} + diff --git a/src/devices/cpu/tms32010/32010dsm.h b/src/devices/cpu/tms32010/32010dsm.h new file mode 100644 index 00000000000..d2b93d5f5a4 --- /dev/null +++ b/src/devices/cpu/tms32010/32010dsm.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:Tony La Porta + /**************************************************************************\ + * Texas Instruments TMS32010 DSP Disassembler * + * * + * Copyright Tony La Porta * + * To be used with TMS32010 DSP Emulator engine. * + * * + * Many thanks to those involved in the i8039 Disassembler * + * as this was based on it. * + * * + * * + * * + * A Memory address * + * B Branch Address for Branch instructions (Requires next opcode read) * + * D Immediate byte load * + * K Immediate bit load * + * W Immediate word load (Actually 13 bit) * + * M AR[x] register modification type (for indirect addressing) * + * N ARP register to change ARP pointer to (for indirect addressing) * + * P I/O port address number * + * R AR[R] register to use * + * S Shift ALU left * + * * + \**************************************************************************/ + +#ifndef MAME_CPU_TMS32010_DIS32010_H +#define MAME_CPU_TMS32010_DIS32010_H + +#pragma once + +class tms32010_disassembler : public util::disasm_interface +{ +public: + tms32010_disassembler(); + virtual ~tms32010_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct TMS32010Opcode { + u16 mask; /* instruction mask */ + u16 bits; /* constant bits */ + u16 extcode; /* value that gets extension code */ + const char *parse; /* how to parse bits */ + const char *fmt; /* instruction format */ + + TMS32010Opcode(u16 m, u16 b, u16 e, const char *p, const char *f) : mask(m), bits(b), extcode(e), parse(p), fmt(f) {} + }; + + static const char *const arith[4]; + static const char *const nextar[4]; + static const char *const TMS32010Formats[]; + + std::vector<TMS32010Opcode> Op; +}; + +#endif diff --git a/src/devices/cpu/tms32010/tms32010.cpp b/src/devices/cpu/tms32010/tms32010.cpp index 007cac7b0fc..968e7bde61f 100644 --- a/src/devices/cpu/tms32010/tms32010.cpp +++ b/src/devices/cpu/tms32010/tms32010.cpp @@ -59,6 +59,7 @@ #include "emu.h" #include "tms32010.h" +#include "32010dsm.h" #include "debugger.h" @@ -134,10 +135,9 @@ device_memory_interface::space_config_vector tms32010_device::memory_space_confi }; } -offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms32010_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms32010 ); - return CPU_DISASSEMBLE_NAME(tms32010)(this, stream, pc, oprom, opram, options); + return new tms32010_disassembler; } @@ -165,14 +165,14 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * Input a word from given I/O port */ -#define TMS32010_In(Port) (m_io->read_word((Port)<<1)) +#define TMS32010_In(Port) (m_io->read_word(Port)) /**************************************************************************** * Output a word to given I/O port */ -#define TMS32010_Out(Port,Value) (m_io->write_word((Port)<<1,Value)) +#define TMS32010_Out(Port,Value) (m_io->write_word(Port,Value)) @@ -180,14 +180,14 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * Read a word from given ROM memory location */ -#define TMS32010_ROM_RDMEM(A) (m_program->read_word((A)<<1)) +#define TMS32010_ROM_RDMEM(A) (m_program->read_word(A)) /**************************************************************************** * Write a word to given ROM memory location */ -#define TMS32010_ROM_WRMEM(A,V) (m_program->write_word((A)<<1,V)) +#define TMS32010_ROM_WRMEM(A,V) (m_program->write_word(A,V)) @@ -195,14 +195,14 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * Read a word from given RAM memory location */ -#define TMS32010_RAM_RDMEM(A) (m_data->read_word((A)<<1)) +#define TMS32010_RAM_RDMEM(A) (m_data->read_word(A)) /**************************************************************************** * Write a word to given RAM memory location */ -#define TMS32010_RAM_WRMEM(A,V) (m_data->write_word((A)<<1,V)) +#define TMS32010_RAM_WRMEM(A,V) (m_data->write_word(A,V)) @@ -212,7 +212,7 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * used to greatly speed up emulation */ -#define TMS32010_RDOP(A) (m_direct->read_word((A)<<1)) +#define TMS32010_RDOP(A) (m_direct->read_word(A)) /**************************************************************************** @@ -221,7 +221,7 @@ offs_t tms32010_device::disasm_disassemble(std::ostream &stream, offs_t pc, cons * that use different encoding mechanisms for opcodes and opcode arguments */ -#define TMS32010_RDOP_ARG(A) (m_direct->read_word((A)<<1)) +#define TMS32010_RDOP_ARG(A) (m_direct->read_word(A)) /************************************************************************ @@ -523,7 +523,7 @@ void tms32010_device::eint() } void tms32010_device::in_p() { - m_ALU.w.l = P_IN( (m_opcode.b.h & 7) ); + m_ALU.w.l = P_IN(m_opcode.b.h & 7); putdata(m_ALU.w.l); } void tms32010_device::lac_sh() @@ -834,7 +834,7 @@ void tms32010_device::device_start() save_item(NAME(m_addr_mask)); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); diff --git a/src/devices/cpu/tms32010/tms32010.h b/src/devices/cpu/tms32010/tms32010.h index 2f2469330e5..eb1e40370e1 100644 --- a/src/devices/cpu/tms32010/tms32010.h +++ b/src/devices/cpu/tms32010/tms32010.h @@ -70,9 +70,7 @@ protected: 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 2; } - 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -109,7 +107,7 @@ private: int m_addr_mask; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; address_space *m_io; diff --git a/src/devices/cpu/tms32025/32025dsm.cpp b/src/devices/cpu/tms32025/32025dsm.cpp index cf9a61571b5..b8ad14415c3 100644 --- a/src/devices/cpu/tms32025/32025dsm.cpp +++ b/src/devices/cpu/tms32025/32025dsm.cpp @@ -31,309 +31,286 @@ \**************************************************************************/ #include "emu.h" -#include "debugger.h" +#include "32025dsm.h" #include <ctype.h> -#include "tms32025.h" +const char *const tms32025_disassembler::arith[8] = { "*", "*-", "*+", "??", "BR0-", "*0-", "*0+", "*BR0+" } ; +const char *const tms32025_disassembler::nextar[16] = { "", "", "", "", "", "", "", "", ",AR0", ",AR1", ",AR2", ",AR3", ",AR4", ",AR5", ",AR6", ",AR7" } ; +const char *const tms32025_disassembler::cmpmode[4] = { "0 (ARx = AR0)" , "1 (ARx < AR0)" , "2 (ARx > AR0)" , "3 (ARx <> AR0)" } ; +const char *const tms32025_disassembler::TMS32025Formats[] = { + "0000tttt0aaaaaaa", "add %A,%T", /* 0xxx */ + "0000tttt1mmmnnnn", "add %M,%T%N", + "0001tttt0aaaaaaa", "sub %A,%T", /* 1xxx */ + "0001tttt1mmmnnnn", "sub %M,%T%N", + "0010tttt0aaaaaaa", "lac %A,%T", /* 2xxx */ + "0010tttt1mmmnnnn", "lac %M,%T%N", + "00110rrr0aaaaaaa", "lar %R,%A", /* 3xxx */ + "00110rrr1mmmnnnn", "lar %R%M%N", + "001110000aaaaaaa", "mpy %A", /* 38xx */ + "001110001mmmnnnn", "mpy %M%N", + "001110010aaaaaaa", "sqra %A", /* 39xx */ + "001110011mmmnnnn", "sqra %M%N", + "001110100aaaaaaa", "mpya %A", /* 3Axx */ + "001110101mmmnnnn", "mpya %M%N", + "001110110aaaaaaa", "mpys %A", /* 3Bxx */ + "001110111mmmnnnn", "mpys %M%N", + "001111000aaaaaaa", "lt %A", /* 3Cxx */ + "001111001mmmnnnn", "lt %M%N", + "001111010aaaaaaa", "lta %A", /* 3Dxx */ + "001111011mmmnnnn", "lta %M%N", + "001111100aaaaaaa", "ltp %A", /* 3Exx */ + "001111101mmmnnnn", "ltp %M%N", + "001111110aaaaaaa", "ltd %A", /* 3Fxx */ + "001111111mmmnnnn", "ltd %M%N", + "010000000aaaaaaa", "zalh %A", /* 40xx */ + "010000001mmmnnnn", "zalh %M%N", + "010000010aaaaaaa", "zals %A", /* 41xx */ + "010000011mmmnnnn", "zals %M%N", + "010000100aaaaaaa", "lact %A", /* 42xx */ + "010000101mmmnnnn", "lact %M%N", + "010000110aaaaaaa", "addc %A%S", /* 43xx */ + "010000111mmmnnnn", "addc %M%S%N", + "010001000aaaaaaa", "subh %A", /* 44xx */ + "010001001mmmnnnn", "subh %M%N", + "010001010aaaaaaa", "subs %A", /* 45xx */ + "010001011mmmnnnn", "subs %M%N", + "010001100aaaaaaa", "subt %A", /* 46xx */ + "010001101mmmnnnn", "subt %M%N", + "010001110aaaaaaa", "subc %A", /* 47xx */ + "010001111mmmnnnn", "subc %M%N", + "010010000aaaaaaa", "addh %A", /* 48xx */ + "010010001mmmnnnn", "addh %M%N", + "010010010aaaaaaa", "adds %A", /* 49xx */ + "010010011mmmnnnn", "adds %M%N", + "010010100aaaaaaa", "addt %A", /* 4Axx */ + "010010101mmmnnnn", "addt %M%N", + "010010110aaaaaaa", "rpt %A", /* 4Bxx */ + "010010111mmmnnnn", "rpt %M%N", + "010011000aaaaaaa", "xor %A", /* 4Cxx */ + "010011001mmmnnnn", "xor %M%N", + "010011010aaaaaaa", "or %A", /* 4Dxx */ + "010011011mmmnnnn", "or %M%N", + "010011100aaaaaaa", "and %A", /* 4Exx */ + "010011101mmmnnnn", "and %M%N", + "010011110aaaaaaa", "subb %A", /* 4Fxx */ + "010011111mmmnnnn", "subb %M%N", + "010100000aaaaaaa", "lst %A", /* 50xx */ + "010100001mmmnnnn", "lst %M%N", + "010100010aaaaaaa", "lst1 %A", /* 51xx */ + "010100011mmmnnnn", "lst1 %M%N", + "010100100aaaaaaa", "ldp %A", /* 52xx */ + "010100101mmmnnnn", "ldp %M%N", + "010100110aaaaaaa", "lph %A", /* 53xx */ + "010100111mmmnnnn", "lph %M%N", + "010101000aaaaaaa", "pshd %A", /* 54xx */ + "010101001mmmnnnn", "pshd %M%N", -typedef unsigned char byte; -typedef unsigned short int word; - -#define FMT(a,b) a, b -#define PTRS_PER_FORMAT 2 - -static const char *const arith[8] = { "*", "*-", "*+", "??", "BR0-", "*0-", "*0+", "*BR0+" } ; -static const char *const nextar[16] = { "", "", "", "", "", "", "", "", ",AR0", ",AR1", ",AR2", ",AR3", ",AR4", ",AR5", ",AR6", ",AR7" } ; -static const char *const cmpmode[4] = { "0 (ARx = AR0)" , "1 (ARx < AR0)" , "2 (ARx > AR0)" , "3 (ARx <> AR0)" } ; - - -static const char *const TMS32025Formats[] = { - FMT("0000tttt0aaaaaaa", "add %A,%T"), /* 0xxx */ - FMT("0000tttt1mmmnnnn", "add %M,%T%N"), - FMT("0001tttt0aaaaaaa", "sub %A,%T"), /* 1xxx */ - FMT("0001tttt1mmmnnnn", "sub %M,%T%N"), - FMT("0010tttt0aaaaaaa", "lac %A,%T"), /* 2xxx */ - FMT("0010tttt1mmmnnnn", "lac %M,%T%N"), - FMT("00110rrr0aaaaaaa", "lar %R,%A"), /* 3xxx */ - FMT("00110rrr1mmmnnnn", "lar %R%M%N"), - FMT("001110000aaaaaaa", "mpy %A"), /* 38xx */ - FMT("001110001mmmnnnn", "mpy %M%N"), - FMT("001110010aaaaaaa", "sqra %A"), /* 39xx */ - FMT("001110011mmmnnnn", "sqra %M%N"), - FMT("001110100aaaaaaa", "mpya %A"), /* 3Axx */ - FMT("001110101mmmnnnn", "mpya %M%N"), - FMT("001110110aaaaaaa", "mpys %A"), /* 3Bxx */ - FMT("001110111mmmnnnn", "mpys %M%N"), - FMT("001111000aaaaaaa", "lt %A"), /* 3Cxx */ - FMT("001111001mmmnnnn", "lt %M%N"), - FMT("001111010aaaaaaa", "lta %A"), /* 3Dxx */ - FMT("001111011mmmnnnn", "lta %M%N"), - FMT("001111100aaaaaaa", "ltp %A"), /* 3Exx */ - FMT("001111101mmmnnnn", "ltp %M%N"), - FMT("001111110aaaaaaa", "ltd %A"), /* 3Fxx */ - FMT("001111111mmmnnnn", "ltd %M%N"), - FMT("010000000aaaaaaa", "zalh %A"), /* 40xx */ - FMT("010000001mmmnnnn", "zalh %M%N"), - FMT("010000010aaaaaaa", "zals %A"), /* 41xx */ - FMT("010000011mmmnnnn", "zals %M%N"), - FMT("010000100aaaaaaa", "lact %A"), /* 42xx */ - FMT("010000101mmmnnnn", "lact %M%N"), - FMT("010000110aaaaaaa", "addc %A%S"), /* 43xx */ - FMT("010000111mmmnnnn", "addc %M%S%N"), - FMT("010001000aaaaaaa", "subh %A"), /* 44xx */ - FMT("010001001mmmnnnn", "subh %M%N"), - FMT("010001010aaaaaaa", "subs %A"), /* 45xx */ - FMT("010001011mmmnnnn", "subs %M%N"), - FMT("010001100aaaaaaa", "subt %A"), /* 46xx */ - FMT("010001101mmmnnnn", "subt %M%N"), - FMT("010001110aaaaaaa", "subc %A"), /* 47xx */ - FMT("010001111mmmnnnn", "subc %M%N"), - FMT("010010000aaaaaaa", "addh %A"), /* 48xx */ - FMT("010010001mmmnnnn", "addh %M%N"), - FMT("010010010aaaaaaa", "adds %A"), /* 49xx */ - FMT("010010011mmmnnnn", "adds %M%N"), - FMT("010010100aaaaaaa", "addt %A"), /* 4Axx */ - FMT("010010101mmmnnnn", "addt %M%N"), - FMT("010010110aaaaaaa", "rpt %A"), /* 4Bxx */ - FMT("010010111mmmnnnn", "rpt %M%N"), - FMT("010011000aaaaaaa", "xor %A"), /* 4Cxx */ - FMT("010011001mmmnnnn", "xor %M%N"), - FMT("010011010aaaaaaa", "or %A"), /* 4Dxx */ - FMT("010011011mmmnnnn", "or %M%N"), - FMT("010011100aaaaaaa", "and %A"), /* 4Exx */ - FMT("010011101mmmnnnn", "and %M%N"), - FMT("010011110aaaaaaa", "subb %A"), /* 4Fxx */ - FMT("010011111mmmnnnn", "subb %M%N"), - FMT("010100000aaaaaaa", "lst %A"), /* 50xx */ - FMT("010100001mmmnnnn", "lst %M%N"), - FMT("010100010aaaaaaa", "lst1 %A"), /* 51xx */ - FMT("010100011mmmnnnn", "lst1 %M%N"), - FMT("010100100aaaaaaa", "ldp %A"), /* 52xx */ - FMT("010100101mmmnnnn", "ldp %M%N"), - FMT("010100110aaaaaaa", "lph %A"), /* 53xx */ - FMT("010100111mmmnnnn", "lph %M%N"), - FMT("010101000aaaaaaa", "pshd %A"), /* 54xx */ - FMT("010101001mmmnnnn", "pshd %M%N"), - -/* FMT("010101010aaaaaaa", "mar %A"), 55xx */ +/* "010101010aaaaaaa", "mar %A", 55xx */ /* MAR direct has been expanded out to all its variations because one of its */ /* its opcodes is the same as NOP. Actually MAR direct just performs a NOP */ - FMT("0101010100000000", "nop"), /* 5500 */ - FMT("0101010100000001", "mar $01"), - FMT("0101010100000010", "mar $02"), - FMT("0101010100000011", "mar $03"), - FMT("0101010100000100", "mar $04"), - FMT("0101010100000101", "mar $05"), - FMT("0101010100000110", "mar $06"), - FMT("0101010100000111", "mar $07"), - FMT("0101010100001000", "mar $08"), - FMT("0101010100001001", "mar $09"), - FMT("0101010100001010", "mar $0A"), - FMT("0101010100001011", "mar $0B"), - FMT("0101010100001100", "mar $0C"), - FMT("0101010100001101", "mar $0D"), - FMT("0101010100001110", "mar $0E"), - FMT("0101010100001111", "mar $0F"), - FMT("010101010001tttt", "mar $1%T"), - FMT("010101010010tttt", "mar $2%T"), - FMT("010101010011tttt", "mar $3%T"), - FMT("010101010100tttt", "mar $4%T"), - FMT("010101010101tttt", "mar $5%T"), - FMT("010101010110tttt", "mar $6%T"), - FMT("010101010111tttt", "mar $7%T"), + "0101010100000000", "nop", /* 5500 */ + "0101010100000001", "mar $01", + "0101010100000010", "mar $02", + "0101010100000011", "mar $03", + "0101010100000100", "mar $04", + "0101010100000101", "mar $05", + "0101010100000110", "mar $06", + "0101010100000111", "mar $07", + "0101010100001000", "mar $08", + "0101010100001001", "mar $09", + "0101010100001010", "mar $0A", + "0101010100001011", "mar $0B", + "0101010100001100", "mar $0C", + "0101010100001101", "mar $0D", + "0101010100001110", "mar $0E", + "0101010100001111", "mar $0F", + "010101010001tttt", "mar $1%T", + "010101010010tttt", "mar $2%T", + "010101010011tttt", "mar $3%T", + "010101010100tttt", "mar $4%T", + "010101010101tttt", "mar $5%T", + "010101010110tttt", "mar $6%T", + "010101010111tttt", "mar $7%T", -/* FMT("010101011mmmnnnn", "mar %M%N"), 55xx */ +/* "010101011mmmnnnn", "mar %M%N", 55xx */ /* MAR indirect has been expanded out to all its variations because one of */ /* its opcodes, is the same as LARP (actually performs the same function) */ - FMT("0101010110000xxx", "mar *"), /* 558x */ - FMT("0101010110001kkk", "larp %K"), /* 558x */ - FMT("010101011001nnnn", "mar *-%N"), /* 558x */ - FMT("010101011010nnnn", "mar *+%N"), - FMT("010101011011nnnn", "mar ??%N"), - FMT("010101011100nnnn", "mar *BR0-%N"), - FMT("010101011101nnnn", "mar *0-%N"), - FMT("010101011110nnnn", "mar *0+%N"), - FMT("010101011111nnnn", "mar *BR0+%N"), + "0101010110000xxx", "mar *", /* 558x */ + "0101010110001kkk", "larp %K", /* 558x */ + "010101011001nnnn", "mar *-%N", /* 558x */ + "010101011010nnnn", "mar *+%N", + "010101011011nnnn", "mar ??%N", + "010101011100nnnn", "mar *BR0-%N", + "010101011101nnnn", "mar *0-%N", + "010101011110nnnn", "mar *0+%N", + "010101011111nnnn", "mar *BR0+%N", - FMT("010101100aaaaaaa", "dmov %A"), /* 56xx */ - FMT("010101101mmmnnnn", "dmov %M%N"), - FMT("010101110aaaaaaa", "bitt %A"), /* 57xx */ - FMT("010101111mmmnnnn", "bitt %M%N"), - FMT("010110000aaaaaaa", "tblr %A"), /* 58xx */ - FMT("010110001mmmnnnn", "tblr %M%N"), - FMT("010110010aaaaaaa", "tblw %A"), /* 59xx */ - FMT("010110011mmmnnnn", "tblw %M%N"), - FMT("010110100aaaaaaa", "sqrs %A"), /* 5Axx */ - FMT("010110101mmmnnnn", "sqrs %M%N"), - FMT("010110110aaaaaaa", "lts %A"), /* 5Bxx */ - FMT("010110111mmmnnnn", "lts %M%N"), - FMT("010111000aaaaaaabbbbbbbbbbbbbbbb", "macd %B,%A"), /* 5Cxx */ - FMT("010111001mmmnnnnbbbbbbbbbbbbbbbb", "macd %B,%M%N"), - FMT("010111010aaaaaaabbbbbbbbbbbbbbbb", "mac %B,%A"), /* 5Dxx */ - FMT("010111011mmmnnnnbbbbbbbbbbbbbbbb", "mac %B,%M%N"), - FMT("010111101mmmnnnnbbbbbbbbbbbbbbbb", "bc %B %M%N"), /* 5Exx */ - FMT("010111111mmmnnnnbbbbbbbbbbbbbbbb", "bnc %B %M%N"), /* 5Fxx */ - FMT("01100sss0aaaaaaa", "sacl %A%S"), /* 6xxx */ - FMT("01100sss1mmmnnnn", "sacl %M%S%N"), - FMT("01101sss0aaaaaaa", "sach %A%S"), /* 6Xxx */ - FMT("01101sss1mmmnnnn", "sach %M%S%N"), - FMT("01110rrr0aaaaaaa", "sar %R,%A"), /* 7xxx */ - FMT("01110rrr1mmmnnnn", "sar %R%M%N"), - FMT("011110000aaaaaaa", "sst %A"), /* 78xx */ - FMT("011110001mmmnnnn", "sst %M%N"), - FMT("011110010aaaaaaa", "sst1 %A"), /* 79xx */ - FMT("011110011mmmnnnn", "sst1 %M%N"), - FMT("011110100aaaaaaa", "popd %A"), /* 7Axx */ - FMT("011110101mmmnnnn", "popd %M%N"), - FMT("011110110aaaaaaa", "zalr %A"), /* 7Bxx */ - FMT("011110111mmmnnnn", "zalr %M%N"), - FMT("011111000aaaaaaa", "spl %A"), /* 7Cxx */ - FMT("011111001mmmnnnn", "spl %M%N"), - FMT("011111010aaaaaaa", "sph %A"), /* 7Dxx */ - FMT("011111011mmmnnnn", "sph %M%N"), - FMT("011111100aaaaaaa", "adrk %A"), /* 7Exx */ - FMT("011111101mmmnnnn", "adrk %M%N"), - FMT("011111110aaaaaaa", "sbrk %A"), /* 7Fxx */ - FMT("011111111mmmnnnn", "sbrk %M%N"), - FMT("1000pppp0aaaaaaa", "in %A,%P"), /* 8xxx */ - FMT("1000pppp1mmmnnnn", "in %M,%P%N"), - FMT("1001tttt0aaaaaaa", "bit %A,%T"), /* 9xxx */ - FMT("1001tttt1mmmnnnn", "bit %M,%T%N"), - FMT("101wwwwwwwwwwwww", "mpyk %W"), /* Axxx-Bxxx */ - FMT("11000rrrdddddddd", "lark %R,%D"), /* Cxxx */ - FMT("1100100kdddddddd", "ldpk %K%D"), /* Cxxx */ -/* FMT("11001010dddddddd", "lack %D"), CAxx */ + "010101100aaaaaaa", "dmov %A", /* 56xx */ + "010101101mmmnnnn", "dmov %M%N", + "010101110aaaaaaa", "bitt %A", /* 57xx */ + "010101111mmmnnnn", "bitt %M%N", + "010110000aaaaaaa", "tblr %A", /* 58xx */ + "010110001mmmnnnn", "tblr %M%N", + "010110010aaaaaaa", "tblw %A", /* 59xx */ + "010110011mmmnnnn", "tblw %M%N", + "010110100aaaaaaa", "sqrs %A", /* 5Axx */ + "010110101mmmnnnn", "sqrs %M%N", + "010110110aaaaaaa", "lts %A", /* 5Bxx */ + "010110111mmmnnnn", "lts %M%N", + "010111000aaaaaaabbbbbbbbbbbbbbbb", "macd %B,%A", /* 5Cxx */ + "010111001mmmnnnnbbbbbbbbbbbbbbbb", "macd %B,%M%N", + "010111010aaaaaaabbbbbbbbbbbbbbbb", "mac %B,%A", /* 5Dxx */ + "010111011mmmnnnnbbbbbbbbbbbbbbbb", "mac %B,%M%N", + "010111101mmmnnnnbbbbbbbbbbbbbbbb", "bc %B %M%N", /* 5Exx */ + "010111111mmmnnnnbbbbbbbbbbbbbbbb", "bnc %B %M%N", /* 5Fxx */ + "01100sss0aaaaaaa", "sacl %A%S", /* 6xxx */ + "01100sss1mmmnnnn", "sacl %M%S%N", + "01101sss0aaaaaaa", "sach %A%S", /* 6Xxx */ + "01101sss1mmmnnnn", "sach %M%S%N", + "01110rrr0aaaaaaa", "sar %R,%A", /* 7xxx */ + "01110rrr1mmmnnnn", "sar %R%M%N", + "011110000aaaaaaa", "sst %A", /* 78xx */ + "011110001mmmnnnn", "sst %M%N", + "011110010aaaaaaa", "sst1 %A", /* 79xx */ + "011110011mmmnnnn", "sst1 %M%N", + "011110100aaaaaaa", "popd %A", /* 7Axx */ + "011110101mmmnnnn", "popd %M%N", + "011110110aaaaaaa", "zalr %A", /* 7Bxx */ + "011110111mmmnnnn", "zalr %M%N", + "011111000aaaaaaa", "spl %A", /* 7Cxx */ + "011111001mmmnnnn", "spl %M%N", + "011111010aaaaaaa", "sph %A", /* 7Dxx */ + "011111011mmmnnnn", "sph %M%N", + "011111100aaaaaaa", "adrk %A", /* 7Exx */ + "011111101mmmnnnn", "adrk %M%N", + "011111110aaaaaaa", "sbrk %A", /* 7Fxx */ + "011111111mmmnnnn", "sbrk %M%N", + "1000pppp0aaaaaaa", "in %A,%P", /* 8xxx */ + "1000pppp1mmmnnnn", "in %M,%P%N", + "1001tttt0aaaaaaa", "bit %A,%T", /* 9xxx */ + "1001tttt1mmmnnnn", "bit %M,%T%N", + "101wwwwwwwwwwwww", "mpyk %W", /* Axxx-Bxxx */ + "11000rrrdddddddd", "lark %R,%D", /* Cxxx */ + "1100100kdddddddd", "ldpk %K%D", /* Cxxx */ +/* "11001010dddddddd", "lack %D", CAxx */ /* LACK has been expanded out to all its variations because one of its */ /* its opcodes is the same as ZAC. Actually, it performs the same function */ - FMT("1100101000000000", "zac"), /* CA00 */ - FMT("1100101000000001", "lack 01h"), /* CAxx */ - FMT("1100101000000010", "lack 02h"), - FMT("1100101000000011", "lack 03h"), - FMT("1100101000000100", "lack 04h"), - FMT("1100101000000101", "lack 05h"), - FMT("1100101000000110", "lack 06h"), - FMT("1100101000000111", "lack 07h"), - FMT("1100101000001000", "lack 08h"), - FMT("1100101000001001", "lack 09h"), - FMT("1100101000001010", "lack 0Ah"), - FMT("1100101000001011", "lack 0Bh"), - FMT("1100101000001100", "lack 0Ch"), - FMT("1100101000001101", "lack 0Dh"), - FMT("1100101000001110", "lack 0Eh"), - FMT("1100101000001111", "lack 0Fh"), - FMT("110010100001tttt", "lack 1%T"), - FMT("110010100010tttt", "lack 2%T"), - FMT("110010100011tttt", "lack 3%T"), - FMT("110010100100tttt", "lack 4%T"), - FMT("110010100101tttt", "lack 5%T"), - FMT("110010100110tttt", "lack 6%T"), - FMT("110010100111tttt", "lack 7%T"), - FMT("110010101000tttt", "lack 8%T"), - FMT("110010101001tttt", "lack 9%T"), - FMT("110010101010tttt", "lack A%T"), - FMT("110010101011tttt", "lack B%T"), - FMT("110010101100tttt", "lack C%T"), - FMT("110010101101tttt", "lack D%T"), - FMT("110010101110tttt", "lack E%T"), - FMT("110010101111tttt", "lack F%T"), + "1100101000000000", "zac", /* CA00 */ + "1100101000000001", "lack 01h", /* CAxx */ + "1100101000000010", "lack 02h", + "1100101000000011", "lack 03h", + "1100101000000100", "lack 04h", + "1100101000000101", "lack 05h", + "1100101000000110", "lack 06h", + "1100101000000111", "lack 07h", + "1100101000001000", "lack 08h", + "1100101000001001", "lack 09h", + "1100101000001010", "lack 0Ah", + "1100101000001011", "lack 0Bh", + "1100101000001100", "lack 0Ch", + "1100101000001101", "lack 0Dh", + "1100101000001110", "lack 0Eh", + "1100101000001111", "lack 0Fh", + "110010100001tttt", "lack 1%T", + "110010100010tttt", "lack 2%T", + "110010100011tttt", "lack 3%T", + "110010100100tttt", "lack 4%T", + "110010100101tttt", "lack 5%T", + "110010100110tttt", "lack 6%T", + "110010100111tttt", "lack 7%T", + "110010101000tttt", "lack 8%T", + "110010101001tttt", "lack 9%T", + "110010101010tttt", "lack A%T", + "110010101011tttt", "lack B%T", + "110010101100tttt", "lack C%T", + "110010101101tttt", "lack D%T", + "110010101110tttt", "lack E%T", + "110010101111tttt", "lack F%T", - FMT("11001011dddddddd", "rptk %D"), /* CBxx */ - FMT("11001100dddddddd", "addk %D"), /* CCxx */ - FMT("11001101dddddddd", "subk %D"), /* CDxx */ - FMT("1100111000000000", "eint"), /* CE00 */ - FMT("1100111000000001", "dint"), /* CE01 */ - FMT("1100111000000010", "rovm"), /* CE02 */ - FMT("1100111000000011", "sovm"), /* CE03 */ - FMT("1100111000000100", "cnfd"), /* CE04 */ - FMT("1100111000000101", "cnfp"), /* CE05 */ - FMT("1100111000000110", "rsxm"), /* CE06 */ - FMT("1100111000000111", "ssxm"), /* CE07 */ - FMT("11001110000010kk", "spm %K"), /* CE0x */ - FMT("1100111000001100", "rxf"), /* CE0C */ - FMT("1100111000001101", "sxf"), /* CE0D */ - FMT("110011100000111k", "fort %K"), /* CE0x */ - FMT("1100111000010100", "pac"), /* CE14 */ - FMT("1100111000010101", "apac"), /* CE15 */ - FMT("1100111000010110", "spac"), /* CE16 */ - FMT("1100111000011000", "sfl"), /* CE18 */ - FMT("1100111000011001", "sfr"), /* CE19 */ - FMT("1100111000011011", "abs"), /* CE1B */ - FMT("1100111000011100", "push"), /* CE1C */ - FMT("1100111000011101", "pop"), /* CE1D */ - FMT("1100111000011110", "trap"), /* CE1E */ - FMT("1100111000011111", "idle"), /* CE1F */ - FMT("1100111000100000", "rtxm"), /* CE20 */ - FMT("1100111000100001", "stxm"), /* CE21 */ - FMT("1100111000100011", "neg"), /* CE23 */ - FMT("1100111000100100", "cala"), /* CE24 */ - FMT("1100111000100101", "bacc"), /* CE25 */ - FMT("1100111000100110", "ret"), /* CE26 */ - FMT("1100111000100111", "cmpl"), /* CE27 */ - FMT("1100111000110000", "rc"), /* CE30 */ - FMT("1100111000110001", "sc"), /* CE31 */ - FMT("1100111000110010", "rtc"), /* CE32 */ - FMT("1100111000110011", "stc"), /* CE33 */ - FMT("1100111000110100", "rol"), /* CE34 */ - FMT("1100111000110101", "ror"), /* CE35 */ - FMT("1100111000110110", "rfsm"), /* CE36 */ - FMT("1100111000110111", "sfsm"), /* CE37 */ - FMT("1100111000111000", "rhm"), /* CE38 */ - FMT("1100111000111001", "shm"), /* CE39 */ - FMT("11001110001111kk", "conf %K"), /* CE3x */ - FMT("11001110010100cc", "cmpr %C"), /* CE5x */ - FMT("110011101mmm0010", "norm %M"), /* CEx2 */ - FMT("110011110aaaaaaa", "mpys %A"), /* CFxx */ - FMT("110011111mmmnnnn", "mpys %M%N"), - FMT("11010rrr00000000wwwwwwwwwwwwwwww", "lrlk %R,%W"), /* Dx00 */ - FMT("1101tttt00000001wwwwwwwwwwwwwwww", "lalk %W,%T"), /* Dx01 */ - FMT("1101tttt00000010wwwwwwwwwwwwwwww", "adlk %W,%T"), /* Dx02 */ - FMT("1101tttt00000011wwwwwwwwwwwwwwww", "sblk %W,%T"), /* Dx03 */ - FMT("1101tttt00000100wwwwwwwwwwwwwwww", "andk %W,%T"), /* Dx04 */ - FMT("1101tttt00000101wwwwwwwwwwwwwwww", "ork %W,%T"), /* Dx05 */ - FMT("1101tttt00000110wwwwwwwwwwwwwwww", "xork %W,%T"), /* Dx06 */ - FMT("1110pppp0aaaaaaa", "out %A,%P"), /* Exxx */ - FMT("1110pppp1mmmnnnn", "out %M,%P%N"), - FMT("111100001mmmnnnnbbbbbbbbbbbbbbbb", "bv %B %M%N"), /* F0xx */ - FMT("111100011mmmnnnnbbbbbbbbbbbbbbbb", "bgz %B %M%N"), /* F1xx */ - FMT("111100101mmmnnnnbbbbbbbbbbbbbbbb", "blez %B %M%N"), /* F2xx */ - FMT("111100111mmmnnnnbbbbbbbbbbbbbbbb", "blz %B %M%N"), /* F3xx */ - FMT("111101001mmmnnnnbbbbbbbbbbbbbbbb", "bgez %B %M%N"), /* F4xx */ - FMT("111101011mmmnnnnbbbbbbbbbbbbbbbb", "bnz %B %M%N"), /* F5xx */ - FMT("111101101mmmnnnnbbbbbbbbbbbbbbbb", "bz %B %M%N"), /* F6xx */ - FMT("111101111mmmnnnnbbbbbbbbbbbbbbbb", "bnv %B %M%N"), /* F7xx */ - FMT("111110001mmmnnnnbbbbbbbbbbbbbbbb", "bbz %B %M%N"), /* F8xx */ - FMT("111110011mmmnnnnbbbbbbbbbbbbbbbb", "bbnz %B %M%N"), /* F9xx */ - FMT("111110101mmmnnnnbbbbbbbbbbbbbbbb", "bioz %B %M%N"), /* FAxx */ - FMT("111110111mmmnnnnbbbbbbbbbbbbbbbb", "banz %B %M%N"), /* FBxx */ - FMT("111111000aaaaaaabbbbbbbbbbbbbbbb", "blkp %B,%A"), /* FCxx */ - FMT("111111001mmmnnnnbbbbbbbbbbbbbbbb", "blkp %B,%M%N"), - FMT("111111010aaaaaaabbbbbbbbbbbbbbbb", "blkd %B,%A"), /* FDxx */ - FMT("111111011mmmnnnnbbbbbbbbbbbbbbbb", "blkd %B,%M%N"), - FMT("111111101mmmnnnnbbbbbbbbbbbbbbbb", "call %B %M%N"), /* FExx */ - FMT("111111111mmmnnnnbbbbbbbbbbbbbbbb", "b %B %M%N"), /* FFxx */ + "11001011dddddddd", "rptk %D", /* CBxx */ + "11001100dddddddd", "addk %D", /* CCxx */ + "11001101dddddddd", "subk %D", /* CDxx */ + "1100111000000000", "eint", /* CE00 */ + "1100111000000001", "dint", /* CE01 */ + "1100111000000010", "rovm", /* CE02 */ + "1100111000000011", "sovm", /* CE03 */ + "1100111000000100", "cnfd", /* CE04 */ + "1100111000000101", "cnfp", /* CE05 */ + "1100111000000110", "rsxm", /* CE06 */ + "1100111000000111", "ssxm", /* CE07 */ + "11001110000010kk", "spm %K", /* CE0x */ + "1100111000001100", "rxf", /* CE0C */ + "1100111000001101", "sxf", /* CE0D */ + "110011100000111k", "fort %K", /* CE0x */ + "1100111000010100", "pac", /* CE14 */ + "1100111000010101", "apac", /* CE15 */ + "1100111000010110", "spac", /* CE16 */ + "1100111000011000", "sfl", /* CE18 */ + "1100111000011001", "sfr", /* CE19 */ + "1100111000011011", "abs", /* CE1B */ + "1100111000011100", "push", /* CE1C */ + "1100111000011101", "pop", /* CE1D */ + "1100111000011110", "trap", /* CE1E */ + "1100111000011111", "idle", /* CE1F */ + "1100111000100000", "rtxm", /* CE20 */ + "1100111000100001", "stxm", /* CE21 */ + "1100111000100011", "neg", /* CE23 */ + "1100111000100100", "cala", /* CE24 */ + "1100111000100101", "bacc", /* CE25 */ + "1100111000100110", "ret", /* CE26 */ + "1100111000100111", "cmpl", /* CE27 */ + "1100111000110000", "rc", /* CE30 */ + "1100111000110001", "sc", /* CE31 */ + "1100111000110010", "rtc", /* CE32 */ + "1100111000110011", "stc", /* CE33 */ + "1100111000110100", "rol", /* CE34 */ + "1100111000110101", "ror", /* CE35 */ + "1100111000110110", "rfsm", /* CE36 */ + "1100111000110111", "sfsm", /* CE37 */ + "1100111000111000", "rhm", /* CE38 */ + "1100111000111001", "shm", /* CE39 */ + "11001110001111kk", "conf %K", /* CE3x */ + "11001110010100cc", "cmpr %C", /* CE5x */ + "110011101mmm0010", "norm %M", /* CEx2 */ + "110011110aaaaaaa", "mpys %A", /* CFxx */ + "110011111mmmnnnn", "mpys %M%N", + "11010rrr00000000wwwwwwwwwwwwwwww", "lrlk %R,%W", /* Dx00 */ + "1101tttt00000001wwwwwwwwwwwwwwww", "lalk %W,%T", /* Dx01 */ + "1101tttt00000010wwwwwwwwwwwwwwww", "adlk %W,%T", /* Dx02 */ + "1101tttt00000011wwwwwwwwwwwwwwww", "sblk %W,%T", /* Dx03 */ + "1101tttt00000100wwwwwwwwwwwwwwww", "andk %W,%T", /* Dx04 */ + "1101tttt00000101wwwwwwwwwwwwwwww", "ork %W,%T", /* Dx05 */ + "1101tttt00000110wwwwwwwwwwwwwwww", "xork %W,%T", /* Dx06 */ + "1110pppp0aaaaaaa", "out %A,%P", /* Exxx */ + "1110pppp1mmmnnnn", "out %M,%P%N", + "111100001mmmnnnnbbbbbbbbbbbbbbbb", "bv %B %M%N", /* F0xx */ + "111100011mmmnnnnbbbbbbbbbbbbbbbb", "bgz %B %M%N", /* F1xx */ + "111100101mmmnnnnbbbbbbbbbbbbbbbb", "blez %B %M%N", /* F2xx */ + "111100111mmmnnnnbbbbbbbbbbbbbbbb", "blz %B %M%N", /* F3xx */ + "111101001mmmnnnnbbbbbbbbbbbbbbbb", "bgez %B %M%N", /* F4xx */ + "111101011mmmnnnnbbbbbbbbbbbbbbbb", "bnz %B %M%N", /* F5xx */ + "111101101mmmnnnnbbbbbbbbbbbbbbbb", "bz %B %M%N", /* F6xx */ + "111101111mmmnnnnbbbbbbbbbbbbbbbb", "bnv %B %M%N", /* F7xx */ + "111110001mmmnnnnbbbbbbbbbbbbbbbb", "bbz %B %M%N", /* F8xx */ + "111110011mmmnnnnbbbbbbbbbbbbbbbb", "bbnz %B %M%N", /* F9xx */ + "111110101mmmnnnnbbbbbbbbbbbbbbbb", "bioz %B %M%N", /* FAxx */ + "111110111mmmnnnnbbbbbbbbbbbbbbbb", "banz %B %M%N", /* FBxx */ + "111111000aaaaaaabbbbbbbbbbbbbbbb", "blkp %B,%A", /* FCxx */ + "111111001mmmnnnnbbbbbbbbbbbbbbbb", "blkp %B,%M%N", + "111111010aaaaaaabbbbbbbbbbbbbbbb", "blkd %B,%A", /* FDxx */ + "111111011mmmnnnnbbbbbbbbbbbbbbbb", "blkd %B,%M%N", + "111111101mmmnnnnbbbbbbbbbbbbbbbb", "call %B %M%N", /* FExx */ + "111111111mmmnnnnbbbbbbbbbbbbbbbb", "b %B %M%N", /* FFxx */ nullptr }; -#define MAX_OPS ((ARRAY_LENGTH(TMS32025Formats) - 1) / PTRS_PER_FORMAT) - -struct TMS32025Opcode { - word mask; /* instruction mask */ - word bits; /* constant bits */ - word extcode; /* value that gets extension code */ - const char *parse; /* how to parse bits */ - const char *fmt; /* instruction format */ -}; - -static TMS32025Opcode Op[MAX_OPS+1]; -static int OpInizialized = 0; - -static void InitDasm32025(void) +tms32025_disassembler::tms32025_disassembler() { const char *p; const char *const *ops; - word mask, bits; + u16 mask, bits; int bit; int i; @@ -374,20 +351,14 @@ static void InitDasm32025(void) ops[0],ops[1],bit); } while (isspace((uint8_t)*p)) p++; - if (*p) Op[i].extcode = *p; - Op[i].bits = bits; - Op[i].mask = mask; - Op[i].fmt = ops[1]; - Op[i].parse = ops[0]; + Op.emplace_back(mask, bits, *p, ops[0], ops[1]); - ops += PTRS_PER_FORMAT; + ops += 2; i++; } - - OpInizialized = 1; } -CPU_DISASSEMBLE(tms32025) +offs_t tms32025_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; int a, b, c, d, k, m, n, p, r, s, t, w; /* these can all be filled in by parsing an instruction */ @@ -399,11 +370,9 @@ CPU_DISASSEMBLE(tms32025) //char *buffertmp; const char *cp; /* character pointer in OpFormats */ - if (!OpInizialized) InitDasm32025(); - op = -1; /* no matching opcode */ - code = (oprom[0] << 8) | oprom[1]; - for ( i = 0; i < MAX_OPS; i++) + code = opcodes.r16(pc); + for ( i = 0; i < int(Op.size()); i++) { if ((code & Op[i].mask) == Op[i].bits) { @@ -418,14 +387,14 @@ CPU_DISASSEMBLE(tms32025) if (op == -1) { util::stream_format(stream, "???? dw %04Xh",code); - return cnt | DASMFLAG_SUPPORTED; + return cnt | SUPPORTED; } //buffertmp = buffer; if (Op[op].extcode) { bit = 31; code <<= 16; - code |= (opram[2] << 8) | opram[3]; + code |= opcodes.r16(pc+1); cnt++; } else @@ -466,9 +435,9 @@ CPU_DISASSEMBLE(tms32025) cp = Op[op].fmt; if (!strncmp(cp, "cal", 3)) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (!strncmp(cp, "ret", 3)) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; while (*cp) { @@ -501,5 +470,10 @@ CPU_DISASSEMBLE(tms32025) stream << *cp++; } } - return cnt | flags | DASMFLAG_SUPPORTED; + return cnt | flags | SUPPORTED; +} + +u32 tms32025_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/tms32025/32025dsm.h b/src/devices/cpu/tms32025/32025dsm.h new file mode 100644 index 00000000000..187628b09de --- /dev/null +++ b/src/devices/cpu/tms32025/32025dsm.h @@ -0,0 +1,66 @@ +// license:BSD-3-Clause +// copyright-holders:Tony La Porta, hap + /**************************************************************************\ + * Texas Instruments TMS320x25 DSP Disassembler * + * * + * Copyright Tony La Porta * + * To be used with TMS320x25 DSP Emulator engine. * + * Written for the MAME project. * + * * + * Many thanks to those involved in the i8039 Disassembler * + * as the structure here was borrowed from it. * + * * + * Note : This is a word based microcontroller, with addressing * + * architecture based on the Harvard addressing scheme. * + * * + * * + * A Memory Address * + * B Opcode Address Argument (Requires next opcode read) * + * C Compare mode * + * D Immediate byte load * + * K Immediate bit load * + * W Immediate word load * + * M AR[x] register modification type (for indirect addressing) * + * N ARP register to change ARP pointer to (for indirect addressing) * + * P I/O port address number * + * R AR[R] register to use * + * S Shift ALU left * + * T Shift ALU left (Hex) / Nibble data * + * X Don't care bit * + * * + \**************************************************************************/ + +#ifndef MAME_CPU_TMS32025_32025DSM_H +#define MAME_CPU_TMS32025_32025DSM_H + +#pragma once + +class tms32025_disassembler : public util::disasm_interface +{ +public: + tms32025_disassembler(); + virtual ~tms32025_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct TMS32025Opcode { + u16 mask; /* instruction mask */ + u16 bits; /* constant bits */ + u16 extcode; /* value that gets extension code */ + const char *parse; /* how to parse bits */ + const char *fmt; /* instruction format */ + + TMS32025Opcode(u16 m, u16 b, u16 e, const char *p, const char *f) : mask(m), bits(b), extcode(e), parse(p), fmt(f) {} + }; + + static const char *const arith[8]; + static const char *const nextar[16]; + static const char *const cmpmode[4]; + static const char *const TMS32025Formats[]; + + std::vector<TMS32025Opcode> Op; +}; + +#endif diff --git a/src/devices/cpu/tms32025/dis32025.cpp b/src/devices/cpu/tms32025/dis32025.cpp deleted file mode 100644 index 6df4b92707a..00000000000 --- a/src/devices/cpu/tms32025/dis32025.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Tony La Porta, hap - /**************************************************************************\ - * Texas Instruments TMS320x25 DSP Disassembler * - * * - * Copyright Tony La Porta * - * Written for the MAME project. * - * * - * Notes : Data is expected to be read from source file as MSB first. * - * This is a word based microcontroller, with addressing * - * architecture based on the Harvard addressing scheme. * - * * - \**************************************************************************/ - -#include <stdio.h> -#include <string.h> - -#include "32025dsm.c" - - -unsigned char *Buffer; - - -int main(int argc,char *argv[]) -{ - int length=0, length_to_dump=0, offset=0, disasm_words=0; - int filelength=0, bytes_read; - int Counter=0; - - FILE *F; - char *String_Output; - - if(argc<2) - { - printf("\n"); - printf("TMS32025 Disassembler 1.1 by Tony La Porta (C)2001-2002+\n\n"); - printf("Usage: dis32025 <input-file> [ <start-addr> [ <num-of-addr> ] ]\n"); - printf(" <input-file> source file data must be MSB first\n"); - printf(" <start-addr> starting address to disassemble from (decimal)\n"); - printf(" <num-of-addr> number of addresses to disassemble (decimal)\n"); - printf(" Precede values with 0x if HEX values preffered\n"); - exit(1); - } - - if(!(F=fopen(argv[1],"rb"))) - { - printf("\n%s: Can't open file %s\n",argv[0],argv[1]); - exit(2); - } - argv++; argc--; - if (argv[1]) - { - offset = strtol(argv[1],nullptr,0); - argv++; argc--; - } - if (argv[1]) - { - length = strtol(argv[1],nullptr,0); - argv++; argc--; - } - - fseek(F,0, SEEK_END); - filelength = ftell(F); - - length *= 2; - - if ((length > (filelength - (offset*2))) || (length == 0)) length = filelength - (offset*2); - printf("Length=%04Xh(words) Offset=$%04Xh filelength=%04Xh(words) %04Xh(bytes)\n",length/2,offset,filelength/2,filelength); - length_to_dump = length; - printf("Starting from %d, dumping %d opcodes (word size)\n",offset,length/2); - Buffer = calloc((filelength+1),sizeof(char)); - if (Buffer==nullptr) - { - printf("Out of Memory !!!"); - fclose(F); - exit(3); - } - String_Output = calloc(80,sizeof(char)); - if (String_Output==nullptr) - { - printf("Out of Memory !!!"); - free(Buffer); - fclose(F); - exit(4); - } - - if (fseek(F,0,SEEK_SET) != 0) - { - printf("Error seeking to beginning of file\n"); - free(String_Output); - free(Buffer); - fclose(F); - exit(5); - } - - Counter = offset; - bytes_read = fread(Buffer,sizeof(char),filelength,F); - if (bytes_read >= length) - { - for (; length > 0; length -= (disasm_words*2)) - { - int ii; - disasm_words = Dasm32025(String_Output,Counter); - printf("$%04lX: ",Counter); - for (ii = 0; ii < disasm_words; ii++) - { - if (((Counter*2) + ii) > filelength) /* Past end of length to dump ? */ - { - sprintf(String_Output,"???? dw %02.2X%02.2Xh (Past end of disassembly !)",Buffer[((Counter-1)*2)],Buffer[((Counter-1)*2)+1]); - } - else - { - printf("%02.2x%02.2x ",Buffer[(Counter*2)],Buffer[(Counter*2) + 1]); - } - Counter++ ; - } - for (; ii < 4; ii++) - { - printf(" "); - } - printf("\t%s\n",String_Output); - } - } - else - { - printf("ERROR length to dump was %d ", length_to_dump/2); - printf(", but bytes read from file were %d\n", bytes_read/2); - free(String_Output); - free(Buffer); - fclose(F); - exit(7); - } - free(String_Output); - free(Buffer); - fclose(F); - return(0); -} diff --git a/src/devices/cpu/tms32025/tms32025.cpp b/src/devices/cpu/tms32025/tms32025.cpp index a9405d72f3d..74529d79894 100644 --- a/src/devices/cpu/tms32025/tms32025.cpp +++ b/src/devices/cpu/tms32025/tms32025.cpp @@ -120,6 +120,7 @@ Table 3-2. TMS32025/26 Memory Blocks #include "emu.h" #include "tms32025.h" +#include "32025dsm.h" #include "debugger.h" @@ -253,11 +254,9 @@ device_memory_interface::space_config_vector tms32025_device::memory_space_confi }; } - -offs_t tms32025_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms32025_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms32025 ); - return CPU_DISASSEMBLE_NAME(tms32025)(this, stream, pc, oprom, opram, options); + return new tms32025_disassembler; } READ16_MEMBER( tms32025_device::drr_r) @@ -514,7 +513,7 @@ void tms32025_device::GETDATA(int shift,int signext) m_external_mem_access = 0; } - m_ALU.d = (uint16_t)m_data->read_word(m_memaccess << 1); + m_ALU.d = (uint16_t)m_data->read_word(m_memaccess); if (signext) m_ALU.d = (int16_t)m_ALU.d; m_ALU.d <<= shift; @@ -528,14 +527,14 @@ void tms32025_device::PUTDATA(uint16_t data) if (m_memaccess >= 0x800) m_external_mem_access = 1; /* Pause if hold pin is active */ else m_external_mem_access = 0; - m_data->write_word(IND << 1, data); + m_data->write_word(IND, data); MODIFY_AR_ARP(); } else { if (m_memaccess >= 0x800) m_external_mem_access = 1; /* Pause if hold pin is active */ else m_external_mem_access = 0; - m_data->write_word(DMA << 1, data); + m_data->write_word(DMA, data); } } void tms32025_device::PUTDATA_SST(uint16_t data) @@ -550,7 +549,7 @@ void tms32025_device::PUTDATA_SST(uint16_t data) m_opcode.b.l &= 0xf7; /* Stop ARP changes */ MODIFY_AR_ARP(); } - m_data->write_word(m_memaccess << 1, data); + m_data->write_word(m_memaccess, data); } @@ -638,8 +637,8 @@ void tms32025_device::addt() void tms32025_device::adlk() { m_oldacc.d = m_ACC.d; - if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC << 1); - else m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC); + else m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d += m_ALU.d; @@ -658,7 +657,7 @@ void tms32025_device::and_() void tms32025_device::andk() { m_oldacc.d = m_ACC.d; - m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d &= m_ALU.d; @@ -673,7 +672,7 @@ void tms32025_device::apac() } void tms32025_device::br() { - m_PC = m_direct->read_word(m_PC << 1); + m_PC = m_direct->read_word(m_PC); MODIFY_AR_ARP(); } void tms32025_device::bacc() @@ -682,43 +681,43 @@ void tms32025_device::bacc() } void tms32025_device::banz() { - if (m_AR[ARP]) m_PC = m_direct->read_word(m_PC << 1); + if (m_AR[ARP]) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bbnz() { - if (TC) m_PC = m_direct->read_word(m_PC << 1); + if (TC) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bbz() { - if (TC == 0) m_PC = m_direct->read_word(m_PC << 1); + if (TC == 0) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bc() { - if (CARRY) m_PC = m_direct->read_word(m_PC << 1); + if (CARRY) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bgez() { - if ( (int32_t)(m_ACC.d) >= 0 ) m_PC = m_direct->read_word(m_PC << 1); + if ( (int32_t)(m_ACC.d) >= 0 ) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bgz() { - if ( (int32_t)(m_ACC.d) > 0 ) m_PC = m_direct->read_word(m_PC << 1); + if ( (int32_t)(m_ACC.d) > 0 ) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bioz() { - if (m_bio_in() != CLEAR_LINE) m_PC = m_direct->read_word(m_PC << 1); + if (m_bio_in() != CLEAR_LINE) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } @@ -736,17 +735,17 @@ void tms32025_device::bitt() } void tms32025_device::blez() { - if ( (int32_t)(m_ACC.d) <= 0 ) m_PC = m_direct->read_word(m_PC << 1); + if ( (int32_t)(m_ACC.d) <= 0 ) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::blkd() { /** Fix cycle timing **/ if (m_init_load_addr) { - m_PFC = m_direct->read_word(m_PC << 1); + m_PFC = m_direct->read_word(m_PC); m_PC++; } - m_ALU.d = m_data->read_word(m_PFC << 1); + m_ALU.d = m_data->read_word(m_PFC); PUTDATA(m_ALU.d); m_PFC++; m_tms32025_dec_cycles += (1*CLK); @@ -754,29 +753,29 @@ void tms32025_device::blkd() void tms32025_device::blkp() { /** Fix cycle timing **/ if (m_init_load_addr) { - m_PFC = m_direct->read_word(m_PC << 1); + m_PFC = m_direct->read_word(m_PC); m_PC++; } - m_ALU.d = m_direct->read_word(m_PFC << 1); + m_ALU.d = m_direct->read_word(m_PFC); PUTDATA(m_ALU.d); m_PFC++; m_tms32025_dec_cycles += (2*CLK); } void tms32025_device::blz() { - if ( (int32_t)(m_ACC.d) < 0 ) m_PC = m_direct->read_word(m_PC << 1); + if ( (int32_t)(m_ACC.d) < 0 ) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bnc() { - if (CARRY == 0) m_PC = m_direct->read_word(m_PC << 1); + if (CARRY == 0) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bnv() { - if (OV == 0) m_PC = m_direct->read_word(m_PC << 1); + if (OV == 0) m_PC = m_direct->read_word(m_PC); else { m_PC++ ; CLR0(OV_FLAG); @@ -785,14 +784,14 @@ void tms32025_device::bnv() } void tms32025_device::bnz() { - if (m_ACC.d != 0) m_PC = m_direct->read_word(m_PC << 1); + if (m_ACC.d != 0) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } void tms32025_device::bv() { if (OV) { - m_PC = m_direct->read_word(m_PC << 1); + m_PC = m_direct->read_word(m_PC); CLR0(OV_FLAG); } else m_PC++ ; @@ -800,7 +799,7 @@ void tms32025_device::bv() } void tms32025_device::bz() { - if (m_ACC.d == 0) m_PC = m_direct->read_word(m_PC << 1); + if (m_ACC.d == 0) m_PC = m_direct->read_word(m_PC); else m_PC++ ; MODIFY_AR_ARP(); } @@ -813,7 +812,7 @@ void tms32025_device::call() { m_PC++ ; PUSH_STACK(m_PC); - m_PC = m_direct->read_word((m_PC - 1) << 1); + m_PC = m_direct->read_word(m_PC - 1); MODIFY_AR_ARP(); } void tms32025_device::cmpl() @@ -916,7 +915,7 @@ void tms32025_device::dint() void tms32025_device::dmov() /** Careful with how memory is configured !! */ { GETDATA(0, 0); - m_data->write_word((m_memaccess + 1) << 1, m_ALU.w.l); + m_data->write_word(m_memaccess + 1, m_ALU.w.l); } void tms32025_device::eint() { @@ -934,7 +933,7 @@ void tms32025_device::idle() } void tms32025_device::in() { - m_ALU.w.l = m_io->read_word( (m_opcode.b.h & 0xf) << 1 ); + m_ALU.w.l = m_io->read_word(m_opcode.b.h & 0xf); PUTDATA(m_ALU.w.l); } void tms32025_device::lac() @@ -953,8 +952,8 @@ void tms32025_device::lact() } void tms32025_device::lalk() { - if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC << 1); - else m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC); + else m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d = m_ALU.d; @@ -991,7 +990,7 @@ void tms32025_device::lph() } void tms32025_device::lrlk() { - m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_AR[m_opcode.b.h & 7] = m_ALU.w.l; } @@ -1036,7 +1035,7 @@ void tms32025_device::ltd() /** Careful with how memory is configured !! */ m_oldacc.d = m_ACC.d; GETDATA(0, 0); m_Treg = m_ALU.w.l; - m_data->write_word((m_memaccess+1) << 1, m_ALU.w.l); + m_data->write_word(m_memaccess+1, m_ALU.w.l); SHIFT_Preg_TO_ALU(); m_ACC.d += m_ALU.d; CALCULATE_ADD_OVERFLOW(m_ALU.d); @@ -1064,7 +1063,7 @@ void tms32025_device::mac() /** RAM blocks B0,B1,B2 may be important ! { /** Fix cycle timing **/ m_oldacc.d = m_ACC.d; if (m_init_load_addr) { - m_PFC = m_direct->read_word(m_PC << 1); + m_PFC = m_direct->read_word(m_PC); m_PC++; } SHIFT_Preg_TO_ALU(); @@ -1073,7 +1072,7 @@ void tms32025_device::mac() /** RAM blocks B0,B1,B2 may be important ! CALCULATE_ADD_CARRY(); GETDATA(0, 0); m_Treg = m_ALU.w.l; - m_Preg.d = ( (int16_t)m_ALU.w.l * (int16_t)m_direct->read_word(m_PFC << 1) ); + m_Preg.d = ( (int16_t)m_ALU.w.l * (int16_t)m_direct->read_word(m_PFC) ); m_PFC++; m_tms32025_dec_cycles += (2*CLK); } @@ -1081,7 +1080,7 @@ void tms32025_device::macd() /** RAM blocks B0,B1,B2 may be important ! { /** Fix cycle timing **/ m_oldacc.d = m_ACC.d; if (m_init_load_addr) { - m_PFC = m_direct->read_word(m_PC << 1); + m_PFC = m_direct->read_word(m_PC); m_PC++; } SHIFT_Preg_TO_ALU(); @@ -1090,10 +1089,10 @@ void tms32025_device::macd() /** RAM blocks B0,B1,B2 may be important ! CALCULATE_ADD_CARRY(); GETDATA(0, 0); if ( (m_opcode.b.l & 0x80) || m_init_load_addr ) { /* No writing during repetition, or DMA mode */ - m_data->write_word((m_memaccess+1) << 1, m_ALU.w.l); + m_data->write_word(m_memaccess+1, m_ALU.w.l); } m_Treg = m_ALU.w.l; - m_Preg.d = ( (int16_t)m_ALU.w.l * (int16_t)m_direct->read_word(m_PFC << 1) ); + m_Preg.d = ( (int16_t)m_ALU.w.l * (int16_t)m_direct->read_word(m_PFC) ); m_PFC++; m_tms32025_dec_cycles += (2*CLK); } @@ -1166,7 +1165,7 @@ void tms32025_device::or_() } void tms32025_device::ork() { - m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d |= (m_ALU.d); @@ -1174,7 +1173,7 @@ void tms32025_device::ork() void tms32025_device::out() { GETDATA(0, 0); - m_io->write_word( (m_opcode.b.h & 0xf) << 1, m_ALU.w.l ); + m_io->write_word(m_opcode.b.h & 0xf, m_ALU.w.l ); } void tms32025_device::pac() { @@ -1285,8 +1284,8 @@ void tms32025_device::sar_ar7() { PUTDATA(m_AR[7]); } void tms32025_device::sblk() { m_oldacc.d = m_ACC.d; - if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC << 1); - else m_ALU.d = (uint16_t)m_direct->read_word(m_PC << 1); + if (SXM) m_ALU.d = (int16_t)m_direct->read_word(m_PC); + else m_ALU.d = (uint16_t)m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d -= m_ALU.d; @@ -1477,7 +1476,7 @@ void tms32025_device::tblr() if (m_init_load_addr) { m_PFC = m_ACC.w.l; } - m_ALU.w.l = m_direct->read_word(m_PFC << 1); + m_ALU.w.l = m_direct->read_word(m_PFC); if ( (CNF0) && ( (uint16_t)(m_PFC) >= 0xff00 ) ) {} /** TMS32025 only */ else m_tms32025_dec_cycles += (1*CLK); PUTDATA(m_ALU.w.l); @@ -1491,7 +1490,7 @@ void tms32025_device::tblw() m_tms32025_dec_cycles += (1*CLK); GETDATA(0, 0); if (m_external_mem_access) m_tms32025_dec_cycles += (1*CLK); - m_program->write_word(m_PFC << 1, m_ALU.w.l); + m_program->write_word(m_PFC, m_ALU.w.l); m_PFC++; } void tms32025_device::trap() @@ -1506,7 +1505,7 @@ void tms32025_device::xor_() } void tms32025_device::xork() { - m_ALU.d = m_direct->read_word(m_PC << 1); + m_ALU.d = m_direct->read_word(m_PC); m_PC++; m_ALU.d <<= (m_opcode.b.h & 0xf); m_ACC.d ^= m_ALU.d; @@ -1620,7 +1619,7 @@ const tms32025_device::tms32025_opcode tms32025_device::s_opcode_Dx_subset[8]= void tms32025_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); @@ -1968,7 +1967,7 @@ void tms32025_device::execute_run() debugger_instruction_hook(this, m_PC); - m_opcode.d = m_direct->read_word(m_PC << 1); + m_opcode.d = m_direct->read_word(m_PC); m_PC++; if (m_opcode.b.h == 0xCE) /* Opcode 0xCExx has many sub-opcodes in its minor byte */ @@ -2002,7 +2001,7 @@ void tms32025_device::execute_run() debugger_instruction_hook(this, m_PC); - m_opcode.d = m_direct->read_word(m_PC << 1); + m_opcode.d = m_direct->read_word(m_PC); m_PC++; m_tms32025_dec_cycles += (1*CLK); diff --git a/src/devices/cpu/tms32025/tms32025.h b/src/devices/cpu/tms32025/tms32025.h index a9ae17576c4..66c76bc001b 100644 --- a/src/devices/cpu/tms32025/tms32025.h +++ b/src/devices/cpu/tms32025/tms32025.h @@ -125,9 +125,7 @@ protected: 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 2; } - 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; + virtual util::disasm_interface *create_disassembler() override; void common_reset(); @@ -141,7 +139,7 @@ protected: optional_shared_ptr<uint16_t> m_b3; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; address_space *m_io; @@ -204,10 +202,6 @@ protected: inline void MODIFY_DP(int data); inline void MODIFY_PM(int data); inline void MODIFY_ARP(int data); - inline uint16_t M_RDROM(offs_t addr); - inline void M_WRTROM(offs_t addr, uint16_t data); - inline uint16_t M_RDRAM(offs_t addr); - inline void M_WRTRAM(offs_t addr, uint16_t data); uint16_t reverse_carry_add(uint16_t arg0, uint16_t arg1 ); inline void MODIFY_AR_ARP(); inline void CALCULATE_ADD_CARRY(); diff --git a/src/devices/cpu/tms32031/dis32031.cpp b/src/devices/cpu/tms32031/dis32031.cpp index b6012827611..6bb468e164a 100644 --- a/src/devices/cpu/tms32031/dis32031.cpp +++ b/src/devices/cpu/tms32031/dis32031.cpp @@ -9,40 +9,13 @@ ***************************************************************************/ #include "emu.h" -#include "tms32031.h" - - -/*************************************************************************** - MEMORY ACCESSORS -***************************************************************************/ - -#define INTEGER 0 -#define FLOAT 1 -#define NODEST 2 -#define NOSOURCE 4 -#define NOSOURCE1 NOSOURCE -#define NOSOURCE2 8 -#define SWAPSRCDST 16 -#define UNSIGNED 32 - +#include "dis32031.h" /*************************************************************************** CODE CODE ***************************************************************************/ -#if 0 -static inline char *signed_16bit(int16_t val) -{ - static char temp[10]; - if (val < 0) - sprintf(temp, "-$%x", -val & 0xffff); - else - sprintf(temp, "$%x", val); - return temp; -} -#endif - -static const char *const regname[32] = +const char *const tms32031_disassembler::regname[32] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "AR0", "AR1", "AR2", "AR3", "AR4", "AR5", "AR6", "AR7", @@ -50,7 +23,7 @@ static const char *const regname[32] = "IOF", "RS", "RE", "RC", "??", "??", "??", "??" }; -static const char *const condition[32] = +const char *const tms32031_disassembler::condition[32] = { "U", "LO", "LS", "HI", "HS", "EQ", "NE", "LT", "LE", "GT", "GE", "??", "NV", "V", "NUF", "UF", @@ -122,7 +95,7 @@ static const char *const condition[32] = // 19 = LUF (LUF) // 20 = ZUF (Z | UF) -static void append_indirect(uint8_t ma, int8_t disp, std::ostream &stream) +void tms32031_disassembler::append_indirect(uint8_t ma, int8_t disp, std::ostream &stream) { std::string dispstr; int mode = (ma >> 3) & 0x1f; @@ -172,14 +145,14 @@ static void append_indirect(uint8_t ma, int8_t disp, std::ostream &stream) } } -static std::string get_indirect(uint8_t ma, int8_t disp) +std::string tms32031_disassembler::get_indirect(uint8_t ma, int8_t disp) { std::ostringstream stream; append_indirect(ma, disp, stream); return stream.str(); } -static void append_immediate(uint16_t data, int is_float, int is_unsigned, std::ostream &stream) +void tms32031_disassembler::append_immediate(uint16_t data, int is_float, int is_unsigned, std::ostream &stream) { if (is_float) { @@ -203,7 +176,7 @@ static void append_immediate(uint16_t data, int is_float, int is_unsigned, std:: util::stream_format(stream, "$%04X", data); } -static void disasm_general(const char *opstring, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_general(const char *opstring, uint32_t op, int flags, std::ostream &stream) { util::stream_format(stream, "%-6s", opstring); @@ -244,7 +217,7 @@ static void disasm_general(const char *opstring, uint32_t op, int flags, std::os } } -static void disasm_3op(const char *opstring, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_3op(const char *opstring, uint32_t op, int flags, std::ostream &stream) { util::stream_format(stream, "%-6s", opstring); @@ -289,7 +262,7 @@ static void disasm_3op(const char *opstring, uint32_t op, int flags, std::ostrea } } -static void disasm_conditional(const char *opstring, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_conditional(const char *opstring, uint32_t op, int flags, std::ostream &stream) { char temp[10]; sprintf(temp, "%s%s", opstring, condition[(op >> 23) & 31]); @@ -297,7 +270,7 @@ static void disasm_conditional(const char *opstring, uint32_t op, int flags, std } -static void disasm_parallel_3op3op(const char *opstring1, const char *opstring2, uint32_t op, int flags, const uint8_t *srctable, std::ostream &stream) +void tms32031_disassembler::disasm_parallel_3op3op(const char *opstring1, const char *opstring2, uint32_t op, int flags, const uint8_t *srctable, std::ostream &stream) { const uint8_t *s = &srctable[((op >> 24) & 3) * 4]; int d1 = (op >> 23) & 1; @@ -315,7 +288,7 @@ static void disasm_parallel_3op3op(const char *opstring1, const char *opstring2, } -static void disasm_parallel_3opstore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_parallel_3opstore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) { int d1 = (op >> 22) & 7; int s1 = (op >> 19) & 7; @@ -335,7 +308,7 @@ static void disasm_parallel_3opstore(const char *opstring1, const char *opstring } -static void disasm_parallel_loadload(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_parallel_loadload(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) { int d2 = (op >> 22) & 7; int d1 = (op >> 19) & 7; @@ -349,7 +322,7 @@ static void disasm_parallel_loadload(const char *opstring1, const char *opstring } -static void disasm_parallel_storestore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) +void tms32031_disassembler::disasm_parallel_storestore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream) { int s2 = (op >> 22) & 7; int s1 = (op >> 16) & 7; @@ -364,9 +337,10 @@ static void disasm_parallel_storestore(const char *opstring1, const char *opstri -static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) +offs_t tms32031_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; + uint32_t op = opcodes.r32(pc); switch (op >> 23) { @@ -485,7 +459,7 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) case 0x0c4: case 0x0c5: util::stream_format(stream, "CALL $%06X", op & 0xffffff); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; @@ -537,7 +511,7 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) char temp[10]; sprintf(temp, "CALL%s", condition[(op >> 16) & 31]); util::stream_format(stream, "%-6s%s", temp, regname[op & 31]); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } @@ -546,7 +520,7 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) char temp[10]; sprintf(temp, "CALL%s", condition[(op >> 16) & 31]); util::stream_format(stream, "%-6s$%06X", temp, (pc + 1 + (int16_t)op) & 0xffffff); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } @@ -556,19 +530,19 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) char temp[10]; sprintf(temp, "TRAP%s", condition[(op >> 16) & 31]); util::stream_format(stream, "%-6s$%02X", temp, op & 31); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; } case 0x0f0: util::stream_format(stream, "RETI%s", condition[(op >> 16) & 31]); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x0f1: util::stream_format(stream, "RETS%s", condition[(op >> 16) & 31]); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; @@ -720,12 +694,11 @@ static unsigned dasm_tms3203x(std::ostream &stream, unsigned pc, uint32_t op) break; } - return 1 | flags | DASMFLAG_SUPPORTED; + return 1 | flags | SUPPORTED; } - -CPU_DISASSEMBLE( tms3203x ) +u32 tms32031_disassembler::opcode_alignment() const { - uint32_t op = oprom[0] | (oprom[1] << 8) | (oprom[2] << 16) | (oprom[3] << 24); - return dasm_tms3203x(stream, pc, op); + return 1; } + diff --git a/src/devices/cpu/tms32031/dis32031.h b/src/devices/cpu/tms32031/dis32031.h new file mode 100644 index 00000000000..b6e03e4f31a --- /dev/null +++ b/src/devices/cpu/tms32031/dis32031.h @@ -0,0 +1,51 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + dis32031.c + Disassembler for the portable TMS32C031 emulator. + Written by Aaron Giles + +***************************************************************************/ + +#ifndef MAME_CPU_TMS32031_DIS32031_H +#define MAME_CPU_TMS32031_DIS32031_H + +#pragma once + +class tms32031_disassembler : public util::disasm_interface +{ +public: + tms32031_disassembler() = default; + virtual ~tms32031_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum { + INTEGER = 0, + FLOAT = 1, + NODEST = 2, + NOSOURCE = 4, + NOSOURCE1 = NOSOURCE, + NOSOURCE2 = 8, + SWAPSRCDST = 16, + UNSIGNED = 32 + }; + + static const char *const regname[32]; + static const char *const condition[32]; + void append_indirect(uint8_t ma, int8_t disp, std::ostream &stream); + std::string get_indirect(uint8_t ma, int8_t disp); + void append_immediate(uint16_t data, int is_float, int is_unsigned, std::ostream &stream); + void disasm_general(const char *opstring, uint32_t op, int flags, std::ostream &stream); + void disasm_3op(const char *opstring, uint32_t op, int flags, std::ostream &stream); + void disasm_conditional(const char *opstring, uint32_t op, int flags, std::ostream &stream); + void disasm_parallel_3op3op(const char *opstring1, const char *opstring2, uint32_t op, int flags, const uint8_t *srctable, std::ostream &stream); + void disasm_parallel_3opstore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream); + void disasm_parallel_loadload(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream); + void disasm_parallel_storestore(const char *opstring1, const char *opstring2, uint32_t op, int flags, std::ostream &stream); +}; + +#endif diff --git a/src/devices/cpu/tms32031/tms32031.cpp b/src/devices/cpu/tms32031/tms32031.cpp index a924791cb71..6f75d3a82cb 100644 --- a/src/devices/cpu/tms32031/tms32031.cpp +++ b/src/devices/cpu/tms32031/tms32031.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "tms32031.h" +#include "dis32031.h" #include "debugger.h" @@ -328,7 +329,7 @@ inline uint32_t tms3203x_device::ROPCODE(offs_t pc) if (m_mcbl_mode && pc < 0x1000) return m_bootrom[pc]; - return m_direct->read_dword(pc << 2); + return m_direct->read_dword(pc); } @@ -341,7 +342,7 @@ inline uint32_t tms3203x_device::RMEM(offs_t addr) if (m_mcbl_mode && addr < 0x1000) return m_bootrom[addr]; - return m_program->read_dword(addr << 2); + return m_program->read_dword(addr); } @@ -351,7 +352,7 @@ inline uint32_t tms3203x_device::RMEM(offs_t addr) inline void tms3203x_device::WMEM(offs_t addr, uint32_t data) { - m_program->write_dword(addr << 2, data); + m_program->write_dword(addr, data); } @@ -363,7 +364,7 @@ void tms3203x_device::device_start() { // find address spaces m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-2>(); // resolve devcb handlers m_xf0_cb.resolve_safe(); @@ -553,36 +554,13 @@ void tms3203x_device::state_string_export(const device_state_entry &entry, std:: //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t tms3203x_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t tms3203x_device::disasm_max_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t tms3203x_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms3203x_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms3203x ); - return CPU_DISASSEMBLE_NAME(tms3203x)(this, stream, pc, oprom, opram, options); + return new tms32031_disassembler; } diff --git a/src/devices/cpu/tms32031/tms32031.h b/src/devices/cpu/tms32031/tms32031.h index e654d4f2f5e..14ac97cd6d0 100644 --- a/src/devices/cpu/tms32031/tms32031.h +++ b/src/devices/cpu/tms32031/tms32031.h @@ -182,9 +182,7 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // memory helpers uint32_t ROPCODE(offs_t pc); @@ -766,7 +764,7 @@ protected: uint32_t m_iotemp; address_space * m_program; - direct_read_data * m_direct; + direct_read_data<-2> *m_direct; uint32_t * m_bootrom; bool m_mcbl_mode; diff --git a/src/devices/cpu/tms32051/dis32051.cpp b/src/devices/cpu/tms32051/dis32051.cpp index b963781beeb..d634ebd37c4 100644 --- a/src/devices/cpu/tms32051/dis32051.cpp +++ b/src/devices/cpu/tms32051/dis32051.cpp @@ -1,10 +1,11 @@ // license:BSD-3-Clause // copyright-holders:Ville Linde -#include "emu.h" +#include "emu.h" +#include "dis32051.h" -static const char *const zl_condition_codes[] = +const char *const tms32051_disassembler::zl_condition_codes[] = { // bit 3, 2 (ZL), bit 1, 0 (MASK) "", // Z=0, L=0, ZM=0, ZL=0 @@ -25,7 +26,7 @@ static const char *const zl_condition_codes[] = "leq", // Z=1, L=1, ZM=1, ZL=1 }; -static const char *const cv_condition_codes[16] = +const char *const tms32051_disassembler::cv_condition_codes[16] = { "", // V=0, C=0, VM=0, CM=0 "nc", // V=0, C=0, VM=0, CM=1 @@ -45,7 +46,7 @@ static const char *const cv_condition_codes[16] = "c ov", // V=1, C=1, VM=1, CM=1 }; -static const char *const tp_condition_codes[4] = +const char *const tms32051_disassembler::tp_condition_codes[4] = { "bio", "tc", @@ -53,24 +54,13 @@ static const char *const tp_condition_codes[4] = "" }; - -static offs_t npc; -static const uint8_t *rombase; -static offs_t pcbase; - -static std::ostream *output; - -static uint16_t FETCH(void) +uint16_t tms32051_disassembler::FETCH(offs_t &npc, const data_buffer &opcodes) { - uint16_t result = rombase[(npc - pcbase) * 2 + 0] | (rombase[(npc - pcbase) * 2 + 1] << 8); - npc++; - return result; + return opcodes.r16(npc++); } -static char *GET_ADDRESS(int addr_mode, int address) +std::string tms32051_disassembler::GET_ADDRESS(int addr_mode, int address) { - static char buffer[100]; - if (addr_mode) // Indirect addressing { int nar = address & 0x7; @@ -78,48 +68,43 @@ static char *GET_ADDRESS(int addr_mode, int address) switch ((address >> 3) & 0xf) { - case 0x0: sprintf(buffer, "*"); break; - case 0x1: sprintf(buffer, "*, ar%d", nar); break; - case 0x2: sprintf(buffer, "*-"); break; - case 0x3: sprintf(buffer, "*-, ar%d", nar); break; - case 0x4: sprintf(buffer, "*+"); break; - case 0x5: sprintf(buffer, "*+, ar%d", nar); break; - case 0x8: sprintf(buffer, "*br0-"); break; - case 0x9: sprintf(buffer, "*br0-, ar%d", nar); break; - case 0xa: sprintf(buffer, "*0-"); break; - case 0xb: sprintf(buffer, "*0-, ar%d", nar); break; - case 0xc: sprintf(buffer, "*0+"); break; - case 0xd: sprintf(buffer, "*0+, ar%d", nar); break; - case 0xe: sprintf(buffer, "*br0+"); break; - case 0xf: sprintf(buffer, "*br0+, ar%d", nar); break; - - default: sprintf(buffer, "??? (indirect)"); break; + case 0x0: return util::string_format("*"); + case 0x1: return util::string_format("*, ar%d", nar); + case 0x2: return util::string_format("*-"); + case 0x3: return util::string_format("*-, ar%d", nar); + case 0x4: return util::string_format("*+"); + case 0x5: return util::string_format("*+, ar%d", nar); + case 0x8: return util::string_format("*br0-"); + case 0x9: return util::string_format("*br0-, ar%d", nar); + case 0xa: return util::string_format("*0-"); + case 0xb: return util::string_format("*0-, ar%d", nar); + case 0xc: return util::string_format("*0+"); + case 0xd: return util::string_format("*0+, ar%d", nar); + case 0xe: return util::string_format("*br0+"); + case 0xf: return util::string_format("*br0+, ar%d", nar); + + default: return util::string_format("??? (indirect)"); } } else // Direct addressing { - sprintf(buffer, "#%02X", address); + return util::string_format("#%02X", address); } - return buffer; } -static char *GET_SHIFT(int shift) +std::string tms32051_disassembler::GET_SHIFT(int shift) { - static char buffer[100]; - if (shift > 0) { - sprintf(buffer, ", %d", shift); + return util::string_format(", %d", shift); } else { - memset(buffer, 0, sizeof(buffer)); + return ""; } - - return buffer; } -static void print_condition_codes(bool pp, int zl, int cv, int tp) +void tms32051_disassembler::print_condition_codes(bool pp, int zl, int cv, int tp) { if (*(zl_condition_codes[zl]) != 0) { @@ -143,7 +128,7 @@ static void print_condition_codes(bool pp, int zl, int cv, int tp) } } -static void dasm_group_be(uint16_t opcode) +void tms32051_disassembler::dasm_group_be(uint16_t opcode, offs_t &npc, const data_buffer &opcodes) { int subop = opcode & 0xff; @@ -217,19 +202,19 @@ static void dasm_group_be(uint16_t opcode) case 0x7c: case 0x7d: case 0x7e: case 0x7f: util::stream_format(*output, "intr %d", opcode & 0x1f); break; - case 0x80: util::stream_format(*output, "mpy #%04X", FETCH()); break; - case 0x81: util::stream_format(*output, "and #%04X", FETCH() << 16); break; - case 0x82: util::stream_format(*output, "or #%04X", FETCH() << 16); break; - case 0x83: util::stream_format(*output, "xor #%04X", FETCH() << 16); break; - case 0xc4: util::stream_format(*output, "rpt #%04X", FETCH()); break; - case 0xc5: util::stream_format(*output, "rptz #%04X", FETCH()); break; - case 0xc6: util::stream_format(*output, "rptb #%04X", FETCH()); break; + case 0x80: util::stream_format(*output, "mpy #%04X", FETCH(npc, opcodes)); break; + case 0x81: util::stream_format(*output, "and #%04X", FETCH(npc, opcodes) << 16); break; + case 0x82: util::stream_format(*output, "or #%04X", FETCH(npc, opcodes) << 16); break; + case 0x83: util::stream_format(*output, "xor #%04X", FETCH(npc, opcodes) << 16); break; + case 0xc4: util::stream_format(*output, "rpt #%04X", FETCH(npc, opcodes)); break; + case 0xc5: util::stream_format(*output, "rptz #%04X", FETCH(npc, opcodes)); break; + case 0xc6: util::stream_format(*output, "rptb #%04X", FETCH(npc, opcodes)); break; default: util::stream_format(*output, "??? (group be)"); break; } } -static void dasm_group_bf(uint16_t opcode) +void tms32051_disassembler::dasm_group_bf(uint16_t opcode, offs_t &npc, const data_buffer &opcodes) { int subop = (opcode >> 4) & 0xf; int shift = opcode & 0xf; @@ -240,7 +225,7 @@ static void dasm_group_bf(uint16_t opcode) { if (opcode & 0x8) { - util::stream_format(*output, "lar ar%d, #%04X", opcode & 0x7, FETCH()); + util::stream_format(*output, "lar ar%d, #%04X", opcode & 0x7, FETCH(npc, opcodes)); } else { @@ -261,31 +246,34 @@ static void dasm_group_bf(uint16_t opcode) break; } - case 0x8: util::stream_format(*output, "lacc #%04X", FETCH() << shift); break; - case 0x9: util::stream_format(*output, "add #%04X", FETCH() << shift); break; - case 0xa: util::stream_format(*output, "sub #%04X", FETCH() << shift); break; - case 0xb: util::stream_format(*output, "and #%04X", FETCH() << shift); break; - case 0xc: util::stream_format(*output, "or #%04X", FETCH() << shift); break; - case 0xd: util::stream_format(*output, "xor #%04X", FETCH() << shift); break; + case 0x8: util::stream_format(*output, "lacc #%04X", FETCH(npc, opcodes) << shift); break; + case 0x9: util::stream_format(*output, "add #%04X", FETCH(npc, opcodes) << shift); break; + case 0xa: util::stream_format(*output, "sub #%04X", FETCH(npc, opcodes) << shift); break; + case 0xb: util::stream_format(*output, "and #%04X", FETCH(npc, opcodes) << shift); break; + case 0xc: util::stream_format(*output, "or #%04X", FETCH(npc, opcodes) << shift); break; + case 0xd: util::stream_format(*output, "xor #%04X", FETCH(npc, opcodes) << shift); break; case 0xe: util::stream_format(*output, "bsar %d", shift+1); break; default: util::stream_format(*output, "??? (group bf)"); break; } } -CPU_DISASSEMBLE(tms32051) +u32 tms32051_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tms32051_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; uint16_t opcode; int baseop; int address, addr_mode; - pcbase = pc; - rombase = oprom; - npc = pc; + offs_t npc = pc; output = &stream; - opcode = FETCH(); + opcode = FETCH(npc, opcodes); baseop = (opcode >> 8) & 0xff; addr_mode = (opcode >> 7) & 0x1; @@ -300,10 +288,10 @@ CPU_DISASSEMBLE(tms32051) break; } case 0x08: util::stream_format(*output, "lamm %s", GET_ADDRESS(addr_mode, address)); break; - case 0x09: util::stream_format(*output, "smmr %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0x09: util::stream_format(*output, "smmr %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0x0a: util::stream_format(*output, "subc %s", GET_ADDRESS(addr_mode, address)); break; case 0x0b: util::stream_format(*output, "rpt %s", GET_ADDRESS(addr_mode, address)); break; - case 0x0c: util::stream_format(*output, "out %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0x0c: util::stream_format(*output, "out %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0x0d: util::stream_format(*output, "ldp %s", GET_ADDRESS(addr_mode, address)); break; case 0x0e: util::stream_format(*output, "lst 0, %s", GET_ADDRESS(addr_mode, address)); break; case 0x0f: util::stream_format(*output, "lst 1, %s", GET_ADDRESS(addr_mode, address)); break; @@ -355,10 +343,10 @@ CPU_DISASSEMBLE(tms32051) case 0x59: util::stream_format(*output, "opl %s", GET_ADDRESS(addr_mode, address)); break; case 0x5a: util::stream_format(*output, "apl %s", GET_ADDRESS(addr_mode, address)); break; case 0x5b: util::stream_format(*output, "cpl %s", GET_ADDRESS(addr_mode, address)); break; - case 0x5c: util::stream_format(*output, "xpl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0x5d: util::stream_format(*output, "opl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0x5e: util::stream_format(*output, "apl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0x5f: util::stream_format(*output, "cpl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0x5c: util::stream_format(*output, "xpl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0x5d: util::stream_format(*output, "opl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0x5e: util::stream_format(*output, "apl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0x5f: util::stream_format(*output, "cpl %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0x60: util::stream_format(*output, "addc %s", GET_ADDRESS(addr_mode, address)); break; case 0x61: util::stream_format(*output, "add %s << 16", GET_ADDRESS(addr_mode, address)); break; @@ -386,13 +374,13 @@ CPU_DISASSEMBLE(tms32051) case 0x76: util::stream_format(*output, "pshd %s", GET_ADDRESS(addr_mode, address)); break; case 0x77: util::stream_format(*output, "dmov %s", GET_ADDRESS(addr_mode, address)); break; case 0x78: util::stream_format(*output, "adrk #%02X", opcode & 0xff); break; - case 0x79: util::stream_format(*output, "b %04X, %s", FETCH(), GET_ADDRESS(1, address)); break; - case 0x7a: util::stream_format(*output, "call %04X, %s", FETCH(), GET_ADDRESS(1, address)); flags = DASMFLAG_STEP_OVER; break; - case 0x7b: util::stream_format(*output, "banz %04X, %s", FETCH(), GET_ADDRESS(1, address)); break; + case 0x79: util::stream_format(*output, "b %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); break; + case 0x7a: util::stream_format(*output, "call %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); flags = STEP_OVER; break; + case 0x7b: util::stream_format(*output, "banz %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); break; case 0x7c: util::stream_format(*output, "sbrk #%02X", opcode & 0xff); break; - case 0x7d: util::stream_format(*output, "bd %04X, %s", FETCH(), GET_ADDRESS(1, address)); break; - case 0x7e: util::stream_format(*output, "calld %04X, %s", FETCH(), GET_ADDRESS(1, address)); flags = DASMFLAG_STEP_OVER; break; - case 0x7f: util::stream_format(*output, "banzd %04X, %s", FETCH(), GET_ADDRESS(1, address)); break; + case 0x7d: util::stream_format(*output, "bd %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); break; + case 0x7e: util::stream_format(*output, "calld %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); flags = STEP_OVER; break; + case 0x7f: util::stream_format(*output, "banzd %04X, %s", FETCH(npc, opcodes), GET_ADDRESS(1, address)); break; case 0x80: case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: @@ -401,7 +389,7 @@ CPU_DISASSEMBLE(tms32051) break; } case 0x88: util::stream_format(*output, "samm %s", GET_ADDRESS(addr_mode, address)); break; - case 0x89: util::stream_format(*output, "lmmr %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0x89: util::stream_format(*output, "lmmr %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0x8a: util::stream_format(*output, "popd %s", GET_ADDRESS(addr_mode, address)); break; case 0x8b: { @@ -433,21 +421,21 @@ CPU_DISASSEMBLE(tms32051) break; } - case 0xa0: util::stream_format(*output, "norm %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0xa2: util::stream_format(*output, "mac %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0xa0: util::stream_format(*output, "norm %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0xa2: util::stream_format(*output, "mac %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0xa3: util::stream_format(*output, "macd %s", GET_ADDRESS(addr_mode, address)); break; case 0xa4: util::stream_format(*output, "blpd %s", GET_ADDRESS(addr_mode, address)); break; - case 0xa5: util::stream_format(*output, "blpd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0xa5: util::stream_format(*output, "blpd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0xa6: util::stream_format(*output, "tblr %s", GET_ADDRESS(addr_mode, address)); break; case 0xa7: util::stream_format(*output, "tblw %s", GET_ADDRESS(addr_mode, address)); break; - case 0xa8: util::stream_format(*output, "bldd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0xa9: util::stream_format(*output, "bldd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0xa8: util::stream_format(*output, "bldd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0xa9: util::stream_format(*output, "bldd %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0xaa: util::stream_format(*output, "mads %s", GET_ADDRESS(addr_mode, address)); break; case 0xab: util::stream_format(*output, "madd %s", GET_ADDRESS(addr_mode, address)); break; case 0xac: util::stream_format(*output, "bldd %s", GET_ADDRESS(addr_mode, address)); break; case 0xad: util::stream_format(*output, "bldd %s", GET_ADDRESS(addr_mode, address)); break; - case 0xae: util::stream_format(*output, "splk %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; - case 0xaf: util::stream_format(*output, "in %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH()); break; + case 0xae: util::stream_format(*output, "splk %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; + case 0xaf: util::stream_format(*output, "in %s, #%04X", GET_ADDRESS(addr_mode, address), FETCH(npc, opcodes)); break; case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: @@ -466,8 +454,8 @@ CPU_DISASSEMBLE(tms32051) util::stream_format(*output, "ldp #%03X", opcode & 0x1ff); break; } - case 0xbe: dasm_group_be(opcode); break; - case 0xbf: dasm_group_bf(opcode); break; + case 0xbe: dasm_group_be(opcode, npc, opcodes); break; + case 0xbf: dasm_group_bf(opcode, npc, opcodes); break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: { @@ -477,7 +465,7 @@ CPU_DISASSEMBLE(tms32051) int cv = ((zlcv << 2) & 0xc) | (zlcvmask & 0x3); int tp = (opcode >> 8) & 0x3; - util::stream_format(*output, "bcnd %04X", FETCH()); + util::stream_format(*output, "bcnd %04X", FETCH(npc, opcodes)); print_condition_codes(true, zl, cv, tp); break; } @@ -505,7 +493,7 @@ CPU_DISASSEMBLE(tms32051) int cv = ((zlcv << 2) & 0xc) | (zlcvmask & 0x3); int tp = (opcode >> 8) & 0x3; - util::stream_format(*output, "cc %04X", FETCH()); + util::stream_format(*output, "cc %04X", FETCH(npc, opcodes)); print_condition_codes(true, zl, cv, tp); break; } @@ -527,7 +515,7 @@ CPU_DISASSEMBLE(tms32051) util::stream_format(*output, "retc "); print_condition_codes(false, zl, cv, tp); } - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; } @@ -539,7 +527,7 @@ CPU_DISASSEMBLE(tms32051) int cv = ((zlcv << 2) & 0xc) | (zlcvmask & 0x3); int tp = (opcode >> 8) & 0x3; - util::stream_format(*output, "bcndd %04X", FETCH()); + util::stream_format(*output, "bcndd %04X", FETCH(npc, opcodes)); print_condition_codes(true, zl, cv, tp); break; } @@ -552,7 +540,7 @@ CPU_DISASSEMBLE(tms32051) int cv = ((zlcv << 2) & 0xc) | (zlcvmask & 0x3); int tp = (opcode >> 8) & 0x3; - util::stream_format(*output, "ccd %04X", FETCH()); + util::stream_format(*output, "ccd %04X", FETCH(npc, opcodes)); print_condition_codes(true, zl, cv, tp); break; } @@ -574,12 +562,12 @@ CPU_DISASSEMBLE(tms32051) util::stream_format(*output, "retcd "); print_condition_codes(false, zl, cv, tp); } - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; } default: util::stream_format(*output, "??? ($%04X)", opcode); break; } - return (npc-pc) | flags | DASMFLAG_SUPPORTED; + return (npc-pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/tms32051/dis32051.h b/src/devices/cpu/tms32051/dis32051.h new file mode 100644 index 00000000000..dd170859bf3 --- /dev/null +++ b/src/devices/cpu/tms32051/dis32051.h @@ -0,0 +1,32 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde + +#ifndef MAME_CPU_TMS32051_DIS32051_H +#define MAME_CPU_TMS32051_DIS32051_H + +#pragma once + +class tms32051_disassembler : public util::disasm_interface +{ +public: + tms32051_disassembler() = default; + virtual ~tms32051_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const zl_condition_codes[]; + static const char *const cv_condition_codes[16]; + static const char *const tp_condition_codes[4]; + uint16_t FETCH(offs_t &npc, const data_buffer &opcodes); + std::string GET_ADDRESS(int addr_mode, int address); + std::string GET_SHIFT(int shift); + void print_condition_codes(bool pp, int zl, int cv, int tp); + void dasm_group_be(uint16_t opcode, offs_t &npc, const data_buffer &opcodes); + void dasm_group_bf(uint16_t opcode, offs_t &npc, const data_buffer &opcodes); + + std::ostream *output; +}; + +#endif diff --git a/src/devices/cpu/tms32051/tms32051.cpp b/src/devices/cpu/tms32051/tms32051.cpp index 22abad952ff..721d1fd1bcb 100644 --- a/src/devices/cpu/tms32051/tms32051.cpp +++ b/src/devices/cpu/tms32051/tms32051.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "tms32051.h" +#include "dis32051.h" #include "debugger.h" enum @@ -117,16 +118,15 @@ tms32053_device::tms32053_device(const machine_config &mconfig, const char *tag, } -offs_t tms32051_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms32051_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms32051 ); - return CPU_DISASSEMBLE_NAME(tms32051)(this, stream, pc, oprom, opram, options); + return new tms32051_disassembler; } #define CYCLES(x) (m_icount -= x) -#define ROPCODE() m_direct->read_word((m_pc++) << 1) +#define ROPCODE() m_direct->read_word(m_pc++) void tms32051_device::CHANGE_PC(uint16_t new_pc) { @@ -135,22 +135,22 @@ void tms32051_device::CHANGE_PC(uint16_t new_pc) uint16_t tms32051_device::PM_READ16(uint16_t address) { - return m_program->read_word(address << 1); + return m_program->read_word(address); } void tms32051_device::PM_WRITE16(uint16_t address, uint16_t data) { - m_program->write_word(address << 1, data); + m_program->write_word(address, data); } uint16_t tms32051_device::DM_READ16(uint16_t address) { - return m_data->read_word(address << 1); + return m_data->read_word(address); } void tms32051_device::DM_WRITE16(uint16_t address, uint16_t data) { - m_data->write_word(address << 1, data); + m_data->write_word(address, data); } #include "32051ops.hxx" @@ -183,7 +183,7 @@ void tms32051_device::delay_slot(uint16_t startpc) void tms32051_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-1>(); m_data = &space(AS_DATA); m_io = &space(AS_IO); @@ -515,7 +515,7 @@ READ16_MEMBER( tms32051_device::cpuregs_r ) case 0x5d: case 0x5e: case 0x5f: - return m_io->read_word(offset << 1); + return m_io->read_word(offset); default: if (!machine().side_effect_disabled()) @@ -626,7 +626,7 @@ WRITE16_MEMBER( tms32051_device::cpuregs_w ) case 0x5d: case 0x5e: case 0x5f: - m_io->write_word(offset << 1, data); + m_io->write_word(offset, data); break; default: diff --git a/src/devices/cpu/tms32051/tms32051.h b/src/devices/cpu/tms32051/tms32051.h index 880741f5a66..2f64822d62c 100644 --- a/src/devices/cpu/tms32051/tms32051.h +++ b/src/devices/cpu/tms32051/tms32051.h @@ -80,9 +80,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - 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; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; address_space_config m_data_config; @@ -161,7 +159,7 @@ protected: } m_shadow; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<-1> *m_direct; address_space *m_data; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/tms32082/dis_mp.cpp b/src/devices/cpu/tms32082/dis_mp.cpp index 0bb6e45d2c5..75c63543256 100644 --- a/src/devices/cpu/tms32082/dis_mp.cpp +++ b/src/devices/cpu/tms32082/dis_mp.cpp @@ -3,12 +3,12 @@ // TMS32082 MP Disassembler #include "emu.h" - +#include "dis_mp.h" #define SIMM15(v) (int32_t)((v & 0x4000) ? (v | 0xffffe000) : (v)) #define UIMM15(v) (v) -static const char *BCND_CONDITION[32] = +const char *tms32082_mp_disassembler::BCND_CONDITION[32] = { "nev.b", "gt0.b", "eq0.b", "ge0.b", "lt0.b", "ne0.b", "le0.b", "alw.b", "nev.h", "gt0.h", "eq0.h", "ge0.h", "lt0.h", "ne0.h", "le0.h", "alw.h", @@ -16,7 +16,7 @@ static const char *BCND_CONDITION[32] = "nev.d", "gt0.d", "eq0.d", "ge0.d", "lt0.d", "ne0.d", "le0.d", "alw.d", }; -static const char *BITNUM_CONDITION[32] = +const char *tms32082_mp_disassembler::BITNUM_CONDITION[32] = { "eq.b", "ne.b", "gt.b", "le.b", "lt.b", "ge.b", "hi.b", "ls.b", "lo.b", "hs.b", "eq.h", "ne.h", "gt.h", "le.h", "lt.h", "ge.h", @@ -24,87 +24,75 @@ static const char *BITNUM_CONDITION[32] = "lt.w", "ge.w", "hi.w", "ls.w", "lo.w", "hs.w", "?", "?", }; -static const char *MEMOP_S[2] = +const char *tms32082_mp_disassembler::MEMOP_S[2] = { ":s", "" }; -static const char *MEMOP_M[2] = +const char *tms32082_mp_disassembler::MEMOP_M[2] = { ":m", "" }; -static const char *FLOATOP_PRECISION[4] = +const char *tms32082_mp_disassembler::FLOATOP_PRECISION[4] = { "s", "d", "i", "u" }; -static const char *ACC_SEL[4] = +const char *tms32082_mp_disassembler::ACC_SEL[4] = { "A0", "A1", "A2", "A3" }; -static const char *FLOATOP_ROUND[4] = +const char *tms32082_mp_disassembler::FLOATOP_ROUND[4] = { "n", "z", "p", "m" }; -static std::ostream *output; -static const uint8_t *opdata; -static int opbytes; - -static uint32_t fetch(void) +uint32_t tms32082_mp_disassembler::fetch(offs_t &pos, const data_buffer &opcodes) { - uint32_t d = ((uint32_t)(opdata[0]) << 24) | ((uint32_t)(opdata[1]) << 16) | ((uint32_t)(opdata[2]) << 8) | opdata[3]; - opdata += 4; - opbytes += 4; + uint32_t d = opcodes.r32(pos); + pos += 4; return d; } -static char* get_creg_name(uint32_t reg) +std::string tms32082_mp_disassembler::get_creg_name(uint32_t reg) { - static char buffer[64]; - switch (reg) { - case 0x0000: sprintf(buffer, "EPC"); break; - case 0x0001: sprintf(buffer, "EIP"); break; - case 0x0002: sprintf(buffer, "CONFIG"); break; - case 0x0004: sprintf(buffer, "INTPEN"); break; - case 0x0006: sprintf(buffer, "IE"); break; - case 0x0008: sprintf(buffer, "FPST"); break; - case 0x000a: sprintf(buffer, "PPERROR"); break; - case 0x000d: sprintf(buffer, "PKTREQ"); break; - case 0x000e: sprintf(buffer, "TCOUNT"); break; - case 0x000f: sprintf(buffer, "TSCALE"); break; - case 0x0010: sprintf(buffer, "FLTOP"); break; - case 0x0011: sprintf(buffer, "FLTADR"); break; - case 0x0012: sprintf(buffer, "FLTTAG"); break; - case 0x0013: sprintf(buffer, "FLTDTL"); break; - case 0x0014: sprintf(buffer, "FLTDTH"); break; - case 0x0020: sprintf(buffer, "SYSSTK"); break; - case 0x0021: sprintf(buffer, "SYSTMP"); break; - case 0x0030: sprintf(buffer, "MPC"); break; - case 0x0031: sprintf(buffer, "MIP"); break; - case 0x0033: sprintf(buffer, "ECOMCNTL"); break; - case 0x0034: sprintf(buffer, "ANASTAT"); break; - case 0x0039: sprintf(buffer, "BRK1"); break; - case 0x003a: sprintf(buffer, "BRK2"); break; - case 0x4000: sprintf(buffer, "IN0P"); break; - case 0x4001: sprintf(buffer, "IN1P"); break; - case 0x4002: sprintf(buffer, "OUTP"); break; - default: sprintf(buffer, "CR %04X", reg); + case 0x0000: return "EPC"; + case 0x0001: return "EIP"; + case 0x0002: return "CONFIG"; + case 0x0004: return "INTPEN"; + case 0x0006: return "IE"; + case 0x0008: return "FPST"; + case 0x000a: return "PPERROR"; + case 0x000d: return "PKTREQ"; + case 0x000e: return "TCOUNT"; + case 0x000f: return "TSCALE"; + case 0x0010: return "FLTOP"; + case 0x0011: return "FLTADR"; + case 0x0012: return "FLTTAG"; + case 0x0013: return "FLTDTL"; + case 0x0014: return "FLTDTH"; + case 0x0020: return "SYSSTK"; + case 0x0021: return "SYSTMP"; + case 0x0030: return "MPC"; + case 0x0031: return "MIP"; + case 0x0033: return "ECOMCNTL"; + case 0x0034: return "ANASTAT"; + case 0x0039: return "BRK1"; + case 0x003a: return "BRK2"; + case 0x4000: return "IN0P"; + case 0x4001: return "IN1P"; + case 0x4002: return "OUTP"; + default: return util::string_format("CR %04X", reg); } - - return buffer; } -static char* format_vector_op(uint32_t op, uint32_t imm32) +std::string tms32082_mp_disassembler::format_vector_op(uint32_t op, uint32_t imm32) { - static char buffer[256]; - static char dest[64]; - char *b = buffer; - + std::string result; int rd = (op >> 27) & 0x1f; int rs = (op >> 22) & 0x1f; int src1 = (op & 0x1f); @@ -121,85 +109,87 @@ static char* format_vector_op(uint32_t op, uint32_t imm32) bool regdest = (op & (1 << 10)) == 0 && (op & (1 << 6)) == 0; // accumulator or register destination - if (regdest) - sprintf(dest, "R%d", rd); - else - sprintf(dest, "A%d", acc); + std::string dest = regdest ? util::string_format("R%d", rd) : util::string_format("A%d", acc); // base op switch (subop) { - case 0xc0: b += sprintf(b, "vadd.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; - case 0xc1: b += sprintf(b, "vadd.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; - case 0xc2: b += sprintf(b, "vsub.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, src1, rs); break; - case 0xc3: b += sprintf(b, "vsub.%s%s R%d, 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, imm32, rs); break; - case 0xc4: b += sprintf(b, "vmpy.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; - case 0xc5: b += sprintf(b, "vmpy.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; + case 0xc0: result += util::string_format("vadd.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; + case 0xc1: result += util::string_format("vadd.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; + case 0xc2: result += util::string_format("vsub.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, src1, rs); break; + case 0xc3: result += util::string_format("vsub.%s%s R%d, 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], rs, imm32, rs); break; + case 0xc4: result += util::string_format("vmpy.%s%s R%d, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], src1, rs, rs); break; + case 0xc5: result += util::string_format("vmpy.%s%s 0x%08X, R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd2], imm32, rs, rs); break; case 0xd6: case 0xc6: - b += sprintf(b, "vmsub.s%s R%d, %s, R%d", FLOATOP_PRECISION[pd2], src1, z ? "0" : ACC_SEL[acc], rs); + result += util::string_format("vmsub.s%s R%d, %s, R%d", FLOATOP_PRECISION[pd2], src1, z ? "0" : ACC_SEL[acc], rs); break; case 0xd7: case 0xc7: - b += sprintf(b, "vmsub.s%s 0x%08X, %s, R%d", FLOATOP_PRECISION[pd2], imm32, z ? "0" : ACC_SEL[acc], rs); + result += util::string_format("vmsub.s%s 0x%08X, %s, R%d", FLOATOP_PRECISION[pd2], imm32, z ? "0" : ACC_SEL[acc], rs); break; case 0xd8: case 0xc8: - b += sprintf(b, "vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], src1, rs); + result += util::string_format("vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], src1, rs); break; case 0xd9: case 0xc9: - b += sprintf(b, "vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], imm32, rs); + result += util::string_format("vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[p1], FLOATOP_PRECISION[pd4], imm32, rs); break; - case 0xca: b += sprintf(b, "vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2],src1, rs); break; - case 0xcb: b += sprintf(b, "vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2], imm32, rs); break; + case 0xca: result += util::string_format("vrnd.%s%s R%d, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2],src1, rs); break; + case 0xcb: result += util::string_format("vrnd.%s%s 0x%08X, R%d", FLOATOP_PRECISION[2 + p1], FLOATOP_PRECISION[pd2], imm32, rs); break; case 0xcc: case 0xdc: - b += sprintf(b, "vmac.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmac.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; case 0xcd: case 0xdd: - b += sprintf(b, "vmac.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmac.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; case 0xce: case 0xde: - b += sprintf(b, "vmsc.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmsc.ss%s R%d, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], src1, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; case 0xcf: case 0xdf: - b += sprintf(b, "vmsc.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); + result += util::string_format("vmsc.ss%s 0x%08X, R%d, %s, %s", FLOATOP_PRECISION[(op >> 9) & 1], imm32, rs, z ? "0" : ACC_SEL[acc], (regdest && rd == 0) ? ACC_SEL[acc] : dest); break; - default: b += sprintf(b, "?"); break; + default: result += '?'; break; } // align the line end - int len = strlen(buffer); + int len = result.size(); if (len < 30) { for (int i=0; i < (30-len); i++) { - b += sprintf(b, " "); + result += ' '; } } // optional load/store op switch (vector_ls_bits) { - case 0x01: b += sprintf(b, "|| vst.s R%d", rd); break; - case 0x03: b += sprintf(b, "|| vst.d R%d", rd); break; - case 0x04: b += sprintf(b, "|| vld0.s R%d", rd); break; - case 0x05: b += sprintf(b, "|| vld1.s R%d", rd); break; - case 0x06: b += sprintf(b, "|| vld0.d R%d", rd); break; - case 0x07: b += sprintf(b, "|| vld1.d R%d", rd); break; + case 0x01: result += util::string_format("|| vst.s R%d", rd); break; + case 0x03: result += util::string_format("|| vst.d R%d", rd); break; + case 0x04: result += util::string_format("|| vld0.s R%d", rd); break; + case 0x05: result += util::string_format("|| vld1.s R%d", rd); break; + case 0x06: result += util::string_format("|| vld0.d R%d", rd); break; + case 0x07: result += util::string_format("|| vld1.d R%d", rd); break; } - return buffer; + return result; +} + + +u32 tms32082_mp_disassembler::opcode_alignment() const +{ + return 4; } -static offs_t tms32082_disasm_mp(std::ostream &stream, offs_t pc, const uint8_t *oprom) +offs_t tms32082_mp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { output = &stream; - opdata = oprom; - opbytes = 0; + offs_t pos = pc; uint32_t flags = 0; - uint32_t op = fetch(); + uint32_t op = fetch(pos, opcodes); int rd = (op >> 27) & 0x1f; int link = rd; @@ -310,7 +300,7 @@ static offs_t tms32082_disasm_mp(std::ostream &stream, offs_t pc, const uint8_t uint32_t imm32 = 0; if (op & (1 << 12)) // fetch 32-bit immediate if needed - imm32 = fetch(); + imm32 = fetch(pos, opcodes); int m = op & (1 << 15) ? 0 : 1; int s = op & (1 << 11) ? 0 : 1; @@ -502,10 +492,5 @@ static offs_t tms32082_disasm_mp(std::ostream &stream, offs_t pc, const uint8_t } } - return opbytes | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(tms32082_mp) -{ - return tms32082_disasm_mp(stream, pc, oprom); + return (pos - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/tms32082/dis_mp.h b/src/devices/cpu/tms32082/dis_mp.h new file mode 100644 index 00000000000..8c3a0721c1a --- /dev/null +++ b/src/devices/cpu/tms32082/dis_mp.h @@ -0,0 +1,35 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde +// TMS32082 MP Disassembler + +#ifndef MAME_CPU_TMS32082_DIS_MP_H +#define MAME_CPU_TMS32082_DIS_MP_H + +#pragma once + +class tms32082_mp_disassembler : public util::disasm_interface +{ +public: + tms32082_mp_disassembler() = default; + virtual ~tms32082_mp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *BCND_CONDITION[32]; + static const char *BITNUM_CONDITION[32]; + static const char *MEMOP_S[2]; + static const char *MEMOP_M[2]; + static const char *FLOATOP_PRECISION[4]; + static const char *ACC_SEL[4]; + static const char *FLOATOP_ROUND[4]; + + std::ostream *output; + + uint32_t fetch(offs_t &pos, const data_buffer &opcodes); + std::string get_creg_name(uint32_t reg); + std::string format_vector_op(uint32_t op, uint32_t imm32); +}; + +#endif diff --git a/src/devices/cpu/tms32082/dis_pp.cpp b/src/devices/cpu/tms32082/dis_pp.cpp index b685ab54b4f..8a3a6475ba0 100644 --- a/src/devices/cpu/tms32082/dis_pp.cpp +++ b/src/devices/cpu/tms32082/dis_pp.cpp @@ -3,9 +3,9 @@ // TMS32082 PP Disassembler #include "emu.h" +#include "dis_pp.h" - -static const char *REG_NAMES[128] = +const char *tms32082_pp_disassembler::REG_NAMES[128] = { // 0 - 15 "a0", "a1", "a2", "a3", "a4", "???", "a6", "a7", @@ -33,7 +33,7 @@ static const char *REG_NAMES[128] = "???", "???", "???", "???", "tag0", "tag1", "tag2", "tag3" }; -static const char *CONDITION_CODES[16] = +const char *tms32082_pp_disassembler::CONDITION_CODES[16] = { "", "[p] ", "[ls] ", "[hi] ", "[lt] ", "[le] ", "[ge] ", "[gt] ", @@ -41,50 +41,40 @@ static const char *CONDITION_CODES[16] = "[v] ", "[nv] ", "[n] ", "[nn] " }; -static const char *TRANSFER_SIZE[4] = +const char *tms32082_pp_disassembler::TRANSFER_SIZE[4] = { "b:", "h:", "w:", "" }; - -static std::ostream *output; - -static char *format_address_mode(int mode, int areg, int s, int limx) +std::string tms32082_pp_disassembler::format_address_mode(int mode, int areg, int s, int limx) { - static char buffer[64]; - - memset(buffer, 0, sizeof(char)*64); - switch (mode) { - case 0x4: sprintf(buffer, "*(a%d++=x%d)", areg, limx); break; - case 0x5: sprintf(buffer, "*(a%d--=x%d)", areg, limx); break; - case 0x6: sprintf(buffer, "*(a%d++0x%04X)", areg, limx); break; - case 0x7: sprintf(buffer, "*(a%d--0x%04X)", areg, limx); break; - case 0x8: sprintf(buffer, "*(a%d+x%d)", areg, limx); break; - case 0x9: sprintf(buffer, "*(a%d-x%d)", areg, limx); break; - case 0xa: sprintf(buffer, "*(a%d+0x%04X)", areg, limx); break; - case 0xb: sprintf(buffer, "*(a%d-0x%04X)", areg, limx); break; - case 0xc: sprintf(buffer, "*(a%d+=x%d)", areg, limx); break; - case 0xd: sprintf(buffer, "*(a%d-=x%d)", areg, limx); break; - case 0xe: sprintf(buffer, "*(a%d+=0x%04X)", areg, limx); break; - case 0xf: sprintf(buffer, "*(a%d-=0x%04X)", areg, limx); break; + case 0x4: return util::string_format("*(a%d++=x%d)", areg, limx); + case 0x5: return util::string_format("*(a%d--=x%d)", areg, limx); + case 0x6: return util::string_format("*(a%d++0x%04X)", areg, limx); + case 0x7: return util::string_format("*(a%d--0x%04X)", areg, limx); + case 0x8: return util::string_format("*(a%d+x%d)", areg, limx); + case 0x9: return util::string_format("*(a%d-x%d)", areg, limx); + case 0xa: return util::string_format("*(a%d+0x%04X)", areg, limx); + case 0xb: return util::string_format("*(a%d-0x%04X)", areg, limx); + case 0xc: return util::string_format("*(a%d+=x%d)", areg, limx); + case 0xd: return util::string_format("*(a%d-=x%d)", areg, limx); + case 0xe: return util::string_format("*(a%d+=0x%04X)", areg, limx); + case 0xf: return util::string_format("*(a%d-=0x%04X)", areg, limx); } - return buffer; + return ""; } -static void format_transfer(uint64_t op) +void tms32082_pp_disassembler::format_transfer(uint64_t op) { - char buffer[128]; - char *b = buffer; + std::string buffer; int lmode = (op >> 35) & 0xf; int gmode = (op >> 13) & 0xf; bool is_nop = false; - memset(buffer, 0, sizeof(char)*128); - switch (lmode) { case 0x0: @@ -106,8 +96,8 @@ static void format_transfer(uint64_t op) int dreg = (dstbank << 3) | dst; int sreg = (srcbank << 3) | src; - b += sprintf(b, "%s", CONDITION_CODES[cond]); - b += sprintf(b, "%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); break; } case 0x01: // Format 8: Conditional DU ||Conditional Field Move @@ -122,8 +112,8 @@ static void format_transfer(uint64_t op) int dreg = (dstbank << 3) | dst; int sreg = (4 << 3) | src; - b += sprintf(b, "%s", CONDITION_CODES[cond]); - b += sprintf(b, "%s = [%s%d]%s", REG_NAMES[dreg], TRANSFER_SIZE[size], itm, REG_NAMES[sreg]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s = [%s%d]%s", REG_NAMES[dreg], TRANSFER_SIZE[size], itm, REG_NAMES[sreg]); break; } case 0x02: case 0x03: // Format 10: Conditional Non-D Data Unit @@ -142,8 +132,8 @@ static void format_transfer(uint64_t op) } else { - b += sprintf(b, "%s", CONDITION_CODES[cond]); - b += sprintf(b, "%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]); } break; } @@ -161,14 +151,14 @@ static void format_transfer(uint64_t op) int greg = (bank << 3) | reg; - b += sprintf(b, "%s", CONDITION_CODES[cond]); + buffer += util::string_format("%s", CONDITION_CODES[cond]); switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx), REG_NAMES[greg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, gimx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx), REG_NAMES[greg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, gimx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break; } } else // Format 5: Global (Long Offset) @@ -190,10 +180,10 @@ static void format_transfer(uint64_t op) switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset), REG_NAMES[greg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, offset)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset), REG_NAMES[greg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, offset)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break; } } break; @@ -210,12 +200,12 @@ static void format_transfer(uint64_t op) { case 0x00: // Format 2: Move || Local { - b += sprintf(b, "move||local <TODO>"); + buffer += util::string_format("move||local <TODO>"); break; } case 0x01: // Format 3: Field Move || Local { - b += sprintf(b, "field move||local <TODO>"); + buffer += util::string_format("field move||local <TODO>"); break; } case 0x02: case 0x03: // Format 6: Non-D DU || Local @@ -231,10 +221,10 @@ static void format_transfer(uint64_t op) switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx), REG_NAMES[reg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, limx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx), REG_NAMES[reg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, limx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break; } break; } @@ -263,10 +253,10 @@ static void format_transfer(uint64_t op) switch (le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset), REG_NAMES[reg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, offset)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset), REG_NAMES[reg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, offset)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break; } break; } @@ -294,10 +284,10 @@ static void format_transfer(uint64_t op) // local transfer switch (local_le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx), REG_NAMES[lreg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[lreg], format_address_mode(lmode, la, local_s, local_imx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx), REG_NAMES[lreg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[lreg], format_address_mode(lmode, la, local_s, local_imx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break; } util::stream_format(*output, ", "); @@ -305,10 +295,10 @@ static void format_transfer(uint64_t op) // global transfer switch (global_le) { - case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx), REG_NAMES[greg]); break; - case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, global_s, global_imx)); break; - case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; - case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; + case 0: buffer += util::string_format("&%s%s = %s", TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx), REG_NAMES[greg]); break; + case 1: buffer += util::string_format("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, global_s, global_imx)); break; + case 2: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; + case 3: buffer += util::string_format("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break; } break; } @@ -320,7 +310,7 @@ static void format_transfer(uint64_t op) util::stream_format(*output, " || %s", buffer); } -static void format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text) +void tms32082_pp_disassembler::format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text) { if (a) // arithmetic { @@ -409,13 +399,17 @@ static void format_alu_op(int aluop, int a, const char *dst_text, const char *a_ } } -static offs_t tms32082_disasm_pp(std::ostream &stream, offs_t pc, const uint8_t *oprom) +u32 tms32082_pp_disassembler::opcode_alignment() const +{ + return 8; +} + +offs_t tms32082_pp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { output = &stream; uint32_t flags = 0; - uint64_t op = ((uint64_t)(oprom[0]) << 56) | ((uint64_t)(oprom[1]) << 48) | ((uint64_t)(oprom[2]) << 40) | ((uint64_t)(oprom[3]) << 32) | - ((uint64_t)(oprom[4]) << 24) | ((uint64_t)(oprom[5]) << 16) | ((uint64_t)(oprom[6]) << 8) | ((uint64_t)(oprom[7])); + uint64_t op = opcodes.r64(pc); switch (op >> 60) { @@ -695,10 +689,5 @@ static offs_t tms32082_disasm_pp(std::ostream &stream, offs_t pc, const uint8_t break; } - return 8 | flags | DASMFLAG_SUPPORTED; -} - -CPU_DISASSEMBLE(tms32082_pp) -{ - return tms32082_disasm_pp(stream, pc, oprom); + return 8 | flags | SUPPORTED; } diff --git a/src/devices/cpu/tms32082/dis_pp.h b/src/devices/cpu/tms32082/dis_pp.h new file mode 100644 index 00000000000..6541eeccb70 --- /dev/null +++ b/src/devices/cpu/tms32082/dis_pp.h @@ -0,0 +1,33 @@ +// license:BSD-3-Clause +// copyright-holders:Ville Linde +// TMS32082 PP Disassembler + +#ifndef MAME_CPU_TMS32082_DIS_PP_H +#define MAME_CPU_TMS32082_DIS_PP_H + +#pragma once + +class tms32082_pp_disassembler : public util::disasm_interface +{ +public: + tms32082_pp_disassembler() = default; + virtual ~tms32082_pp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *REG_NAMES[128]; + static const char *CONDITION_CODES[16]; + static const char *TRANSFER_SIZE[4]; + + + std::ostream *output; + + + std::string format_address_mode(int mode, int areg, int s, int limx); + void format_transfer(uint64_t op); + void format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text); +}; + +#endif diff --git a/src/devices/cpu/tms32082/tms32082.cpp b/src/devices/cpu/tms32082/tms32082.cpp index e2a975ea995..392cd0d8738 100644 --- a/src/devices/cpu/tms32082/tms32082.cpp +++ b/src/devices/cpu/tms32082/tms32082.cpp @@ -9,11 +9,10 @@ #include "emu.h" #include "tms32082.h" +#include "dis_pp.h" +#include "dis_mp.h" #include "debugger.h" -extern CPU_DISASSEMBLE(tms32082_mp); -extern CPU_DISASSEMBLE(tms32082_pp); - DEFINE_DEVICE_TYPE(TMS32082_MP, tms32082_mp_device, "tms32082_mp", "TMS32082 MP") DEFINE_DEVICE_TYPE(TMS32082_PP, tms32082_pp_device, "tms32082_pp", "TMS32082 PP") @@ -64,13 +63,12 @@ device_memory_interface::space_config_vector tms32082_pp_device::memory_space_co }; } -offs_t tms32082_mp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) + +util::disasm_interface *tms32082_mp_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(tms32082_mp)(this, stream, pc, oprom, opram, options); + return new tms32082_mp_disassembler; } - - void tms32082_mp_device::set_command_callback(write32_delegate callback) { m_cmd_callback = callback; @@ -223,7 +221,7 @@ void tms32082_mp_device::device_start() state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_icountptr = &m_icount; } @@ -502,9 +500,9 @@ tms32082_pp_device::tms32082_pp_device(const machine_config &mconfig, const char } -offs_t tms32082_pp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms32082_pp_device::create_disassembler() { - return CPU_DISASSEMBLE_NAME(tms32082_pp)(this, stream, pc, oprom, opram, options); + return new tms32082_pp_disassembler; } void tms32082_pp_device::device_start() @@ -521,7 +519,7 @@ void tms32082_pp_device::device_start() state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow(); m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_icountptr = &m_icount; } diff --git a/src/devices/cpu/tms32082/tms32082.h b/src/devices/cpu/tms32082/tms32082.h index c1d4674dbeb..88f968584a7 100644 --- a/src/devices/cpu/tms32082/tms32082.h +++ b/src/devices/cpu/tms32082/tms32082.h @@ -93,9 +93,7 @@ protected: 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 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -132,7 +130,7 @@ protected: int m_icount; address_space *m_program; - direct_read_data* m_direct; + direct_read_data<0> * m_direct; write32_delegate m_cmd_callback; @@ -181,9 +179,7 @@ protected: 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 8; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; address_space_config m_program_config; @@ -193,7 +189,7 @@ protected: int m_icount; address_space *m_program; - direct_read_data* m_direct; + direct_read_data<0> * m_direct; }; diff --git a/src/devices/cpu/tms34010/34010dsm.cpp b/src/devices/cpu/tms34010/34010dsm.cpp index f4bad3089ee..cb2fd0ffe4e 100644 --- a/src/devices/cpu/tms34010/34010dsm.cpp +++ b/src/devices/cpu/tms34010/34010dsm.cpp @@ -8,30 +8,23 @@ */ #include "emu.h" +#include "34010dsm.h" -#ifdef STANDALONE -#define PC __pc + (offset << 3) -#define OP_WORD(v) { v = filebuf[_pc>>3]; _pc += 8; v = v | (filebuf[_pc>>3] << 8); _pc += 8;} -#define PARAM_WORD(v) { v = filebuf[_pc>>3]; _pc += 8; v = v | (filebuf[_pc>>3] << 8); _pc += 8;} -#define PARAM_LONG(v) { int v1, v2; PARAM_WORD(v1); PARAM_WORD(v2); v = v1 | (v2 << 16); } -#else -#define PC __pc -#define OP_WORD(v) { v = rombase[(__pc - pcbase) >> 3] | (rombase[(__pc + 8 - pcbase) >> 3] << 8); _pc += 16; } -#define PARAM_WORD(v) { v = rambase[(__pc + 16 - pcbase) >> 3] | (rambase[(__pc + 24 - pcbase) >> 3] << 8); _pc += 16; } -#define PARAM_LONG(v) { v = rambase[(__pc + 16 - pcbase) >> 3] | (rambase[(__pc + 24 - pcbase) >> 3] << 8) | (rambase[(__pc + 32 - pcbase) >> 3] << 16) | (rambase[(__pc + 40 - pcbase) >> 3] << 24); _pc += 32; } -#define PARM2_LONG(v) { v = rambase[(__pc + 48 - pcbase) >> 3] | (rambase[(__pc + 56 - pcbase) >> 3] << 8) | (rambase[(__pc + 64 - pcbase) >> 3] << 16) | (rambase[(__pc + 72 - pcbase) >> 3] << 24); _pc += 32; } -#endif - -static uint8_t rf; -static uint32_t __pc, _pc; -static uint16_t op,rs,rd; - -static const uint8_t *rombase; -static const uint8_t *rambase; -static offs_t pcbase; - - -static void print_reg(std::ostream &stream, uint8_t reg) +uint16_t tms34010_disassembler::r16(offs_t &pos, const data_buffer &opcodes) +{ + uint16_t r = opcodes.r16(pos); + pos += 16; + return r; +} + +uint32_t tms34010_disassembler::r32(offs_t &pos, const data_buffer &opcodes) +{ + uint32_t r = opcodes.r32(pos); + pos += 32; + return r; +} + +void tms34010_disassembler::print_reg(std::ostream &stream, uint8_t reg) { if (reg != 0x0f) { @@ -43,73 +36,51 @@ static void print_reg(std::ostream &stream, uint8_t reg) } } -static void print_src_reg(std::ostream &stream) +void tms34010_disassembler::print_src_reg(std::ostream &stream) { print_reg(stream, rs); } -static void print_des_reg(std::ostream &stream) +void tms34010_disassembler::print_des_reg(std::ostream &stream) { print_reg(stream, rd); } -static void print_src_des_reg(std::ostream &stream) +void tms34010_disassembler::print_src_des_reg(std::ostream &stream) { print_src_reg(stream); stream << ","; print_des_reg(stream); } -static void print_word_parm(std::ostream &stream) +void tms34010_disassembler::print_word_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms) { - uint16_t w; - - PARAM_WORD(w); - - util::stream_format(stream, "%Xh", w); + util::stream_format(stream, "%Xh", r16(pos, params)); } -static void print_word_parm_1s_comp(std::ostream &stream) +void tms34010_disassembler::print_word_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms) { - uint16_t w; - - PARAM_WORD(w); - w = ~w; - util::stream_format(stream, "%Xh", w); + util::stream_format(stream, "%Xh", u16(~r16(pos, params))); } -static void print_long_parm(std::ostream &stream) +void tms34010_disassembler::print_long_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms) { - uint32_t l; - - PARAM_LONG(l); - util::stream_format(stream, "%Xh", l); -} - -static void print_long_parm2(std::ostream &stream) -{ - uint32_t l; - - PARM2_LONG(l); - util::stream_format(stream, "%Xh", l); + util::stream_format(stream, "%Xh", r32(pos, params)); } -static void print_long_parm_1s_comp(std::ostream &stream) +void tms34010_disassembler::print_long_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms) { - uint32_t l; - - PARAM_LONG(l); - util::stream_format(stream, "%Xh", ~l); + util::stream_format(stream, "%Xh", u32(~r32(pos, params))); } -static void print_constant(std::ostream &stream) +void tms34010_disassembler::print_constant(std::ostream &stream) { uint8_t constant = (op >> 5) & 0x1f; util::stream_format(stream, "%Xh", constant); } -static void print_constant_1_32(std::ostream &stream) +void tms34010_disassembler::print_constant_1_32(std::ostream &stream) { uint8_t constant = (op >> 5) & 0x1f; if (!constant) constant = 0x20; @@ -117,52 +88,48 @@ static void print_constant_1_32(std::ostream &stream) util::stream_format(stream, "%Xh", constant); } -static void print_constant_1s_comp(std::ostream &stream) +void tms34010_disassembler::print_constant_1s_comp(std::ostream &stream) { uint8_t constant = (~op >> 5) & 0x1f; util::stream_format(stream, "%Xh", constant); } -static void print_constant_2s_comp(std::ostream &stream) +void tms34010_disassembler::print_constant_2s_comp(std::ostream &stream) { uint8_t constant = 32 - ((op >> 5) & 0x1f); util::stream_format(stream, "%Xh", constant); } -static void print_relative(std::ostream &stream) +void tms34010_disassembler::print_relative(std::ostream &stream, offs_t pc, offs_t &pos, const data_buffer ¶ms) { - uint16_t l; - int16_t ls; + int16_t ls = (int16_t)r16(pos, params); - PARAM_WORD(l); - ls = (int16_t)l; - - util::stream_format(stream, "%Xh", PC + 32 + (ls << 4)); + util::stream_format(stream, "%Xh", pc + 32 + (ls << 4)); } -static void print_relative_8bit(std::ostream &stream) +void tms34010_disassembler::print_relative_8bit(std::ostream &stream, offs_t pc) { int8_t ls = (int8_t)op; - util::stream_format(stream, "%Xh", PC + 16 + (ls << 4)); + util::stream_format(stream, "%Xh", pc + 16 + (ls << 4)); } -static void print_relative_5bit(std::ostream &stream) +void tms34010_disassembler::print_relative_5bit(std::ostream &stream, offs_t pc) { int8_t ls = (int8_t)((op >> 5) & 0x1f); if (op & 0x0400) ls = -ls; - util::stream_format(stream, "%Xh", PC + 16 + (ls << 4)); + util::stream_format(stream, "%Xh", pc + 16 + (ls << 4)); } -static void print_field(std::ostream &stream) +void tms34010_disassembler::print_field(std::ostream &stream) { util::stream_format(stream, "%c", (op & 0x200) ? '1' : '0'); } -static void print_condition_code(std::ostream &stream) +void tms34010_disassembler::print_condition_code(std::ostream &stream) { switch (op & 0x0f00) { @@ -185,7 +152,7 @@ static void print_condition_code(std::ostream &stream) } } -static void print_reg_list_range(std::ostream &stream, int8_t first, int8_t last) +void tms34010_disassembler::print_reg_list_range(std::ostream &stream, int8_t first, int8_t last) { if ((first != -1 ) && (first != last)) { @@ -197,13 +164,12 @@ static void print_reg_list_range(std::ostream &stream, int8_t first, int8_t last } } -static void print_reg_list(std::ostream &stream, uint16_t rev) +void tms34010_disassembler::print_reg_list(std::ostream &stream, uint16_t rev, offs_t &pos, const data_buffer ¶ms) { - uint16_t l; uint8_t i; int8_t first = -1, last = 0; - PARAM_WORD(l); + uint16_t l = r16(pos, params); for (i = 0; i < 16; i++) { @@ -241,15 +207,14 @@ static void print_reg_list(std::ostream &stream, uint16_t rev) } -static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) +offs_t tms34010_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int flags = 0; uint8_t bad = 0; uint16_t subop; + offs_t pos = pc; - __pc = _pc = pc; - - OP_WORD(op); + op = r16(pos, opcodes); subop = (op & 0x01e0); rs = (op >> 5) & 0x0f; /* Source register */ @@ -267,21 +232,21 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "IDLE "); else bad = 1; break; case 0x0080: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "MWAIT "); else bad = 1; break; case 0x00e0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "BLMOVE %d,%d", (op >> 1) & 1, op & 1); else bad = 1; @@ -334,21 +299,21 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "SETCSP "); else bad = 1; break; case 0x0060: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "SETCDP "); else bad = 1; break; case 0x0080: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "RPIX "); print_des_reg(stream); @@ -358,7 +323,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00a0: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "EXGPS "); print_des_reg(stream); @@ -368,7 +333,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00c0: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "GETPS "); print_des_reg(stream); @@ -378,7 +343,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00e0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "SETCMP "); else bad = 1; @@ -394,9 +359,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0140: util::stream_format(stream, "MOVB @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ",@"; - print_long_parm2(stream); + print_long_parm(stream, pos, params); break; case 0x0160: @@ -434,10 +399,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CEXEC %d,%06X,%d", (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7); } else @@ -445,10 +409,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0020: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVGC "); print_des_reg(stream); util::stream_format(stream, ",%06X,%d", (x >> 8) & 0x1fffff, (x >> 29) & 7); @@ -458,10 +421,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0040: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVGC "); print_des_reg(stream); stream << ","; @@ -474,10 +436,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0060: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); if (op == 0x0660 && (x & 0xff) == 0x01) { @@ -499,10 +460,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0080: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVMC *"); rf = (x & 0x10) ? 'B' : 'A'; print_reg(stream, x & 0x0f); @@ -513,10 +473,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00a0: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVCM *"); print_des_reg(stream); util::stream_format(stream, "+,%d,%d,%06X,%d", x & 0x1f, (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7); @@ -526,10 +485,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00c0: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVCM *-"); print_des_reg(stream); util::stream_format(stream, ",%d,%d,%06X,%d", x & 0x1f, (x >> 7) & 1, (x >> 8) & 0x1fffff, (x >> 29) & 7); @@ -539,10 +497,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00e0: - if (is_34020 && (op & 0xfe00) == 0x0600) + if (m_is_34020 && (op & 0xfe00) == 0x0600) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVMC *"); rf = (x & 0x10) ? 'B' : 'A'; print_reg(stream, x & 0x0f); @@ -581,14 +538,14 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVE "); print_des_reg(stream); stream << ",@"; - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_field(stream); break; case 0x01a0: util::stream_format(stream, "MOVE @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); stream << ","; @@ -597,9 +554,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x01c0: util::stream_format(stream, "MOVE @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ",@"; - print_long_parm2(stream); + print_long_parm(stream, pos, params); stream << ","; print_field(stream); break; @@ -608,7 +565,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) if (op & 0x200) { util::stream_format(stream, "MOVE @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); } @@ -617,7 +574,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVB "); print_des_reg(stream); stream << ",@"; - print_long_parm(stream); + print_long_parm(stream, pos, params); } break; @@ -631,20 +588,19 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "TRAPL "); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; } else bad = 1; break; case 0x0020: - if (is_34020) + if (m_is_34020) { - uint32_t x; - PARAM_LONG(x); + uint32_t x = r32(pos, params); util::stream_format(stream, "CMOVMC *-"); rf = (x & 0x10) ? 'B' : 'A'; print_reg(stream, x & 0x0f); @@ -655,24 +611,24 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "VBLT B,L"); else bad = 1; break; case 0x0060: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "RETM "); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; } else bad = 1; break; case 0x00e0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "CLIP "); else bad = 1; @@ -680,23 +636,23 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0100: util::stream_format(stream, "TRAP %Xh", op & 0x1f); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x0120: util::stream_format(stream, "CALL "); print_des_reg(stream); - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; break; case 0x0140: util::stream_format(stream, "RETI "); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; break; case 0x0160: util::stream_format(stream, "RETS "); - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; if (op & 0x1f) { util::stream_format(stream, "%Xh", op & 0x1f); @@ -706,25 +662,25 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0180: util::stream_format(stream, "MMTM "); print_des_reg(stream); - print_reg_list(stream, 1); + print_reg_list(stream, 1, pos, params); break; case 0x01a0: util::stream_format(stream, "MMFM "); print_des_reg(stream); - print_reg_list(stream, 0); + print_reg_list(stream, 0, pos, params); break; case 0x01c0: util::stream_format(stream, "MOVI "); - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x01e0: util::stream_format(stream, "MOVI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; @@ -739,28 +695,28 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "VLCOL "); else bad = 1; break; case 0x0020: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "PFILL XY"); else bad = 1; break; case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "VFILL L"); else bad = 1; break; case 0x0060: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "CVMXYL "); print_des_reg(stream); @@ -770,7 +726,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0080: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "CVDXYL "); print_des_reg(stream); @@ -780,14 +736,14 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x00a0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "FPIXEQ "); else bad = 1; break; case 0x00c0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "FPIXNE "); else bad = 1; @@ -795,56 +751,56 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0100: util::stream_format(stream, "ADDI "); - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0120: util::stream_format(stream, "ADDI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0140: util::stream_format(stream, "CMPI "); - print_word_parm_1s_comp(stream); + print_word_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0160: util::stream_format(stream, "CMPI "); - print_long_parm_1s_comp(stream); + print_long_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0180: util::stream_format(stream, "ANDI "); - print_long_parm_1s_comp(stream); + print_long_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x01a0: util::stream_format(stream, "ORI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x01c0: util::stream_format(stream, "XORI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x01e0: util::stream_format(stream, "SUBI "); - print_word_parm_1s_comp(stream); + print_word_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; @@ -859,10 +815,10 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "ADDXYI "); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ","; print_des_reg(stream); } @@ -871,7 +827,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x0040: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "LINIT "); else bad = 1; @@ -879,21 +835,21 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0100: util::stream_format(stream, "SUBI "); - print_long_parm_1s_comp(stream); + print_long_parm_1s_comp(stream, pos, params); stream << ","; print_des_reg(stream); break; case 0x0120: util::stream_format(stream, "CALLR "); - print_relative(stream); - flags = DASMFLAG_STEP_OVER; + print_relative(stream, pc, pos, params); + flags = STEP_OVER; break; case 0x0140: util::stream_format(stream, "CALLA "); - print_long_parm(stream); - flags = DASMFLAG_STEP_OVER; + print_long_parm(stream, pos, params); + flags = STEP_OVER; break; case 0x0160: @@ -904,24 +860,24 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "DSJ "); print_des_reg(stream); stream << ","; - print_relative(stream); - flags = DASMFLAG_STEP_OVER; + print_relative(stream, pc, pos, params); + flags = STEP_OVER; break; case 0x01a0: util::stream_format(stream, "DSJEQ "); print_des_reg(stream); stream << ","; - print_relative(stream); - flags = DASMFLAG_STEP_OVER; + print_relative(stream, pc, pos, params); + flags = STEP_OVER; break; case 0x01c0: util::stream_format(stream, "DSJNE "); print_des_reg(stream); stream << ","; - print_relative(stream); - flags = DASMFLAG_STEP_OVER; + print_relative(stream, pc, pos, params); + flags = STEP_OVER; break; case 0x01e0: @@ -935,18 +891,18 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x0e00: - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "PIXBLT L,M,L"); else bad = 1; break; case 0x00e0: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "TFILL XY"); else bad = 1; @@ -1088,7 +1044,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x3400: case 0x3600: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "CMPK "); print_constant_1_32(stream); @@ -1106,8 +1062,8 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "DSJS "); print_des_reg(stream); stream << ","; - print_relative_5bit(stream); - flags = DASMFLAG_STEP_OVER; + print_relative_5bit(stream, pc); + flags = STEP_OVER; break; @@ -1279,7 +1235,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0x7a00: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "RMO "); print_src_des_reg(stream); @@ -1289,7 +1245,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0x7e00: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "SWAPF *"); print_src_des_reg(stream); @@ -1423,7 +1379,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) stream << ",*"; print_des_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << ")"; break; @@ -1432,7 +1388,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVB *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),"; print_des_reg(stream); break; @@ -1445,7 +1401,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) stream << ",*"; print_des_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),"; print_field(stream); break; @@ -1456,7 +1412,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVE *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),"; print_des_reg(stream); stream << ","; @@ -1469,11 +1425,11 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVE *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),*"; print_des_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),"; print_field(stream); break; @@ -1483,11 +1439,11 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVB *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),*"; print_des_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << ")"; break; @@ -1515,15 +1471,15 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (op & 0x00ff) { case 0x00: - print_relative(stream); + print_relative(stream, pc, pos, params); break; case 0x80: - print_long_parm(stream); + print_long_parm(stream, pos, params); break; default: - print_relative_8bit(stream); + print_relative_8bit(stream, pc); } break; @@ -1533,7 +1489,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "MOVE *"); print_src_reg(stream); stream << "("; - print_word_parm(stream); + print_word_parm(stream, pos, params); stream << "),*"; print_des_reg(stream); stream << "+,"; @@ -1547,7 +1503,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) { case 0x0000: util::stream_format(stream, "MOVE @"); - print_long_parm(stream); + print_long_parm(stream, pos, params); stream << ",*"; print_des_reg(stream); stream << "+,"; @@ -1567,10 +1523,9 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) break; case 0xd800: - if (is_34020) + if (m_is_34020) { - uint32_t x; - PARAM_WORD(x); + uint32_t x = r16(pos, params); util::stream_format(stream, "CEXEC %d,%06X,%d", op & 1, ((x << 5) & 0x1fffe0) | ((op >> 1) & 0x1f), (x >> 13) & 7); } else @@ -1582,14 +1537,14 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) switch (subop) { case 0x0000: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "FLINE 0"); else bad = 1; break; case 0x0080: - if (is_34020) + if (m_is_34020) util::stream_format(stream, "FLINE 1"); else bad = 1; @@ -1639,7 +1594,7 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) case 0xea00: - if (is_34020) + if (m_is_34020) { util::stream_format(stream, "CVSXYL "); print_src_des_reg(stream); @@ -1723,21 +1678,14 @@ static unsigned Dasm340x0(std::ostream &stream, uint32_t pc, bool is_34020) util::stream_format(stream, "DW %04Xh", op & 0xffff); } - return (_pc - __pc) | flags | DASMFLAG_SUPPORTED; + return (pos - pc) | flags | SUPPORTED; } -CPU_DISASSEMBLE( tms34010 ) +uint32_t tms34010_disassembler::opcode_alignment() const { - rombase = oprom; - rambase = opram; - pcbase = pc; - return Dasm340x0(stream, pc, false); + return 16; } -CPU_DISASSEMBLE( tms34020 ) +tms34010_disassembler::tms34010_disassembler(bool is_34020) : m_is_34020(is_34020) { - rombase = oprom; - rambase = opram; - pcbase = pc; - return Dasm340x0(stream, pc, true); } diff --git a/src/devices/cpu/tms34010/34010dsm.h b/src/devices/cpu/tms34010/34010dsm.h new file mode 100644 index 00000000000..2e8e72ee191 --- /dev/null +++ b/src/devices/cpu/tms34010/34010dsm.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:Zsolt Vasvari +/* + * A TMS34010 disassembler + * + * This code written by Zsolt Vasvari for the MAME project + * + */ + +#ifndef MAME_CPU_TMS34010_34010DSM_H +#define MAME_CPU_TMS34010_34010DSM_H + +#pragma once + +class tms34010_disassembler : public util::disasm_interface +{ +public: + tms34010_disassembler(bool is_34020); + virtual ~tms34010_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + bool m_is_34020; + uint8_t rf; + uint16_t op,rs,rd; + + uint16_t r16(offs_t &pos, const data_buffer &opcodes); + uint32_t r32(offs_t &pos, const data_buffer &opcodes); + void print_reg(std::ostream &stream, uint8_t reg); + void print_src_reg(std::ostream &stream); + void print_des_reg(std::ostream &stream); + void print_src_des_reg(std::ostream &stream); + void print_word_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms); + void print_word_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms); + void print_long_parm(std::ostream &stream, offs_t &pos, const data_buffer ¶ms); + void print_long_parm_1s_comp(std::ostream &stream, offs_t &pos, const data_buffer ¶ms); + void print_constant(std::ostream &stream); + void print_constant_1_32(std::ostream &stream); + void print_constant_1s_comp(std::ostream &stream); + void print_constant_2s_comp(std::ostream &stream); + void print_relative(std::ostream &stream, offs_t pc, offs_t &pos, const data_buffer ¶ms); + void print_relative_8bit(std::ostream &stream, offs_t pc); + void print_relative_5bit(std::ostream &stream, offs_t pc); + void print_field(std::ostream &stream); + void print_condition_code(std::ostream &stream); + void print_reg_list_range(std::ostream &stream, int8_t first, int8_t last); + void print_reg_list(std::ostream &stream, uint16_t rev, offs_t &pos, const data_buffer ¶ms); +}; + +#endif diff --git a/src/devices/cpu/tms34010/34010fld.hxx b/src/devices/cpu/tms34010/34010fld.hxx index 7d55bca3b7b..79c2caa5c50 100644 --- a/src/devices/cpu/tms34010/34010fld.hxx +++ b/src/devices/cpu/tms34010/34010fld.hxx @@ -98,7 +98,7 @@ void tms340x0_device::wfield_16(offs_t offset, uint32_t data) } else { - TMS34010_WRMEM_WORD(TOBYTE(offset),data); + TMS34010_WRMEM_WORD(offset,data); } } @@ -313,7 +313,7 @@ uint32_t tms340x0_device::rfield_z_16(offs_t offset) } else - ret = TMS34010_RDMEM_WORD(TOBYTE(offset)); + ret = TMS34010_RDMEM_WORD(offset); return ret; } @@ -490,7 +490,7 @@ uint32_t tms340x0_device::rfield_s_08(offs_t offset) } else - ret = TMS34010_RDMEM(TOBYTE(offset)); + ret = TMS34010_RDMEM(offset); return (int32_t)(int8_t)ret; } @@ -553,7 +553,7 @@ uint32_t tms340x0_device::rfield_s_16(offs_t offset) else { - ret = TMS34010_RDMEM_WORD(TOBYTE(offset)); + ret = TMS34010_RDMEM_WORD(offset); } return (int32_t)(int16_t)ret; diff --git a/src/devices/cpu/tms34010/34010gfx.hxx b/src/devices/cpu/tms34010/34010gfx.hxx index 5c92ad36b6b..410b2d3a06a 100644 --- a/src/devices/cpu/tms34010/34010gfx.hxx +++ b/src/devices/cpu/tms34010/34010gfx.hxx @@ -207,6 +207,11 @@ int tms340x0_device::compute_pixblt_b_cycles(int left_partials, int right_partia /* Shift register handling */ void tms340x0_device::memory_w(address_space &space, offs_t offset,uint16_t data) { + logerror("memory_w %08x %04x\n", offset << 3, data); + if((offset << 3) == 0x02005010 && data == 0x0000) { + machine().debug_break(); + // abort(); + } space.write_word(offset, data); } @@ -217,8 +222,9 @@ uint16_t tms340x0_device::memory_r(address_space &space, offs_t offset) void tms340x0_device::shiftreg_w(address_space &space, offs_t offset,uint16_t data) { + logerror("shiftreg_w %08x %04x\n", offset << 3, data); if (!m_from_shiftreg_cb.isnull()) - m_from_shiftreg_cb(space, (uint32_t)(offset << 3) & ~15, &m_shiftreg[0]); + m_from_shiftreg_cb(space, offset, &m_shiftreg[0]); else logerror("From ShiftReg function not set. PC = %08X\n", m_pc); } @@ -226,7 +232,7 @@ void tms340x0_device::shiftreg_w(address_space &space, offs_t offset,uint16_t da uint16_t tms340x0_device::shiftreg_r(address_space &space, offs_t offset) { if (!m_to_shiftreg_cb.isnull()) - m_to_shiftreg_cb(space, (uint32_t)(offset << 3) & ~15, &m_shiftreg[0]); + m_to_shiftreg_cb(space, offset, &m_shiftreg[0]); else logerror("To ShiftReg function not set. PC = %08X\n", m_pc); return m_shiftreg[0]; @@ -1028,13 +1034,13 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear uint32_t srcword, dstword = 0; /* fetch the initial source word */ - srcword = (this->*word_read)(*m_program, srcwordaddr++ << 1); + srcword = (this->*word_read)(*m_program, srcwordaddr++ << 4); readwrites++; /* fetch the initial dest word */ if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY || (daddr & 0x0f) != 0) { - dstword = (this->*word_read)(*m_program, dstwordaddr << 1); + dstword = (this->*word_read)(*m_program, dstwordaddr << 4); readwrites++; } @@ -1047,7 +1053,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear /* fetch more words if necessary */ if (srcbit + BITS_PER_PIXEL > 16) { - srcword |= (this->*word_read)(*m_program, srcwordaddr++ << 1) << 16; + srcword |= (this->*word_read)(*m_program, srcwordaddr++ << 4) << 16; readwrites++; } @@ -1064,7 +1070,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) if (dstbit + BITS_PER_PIXEL > 16) { - dstword |= (this->*word_read)(*m_program, (dstwordaddr + 1) << 1) << 16; + dstword |= (this->*word_read)(*m_program, (dstwordaddr + 1) << 4) << 16; readwrites++; } @@ -1079,7 +1085,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear dstbit += BITS_PER_PIXEL; if (dstbit > 16) { - (this->*word_write)(*m_program, dstwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dstwordaddr++ << 4, dstword); readwrites++; dstbit -= 16; dstword >>= 16; @@ -1092,13 +1098,13 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear /* if we're right-partial, read and mask the remaining bits */ if (dstbit != 16) { - uint16_t origdst = (this->*word_read)(*m_program, dstwordaddr << 1); + uint16_t origdst = (this->*word_read)(*m_program, dstwordaddr << 4); uint16_t mask = 0xffff << dstbit; dstword = (dstword & ~mask) | (origdst & mask); readwrites++; } - (this->*word_write)(*m_program, dstwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dstwordaddr++ << 4, dstword); readwrites++; } @@ -1130,14 +1136,14 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear dwordaddr = daddr >> 4; /* fetch the initial source word */ - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = PIXEL_MASK << (saddr & 15); /* handle the left partial word */ if (left_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK << (daddr & 15); /* loop over partials */ @@ -1146,7 +1152,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear /* fetch another word if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = PIXEL_MASK; } @@ -1168,7 +1174,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* loop over full words */ @@ -1176,7 +1182,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear { /* fetch the destination word (if necessary) */ if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); else dstword = 0; dstmask = PIXEL_MASK; @@ -1187,7 +1193,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear /* fetch another word if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = PIXEL_MASK; } @@ -1209,14 +1215,14 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* handle the right partial word */ if (right_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK; /* loop over partials */ @@ -1226,7 +1232,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear if (srcmask == 0) { LOGGFX((" right fetch @ %08x\n", swordaddr)); - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = PIXEL_MASK; } @@ -1248,7 +1254,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt)(int src_is_linear, int dst_is_linear } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } #endif @@ -1399,14 +1405,14 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d dwordaddr = (daddr + 15) >> 4; /* fetch the initial source word */ - srcword = (this->*word_read)(*m_program, --swordaddr << 1); + srcword = (this->*word_read)(*m_program, --swordaddr << 4); srcmask = PIXEL_MASK << ((saddr - BITS_PER_PIXEL) & 15); /* handle the right partial word */ if (right_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, --dwordaddr << 1); + dstword = (this->*word_read)(*m_program, --dwordaddr << 4); dstmask = PIXEL_MASK << ((daddr - BITS_PER_PIXEL) & 15); /* loop over partials */ @@ -1415,7 +1421,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d /* fetch source pixel if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, --swordaddr << 1); + srcword = (this->*word_read)(*m_program, --swordaddr << 4); srcmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); } @@ -1442,7 +1448,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d } /* write the result */ - (this->*word_write)(*m_program, dwordaddr << 1, dstword); + (this->*word_write)(*m_program, dwordaddr << 4, dstword); } /* loop over full words */ @@ -1451,7 +1457,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d /* fetch the destination word (if necessary) */ dwordaddr--; if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); else dstword = 0; dstmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); @@ -1462,7 +1468,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d /* fetch source pixel if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, --swordaddr << 1); + srcword = (this->*word_read)(*m_program, --swordaddr << 4); srcmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); } @@ -1489,14 +1495,14 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d } /* write the result */ - (this->*word_write)(*m_program, dwordaddr << 1, dstword); + (this->*word_write)(*m_program, dwordaddr << 4, dstword); } /* handle the left partial word */ if (left_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, --dwordaddr << 1); + dstword = (this->*word_read)(*m_program, --dwordaddr << 4); dstmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); /* loop over partials */ @@ -1505,7 +1511,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d /* fetch the source pixel if necessary */ if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, --swordaddr << 1); + srcword = (this->*word_read)(*m_program, --swordaddr << 4); srcmask = PIXEL_MASK << (16 - BITS_PER_PIXEL); } @@ -1532,7 +1538,7 @@ if ((daddr & (BITS_PER_PIXEL - 1)) != 0) osd_printf_debug("PIXBLT_R%d with odd d } /* write the result */ - (this->*word_write)(*m_program, dwordaddr << 1, dstword); + (this->*word_write)(*m_program, dwordaddr << 4, dstword); } /* update for next row */ @@ -1657,14 +1663,14 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) dwordaddr = daddr >> 4; /* fetch the initial source word */ - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = 1 << (saddr & 15); /* handle the left partial word */ if (left_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK << (daddr & 15); /* loop over partials */ @@ -1681,7 +1687,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) srcmask <<= 1; if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = 0x0001; } @@ -1690,7 +1696,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* loop over full words */ @@ -1698,7 +1704,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) { /* fetch the destination word (if necessary) */ if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); else dstword = 0; dstmask = PIXEL_MASK; @@ -1717,7 +1723,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) srcmask <<= 1; if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = 0x0001; } @@ -1726,14 +1732,14 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* handle the right partial word */ if (right_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK; /* loop over partials */ @@ -1750,7 +1756,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) srcmask <<= 1; if (srcmask == 0) { - srcword = (this->*word_read)(*m_program, swordaddr++ << 1); + srcword = (this->*word_read)(*m_program, swordaddr++ << 4); srcmask = 0x0001; } @@ -1759,7 +1765,7 @@ void FUNCTION_NAME(tms340x0_device::pixblt_b)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* update for next row */ @@ -1873,7 +1879,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) if (left_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK << (daddr & 15); /* loop over partials */ @@ -1890,7 +1896,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* loop over full words */ @@ -1898,7 +1904,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) { /* fetch the destination word (if necessary) */ if (PIXEL_OP_REQUIRES_SOURCE || TRANSPARENCY) - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); else dstword = 0; dstmask = PIXEL_MASK; @@ -1917,14 +1923,14 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* handle the right partial word */ if (right_partials != 0) { /* fetch the destination word */ - dstword = (this->*word_read)(*m_program, dwordaddr << 1); + dstword = (this->*word_read)(*m_program, dwordaddr << 4); dstmask = PIXEL_MASK; /* loop over partials */ @@ -1941,7 +1947,7 @@ void FUNCTION_NAME(tms340x0_device::fill)(int dst_is_linear) } /* write the result */ - (this->*word_write)(*m_program, dwordaddr++ << 1, dstword); + (this->*word_write)(*m_program, dwordaddr++ << 4, dstword); } /* update for next row */ diff --git a/src/devices/cpu/tms34010/34010ops.h b/src/devices/cpu/tms34010/34010ops.h index 901e9b56888..41481212804 100644 --- a/src/devices/cpu/tms34010/34010ops.h +++ b/src/devices/cpu/tms34010/34010ops.h @@ -26,7 +26,7 @@ inline uint32_t tms340x0_device::TMS34010_RDMEM_DWORD(offs_t A) { uint32_t result = m_program->read_word(A); - return result | (m_program->read_word(A+2)<<16); + return result | (m_program->read_word(A+16)<<16); } #define TMS34010_WRMEM(A,V) (m_program->write_byte(A,V)) @@ -34,7 +34,7 @@ inline uint32_t tms340x0_device::TMS34010_RDMEM_DWORD(offs_t A) inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) { m_program->write_word(A,V); - m_program->write_word(A+2,V>>16); + m_program->write_word(A+16,V>>16); } @@ -52,36 +52,36 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) ***************************************************************************/ #define WFIELDMAC(MASK,MAX) \ - uint32_t shift = offset & 0x0f; \ - uint32_t masked_data = data & (MASK); \ - uint32_t old; \ + uint32_t shift = offset & 0x0f; \ + uint32_t masked_data = data & (MASK); \ + uint32_t old; \ \ - offset = TOBYTE(offset & 0xfffffff0); \ + offset = offset & 0xfffffff0; \ \ if (shift >= MAX) \ { \ - old = (uint32_t)TMS34010_RDMEM_DWORD(offset) & ~((MASK) << shift); \ + old = (uint32_t)TMS34010_RDMEM_DWORD(offset) & ~((MASK) << shift); \ TMS34010_WRMEM_DWORD(offset, (masked_data << shift) | old); \ } \ else \ { \ - old = (uint32_t)TMS34010_RDMEM_WORD(offset) & ~((MASK) << shift); \ + old = (uint32_t)TMS34010_RDMEM_WORD(offset) & ~((MASK) << shift); \ TMS34010_WRMEM_WORD(offset, ((masked_data & (MASK)) << shift) | old); \ } #define WFIELDMAC_BIG(MASK,MAX) \ - uint32_t shift = offset & 0x0f; \ - uint32_t masked_data = data & (MASK); \ - uint32_t old; \ + uint32_t shift = offset & 0x0f; \ + uint32_t masked_data = data & (MASK); \ + uint32_t old; \ \ - offset = TOBYTE(offset & 0xfffffff0); \ + offset = offset & 0xfffffff0; \ \ - old = (uint32_t)TMS34010_RDMEM_DWORD(offset) & ~(uint32_t)((MASK) << shift); \ - TMS34010_WRMEM_DWORD(offset, (uint32_t)(masked_data << shift) | old); \ + old = (uint32_t)TMS34010_RDMEM_DWORD(offset) & ~(uint32_t)((MASK) << shift); \ + TMS34010_WRMEM_DWORD(offset, (uint32_t)(masked_data << shift) | old); \ if (shift >= MAX) \ { \ shift = 32 - shift; \ - old = (uint32_t)TMS34010_RDMEM_WORD(offset + 4) & ~((MASK) >> shift); \ + old = (uint32_t)TMS34010_RDMEM_WORD(offset + 0x20) & ~((MASK) >> shift); \ TMS34010_WRMEM_WORD(offset, (masked_data >> shift) | old); \ } @@ -91,7 +91,7 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) WFIELDMAC(0xff,9); \ } \ else \ - TMS34010_WRMEM(TOBYTE(offset), data); + TMS34010_WRMEM(offset, data); #define RFIELDMAC_8() \ if (offset & 0x07) \ @@ -99,22 +99,22 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) RFIELDMAC(0xff,9); \ } \ else \ - return TMS34010_RDMEM(TOBYTE(offset)); + ret = TMS34010_RDMEM(offset); #define WFIELDMAC_32() \ if (offset & 0x0f) \ { \ - uint32_t shift = offset&0x0f; \ - uint32_t old; \ - uint32_t hiword; \ + uint32_t shift = offset&0x0f; \ + uint32_t old; \ + uint32_t hiword; \ offset &= 0xfffffff0; \ - old = ((uint32_t) TMS34010_RDMEM_DWORD (TOBYTE(offset ))&(0xffffffff>>(0x20-shift))); \ - hiword = ((uint32_t) TMS34010_RDMEM_DWORD (TOBYTE(offset+0x20))&(0xffffffff<<shift)); \ - TMS34010_WRMEM_DWORD(TOBYTE(offset ),(data<< shift) |old); \ - TMS34010_WRMEM_DWORD(TOBYTE(offset+0x20),(data>>(0x20-shift))|hiword); \ + old = ((uint32_t) TMS34010_RDMEM_DWORD (offset )&(0xffffffff>>(0x20-shift))); \ + hiword = ((uint32_t) TMS34010_RDMEM_DWORD (offset+0x20)&(0xffffffff<<shift)); \ + TMS34010_WRMEM_DWORD(offset ,(data<< shift) |old); \ + TMS34010_WRMEM_DWORD(offset+0x20,(data>>(0x20-shift))|hiword); \ } \ else \ - TMS34010_WRMEM_DWORD(TOBYTE(offset),data); + TMS34010_WRMEM_DWORD(offset,data); /*************************************************************************** @@ -122,33 +122,33 @@ inline void tms340x0_device::TMS34010_WRMEM_DWORD(offs_t A, uint32_t V) ***************************************************************************/ #define RFIELDMAC(MASK,MAX) \ - uint32_t shift = offset & 0x0f; \ - offset = TOBYTE(offset & 0xfffffff0); \ + uint32_t shift = offset & 0x0f; \ + offset = offset & 0xfffffff0; \ \ if (shift >= MAX) \ - ret = (TMS34010_RDMEM_DWORD(offset) >> shift) & (MASK); \ + ret = (TMS34010_RDMEM_DWORD(offset) >> shift) & (MASK); \ else \ ret = (TMS34010_RDMEM_WORD(offset) >> shift) & (MASK); #define RFIELDMAC_BIG(MASK,MAX) \ - uint32_t shift = offset & 0x0f; \ - offset = TOBYTE(offset & 0xfffffff0); \ + uint32_t shift = offset & 0x0f; \ + offset = offset & 0xfffffff0; \ \ - ret = (uint32_t)TMS34010_RDMEM_DWORD(offset) >> shift; \ + ret = (uint32_t)TMS34010_RDMEM_DWORD(offset) >> shift; \ if (shift >= MAX) \ - ret |= (TMS34010_RDMEM_WORD(offset + 4) << (32 - shift)); \ + ret |= (TMS34010_RDMEM_WORD(offset + 0x20) << (32 - shift)); \ ret &= MASK; #define RFIELDMAC_32() \ if (offset&0x0f) \ { \ - uint32_t shift = offset&0x0f; \ + uint32_t shift = offset&0x0f; \ offset &= 0xfffffff0; \ - return (((uint32_t)TMS34010_RDMEM_DWORD (TOBYTE(offset ))>> shift) | \ - (TMS34010_RDMEM_DWORD (TOBYTE(offset+0x20))<<(0x20-shift)));\ + return (((uint32_t)TMS34010_RDMEM_DWORD (offset )>> shift) | \ + (TMS34010_RDMEM_DWORD (offset+0x20)<<(0x20-shift))); \ } \ else \ - return TMS34010_RDMEM_DWORD(TOBYTE(offset)); + return TMS34010_RDMEM_DWORD(offset); #endif // MAME_CPU_TMS34010_34010OPS_H diff --git a/src/devices/cpu/tms34010/34010ops.hxx b/src/devices/cpu/tms34010/34010ops.hxx index 57b5cca536e..85a1b932747 100644 --- a/src/devices/cpu/tms34010/34010ops.hxx +++ b/src/devices/cpu/tms34010/34010ops.hxx @@ -80,13 +80,13 @@ void tms340x0_device::unimpl(uint16_t op) { /* kludge for Super High Impact -- this doesn't seem to cause */ /* an illegal opcode exception */ - if (m_direct->read_word(TOBYTE(m_pc - 0x10)) == 0x0007) + if (m_direct->read_word(m_pc - 0x10) == 0x0007) return; /* 9 Ball Shootout calls to FFDF7468, expecting it */ /* to execute the next instruction from FFDF7470 */ /* but the instruction at FFDF7460 is an 0x0001 */ - if (m_direct->read_word(TOBYTE(m_pc - 0x10)) == 0x0001) + if (m_direct->read_word(m_pc - 0x10) == 0x0001) return; PUSH(m_pc); @@ -96,7 +96,7 @@ void tms340x0_device::unimpl(uint16_t op) COUNT_UNKNOWN_CYCLES(16); /* extra check to prevent bad things */ - if (m_pc == 0 || s_opcode_table[m_direct->read_word(TOBYTE(m_pc)) >> 4] == &tms34010_device::unimpl) + if (m_pc == 0 || s_opcode_table[m_direct->read_word(m_pc) >> 4] == &tms34010_device::unimpl) { set_input_line(INPUT_LINE_HALT, ASSERT_LINE); machine().debug_break(); @@ -2055,7 +2055,7 @@ void tms340x0_device::blmove(uint16_t op) { while (bits >= 16 && m_icount > 0) { - TMS34010_WRMEM_WORD(TOBYTE(dst), TMS34010_RDMEM_WORD(TOBYTE(src))); + TMS34010_WRMEM_WORD(dst, TMS34010_RDMEM_WORD(src)); src += 0x10; dst += 0x10; bits -= 0x10; diff --git a/src/devices/cpu/tms34010/dis34010.cpp b/src/devices/cpu/tms34010/dis34010.cpp deleted file mode 100644 index 01aebd4a6f1..00000000000 --- a/src/devices/cpu/tms34010/dis34010.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Zsolt Vasvari -/* This program is based on DIS68k by Aaron Giles */ - -#include "emu.h" - -static uint8_t *filebuf; -static uint32_t offset; - -#define STANDALONE -#include "34010dsm.c" - - -static const char *const Options[]= -{ - "begin","end","offset",0 -}; - -static void usage (void) -{ - printf ("Usage: DIS34010 [options] <filename>\n" - "Available options are:\n" - " -begin - Specify begin offset in file to disassemble in bits [0]\n" - " -end - Specify end offset in file to disassemble in bits [none]\n" - " -offset - Specify address to load program in bits [0]\n" - "All values should be entered in hexadecimal\n"); - exit (1); -} - -int main (int argc,char *argv[]) -{ - uint8_t i,j,n; - char *filename=0,buf[80]; - FILE *f; - uint32_t begin=0,end=(uint32_t)-1,filelen,len,pc; - printf ("DIS34010\n" - "Copyright Zsolt Vasvari/Aaron Giles\n"); - - for (i=1,n=0;i<argc;++i) - { - if (argv[i][0]!='-') - { - switch (++n) - { - case 1: filename=argv[i]; break; - default: usage(); - } - } - else - { - for (j=0;Options[j];++j) - if (!strcmp(argv[i]+1,Options[j])) break; - - switch (j) - { - case 0: ++i; if (i>argc) usage(); - begin=strtoul(argv[i],0,16) >> 3; - break; - case 1: ++i; if (i>argc) usage(); - end=strtoul(argv[i],0,16) >> 3; - break; - case 2: ++i; if (i>argc) usage(); - offset=strtoul(argv[i],0,16) >> 3; - break; - default: usage(); - } - } - } - - if (!filename) - { - usage(); - return 1; - } - f=fopen (filename,"rb"); - if (!f) - { - printf ("Unable to open %s\n",filename); - return 2; - } - fseek (f,0,SEEK_END); - filelen=ftell (f); - fseek (f,begin,SEEK_SET); - len=(filelen>end)? (end-begin+1):(filelen-begin); - filebuf=malloc(len+16); - if (!filebuf) - { - printf ("Memory allocation error\n"); - fclose (f); - return 3; - } - memset (filebuf,0,len+16); - if (fread(filebuf,1,len,f)!=len) - { - printf ("Read error\n"); - fclose (f); - free (filebuf); - return 4; - } - fclose (f); - pc=0; - while (pc<len-1) - { - i=(Dasm34010 (buf,pc<<3))>>3; - - printf ("%08X: ",(pc+offset) << 3); - for (j=0;j<i ;++j) printf("%02X ",filebuf[pc+j]); - for ( ;j<10;++j) printf(" "); - printf(buf); - printf ("\n"); - pc+=i; - } - free (filebuf); - return 0; -} diff --git a/src/devices/cpu/tms34010/tms34010.cpp b/src/devices/cpu/tms34010/tms34010.cpp index d442a2a2feb..770777b03fb 100644 --- a/src/devices/cpu/tms34010/tms34010.cpp +++ b/src/devices/cpu/tms34010/tms34010.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "tms34010.h" +#include "34010dsm.h" #include "debugger.h" #include "screen.h" @@ -179,34 +180,34 @@ inline void tms340x0_device::RESET_ST() /* shortcuts for reading opcodes */ inline uint32_t tms340x0_device::ROPCODE() { - uint32_t pc = TOBYTE(m_pc); + uint32_t pc = m_pc; m_pc += 2 << 3; return m_direct->read_word(pc); } inline int16_t tms340x0_device::PARAM_WORD() { - uint32_t pc = TOBYTE(m_pc); + uint32_t pc = m_pc; m_pc += 2 << 3; return m_direct->read_word(pc); } inline int32_t tms340x0_device::PARAM_LONG() { - uint32_t pc = TOBYTE(m_pc); + uint32_t pc = m_pc; m_pc += 4 << 3; - return (uint16_t)m_direct->read_word(pc) | (m_direct->read_word(pc + 2) << 16); + return (uint16_t)m_direct->read_word(pc) | (m_direct->read_word(pc + 16) << 16); } inline int16_t tms340x0_device::PARAM_WORD_NO_INC() { - return m_direct->read_word(TOBYTE(m_pc)); + return m_direct->read_word(m_pc); } inline int32_t tms340x0_device::PARAM_LONG_NO_INC() { - uint32_t pc = TOBYTE(m_pc); - return (uint16_t)m_direct->read_word(pc) | (m_direct->read_word(pc + 2) << 16); + uint32_t pc = m_pc; + return (uint16_t)m_direct->read_word(pc) | (m_direct->read_word(pc + 16) << 16); } /* read memory byte */ @@ -257,7 +258,7 @@ inline int32_t tms340x0_device::POP() #define RP(m1,m2) \ /* TODO: Plane masking */ \ - return (TMS34010_RDMEM_WORD(TOBYTE(offset & 0xfffffff0)) >> (offset & m1)) & m2; + return (TMS34010_RDMEM_WORD(offset & 0xfffffff0) >> (offset & m1)) & m2; uint32_t tms340x0_device::read_pixel_1(offs_t offset) { RP(0x0f,0x01) } uint32_t tms340x0_device::read_pixel_2(offs_t offset) { RP(0x0e,0x03) } @@ -266,12 +267,12 @@ uint32_t tms340x0_device::read_pixel_8(offs_t offset) { RP(0x08,0xff) } uint32_t tms340x0_device::read_pixel_16(offs_t offset) { /* TODO: Plane masking */ - return TMS34010_RDMEM_WORD(TOBYTE(offset & 0xfffffff0)); + return TMS34010_RDMEM_WORD(offset & 0xfffffff0); } uint32_t tms340x0_device::read_pixel_32(offs_t offset) { /* TODO: Plane masking */ - return TMS34010_RDMEM_DWORD(TOBYTE(offset & 0xffffffe0)); + return TMS34010_RDMEM_DWORD(offset & 0xffffffe0); } /* Shift register read */ @@ -292,9 +293,9 @@ uint32_t tms340x0_device::read_pixel_shiftreg(offs_t offset) /* No Raster Op + No Transparency */ #define WP(m1,m2) \ - uint32_t a = TOBYTE(offset & 0xfffffff0); \ - uint32_t pix = TMS34010_RDMEM_WORD(a); \ - uint32_t shiftcount = offset & m1; \ + uint32_t a = offset & 0xfffffff0; \ + uint32_t pix = TMS34010_RDMEM_WORD(a); \ + uint32_t shiftcount = offset & m1; \ \ /* TODO: plane masking */ \ data &= m2; \ @@ -307,9 +308,9 @@ uint32_t tms340x0_device::read_pixel_shiftreg(offs_t offset) data &= m2; \ if (data) \ { \ - uint32_t a = TOBYTE(offset & 0xfffffff0); \ - uint32_t pix = TMS34010_RDMEM_WORD(a); \ - uint32_t shiftcount = offset & m1; \ + uint32_t a = offset & 0xfffffff0; \ + uint32_t pix = TMS34010_RDMEM_WORD(a); \ + uint32_t shiftcount = offset & m1; \ \ /* TODO: plane masking */ \ pix = (pix & ~(m2 << shiftcount)) | (data << shiftcount); \ @@ -317,9 +318,9 @@ uint32_t tms340x0_device::read_pixel_shiftreg(offs_t offset) } /* Raster Op + No Transparency */ #define WP_R(m1,m2) \ - uint32_t a = TOBYTE(offset & 0xfffffff0); \ - uint32_t pix = TMS34010_RDMEM_WORD(a); \ - uint32_t shiftcount = offset & m1; \ + uint32_t a = offset & 0xfffffff0; \ + uint32_t pix = TMS34010_RDMEM_WORD(a); \ + uint32_t shiftcount = offset & m1; \ \ /* TODO: plane masking */ \ data = (this->*m_raster_op)(data & m2, (pix >> shiftcount) & m2) & m2; \ @@ -328,9 +329,9 @@ uint32_t tms340x0_device::read_pixel_shiftreg(offs_t offset) /* Raster Op + Transparency */ #define WP_R_T(m1,m2) \ - uint32_t a = TOBYTE(offset & 0xfffffff0); \ - uint32_t pix = TMS34010_RDMEM_WORD(a); \ - uint32_t shiftcount = offset & m1; \ + uint32_t a = offset & 0xfffffff0; \ + uint32_t pix = TMS34010_RDMEM_WORD(a); \ + uint32_t shiftcount = offset & m1; \ \ /* TODO: plane masking */ \ data = (this->*m_raster_op)(data & m2, (pix >> shiftcount) & m2) & m2; \ @@ -348,12 +349,12 @@ void tms340x0_device::write_pixel_8(offs_t offset, uint32_t data) { WP(0x08, 0xf void tms340x0_device::write_pixel_16(offs_t offset, uint32_t data) { /* TODO: plane masking */ - TMS34010_WRMEM_WORD(TOBYTE(offset & 0xfffffff0), data); + TMS34010_WRMEM_WORD(offset & 0xfffffff0, data); } void tms340x0_device::write_pixel_32(offs_t offset, uint32_t data) { /* TODO: plane masking */ - TMS34010_WRMEM_WORD(TOBYTE(offset & 0xffffffe0), data); + TMS34010_WRMEM_WORD(offset & 0xffffffe0, data); } /* No Raster Op + Transparency */ @@ -365,13 +366,13 @@ void tms340x0_device::write_pixel_t_16(offs_t offset, uint32_t data) { /* TODO: plane masking */ if (data) - TMS34010_WRMEM_WORD(TOBYTE(offset & 0xfffffff0), data); + TMS34010_WRMEM_WORD(offset & 0xfffffff0, data); } void tms340x0_device::write_pixel_t_32(offs_t offset, uint32_t data) { /* TODO: plane masking */ if (data) - TMS34010_WRMEM_DWORD(TOBYTE(offset & 0xffffffe0), data); + TMS34010_WRMEM_DWORD(offset & 0xffffffe0, data); } /* Raster Op + No Transparency */ @@ -382,13 +383,13 @@ void tms340x0_device::write_pixel_r_8(offs_t offset, uint32_t data) { WP_R(0x08, void tms340x0_device::write_pixel_r_16(offs_t offset, uint32_t data) { /* TODO: plane masking */ - uint32_t a = TOBYTE(offset & 0xfffffff0); + uint32_t a = offset & 0xfffffff0; TMS34010_WRMEM_WORD(a, (this->*m_raster_op)(data, TMS34010_RDMEM_WORD(a))); } void tms340x0_device::write_pixel_r_32(offs_t offset, uint32_t data) { /* TODO: plane masking */ - uint32_t a = TOBYTE(offset & 0xffffffe0); + uint32_t a = offset & 0xffffffe0; TMS34010_WRMEM_DWORD(a, (this->*m_raster_op)(data, TMS34010_RDMEM_DWORD(a))); } @@ -400,7 +401,7 @@ void tms340x0_device::write_pixel_r_t_8(offs_t offset, uint32_t data) { WP_R_T(0 void tms340x0_device::write_pixel_r_t_16(offs_t offset, uint32_t data) { /* TODO: plane masking */ - uint32_t a = TOBYTE(offset & 0xfffffff0); + uint32_t a = offset & 0xfffffff0; data = (this->*m_raster_op)(data, TMS34010_RDMEM_WORD(a)); if (data) @@ -409,7 +410,7 @@ void tms340x0_device::write_pixel_r_t_16(offs_t offset, uint32_t data) void tms340x0_device::write_pixel_r_t_32(offs_t offset, uint32_t data) { /* TODO: plane masking */ - uint32_t a = TOBYTE(offset & 0xffffffe0); + uint32_t a = offset & 0xffffffe0; data = (this->*m_raster_op)(data, TMS34010_RDMEM_DWORD(a)); if (data) @@ -587,7 +588,7 @@ void tms340x0_device::device_start() m_external_host_access = false; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<03>(); /* set up the state table */ { @@ -1511,7 +1512,7 @@ WRITE16_MEMBER( tms340x0_device::host_w ) /* write to the address */ addr = (IOREG(REG_HSTADRH) << 16) | IOREG(REG_HSTADRL); - TMS34010_WRMEM_WORD(TOBYTE(addr & 0xfffffff0), data); + TMS34010_WRMEM_WORD(addr & 0xfffffff0, data); /* optional postincrement */ if (IOREG(REG_HSTCTLH) & 0x0800) @@ -1570,7 +1571,7 @@ READ16_MEMBER( tms340x0_device::host_r ) /* read from the address */ addr = (IOREG(REG_HSTADRH) << 16) | IOREG(REG_HSTADRL); - result = TMS34010_RDMEM_WORD(TOBYTE(addr & 0xfffffff0)); + result = TMS34010_RDMEM_WORD(addr & 0xfffffff0); /* optional postincrement (it says preincrement, but data is preloaded, so it is effectively a postincrement */ @@ -1625,18 +1626,12 @@ void tms340x0_device::state_string_export(const device_state_entry &entry, std:: } } - -offs_t tms34010_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms34010_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms34010 ); - - return CPU_DISASSEMBLE_NAME(tms34010)(this, stream, pc, oprom, opram, options); + return new tms34010_disassembler(false); } - -offs_t tms34020_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms34020_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms34020 ); - - return CPU_DISASSEMBLE_NAME(tms34020)(this, stream, pc, oprom, opram, options); + return new tms34010_disassembler(true); } diff --git a/src/devices/cpu/tms34010/tms34010.h b/src/devices/cpu/tms34010/tms34010.h index 9846d69625a..0f9c3a27a57 100644 --- a/src/devices/cpu/tms34010/tms34010.h +++ b/src/devices/cpu/tms34010/tms34010.h @@ -276,10 +276,6 @@ protected: // device_state_interface overrides 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; } - typedef void (tms340x0_device::*pixel_write_func)(offs_t offset, uint32_t data); typedef uint32_t (tms340x0_device::*pixel_read_func)(offs_t offset); typedef uint32_t (tms340x0_device::*raster_op_func)(uint32_t newpix, uint32_t oldpix); @@ -327,7 +323,7 @@ protected: uint8_t m_external_host_access; uint8_t m_executing; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<3> *m_direct; uint32_t m_pixclock; /* the pixel clock (0 means don't adjust screen size) */ int m_pixperclock; /* pixels per clock */ emu_timer *m_scantimer; @@ -1025,7 +1021,7 @@ public: protected: virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 8 - 1) / 8; } virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 8); } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; DECLARE_DEVICE_TYPE(TMS34010, tms34010_device) @@ -1042,7 +1038,7 @@ public: protected: virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 4 - 1) / 4; } virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 4); } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; }; DECLARE_DEVICE_TYPE(TMS34020, tms34020_device) @@ -1055,12 +1051,4 @@ DECLARE_DEVICE_TYPE(TMS34020, tms34020_device) #define TMS34010_HOST_DATA 2 #define TMS34010_HOST_CONTROL 3 -/* Use this macro in the memory definitions to specify bit-based addresses */ -#define TOBYTE(bitaddr) ((offs_t)(bitaddr) >> 3) -#define TOWORD(bitaddr) ((offs_t)(bitaddr) >> 4) - - -CPU_DISASSEMBLE( tms34010 ); -CPU_DISASSEMBLE( tms34020 ); - #endif // MAME_CPU_TMS34010_TMS34010_H diff --git a/src/devices/cpu/tms57002/57002dsm.cpp b/src/devices/cpu/tms57002/57002dsm.cpp index 0f92c9af145..b8d03ab8172 100644 --- a/src/devices/cpu/tms57002/57002dsm.cpp +++ b/src/devices/cpu/tms57002/57002dsm.cpp @@ -9,10 +9,13 @@ ***************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "tms57002.h" +#include "57002dsm.h" -static std::string get_memadr(uint32_t opcode, char type) +tms57002_disassembler::tms57002_disassembler() +{ +} + +std::string tms57002_disassembler::get_memadr(uint32_t opcode, char type) { std::string buf; @@ -30,11 +33,15 @@ static std::string get_memadr(uint32_t opcode, char type) return buf; } +u32 tms57002_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE(tms57002) +offs_t tms57002_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { std::streampos original_pos = stream.tellp(); - uint32_t opcode = opram[0] | (opram[1] << 8) | (opram[2] << 16); + uint32_t opcode = opcodes.r32(pc); uint8_t fa = opcode >> 18; if(fa == 0x3f) { switch((opcode >> 11) & 0x7f) { // category 3 diff --git a/src/devices/cpu/tms57002/57002dsm.h b/src/devices/cpu/tms57002/57002dsm.h new file mode 100644 index 00000000000..56ed3d0ea25 --- /dev/null +++ b/src/devices/cpu/tms57002/57002dsm.h @@ -0,0 +1,30 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + 57002dsm.c + + TMS57002 "DASP" emulator. + +***************************************************************************/ + +#ifndef MAME_CPU_TMS57002_57002DSM_H +#define MAME_CPU_TMS57002_57002DSM_H + +#pragma once + +class tms57002_disassembler : public util::disasm_interface +{ +public: + tms57002_disassembler(); + virtual ~tms57002_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static std::string get_memadr(uint32_t opcode, char type); + +}; + +#endif diff --git a/src/devices/cpu/tms57002/tms57002.cpp b/src/devices/cpu/tms57002/tms57002.cpp index 4b88669298b..f98e0497acf 100644 --- a/src/devices/cpu/tms57002/tms57002.cpp +++ b/src/devices/cpu/tms57002/tms57002.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "tms57002.h" #include "debugger.h" +#include "57002dsm.h" DEFINE_DEVICE_TYPE(TMS57002, tms57002_device, "tms57002", "TMS57002") @@ -29,6 +30,10 @@ tms57002_device::tms57002_device(const machine_config &mconfig, const char *tag, { } +util::disasm_interface *tms57002_device::create_disassembler() +{ + return new tms57002_disassembler; +} WRITE_LINE_MEMBER(tms57002_device::pload_w) { @@ -103,7 +108,7 @@ WRITE8_MEMBER(tms57002_device::data_w) sti = (sti & ~SU_MASK) | SU_PRG; break; case SU_PRG: - program->write_dword(pc++ << 2, val); + program->write_dword(pc++, val); break; } } @@ -684,7 +689,7 @@ int tms57002_device::decode_get_pc() for(;;) { short ipc; - uint32_t opcode = program->read_dword(adr << 2); + uint32_t opcode = program->read_dword(adr); cs.inc = 0; @@ -892,22 +897,6 @@ uint32_t tms57002_device::execute_input_lines() const return 0; } -uint32_t tms57002_device::disasm_min_opcode_bytes() const -{ - return 4; -} - -uint32_t tms57002_device::disasm_max_opcode_bytes() const -{ - return 4; -} - -offs_t tms57002_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( tms57002 ); - return CPU_DISASSEMBLE_NAME(tms57002)(this, stream, pc, oprom, opram, options); -} - device_memory_interface::space_config_vector tms57002_device::memory_space_config() const { return space_config_vector { diff --git a/src/devices/cpu/tms57002/tms57002.h b/src/devices/cpu/tms57002/tms57002.h index 361c0b8a7d8..120af046362 100644 --- a/src/devices/cpu/tms57002/tms57002.h +++ b/src/devices/cpu/tms57002/tms57002.h @@ -35,9 +35,7 @@ protected: virtual uint32_t execute_max_cycles() const override; virtual uint32_t execute_input_lines() const override; virtual void execute_run() override; - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: enum { diff --git a/src/devices/cpu/tms57002/tms57kdec.cpp b/src/devices/cpu/tms57002/tms57kdec.cpp index b3b71cb58e4..8cca7ba825f 100644 --- a/src/devices/cpu/tms57002/tms57kdec.cpp +++ b/src/devices/cpu/tms57002/tms57kdec.cpp @@ -72,18 +72,11 @@ inline int tms57002_device::sfma(uint32_t st1) void tms57002_device::decode_error(uint32_t opcode) { - uint8_t opr[3]; if(unsupported_inst_warning) return; unsupported_inst_warning = 1; - opr[0] = opcode; - opr[1] = opcode >> 8; - opr[2] = opcode >> 16; - - std::stringstream stream; - disasm_disassemble(stream, pc, opr, opr, 0); - popmessage("tms57002: %s - Contact Mamedev", stream.str()); + popmessage("tms57002: %06x - Contact Mamedev", opcode); } void tms57002_device::decode_cat1(uint32_t opcode, unsigned short *op, cstate *cs) diff --git a/src/devices/cpu/tms7000/7000dasm.cpp b/src/devices/cpu/tms7000/7000dasm.cpp index 1f7f8549852..000c7ea2ea3 100644 --- a/src/devices/cpu/tms7000/7000dasm.cpp +++ b/src/devices/cpu/tms7000/7000dasm.cpp @@ -7,24 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "tms7000.h" +#include "7000dasm.h" -enum operandtype { DONE, NONE, UI8, I8, UI16, I16, PCREL, PCABS, TRAP }; - -struct oprandinfo { - char opstr[4][12]; - operandtype decode[4]; -}; - -struct tms7000_opcodeinfo { - int opcode; - char name[8]; - int operand; - uint32_t s_flag; -}; - -static const oprandinfo of[] = { +const tms7000_disassembler::oprandinfo tms7000_disassembler::of[] = { /* 00 */ { {" B,A", "", "", ""}, {NONE, DONE, DONE, DONE} }, /* 01 */ { {" R%u", ",A", "", ""}, {UI8, NONE, DONE, DONE} }, /* 02 */ { {" R%u", ",B", "", ""}, {UI8, NONE, DONE, DONE} }, @@ -84,7 +69,7 @@ static const oprandinfo of[] = { /* 45 */ { {" *R%u", "", "", ""}, {UI8, DONE, DONE, DONE} } }; -static const tms7000_opcodeinfo opcodes[] = { +const tms7000_disassembler::tms7000_opcodeinfo tms7000_disassembler::opcs[] = { {0x69, "ADC", 0, 0 }, {0x19, "ADC", 1, 0 }, {0x39, "ADC", 2, 0 }, @@ -141,9 +126,9 @@ static const tms7000_opcodeinfo opcodes[] = { {0x97, "BTJZP", 21, 0 }, {0xA7, "BTJZP", 22, 0 }, - {0x8E, "CALL", 43, DASMFLAG_STEP_OVER }, - {0x9E, "CALL", 45, DASMFLAG_STEP_OVER }, - {0xAE, "CALL", 12, DASMFLAG_STEP_OVER }, + {0x8E, "CALL", 43, STEP_OVER }, + {0x9E, "CALL", 45, STEP_OVER }, + {0xAE, "CALL", 12, STEP_OVER }, {0xB5, "CLR A", 23, 0 }, {0xC5, "CLR B", 23, 0 }, @@ -273,8 +258,8 @@ static const tms7000_opcodeinfo opcodes[] = { {0xD8, "PUSH", 24, 0 }, {0x0E, "PUSH ST", 23, 0 }, - {0x0B, "RETI", 23, DASMFLAG_STEP_OUT }, - {0x0A, "RETS", 23, DASMFLAG_STEP_OUT }, + {0x0B, "RETI", 23, STEP_OUT }, + {0x0A, "RETS", 23, STEP_OUT }, {0xBE, "RL A", 23, 0 }, {0xCE, "RL B", 23, 0 }, @@ -316,30 +301,30 @@ static const tms7000_opcodeinfo opcodes[] = { {0x5A, "SUB", 5, 0 }, {0x7A, "SUB", 6, 0 }, - {0xFF, "TRAP 0", 44, DASMFLAG_STEP_OVER }, - {0xFE, "TRAP 1", 44, DASMFLAG_STEP_OVER }, - {0xFD, "TRAP 2", 44, DASMFLAG_STEP_OVER }, - {0xFC, "TRAP 3", 44, DASMFLAG_STEP_OVER }, - {0xFB, "TRAP 4", 44, DASMFLAG_STEP_OVER }, - {0xFA, "TRAP 5", 44, DASMFLAG_STEP_OVER }, - {0xF9, "TRAP 6", 44, DASMFLAG_STEP_OVER }, - {0xF8, "TRAP 7", 44, DASMFLAG_STEP_OVER }, - {0xF7, "TRAP 8", 44, DASMFLAG_STEP_OVER }, - {0xF6, "TRAP 9", 44, DASMFLAG_STEP_OVER }, - {0xF5, "TRAP 10", 44, DASMFLAG_STEP_OVER }, - {0xF4, "TRAP 11", 44, DASMFLAG_STEP_OVER }, - {0xF3, "TRAP 12", 44, DASMFLAG_STEP_OVER }, - {0xF2, "TRAP 13", 44, DASMFLAG_STEP_OVER }, - {0xF1, "TRAP 14", 44, DASMFLAG_STEP_OVER }, - {0xF0, "TRAP 15", 44, DASMFLAG_STEP_OVER }, - {0xEF, "TRAP 16", 44, DASMFLAG_STEP_OVER }, - {0xEE, "TRAP 17", 44, DASMFLAG_STEP_OVER }, - {0xED, "TRAP 18", 44, DASMFLAG_STEP_OVER }, - {0xEC, "TRAP 19", 44, DASMFLAG_STEP_OVER }, - {0xEB, "TRAP 20", 44, DASMFLAG_STEP_OVER }, - {0xEA, "TRAP 21", 44, DASMFLAG_STEP_OVER }, - {0xE9, "TRAP 22", 44, DASMFLAG_STEP_OVER }, - {0xE8, "TRAP 23", 44, DASMFLAG_STEP_OVER }, + {0xFF, "TRAP 0", 44, STEP_OVER }, + {0xFE, "TRAP 1", 44, STEP_OVER }, + {0xFD, "TRAP 2", 44, STEP_OVER }, + {0xFC, "TRAP 3", 44, STEP_OVER }, + {0xFB, "TRAP 4", 44, STEP_OVER }, + {0xFA, "TRAP 5", 44, STEP_OVER }, + {0xF9, "TRAP 6", 44, STEP_OVER }, + {0xF8, "TRAP 7", 44, STEP_OVER }, + {0xF7, "TRAP 8", 44, STEP_OVER }, + {0xF6, "TRAP 9", 44, STEP_OVER }, + {0xF5, "TRAP 10", 44, STEP_OVER }, + {0xF4, "TRAP 11", 44, STEP_OVER }, + {0xF3, "TRAP 12", 44, STEP_OVER }, + {0xF2, "TRAP 13", 44, STEP_OVER }, + {0xF1, "TRAP 14", 44, STEP_OVER }, + {0xF0, "TRAP 15", 44, STEP_OVER }, + {0xEF, "TRAP 16", 44, STEP_OVER }, + {0xEE, "TRAP 17", 44, STEP_OVER }, + {0xED, "TRAP 18", 44, STEP_OVER }, + {0xEC, "TRAP 19", 44, STEP_OVER }, + {0xEB, "TRAP 20", 44, STEP_OVER }, + {0xEA, "TRAP 21", 44, STEP_OVER }, + {0xE9, "TRAP 22", 44, STEP_OVER }, + {0xE8, "TRAP 23", 44, STEP_OVER }, {0xB7, "SWAP A", 23, 0 }, {0xC7, "SWAP B", 23, 0 }, @@ -367,17 +352,22 @@ static const tms7000_opcodeinfo opcodes[] = { {0x00, "NOP", 23, 0 } }; -CPU_DISASSEMBLE(tms7000) +u32 tms7000_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t tms7000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int opcode, i/*, size = 1*/; - int pos = 0; + offs_t pos = pc; char tmpbuf[32]; - opcode = oprom[pos++]; + opcode = opcodes.r8(pos++); - for( i=0; i<sizeof(opcodes) / sizeof(tms7000_opcodeinfo); i++ ) + for( i=0; i<sizeof(opcs) / sizeof(tms7000_opcodeinfo); i++ ) { - if( opcode == opcodes[i].opcode ) + if( opcode == opcs[i].opcode ) { /* We found a match */ @@ -387,9 +377,9 @@ CPU_DISASSEMBLE(tms7000) uint16_t c; int16_t d; - util::stream_format(stream, "%s", opcodes[i].name); + util::stream_format(stream, "%s", opcs[i].name); - j=opcodes[i].operand; + j=opcs[i].operand; for( k=0; k<4; k++ ) { @@ -401,34 +391,34 @@ CPU_DISASSEMBLE(tms7000) util::stream_format(stream, "%s", of[j].opstr[k]); break; case UI8: - a = (uint8_t)opram[pos++]; + a = (uint8_t)params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (unsigned int)a); break; case I8: - b = (int8_t)opram[pos++]; + b = (int8_t)params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (int8_t)b); break; case UI16: - c = (uint16_t)opram[pos++]; + c = (uint16_t)params.r8(pos++); c <<= 8; - c += opram[pos++]; + c += params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (unsigned int)c); break; case I16: - d = (int16_t)opram[pos++]; + d = (int16_t)params.r8(pos++); d <<= 8; - d += opram[pos++]; + d += params.r8(pos++); util::stream_format(stream, of[j].opstr[k], (signed int)d); break; case PCREL: - b = (int8_t)opram[pos++]; + b = (int8_t)params.r8(pos++); sprintf(tmpbuf, "$%04X", pc+2+k+b); util::stream_format(stream, of[j].opstr[k], tmpbuf); break; case PCABS: - c = (uint16_t)opram[pos++]; + c = (uint16_t)params.r8(pos++); c <<= 8; - c += opram[pos++]; + c += params.r8(pos++); sprintf(tmpbuf, "$%04X", c); util::stream_format(stream, of[j].opstr[k], tmpbuf); break; @@ -438,11 +428,11 @@ CPU_DISASSEMBLE(tms7000) break; } } - return pos | opcodes[i].s_flag | DASMFLAG_SUPPORTED; + return (pos - pc) | opcs[i].s_flag | SUPPORTED; } } /* No Match */ stream << "Illegal Opcode"; - return pos | DASMFLAG_SUPPORTED; + return (pos - pc) | SUPPORTED; } diff --git a/src/devices/cpu/tms7000/7000dasm.h b/src/devices/cpu/tms7000/7000dasm.h new file mode 100644 index 00000000000..70c01e59fe6 --- /dev/null +++ b/src/devices/cpu/tms7000/7000dasm.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Tim Lindner +/* + + TMS7000 disassembler + +*/ + +#ifndef MAME_CPU_TMS7000_7000DASM_H +#define MAME_CPU_TMS7000_7000DASM_H + +#pragma once + +class tms7000_disassembler : public util::disasm_interface +{ +public: + tms7000_disassembler() = default; + virtual ~tms7000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum operandtype { DONE, NONE, UI8, I8, UI16, I16, PCREL, PCABS, TRAP }; + + struct oprandinfo { + char opstr[4][12]; + operandtype decode[4]; + }; + + struct tms7000_opcodeinfo { + int opcode; + char name[8]; + int operand; + uint32_t s_flag; + }; + + static const oprandinfo of[]; + static const tms7000_opcodeinfo opcs[]; +}; + +#endif diff --git a/src/devices/cpu/tms7000/tms7000.cpp b/src/devices/cpu/tms7000/tms7000.cpp index a54bac9e20f..25265218735 100644 --- a/src/devices/cpu/tms7000/tms7000.cpp +++ b/src/devices/cpu/tms7000/tms7000.cpp @@ -19,6 +19,7 @@ #include "emu.h" #include "tms7000.h" +#include "7000dasm.h" // TMS7000 is the most basic one, 128 bytes internal RAM and no internal ROM. // TMS7020 and TMS7040 are same, but with 2KB and 4KB internal ROM respectively. @@ -51,10 +52,6 @@ DEFINE_DEVICE_TYPE(TMS70C46, tms70c46_device, "tms70c46", "TMC70C46") // internal memory maps -static ADDRESS_MAP_START(tms7000_io, AS_IO, 8, tms7000_device) - AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_READNOP -ADDRESS_MAP_END - static ADDRESS_MAP_START(tms7000_mem, AS_PROGRAM, 8, tms7000_device ) AM_RANGE(0x0000, 0x007f) AM_RAM // 128 bytes internal RAM AM_RANGE(0x0080, 0x00ff) AM_READWRITE(tms7000_unmapped_rf_r, tms7000_unmapped_rf_w) @@ -114,7 +111,8 @@ tms7000_device::tms7000_device(const machine_config &mconfig, const char *tag, d tms7000_device::tms7000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal, uint32_t info_flags) : cpu_device(mconfig, type, tag, owner, clock), m_program_config("program", ENDIANNESS_BIG, 8, 16, 0, internal), - m_io_config("io", ENDIANNESS_BIG, 8, 8, 0, ADDRESS_MAP_NAME(tms7000_io)), + m_port_in_cb{{*this}, {*this}, {*this}, {*this}, {*this}}, + m_port_out_cb{{*this}, {*this}, {*this}, {*this}, {*this}}, m_info_flags(info_flags) { } @@ -177,8 +175,7 @@ tms70c46_device::tms70c46_device(const machine_config &mconfig, const char *tag, device_memory_interface::space_config_vector tms7000_device::memory_space_config() const { return space_config_vector { - std::make_pair(AS_PROGRAM, &m_program_config), - std::make_pair(AS_IO, &m_io_config) + std::make_pair(AS_PROGRAM, &m_program_config) }; } @@ -191,14 +188,18 @@ void tms7000_device::device_start() { // init/zerofill m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); - m_io = &space(AS_IO); + m_direct = m_program->direct<0>(); m_icountptr = &m_icount; m_irq_state[TMS7000_INT1_LINE] = false; m_irq_state[TMS7000_INT3_LINE] = false; + for (auto &cb : m_port_in_cb) + cb.resolve_safe(0xff); + for (auto &cb : m_port_out_cb) + cb.resolve_safe(); + m_idle_state = false; m_idle_halt = false; m_pc = 0; @@ -273,10 +274,9 @@ void tms7000_device::state_string_export(const device_state_entry &entry, std::s } } -offs_t tms7000_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms7000_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms7000 ); - return CPU_DISASSEMBLE_NAME(tms7000)(this, stream, pc, oprom, opram, options); + return new tms7000_disassembler; } @@ -512,7 +512,7 @@ READ8_MEMBER(tms7000_device::tms7000_pf_r) // note: port B is write-only, reading it returns the output value as if ddr is 0xff int port = offset / 2 - 2; if (!machine().side_effect_disabled()) - return (m_io->read_byte(port) & ~m_port_ddr[port]) | (m_port_latch[port] & m_port_ddr[port]); + return (m_port_in_cb[port]() & ~m_port_ddr[port]) | (m_port_latch[port] & m_port_ddr[port]); break; } @@ -594,7 +594,7 @@ WRITE8_MEMBER(tms7000_device::tms7000_pf_w) // note: in memory expansion modes, some port output pins are used for memory strobes. // this is currently ignored, since port writes will always be visible externally on peripheral expansion anyway. int port = offset / 2 - 2; - m_io->write_byte(port, data & m_port_ddr[port]); + m_port_out_cb[port](data & m_port_ddr[port]); m_port_latch[port] = data; break; } @@ -888,7 +888,9 @@ void tms70c46_device::device_start() void tms70c46_device::device_reset() { m_control = 0; - m_io->write_byte(TMS7000_PORTE, 0xff); + + // reset port E + m_port_out_cb[4](0xff); tms7000_device::device_reset(); } @@ -902,7 +904,7 @@ WRITE8_MEMBER(tms70c46_device::control_w) { // d5: enable external databus if (~m_control & data & 0x20) - m_io->write_byte(TMS7000_PORTE, 0xff); // go into high impedance + m_port_out_cb[4](0xff); // put port E into high impedance // d4: enable clock divider when accessing slow memory (not emulated) // known fast memory areas: internal ROM/RAM, system RAM diff --git a/src/devices/cpu/tms7000/tms7000.h b/src/devices/cpu/tms7000/tms7000.h index ef69bdb881e..bd941fbf9ca 100644 --- a/src/devices/cpu/tms7000/tms7000.h +++ b/src/devices/cpu/tms7000/tms7000.h @@ -14,6 +14,33 @@ #include "debugger.h" +// read-only on 70x0 +#define MCFG_TMS7000_IN_PORTA_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 0, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTA_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 0, DEVCB_##_devcb); + +// write-only +#define MCFG_TMS7000_OUT_PORTB_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 1, DEVCB_##_devcb); + +#define MCFG_TMS7000_IN_PORTC_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 2, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTC_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 2, DEVCB_##_devcb); + +#define MCFG_TMS7000_IN_PORTD_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 3, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTD_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 3, DEVCB_##_devcb); + +// TMS70C46 only +#define MCFG_TMS7000_IN_PORTE_CB(_devcb) \ + devcb = &tms7000_device::set_port_read_cb(*device, 4, DEVCB_##_devcb); +#define MCFG_TMS7000_OUT_PORTE_CB(_devcb) \ + devcb = &tms7000_device::set_port_write_cb(*device, 4, DEVCB_##_devcb); + + enum { TMS7000_PC=1, TMS7000_SP, TMS7000_ST }; enum @@ -23,15 +50,6 @@ enum TMS7000_INT3_LINE }; -enum -{ - TMS7000_PORTA = 0, /* read-only on 70x0 */ - TMS7000_PORTB, /* write-only */ - TMS7000_PORTC, - TMS7000_PORTD, - TMS7000_PORTE /* TMS70C46 only */ -}; - class tms7000_device : public cpu_device { @@ -39,6 +57,12 @@ public: // construction/destruction tms7000_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + // static configuration + template<class Object> + static devcb_base &set_port_read_cb(device_t &device, int p, Object &&object) { return downcast<tms7000_device &>(device).m_port_in_cb[p].set_callback(std::move(object)); } + template<class Object> + static devcb_base &set_port_write_cb(device_t &device, int p, Object &&object) { return downcast<tms7000_device &>(device).m_port_out_cb[p].set_callback(std::move(object)); } + DECLARE_READ8_MEMBER(tms7000_unmapped_rf_r) { if (!machine().side_effect_disabled()) logerror("'%s' (%04X): unmapped_rf_r @ $%04x\n", tag(), m_pc, offset + 0x80); return 0; }; DECLARE_WRITE8_MEMBER(tms7000_unmapped_rf_w) { logerror("'%s' (%04X): unmapped_rf_w @ $%04x = $%02x\n", tag(), m_pc, offset + 0x80, data); }; @@ -82,22 +106,21 @@ protected: 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 1; } - 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; + virtual util::disasm_interface *create_disassembler() override; uint32_t chip_get_family() const { return m_info_flags & CHIP_FAMILY_MASK; } virtual void execute_one(uint8_t op); address_space_config m_program_config; - address_space_config m_io_config; + + devcb_read8 m_port_in_cb[5]; + devcb_write8 m_port_out_cb[5]; uint32_t m_info_flags; address_space *m_program; - direct_read_data *m_direct; - address_space *m_io; + direct_read_data<0> *m_direct; int m_icount; bool m_irq_state[2]; @@ -319,8 +342,8 @@ public: DECLARE_WRITE8_MEMBER(dockbus_data_w); // access I/O port E if databus is disabled - DECLARE_READ8_MEMBER(e_bus_data_r) { return machine().side_effect_disabled() ? 0xff : ((m_control & 0x20) ? 0xff : m_io->read_byte(TMS7000_PORTE)); } - DECLARE_WRITE8_MEMBER(e_bus_data_w) { if (~m_control & 0x20) m_io->write_byte(TMS7000_PORTE, data); } + DECLARE_READ8_MEMBER(e_bus_data_r) { return machine().side_effect_disabled() ? 0xff : ((m_control & 0x20) ? 0xff : m_port_in_cb[4]()); } + DECLARE_WRITE8_MEMBER(e_bus_data_w) { if (~m_control & 0x20) m_port_out_cb[4](data); } protected: // device-level overrides diff --git a/src/devices/cpu/tms9900/9900dasm.cpp b/src/devices/cpu/tms9900/9900dasm.cpp index 5d3eac1c105..64520815353 100644 --- a/src/devices/cpu/tms9900/9900dasm.cpp +++ b/src/devices/cpu/tms9900/9900dasm.cpp @@ -9,103 +9,14 @@ #include "emu.h" -#include "debugger.h" -#include "tms9900.h" +#include "tms99com.h" +#include "9900dasm.h" #define MASK 0x0000ffff #define BITS(val,n1,n2) ((val>>(15-(n2))) & (MASK>>(15-((n2)-(n1))))) -enum format_t -{ - format_1, /* 2 address instructions */ - format_2a, /* jump instructions */ - format_2b, /* bit I/O instructions */ - format_3_9, /* logical, multiply, and divide instructions */ - format_4, /* CRU instructions */ - format_5, /* register shift instructions */ - format_6, /* single address instructions */ - format_7, /* instructions without operands */ - format_8a, /* immediate instructions (destination register) */ - format_8b, /* immediate instructions (no destination register) */ - format_9, /* extended operation instruction */ - format_10, /* memory map file instruction */ - format_11, /* multiple precision instructions */ - format_12, /* string instructions */ - format_13, /* multiple precision shift instructions */ - format_14, /* bit testing instructions */ - format_15, /* invert order of field instruction */ - format_16, /* field instructions */ - format_17, /* alter register and jump instructions */ - format_18, /* single register operand instructions */ - format_liim,/* format for liim (looks like format 18) */ - format_19, /* move address instruction */ - format_20, /* list search instructions */ - format_21, /* extend precision instruction */ - - illegal -}; - -/* definitions for flags */ -enum -{ - /* processor set on which opcodes are available */ - ps_any = 0x01, /* every processor in the tms9900/ti990 family */ - ps_mapper = 0x02, /* processors with memory mapper (ti990/10, ti990/12, - and tms99000 with mapper coprocessor) */ - ps_tms9995 = 0x04, /* ti990/12, tms9995, and later */ - ps_tms99000 = 0x08, /* ti990/12, tms99000, and later */ - ps_ti990_12 = 0x10, /* ti990/12 only */ - - /* additional flags for special decoding */ - sd_11 = 0x100, /* bit 11 should be cleared in li, ai, andi, ori, ci, stwp, stst */ - sd_11_15 = 0x200 /* bits 11-15 should be cleared in lwpi, limi, idle, rset, rtwp, ckon, ckof, lrex */ -}; -struct description_t -{ - const char *mnemonic; - format_t format; - int flags; -}; - - -enum opcodes { - /* basic instruction set */ - _a=0, _ab, _c, _cb, _s, _sb, _soc, _socb, _szc, _szcb, - _mov, _movb, _coc, _czc, _xor, _mpy, _div, _xop, _b, _bl, - _blwp, _clr, _seto, _inv, _neg, _abs, _swpb, _inc, _inct, _dec, - _dect, _x, _ldcr, _stcr, _sbo, _sbz, _tb, _jeq, _jgt, _jh, - _jhe, _jl, _jle, _jlt, _jmp, _jnc, _jne, _jno, _joc, _jop, - _sla, _sra, _src, _srl, _ai, _andi, _ci, _li, _ori, _lwpi, - _limi, _stst, _stwp, _rtwp, _idle, _rset, _ckof, _ckon, _lrex, - - /* mapper instruction set */ - _lds, _ldd, _lmf, - - /* tms9995 instruction set */ - _divs, _mpys, _lst, _lwp, - - /* tms99000 instruction set */ - _bind, - - /* ti990/12 instruction set */ - _sram, _slam, _rto, _lto, _cnto, _slsl, _slsp, _bdc, _dbc, _swpm, - _xorm, _orm, _andm, _sm, _am, _mova, _emd, _eint, _dint, _stpc, - _cs, _seqb, _movs, _lim, _lcs, _blsk, _mvsr, _mvsk, _pops, _pshs, - - _cri, _cdi, _negr, _negd, _cre, _cde, _cer, _ced, _nrm, _tmb, - _tcmb, _tsmb, _srj, _arj, _xit, _insf, _xv, _xf, _ar, _cir, - _sr, _mr, _dr, _lr, _str, _iof, _sneb, _crc, _ts, _ad, - _cid, _sd, _md, _dd, _ld, _std, _ep, - - /* tms9940-only instruction set */ - _liim, _dca, _dcs, - - _ill -}; - - -static const description_t descriptions[144+3+1] = +const tms9900_disassembler::description_t tms9900_disassembler::descriptions[144+3+1] = { /* basic instruction set */ { "a", format_1, ps_any }, { "ab", format_1, ps_any }, @@ -203,51 +114,51 @@ static const description_t descriptions[144+3+1] = }; -static const enum opcodes ops_4000_ffff_s12[12]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_4000_ffff_s12[12]= { _szc, _szcb, _s, _sb, /*4000-7000*/ _c, _cb, _a, _ab, _mov, _movb, _soc, _socb /*8000-f000*/ }; -static const enum opcodes ops_2000_3fff_s10[8]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_2000_3fff_s10[8]= { _coc, _czc, _xor, _xop, _ldcr, _stcr, _mpy, _div /*2000-3800*/ }; -static const enum opcodes ops_1000_1fff_s8[16]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_1000_1fff_s8[16]= { _jmp, _jlt, _jle, _jeq, _jhe, _jgt, _jne, _jnc, /*1000-1700*/ _joc, _jno, _jl, _jh, _jop, _sbo, _sbz, _tb /*1800-1f00*/ }; -static const enum opcodes ops_0e40_0fff_s6[7]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0e40_0fff_s6[7]= { _ad, _cid, _sd, _md, _dd, _ld, _std /*0e40-0fc0*/ }; -static const enum opcodes ops_0e00_0e3f_s4[4]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0e00_0e3f_s4[4]= { _iof, _sneb, _crc, _ts /*0e00-0e30*/ }; -static const enum opcodes ops_0c40_0dff_s6[7]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0c40_0dff_s6[7]= { _ar, _cir, _sr, _mr, _dr, _lr, _str /*0c40-0dc0*/ }; -static const enum opcodes ops_0c10_0c3f_s4[3]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0c10_0c3f_s4[3]= { _insf, _xv, _xf /*0c10-0c30*/ }; -static const enum opcodes ops_0c00_0c0f_s0[16]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0c00_0c0f_s0[16]= { _cri, _cdi, _negr, _negd, _cre, _cde, _cer, _ced, /*0c00-0c07*/ _nrm, _tmb, _tcmb, _tsmb, _srj, _arj, _xit, _xit /*0c08-0c0f*/ @@ -255,40 +166,40 @@ static const enum opcodes ops_0c00_0c0f_s0[16]= -static const enum opcodes ops_0800_0bff_s8[4]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0800_0bff_s8[4]= { _sra, _srl, _sla, _src /*0800-0b00*/ }; -static const enum opcodes ops_0400_07ff_s6[16]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0400_07ff_s6[16]= { _blwp, _b, _x, _clr, _neg, _inv, _inc, _inct, /*0400-05c0*/ _dec, _dect, _bl, _swpb, _seto, _abs, _lds, _ldd /*0600-07c0*/ }; -static const enum opcodes ops_0200_03ff_s5[16]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0200_03ff_s5[16]= { _li, _ai, _andi, _ori, _ci, _stwp, _stst, _lwpi, /*0200-02e0*/ _limi, _lmf, _idle, _rset, _rtwp, _ckon, _ckof, _lrex /*0300-03e0*/ }; -static const enum opcodes ops_0100_01ff_s6[4]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0100_01ff_s6[4]= { _ill, _bind, _divs, _mpys /*0100-01c0*/ }; -static const enum opcodes ops_0030_00ff_s4[13]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_0030_00ff_s4[13]= { _stpc, _cs, _seqb, _movs, _lim, /*0030-0070*/ _lst, _lwp, _lcs, _blsk, _mvsr, _mvsk, _pops, _pshs /*0080-00f0*/ }; -static const enum opcodes ops_001c_002f_s0[20]= +const enum tms9900_disassembler::opcodes tms9900_disassembler::ops_001c_002f_s0[20]= { _sram, _slam, _rto, _lto, /*001c-001f*/ _cnto, _slsl, _slsp, _bdc, _dbc, _swpm, _xorm, _orm, /*0020-0027*/ @@ -296,17 +207,14 @@ static const enum opcodes ops_001c_002f_s0[20]= }; - -static int PC; - - -static inline uint16_t readop_arg(const uint8_t *opram, unsigned pc) +inline uint16_t tms9900_disassembler::readop_arg(const data_buffer ¶ms, offs_t &PC) { - uint16_t result = opram[PC++ - pc] << 8; - return result | opram[PC++ - pc]; + uint16_t result = params.r16(PC); + PC += 2;; + return result; } -static void print_arg (std::ostream &stream, int mode, int arg, const uint8_t *opram, unsigned pc) +void tms9900_disassembler::print_arg (std::ostream &stream, int mode, int arg, const data_buffer ¶ms, offs_t &PC) { int base; @@ -319,7 +227,7 @@ static void print_arg (std::ostream &stream, int mode, int arg, const uint8_t *o util::stream_format(stream, "*R%d", arg); break; case 0x2: /* symbolic|indexed */ - base = readop_arg(opram, pc); + base = readop_arg(params, PC); if (arg) /* indexed */ util::stream_format(stream, "@>%04x(R%d)", base, arg); else /* symbolic (direct) */ @@ -331,11 +239,19 @@ static void print_arg (std::ostream &stream, int mode, int arg, const uint8_t *o } } +tms9900_disassembler::tms9900_disassembler(int model) : m_model_id(model) +{ +} + +u32 tms9900_disassembler::opcode_alignment() const +{ + return 2; +} /***************************************************************************** * Disassemble a single command and return the number of bytes it uses. *****************************************************************************/ -static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const uint8_t *oprom, const uint8_t *opram) +offs_t tms9900_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int OP, OP2, opc; int sarg, darg, smode, dmode; @@ -355,26 +271,26 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const Additionally, ti990/12 and tms9995 will generate an illegal error when bits 12-15 are non-zero. */ - #define BETTER_0200_DECODING (model_id == TI990_10_ID) - #define COMPLETE_0200_DECODING (/*(model_id == TI990_12_ID) ||*/ (model_id >= TMS9995_ID)) + #define BETTER_0200_DECODING (m_model_id == TI990_10_ID) + #define COMPLETE_0200_DECODING (/*(m_model_id == TI990_12_ID) ||*/ (m_model_id >= TMS9995_ID)) int processor_mask = ps_any; - if ((model_id == TI990_10_ID) /*|| (model_id == TI990_12_ID)*/ || (model_id >= TMS99000_ID)) + if ((m_model_id == TI990_10_ID) /*|| (m_model_id == TI990_12_ID)*/ || (m_model_id >= TMS99000_ID)) processor_mask |= ps_mapper; /* processors with memory mapper (ti990/10, ti990/12, and tms99000 with mapper coprocessor) */ - if (/*(model_id == TI990_12_ID) ||*/ (model_id >= TMS9995_ID)) + if (/*(m_model_id == TI990_12_ID) ||*/ (m_model_id >= TMS9995_ID)) processor_mask |= ps_tms9995; /* ti990/12, tms9995, and later */ - if (/*(model_id == TI990_12_ID) ||*/ (model_id >= TMS99000_ID)) + if (/*(m_model_id == TI990_12_ID) ||*/ (m_model_id >= TMS99000_ID)) processor_mask |= ps_tms99000; /* ti990/12, tms99000, and later */ - /*if ((model_id == TI990_12_ID)) + /*if ((m_model_id == TI990_12_ID)) processor_mask |= ps_ti990_12;*/ /* ti990/12, tms99000, and later */ - PC = pc; - OP = oprom[PC++ - pc] << 8; - OP |= oprom[PC++ - pc]; + offs_t PC = pc; + OP = opcodes.r16(PC); + PC += 2; /* let's identify the opcode */ if (OP >= 0x4000) @@ -434,7 +350,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const } /* tms9940 replace a few xops with custom instructions */ - if ((opc == _xop) && ((model_id == TMS9940_ID) || (model_id == TMS9985_ID))) + if ((opc == _xop) && ((m_model_id == TMS9940_ID) || (m_model_id == TMS9985_ID))) { switch (BITS(OP,6,9)) { @@ -473,11 +389,11 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const /* bl and blwp instructions are subroutines */ if (mnemonic != nullptr && mnemonic[0] == 'b' && mnemonic[1] == 'l') - dasmflags = DASMFLAG_STEP_OVER; + dasmflags = STEP_OVER; /* b *r11 and rtwp are returns */ else if (opc == 0x045b || (mnemonic != nullptr && strcmp(mnemonic, "rtwp") == 0)) - dasmflags = DASMFLAG_STEP_OUT; + dasmflags = STEP_OUT; switch (format) { @@ -488,9 +404,9 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const darg = BITS(OP,6,9); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); break; case format_2a: /* jump instructions */ @@ -516,13 +432,13 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const if (format == format_3_9) { util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ",R%d", darg); } else { util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ",%d", darg); } break; @@ -539,7 +455,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const sarg = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); break; case format_7: /* instructions without operands */ @@ -548,13 +464,13 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const case format_8a: /* immediate instructions (destination register) */ darg = BITS(OP,12,15); - sarg = readop_arg(opram, pc); + sarg = readop_arg(params, PC); util::stream_format(stream, "%-4s R%d,>%04x", mnemonic, darg, sarg); break; case format_8b: /* immediate instructions (no destination register) */ - sarg = readop_arg(opram, pc); + sarg = readop_arg(params, PC); util::stream_format(stream, "%-4s >%04x", mnemonic, sarg); break; @@ -567,7 +483,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const break; case format_11: /* multiple precision instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -576,14 +492,14 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const byte_count = BITS(OP2,0,3); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); util::stream_format(stream, byte_count ? ",%d" : ",R%d", byte_count); break; case format_12: /* string instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -593,14 +509,14 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const checkpoint = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); util::stream_format(stream, byte_count ? ",%d,R%d" : ",R%d,R%d", byte_count, checkpoint); break; case format_13: /* multiple precision shift instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -608,20 +524,20 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const byte_count = BITS(OP2,0,3); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, byte_count ? ",%d" : ",R%d", byte_count); util::stream_format(stream, darg ? ",%d" : ",R%d", darg); break; case format_14: /* bit testing instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); darg = BITS(OP2,0,9); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); if (darg == 0x3ff) util::stream_format(stream, ",R0"); else @@ -629,7 +545,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const break; case format_15: /* invert order of field instruction */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -637,13 +553,13 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const bit_width = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, bit_position ? ",(%d," : ",(R%d,", bit_position); util::stream_format(stream, bit_width ? "%d)" : "R%d)", bit_width); break; case format_16: /* field instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -653,15 +569,15 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const bit_width = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); util::stream_format(stream, bit_position ? ",(%d," : ",(%d,", bit_position); util::stream_format(stream, bit_width ? "%d)" : "R%d)", bit_width); break; case format_17: /* alter register and jump instructions */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); displacement = (signed char)BITS(OP2,8,15); sarg = BITS(OP2,4,7); @@ -684,7 +600,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const break; case format_19: /* move address instruction */ - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -692,16 +608,16 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const darg = BITS(OP2,6,9); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); break; case format_20: /* list search instructions */ { const char *condition_code; - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -746,9 +662,9 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const } util::stream_format(stream, "%-4s %s,", mnemonic, condition_code); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); break; } @@ -756,7 +672,7 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const { int dest_byte_count; - OP2 = readop_arg(opram, pc); + OP2 = readop_arg(params, PC); smode = BITS(OP2,10,11); sarg = BITS(OP2,12,15); @@ -766,9 +682,9 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const dest_byte_count = BITS(OP,12,15); util::stream_format(stream, "%-4s ", mnemonic); - print_arg(stream, smode, sarg, opram, pc); + print_arg(stream, smode, sarg, params, PC); util::stream_format(stream, ","); - print_arg(stream, dmode, darg, opram, pc); + print_arg(stream, dmode, darg, params, PC); util::stream_format(stream, byte_count ? ",%d" : ",R%d", byte_count); util::stream_format(stream, dest_byte_count ? ",%d" : ",R%d", dest_byte_count); break; @@ -781,20 +697,5 @@ static unsigned Dasm9900 (std::ostream &stream, unsigned pc, int model_id, const break; } - return (PC - pc) | DASMFLAG_SUPPORTED | dasmflags; -} - -CPU_DISASSEMBLE( tms9900 ) -{ - return Dasm9900(stream, pc, TMS9900_ID, oprom, opram); -} - -CPU_DISASSEMBLE( tms9980 ) -{ - return Dasm9900(stream, pc, TMS9980_ID, oprom, opram); -} - -CPU_DISASSEMBLE( tms9995 ) -{ - return Dasm9900(stream, pc, TMS9995_ID, oprom, opram); + return (PC - pc) | SUPPORTED | dasmflags; } diff --git a/src/devices/cpu/tms9900/9900dasm.h b/src/devices/cpu/tms9900/9900dasm.h new file mode 100644 index 00000000000..53fa192284d --- /dev/null +++ b/src/devices/cpu/tms9900/9900dasm.h @@ -0,0 +1,136 @@ +// license:BSD-3-Clause +// copyright-holders:Raphael Nabet +/***************************************************************************** + * + * 9900dasm.c + * TMS 9900 family disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_TMS9900_TMS9900DASM_H +#define MAME_CPU_TMS9900_TMS9900DASM_H + +#pragma once + +class tms9900_disassembler : public util::disasm_interface +{ +public: + tms9900_disassembler(int model); + virtual ~tms9900_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum format_t + { + format_1, /* 2 address instructions */ + format_2a, /* jump instructions */ + format_2b, /* bit I/O instructions */ + format_3_9, /* logical, multiply, and divide instructions */ + format_4, /* CRU instructions */ + format_5, /* register shift instructions */ + format_6, /* single address instructions */ + format_7, /* instructions without operands */ + format_8a, /* immediate instructions (destination register) */ + format_8b, /* immediate instructions (no destination register) */ + format_9, /* extended operation instruction */ + format_10, /* memory map file instruction */ + format_11, /* multiple precision instructions */ + format_12, /* string instructions */ + format_13, /* multiple precision shift instructions */ + format_14, /* bit testing instructions */ + format_15, /* invert order of field instruction */ + format_16, /* field instructions */ + format_17, /* alter register and jump instructions */ + format_18, /* single register operand instructions */ + format_liim,/* format for liim (looks like format 18) */ + format_19, /* move address instruction */ + format_20, /* list search instructions */ + format_21, /* extend precision instruction */ + + illegal + }; + + /* definitions for flags */ + enum + { + /* processor set on which opcodes are available */ + ps_any = 0x01, /* every processor in the tms9900/ti990 family */ + ps_mapper = 0x02, /* processors with memory mapper (ti990/10, ti990/12, + and tms99000 with mapper coprocessor) */ + ps_tms9995 = 0x04, /* ti990/12, tms9995, and later */ + ps_tms99000 = 0x08, /* ti990/12, tms99000, and later */ + ps_ti990_12 = 0x10, /* ti990/12 only */ + + /* additional flags for special decoding */ + sd_11 = 0x100, /* bit 11 should be cleared in li, ai, andi, ori, ci, stwp, stst */ + sd_11_15 = 0x200 /* bits 11-15 should be cleared in lwpi, limi, idle, rset, rtwp, ckon, ckof, lrex */ + }; + + struct description_t + { + const char *mnemonic; + format_t format; + int flags; + }; + + + enum opcodes { + /* basic instruction set */ + _a=0, _ab, _c, _cb, _s, _sb, _soc, _socb, _szc, _szcb, + _mov, _movb, _coc, _czc, _xor, _mpy, _div, _xop, _b, _bl, + _blwp, _clr, _seto, _inv, _neg, _abs, _swpb, _inc, _inct, _dec, + _dect, _x, _ldcr, _stcr, _sbo, _sbz, _tb, _jeq, _jgt, _jh, + _jhe, _jl, _jle, _jlt, _jmp, _jnc, _jne, _jno, _joc, _jop, + _sla, _sra, _src, _srl, _ai, _andi, _ci, _li, _ori, _lwpi, + _limi, _stst, _stwp, _rtwp, _idle, _rset, _ckof, _ckon, _lrex, + + /* mapper instruction set */ + _lds, _ldd, _lmf, + + /* tms9995 instruction set */ + _divs, _mpys, _lst, _lwp, + + /* tms99000 instruction set */ + _bind, + + /* ti990/12 instruction set */ + _sram, _slam, _rto, _lto, _cnto, _slsl, _slsp, _bdc, _dbc, _swpm, + _xorm, _orm, _andm, _sm, _am, _mova, _emd, _eint, _dint, _stpc, + _cs, _seqb, _movs, _lim, _lcs, _blsk, _mvsr, _mvsk, _pops, _pshs, + + _cri, _cdi, _negr, _negd, _cre, _cde, _cer, _ced, _nrm, _tmb, + _tcmb, _tsmb, _srj, _arj, _xit, _insf, _xv, _xf, _ar, _cir, + _sr, _mr, _dr, _lr, _str, _iof, _sneb, _crc, _ts, _ad, + _cid, _sd, _md, _dd, _ld, _std, _ep, + + /* tms9940-only instruction set */ + _liim, _dca, _dcs, + + _ill + }; + + static const description_t descriptions[144+3+1]; + static const enum opcodes ops_4000_ffff_s12[12]; + static const enum opcodes ops_2000_3fff_s10[8]; + static const enum opcodes ops_1000_1fff_s8[16]; + static const enum opcodes ops_0e40_0fff_s6[7]; + static const enum opcodes ops_0e00_0e3f_s4[4]; + static const enum opcodes ops_0c40_0dff_s6[7]; + static const enum opcodes ops_0c10_0c3f_s4[3]; + static const enum opcodes ops_0c00_0c0f_s0[16]; + static const enum opcodes ops_0800_0bff_s8[4]; + static const enum opcodes ops_0400_07ff_s6[16]; + static const enum opcodes ops_0200_03ff_s5[16]; + static const enum opcodes ops_0100_01ff_s6[4]; + static const enum opcodes ops_0030_00ff_s4[13]; + static const enum opcodes ops_001c_002f_s0[20]; + + int m_model_id; + + inline uint16_t readop_arg(const data_buffer ¶ms, offs_t &PC); + void print_arg (std::ostream &stream, int mode, int arg, const data_buffer ¶ms, offs_t &PC); +}; + +#endif diff --git a/src/devices/cpu/tms9900/ti990_10.cpp b/src/devices/cpu/tms9900/ti990_10.cpp index 3f9f60b4129..bcb96cb6d90 100644 --- a/src/devices/cpu/tms9900/ti990_10.cpp +++ b/src/devices/cpu/tms9900/ti990_10.cpp @@ -25,6 +25,7 @@ #include "emu.h" #include "ti990_10.h" +#include "9900dasm.h" /* The following defines can be set to 0 or 1 to disable or enable certain @@ -122,22 +123,10 @@ uint32_t ti990_10_device::execute_input_lines() const return 2; } -// device_disasm_interface overrides -uint32_t ti990_10_device::disasm_min_opcode_bytes() const -{ - return 2; -} - -uint32_t ti990_10_device::disasm_max_opcode_bytes() const -{ - return 6; -} - // TODO: check 9900dasm -offs_t ti990_10_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *ti990_10_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms9900 ); - return CPU_DISASSEMBLE_NAME(tms9900)(this, stream, pc, oprom, opram, options); + return new tms9900_disassembler(TMS9900_ID); } DEFINE_DEVICE_TYPE(TI990_10, ti990_10_device, "ti990_10_cpu", "TI990/10 CPU") diff --git a/src/devices/cpu/tms9900/ti990_10.h b/src/devices/cpu/tms9900/ti990_10.h index bd2d6a65d43..6e9b945e17e 100644 --- a/src/devices/cpu/tms9900/ti990_10.h +++ b/src/devices/cpu/tms9900/ti990_10.h @@ -34,9 +34,7 @@ protected: void execute_run() override; // device_disasm_interface overrides - uint32_t disasm_min_opcode_bytes() const override; - uint32_t disasm_max_opcode_bytes() const override; - offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/cpu/tms9900/tms9900.cpp b/src/devices/cpu/tms9900/tms9900.cpp index e0b207f3335..89f2e1e70a6 100644 --- a/src/devices/cpu/tms9900/tms9900.cpp +++ b/src/devices/cpu/tms9900/tms9900.cpp @@ -110,6 +110,7 @@ #include "emu.h" #include "tms9900.h" +#include "9900dasm.h" #define NOPRG -1 @@ -175,9 +176,9 @@ enum twice their number. Accordingly, the TMS9900 has a CRU bitmask 0x0fff. ****************************************************************************/ -tms99xx_device::tms99xx_device(const machine_config &mconfig, device_type type, const char *tag, int databus_width, int prg_addr_bits, int cru_addr_bits, device_t *owner, uint32_t clock) +tms99xx_device::tms99xx_device(const machine_config &mconfig, device_type type, const char *tag, int data_width, int prg_addr_bits, int cru_addr_bits, device_t *owner, uint32_t clock) : cpu_device(mconfig, type, tag, owner, clock), - m_program_config("program", ENDIANNESS_BIG, databus_width, prg_addr_bits), + m_program_config("program", ENDIANNESS_BIG, data_width, prg_addr_bits), m_io_config("cru", ENDIANNESS_BIG, 8, cru_addr_bits), m_prgspace(nullptr), m_cru(nullptr), @@ -2751,20 +2752,10 @@ uint32_t tms99xx_device::execute_input_lines() const // execute_burn = nop // device_disasm_interface overrides -uint32_t tms99xx_device::disasm_min_opcode_bytes() const -{ - return 2; -} - -uint32_t tms99xx_device::disasm_max_opcode_bytes() const -{ - return 6; -} -offs_t tms99xx_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms99xx_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms9900 ); - return CPU_DISASSEMBLE_NAME(tms9900)(this, stream, pc, oprom, opram, options); + return new tms9900_disassembler(TMS9900_ID); } diff --git a/src/devices/cpu/tms9900/tms9900.h b/src/devices/cpu/tms9900/tms9900.h index 5486043aaa1..61a0fc46b69 100644 --- a/src/devices/cpu/tms9900/tms9900.h +++ b/src/devices/cpu/tms9900/tms9900.h @@ -64,7 +64,7 @@ public: protected: tms99xx_device(const machine_config &mconfig, device_type type, - const char *tag, int databus_width, int prg_addr_bits, int cru_addr_bits, + const char *tag, int data_width, int prg_addr_bits, int cru_addr_bits, device_t *owner, uint32_t clock); // device-level overrides @@ -82,9 +82,7 @@ protected: virtual void execute_run() override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/cpu/tms9900/tms9980a.cpp b/src/devices/cpu/tms9900/tms9980a.cpp index b2dcc2f389a..fc1d12afbc8 100644 --- a/src/devices/cpu/tms9900/tms9980a.cpp +++ b/src/devices/cpu/tms9900/tms9980a.cpp @@ -53,6 +53,7 @@ #include "emu.h" #include "tms9980a.h" +#include "9900dasm.h" /* The following defines can be set to 0 or 1 to disable or enable certain @@ -282,20 +283,10 @@ uint32_t tms9980a_device::execute_input_lines() const // execute_burn = nop // device_disasm_interface overrides -uint32_t tms9980a_device::disasm_min_opcode_bytes() const -{ - return 2; -} - -uint32_t tms9980a_device::disasm_max_opcode_bytes() const -{ - return 6; -} -offs_t tms9980a_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *tms9980a_device::create_disassembler() { - extern CPU_DISASSEMBLE( tms9980 ); - return CPU_DISASSEMBLE_NAME(tms9980)(this, stream, pc, oprom, opram, options); + return new tms9900_disassembler(TMS9980_ID); } DEFINE_DEVICE_TYPE(TMS9980A, tms9980a_device, "tms9980a", "TMS9980A") diff --git a/src/devices/cpu/tms9900/tms9980a.h b/src/devices/cpu/tms9900/tms9980a.h index 34f6eadc434..72adcaf56c5 100644 --- a/src/devices/cpu/tms9900/tms9980a.h +++ b/src/devices/cpu/tms9900/tms9980a.h @@ -44,9 +44,8 @@ protected: uint32_t execute_input_lines() const override; void execute_set_input(int irqline, int state) override; - uint32_t disasm_min_opcode_bytes() const override; - uint32_t disasm_max_opcode_bytes() const override; - offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + address_space_config m_program_config80; address_space_config m_io_config80; }; diff --git a/src/devices/cpu/tms9900/tms9995.cpp b/src/devices/cpu/tms9900/tms9995.cpp index d6bab5aaa4b..542f51f88ae 100644 --- a/src/devices/cpu/tms9900/tms9995.cpp +++ b/src/devices/cpu/tms9900/tms9995.cpp @@ -91,6 +91,7 @@ #include "emu.h" #include "tms9995.h" +#include "9900dasm.h" #define NOPRG -1 @@ -3514,20 +3515,9 @@ uint32_t tms9995_device::execute_input_lines() const return 2; } -uint32_t tms9995_device::disasm_min_opcode_bytes() const +util::disasm_interface *tms9995_device::create_disassembler() { - return 2; -} - -uint32_t tms9995_device::disasm_max_opcode_bytes() const -{ - return 6; -} - -offs_t tms9995_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( tms9995 ); - return CPU_DISASSEMBLE_NAME(tms9995)(this, stream, pc, oprom, opram, options); + return new tms9900_disassembler(TMS9995_ID); } diff --git a/src/devices/cpu/tms9900/tms9995.h b/src/devices/cpu/tms9900/tms9995.h index a0ffa861f8c..ff0357e74e4 100644 --- a/src/devices/cpu/tms9900/tms9995.h +++ b/src/devices/cpu/tms9900/tms9995.h @@ -94,9 +94,7 @@ protected: virtual void execute_run() override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/cpu/ucom4/ucom4.cpp b/src/devices/cpu/ucom4/ucom4.cpp index 81b4e8ae913..8d1523751a9 100644 --- a/src/devices/cpu/ucom4/ucom4.cpp +++ b/src/devices/cpu/ucom4/ucom4.cpp @@ -22,6 +22,7 @@ #include "emu.h" #include "ucom4.h" +#include "ucom4d.h" #include "debugger.h" @@ -136,14 +137,12 @@ void ucom4_cpu_device::state_string_export(const device_state_entry &entry, std: } } -offs_t ucom4_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +util::disasm_interface *ucom4_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE(ucom4); - return CPU_DISASSEMBLE_NAME(ucom4)(this, stream, pc, oprom, opram, options); + return new ucom4_disassembler; } - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- diff --git a/src/devices/cpu/ucom4/ucom4.h b/src/devices/cpu/ucom4/ucom4.h index a442e5c676a..6db82e1a41e 100644 --- a/src/devices/cpu/ucom4/ucom4.h +++ b/src/devices/cpu/ucom4/ucom4.h @@ -134,9 +134,7 @@ protected: virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides - virtual u32 disasm_min_opcode_bytes() const override { return 1; } - virtual u32 disasm_max_opcode_bytes() const override { return 2; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override; + virtual util::disasm_interface *create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; diff --git a/src/devices/cpu/ucom4/ucom4d.cpp b/src/devices/cpu/ucom4/ucom4d.cpp index f83801813ee..678c1952dfc 100644 --- a/src/devices/cpu/ucom4/ucom4d.cpp +++ b/src/devices/cpu/ucom4/ucom4d.cpp @@ -7,24 +7,9 @@ */ #include "emu.h" -#include "debugger.h" -#include "ucom4.h" +#include "ucom4d.h" - -enum e_mnemonics -{ - mLI, mL, mLM, mLDI, mLDZ, mS, mTAL, mTLA, - mX, mXI, mXD, mXM, mXMI, mXMD, mAD, mADC, mADS, mDAA, mDAS, - mEXL, mCLA, mCMA, mCIA, mCLC, mSTC, mTC, mINC, mDEC, mIND, mDED, - mRMB, mSMB, mREB, mSEB, mRPB, mSPB, mJMP, mJCP, mJPA, mCAL, mCZP, mRT, mRTS, - mCI, mCM, mCMB, mTAB, mCLI, mTMB, mTPA, mTPB, - mTIT, mIA, mIP, mOE, mOP, mOCD, mNOP, - mILL, - mTAW, mTAZ, mTHX, mTLY, mXAW, mXAZ, mXHR, mXHX, mXLS, mXLY, mXC, - mSFB, mRFB, mFBT, mFBF, mRAR, mINM, mDEM, mSTM, mTTM, mEI, mDI -}; - -static const char *const s_mnemonics[] = +const char *const ucom4_disassembler::s_mnemonics[] = { "LI", "L", "LM", "LDI", "LDZ", "S", "TAL", "TLA", "X", "XI", "XD", "XM", "XMI", "XMD", "AD", "ADC", "ADS", "DAA", "DAS", @@ -38,7 +23,7 @@ static const char *const s_mnemonics[] = }; // number of bits per opcode parameter, 2 digits means opcode is 2 bytes -static const u8 s_bits[] = +const u8 ucom4_disassembler::s_bits[] = { 4, 0, 2, 80, 4, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, @@ -51,15 +36,12 @@ static const u8 s_bits[] = 2, 2, 2, 2, 0, 0, 0, 80, 0, 0, 0 }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const u32 s_flags[] = +const u32 ucom4_disassembler::s_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, _OVER, _OVER, _OUT, _OUT, + 0, 0, 0, 0, 0, 0, 0, 0, 0, STEP_OVER, STEP_OVER, STEP_OUT, STEP_OUT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -68,7 +50,7 @@ static const u32 s_flags[] = }; -static const u8 ucom4_mnemonic[0x100] = +const u8 ucom4_disassembler::ucom4_mnemonic[0x100] = { /* 0x00 */ mNOP, mDI, mS, mTIT, mTC, mTTM, mDAA, mTAL, @@ -112,11 +94,31 @@ static const u8 ucom4_mnemonic[0x100] = }; +u32 ucom4_disassembler::opcode_alignment() const +{ + return 1; +} + +u32 ucom4_disassembler::interface_flags() const +{ + return PAGED2LEVEL; +} + +u32 ucom4_disassembler::page_address_bits() const +{ + return 6; +} + +u32 ucom4_disassembler::page2_address_bits() const +{ + return 2; +} + -CPU_DISASSEMBLE(ucom4) +offs_t ucom4_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int pos = 0; - u8 op = oprom[pos++]; + offs_t pos = pc; + u8 op = opcodes.r8(pos++); u8 instr = ucom4_mnemonic[op]; util::stream_format(stream,"%-4s ", s_mnemonics[instr]); @@ -128,7 +130,7 @@ CPU_DISASSEMBLE(ucom4) u16 param = op & ((1 << (bits % 10)) - 1); if (bits / 10) { - u8 op2 = oprom[pos++]; + u8 op2 = opcodes.r8(pos++); param = (param << (bits / 10)) | (op2 & ((1 << (bits / 10)) - 1)); bits = (bits % 10) + (bits / 10); } @@ -148,5 +150,5 @@ CPU_DISASSEMBLE(ucom4) util::stream_format(stream, "$%03X", param); } - return pos | s_flags[instr] | DASMFLAG_SUPPORTED; + return (pos - pc) | s_flags[instr] | SUPPORTED; } diff --git a/src/devices/cpu/ucom4/ucom4d.h b/src/devices/cpu/ucom4/ucom4d.h new file mode 100644 index 00000000000..2dd3be4914b --- /dev/null +++ b/src/devices/cpu/ucom4/ucom4d.h @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + NEC uCOM-4 MCU family disassembler + +*/ + + +#ifndef MAME_CPU_UCOM4_UCOM4DASM_H +#define MAME_CPU_UCOM4_UCOM4DASM_H + +#pragma once + +class ucom4_disassembler : public util::disasm_interface +{ +public: + ucom4_disassembler() = default; + virtual ~ucom4_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual u32 page2_address_bits() const override; + + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + enum e_mnemonics + { + mLI, mL, mLM, mLDI, mLDZ, mS, mTAL, mTLA, + mX, mXI, mXD, mXM, mXMI, mXMD, mAD, mADC, mADS, mDAA, mDAS, + mEXL, mCLA, mCMA, mCIA, mCLC, mSTC, mTC, mINC, mDEC, mIND, mDED, + mRMB, mSMB, mREB, mSEB, mRPB, mSPB, mJMP, mJCP, mJPA, mCAL, mCZP, mRT, mRTS, + mCI, mCM, mCMB, mTAB, mCLI, mTMB, mTPA, mTPB, + mTIT, mIA, mIP, mOE, mOP, mOCD, mNOP, + mILL, + mTAW, mTAZ, mTHX, mTLY, mXAW, mXAZ, mXHR, mXHX, mXLS, mXLY, mXC, + mSFB, mRFB, mFBT, mFBF, mRAR, mINM, mDEM, mSTM, mTTM, mEI, mDI + }; + + static const char *const s_mnemonics[]; + static const u8 s_bits[]; + static const u32 s_flags[]; + static const u8 ucom4_mnemonic[0x100]; +}; + +#endif diff --git a/src/devices/cpu/uml.h b/src/devices/cpu/uml.h index 1b60d46cd8b..be32dedd724 100644 --- a/src/devices/cpu/uml.h +++ b/src/devices/cpu/uml.h @@ -73,20 +73,20 @@ namespace uml COND_NV, // requires V COND_U, // requires U COND_NU, // requires U - COND_A, // requires CZ - COND_BE, // requires CZ - COND_G, // requires SVZ - COND_LE, // requires SVZ - COND_L, // requires SV - COND_GE, // requires SV + COND_A, // requires CZ, unsigned + COND_BE, // requires CZ, unsigned + COND_G, // requires SVZ, signed + COND_LE, // requires SVZ, signed + COND_L, // requires SV, signed + COND_GE, // requires SV, signed COND_MAX, // basic condition code aliases COND_E = COND_Z, COND_NE = COND_NZ, - COND_B = COND_C, - COND_AE = COND_NC + COND_B = COND_C, // unsigned + COND_AE = COND_NC // unsigned }; // floating point rounding modes diff --git a/src/devices/cpu/unsp/unsp.cpp b/src/devices/cpu/unsp/unsp.cpp index cb14e9cdec4..8ee2111af65 100644 --- a/src/devices/cpu/unsp/unsp.cpp +++ b/src/devices/cpu/unsp/unsp.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "unsp.h" +#include "unspdasm.h" #include "debugger.h" @@ -30,10 +31,9 @@ device_memory_interface::space_config_vector unsp_device::memory_space_config() }; } -offs_t unsp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *unsp_device::create_disassembler() { - extern CPU_DISASSEMBLE( unsp ); - return CPU_DISASSEMBLE_NAME(unsp)(this, stream, pc, oprom, opram, options); + return new unsp_disassembler; } @@ -116,12 +116,12 @@ void unsp_device::unimplemented_opcode(uint16_t op) uint16_t unsp_device::READ16(uint32_t address) { - return m_program->read_word(address<<1); + return m_program->read_word(address); } void unsp_device::WRITE16(uint32_t address, uint16_t data) { - m_program->write_word(address<<1, data); + m_program->write_word(address, data); } /*****************************************************************************/ diff --git a/src/devices/cpu/unsp/unsp.h b/src/devices/cpu/unsp/unsp.h index 5a445e05099..331bbf46786 100644 --- a/src/devices/cpu/unsp/unsp.h +++ b/src/devices/cpu/unsp/unsp.h @@ -75,9 +75,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; diff --git a/src/devices/cpu/unsp/unspdasm.cpp b/src/devices/cpu/unsp/unspdasm.cpp index 68d620fb7b6..bdea7a729a5 100644 --- a/src/devices/cpu/unsp/unspdasm.cpp +++ b/src/devices/cpu/unsp/unspdasm.cpp @@ -9,22 +9,22 @@ \**************************/ #include "emu.h" -#include <stdarg.h> +#include "unspdasm.h" /*****************************************************************************/ -static const char *reg[] = +const char *unsp_disassembler::reg[] = { "sp", "r1", "r2", "r3", "r4", "bp", "sr", "pc" }; -static const char *jmp[] = +const char *unsp_disassembler::jmp[] = { "jb", "jae", "jge", "jl", "jne", "je", "jpl", "jmi", "jbe", "ja", "jle", "jg", "jvc", "jvs", "jmp", "<inv>" }; -static const char *alu[] = +const char *unsp_disassembler::alu[] = { "add", "adc", "sub", "sbc", "cmp", "<inv>", "neg", "<inv>", @@ -44,14 +44,17 @@ static const char *alu[] = /*****************************************************************************/ -#define UNSP_DASM_OK ((OP2X ? 2 : 1) | DASMFLAG_SUPPORTED) +#define UNSP_DASM_OK ((OP2X ? 2 : 1) | SUPPORTED) -CPU_DISASSEMBLE(unsp) +u32 unsp_disassembler::opcode_alignment() const { - uint16_t op = *(uint16_t *)oprom; - uint16_t imm16 = *(uint16_t *)(oprom + 2); - op = big_endianize_int16(op); - imm16 = big_endianize_int16(imm16); + return 1; +} + +offs_t unsp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint16_t op = opcodes.r16(pc); + uint16_t imm16 = opcodes.r16(pc+1); if(OP0 < 0xf && OPA == 0x7 && OP1 < 2) { diff --git a/src/devices/cpu/unsp/unspdasm.h b/src/devices/cpu/unsp/unspdasm.h new file mode 100644 index 00000000000..ef25b2a433b --- /dev/null +++ b/src/devices/cpu/unsp/unspdasm.h @@ -0,0 +1,32 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/**************************\ +* +* SunPlus u'nSP disassembler +* +* by Ryan Holtz +* +\**************************/ + + +#ifndef MAME_CPU_UNSP_UNSPDASM_H +#define MAME_CPU_UNSP_UNSPDASM_H + +#pragma once + +class unsp_disassembler : public util::disasm_interface +{ +public: + unsp_disassembler() = default; + virtual ~unsp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *reg[]; + static const char *jmp[]; + static const char *alu[]; +}; + +#endif diff --git a/src/devices/cpu/upd7725/dasm7725.cpp b/src/devices/cpu/upd7725/dasm7725.cpp index f2e644e0bec..06a9fdd3d16 100644 --- a/src/devices/cpu/upd7725/dasm7725.cpp +++ b/src/devices/cpu/upd7725/dasm7725.cpp @@ -10,11 +10,16 @@ ***************************************************************************/ #include "emu.h" -#include "upd7725.h" +#include "dasm7725.h" -CPU_DISASSEMBLE(upd7725) +u32 necdsp_disassembler::opcode_alignment() const { - uint32_t opcode = oprom[2] | (oprom[1] << 8) | (oprom[0] << 16); + return 1; +} + +offs_t necdsp_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + uint32_t opcode = opcodes.r32(pc); uint32_t type = (opcode >> 22); // printf("dasm: PC %x opcode %08x\n", pc, opcode); @@ -220,5 +225,5 @@ CPU_DISASSEMBLE(upd7725) } } - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; } diff --git a/src/devices/cpu/upd7725/dasm7725.h b/src/devices/cpu/upd7725/dasm7725.h new file mode 100644 index 00000000000..5280c3e4a46 --- /dev/null +++ b/src/devices/cpu/upd7725/dasm7725.h @@ -0,0 +1,27 @@ +// license:BSD-3-Clause +// copyright-holders:R. Belmont,byuu +/*************************************************************************** + + dasm7725.c + Disassembler for the portable uPD7725 emulator. + Written by byuu + MAME conversion by R. Belmont + +***************************************************************************/ + +#ifndef MAME_CPU_UPD7725_DASM7725_H +#define MAME_CPU_UPD7725_DASM7725_H + +#pragma once + +class necdsp_disassembler : public util::disasm_interface +{ +public: + necdsp_disassembler() = default; + virtual ~necdsp_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + +#endif diff --git a/src/devices/cpu/upd7725/upd7725.cpp b/src/devices/cpu/upd7725/upd7725.cpp index 7ef876613db..716fa45ccf9 100644 --- a/src/devices/cpu/upd7725/upd7725.cpp +++ b/src/devices/cpu/upd7725/upd7725.cpp @@ -14,6 +14,7 @@ #include "emu.h" #include "debugger.h" #include "upd7725.h" +#include "dasm7725.h" //************************************************************************** @@ -67,7 +68,7 @@ void necdsp_device::device_start() // get our address spaces m_program = &space(AS_PROGRAM); m_data = &space(AS_DATA); - m_direct = &m_program->direct(); + m_direct = m_program->direct<-2>(); // register our state for the debugger state_add(STATE_GENPC, "GENPC", regs.pc).noshow(); @@ -316,35 +317,13 @@ void necdsp_device::execute_set_input(int inputnum, int state) } //------------------------------------------------- -// disasm_min_opcode_bytes - return the length -// of the shortest instruction, in bytes -//------------------------------------------------- - -uint32_t necdsp_device::disasm_min_opcode_bytes() const -{ - return 4; -} - - -//------------------------------------------------- -// disasm_max_opcode_bytes - return the length -// of the longest instruction, in bytes -//------------------------------------------------- - -uint32_t necdsp_device::disasm_max_opcode_bytes() const -{ - return 4; -} - -//------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t necdsp_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *necdsp_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd7725 ); - return CPU_DISASSEMBLE_NAME(upd7725)(this, stream, pc, oprom, opram, options); + return new necdsp_disassembler; } void necdsp_device::execute_run() @@ -361,7 +340,7 @@ void necdsp_device::execute_run() if (m_irq_firing == 0) // normal opcode { - opcode = m_direct->read_dword(regs.pc<<2)>>8; + opcode = m_direct->read_dword(regs.pc) >> 8; regs.pc++; } else if (m_irq_firing == 1) // if we're in an interrupt cycle, execute a op 'nop' first... @@ -413,7 +392,7 @@ void necdsp_device::exec_op(uint32_t opcode) { case 3: regs.idb = regs.tr; break; case 4: regs.idb = regs.dp; break; case 5: regs.idb = regs.rp; break; - case 6: regs.idb = m_data->read_word(regs.rp<<1); break; + case 6: regs.idb = m_data->read_word(regs.rp); break; case 7: regs.idb = 0x8000 - regs.flaga.s1; break; //SGN case 8: regs.idb = regs.dr; regs.sr.rqm = 1; break; case 9: regs.idb = regs.dr; break; @@ -610,7 +589,7 @@ void necdsp_device::exec_ld(uint32_t opcode) { case 8: regs.so = BITSWAP16(id, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); break; //LSB first output, output tapped at bit 15 shifting left case 9: regs.so = id; break; //MSB first output, output tapped at bit 15 shifting left case 10: regs.k = id; break; - case 11: regs.k = id; regs.l = m_data->read_word(regs.rp<<1); break; + case 11: regs.k = id; regs.l = m_data->read_word(regs.rp); break; case 12: regs.l = id; regs.k = dataRAM[regs.dp | 0x40]; break; case 13: regs.l = id; break; case 14: regs.trb = id; break; diff --git a/src/devices/cpu/upd7725/upd7725.h b/src/devices/cpu/upd7725/upd7725.h index 76cc13b9226..c52959124a1 100644 --- a/src/devices/cpu/upd7725/upd7725.h +++ b/src/devices/cpu/upd7725/upd7725.h @@ -107,9 +107,7 @@ protected: 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; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // inline data const address_space_config m_program_config, m_data_config; @@ -191,7 +189,7 @@ private: // 2 = next opcode is the second half of int firing 'CALL 0100' int m_irq_firing; address_space *m_program, *m_data; - direct_read_data *m_direct; + direct_read_data<-2> *m_direct; protected: // device callbacks diff --git a/src/devices/cpu/upd7810/upd7810.cpp b/src/devices/cpu/upd7810/upd7810.cpp index 67b6818ec72..4871aaebcbd 100644 --- a/src/devices/cpu/upd7810/upd7810.cpp +++ b/src/devices/cpu/upd7810/upd7810.cpp @@ -374,6 +374,7 @@ STOP 01001000 10111011 12 stop #include "debugger.h" #include "upd7810_macros.h" +#include "upd7810_dasm.h" DEFINE_DEVICE_TYPE(UPD7810, upd7810_device, "upd7810", "uPD7810") @@ -519,28 +520,24 @@ device_memory_interface::space_config_vector upd7810_device::memory_space_config }; } -offs_t upd7810_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upd7810_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd7810 ); - return CPU_DISASSEMBLE_NAME(upd7810)(this, stream, pc, oprom, opram, options); + return new upd7810_disassembler; } -offs_t upd7807_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upd7807_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd7807 ); - return CPU_DISASSEMBLE_NAME(upd7807)(this, stream, pc, oprom, opram, options); + return new upd7807_disassembler; } -offs_t upd7801_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upd7801_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd7801 ); - return CPU_DISASSEMBLE_NAME(upd7801)(this, stream, pc, oprom, opram, options); + return new upd7801_disassembler; } -offs_t upd78c05_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *upd78c05_device::create_disassembler() { - extern CPU_DISASSEMBLE( upd78c05 ); - return CPU_DISASSEMBLE_NAME(upd78c05)(this, stream, pc, oprom, opram, options); + return new upd78c05_disassembler; } WRITE8_MEMBER(upd7810_device::pa_w) @@ -1571,7 +1568,7 @@ void upd78c05_device::handle_timers(int cycles) void upd7810_device::base_device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_to_func.resolve_safe(); m_co0_func.resolve_safe(); diff --git a/src/devices/cpu/upd7810/upd7810.h b/src/devices/cpu/upd7810/upd7810.h index a7d9ec13793..427a4d2d52b 100644 --- a/src/devices/cpu/upd7810/upd7810.h +++ b/src/devices/cpu/upd7810/upd7810.h @@ -227,9 +227,7 @@ protected: 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 1; } - 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; + virtual util::disasm_interface *create_disassembler() override; virtual void handle_timers(int cycles); virtual void upd7810_take_irq(); @@ -413,7 +411,7 @@ protected: const struct opcode_s *m_op70; const struct opcode_s *m_op74; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; int m_icount; uint8_t RP(offs_t port); @@ -1443,7 +1441,7 @@ public: upd7807_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void configure_ops() override; }; @@ -1457,7 +1455,7 @@ public: protected: virtual void device_reset() override; virtual void execute_set_input(int inputnum, int state) override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void handle_timers(int cycles) override; virtual void upd7810_take_irq() override; virtual void configure_ops() override; @@ -1477,7 +1475,7 @@ protected: virtual void device_reset() override; virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const override { return (clocks + 4 - 1) / 4; } virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const override { return (cycles * 4); } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; virtual void handle_timers(int cycles) override; virtual void configure_ops() override; }; diff --git a/src/devices/cpu/upd7810/upd7810_dasm.cpp b/src/devices/cpu/upd7810/upd7810_dasm.cpp index f3da1ba4160..1af4415486e 100644 --- a/src/devices/cpu/upd7810/upd7810_dasm.cpp +++ b/src/devices/cpu/upd7810/upd7810_dasm.cpp @@ -9,249 +9,52 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "upd7810.h" +#include "upd7810_dasm.h" -namespace { +const char *upd7810_base_disassembler::dasm_s::name() const +{ + return token_names[m_token]; +} -class dasm_s +const char *upd7810_base_disassembler::dasm_s::args() const { -public: - const char *name() const { return token_names[m_token]; } - const char *args() const { return (m_token != prefix) ? reinterpret_cast<const char *>(m_args) : nullptr; } + return (m_token != prefix) ? reinterpret_cast<const char *>(m_args) : nullptr; +} - bool is_prefix() const { return m_token == prefix; } - bool is_call() const { return (m_token == CALB) || (m_token == CALF) || (m_token == CALL) || (m_token == CALT); } - bool is_return() const { return (m_token == RET) || (m_token == RETI); } +bool upd7810_base_disassembler::dasm_s::is_prefix() const +{ + return m_token == prefix; +} - const dasm_s &prefix_get(uint8_t op) const { assert(m_token == prefix); return reinterpret_cast<const dasm_s *>(m_args)[op]; } +bool upd7810_base_disassembler::dasm_s::is_call() const +{ + return (m_token == CALB) || (m_token == CALF) || (m_token == CALL) || (m_token == CALT); +} - static const dasm_s XX_7810[256]; - static const dasm_s XX_7807[256]; +bool upd7810_base_disassembler::dasm_s::is_return() const +{ + return (m_token == RET) || (m_token == RETI); +} - static const dasm_s XX_7801[256]; - static const dasm_s XX_78c05[256]; +const upd7810_base_disassembler::dasm_s &upd7810_base_disassembler::dasm_s::prefix_get(uint8_t op) const +{ + assert(m_token == prefix); + return reinterpret_cast<const dasm_s *>(m_args)[op]; +} -protected: - enum - { - prefix = 0, - illegal, - ACI, - ADC, - ADCW, - ADCX, - ADD, - ADDNC, - ADDNCW, - ADDNCX, - ADDW, - ADDX, - ADI, - ADINC, - ANA, - ANAW, - ANAX, - AND, - ANI, - ANIW, - BIT, - BLOCK, - CALB, - CALF, - CALL, - CALT, - CLC, - CLR, /* 7807 */ - CMC, /* 7807 */ - DAA, - DADC, - DADD, - DADDNC, - DAN, - DCR, - DCRW, - DCX, - DEQ, - DGT, - DI, - DIV, - DLT, - DMOV, - DNE, - DOFF, - DON, - DOR, - DRLL, - DRLR, - DSBB, - DSLL, - DSLR, - DSUB, - DSUBNB, - DXR, - EADD, - EI, - EQA, - EQAW, - EQAX, - EQI, - EQIW, - ESUB, - EX, /* 7801 */ - EXA, - EXH, - EXX, - EXR, /* 7807 */ - GTA, - GTAW, - GTAX, - GTI, - GTIW, - HALT, - IN, /* 7801 */ - INR, - INRW, - INX, - JB, - JEA, - JMP, - JR, - JRE, - LBCD, - LDAW, - LDAX, - LDEAX, - LDED, - LHLD, - LSPD, - LTA, - LTAW, - LTAX, - LTI, - LTIW, - LXI, - MOV, - MUL, - MVI, - MVIW, - MVIX, - NEA, - NEAW, - NEAX, - NEGA, - NEI, - NEIW, - NOP, - NOT, /* 7807 */ - OFFA, - OFFAW, - OFFAX, - OFFI, - OFFIW, - ONA, - ONAW, - ONAX, - ONI, - ONIW, - OR, /* 7807 */ - ORA, - ORAW, - ORAX, - ORI, - ORIW, - OUT, /* 7801 */ - PER, /* 7801 */ - PEX, /* 7801 */ - POP, - PUSH, - RET, - RETI, - RETS, - RLD, - RLL, - RLR, - RRD, - SBB, - SBBW, - SBBX, - SBCD, - SBI, - SDED, - SETB, /* 7807 */ - SHLD, - SIO, /* 7801 */ - SK, - SKIT, - SKN, - SKNIT, - SLL, - SLLC, - SLR, - SLRC, - SOFTI, - SSPD, - STAW, - STAX, - STC, - STEAX, - STM, /* 7801 */ - STOP, - SUB, - SUBNB, - SUBNBW, - SUBNBX, - SUBW, - SUBX, - SUI, - SUINB, - TABLE, - XOR, /* 7807 */ - XRA, - XRAW, - XRAX, - XRI - }; - - dasm_s() : m_token(illegal), m_args(nullptr) { } - dasm_s(uint8_t t, const char *a) : m_token(t), m_args(a) { } - dasm_s(const dasm_s (&a)[256]) : m_token(prefix), m_args(a) { } - - uint8_t m_token; - const void *m_args; - - static const char *const token_names[]; - - static const dasm_s d48_7810[256]; - static const dasm_s d48_7807[256]; - static const dasm_s d4C_7810[256]; - static const dasm_s d4C_7807[256]; - static const dasm_s d4D_7810[256]; - static const dasm_s d4D_7807[256]; - static const dasm_s d60[256]; - static const dasm_s d64_7810[256]; - static const dasm_s d64_7807[256]; - static const dasm_s d70[256]; - static const dasm_s d74[256]; - - static const dasm_s d48_7801[256]; - static const dasm_s d4C_7801[256]; - static const dasm_s d4D_7801[256]; - static const dasm_s d60_7801[256]; - static const dasm_s d64_7801[256]; - static const dasm_s d70_7801[256]; - static const dasm_s d74_7801[256]; - - static const dasm_s d48_78c05[256]; - static const dasm_s d4C_78c05[256]; - static const dasm_s d4D_78c05[256]; - static const dasm_s d60_78c05[256]; - static const dasm_s d64_78c05[256]; - static const dasm_s d70_78c05[256]; - static const dasm_s d74_78c05[256]; -}; +upd7810_base_disassembler::dasm_s::dasm_s() : m_token(illegal), m_args(nullptr) +{ +} -const char *const dasm_s::token_names[] = +upd7810_base_disassembler::dasm_s::dasm_s(uint8_t t, const char *a) : m_token(t), m_args(a) +{ +} + +upd7810_base_disassembler::dasm_s::dasm_s(const dasm_s (&a)[256]) : m_token(prefix), m_args(a) +{ +} + +const char *const upd7810_base_disassembler::dasm_s::token_names[] = { "", "illegal", @@ -431,284 +234,836 @@ const char *const dasm_s::token_names[] = "XRI" }; +// prefix 60 +const upd7810_base_disassembler::dasm_s upd7810_base_disassembler::d60[256] = +{ + { }, // 00: 0110 0000 0000 0000 + { }, // 01: 0110 0000 0000 0001 + { }, // 02: 0110 0000 0000 0010 + { }, // 03: 0110 0000 0000 0011 + { }, // 04: 0110 0000 0000 0100 + { }, // 05: 0110 0000 0000 0101 + { }, // 06: 0110 0000 0000 0110 + { }, // 07: 0110 0000 0000 0111 + {ANA, "V,A" }, // 08: 0110 0000 0000 1000 + {ANA, "A,A" }, // 09: 0110 0000 0000 1001 + {ANA, "B,A" }, // 0a: 0110 0000 0000 1010 + {ANA, "C,A" }, // 0b: 0110 0000 0000 1011 + {ANA, "D,A" }, // 0c: 0110 0000 0000 1100 + {ANA, "E,A" }, // 0d: 0110 0000 0000 1101 + {ANA, "H,A" }, // 0e: 0110 0000 0000 1110 + {ANA, "L,A" }, // 0f: 0110 0000 0000 1111 -// prefix 48 -const dasm_s dasm_s::d48_7810[256] = + {XRA, "V,A" }, // 10: 0110 0000 0001 0000 + {XRA, "A,A" }, // 11: 0110 0000 0001 0001 + {XRA, "B,A" }, // 12: 0110 0000 0001 0010 + {XRA, "C,A" }, // 13: 0110 0000 0001 0011 + {XRA, "D,A" }, // 14: 0110 0000 0001 0100 + {XRA, "E,A" }, // 15: 0110 0000 0001 0101 + {XRA, "H,A" }, // 16: 0110 0000 0001 0110 + {XRA, "L,A" }, // 17: 0110 0000 0001 0111 + {ORA, "V,A" }, // 18: 0110 0000 0001 1000 + {ORA, "A,A" }, // 19: 0110 0000 0001 1001 + {ORA, "B,A" }, // 1a: 0110 0000 0001 1010 + {ORA, "C,A" }, // 1b: 0110 0000 0001 1011 + {ORA, "D,A" }, // 1c: 0110 0000 0001 1100 + {ORA, "E,A" }, // 1d: 0110 0000 0001 1101 + {ORA, "H,A" }, // 1e: 0110 0000 0001 1110 + {ORA, "L,A" }, // 1f: 0110 0000 0001 1111 + + {ADDNC, "V,A" }, // 20: 0110 0000 0010 0000 + {ADDNC, "A,A" }, // 21: 0110 0000 0010 0001 + {ADDNC, "B,A" }, // 22: 0110 0000 0010 0010 + {ADDNC, "C,A" }, // 23: 0110 0000 0010 0011 + {ADDNC, "D,A" }, // 24: 0110 0000 0010 0100 + {ADDNC, "E,A" }, // 25: 0110 0000 0010 0101 + {ADDNC, "H,A" }, // 26: 0110 0000 0010 0110 + {ADDNC, "L,A" }, // 27: 0110 0000 0010 0111 + {GTA, "V,A" }, // 28: 0110 0000 0010 1000 + {GTA, "A,A" }, // 29: 0110 0000 0010 1001 + {GTA, "B,A" }, // 2a: 0110 0000 0010 1010 + {GTA, "C,A" }, // 2b: 0110 0000 0010 1011 + {GTA, "D,A" }, // 2c: 0110 0000 0010 1100 + {GTA, "E,A" }, // 2d: 0110 0000 0010 1101 + {GTA, "H,A" }, // 2e: 0110 0000 0010 1110 + {GTA, "L,A" }, // 2f: 0110 0000 0010 1111 + + {SUBNB, "V,A" }, // 30: 0110 0000 0011 0000 + {SUBNB, "A,A" }, // 31: 0110 0000 0011 0001 + {SUBNB, "B,A" }, // 32: 0110 0000 0011 0010 + {SUBNB, "C,A" }, // 33: 0110 0000 0011 0011 + {SUBNB, "D,A" }, // 34: 0110 0000 0011 0100 + {SUBNB, "E,A" }, // 35: 0110 0000 0011 0101 + {SUBNB, "H,A" }, // 36: 0110 0000 0011 0110 + {SUBNB, "L,A" }, // 37: 0110 0000 0011 0111 + {LTA, "V,A" }, // 38: 0110 0000 0011 1000 + {LTA, "A,A" }, // 39: 0110 0000 0011 1001 + {LTA, "B,A" }, // 3a: 0110 0000 0011 1010 + {LTA, "C,A" }, // 3b: 0110 0000 0011 1011 + {LTA, "D,A" }, // 3c: 0110 0000 0011 1100 + {LTA, "E,A" }, // 3d: 0110 0000 0011 1101 + {LTA, "H,A" }, // 3e: 0110 0000 0011 1110 + {LTA, "L,A" }, // 3f: 0110 0000 0011 1111 + + {ADD, "V,A" }, // 40: 0110 0000 0100 0000 + {ADD, "A,A" }, // 41: 0110 0000 0100 0001 + {ADD, "B,A" }, // 42: 0110 0000 0100 0010 + {ADD, "C,A" }, // 43: 0110 0000 0100 0011 + {ADD, "D,A" }, // 44: 0110 0000 0100 0100 + {ADD, "E,A" }, // 45: 0110 0000 0100 0101 + {ADD, "H,A" }, // 46: 0110 0000 0100 0110 + {ADD, "L,A" }, // 47: 0110 0000 0100 0111 + { }, // 48: 0110 0000 0100 1000 + { }, // 49: 0110 0000 0100 1001 + { }, // 4a: 0110 0000 0100 1010 + { }, // 4b: 0110 0000 0100 1011 + { }, // 4c: 0110 0000 0100 1100 + { }, // 4d: 0110 0000 0100 1101 + { }, // 4e: 0110 0000 0100 1110 + { }, // 4f: 0110 0000 0100 1111 + + {ADC, "V,A" }, // 50: 0110 0000 0101 0000 + {ADC, "A,A" }, // 51: 0110 0000 0101 0001 + {ADC, "B,A" }, // 52: 0110 0000 0101 0010 + {ADC, "C,A" }, // 53: 0110 0000 0101 0011 + {ADC, "D,A" }, // 54: 0110 0000 0101 0100 + {ADC, "E,A" }, // 55: 0110 0000 0101 0101 + {ADC, "H,A" }, // 56: 0110 0000 0101 0110 + {ADC, "L,A" }, // 57: 0110 0000 0101 0111 + { }, // 58: 0110 0000 0101 1000 + { }, // 59: 0110 0000 0101 1001 + { }, // 5a: 0110 0000 0101 1010 + { }, // 5b: 0110 0000 0101 1011 + { }, // 5c: 0110 0000 0101 1100 + { }, // 5d: 0110 0000 0101 1101 + { }, // 5e: 0110 0000 0101 1110 + { }, // 5f: 0110 0000 0101 1111 + + {SUB, "V,A" }, // 60: 0110 0000 0110 0000 + {SUB, "A,A" }, // 61: 0110 0000 0110 0001 + {SUB, "B,A" }, // 62: 0110 0000 0110 0010 + {SUB, "C,A" }, // 63: 0110 0000 0110 0011 + {SUB, "D,A" }, // 64: 0110 0000 0110 0100 + {SUB, "E,A" }, // 65: 0110 0000 0110 0101 + {SUB, "H,A" }, // 66: 0110 0000 0110 0110 + {SUB, "L,A" }, // 67: 0110 0000 0110 0111 + {NEA, "V,A" }, // 68: 0110 0000 0110 1000 + {NEA, "A,A" }, // 69: 0110 0000 0110 1001 + {NEA, "B,A" }, // 6a: 0110 0000 0110 1010 + {NEA, "C,A" }, // 6b: 0110 0000 0110 1011 + {NEA, "D,A" }, // 6c: 0110 0000 0110 1100 + {NEA, "E,A" }, // 6d: 0110 0000 0110 1101 + {NEA, "H,A" }, // 6e: 0110 0000 0110 1110 + {NEA, "L,A" }, // 6f: 0110 0000 0110 1111 + + {SBB, "V,A" }, // 70: 0110 0000 0111 0000 + {SBB, "A,A" }, // 71: 0110 0000 0111 0001 + {SBB, "B,A" }, // 72: 0110 0000 0111 0010 + {SBB, "C,A" }, // 73: 0110 0000 0111 0011 + {SBB, "D,A" }, // 74: 0110 0000 0111 0100 + {SBB, "E,A" }, // 75: 0110 0000 0111 0101 + {SBB, "H,A" }, // 76: 0110 0000 0111 0110 + {SBB, "L,A" }, // 77: 0110 0000 0111 0111 + {EQA, "V,A" }, // 78: 0110 0000 0111 1000 + {EQA, "A,A" }, // 79: 0110 0000 0111 1001 + {EQA, "B,A" }, // 7a: 0110 0000 0111 1010 + {EQA, "C,A" }, // 7b: 0110 0000 0111 1011 + {EQA, "D,A" }, // 7c: 0110 0000 0111 1100 + {EQA, "E,A" }, // 7d: 0110 0000 0111 1101 + {EQA, "H,A" }, // 7e: 0110 0000 0111 1110 + {EQA, "L,A" }, // 7f: 0110 0000 0111 1111 + + { }, // 80: 0110 0000 1000 0000 + { }, // 81: 0110 0000 1000 0001 + { }, // 82: 0110 0000 1000 0010 + { }, // 83: 0110 0000 1000 0011 + { }, // 84: 0110 0000 1000 0100 + { }, // 85: 0110 0000 1000 0101 + { }, // 86: 0110 0000 1000 0110 + { }, // 87: 0110 0000 1000 0111 + {ANA, "A,V" }, // 88: 0110 0000 1000 1000 + {ANA, "A,A" }, // 89: 0110 0000 1000 1001 + {ANA, "A,B" }, // 8a: 0110 0000 1000 1010 + {ANA, "A,C" }, // 8b: 0110 0000 1000 1011 + {ANA, "A,D" }, // 8c: 0110 0000 1000 1100 + {ANA, "A,E" }, // 8d: 0110 0000 1000 1101 + {ANA, "A,H" }, // 8e: 0110 0000 1000 1110 + {ANA, "A,L" }, // 8f: 0110 0000 1000 1111 + + {XRA, "A,V" }, // 90: 0110 0000 1001 0000 + {XRA, "A,A" }, // 91: 0110 0000 1001 0001 + {XRA, "A,B" }, // 92: 0110 0000 1001 0010 + {XRA, "A,C" }, // 93: 0110 0000 1001 0011 + {XRA, "A,D" }, // 94: 0110 0000 1001 0100 + {XRA, "A,E" }, // 95: 0110 0000 1001 0101 + {XRA, "A,H" }, // 96: 0110 0000 1001 0110 + {XRA, "A,L" }, // 97: 0110 0000 1001 0111 + {ORA, "A,V" }, // 98: 0110 0000 1001 1000 + {ORA, "A,A" }, // 99: 0110 0000 1001 1001 + {ORA, "A,B" }, // 9a: 0110 0000 1001 1010 + {ORA, "A,C" }, // 9b: 0110 0000 1001 1011 + {ORA, "A,D" }, // 9c: 0110 0000 1001 1100 + {ORA, "A,E" }, // 9d: 0110 0000 1001 1101 + {ORA, "A,H" }, // 9e: 0110 0000 1001 1110 + {ORA, "A,L" }, // 9f: 0110 0000 1001 1111 + + {ADDNC, "A,V" }, // a0: 0110 0000 1010 0000 + {ADDNC, "A,A" }, // a1: 0110 0000 1010 0001 + {ADDNC, "A,B" }, // a2: 0110 0000 1010 0010 + {ADDNC, "A,C" }, // a3: 0110 0000 1010 0011 + {ADDNC, "A,D" }, // a4: 0110 0000 1010 0100 + {ADDNC, "A,E" }, // a5: 0110 0000 1010 0101 + {ADDNC, "A,H" }, // a6: 0110 0000 1010 0110 + {ADDNC, "A,L" }, // a7: 0110 0000 1010 0111 + {GTA, "A,V" }, // a8: 0110 0000 1010 1000 + {GTA, "A,A" }, // a9: 0110 0000 1010 1001 + {GTA, "A,B" }, // aa: 0110 0000 1010 1010 + {GTA, "A,C" }, // ab: 0110 0000 1010 1011 + {GTA, "A,D" }, // ac: 0110 0000 1010 1100 + {GTA, "A,E" }, // ad: 0110 0000 1010 1101 + {GTA, "A,H" }, // ae: 0110 0000 1010 1110 + {GTA, "A,L" }, // af: 0110 0000 1010 1111 + + {SUBNB, "A,V" }, // b0: 0110 0000 1011 0000 + {SUBNB, "A,A" }, // b1: 0110 0000 1011 0001 + {SUBNB, "A,B" }, // b2: 0110 0000 1011 0010 + {SUBNB, "A,C" }, // b3: 0110 0000 1011 0011 + {SUBNB, "A,D" }, // b4: 0110 0000 1011 0100 + {SUBNB, "A,E" }, // b5: 0110 0000 1011 0101 + {SUBNB, "A,H" }, // b6: 0110 0000 1011 0110 + {SUBNB, "A,L" }, // b7: 0110 0000 1011 0111 + {LTA, "A,V" }, // b8: 0110 0000 1011 1000 + {LTA, "A,A" }, // b9: 0110 0000 1011 1001 + {LTA, "A,B" }, // ba: 0110 0000 1011 1010 + {LTA, "A,C" }, // bb: 0110 0000 1011 1011 + {LTA, "A,D" }, // bc: 0110 0000 1011 1100 + {LTA, "A,E" }, // bd: 0110 0000 1011 1101 + {LTA, "A,H" }, // be: 0110 0000 1011 1110 + {LTA, "A,L" }, // bf: 0110 0000 1011 1111 + + {ADD, "A,V" }, // c0: 0110 0000 1100 0000 + {ADD, "A,A" }, // c1: 0110 0000 1100 0001 + {ADD, "A,B" }, // c2: 0110 0000 1100 0010 + {ADD, "A,C" }, // c3: 0110 0000 1100 0011 + {ADD, "A,D" }, // c4: 0110 0000 1100 0100 + {ADD, "A,E" }, // c5: 0110 0000 1100 0101 + {ADD, "A,H" }, // c6: 0110 0000 1100 0110 + {ADD, "A,L" }, // c7: 0110 0000 1100 0111 + {ONA, "A,V" }, // c8: 0110 0000 1100 1000 + {ONA, "A,A" }, // c9: 0110 0000 1100 1001 + {ONA, "A,B" }, // ca: 0110 0000 1100 1010 + {ONA, "A,C" }, // cb: 0110 0000 1100 1011 + {ONA, "A,D" }, // cc: 0110 0000 1100 1100 + {ONA, "A,E" }, // cd: 0110 0000 1100 1101 + {ONA, "A,H" }, // ce: 0110 0000 1100 1110 + {ONA, "A,L" }, // cf: 0110 0000 1100 1111 + + {ADC, "A,V" }, // d0: 0110 0000 1101 0000 + {ADC, "A,A" }, // d1: 0110 0000 1101 0001 + {ADC, "A,B" }, // d2: 0110 0000 1101 0010 + {ADC, "A,C" }, // d3: 0110 0000 1101 0011 + {ADC, "A,D" }, // d4: 0110 0000 1101 0100 + {ADC, "A,E" }, // d5: 0110 0000 1101 0101 + {ADC, "A,H" }, // d6: 0110 0000 1101 0110 + {ADC, "A,L" }, // d7: 0110 0000 1101 0111 + {OFFA, "A,V" }, // d8: 0110 0000 1101 1000 + {OFFA, "A,A" }, // d9: 0110 0000 1101 1001 + {OFFA, "A,B" }, // da: 0110 0000 1101 1010 + {OFFA, "A,C" }, // db: 0110 0000 1101 1011 + {OFFA, "A,D" }, // dc: 0110 0000 1101 1100 + {OFFA, "A,E" }, // dd: 0110 0000 1101 1101 + {OFFA, "A,H" }, // de: 0110 0000 1101 1110 + {OFFA, "A,L" }, // df: 0110 0000 1101 1111 + + {SUB, "A,V" }, // e0: 0110 0000 1110 0000 + {SUB, "A,A" }, // e1: 0110 0000 1110 0001 + {SUB, "A,B" }, // e2: 0110 0000 1110 0010 + {SUB, "A,C" }, // e3: 0110 0000 1110 0011 + {SUB, "A,D" }, // e4: 0110 0000 1110 0100 + {SUB, "A,E" }, // e5: 0110 0000 1110 0101 + {SUB, "A,H" }, // e6: 0110 0000 1110 0110 + {SUB, "A,L" }, // e7: 0110 0000 1110 0111 + {NEA, "A,V" }, // e8: 0110 0000 1110 1000 + {NEA, "A,A" }, // e9: 0110 0000 1110 1001 + {NEA, "A,B" }, // ea: 0110 0000 1110 1010 + {NEA, "A,C" }, // eb: 0110 0000 1110 1011 + {NEA, "A,D" }, // ec: 0110 0000 1110 1100 + {NEA, "A,E" }, // ed: 0110 0000 1110 1101 + {NEA, "A,H" }, // ee: 0110 0000 1110 1110 + {NEA, "A,L" }, // ef: 0110 0000 1110 1111 + + {SBB, "A,V" }, // f0: 0110 0000 1111 0000 + {SBB, "A,A" }, // f1: 0110 0000 1111 0001 + {SBB, "A,B" }, // f2: 0110 0000 1111 0010 + {SBB, "A,C" }, // f3: 0110 0000 1111 0011 + {SBB, "A,D" }, // f4: 0110 0000 1111 0100 + {SBB, "A,E" }, // f5: 0110 0000 1111 0101 + {SBB, "A,H" }, // f6: 0110 0000 1111 0110 + {SBB, "A,L" }, // f7: 0110 0000 1111 0111 + {EQA, "A,V" }, // f8: 0110 0000 1111 1000 + {EQA, "A,A" }, // f9: 0110 0000 1111 1001 + {EQA, "A,B" }, // fa: 0110 0000 1111 1010 + {EQA, "A,C" }, // fb: 0110 0000 1111 1011 + {EQA, "A,D" }, // fc: 0110 0000 1111 1100 + {EQA, "A,E" }, // fd: 0110 0000 1111 1101 + {EQA, "A,H" }, // fe: 0110 0000 1111 1110 + {EQA, "A,L" } // ff: 0110 0000 1111 1111 +}; + +// prefix 70 +const upd7810_base_disassembler::dasm_s upd7810_base_disassembler::d70[256] = { - { }, // 00: 0100 1000 0000 0000 - {SLRC, "A" }, // 01: 0100 1000 0000 0001 - {SLRC, "B" }, // 02: 0100 1000 0000 0010 - {SLRC, "C" }, // 03: 0100 1000 0000 0011 - { }, // 04: 0100 1000 0000 0100 - {SLLC, "A" }, // 05: 0100 1000 0000 0101 - {SLLC, "B" }, // 06: 0100 1000 0000 0110 - {SLLC, "C" }, // 07: 0100 1000 0000 0111 - {SK, "NV" }, // 08: 0100 1000 0000 1000 - { }, // 09: 0100 1000 0000 1001 - {SK, "CY" }, // 0a: 0100 1000 0000 1010 - {SK, "HC" }, // 0b: 0100 1000 0000 1011 - {SK, "Z" }, // 0c: 0100 1000 0000 1100 - { }, // 0d: 0100 1000 0000 1101 - { }, // 0e: 0100 1000 0000 1110 - { }, // 0f: 0100 1000 0000 1111 + { }, // 00: 0111 0000 0000 0000 + { }, // 01: 0111 0000 0000 0001 + { }, // 02: 0111 0000 0000 0010 + { }, // 03: 0111 0000 0000 0011 + { }, // 04: 0111 0000 0000 0100 + { }, // 05: 0111 0000 0000 0101 + { }, // 06: 0111 0000 0000 0110 + { }, // 07: 0111 0000 0000 0111 + { }, // 08: 0111 0000 0000 1000 + { }, // 09: 0111 0000 0000 1001 + { }, // 0a: 0111 0000 0000 1010 + { }, // 0b: 0111 0000 0000 1011 + { }, // 0c: 0111 0000 0000 1100 + { }, // 0d: 0111 0000 0000 1101 + {SSPD, "%w" }, // 0e: 0111 0000 0000 1110 llll llll hhhh hhhh + {LSPD, "%w" }, // 0f: 0111 0000 0000 1111 llll llll hhhh hhhh - { }, // 10: 0100 1000 0001 0000 - { }, // 11: 0100 1000 0001 0001 - { }, // 12: 0100 1000 0001 0010 - { }, // 13: 0100 1000 0001 0011 - { }, // 14: 0100 1000 0001 0100 - { }, // 15: 0100 1000 0001 0101 - { }, // 16: 0100 1000 0001 0110 - { }, // 17: 0100 1000 0001 0111 - {SKN, "NV" }, // 18: 0100 1000 0001 1000 - { }, // 19: 0100 1000 0001 1001 - {SKN, "CY" }, // 1a: 0100 1000 0001 1010 - {SKN, "HC" }, // 1b: 0100 1000 0001 1011 - {SKN, "Z" }, // 1c: 0100 1000 0001 1100 - { }, // 1d: 0100 1000 0001 1101 - { }, // 1e: 0100 1000 0001 1110 - { }, // 1f: 0100 1000 0001 1111 + { }, // 10: 0111 0000 0001 0000 + { }, // 11: 0111 0000 0001 0001 + { }, // 12: 0111 0000 0001 0010 + { }, // 13: 0111 0000 0001 0011 + { }, // 14: 0111 0000 0001 0100 + { }, // 15: 0111 0000 0001 0101 + { }, // 16: 0111 0000 0001 0110 + { }, // 17: 0111 0000 0001 0111 + { }, // 18: 0111 0000 0001 1000 + { }, // 19: 0111 0000 0001 1001 + { }, // 1a: 0111 0000 0001 1010 + { }, // 1b: 0111 0000 0001 1011 + { }, // 1c: 0111 0000 0001 1100 + { }, // 1d: 0111 0000 0001 1101 + {SBCD, "%w" }, // 1e: 0111 0000 0001 1110 llll llll hhhh hhhh + {LBCD, "%w" }, // 1f: 0111 0000 0001 1111 llll llll hhhh hhhh - { }, // 20: 0100 1000 0010 0000 - {SLR, "A" }, // 21: 0100 1000 0010 0001 - {SLR, "B" }, // 22: 0100 1000 0010 0010 - {SLR, "C" }, // 23: 0100 1000 0010 0011 - { }, // 24: 0100 1000 0010 0100 - {SLL, "A" }, // 25: 0100 1000 0010 0101 - {SLL, "B" }, // 26: 0100 1000 0010 0110 - {SLL, "C" }, // 27: 0100 1000 0010 0111 - {JEA, nullptr }, // 28: 0100 1000 0010 1000 - {CALB,nullptr }, // 29: 0100 1000 0010 1001 - {CLC, nullptr }, // 2a: 0100 1000 0010 1010 - {STC, nullptr }, // 2b: 0100 1000 0010 1011 - { }, // 2c: 0100 1000 0010 1100 - {MUL, "A" }, // 2d: 0100 1000 0010 1101 - {MUL, "B" }, // 2e: 0100 1000 0010 1110 - {MUL, "C" }, // 2f: 0100 1000 0010 1111 + { }, // 20: 0111 0000 0010 0000 + { }, // 21: 0111 0000 0010 0001 + { }, // 22: 0111 0000 0010 0010 + { }, // 23: 0111 0000 0010 0011 + { }, // 24: 0111 0000 0010 0100 + { }, // 25: 0111 0000 0010 0101 + { }, // 26: 0111 0000 0010 0110 + { }, // 27: 0111 0000 0010 0111 + { }, // 28: 0111 0000 0010 1000 + { }, // 29: 0111 0000 0010 1001 + { }, // 2a: 0111 0000 0010 1010 + { }, // 2b: 0111 0000 0010 1011 + { }, // 2c: 0111 0000 0010 1100 + { }, // 2d: 0111 0000 0010 1101 + {SDED, "%w" }, // 2e: 0111 0000 0010 1110 llll llll hhhh hhhh + {LDED, "%w" }, // 2f: 0111 0000 0010 1111 llll llll hhhh hhhh - { }, // 30: 0100 1000 0011 0000 - {RLR, "A" }, // 31: 0100 1000 0011 0001 - {RLR, "B" }, // 32: 0100 1000 0011 0010 - {RLR, "C" }, // 33: 0100 1000 0011 0011 - { }, // 34: 0100 1000 0011 0100 - {RLL, "A" }, // 35: 0100 1000 0011 0101 - {RLL, "B" }, // 36: 0100 1000 0011 0110 - {RLL, "C" }, // 37: 0100 1000 0011 0111 - {RLD, nullptr }, // 38: 0100 1000 0011 1000 - {RRD, nullptr }, // 39: 0100 1000 0011 1001 - {NEGA, nullptr }, // 3a: 0100 1000 0011 1010 - {HALT, nullptr }, // 3b: 0100 1000 0011 1011 - { }, // 3c: 0100 1000 0011 1100 - {DIV, "A" }, // 3d: 0100 1000 0011 1101 - {DIV, "B" }, // 3e: 0100 1000 0011 1110 - {DIV, "C" }, // 3f: 0100 1000 0011 1111 + { }, // 30: 0111 0000 0011 0000 + { }, // 31: 0111 0000 0011 0001 + { }, // 32: 0111 0000 0011 0010 + { }, // 33: 0111 0000 0011 0011 + { }, // 34: 0111 0000 0011 0100 + { }, // 35: 0111 0000 0011 0101 + { }, // 36: 0111 0000 0011 0110 + { }, // 37: 0111 0000 0011 0111 + { }, // 38: 0111 0000 0011 1000 + { }, // 39: 0111 0000 0011 1001 + { }, // 3a: 0111 0000 0011 1010 + { }, // 3b: 0111 0000 0011 1011 + { }, // 3c: 0111 0000 0011 1100 + { }, // 3d: 0111 0000 0011 1101 + {SHLD, "%w" }, // 3e: 0111 0000 0011 1110 llll llll hhhh hhhh + {LHLD, "%w" }, // 3f: 0111 0000 0011 1111 llll llll hhhh hhhh - {SKIT, "NMI" }, // 40: 0100 1000 0100 0000 - {SKIT, "FT0" }, // 41: 0100 1000 0100 0001 - {SKIT, "FT1" }, // 42: 0100 1000 0100 0010 - {SKIT, "F1" }, // 43: 0100 1000 0100 0011 - {SKIT, "F2" }, // 44: 0100 1000 0100 0100 - {SKIT, "FE0" }, // 45: 0100 1000 0100 0101 - {SKIT, "FE1" }, // 46: 0100 1000 0100 0110 - {SKIT, "FEIN" }, // 47: 0100 1000 0100 0111 - {SKIT, "FAD" }, // 48: 0100 1000 0100 1000 - {SKIT, "FSR" }, // 49: 0100 1000 0100 1001 - {SKIT, "FST" }, // 4a: 0100 1000 0100 1010 - {SKIT, "ER" }, // 4b: 0100 1000 0100 1011 - {SKIT, "OV" }, // 4c: 0100 1000 0100 1100 - { }, // 4d: 0100 1000 0100 1101 - { }, // 4e: 0100 1000 0100 1110 - { }, // 4f: 0100 1000 0100 1111 + {EADD, "EA,V" }, // 40: 0111 0000 0100 0000 + {EADD, "EA,A" }, // 41: 0111 0000 0100 0001 + {EADD, "EA,B" }, // 42: 0111 0000 0100 0010 + {EADD, "EA,C" }, // 43: 0111 0000 0100 0011 + { }, // 44: 0111 0000 0100 0100 + { }, // 45: 0111 0000 0100 0101 + { }, // 46: 0111 0000 0100 0110 + { }, // 47: 0111 0000 0100 0111 + { }, // 48: 0111 0000 0100 1000 + { }, // 49: 0111 0000 0100 1001 + { }, // 4a: 0111 0000 0100 1010 + { }, // 4b: 0111 0000 0100 1011 + { }, // 4c: 0111 0000 0100 1100 + { }, // 4d: 0111 0000 0100 1101 + { }, // 4e: 0111 0000 0100 1110 + { }, // 4f: 0111 0000 0100 1111 - {SKIT, "AN4" }, // 50: 0100 1000 0101 0000 - {SKIT, "AN5" }, // 51: 0100 1000 0101 0001 - {SKIT, "AN6" }, // 52: 0100 1000 0101 0010 - {SKIT, "AN7" }, // 53: 0100 1000 0101 0011 - {SKIT, "SB" }, // 54: 0100 1000 0101 0100 - { }, // 55: 0100 1000 0101 0101 - { }, // 56: 0100 1000 0101 0110 - { }, // 57: 0100 1000 0101 0111 - { }, // 58: 0100 1000 0101 1000 - { }, // 59: 0100 1000 0101 1001 - { }, // 5a: 0100 1000 0101 1010 - { }, // 5b: 0100 1000 0101 1011 - { }, // 5c: 0100 1000 0101 1100 - { }, // 5d: 0100 1000 0101 1101 - { }, // 5e: 0100 1000 0101 1110 - { }, // 5f: 0100 1000 0101 1111 + { }, // 50: 0111 0000 0101 0000 + { }, // 51: 0111 0000 0101 0001 + { }, // 52: 0111 0000 0101 0010 + { }, // 53: 0111 0000 0101 0011 + { }, // 54: 0111 0000 0101 0100 + { }, // 55: 0111 0000 0101 0101 + { }, // 56: 0111 0000 0101 0110 + { }, // 57: 0111 0000 0101 0111 + { }, // 58: 0111 0000 0101 1000 + { }, // 59: 0111 0000 0101 1001 + { }, // 5a: 0111 0000 0101 1010 + { }, // 5b: 0111 0000 0101 1011 + { }, // 5c: 0111 0000 0101 1100 + { }, // 5d: 0111 0000 0101 1101 + { }, // 5e: 0111 0000 0101 1110 + { }, // 5f: 0111 0000 0101 1111 - {SKNIT, "NMI" }, // 60: 0100 1000 0110 0000 - {SKNIT, "FT0" }, // 61: 0100 1000 0110 0001 - {SKNIT, "FT1" }, // 62: 0100 1000 0110 0010 - {SKNIT, "F1" }, // 63: 0100 1000 0110 0011 - {SKNIT, "F2" }, // 64: 0100 1000 0110 0100 - {SKNIT, "FE0" }, // 65: 0100 1000 0110 0101 - {SKNIT, "FE1" }, // 66: 0100 1000 0110 0110 - {SKNIT, "FEIN" }, // 67: 0100 1000 0110 0111 - {SKNIT, "FAD" }, // 68: 0100 1000 0110 1000 - {SKNIT, "FSR" }, // 69: 0100 1000 0110 1001 - {SKNIT, "FST" }, // 6a: 0100 1000 0110 1010 - {SKNIT, "ER" }, // 6b: 0100 1000 0110 1011 - {SKNIT, "OV" }, // 6c: 0100 1000 0110 1100 - { }, // 6d: 0100 1000 0110 1101 - { }, // 6e: 0100 1000 0110 1110 - { }, // 6f: 0100 1000 0110 1111 + {ESUB, "EA,V" }, // 60: 0111 0000 0110 0000 + {ESUB, "EA,A" }, // 61: 0111 0000 0110 0001 + {ESUB, "EA,B" }, // 62: 0111 0000 0110 0010 + {ESUB, "EA,C" }, // 63: 0111 0000 0110 0011 + { }, // 64: 0111 0000 0110 0100 + { }, // 65: 0111 0000 0110 0101 + { }, // 66: 0111 0000 0110 0110 + { }, // 67: 0111 0000 0110 0111 + {MOV, "V,(%w)" }, // 68: 0111 0000 0110 1000 llll llll hhhh hhhh + {MOV, "A,(%w)" }, // 69: 0111 0000 0110 1001 llll llll hhhh hhhh + {MOV, "B,(%w)" }, // 6a: 0111 0000 0110 1010 llll llll hhhh hhhh + {MOV, "C,(%w)" }, // 6b: 0111 0000 0110 1011 llll llll hhhh hhhh + {MOV, "D,(%w)" }, // 6c: 0111 0000 0110 1100 llll llll hhhh hhhh + {MOV, "E,(%w)" }, // 6d: 0111 0000 0110 1101 llll llll hhhh hhhh + {MOV, "H,(%w)" }, // 6e: 0111 0000 0110 1110 llll llll hhhh hhhh + {MOV, "L,(%w)" }, // 6f: 0111 0000 0110 1111 llll llll hhhh hhhh - {SKNIT, "AN4" }, // 70: 0100 1000 0111 0000 - {SKNIT, "AN5" }, // 71: 0100 1000 0111 0001 - {SKNIT, "AN6" }, // 72: 0100 1000 0111 0010 - {SKNIT, "AN7" }, // 73: 0100 1000 0111 0011 - {SKNIT, "SB" }, // 74: 0100 1000 0111 0100 - { }, // 75: 0100 1000 0111 0101 - { }, // 76: 0100 1000 0111 0110 - { }, // 77: 0100 1000 0111 0111 - { }, // 78: 0100 1000 0111 1000 - { }, // 79: 0100 1000 0111 1001 - { }, // 7a: 0100 1000 0111 1010 - { }, // 7b: 0100 1000 0111 1011 - { }, // 7c: 0100 1000 0111 1100 - { }, // 7d: 0100 1000 0111 1101 - { }, // 7e: 0100 1000 0111 1110 - { }, // 7f: 0100 1000 0111 1111 + { }, // 70: 0111 0000 0111 0000 + { }, // 71: 0111 0000 0111 0001 + { }, // 72: 0111 0000 0111 0010 + { }, // 73: 0111 0000 0111 0011 + { }, // 74: 0111 0000 0111 0100 + { }, // 75: 0111 0000 0111 0101 + { }, // 76: 0111 0000 0111 0110 + { }, // 77: 0111 0000 0111 0111 + {MOV, "(%w),V" }, // 78: 0111 0000 0111 1000 llll llll hhhh hhhh + {MOV, "(%w),A" }, // 79: 0111 0000 0111 1001 llll llll hhhh hhhh + {MOV, "(%w),B" }, // 7a: 0111 0000 0111 1010 llll llll hhhh hhhh + {MOV, "(%w),C" }, // 7b: 0111 0000 0111 1011 llll llll hhhh hhhh + {MOV, "(%w),D" }, // 7c: 0111 0000 0111 1100 llll llll hhhh hhhh + {MOV, "(%w),E" }, // 7d: 0111 0000 0111 1101 llll llll hhhh hhhh + {MOV, "(%w),H" }, // 7e: 0111 0000 0111 1110 llll llll hhhh hhhh + {MOV, "(%w),L" }, // 7f: 0111 0000 0111 1111 llll llll hhhh hhhh - { }, // 80: 0100 1000 1000 0000 - { }, // 81: 0100 1000 1000 0001 - {LDEAX, "(DE)" }, // 82: 0100 1000 1000 0010 - {LDEAX, "(HL)" }, // 83: 0100 1000 1000 0011 - {LDEAX, "(DE++)" }, // 84: 0100 1000 1000 0100 - {LDEAX, "(HL++)" }, // 85: 0100 1000 1000 0101 - { }, // 86: 0100 1000 1000 0110 - { }, // 87: 0100 1000 1000 0111 - { }, // 88: 0100 1000 1000 1000 - { }, // 89: 0100 1000 1000 1001 - { }, // 8a: 0100 1000 1000 1010 - {LDEAX, "(DE+%b)" }, // 8b: 0100 1000 1000 1011 xxxx xxxx - {LDEAX, "(HL+A)" }, // 8c: 0100 1000 1000 1100 - {LDEAX, "(HL+B)" }, // 8d: 0100 1000 1000 1101 - {LDEAX, "(HL+EA)" }, // 8e: 0100 1000 1000 1110 - {LDEAX, "(HL+%b)" }, // 8f: 0100 1000 1000 1111 xxxx xxxx + { }, // 80: 0111 0000 1000 0000 + { }, // 81: 0111 0000 1000 0001 + { }, // 82: 0111 0000 1000 0010 + { }, // 83: 0111 0000 1000 0011 + { }, // 84: 0111 0000 1000 0100 + { }, // 85: 0111 0000 1000 0101 + { }, // 86: 0111 0000 1000 0110 + { }, // 87: 0111 0000 1000 0111 + { }, // 88: 0111 0000 1000 1000 + {ANAX, "(BC)" }, // 89: 0111 0000 1000 1001 + {ANAX, "(DE)" }, // 8a: 0111 0000 1000 1010 + {ANAX, "(HL)" }, // 8b: 0111 0000 1000 1011 + {ANAX, "(DE+)" }, // 8c: 0111 0000 1000 1100 + {ANAX, "(HL+)" }, // 8d: 0111 0000 1000 1101 + {ANAX, "(DE-)" }, // 8e: 0111 0000 1000 1110 + {ANAX, "(HL-)" }, // 8f: 0111 0000 1000 1111 - { }, // 90: 0100 1000 1000 0000 - { }, // 91: 0100 1000 1000 0001 - {STEAX, "(DE)" }, // 92: 0100 1000 1000 0010 - {STEAX, "(HL)" }, // 93: 0100 1000 1000 0011 - {STEAX, "(DE++)" }, // 94: 0100 1000 1000 0100 - {STEAX, "(HL++)" }, // 95: 0100 1000 1000 0101 - { }, // 96: 0100 1000 1000 0110 - { }, // 97: 0100 1000 1000 0111 - { }, // 98: 0100 1000 1000 1000 - { }, // 99: 0100 1000 1000 1001 - { }, // 9a: 0100 1000 1000 1010 - {STEAX, "(DE+%b)" }, // 9b: 0100 1000 1000 1011 xxxx xxxx - {STEAX, "(HL+A)" }, // 9c: 0100 1000 1000 1100 - {STEAX, "(HL+B)" }, // 9d: 0100 1000 1000 1101 - {STEAX, "(HL+EA)" }, // 9e: 0100 1000 1000 1110 - {STEAX, "(HL+%b)" }, // 9f: 0100 1000 1000 1111 xxxx xxxx + { }, // 90: 0111 0000 1001 0000 + {XRAX, "(BC)" }, // 91: 0111 0000 1001 0001 + {XRAX, "(DE)" }, // 92: 0111 0000 1001 0010 + {XRAX, "(HL)" }, // 93: 0111 0000 1001 0011 + {XRAX, "(DE+)" }, // 94: 0111 0000 1001 0100 + {XRAX, "(HL+)" }, // 95: 0111 0000 1001 0101 + {XRAX, "(DE-)" }, // 96: 0111 0000 1001 0110 + {XRAX, "(HL-)" }, // 97: 0111 0000 1001 0111 + { }, // 98: 0111 0000 1001 1000 + {ORAX, "(BC)" }, // 99: 0111 0000 1001 1001 + {ORAX, "(DE)" }, // 9a: 0111 0000 1001 1010 + {ORAX, "(HL)" }, // 9b: 0111 0000 1001 1011 + {ORAX, "(DE+)" }, // 9c: 0111 0000 1001 1100 + {ORAX, "(HL+)" }, // 9d: 0111 0000 1001 1101 + {ORAX, "(DE-)" }, // 9e: 0111 0000 1001 1110 + {ORAX, "(HL-)" }, // 9f: 0111 0000 1001 1111 - {DSLR, "EA" }, // a0: 0100 1000 1010 0000 - { }, // a1: 0100 1000 1010 0001 - { }, // a2: 0100 1000 1010 0010 - { }, // a3: 0100 1000 1010 0011 - {DSLL, "EA" }, // a4: 0100 1000 1010 0100 - { }, // a5: 0100 1000 1010 0101 - { }, // a6: 0100 1000 1010 0110 - { }, // a7: 0100 1000 1010 0111 - {TABLE, nullptr }, // a8: 0100 1000 1010 1000 - { }, // a9: 0100 1000 1010 1001 - { }, // aa: 0100 1000 1010 1010 - { }, // ab: 0100 1000 1010 1011 - { }, // ac: 0100 1000 1010 1100 - { }, // ad: 0100 1000 1010 1101 - { }, // ae: 0100 1000 1010 1110 - { }, // af: 0100 1000 1010 1111 + { }, // a0: 0111 0000 1010 0000 + {ADDNCX, "(BC)" }, // a1: 0111 0000 1010 0001 + {ADDNCX, "(DE)" }, // a2: 0111 0000 1010 0010 + {ADDNCX, "(HL)" }, // a3: 0111 0000 1010 0011 + {ADDNCX, "(DE+)" }, // a4: 0111 0000 1010 0100 + {ADDNCX, "(HL+)" }, // a5: 0111 0000 1010 0101 + {ADDNCX, "(DE-)" }, // a6: 0111 0000 1010 0110 + {ADDNCX, "(HL-)" }, // a7: 0111 0000 1010 0111 + { }, // a8: 0111 0000 1010 1000 + {GTAX, "(BC)" }, // a9: 0111 0000 1010 1001 + {GTAX, "(DE)" }, // aa: 0111 0000 1010 1010 + {GTAX, "(HL)" }, // ab: 0111 0000 1010 1011 + {GTAX, "(DE+)" }, // ac: 0111 0000 1010 1100 + {GTAX, "(HL+)" }, // ad: 0111 0000 1010 1101 + {GTAX, "(DE-)" }, // ae: 0111 0000 1010 1110 + {GTAX, "(HL-)" }, // af: 0111 0000 1010 1111 - {DRLR, "EA" }, // b0: 0100 1000 1011 0000 - { }, // b1: 0100 1000 1011 0001 - { }, // b2: 0100 1000 1011 0010 - { }, // b3: 0100 1000 1011 0011 - {DRLL, "EA" }, // b4: 0100 1000 1011 0100 - { }, // b5: 0100 1000 1011 0101 - { }, // b6: 0100 1000 1011 0110 - { }, // b7: 0100 1000 1011 0111 - { }, // b8: 0100 1000 1011 1000 - { }, // b9: 0100 1000 1011 1001 - { }, // ba: 0100 1000 1011 1010 - {STOP, nullptr }, // bb: 0100 1000 1011 1011 7810 - { }, // bc: 0100 1000 1011 1100 - { }, // bd: 0100 1000 1011 1101 - { }, // be: 0100 1000 1011 1110 - { }, // bf: 0100 1000 1011 1111 + { }, // b0: 0111 0000 1011 0000 + {SUBNBX, "(BC)" }, // b1: 0111 0000 1011 0001 + {SUBNBX, "(DE)" }, // b2: 0111 0000 1011 0010 + {SUBNBX, "(HL)" }, // b3: 0111 0000 1011 0011 + {SUBNBX, "(DE+)" }, // b4: 0111 0000 1011 0100 + {SUBNBX, "(HL+)" }, // b5: 0111 0000 1011 0101 + {SUBNBX, "(DE-)" }, // b6: 0111 0000 1011 0110 + {SUBNBX, "(HL-)" }, // b7: 0111 0000 1011 0111 + { }, // b8: 0111 0000 1011 1000 + {LTAX, "(BC)" }, // b9: 0111 0000 1011 1001 + {LTAX, "(DE)" }, // ba: 0111 0000 1011 1010 + {LTAX, "(HL)" }, // bb: 0111 0000 1011 1011 + {LTAX, "(DE+)" }, // bc: 0111 0000 1011 1100 + {LTAX, "(HL+)" }, // bd: 0111 0000 1011 1101 + {LTAX, "(DE-)" }, // be: 0111 0000 1011 1110 + {LTAX, "(HL-)" }, // bf: 0111 0000 1011 1111 - {DMOV, "EA,ECNT" }, // c0: 0100 1000 1100 0000 - {DMOV, "EA,ECPT" }, // c1: 0100 1000 1100 0001 7810 - { }, // c2: 0100 1000 1100 0010 - { }, // c3: 0100 1000 1100 0011 - { }, // c4: 0100 1000 1100 0100 - { }, // c5: 0100 1000 1100 0101 - { }, // c6: 0100 1000 1100 0110 - { }, // c7: 0100 1000 1100 0111 - { }, // c8: 0100 1000 1100 1000 - { }, // c9: 0100 1000 1100 1001 - { }, // ca: 0100 1000 1100 1010 - { }, // cb: 0100 1000 1100 1011 - { }, // cc: 0100 1000 1100 1100 - { }, // cd: 0100 1000 1100 1101 - { }, // ce: 0100 1000 1100 1110 - { }, // cf: 0100 1000 1100 1111 + { }, // c0: 0111 0000 1100 0000 + {ADDX, "(BC)" }, // c1: 0111 0000 1100 0001 + {ADDX, "(DE)" }, // c2: 0111 0000 1100 0010 + {ADDX, "(HL)" }, // c3: 0111 0000 1100 0011 + {ADDX, "(DE+)" }, // c4: 0111 0000 1100 0100 + {ADDX, "(HL+)" }, // c5: 0111 0000 1100 0101 + {ADDX, "(DE-)" }, // c6: 0111 0000 1100 0110 + {ADDX, "(HL-)" }, // c7: 0111 0000 1100 0111 + { }, // c8: 0111 0000 1100 1000 + {ONAX, "(BC)" }, // c9: 0111 0000 1100 1001 + {ONAX, "(DE)" }, // ca: 0111 0000 1100 1010 + {ONAX, "(HL)" }, // cb: 0111 0000 1100 1011 + {ONAX, "(DE+)" }, // cc: 0111 0000 1100 1100 + {ONAX, "(HL+)" }, // cd: 0111 0000 1100 1101 + {ONAX, "(DE-)" }, // ce: 0111 0000 1100 1110 + {ONAX, "(HL-)" }, // cf: 0111 0000 1100 1111 - { }, // d0: 0100 1000 1101 0000 - { }, // d1: 0100 1000 1101 0001 - {DMOV, "ETM0,EA" }, // d2: 0100 1000 1101 0010 - {DMOV, "ETM1,EA" }, // d3: 0100 1000 1101 0011 - { }, // d4: 0100 1000 1101 0100 - { }, // d5: 0100 1000 1101 0101 - { }, // d6: 0100 1000 1101 0110 - { }, // d7: 0100 1000 1101 0111 - { }, // d8: 0100 1000 1101 1000 - { }, // d9: 0100 1000 1101 1001 - { }, // da: 0100 1000 1101 1010 - { }, // db: 0100 1000 1101 1011 - { }, // dc: 0100 1000 1101 1100 - { }, // dd: 0100 1000 1101 1101 - { }, // de: 0100 1000 1101 1110 - { }, // df: 0100 1000 1101 1111 + { }, // d0: 0111 0000 1101 0000 + {ADCX, "(BC)" }, // d1: 0111 0000 1101 0001 + {ADCX, "(DE)" }, // d2: 0111 0000 1101 0010 + {ADCX, "(HL)" }, // d3: 0111 0000 1101 0011 + {ADCX, "(DE+)" }, // d4: 0111 0000 1101 0100 + {ADCX, "(HL+)" }, // d5: 0111 0000 1101 0101 + {ADCX, "(DE-)" }, // d6: 0111 0000 1101 0110 + {ADCX, "(HL-)" }, // d7: 0111 0000 1101 0111 + { }, // d8: 0111 0000 1101 1000 + {OFFAX, "(BC)" }, // d9: 0111 0000 1101 1001 + {OFFAX, "(DE)" }, // da: 0111 0000 1101 1010 + {OFFAX, "(HL)" }, // db: 0111 0000 1101 1011 + {OFFAX, "(DE+)" }, // dc: 0111 0000 1101 1100 + {OFFAX, "(HL+)" }, // dd: 0111 0000 1101 1101 + {OFFAX, "(DE-)" }, // de: 0111 0000 1101 1110 + {OFFAX, "(HL-)" }, // df: 0111 0000 1101 1111 - { }, // e0: 0100 1000 1110 0000 - { }, // e1: 0100 1000 1110 0001 - { }, // e2: 0100 1000 1110 0010 - { }, // e3: 0100 1000 1110 0011 - { }, // e4: 0100 1000 1110 0100 - { }, // e5: 0100 1000 1110 0101 - { }, // e6: 0100 1000 1110 0110 - { }, // e7: 0100 1000 1110 0111 - { }, // e8: 0100 1000 1110 1000 - { }, // e9: 0100 1000 1110 1001 - { }, // ea: 0100 1000 1110 1010 - { }, // eb: 0100 1000 1110 1011 - { }, // ec: 0100 1000 1110 1100 - { }, // ed: 0100 1000 1110 1101 - { }, // ee: 0100 1000 1110 1110 - { }, // ef: 0100 1000 1110 1111 + { }, // e0: 0111 0000 1110 0000 + {SUBX, "(BC)" }, // e1: 0111 0000 1110 0001 + {SUBX, "(DE)" }, // e2: 0111 0000 1110 0010 + {SUBX, "(HL)" }, // e3: 0111 0000 1110 0011 + {SUBX, "(DE+)" }, // e4: 0111 0000 1110 0100 + {SUBX, "(HL+)" }, // e5: 0111 0000 1110 0101 + {SUBX, "(DE-)" }, // e6: 0111 0000 1110 0110 + {SUBX, "(HL-)" }, // e7: 0111 0000 1110 0111 + { }, // e8: 0111 0000 1110 1000 + {NEAX, "(BC)" }, // e9: 0111 0000 1110 1001 + {NEAX, "(DE)" }, // ea: 0111 0000 1110 1010 + {NEAX, "(HL)" }, // eb: 0111 0000 1110 1011 + {NEAX, "(DE+)" }, // ec: 0111 0000 1110 1100 + {NEAX, "(HL+)" }, // ed: 0111 0000 1110 1101 + {NEAX, "(DE-)" }, // ee: 0111 0000 1110 1110 + {NEAX, "(HL-)" }, // ef: 0111 0000 1110 1111 - { }, // f0: 0100 1000 1111 0000 - { }, // f1: 0100 1000 1111 0001 - { }, // f2: 0100 1000 1111 0010 - { }, // f3: 0100 1000 1111 0011 - { }, // f4: 0100 1000 1111 0100 - { }, // f5: 0100 1000 1111 0101 - { }, // f6: 0100 1000 1111 0110 - { }, // f7: 0100 1000 1111 0111 - { }, // f8: 0100 1000 1111 1000 - { }, // f9: 0100 1000 1111 1001 - { }, // fa: 0100 1000 1111 1010 - { }, // fb: 0100 1000 1111 1011 - { }, // fc: 0100 1000 1111 1100 - { }, // fd: 0100 1000 1111 1101 - { }, // fe: 0100 1000 1111 1110 - { } // ff: 0100 1000 1111 1111 + { }, // f0: 0111 0000 1111 0000 + {SBBX, "(BC)" }, // f1: 0111 0000 1111 0001 + {SBBX, "(DE)" }, // f2: 0111 0000 1111 0010 + {SBBX, "(HL)" }, // f3: 0111 0000 1111 0011 + {SBBX, "(DE+)" }, // f4: 0111 0000 1111 0100 + {SBBX, "(HL+)" }, // f5: 0111 0000 1111 0101 + {SBBX, "(DE-)" }, // f6: 0111 0000 1111 0110 + {SBBX, "(HL-)" }, // f7: 0111 0000 1111 0111 + { }, // f8: 0111 0000 1111 1000 + {EQAX, "(BC)" }, // f9: 0111 0000 1111 1001 + {EQAX, "(DE)" }, // fa: 0111 0000 1111 1010 + {EQAX, "(HL)" }, // fb: 0111 0000 1111 1011 + {EQAX, "(DE+)" }, // fc: 0111 0000 1111 1100 + {EQAX, "(HL+)" }, // fd: 0111 0000 1111 1101 + {EQAX, "(DE-)" }, // fe: 0111 0000 1111 1110 + {EQAX, "(HL-)" } // ff: 0111 0000 1111 1111 +}; + +// prefix 74 +const upd7810_base_disassembler::dasm_s upd7810_base_disassembler::d74[256] = +{ + { }, // 00: 0111 0100 0000 0000 + { }, // 01: 0111 0100 0000 0001 + { }, // 02: 0111 0100 0000 0010 + { }, // 03: 0111 0100 0000 0011 + { }, // 04: 0111 0100 0000 0100 + { }, // 05: 0111 0100 0000 0101 + { }, // 06: 0111 0100 0000 0110 + { }, // 07: 0111 0100 0000 0111 + {ANI, "V,%b" }, // 08: 0111 0100 0000 1000 xxxx xxxx + {ANI, "A,%b" }, // 09: 0111 0100 0000 1001 xxxx xxxx + {ANI, "B,%b" }, // 0a: 0111 0100 0000 1010 xxxx xxxx + {ANI, "C,%b" }, // 0b: 0111 0100 0000 1011 xxxx xxxx + {ANI, "D,%b" }, // 0c: 0111 0100 0000 1100 xxxx xxxx + {ANI, "E,%b" }, // 0d: 0111 0100 0000 1101 xxxx xxxx + {ANI, "H,%b" }, // 0e: 0111 0100 0000 1110 xxxx xxxx + {ANI, "L,%b" }, // 0f: 0111 0100 0000 1111 xxxx xxxx + + {XRI, "V,%b" }, // 10: 0111 0100 0001 0000 xxxx xxxx + {XRI, "A,%b" }, // 11: 0111 0100 0001 0001 xxxx xxxx + {XRI, "B,%b" }, // 12: 0111 0100 0001 0010 xxxx xxxx + {XRI, "C,%b" }, // 13: 0111 0100 0001 0011 xxxx xxxx + {XRI, "D,%b" }, // 14: 0111 0100 0001 0100 xxxx xxxx + {XRI, "E,%b" }, // 15: 0111 0100 0001 0101 xxxx xxxx + {XRI, "H,%b" }, // 16: 0111 0100 0001 0110 xxxx xxxx + {XRI, "L,%b" }, // 17: 0111 0100 0001 0111 xxxx xxxx + {ORI, "V,%b" }, // 18: 0111 0100 0001 1000 xxxx xxxx + {ORI, "A,%b" }, // 19: 0111 0100 0001 1001 xxxx xxxx + {ORI, "B,%b" }, // 1a: 0111 0100 0001 1010 xxxx xxxx + {ORI, "C,%b" }, // 1b: 0111 0100 0001 1011 xxxx xxxx + {ORI, "D,%b" }, // 1c: 0111 0100 0001 1100 xxxx xxxx + {ORI, "E,%b" }, // 1d: 0111 0100 0001 1101 xxxx xxxx + {ORI, "H,%b" }, // 1e: 0111 0100 0001 1110 xxxx xxxx + {ORI, "L,%b" }, // 1f: 0111 0100 0001 1111 xxxx xxxx + + {ADINC, "V,%b" }, // 20: 0111 0100 0010 0000 xxxx xxxx + {ADINC, "A,%b" }, // 21: 0111 0100 0010 0001 xxxx xxxx + {ADINC, "B,%b" }, // 22: 0111 0100 0010 0010 xxxx xxxx + {ADINC, "C,%b" }, // 23: 0111 0100 0010 0011 xxxx xxxx + {ADINC, "D,%b" }, // 24: 0111 0100 0010 0100 xxxx xxxx + {ADINC, "E,%b" }, // 25: 0111 0100 0010 0101 xxxx xxxx + {ADINC, "H,%b" }, // 26: 0111 0100 0010 0110 xxxx xxxx + {ADINC, "L,%b" }, // 27: 0111 0100 0010 0111 xxxx xxxx + {GTI, "V,%b" }, // 28: 0111 0100 0010 1000 xxxx xxxx + {GTI, "A,%b" }, // 29: 0111 0100 0010 1001 xxxx xxxx + {GTI, "B,%b" }, // 2a: 0111 0100 0010 1010 xxxx xxxx + {GTI, "C,%b" }, // 2b: 0111 0100 0010 1011 xxxx xxxx + {GTI, "D,%b" }, // 2c: 0111 0100 0010 1100 xxxx xxxx + {GTI, "E,%b" }, // 2d: 0111 0100 0010 1101 xxxx xxxx + {GTI, "H,%b" }, // 2e: 0111 0100 0010 1110 xxxx xxxx + {GTI, "L,%b" }, // 2f: 0111 0100 0010 1111 xxxx xxxx + + {SUINB, "V,%b" }, // 30: 0111 0100 0011 0000 xxxx xxxx + {SUINB, "A,%b" }, // 31: 0111 0100 0011 0001 xxxx xxxx + {SUINB, "B,%b" }, // 32: 0111 0100 0011 0010 xxxx xxxx + {SUINB, "C,%b" }, // 33: 0111 0100 0011 0011 xxxx xxxx + {SUINB, "D,%b" }, // 34: 0111 0100 0011 0100 xxxx xxxx + {SUINB, "E,%b" }, // 35: 0111 0100 0011 0101 xxxx xxxx + {SUINB, "H,%b" }, // 36: 0111 0100 0011 0110 xxxx xxxx + {SUINB, "L,%b" }, // 37: 0111 0100 0011 0111 xxxx xxxx + {LTI, "V,%b" }, // 37: 0111 0100 0011 1000 xxxx xxxx + {LTI, "A,%b" }, // 39: 0111 0100 0011 1001 xxxx xxxx + {LTI, "B,%b" }, // 3a: 0111 0100 0011 1010 xxxx xxxx + {LTI, "C,%b" }, // 3b: 0111 0100 0011 1011 xxxx xxxx + {LTI, "D,%b" }, // 3c: 0111 0100 0011 1100 xxxx xxxx + {LTI, "E,%b" }, // 3d: 0111 0100 0011 1101 xxxx xxxx + {LTI, "H,%b" }, // 3e: 0111 0100 0011 1110 xxxx xxxx + {LTI, "L,%b" }, // 3f: 0111 0100 0011 1111 xxxx xxxx + + {ADI, "V,%b" }, // 40: 0111 0100 0100 0000 xxxx xxxx + {ADI, "A,%b" }, // 41: 0111 0100 0100 0001 xxxx xxxx + {ADI, "B,%b" }, // 42: 0111 0100 0100 0010 xxxx xxxx + {ADI, "C,%b" }, // 43: 0111 0100 0100 0011 xxxx xxxx + {ADI, "D,%b" }, // 44: 0111 0100 0100 0100 xxxx xxxx + {ADI, "E,%b" }, // 45: 0111 0100 0100 0101 xxxx xxxx + {ADI, "H,%b" }, // 46: 0111 0100 0100 0110 xxxx xxxx + {ADI, "L,%b" }, // 47: 0111 0100 0100 0111 xxxx xxxx + {ONI, "V,%b" }, // 48: 0111 0100 0100 1000 xxxx xxxx + {ONI, "A,%b" }, // 49: 0111 0100 0100 1001 xxxx xxxx + {ONI, "B,%b" }, // 4a: 0111 0100 0100 1010 xxxx xxxx + {ONI, "C,%b" }, // 4b: 0111 0100 0100 1011 xxxx xxxx + {ONI, "D,%b" }, // 4c: 0111 0100 0100 1100 xxxx xxxx + {ONI, "E,%b" }, // 4d: 0111 0100 0100 1101 xxxx xxxx + {ONI, "H,%b" }, // 4e: 0111 0100 0100 1110 xxxx xxxx + {ONI, "L,%b" }, // 4f: 0111 0100 0100 1111 xxxx xxxx + + {ACI, "V,%b" }, // 50: 0111 0100 0101 0000 xxxx xxxx + {ACI, "A,%b" }, // 51: 0111 0100 0101 0001 xxxx xxxx + {ACI, "B,%b" }, // 52: 0111 0100 0101 0010 xxxx xxxx + {ACI, "C,%b" }, // 53: 0111 0100 0101 0011 xxxx xxxx + {ACI, "D,%b" }, // 54: 0111 0100 0101 0100 xxxx xxxx + {ACI, "E,%b" }, // 55: 0111 0100 0101 0101 xxxx xxxx + {ACI, "H,%b" }, // 56: 0111 0100 0101 0110 xxxx xxxx + {ACI, "L,%b" }, // 57: 0111 0100 0101 0111 xxxx xxxx + {OFFI, "V,%b" }, // 58: 0111 0100 0101 1000 xxxx xxxx + {OFFI, "A,%b" }, // 59: 0111 0100 0101 1001 xxxx xxxx + {OFFI, "B,%b" }, // 5a: 0111 0100 0101 1010 xxxx xxxx + {OFFI, "C,%b" }, // 5b: 0111 0100 0101 1011 xxxx xxxx + {OFFI, "D,%b" }, // 5c: 0111 0100 0101 1100 xxxx xxxx + {OFFI, "E,%b" }, // 5d: 0111 0100 0101 1101 xxxx xxxx + {OFFI, "H,%b" }, // 5e: 0111 0100 0101 1110 xxxx xxxx + {OFFI, "L,%b" }, // 5f: 0111 0100 0101 1111 xxxx xxxx + + {SUI, "V,%b" }, // 60: 0111 0100 0110 0000 xxxx xxxx + {SUI, "A,%b" }, // 61: 0111 0100 0110 0001 xxxx xxxx + {SUI, "B,%b" }, // 62: 0111 0100 0110 0010 xxxx xxxx + {SUI, "C,%b" }, // 63: 0111 0100 0110 0011 xxxx xxxx + {SUI, "D,%b" }, // 64: 0111 0100 0110 0100 xxxx xxxx + {SUI, "E,%b" }, // 65: 0111 0100 0110 0101 xxxx xxxx + {SUI, "H,%b" }, // 66: 0111 0100 0110 0110 xxxx xxxx + {SUI, "L,%b" }, // 67: 0111 0100 0110 0111 xxxx xxxx + {NEI, "V,%b" }, // 68: 0111 0100 0110 1000 xxxx xxxx + {NEI, "A,%b" }, // 69: 0111 0100 0110 1001 xxxx xxxx + {NEI, "B,%b" }, // 6a: 0111 0100 0110 1010 xxxx xxxx + {NEI, "C,%b" }, // 6b: 0111 0100 0110 1011 xxxx xxxx + {NEI, "D,%b" }, // 6c: 0111 0100 0110 1100 xxxx xxxx + {NEI, "E,%b" }, // 6d: 0111 0100 0110 1101 xxxx xxxx + {NEI, "H,%b" }, // 6e: 0111 0100 0110 1110 xxxx xxxx + {NEI, "L,%b" }, // 6f: 0111 0100 0110 1111 xxxx xxxx + + {SBI, "V,%b" }, // 70: 0111 0100 0111 0000 xxxx xxxx + {SBI, "A,%b" }, // 71: 0111 0100 0111 0001 xxxx xxxx + {SBI, "B,%b" }, // 72: 0111 0100 0111 0010 xxxx xxxx + {SBI, "C,%b" }, // 73: 0111 0100 0111 0011 xxxx xxxx + {SBI, "D,%b" }, // 74: 0111 0100 0111 0100 xxxx xxxx + {SBI, "E,%b" }, // 75: 0111 0100 0111 0101 xxxx xxxx + {SBI, "H,%b" }, // 76: 0111 0100 0111 0110 xxxx xxxx + {SBI, "L,%b" }, // 77: 0111 0100 0111 0111 xxxx xxxx + {EQI, "V,%b" }, // 78: 0111 0100 0111 1000 xxxx xxxx + {EQI, "A,%b" }, // 79: 0111 0100 0111 1001 xxxx xxxx + {EQI, "B,%b" }, // 7a: 0111 0100 0111 1010 xxxx xxxx + {EQI, "C,%b" }, // 7b: 0111 0100 0111 1011 xxxx xxxx + {EQI, "D,%b" }, // 7c: 0111 0100 0111 1100 xxxx xxxx + {EQI, "E,%b" }, // 7d: 0111 0100 0111 1101 xxxx xxxx + {EQI, "H,%b" }, // 7e: 0111 0100 0111 1110 xxxx xxxx + {EQI, "L,%b" }, // 7f: 0111 0100 0111 1111 xxxx xxxx + + { }, // 80: 0111 0100 1000 0000 + { }, // 81: 0111 0100 1000 0001 + { }, // 82: 0111 0100 1000 0010 + { }, // 83: 0111 0100 1000 0011 + { }, // 84: 0111 0100 1000 0100 + { }, // 85: 0111 0100 1000 0101 + { }, // 86: 0111 0100 1000 0110 + { }, // 87: 0111 0100 1000 0111 + {ANAW, "%a" }, // 88: 0111 0100 1000 1000 oooo oooo + { }, // 89: 0111 0100 1000 1001 + { }, // 8a: 0111 0100 1000 1010 + { }, // 8b: 0111 0100 1000 1011 + { }, // 8c: 0111 0100 1000 1100 + {DAN, "EA,BC" }, // 8d: 0111 0100 1000 1101 + {DAN, "EA,DE" }, // 8e: 0111 0100 1000 1110 + {DAN, "EA,HL" }, // 8f: 0111 0100 1000 1111 + + {XRAW, "%a" }, // 90: 0111 0100 1001 0000 oooo oooo + { }, // 91: 0111 0100 1001 0001 + { }, // 92: 0111 0100 1001 0010 + { }, // 93: 0111 0100 1001 0011 + { }, // 94: 0111 0100 1001 0100 + {DXR, "EA,BC" }, // 95: 0111 0100 1001 0101 + {DXR, "EA,DE" }, // 96: 0111 0100 1001 0110 + {DXR, "EA,HL" }, // 97: 0111 0100 1001 0111 + {ORAW, "%a" }, // 98: 0111 0100 1001 1000 oooo oooo + { }, // 99: 0111 0100 1001 1001 + { }, // 9a: 0111 0100 1001 1010 + { }, // 9b: 0111 0100 1001 1011 + { }, // 9c: 0111 0100 1001 1100 + {DOR, "EA,BC" }, // 9d: 0111 0100 1001 1101 + {DOR, "EA,DE" }, // 9e: 0111 0100 1001 1110 + {DOR, "EA,HL" }, // 9f: 0111 0100 1001 1111 + + {ADDNCW, "%a" }, // a0: 0111 0100 1010 0000 oooo oooo + { }, // a1: 0111 0100 1010 0001 + { }, // a2: 0111 0100 1010 0010 + { }, // a3: 0111 0100 1010 0011 + { }, // a4: 0111 0100 1010 0100 + {DADDNC, "EA,BC" }, // a5: 0111 0100 1010 0101 + {DADDNC, "EA,DE" }, // a6: 0111 0100 1010 0110 + {DADDNC, "EA,HL" }, // a7: 0111 0100 1010 0111 + {GTAW, "%a" }, // a8: 0111 0100 1010 1000 oooo oooo + { }, // a9: 0111 0100 1010 1001 + { }, // aa: 0111 0100 1010 1010 + { }, // ab: 0111 0100 1010 1011 + { }, // ac: 0111 0100 1010 1100 + {DGT, "EA,BC" }, // ad: 0111 0100 1010 1101 + {DGT, "EA,DE" }, // ae: 0111 0100 1010 1110 + {DGT, "EA,HL" }, // af: 0111 0100 1010 1111 + + {SUBNBW, "%a" }, // b0: 0111 0100 1011 0000 oooo oooo + { }, // b1: 0111 0100 1011 0001 + { }, // b2: 0111 0100 1011 0010 + { }, // b3: 0111 0100 1011 0011 + { }, // b4: 0111 0100 1011 0100 + {DSUBNB, "EA,BC" }, // b5: 0111 0100 1011 0101 + {DSUBNB, "EA,DE" }, // b6: 0111 0100 1011 0110 + {DSUBNB, "EA,HL" }, // b7: 0111 0100 1011 0111 + {LTAW, "%a" }, // b8: 0111 0100 1011 1000 oooo oooo + { }, // b9: 0111 0100 1011 1001 + { }, // ba: 0111 0100 1011 1010 + { }, // bb: 0111 0100 1011 1011 + { }, // bc: 0111 0100 1011 1100 + {DLT, "EA,BC" }, // bd: 0111 0100 1011 1101 + {DLT, "EA,DE" }, // be: 0111 0100 1011 1110 + {DLT, "EA,HL" }, // bf: 0111 0100 1011 1111 + + {ADDW, "%a" }, // c0: 0111 0100 1100 0000 oooo oooo + { }, // c1: 0111 0100 1100 0001 + { }, // c2: 0111 0100 1100 0010 + { }, // c3: 0111 0100 1100 0011 + { }, // c4: 0111 0100 1100 0100 + {DADD, "EA,BC" }, // c5: 0111 0100 1100 0101 + {DADD, "EA,DE" }, // c6: 0111 0100 1100 0110 + {DADD, "EA,HL" }, // c7: 0111 0100 1100 0111 + {ONAW, "%a" }, // c8: 0111 0100 1100 1000 oooo oooo + { }, // c9: 0111 0100 1100 1001 + { }, // ca: 0111 0100 1100 1010 + { }, // cb: 0111 0100 1100 1011 + { }, // cc: 0111 0100 1100 1100 + {DON, "EA,BC" }, // cd: 0111 0100 1100 1101 + {DON, "EA,DE" }, // ce: 0111 0100 1100 1110 + {DON, "EA,HL" }, // cf: 0111 0100 1100 1111 + + {ADCW, "%a" }, // d0: 0111 0100 1101 0000 oooo oooo + { }, // d1: 0111 0100 1101 0001 + { }, // d2: 0111 0100 1101 0010 + { }, // d3: 0111 0100 1101 0011 + { }, // d4: 0111 0100 1101 0100 + {DADC, "EA,BC" }, // d5: 0111 0100 1101 0101 + {DADC, "EA,DE" }, // d6: 0111 0100 1101 0110 + {DADC, "EA,HL" }, // d7: 0111 0100 1101 0111 + {OFFAW, "%a" }, // d8: 0111 0100 1101 1000 oooo oooo + { }, // d9: 0111 0100 1101 1001 + { }, // da: 0111 0100 1101 1010 + { }, // db: 0111 0100 1101 1011 + { }, // dc: 0111 0100 1101 1100 + {DOFF, "EA,BC" }, // dd: 0111 0100 1101 1101 + {DOFF, "EA,DE" }, // de: 0111 0100 1101 1110 + {DOFF, "EA,HL" }, // df: 0111 0100 1101 1111 + + {SUBW, "%a" }, // e0: 0111 0100 1110 0000 oooo oooo + { }, // e1: 0111 0100 1110 0001 + { }, // e2: 0111 0100 1110 0010 + { }, // e3: 0111 0100 1110 0011 + { }, // e4: 0111 0100 1110 0100 + {DSUB, "EA,BC" }, // e5: 0111 0100 1110 0101 + {DSUB, "EA,DE" }, // e6: 0111 0100 1110 0110 + {DSUB, "EA,HL" }, // e7: 0111 0100 1110 0111 + {NEAW, "%a" }, // e8: 0111 0100 1110 1000 oooo oooo + { }, // e9: 0111 0100 1110 1001 + { }, // ea: 0111 0100 1110 1010 + { }, // eb: 0111 0100 1110 1011 + { }, // ec: 0111 0100 1110 1100 + {DNE, "EA,BC" }, // ed: 0111 0100 1110 1101 + {DNE, "EA,DE" }, // ee: 0111 0100 1110 1110 + {DNE, "EA,HL" }, // ef: 0111 0100 1110 1111 + + {SBBW, "%a" }, // f0: 0111 0100 1111 0000 oooo oooo + { }, // f1: 0111 0100 1111 0001 + { }, // f2: 0111 0100 1111 0010 + { }, // f3: 0111 0100 1111 0011 + { }, // f4: 0111 0100 1111 0100 + {DSBB, "EA,BC" }, // f5: 0111 0100 1111 0101 + {DSBB, "EA,DE" }, // f6: 0111 0100 1111 0110 + {DSBB, "EA,HL" }, // f7: 0111 0100 1111 0111 + {EQAW, "%a" }, // f8: 0111 0100 1111 1000 oooo oooo + { }, // f9: 0111 0100 1111 1001 + { }, // fa: 0111 0100 1111 1010 + { }, // fb: 0111 0100 1111 1011 + { }, // fc: 0111 0100 1111 1100 + {DEQ, "EA,BC" }, // fd: 0111 0100 1111 1101 + {DEQ, "EA,DE" }, // fe: 0111 0100 1111 1110 + {DEQ, "EA,HL" } // ff: 0111 0100 1111 1111 }; -const dasm_s dasm_s::d48_7807[256] = +// prefix 48 +const upd7810_base_disassembler::dasm_s upd7810_disassembler::d48_7810[256] = { { }, // 00: 0100 1000 0000 0000 {SLRC, "A" }, // 01: 0100 1000 0000 0001 @@ -753,7 +1108,7 @@ const dasm_s dasm_s::d48_7807[256] = {SLL, "B" }, // 26: 0100 1000 0010 0110 {SLL, "C" }, // 27: 0100 1000 0010 0111 {JEA, nullptr }, // 28: 0100 1000 0010 1000 - {CALB, nullptr }, // 29: 0100 1000 0010 1001 + {CALB,nullptr }, // 29: 0100 1000 0010 1001 {CLC, nullptr }, // 2a: 0100 1000 0010 1010 {STC, nullptr }, // 2b: 0100 1000 0010 1011 { }, // 2c: 0100 1000 0010 1100 @@ -874,11 +1229,11 @@ const dasm_s dasm_s::d48_7807[256] = { }, // 98: 0100 1000 1000 1000 { }, // 99: 0100 1000 1000 1001 { }, // 9a: 0100 1000 1000 1010 - {STEAX, "(DE+%b)" }, // 9b: 0100 1000 1000 1011 xxxx xxxx - {STEAX, "(HL+A)" }, // 9c: 0100 1000 1000 1100 - {STEAX, "(HL+B)" }, // 9d: 0100 1000 1000 1101 - {STEAX, "(HL+EA)" }, // 9e: 0100 1000 1000 1110 - {STEAX, "(HL+%b)" }, // 9f: 0100 1000 1000 1111 xxxx xxxx + {STEAX, "(DE+%b)" }, // 9b: 0100 1000 1000 1011 xxxx xxxx + {STEAX, "(HL+A)" }, // 9c: 0100 1000 1000 1100 + {STEAX, "(HL+B)" }, // 9d: 0100 1000 1000 1101 + {STEAX, "(HL+EA)" }, // 9e: 0100 1000 1000 1110 + {STEAX, "(HL+%b)" }, // 9f: 0100 1000 1000 1111 xxxx xxxx {DSLR, "EA" }, // a0: 0100 1000 1010 0000 { }, // a1: 0100 1000 1010 0001 @@ -890,12 +1245,12 @@ const dasm_s dasm_s::d48_7807[256] = { }, // a7: 0100 1000 1010 0111 {TABLE, nullptr }, // a8: 0100 1000 1010 1000 { }, // a9: 0100 1000 1010 1001 - {CMC, nullptr }, // aa: 0100 1000 1010 1010 7807 + { }, // aa: 0100 1000 1010 1010 { }, // ab: 0100 1000 1010 1011 - {EXA, nullptr }, // ac: 0100 1000 1010 1100 7807 - {EXR, nullptr }, // ad: 0100 1000 1010 1101 7807 - {EXH, nullptr }, // ae: 0100 1000 1010 1110 7807 - {EXX, nullptr }, // af: 0100 1000 1010 1111 7807 + { }, // ac: 0100 1000 1010 1100 + { }, // ad: 0100 1000 1010 1101 + { }, // ae: 0100 1000 1010 1110 + { }, // af: 0100 1000 1010 1111 {DRLR, "EA" }, // b0: 0100 1000 1011 0000 { }, // b1: 0100 1000 1011 0001 @@ -908,15 +1263,15 @@ const dasm_s dasm_s::d48_7807[256] = { }, // b8: 0100 1000 1011 1000 { }, // b9: 0100 1000 1011 1001 { }, // ba: 0100 1000 1011 1010 - { }, // bb: 0100 1000 1011 1011 + {STOP, nullptr }, // bb: 0100 1000 1011 1011 7810 { }, // bc: 0100 1000 1011 1100 { }, // bd: 0100 1000 1011 1101 { }, // be: 0100 1000 1011 1110 { }, // bf: 0100 1000 1011 1111 {DMOV, "EA,ECNT" }, // c0: 0100 1000 1100 0000 - {DMOV, "EA,ECPT0"}, // c1: 0100 1000 1100 0001 7807 - {DMOV, "EA,ECPT1"}, // c2: 0100 1000 1100 0010 7807 + {DMOV, "EA,ECPT" }, // c1: 0100 1000 1100 0001 7810 + { }, // c2: 0100 1000 1100 0010 { }, // c3: 0100 1000 1100 0011 { }, // c4: 0100 1000 1100 0100 { }, // c5: 0100 1000 1100 0101 @@ -984,7 +1339,7 @@ const dasm_s dasm_s::d48_7807[256] = }; // prefix 4C -const dasm_s dasm_s::d4C_7810[256] = +const upd7810_base_disassembler::dasm_s upd7810_disassembler::d4C_7810[256] = { { }, // 00: 0100 1100 0000 0000 { }, // 01: 0100 1100 0000 0001 @@ -1259,283 +1614,9 @@ const dasm_s dasm_s::d4C_7810[256] = { } // ff: 0100 1100 1111 1111 }; -const dasm_s dasm_s::d4C_7807[256] = -{ - { }, // 00: 0100 1100 0000 0000 - { }, // 01: 0100 1100 0000 0001 - { }, // 02: 0100 1100 0000 0010 - { }, // 03: 0100 1100 0000 0011 - { }, // 04: 0100 1100 0000 0100 - { }, // 05: 0100 1100 0000 0101 - { }, // 06: 0100 1100 0000 0110 - { }, // 07: 0100 1100 0000 0111 - { }, // 08: 0100 1100 0000 1000 - { }, // 09: 0100 1100 0000 1001 - { }, // 0a: 0100 1100 0000 1010 - { }, // 0b: 0100 1100 0000 1011 - { }, // 0c: 0100 1100 0000 1100 - { }, // 0d: 0100 1100 0000 1101 - { }, // 0e: 0100 1100 0000 1110 - { }, // 0f: 0100 1100 0000 1111 - - { }, // 10: 0100 1100 0001 0000 - { }, // 11: 0100 1100 0001 0001 - { }, // 12: 0100 1100 0001 0010 - { }, // 13: 0100 1100 0001 0011 - { }, // 14: 0100 1100 0001 0100 - { }, // 15: 0100 1100 0001 0101 - { }, // 16: 0100 1100 0001 0110 - { }, // 17: 0100 1100 0001 0111 - { }, // 18: 0100 1100 0001 1000 - { }, // 19: 0100 1100 0001 1001 - { }, // 1a: 0100 1100 0001 1010 - { }, // 1b: 0100 1100 0001 1011 - { }, // 1c: 0100 1100 0001 1100 - { }, // 1d: 0100 1100 0001 1101 - { }, // 1e: 0100 1100 0001 1110 - { }, // 1f: 0100 1100 0001 1111 - - { }, // 20: 0100 1100 0010 0000 - { }, // 21: 0100 1100 0010 0001 - { }, // 22: 0100 1100 0010 0010 - { }, // 23: 0100 1100 0010 0011 - { }, // 24: 0100 1100 0010 0100 - { }, // 25: 0100 1100 0010 0101 - { }, // 26: 0100 1100 0010 0110 - { }, // 27: 0100 1100 0010 0111 - { }, // 28: 0100 1100 0010 1000 - { }, // 29: 0100 1100 0010 1001 - { }, // 2a: 0100 1100 0010 1010 - { }, // 2b: 0100 1100 0010 1011 - { }, // 2c: 0100 1100 0010 1100 - { }, // 2d: 0100 1100 0010 1101 - { }, // 2e: 0100 1100 0010 1110 - { }, // 2f: 0100 1100 0010 1111 - - { }, // 30: 0100 1100 0011 0000 - { }, // 31: 0100 1100 0011 0001 - { }, // 32: 0100 1100 0011 0010 - { }, // 33: 0100 1100 0011 0011 - { }, // 34: 0100 1100 0011 0100 - { }, // 35: 0100 1100 0011 0101 - { }, // 36: 0100 1100 0011 0110 - { }, // 37: 0100 1100 0011 0111 - { }, // 38: 0100 1100 0011 1000 - { }, // 39: 0100 1100 0011 1001 - { }, // 3a: 0100 1100 0011 1010 - { }, // 3b: 0100 1100 0011 1011 - { }, // 3c: 0100 1100 0011 1100 - { }, // 3d: 0100 1100 0011 1101 - { }, // 3e: 0100 1100 0011 1110 - { }, // 3f: 0100 1100 0011 1111 - - { }, // 40: 0100 1100 0100 0000 - { }, // 41: 0100 1100 0100 0001 - { }, // 42: 0100 1100 0100 0010 - { }, // 43: 0100 1100 0100 0011 - { }, // 44: 0100 1100 0100 0100 - { }, // 45: 0100 1100 0100 0101 - { }, // 46: 0100 1100 0100 0110 - { }, // 47: 0100 1100 0100 0111 - { }, // 48: 0100 1100 0100 1000 - { }, // 49: 0100 1100 0100 1001 - { }, // 4a: 0100 1100 0100 1010 - { }, // 4b: 0100 1100 0100 1011 - { }, // 4c: 0100 1100 0100 1100 - { }, // 4d: 0100 1100 0100 1101 - { }, // 4e: 0100 1100 0100 1110 - { }, // 4f: 0100 1100 0100 1111 - - { }, // 50: 0100 1100 0101 0000 - { }, // 51: 0100 1100 0101 0001 - { }, // 52: 0100 1100 0101 0010 - { }, // 53: 0100 1100 0101 0011 - { }, // 54: 0100 1100 0101 0100 - { }, // 55: 0100 1100 0101 0101 - { }, // 56: 0100 1100 0101 0110 - { }, // 57: 0100 1100 0101 0111 - { }, // 58: 0100 1100 0101 1000 - { }, // 59: 0100 1100 0101 1001 - { }, // 5a: 0100 1100 0101 1010 - { }, // 5b: 0100 1100 0101 1011 - { }, // 5c: 0100 1100 0101 1100 - { }, // 5d: 0100 1100 0101 1101 - { }, // 5e: 0100 1100 0101 1110 - { }, // 5f: 0100 1100 0101 1111 - - { }, // 60: 0100 1100 0110 0000 - { }, // 61: 0100 1100 0110 0001 - { }, // 62: 0100 1100 0110 0010 - { }, // 63: 0100 1100 0110 0011 - { }, // 64: 0100 1100 0110 0100 - { }, // 65: 0100 1100 0110 0101 - { }, // 66: 0100 1100 0110 0110 - { }, // 67: 0100 1100 0110 0111 - { }, // 68: 0100 1100 0110 1000 - { }, // 69: 0100 1100 0110 1001 - { }, // 6a: 0100 1100 0110 1010 - { }, // 6b: 0100 1100 0110 1011 - { }, // 6c: 0100 1100 0110 1100 - { }, // 6d: 0100 1100 0110 1101 - { }, // 6e: 0100 1100 0110 1110 - { }, // 6f: 0100 1100 0110 1111 - - { }, // 70: 0100 1100 0111 0000 - { }, // 71: 0100 1100 0111 0001 - { }, // 72: 0100 1100 0111 0010 - { }, // 73: 0100 1100 0111 0011 - { }, // 74: 0100 1100 0111 0100 - { }, // 75: 0100 1100 0111 0101 - { }, // 76: 0100 1100 0111 0110 - { }, // 77: 0100 1100 0111 0111 - { }, // 78: 0100 1100 0111 1000 - { }, // 79: 0100 1100 0111 1001 - { }, // 7a: 0100 1100 0111 1010 - { }, // 7b: 0100 1100 0111 1011 - { }, // 7c: 0100 1100 0111 1100 - { }, // 7d: 0100 1100 0111 1101 - { }, // 7e: 0100 1100 0111 1110 - { }, // 7f: 0100 1100 0111 1111 - - { }, // 80: 0100 1100 1000 0000 - { }, // 81: 0100 1100 1000 0001 - { }, // 82: 0100 1100 1000 0010 - { }, // 83: 0100 1100 1000 0011 - { }, // 84: 0100 1100 1000 0100 - { }, // 85: 0100 1100 1000 0101 - { }, // 86: 0100 1100 1000 0110 - { }, // 87: 0100 1100 1000 0111 - { }, // 88: 0100 1100 1000 1000 - { }, // 89: 0100 1100 1000 1001 - { }, // 8a: 0100 1100 1000 1010 - { }, // 8b: 0100 1100 1000 1011 - { }, // 8c: 0100 1100 1000 1100 - { }, // 8d: 0100 1100 1000 1101 - { }, // 8e: 0100 1100 1000 1110 - { }, // 8f: 0100 1100 1000 1111 - - { }, // 90: 0100 1100 1001 0000 - { }, // 91: 0100 1100 1001 0001 - { }, // 92: 0100 1100 1001 0010 - { }, // 93: 0100 1100 1001 0011 - { }, // 94: 0100 1100 1001 0100 - { }, // 95: 0100 1100 1001 0101 - { }, // 96: 0100 1100 1001 0110 - { }, // 97: 0100 1100 1001 0111 - { }, // 98: 0100 1100 1001 1000 - { }, // 99: 0100 1100 1001 1001 - { }, // 9a: 0100 1100 1001 1010 - { }, // 9b: 0100 1100 1001 1011 - { }, // 9c: 0100 1100 1001 1100 - { }, // 9d: 0100 1100 1001 1101 - { }, // 9e: 0100 1100 1001 1110 - { }, // 9f: 0100 1100 1001 1111 - - { }, // a0: 0100 1100 1010 0000 - { }, // a1: 0100 1100 1010 0001 - { }, // a2: 0100 1100 1010 0010 - { }, // a3: 0100 1100 1010 0011 - { }, // a4: 0100 1100 1010 0100 - { }, // a5: 0100 1100 1010 0101 - { }, // a6: 0100 1100 1010 0110 - { }, // a7: 0100 1100 1010 0111 - { }, // a8: 0100 1100 1010 1000 - { }, // a9: 0100 1100 1010 1001 - { }, // aa: 0100 1100 1010 1010 - { }, // ab: 0100 1100 1010 1011 - { }, // ac: 0100 1100 1010 1100 - { }, // ad: 0100 1100 1010 1101 - { }, // ae: 0100 1100 1010 1110 - { }, // af: 0100 1100 1010 1111 - - { }, // b0: 0100 1100 1011 0000 - { }, // b1: 0100 1100 1011 0001 - { }, // b2: 0100 1100 1011 0010 - { }, // b3: 0100 1100 1011 0011 - { }, // b4: 0100 1100 1011 0100 - { }, // b5: 0100 1100 1011 0101 - { }, // b6: 0100 1100 1011 0110 - { }, // b7: 0100 1100 1011 0111 - { }, // b8: 0100 1100 1011 1000 - { }, // b9: 0100 1100 1011 1001 - { }, // ba: 0100 1100 1011 1010 - { }, // bb: 0100 1100 1011 1011 - { }, // bc: 0100 1100 1011 1100 - { }, // bd: 0100 1100 1011 1101 - { }, // be: 0100 1100 1011 1110 - { }, // bf: 0100 1100 1011 1111 - - {MOV, "A,PA" }, // c0: 0100 1100 1100 0000 - {MOV, "A,PB" }, // c1: 0100 1100 1100 0001 - {MOV, "A,PC" }, // c2: 0100 1100 1100 0010 - {MOV, "A,PD" }, // c3: 0100 1100 1100 0011 - { }, // c4: 0100 1100 1100 0100 - {MOV, "A,PF" }, // c5: 0100 1100 1100 0101 - {MOV, "A,MKH" }, // c6: 0100 1100 1100 0110 - {MOV, "A,MKL" }, // c7: 0100 1100 1100 0111 - { }, // c8: 0100 1100 1100 1000 - {MOV, "A,SMH" }, // c9: 0100 1100 1100 1001 - { }, // ca: 0100 1100 1100 1010 - {MOV, "A,EOM" }, // cb: 0100 1100 1100 1011 - { }, // cc: 0100 1100 1100 1100 - {MOV, "A,TMM" }, // cd: 0100 1100 1100 1101 - {MOV, "A,PT" }, // ce: 0100 1100 1100 1110 7807 - { }, // cf: 0100 1100 1100 1111 - - { }, // d0: 0100 1100 1101 0000 - { }, // d1: 0100 1100 1101 0001 - { }, // d2: 0100 1100 1101 0010 - { }, // d3: 0100 1100 1101 0011 - { }, // d4: 0100 1100 1101 0100 - { }, // d5: 0100 1100 1101 0101 - { }, // d6: 0100 1100 1101 0110 - { }, // d7: 0100 1100 1101 0111 - { }, // d8: 0100 1100 1101 1000 - {MOV, "A,RXB" }, // d9: 0100 1100 1101 1001 - { }, // da: 0100 1100 1101 1010 - { }, // db: 0100 1100 1101 1011 - { }, // dc: 0100 1100 1101 1100 - { }, // dd: 0100 1100 1101 1101 - { }, // de: 0100 1100 1101 1110 - { }, // df: 0100 1100 1101 1111 - - { }, // e0: 0100 1100 1110 0000 - { }, // e1: 0100 1100 1110 0001 - { }, // e2: 0100 1100 1110 0010 - { }, // e3: 0100 1100 1110 0011 - { }, // e4: 0100 1100 1110 0100 - { }, // e5: 0100 1100 1110 0101 - { }, // e6: 0100 1100 1110 0110 - { }, // e7: 0100 1100 1110 0111 - { }, // e8: 0100 1100 1110 1000 - { }, // e9: 0100 1100 1110 1001 - { }, // ea: 0100 1100 1110 1010 - { }, // eb: 0100 1100 1110 1011 - { }, // ec: 0100 1100 1110 1100 - { }, // ed: 0100 1100 1110 1101 - { }, // ee: 0100 1100 1110 1110 - { }, // ef: 0100 1100 1110 1111 - - { }, // f0: 0100 1100 1111 0000 - { }, // f1: 0100 1100 1111 0001 - { }, // f2: 0100 1100 1111 0010 - { }, // f3: 0100 1100 1111 0011 - { }, // f4: 0100 1100 1111 0100 - { }, // f5: 0100 1100 1111 0101 - { }, // f6: 0100 1100 1111 0110 - { }, // f7: 0100 1100 1111 0111 - { }, // f8: 0100 1100 1111 1000 - { }, // f9: 0100 1100 1111 1001 - { }, // fa: 0100 1100 1111 1010 - { }, // fb: 0100 1100 1111 1011 - { }, // fc: 0100 1100 1111 1100 - { }, // fd: 0100 1100 1111 1101 - { }, // fe: 0100 1100 1111 1110 - { } // ff: 0100 1100 1111 1111 -}; // prefix 4D -const dasm_s dasm_s::d4D_7810[256] = +const upd7810_base_disassembler::dasm_s upd7810_disassembler::d4D_7810[256] = { { }, // 00: 0100 1101 0000 0000 { }, // 01: 0100 1101 0000 0001 @@ -1810,559 +1891,10 @@ const dasm_s dasm_s::d4D_7810[256] = { } // ff: 0100 1101 1111 1111 }; -const dasm_s dasm_s::d4D_7807[256] = -{ - { }, // 00: 0100 1101 0000 0000 - { }, // 01: 0100 1101 0000 0001 - { }, // 02: 0100 1101 0000 0010 - { }, // 03: 0100 1101 0000 0011 - { }, // 04: 0100 1101 0000 0100 - { }, // 05: 0100 1101 0000 0101 - { }, // 06: 0100 1101 0000 0110 - { }, // 07: 0100 1101 0000 0111 - { }, // 08: 0100 1101 0000 1000 - { }, // 09: 0100 1101 0000 1001 - { }, // 0a: 0100 1101 0000 1010 - { }, // 0b: 0100 1101 0000 1011 - { }, // 0c: 0100 1101 0000 1100 - { }, // 0d: 0100 1101 0000 1101 - { }, // 0e: 0100 1101 0000 1110 - { }, // 0f: 0100 1101 0000 1111 - - { }, // 10: 0100 1101 0001 0000 - { }, // 11: 0100 1101 0001 0001 - { }, // 12: 0100 1101 0001 0010 - { }, // 13: 0100 1101 0001 0011 - { }, // 14: 0100 1101 0001 0100 - { }, // 15: 0100 1101 0001 0101 - { }, // 16: 0100 1101 0001 0110 - { }, // 17: 0100 1101 0001 0111 - { }, // 18: 0100 1101 0001 1000 - { }, // 19: 0100 1101 0001 1001 - { }, // 1a: 0100 1101 0001 1010 - { }, // 1b: 0100 1101 0001 1011 - { }, // 1c: 0100 1101 0001 1100 - { }, // 1d: 0100 1101 0001 1101 - { }, // 1e: 0100 1101 0001 1110 - { }, // 1f: 0100 1101 0001 1111 - - { }, // 20: 0100 1101 0010 0000 - { }, // 21: 0100 1101 0010 0001 - { }, // 22: 0100 1101 0010 0010 - { }, // 23: 0100 1101 0010 0011 - { }, // 24: 0100 1101 0010 0100 - { }, // 25: 0100 1101 0010 0101 - { }, // 26: 0100 1101 0010 0110 - { }, // 27: 0100 1101 0010 0111 - { }, // 28: 0100 1101 0010 1000 - { }, // 29: 0100 1101 0010 1001 - { }, // 2a: 0100 1101 0010 1010 - { }, // 2b: 0100 1101 0010 1011 - { }, // 2c: 0100 1101 0010 1100 - { }, // 2d: 0100 1101 0010 1101 - { }, // 2e: 0100 1101 0010 1110 - { }, // 2f: 0100 1101 0010 1111 - - { }, // 30: 0100 1101 0011 0000 - { }, // 31: 0100 1101 0011 0001 - { }, // 32: 0100 1101 0011 0010 - { }, // 33: 0100 1101 0011 0011 - { }, // 34: 0100 1101 0011 0100 - { }, // 35: 0100 1101 0011 0101 - { }, // 36: 0100 1101 0011 0110 - { }, // 37: 0100 1101 0011 0111 - { }, // 38: 0100 1101 0011 1000 - { }, // 39: 0100 1101 0011 1001 - { }, // 3a: 0100 1101 0011 1010 - { }, // 3b: 0100 1101 0011 1011 - { }, // 3c: 0100 1101 0011 1100 - { }, // 3d: 0100 1101 0011 1101 - { }, // 3e: 0100 1101 0011 1110 - { }, // 3f: 0100 1101 0011 1111 - - { }, // 40: 0100 1101 0100 0000 - { }, // 41: 0100 1101 0100 0001 - { }, // 42: 0100 1101 0100 0010 - { }, // 43: 0100 1101 0100 0011 - { }, // 44: 0100 1101 0100 0100 - { }, // 45: 0100 1101 0100 0101 - { }, // 46: 0100 1101 0100 0110 - { }, // 47: 0100 1101 0100 0111 - { }, // 48: 0100 1101 0100 1000 - { }, // 49: 0100 1101 0100 1001 - { }, // 4a: 0100 1101 0100 1010 - { }, // 4b: 0100 1101 0100 1011 - { }, // 4c: 0100 1101 0100 1100 - { }, // 4d: 0100 1101 0100 1101 - { }, // 4e: 0100 1101 0100 1110 - { }, // 4f: 0100 1101 0100 1111 - - { }, // 50: 0100 1101 0101 0000 - { }, // 51: 0100 1101 0101 0001 - { }, // 52: 0100 1101 0101 0010 - { }, // 53: 0100 1101 0101 0011 - { }, // 54: 0100 1101 0101 0100 - { }, // 55: 0100 1101 0101 0101 - { }, // 56: 0100 1101 0101 0110 - { }, // 57: 0100 1101 0101 0111 - { }, // 58: 0100 1101 0101 1000 - { }, // 59: 0100 1101 0101 1001 - { }, // 5a: 0100 1101 0101 1010 - { }, // 5b: 0100 1101 0101 1011 - { }, // 5c: 0100 1101 0101 1100 - { }, // 5d: 0100 1101 0101 1101 - { }, // 5e: 0100 1101 0101 1110 - { }, // 5f: 0100 1101 0101 1111 - - { }, // 60: 0100 1101 0110 0000 - { }, // 61: 0100 1101 0110 0001 - { }, // 62: 0100 1101 0110 0010 - { }, // 63: 0100 1101 0110 0011 - { }, // 64: 0100 1101 0110 0100 - { }, // 65: 0100 1101 0110 0101 - { }, // 66: 0100 1101 0110 0110 - { }, // 67: 0100 1101 0110 0111 - { }, // 68: 0100 1101 0110 1000 - { }, // 69: 0100 1101 0110 1001 - { }, // 6a: 0100 1101 0110 1010 - { }, // 6b: 0100 1101 0110 1011 - { }, // 6c: 0100 1101 0110 1100 - { }, // 6d: 0100 1101 0110 1101 - { }, // 6e: 0100 1101 0110 1110 - { }, // 6f: 0100 1101 0110 1111 - - { }, // 70: 0100 1101 0111 0000 - { }, // 71: 0100 1101 0111 0001 - { }, // 72: 0100 1101 0111 0010 - { }, // 73: 0100 1101 0111 0011 - { }, // 74: 0100 1101 0111 0100 - { }, // 75: 0100 1101 0111 0101 - { }, // 76: 0100 1101 0111 0110 - { }, // 77: 0100 1101 0111 0111 - { }, // 78: 0100 1101 0111 1000 - { }, // 79: 0100 1101 0111 1001 - { }, // 7a: 0100 1101 0111 1010 - { }, // 7b: 0100 1101 0111 1011 - { }, // 7c: 0100 1101 0111 1100 - { }, // 7d: 0100 1101 0111 1101 - { }, // 7e: 0100 1101 0111 1110 - { }, // 7f: 0100 1101 0111 1111 - - { }, // 80: 0100 1101 1000 0000 - { }, // 81: 0100 1101 1000 0001 - { }, // 82: 0100 1101 1000 0010 - { }, // 83: 0100 1101 1000 0011 - { }, // 84: 0100 1101 1000 0100 - { }, // 85: 0100 1101 1000 0101 - { }, // 86: 0100 1101 1000 0110 - { }, // 87: 0100 1101 1000 0111 - { }, // 88: 0100 1101 1000 1000 - { }, // 89: 0100 1101 1000 1001 - { }, // 8a: 0100 1101 1000 1010 - { }, // 8b: 0100 1101 1000 1011 - { }, // 8c: 0100 1101 1000 1100 - { }, // 8d: 0100 1101 1000 1101 - { }, // 8e: 0100 1101 1000 1110 - { }, // 8f: 0100 1101 1000 1111 - - { }, // 90: 0100 1101 1001 0000 - { }, // 91: 0100 1101 1001 0001 - { }, // 92: 0100 1101 1001 0010 - { }, // 93: 0100 1101 1001 0011 - { }, // 94: 0100 1101 1001 0100 - { }, // 95: 0100 1101 1001 0101 - { }, // 96: 0100 1101 1001 0110 - { }, // 97: 0100 1101 1001 0111 - { }, // 98: 0100 1101 1001 1000 - { }, // 99: 0100 1101 1001 1001 - { }, // 9a: 0100 1101 1001 1010 - { }, // 9b: 0100 1101 1001 1011 - { }, // 9c: 0100 1101 1001 1100 - { }, // 9d: 0100 1101 1001 1101 - { }, // 9e: 0100 1101 1001 1110 - { }, // 9f: 0100 1101 1001 1111 - - { }, // a0: 0100 1101 1010 0000 - { }, // a1: 0100 1101 1010 0001 - { }, // a2: 0100 1101 1010 0010 - { }, // a3: 0100 1101 1010 0011 - { }, // a4: 0100 1101 1010 0100 - { }, // a5: 0100 1101 1010 0101 - { }, // a6: 0100 1101 1010 0110 - { }, // a7: 0100 1101 1010 0111 - { }, // a8: 0100 1101 1010 1000 - { }, // a9: 0100 1101 1010 1001 - { }, // aa: 0100 1101 1010 1010 - { }, // ab: 0100 1101 1010 1011 - { }, // ac: 0100 1101 1010 1100 - { }, // ad: 0100 1101 1010 1101 - { }, // ae: 0100 1101 1010 1110 - { }, // af: 0100 1101 1010 1111 - - { }, // b0: 0100 1101 1011 0000 - { }, // b1: 0100 1101 1011 0001 - { }, // b2: 0100 1101 1011 0010 - { }, // b3: 0100 1101 1011 0011 - { }, // b4: 0100 1101 1011 0100 - { }, // b5: 0100 1101 1011 0101 - { }, // b6: 0100 1101 1011 0110 - { }, // b7: 0100 1101 1011 0111 - { }, // b8: 0100 1101 1011 1000 - { }, // b9: 0100 1101 1011 1001 - { }, // ba: 0100 1101 1011 1010 - { }, // bb: 0100 1101 1011 1011 - { }, // bc: 0100 1101 1011 1100 - { }, // bd: 0100 1101 1011 1101 - { }, // be: 0100 1101 1011 1110 - { }, // bf: 0100 1101 1011 1111 - - {MOV, "PA,A" }, // c0: 0100 1101 1100 0000 - {MOV, "PB,A" }, // c1: 0100 1101 1100 0001 - {MOV, "PC,A" }, // c2: 0100 1101 1100 0010 - {MOV, "PD,A" }, // c3: 0100 1101 1100 0011 - { }, // c4: 0100 1101 1100 0100 - {MOV, "PF,A" }, // c5: 0100 1101 1100 0101 - {MOV, "MKH,A" }, // c6: 0100 1101 1100 0110 - {MOV, "MKL,A" }, // c7: 0100 1101 1100 0111 - { }, // c8: 0100 1101 1100 1000 - {MOV, "SMH,A" }, // c9: 0100 1101 1100 1001 - {MOV, "SML,A" }, // ca: 0100 1101 1100 1010 - {MOV, "EOM,A" }, // cb: 0100 1101 1100 1011 - {MOV, "ETMM,A" }, // cc: 0100 1101 1100 1100 - {MOV, "TMM,A" }, // cd: 0100 1101 1100 1101 - { }, // ce: 0100 1101 1100 1110 - { }, // cf: 0100 1101 1100 1111 - - {MOV, "MM,A" }, // d0: 0100 1101 1101 0000 - {MOV, "MCC,A" }, // d1: 0100 1101 1101 0001 - {MOV, "MA,A" }, // d2: 0100 1101 1101 0010 - {MOV, "MB,A" }, // d3: 0100 1101 1101 0011 - {MOV, "MC,A" }, // d4: 0100 1101 1101 0100 - { }, // d5: 0100 1101 1101 0101 - { }, // d6: 0100 1101 1101 0110 - {MOV, "MF,A" }, // d7: 0100 1101 1101 0111 - {MOV, "TXB,A" }, // d8: 0100 1101 1101 1000 - { }, // d9: 0100 1101 1101 1001 - {MOV, "TM0,A" }, // da: 0100 1101 1101 1010 - {MOV, "TM1,A" }, // db: 0100 1101 1101 1011 - { }, // dc: 0100 1101 1101 1100 - { }, // dd: 0100 1101 1101 1101 - { }, // de: 0100 1101 1101 1110 - { }, // df: 0100 1101 1101 1111 - - { }, // e0: 0100 1101 1110 0000 - { }, // e1: 0100 1101 1110 0001 - { }, // e2: 0100 1101 1110 0010 - { }, // e3: 0100 1101 1110 0011 - { }, // e4: 0100 1101 1110 0100 - {MOV, "MT,A" }, // e5: 0100 1101 1110 0101 7807 - { }, // e6: 0100 1101 1110 0110 - { }, // e7: 0100 1101 1110 0111 - { }, // e8: 0100 1101 1110 1000 - { }, // e9: 0100 1101 1110 1001 - { }, // ea: 0100 1101 1110 1010 - { }, // eb: 0100 1101 1110 1011 - { }, // ec: 0100 1101 1110 1100 - { }, // ed: 0100 1101 1110 1101 - { }, // ee: 0100 1101 1110 1110 - { }, // ef: 0100 1101 1110 1111 - - { }, // f0: 0100 1101 1111 0000 - { }, // f1: 0100 1101 1111 0001 - { }, // f2: 0100 1101 1111 0010 - { }, // f3: 0100 1101 1111 0011 - { }, // f4: 0100 1101 1111 0100 - { }, // f5: 0100 1101 1111 0101 - { }, // f6: 0100 1101 1111 0110 - { }, // f7: 0100 1101 1111 0111 - { }, // f8: 0100 1101 1111 1000 - { }, // f9: 0100 1101 1111 1001 - { }, // fa: 0100 1101 1111 1010 - { }, // fb: 0100 1101 1111 1011 - { }, // fc: 0100 1101 1111 1100 - { }, // fd: 0100 1101 1111 1101 - { }, // fe: 0100 1101 1111 1110 - { } // ff: 0100 1101 1111 1111 -}; - -// prefix 60 -const dasm_s dasm_s::d60[256] = -{ - { }, // 00: 0110 0000 0000 0000 - { }, // 01: 0110 0000 0000 0001 - { }, // 02: 0110 0000 0000 0010 - { }, // 03: 0110 0000 0000 0011 - { }, // 04: 0110 0000 0000 0100 - { }, // 05: 0110 0000 0000 0101 - { }, // 06: 0110 0000 0000 0110 - { }, // 07: 0110 0000 0000 0111 - {ANA, "V,A" }, // 08: 0110 0000 0000 1000 - {ANA, "A,A" }, // 09: 0110 0000 0000 1001 - {ANA, "B,A" }, // 0a: 0110 0000 0000 1010 - {ANA, "C,A" }, // 0b: 0110 0000 0000 1011 - {ANA, "D,A" }, // 0c: 0110 0000 0000 1100 - {ANA, "E,A" }, // 0d: 0110 0000 0000 1101 - {ANA, "H,A" }, // 0e: 0110 0000 0000 1110 - {ANA, "L,A" }, // 0f: 0110 0000 0000 1111 - - {XRA, "V,A" }, // 10: 0110 0000 0001 0000 - {XRA, "A,A" }, // 11: 0110 0000 0001 0001 - {XRA, "B,A" }, // 12: 0110 0000 0001 0010 - {XRA, "C,A" }, // 13: 0110 0000 0001 0011 - {XRA, "D,A" }, // 14: 0110 0000 0001 0100 - {XRA, "E,A" }, // 15: 0110 0000 0001 0101 - {XRA, "H,A" }, // 16: 0110 0000 0001 0110 - {XRA, "L,A" }, // 17: 0110 0000 0001 0111 - {ORA, "V,A" }, // 18: 0110 0000 0001 1000 - {ORA, "A,A" }, // 19: 0110 0000 0001 1001 - {ORA, "B,A" }, // 1a: 0110 0000 0001 1010 - {ORA, "C,A" }, // 1b: 0110 0000 0001 1011 - {ORA, "D,A" }, // 1c: 0110 0000 0001 1100 - {ORA, "E,A" }, // 1d: 0110 0000 0001 1101 - {ORA, "H,A" }, // 1e: 0110 0000 0001 1110 - {ORA, "L,A" }, // 1f: 0110 0000 0001 1111 - - {ADDNC, "V,A" }, // 20: 0110 0000 0010 0000 - {ADDNC, "A,A" }, // 21: 0110 0000 0010 0001 - {ADDNC, "B,A" }, // 22: 0110 0000 0010 0010 - {ADDNC, "C,A" }, // 23: 0110 0000 0010 0011 - {ADDNC, "D,A" }, // 24: 0110 0000 0010 0100 - {ADDNC, "E,A" }, // 25: 0110 0000 0010 0101 - {ADDNC, "H,A" }, // 26: 0110 0000 0010 0110 - {ADDNC, "L,A" }, // 27: 0110 0000 0010 0111 - {GTA, "V,A" }, // 28: 0110 0000 0010 1000 - {GTA, "A,A" }, // 29: 0110 0000 0010 1001 - {GTA, "B,A" }, // 2a: 0110 0000 0010 1010 - {GTA, "C,A" }, // 2b: 0110 0000 0010 1011 - {GTA, "D,A" }, // 2c: 0110 0000 0010 1100 - {GTA, "E,A" }, // 2d: 0110 0000 0010 1101 - {GTA, "H,A" }, // 2e: 0110 0000 0010 1110 - {GTA, "L,A" }, // 2f: 0110 0000 0010 1111 - {SUBNB, "V,A" }, // 30: 0110 0000 0011 0000 - {SUBNB, "A,A" }, // 31: 0110 0000 0011 0001 - {SUBNB, "B,A" }, // 32: 0110 0000 0011 0010 - {SUBNB, "C,A" }, // 33: 0110 0000 0011 0011 - {SUBNB, "D,A" }, // 34: 0110 0000 0011 0100 - {SUBNB, "E,A" }, // 35: 0110 0000 0011 0101 - {SUBNB, "H,A" }, // 36: 0110 0000 0011 0110 - {SUBNB, "L,A" }, // 37: 0110 0000 0011 0111 - {LTA, "V,A" }, // 38: 0110 0000 0011 1000 - {LTA, "A,A" }, // 39: 0110 0000 0011 1001 - {LTA, "B,A" }, // 3a: 0110 0000 0011 1010 - {LTA, "C,A" }, // 3b: 0110 0000 0011 1011 - {LTA, "D,A" }, // 3c: 0110 0000 0011 1100 - {LTA, "E,A" }, // 3d: 0110 0000 0011 1101 - {LTA, "H,A" }, // 3e: 0110 0000 0011 1110 - {LTA, "L,A" }, // 3f: 0110 0000 0011 1111 - - {ADD, "V,A" }, // 40: 0110 0000 0100 0000 - {ADD, "A,A" }, // 41: 0110 0000 0100 0001 - {ADD, "B,A" }, // 42: 0110 0000 0100 0010 - {ADD, "C,A" }, // 43: 0110 0000 0100 0011 - {ADD, "D,A" }, // 44: 0110 0000 0100 0100 - {ADD, "E,A" }, // 45: 0110 0000 0100 0101 - {ADD, "H,A" }, // 46: 0110 0000 0100 0110 - {ADD, "L,A" }, // 47: 0110 0000 0100 0111 - { }, // 48: 0110 0000 0100 1000 - { }, // 49: 0110 0000 0100 1001 - { }, // 4a: 0110 0000 0100 1010 - { }, // 4b: 0110 0000 0100 1011 - { }, // 4c: 0110 0000 0100 1100 - { }, // 4d: 0110 0000 0100 1101 - { }, // 4e: 0110 0000 0100 1110 - { }, // 4f: 0110 0000 0100 1111 - - {ADC, "V,A" }, // 50: 0110 0000 0101 0000 - {ADC, "A,A" }, // 51: 0110 0000 0101 0001 - {ADC, "B,A" }, // 52: 0110 0000 0101 0010 - {ADC, "C,A" }, // 53: 0110 0000 0101 0011 - {ADC, "D,A" }, // 54: 0110 0000 0101 0100 - {ADC, "E,A" }, // 55: 0110 0000 0101 0101 - {ADC, "H,A" }, // 56: 0110 0000 0101 0110 - {ADC, "L,A" }, // 57: 0110 0000 0101 0111 - { }, // 58: 0110 0000 0101 1000 - { }, // 59: 0110 0000 0101 1001 - { }, // 5a: 0110 0000 0101 1010 - { }, // 5b: 0110 0000 0101 1011 - { }, // 5c: 0110 0000 0101 1100 - { }, // 5d: 0110 0000 0101 1101 - { }, // 5e: 0110 0000 0101 1110 - { }, // 5f: 0110 0000 0101 1111 - - {SUB, "V,A" }, // 60: 0110 0000 0110 0000 - {SUB, "A,A" }, // 61: 0110 0000 0110 0001 - {SUB, "B,A" }, // 62: 0110 0000 0110 0010 - {SUB, "C,A" }, // 63: 0110 0000 0110 0011 - {SUB, "D,A" }, // 64: 0110 0000 0110 0100 - {SUB, "E,A" }, // 65: 0110 0000 0110 0101 - {SUB, "H,A" }, // 66: 0110 0000 0110 0110 - {SUB, "L,A" }, // 67: 0110 0000 0110 0111 - {NEA, "V,A" }, // 68: 0110 0000 0110 1000 - {NEA, "A,A" }, // 69: 0110 0000 0110 1001 - {NEA, "B,A" }, // 6a: 0110 0000 0110 1010 - {NEA, "C,A" }, // 6b: 0110 0000 0110 1011 - {NEA, "D,A" }, // 6c: 0110 0000 0110 1100 - {NEA, "E,A" }, // 6d: 0110 0000 0110 1101 - {NEA, "H,A" }, // 6e: 0110 0000 0110 1110 - {NEA, "L,A" }, // 6f: 0110 0000 0110 1111 - - {SBB, "V,A" }, // 70: 0110 0000 0111 0000 - {SBB, "A,A" }, // 71: 0110 0000 0111 0001 - {SBB, "B,A" }, // 72: 0110 0000 0111 0010 - {SBB, "C,A" }, // 73: 0110 0000 0111 0011 - {SBB, "D,A" }, // 74: 0110 0000 0111 0100 - {SBB, "E,A" }, // 75: 0110 0000 0111 0101 - {SBB, "H,A" }, // 76: 0110 0000 0111 0110 - {SBB, "L,A" }, // 77: 0110 0000 0111 0111 - {EQA, "V,A" }, // 78: 0110 0000 0111 1000 - {EQA, "A,A" }, // 79: 0110 0000 0111 1001 - {EQA, "B,A" }, // 7a: 0110 0000 0111 1010 - {EQA, "C,A" }, // 7b: 0110 0000 0111 1011 - {EQA, "D,A" }, // 7c: 0110 0000 0111 1100 - {EQA, "E,A" }, // 7d: 0110 0000 0111 1101 - {EQA, "H,A" }, // 7e: 0110 0000 0111 1110 - {EQA, "L,A" }, // 7f: 0110 0000 0111 1111 - - { }, // 80: 0110 0000 1000 0000 - { }, // 81: 0110 0000 1000 0001 - { }, // 82: 0110 0000 1000 0010 - { }, // 83: 0110 0000 1000 0011 - { }, // 84: 0110 0000 1000 0100 - { }, // 85: 0110 0000 1000 0101 - { }, // 86: 0110 0000 1000 0110 - { }, // 87: 0110 0000 1000 0111 - {ANA, "A,V" }, // 88: 0110 0000 1000 1000 - {ANA, "A,A" }, // 89: 0110 0000 1000 1001 - {ANA, "A,B" }, // 8a: 0110 0000 1000 1010 - {ANA, "A,C" }, // 8b: 0110 0000 1000 1011 - {ANA, "A,D" }, // 8c: 0110 0000 1000 1100 - {ANA, "A,E" }, // 8d: 0110 0000 1000 1101 - {ANA, "A,H" }, // 8e: 0110 0000 1000 1110 - {ANA, "A,L" }, // 8f: 0110 0000 1000 1111 - - {XRA, "A,V" }, // 90: 0110 0000 1001 0000 - {XRA, "A,A" }, // 91: 0110 0000 1001 0001 - {XRA, "A,B" }, // 92: 0110 0000 1001 0010 - {XRA, "A,C" }, // 93: 0110 0000 1001 0011 - {XRA, "A,D" }, // 94: 0110 0000 1001 0100 - {XRA, "A,E" }, // 95: 0110 0000 1001 0101 - {XRA, "A,H" }, // 96: 0110 0000 1001 0110 - {XRA, "A,L" }, // 97: 0110 0000 1001 0111 - {ORA, "A,V" }, // 98: 0110 0000 1001 1000 - {ORA, "A,A" }, // 99: 0110 0000 1001 1001 - {ORA, "A,B" }, // 9a: 0110 0000 1001 1010 - {ORA, "A,C" }, // 9b: 0110 0000 1001 1011 - {ORA, "A,D" }, // 9c: 0110 0000 1001 1100 - {ORA, "A,E" }, // 9d: 0110 0000 1001 1101 - {ORA, "A,H" }, // 9e: 0110 0000 1001 1110 - {ORA, "A,L" }, // 9f: 0110 0000 1001 1111 - - {ADDNC, "A,V" }, // a0: 0110 0000 1010 0000 - {ADDNC, "A,A" }, // a1: 0110 0000 1010 0001 - {ADDNC, "A,B" }, // a2: 0110 0000 1010 0010 - {ADDNC, "A,C" }, // a3: 0110 0000 1010 0011 - {ADDNC, "A,D" }, // a4: 0110 0000 1010 0100 - {ADDNC, "A,E" }, // a5: 0110 0000 1010 0101 - {ADDNC, "A,H" }, // a6: 0110 0000 1010 0110 - {ADDNC, "A,L" }, // a7: 0110 0000 1010 0111 - {GTA, "A,V" }, // a8: 0110 0000 1010 1000 - {GTA, "A,A" }, // a9: 0110 0000 1010 1001 - {GTA, "A,B" }, // aa: 0110 0000 1010 1010 - {GTA, "A,C" }, // ab: 0110 0000 1010 1011 - {GTA, "A,D" }, // ac: 0110 0000 1010 1100 - {GTA, "A,E" }, // ad: 0110 0000 1010 1101 - {GTA, "A,H" }, // ae: 0110 0000 1010 1110 - {GTA, "A,L" }, // af: 0110 0000 1010 1111 - - {SUBNB, "A,V" }, // b0: 0110 0000 1011 0000 - {SUBNB, "A,A" }, // b1: 0110 0000 1011 0001 - {SUBNB, "A,B" }, // b2: 0110 0000 1011 0010 - {SUBNB, "A,C" }, // b3: 0110 0000 1011 0011 - {SUBNB, "A,D" }, // b4: 0110 0000 1011 0100 - {SUBNB, "A,E" }, // b5: 0110 0000 1011 0101 - {SUBNB, "A,H" }, // b6: 0110 0000 1011 0110 - {SUBNB, "A,L" }, // b7: 0110 0000 1011 0111 - {LTA, "A,V" }, // b8: 0110 0000 1011 1000 - {LTA, "A,A" }, // b9: 0110 0000 1011 1001 - {LTA, "A,B" }, // ba: 0110 0000 1011 1010 - {LTA, "A,C" }, // bb: 0110 0000 1011 1011 - {LTA, "A,D" }, // bc: 0110 0000 1011 1100 - {LTA, "A,E" }, // bd: 0110 0000 1011 1101 - {LTA, "A,H" }, // be: 0110 0000 1011 1110 - {LTA, "A,L" }, // bf: 0110 0000 1011 1111 - - {ADD, "A,V" }, // c0: 0110 0000 1100 0000 - {ADD, "A,A" }, // c1: 0110 0000 1100 0001 - {ADD, "A,B" }, // c2: 0110 0000 1100 0010 - {ADD, "A,C" }, // c3: 0110 0000 1100 0011 - {ADD, "A,D" }, // c4: 0110 0000 1100 0100 - {ADD, "A,E" }, // c5: 0110 0000 1100 0101 - {ADD, "A,H" }, // c6: 0110 0000 1100 0110 - {ADD, "A,L" }, // c7: 0110 0000 1100 0111 - {ONA, "A,V" }, // c8: 0110 0000 1100 1000 - {ONA, "A,A" }, // c9: 0110 0000 1100 1001 - {ONA, "A,B" }, // ca: 0110 0000 1100 1010 - {ONA, "A,C" }, // cb: 0110 0000 1100 1011 - {ONA, "A,D" }, // cc: 0110 0000 1100 1100 - {ONA, "A,E" }, // cd: 0110 0000 1100 1101 - {ONA, "A,H" }, // ce: 0110 0000 1100 1110 - {ONA, "A,L" }, // cf: 0110 0000 1100 1111 - - {ADC, "A,V" }, // d0: 0110 0000 1101 0000 - {ADC, "A,A" }, // d1: 0110 0000 1101 0001 - {ADC, "A,B" }, // d2: 0110 0000 1101 0010 - {ADC, "A,C" }, // d3: 0110 0000 1101 0011 - {ADC, "A,D" }, // d4: 0110 0000 1101 0100 - {ADC, "A,E" }, // d5: 0110 0000 1101 0101 - {ADC, "A,H" }, // d6: 0110 0000 1101 0110 - {ADC, "A,L" }, // d7: 0110 0000 1101 0111 - {OFFA, "A,V" }, // d8: 0110 0000 1101 1000 - {OFFA, "A,A" }, // d9: 0110 0000 1101 1001 - {OFFA, "A,B" }, // da: 0110 0000 1101 1010 - {OFFA, "A,C" }, // db: 0110 0000 1101 1011 - {OFFA, "A,D" }, // dc: 0110 0000 1101 1100 - {OFFA, "A,E" }, // dd: 0110 0000 1101 1101 - {OFFA, "A,H" }, // de: 0110 0000 1101 1110 - {OFFA, "A,L" }, // df: 0110 0000 1101 1111 - - {SUB, "A,V" }, // e0: 0110 0000 1110 0000 - {SUB, "A,A" }, // e1: 0110 0000 1110 0001 - {SUB, "A,B" }, // e2: 0110 0000 1110 0010 - {SUB, "A,C" }, // e3: 0110 0000 1110 0011 - {SUB, "A,D" }, // e4: 0110 0000 1110 0100 - {SUB, "A,E" }, // e5: 0110 0000 1110 0101 - {SUB, "A,H" }, // e6: 0110 0000 1110 0110 - {SUB, "A,L" }, // e7: 0110 0000 1110 0111 - {NEA, "A,V" }, // e8: 0110 0000 1110 1000 - {NEA, "A,A" }, // e9: 0110 0000 1110 1001 - {NEA, "A,B" }, // ea: 0110 0000 1110 1010 - {NEA, "A,C" }, // eb: 0110 0000 1110 1011 - {NEA, "A,D" }, // ec: 0110 0000 1110 1100 - {NEA, "A,E" }, // ed: 0110 0000 1110 1101 - {NEA, "A,H" }, // ee: 0110 0000 1110 1110 - {NEA, "A,L" }, // ef: 0110 0000 1110 1111 - - {SBB, "A,V" }, // f0: 0110 0000 1111 0000 - {SBB, "A,A" }, // f1: 0110 0000 1111 0001 - {SBB, "A,B" }, // f2: 0110 0000 1111 0010 - {SBB, "A,C" }, // f3: 0110 0000 1111 0011 - {SBB, "A,D" }, // f4: 0110 0000 1111 0100 - {SBB, "A,E" }, // f5: 0110 0000 1111 0101 - {SBB, "A,H" }, // f6: 0110 0000 1111 0110 - {SBB, "A,L" }, // f7: 0110 0000 1111 0111 - {EQA, "A,V" }, // f8: 0110 0000 1111 1000 - {EQA, "A,A" }, // f9: 0110 0000 1111 1001 - {EQA, "A,B" }, // fa: 0110 0000 1111 1010 - {EQA, "A,C" }, // fb: 0110 0000 1111 1011 - {EQA, "A,D" }, // fc: 0110 0000 1111 1100 - {EQA, "A,E" }, // fd: 0110 0000 1111 1101 - {EQA, "A,H" }, // fe: 0110 0000 1111 1110 - {EQA, "A,L" } // ff: 0110 0000 1111 1111 -}; // prefix 64 -const dasm_s dasm_s::d64_7810[256] = +const upd7810_base_disassembler::dasm_s upd7810_disassembler::d64_7810[256] = { {MVI, "PA,%b" }, // 00: 0110 0100 0000 0000 xxxx xxxx {MVI, "PB,%b" }, // 01: 0110 0100 0000 0001 xxxx xxxx @@ -2637,835 +2169,10 @@ const dasm_s dasm_s::d64_7810[256] = { } // ff: 0110 0100 1111 1111 xxxx xxxx }; -const dasm_s dasm_s::d64_7807[256] = -{ - {MVI, "PA,%b" }, // 00: 0110 0100 0000 0000 xxxx xxxx - {MVI, "PB,%b" }, // 01: 0110 0100 0000 0001 xxxx xxxx - {MVI, "PC,%b" }, // 02: 0110 0100 0000 0010 xxxx xxxx - {MVI, "PD,%b" }, // 03: 0110 0100 0000 0011 xxxx xxxx - { }, // 04: 0110 0100 0000 0100 xxxx xxxx - {MVI, "PF,%b" }, // 05: 0110 0100 0000 0101 xxxx xxxx - {MVI, "MKH,%b" }, // 06: 0110 0100 0000 0110 xxxx xxxx - {MVI, "MKL,%b" }, // 07: 0110 0100 0000 0111 xxxx xxxx - {ANI, "PA,%b" }, // 08: 0110 0100 0000 1000 xxxx xxxx - {ANI, "PB,%b" }, // 09: 0110 0100 0000 1001 xxxx xxxx - {ANI, "PC,%b" }, // 0a: 0110 0100 0000 1010 xxxx xxxx - {ANI, "PD,%b" }, // 0b: 0110 0100 0000 1011 xxxx xxxx - { }, // 0c: 0110 0100 0000 1100 xxxx xxxx - {ANI, "PF,%b" }, // 0d: 0110 0100 0000 1101 xxxx xxxx - {ANI, "MKH,%b" }, // 0e: 0110 0100 0000 1110 xxxx xxxx - {ANI, "MKL,%b" }, // 0f: 0110 0100 0000 1111 xxxx xxxx - - {XRI, "PA,%b" }, // 10: 0110 0100 0001 0000 xxxx xxxx - {XRI, "PB,%b" }, // 11: 0110 0100 0001 0001 xxxx xxxx - {XRI, "PC,%b" }, // 12: 0110 0100 0001 0010 xxxx xxxx - {XRI, "PD,%b" }, // 13: 0110 0100 0001 0011 xxxx xxxx - { }, // 14: 0110 0100 0001 0100 xxxx xxxx - {XRI, "PF,%b" }, // 15: 0110 0100 0001 0101 xxxx xxxx - {XRI, "MKH,%b" }, // 16: 0110 0100 0001 0110 xxxx xxxx - {XRI, "MKL,%b" }, // 17: 0110 0100 0001 0111 xxxx xxxx - {ORI, "PA,%b" }, // 18: 0110 0100 0001 1000 xxxx xxxx - {ORI, "PB,%b" }, // 19: 0110 0100 0001 1001 xxxx xxxx - {ORI, "PC,%b" }, // 1a: 0110 0100 0001 1010 xxxx xxxx - {ORI, "PD,%b" }, // 1b: 0110 0100 0001 1011 xxxx xxxx - { }, // 1c: 0110 0100 0001 1100 xxxx xxxx - {ORI, "PF,%b" }, // 1d: 0110 0100 0001 1101 xxxx xxxx - {ORI, "MKH,%b" }, // 1e: 0110 0100 0001 1110 xxxx xxxx - {ORI, "MKL,%b" }, // 1f: 0110 0100 0001 1111 xxxx xxxx - - {ADINC, "PA,%b" }, // 20: 0110 0100 0010 0000 xxxx xxxx - {ADINC, "PB,%b" }, // 21: 0110 0100 0010 0001 xxxx xxxx - {ADINC, "PC,%b" }, // 22: 0110 0100 0010 0010 xxxx xxxx - {ADINC, "PD,%b" }, // 23: 0110 0100 0010 0011 xxxx xxxx - { }, // 24: 0110 0100 0010 0100 xxxx xxxx - {ADINC, "PF,%b" }, // 25: 0110 0100 0010 0101 xxxx xxxx - {ADINC, "MKH,%b" }, // 26: 0110 0100 0010 0110 xxxx xxxx - {ADINC, "MKL,%b" }, // 27: 0110 0100 0010 0111 xxxx xxxx - {GTI, "PA,%b" }, // 28: 0110 0100 0010 1000 xxxx xxxx - {GTI, "PB,%b" }, // 29: 0110 0100 0010 1001 xxxx xxxx - {GTI, "PC,%b" }, // 2a: 0110 0100 0010 1010 xxxx xxxx - {GTI, "PD,%b" }, // 2b: 0110 0100 0010 1011 xxxx xxxx - { }, // 2c: 0110 0100 0010 1100 xxxx xxxx - {GTI, "PF,%b" }, // 2d: 0110 0100 0010 1101 xxxx xxxx - {GTI, "MKH,%b" }, // 2e: 0110 0100 0010 1110 xxxx xxxx - {GTI, "MKL,%b" }, // 2f: 0110 0100 0010 1111 xxxx xxxx - - {SUINB, "PA,%b" }, // 30: 0110 0100 0011 0000 xxxx xxxx - {SUINB, "PB,%b" }, // 31: 0110 0100 0011 0001 xxxx xxxx - {SUINB, "PC,%b" }, // 32: 0110 0100 0011 0010 xxxx xxxx - {SUINB, "PD,%b" }, // 33: 0110 0100 0011 0011 xxxx xxxx - { }, // 34: 0110 0100 0011 0100 xxxx xxxx - {SUINB, "PF,%b" }, // 35: 0110 0100 0011 0101 xxxx xxxx - {SUINB, "MKH,%b" }, // 36: 0110 0100 0011 0110 xxxx xxxx - {SUINB, "MKL,%b" }, // 37: 0110 0100 0011 0111 xxxx xxxx - {LTI, "PA,%b" }, // 38: 0110 0100 0011 1000 xxxx xxxx - {LTI, "PB,%b" }, // 39: 0110 0100 0011 1001 xxxx xxxx - {LTI, "PC,%b" }, // 3a: 0110 0100 0011 1010 xxxx xxxx - {LTI, "PD,%b" }, // 3b: 0110 0100 0011 1011 xxxx xxxx - { }, // 3c: 0110 0100 0011 1100 xxxx xxxx - {LTI, "PF,%b" }, // 3d: 0110 0100 0011 1101 xxxx xxxx - {LTI, "MKH,%b" }, // 3e: 0110 0100 0011 1110 xxxx xxxx - {LTI, "MKL,%b" }, // 3f: 0110 0100 0011 1111 xxxx xxxx - - {ADI, "PA,%b" }, // 40: 0110 0100 0100 0000 xxxx xxxx - {ADI, "PB,%b" }, // 41: 0110 0100 0100 0001 xxxx xxxx - {ADI, "PC,%b" }, // 42: 0110 0100 0100 0010 xxxx xxxx - {ADI, "PD,%b" }, // 43: 0110 0100 0100 0011 xxxx xxxx - { }, // 44: 0110 0100 0100 0100 xxxx xxxx - {ADI, "PF,%b" }, // 45: 0110 0100 0100 0101 xxxx xxxx - {ADI, "MKH,%b" }, // 46: 0110 0100 0100 0110 xxxx xxxx - {ADI, "MKL,%b" }, // 47: 0110 0100 0100 0111 xxxx xxxx - {ONI, "PA,%b" }, // 48: 0110 0100 0100 1000 xxxx xxxx - {ONI, "PB,%b" }, // 49: 0110 0100 0100 1001 xxxx xxxx - {ONI, "PC,%b" }, // 4a: 0110 0100 0100 1010 xxxx xxxx - {ONI, "PD,%b" }, // 4b: 0110 0100 0100 1011 xxxx xxxx - { }, // 4c: 0110 0100 0100 1100 xxxx xxxx - {ONI, "PF,%b" }, // 4d: 0110 0100 0100 1101 xxxx xxxx - {ONI, "MKH,%b" }, // 4e: 0110 0100 0100 1110 xxxx xxxx - {ONI, "MKL,%b" }, // 4f: 0110 0100 0100 1111 xxxx xxxx - - {ACI, "PA,%b" }, // 50: 0110 0100 0101 0000 xxxx xxxx - {ACI, "PB,%b" }, // 51: 0110 0100 0101 0001 xxxx xxxx - {ACI, "PC,%b" }, // 52: 0110 0100 0101 0010 xxxx xxxx - {ACI, "PD,%b" }, // 53: 0110 0100 0101 0011 xxxx xxxx - { }, // 54: 0110 0100 0101 0100 xxxx xxxx - {ACI, "PF,%b" }, // 55: 0110 0100 0101 0101 xxxx xxxx - {ACI, "MKH,%b" }, // 56: 0110 0100 0101 0110 xxxx xxxx - {ACI, "MKL,%b" }, // 57: 0110 0100 0101 0111 xxxx xxxx - {OFFI, "PA,%b" }, // 58: 0110 0100 0101 1000 xxxx xxxx - {OFFI, "PB,%b" }, // 59: 0110 0100 0101 1001 xxxx xxxx - {OFFI, "PC,%b" }, // 5a: 0110 0100 0101 1010 xxxx xxxx - {OFFI, "PD,%b" }, // 5b: 0110 0100 0101 1011 xxxx xxxx - { }, // 5c: 0110 0100 0101 1100 xxxx xxxx - {OFFI, "PF,%b" }, // 5d: 0110 0100 0101 1101 xxxx xxxx - {OFFI, "MKH,%b" }, // 5e: 0110 0100 0101 1110 xxxx xxxx - {OFFI, "MKL,%b" }, // 5f: 0110 0100 0101 1111 xxxx xxxx - - {SUI, "PA,%b" }, // 60: 0110 0100 0110 0000 xxxx xxxx - {SUI, "PB,%b" }, // 61: 0110 0100 0110 0001 xxxx xxxx - {SUI, "PC,%b" }, // 62: 0110 0100 0110 0010 xxxx xxxx - {SUI, "PD,%b" }, // 63: 0110 0100 0110 0011 xxxx xxxx - { }, // 64: 0110 0100 0110 0100 xxxx xxxx - {SUI, "PF,%b" }, // 65: 0110 0100 0110 0101 xxxx xxxx - {SUI, "MKH,%b" }, // 66: 0110 0100 0110 0110 xxxx xxxx - {SUI, "MKL,%b" }, // 67: 0110 0100 0110 0111 xxxx xxxx - {NEI, "PA,%b" }, // 68: 0110 0100 0110 1000 xxxx xxxx - {NEI, "PB,%b" }, // 69: 0110 0100 0110 1001 xxxx xxxx - {NEI, "PC,%b" }, // 6a: 0110 0100 0110 1010 xxxx xxxx - {NEI, "PD,%b" }, // 6b: 0110 0100 0110 1011 xxxx xxxx - { }, // 6c: 0110 0100 0110 1100 xxxx xxxx - {NEI, "PF,%b" }, // 6d: 0110 0100 0110 1101 xxxx xxxx - {NEI, "MKH,%b" }, // 6e: 0110 0100 0110 1110 xxxx xxxx - {NEI, "MKL,%b" }, // 6f: 0110 0100 0110 1111 xxxx xxxx - - {SBI, "PA,%b" }, // 70: 0110 0100 0111 0000 xxxx xxxx - {SBI, "PB,%b" }, // 71: 0110 0100 0111 0001 xxxx xxxx - {SBI, "PC,%b" }, // 72: 0110 0100 0111 0010 xxxx xxxx - {SBI, "PD,%b" }, // 73: 0110 0100 0111 0011 xxxx xxxx - { }, // 74: 0110 0100 0111 0100 xxxx xxxx - {SBI, "PF,%b" }, // 75: 0110 0100 0111 0101 xxxx xxxx - {SBI, "MKH,%b" }, // 76: 0110 0100 0111 0110 xxxx xxxx - {SBI, "MKL,%b" }, // 77: 0110 0100 0111 0111 xxxx xxxx - {EQI, "PA,%b" }, // 78: 0110 0100 0111 1000 xxxx xxxx - {EQI, "PB,%b" }, // 79: 0110 0100 0111 1001 xxxx xxxx - {EQI, "PC,%b" }, // 7a: 0110 0100 0111 1010 xxxx xxxx - {EQI, "PD,%b" }, // 7b: 0110 0100 0111 1011 xxxx xxxx - { }, // 7c: 0110 0100 0111 1100 xxxx xxxx - {EQI, "PF,%b" }, // 7d: 0110 0100 0111 1101 xxxx xxxx - {EQI, "MKH,%b" }, // 7e: 0110 0100 0111 1110 xxxx xxxx - {EQI, "MKL,%b" }, // 7f: 0110 0100 0111 1111 xxxx xxxx - - { }, // 80: 0110 0100 1000 0000 xxxx xxxx - {MVI, "SMH,%b" }, // 81: 0110 0100 1000 0001 xxxx xxxx - { }, // 82: 0110 0100 1000 0010 xxxx xxxx - {MVI, "EOM,%b" }, // 83: 0110 0100 1000 0011 xxxx xxxx - { }, // 84: 0110 0100 1000 0100 xxxx xxxx - {MVI, "TMM,%b" }, // 85: 0110 0100 1000 0101 xxxx xxxx - { }, // 86: 0110 0100 1000 0110 xxxx xxxx - { }, // 87: 0110 0100 1000 0111 xxxx xxxx - { }, // 88: 0110 0100 1000 1000 xxxx xxxx - {ANI, "SMH,%b" }, // 89: 0110 0100 1000 1001 xxxx xxxx - { }, // 8a: 0110 0100 1000 1010 xxxx xxxx - {ANI, "EOM,%b" }, // 8b: 0110 0100 1000 1011 xxxx xxxx - { }, // 8c: 0110 0100 1000 1100 xxxx xxxx - {ANI, "TMM,%b" }, // 8d: 0110 0100 1000 1101 xxxx xxxx - { }, // 8e: 0110 0100 1000 1110 xxxx xxxx - { }, // 8f: 0110 0100 1000 1111 xxxx xxxx - - { }, // 90: 0110 0100 1001 0000 xxxx xxxx - {XRI, "SMH,%b" }, // 91: 0110 0100 1001 0001 xxxx xxxx - { }, // 92: 0110 0100 1001 0010 xxxx xxxx - {XRI, "EOM,%b" }, // 93: 0110 0100 1001 0011 xxxx xxxx - { }, // 94: 0110 0100 1001 0100 xxxx xxxx - {XRI, "TMM,%b" }, // 95: 0110 0100 1001 0101 xxxx xxxx - { }, // 96: 0110 0100 1001 0110 xxxx xxxx - { }, // 97: 0110 0100 1001 0111 xxxx xxxx - { }, // 98: 0110 0100 1001 1000 xxxx xxxx - {ORI, "SMH,%b" }, // 99: 0110 0100 1001 1001 xxxx xxxx - { }, // 9a: 0110 0100 1001 1010 xxxx xxxx - {ORI, "EOM,%b" }, // 9b: 0110 0100 1001 1011 xxxx xxxx - { }, // 9c: 0110 0100 1001 1100 xxxx xxxx - {ORI, "TMM,%b" }, // 9d: 0110 0100 1001 1101 xxxx xxxx - { }, // 9e: 0110 0100 1001 1110 xxxx xxxx - { }, // 9f: 0110 0100 1001 1111 xxxx xxxx - - { }, // a0: 0110 0100 1010 0000 xxxx xxxx - {ADINC, "SMH,%b" }, // a1: 0110 0100 1010 0001 xxxx xxxx - { }, // a2: 0110 0100 1010 0010 xxxx xxxx - {ADINC, "EOM,%b" }, // a3: 0110 0100 1010 0011 xxxx xxxx - { }, // a4: 0110 0100 1010 0100 xxxx xxxx - {ADINC, "TMM,%b" }, // a5: 0110 0100 1010 0101 xxxx xxxx - { }, // a6: 0110 0100 1010 0110 xxxx xxxx - { }, // a7: 0110 0100 1010 0111 xxxx xxxx - { }, // a8: 0110 0100 1010 1000 xxxx xxxx - {GTI, "SMH,%b" }, // a9: 0110 0100 1010 1001 xxxx xxxx - { }, // aa: 0110 0100 1010 1010 xxxx xxxx - {GTI, "EOM,%b" }, // ab: 0110 0100 1010 1011 xxxx xxxx - { }, // ac: 0110 0100 1010 1100 xxxx xxxx - {GTI, "TMM,%b" }, // ad: 0110 0100 1010 1101 xxxx xxxx - {GTI, "PT,%b" }, // ae: 0110 0100 1010 1110 xxxx xxxx - { }, // af: 0110 0100 1010 1111 xxxx xxxx - - { }, // b0: 0110 0100 1011 0000 xxxx xxxx - {SUINB, "SMH,%b" }, // b1: 0110 0100 1011 0001 xxxx xxxx - { }, // b2: 0110 0100 1011 0010 xxxx xxxx - {SUINB, "EOM,%b" }, // b3: 0110 0100 1011 0011 xxxx xxxx - { }, // b4: 0110 0100 1011 0100 xxxx xxxx - {SUINB, "TMM,%b" }, // b5: 0110 0100 1011 0101 xxxx xxxx - { }, // b6: 0110 0100 1011 0110 xxxx xxxx - { }, // b7: 0110 0100 1011 0111 xxxx xxxx - { }, // b8: 0110 0100 1011 1000 xxxx xxxx - {LTI, "SMH,%b" }, // b9: 0110 0100 1011 1001 xxxx xxxx - { }, // ba: 0110 0100 1011 1010 xxxx xxxx - {LTI, "EOM,%b" }, // bb: 0110 0100 1011 1011 xxxx xxxx - { }, // bc: 0110 0100 1011 1100 xxxx xxxx - {LTI, "TMM,%b" }, // bd: 0110 0100 1011 1101 xxxx xxxx - {LTI, "PT,%b" }, // be: 0110 0100 1011 1110 xxxx xxxx - { }, // bf: 0110 0100 1011 1111 xxxx xxxx - - { }, // c0: 0110 0100 1100 0000 xxxx xxxx - {ADI, "SMH,%b" }, // c1: 0110 0100 1100 0001 xxxx xxxx - { }, // c2: 0110 0100 1100 0010 xxxx xxxx - {ADI, "EOM,%b" }, // c3: 0110 0100 1100 0011 xxxx xxxx - { }, // c4: 0110 0100 1100 0100 xxxx xxxx - {ADI, "TMM,%b" }, // c5: 0110 0100 1100 0101 xxxx xxxx - { }, // c6: 0110 0100 1100 0110 xxxx xxxx - { }, // c7: 0110 0100 1100 0111 xxxx xxxx - { }, // c8: 0110 0100 1100 1000 xxxx xxxx - {ONI, "SMH,%b" }, // c9: 0110 0100 1100 1001 xxxx xxxx - { }, // ca: 0110 0100 1100 1010 xxxx xxxx - {ONI, "EOM,%b" }, // cb: 0110 0100 1100 1011 xxxx xxxx - { }, // cc: 0110 0100 1100 1100 xxxx xxxx - {ONI, "TMM,%b" }, // cd: 0110 0100 1100 1101 xxxx xxxx - {ONI, "PT,%b" }, // ce: 0110 0100 1100 1110 xxxx xxxx - { }, // cf: 0110 0100 1100 1111 xxxx xxxx - - { }, // d0: 0110 0100 1101 0000 xxxx xxxx - {ACI, "SMH,%b" }, // d1: 0110 0100 1101 0001 xxxx xxxx - { }, // d2: 0110 0100 1101 0010 xxxx xxxx - {ACI, "EOM,%b" }, // d3: 0110 0100 1101 0011 xxxx xxxx - { }, // d4: 0110 0100 1101 0100 xxxx xxxx - {ACI, "TMM,%b" }, // d5: 0110 0100 1101 0101 xxxx xxxx - { }, // d6: 0110 0100 1101 0110 xxxx xxxx - { }, // d7: 0110 0100 1101 0111 xxxx xxxx - { }, // d8: 0110 0100 1101 1000 xxxx xxxx - {OFFI, "SMH,%b" }, // d9: 0110 0100 1101 1001 xxxx xxxx - { }, // da: 0110 0100 1101 1010 xxxx xxxx - {OFFI, "EOM,%b" }, // db: 0110 0100 1101 1011 xxxx xxxx - { }, // dc: 0110 0100 1101 1100 xxxx xxxx - {OFFI, "TMM,%b" }, // dd: 0110 0100 1101 1101 xxxx xxxx - {OFFI, "PT,%b" }, // de: 0110 0100 1101 1110 xxxx xxxx - { }, // df: 0110 0100 1101 1111 xxxx xxxx - - { }, // e0: 0110 0100 1110 0000 xxxx xxxx - {SUI, "SMH,%b" }, // e1: 0110 0100 1110 0001 xxxx xxxx - { }, // e2: 0110 0100 1110 0010 xxxx xxxx - {SUI, "EOM,%b" }, // e3: 0110 0100 1110 0011 xxxx xxxx - { }, // e4: 0110 0100 1110 0100 xxxx xxxx - {SUI, "TMM,%b" }, // e5: 0110 0100 1110 0101 xxxx xxxx - { }, // e6: 0110 0100 1110 0110 xxxx xxxx - { }, // e7: 0110 0100 1110 0111 xxxx xxxx - { }, // e8: 0110 0100 1110 1000 xxxx xxxx - {NEI, "SMH,%b" }, // e9: 0110 0100 1110 1001 xxxx xxxx - { }, // ea: 0110 0100 1110 1010 xxxx xxxx - {NEI, "EOM,%b" }, // eb: 0110 0100 1110 1011 xxxx xxxx - { }, // ec: 0110 0100 1110 1100 xxxx xxxx - {NEI, "TMM,%b" }, // ed: 0110 0100 1110 1101 xxxx xxxx - {NEI, "PT,%b" }, // ee: 0110 0100 1110 1110 xxxx xxxx - { }, // ef: 0110 0100 1110 1111 xxxx xxxx - - { }, // f0: 0110 0100 1111 0000 xxxx xxxx - {SBI, "SMH,%b" }, // f1: 0110 0100 1111 0001 xxxx xxxx - { }, // f2: 0110 0100 1111 0010 xxxx xxxx - {SBI, "EOM,%b" }, // f3: 0110 0100 1111 0011 xxxx xxxx - { }, // f4: 0110 0100 1111 0100 xxxx xxxx - {SBI, "TMM,%b" }, // f5: 0110 0100 1111 0101 xxxx xxxx - { }, // f6: 0110 0100 1111 0110 xxxx xxxx - { }, // f7: 0110 0100 1111 0111 xxxx xxxx - { }, // f8: 0110 0100 1111 1000 xxxx xxxx - {EQI, "SMH,%b" }, // f9: 0110 0100 1111 1001 xxxx xxxx - { }, // fa: 0110 0100 1111 1010 xxxx xxxx - {EQI, "EOM,%b" }, // fb: 0110 0100 1111 1011 xxxx xxxx - { }, // fc: 0110 0100 1111 1100 xxxx xxxx - {EQI, "TMM,%b" }, // fd: 0110 0100 1111 1101 xxxx xxxx - {EQI, "PT,%b" }, // fe: 0110 0100 1111 1110 xxxx xxxx - { } // ff: 0110 0100 1111 1111 xxxx xxxx -}; - -// prefix 70 -const dasm_s dasm_s::d70[256] = -{ - { }, // 00: 0111 0000 0000 0000 - { }, // 01: 0111 0000 0000 0001 - { }, // 02: 0111 0000 0000 0010 - { }, // 03: 0111 0000 0000 0011 - { }, // 04: 0111 0000 0000 0100 - { }, // 05: 0111 0000 0000 0101 - { }, // 06: 0111 0000 0000 0110 - { }, // 07: 0111 0000 0000 0111 - { }, // 08: 0111 0000 0000 1000 - { }, // 09: 0111 0000 0000 1001 - { }, // 0a: 0111 0000 0000 1010 - { }, // 0b: 0111 0000 0000 1011 - { }, // 0c: 0111 0000 0000 1100 - { }, // 0d: 0111 0000 0000 1101 - {SSPD, "%w" }, // 0e: 0111 0000 0000 1110 llll llll hhhh hhhh - {LSPD, "%w" }, // 0f: 0111 0000 0000 1111 llll llll hhhh hhhh - - { }, // 10: 0111 0000 0001 0000 - { }, // 11: 0111 0000 0001 0001 - { }, // 12: 0111 0000 0001 0010 - { }, // 13: 0111 0000 0001 0011 - { }, // 14: 0111 0000 0001 0100 - { }, // 15: 0111 0000 0001 0101 - { }, // 16: 0111 0000 0001 0110 - { }, // 17: 0111 0000 0001 0111 - { }, // 18: 0111 0000 0001 1000 - { }, // 19: 0111 0000 0001 1001 - { }, // 1a: 0111 0000 0001 1010 - { }, // 1b: 0111 0000 0001 1011 - { }, // 1c: 0111 0000 0001 1100 - { }, // 1d: 0111 0000 0001 1101 - {SBCD, "%w" }, // 1e: 0111 0000 0001 1110 llll llll hhhh hhhh - {LBCD, "%w" }, // 1f: 0111 0000 0001 1111 llll llll hhhh hhhh - - { }, // 20: 0111 0000 0010 0000 - { }, // 21: 0111 0000 0010 0001 - { }, // 22: 0111 0000 0010 0010 - { }, // 23: 0111 0000 0010 0011 - { }, // 24: 0111 0000 0010 0100 - { }, // 25: 0111 0000 0010 0101 - { }, // 26: 0111 0000 0010 0110 - { }, // 27: 0111 0000 0010 0111 - { }, // 28: 0111 0000 0010 1000 - { }, // 29: 0111 0000 0010 1001 - { }, // 2a: 0111 0000 0010 1010 - { }, // 2b: 0111 0000 0010 1011 - { }, // 2c: 0111 0000 0010 1100 - { }, // 2d: 0111 0000 0010 1101 - {SDED, "%w" }, // 2e: 0111 0000 0010 1110 llll llll hhhh hhhh - {LDED, "%w" }, // 2f: 0111 0000 0010 1111 llll llll hhhh hhhh - - { }, // 30: 0111 0000 0011 0000 - { }, // 31: 0111 0000 0011 0001 - { }, // 32: 0111 0000 0011 0010 - { }, // 33: 0111 0000 0011 0011 - { }, // 34: 0111 0000 0011 0100 - { }, // 35: 0111 0000 0011 0101 - { }, // 36: 0111 0000 0011 0110 - { }, // 37: 0111 0000 0011 0111 - { }, // 38: 0111 0000 0011 1000 - { }, // 39: 0111 0000 0011 1001 - { }, // 3a: 0111 0000 0011 1010 - { }, // 3b: 0111 0000 0011 1011 - { }, // 3c: 0111 0000 0011 1100 - { }, // 3d: 0111 0000 0011 1101 - {SHLD, "%w" }, // 3e: 0111 0000 0011 1110 llll llll hhhh hhhh - {LHLD, "%w" }, // 3f: 0111 0000 0011 1111 llll llll hhhh hhhh - - {EADD, "EA,V" }, // 40: 0111 0000 0100 0000 - {EADD, "EA,A" }, // 41: 0111 0000 0100 0001 - {EADD, "EA,B" }, // 42: 0111 0000 0100 0010 - {EADD, "EA,C" }, // 43: 0111 0000 0100 0011 - { }, // 44: 0111 0000 0100 0100 - { }, // 45: 0111 0000 0100 0101 - { }, // 46: 0111 0000 0100 0110 - { }, // 47: 0111 0000 0100 0111 - { }, // 48: 0111 0000 0100 1000 - { }, // 49: 0111 0000 0100 1001 - { }, // 4a: 0111 0000 0100 1010 - { }, // 4b: 0111 0000 0100 1011 - { }, // 4c: 0111 0000 0100 1100 - { }, // 4d: 0111 0000 0100 1101 - { }, // 4e: 0111 0000 0100 1110 - { }, // 4f: 0111 0000 0100 1111 - - { }, // 50: 0111 0000 0101 0000 - { }, // 51: 0111 0000 0101 0001 - { }, // 52: 0111 0000 0101 0010 - { }, // 53: 0111 0000 0101 0011 - { }, // 54: 0111 0000 0101 0100 - { }, // 55: 0111 0000 0101 0101 - { }, // 56: 0111 0000 0101 0110 - { }, // 57: 0111 0000 0101 0111 - { }, // 58: 0111 0000 0101 1000 - { }, // 59: 0111 0000 0101 1001 - { }, // 5a: 0111 0000 0101 1010 - { }, // 5b: 0111 0000 0101 1011 - { }, // 5c: 0111 0000 0101 1100 - { }, // 5d: 0111 0000 0101 1101 - { }, // 5e: 0111 0000 0101 1110 - { }, // 5f: 0111 0000 0101 1111 - - {ESUB, "EA,V" }, // 60: 0111 0000 0110 0000 - {ESUB, "EA,A" }, // 61: 0111 0000 0110 0001 - {ESUB, "EA,B" }, // 62: 0111 0000 0110 0010 - {ESUB, "EA,C" }, // 63: 0111 0000 0110 0011 - { }, // 64: 0111 0000 0110 0100 - { }, // 65: 0111 0000 0110 0101 - { }, // 66: 0111 0000 0110 0110 - { }, // 67: 0111 0000 0110 0111 - {MOV, "V,(%w)" }, // 68: 0111 0000 0110 1000 llll llll hhhh hhhh - {MOV, "A,(%w)" }, // 69: 0111 0000 0110 1001 llll llll hhhh hhhh - {MOV, "B,(%w)" }, // 6a: 0111 0000 0110 1010 llll llll hhhh hhhh - {MOV, "C,(%w)" }, // 6b: 0111 0000 0110 1011 llll llll hhhh hhhh - {MOV, "D,(%w)" }, // 6c: 0111 0000 0110 1100 llll llll hhhh hhhh - {MOV, "E,(%w)" }, // 6d: 0111 0000 0110 1101 llll llll hhhh hhhh - {MOV, "H,(%w)" }, // 6e: 0111 0000 0110 1110 llll llll hhhh hhhh - {MOV, "L,(%w)" }, // 6f: 0111 0000 0110 1111 llll llll hhhh hhhh - - { }, // 70: 0111 0000 0111 0000 - { }, // 71: 0111 0000 0111 0001 - { }, // 72: 0111 0000 0111 0010 - { }, // 73: 0111 0000 0111 0011 - { }, // 74: 0111 0000 0111 0100 - { }, // 75: 0111 0000 0111 0101 - { }, // 76: 0111 0000 0111 0110 - { }, // 77: 0111 0000 0111 0111 - {MOV, "(%w),V" }, // 78: 0111 0000 0111 1000 llll llll hhhh hhhh - {MOV, "(%w),A" }, // 79: 0111 0000 0111 1001 llll llll hhhh hhhh - {MOV, "(%w),B" }, // 7a: 0111 0000 0111 1010 llll llll hhhh hhhh - {MOV, "(%w),C" }, // 7b: 0111 0000 0111 1011 llll llll hhhh hhhh - {MOV, "(%w),D" }, // 7c: 0111 0000 0111 1100 llll llll hhhh hhhh - {MOV, "(%w),E" }, // 7d: 0111 0000 0111 1101 llll llll hhhh hhhh - {MOV, "(%w),H" }, // 7e: 0111 0000 0111 1110 llll llll hhhh hhhh - {MOV, "(%w),L" }, // 7f: 0111 0000 0111 1111 llll llll hhhh hhhh - - { }, // 80: 0111 0000 1000 0000 - { }, // 81: 0111 0000 1000 0001 - { }, // 82: 0111 0000 1000 0010 - { }, // 83: 0111 0000 1000 0011 - { }, // 84: 0111 0000 1000 0100 - { }, // 85: 0111 0000 1000 0101 - { }, // 86: 0111 0000 1000 0110 - { }, // 87: 0111 0000 1000 0111 - { }, // 88: 0111 0000 1000 1000 - {ANAX, "(BC)" }, // 89: 0111 0000 1000 1001 - {ANAX, "(DE)" }, // 8a: 0111 0000 1000 1010 - {ANAX, "(HL)" }, // 8b: 0111 0000 1000 1011 - {ANAX, "(DE+)" }, // 8c: 0111 0000 1000 1100 - {ANAX, "(HL+)" }, // 8d: 0111 0000 1000 1101 - {ANAX, "(DE-)" }, // 8e: 0111 0000 1000 1110 - {ANAX, "(HL-)" }, // 8f: 0111 0000 1000 1111 - - { }, // 90: 0111 0000 1001 0000 - {XRAX, "(BC)" }, // 91: 0111 0000 1001 0001 - {XRAX, "(DE)" }, // 92: 0111 0000 1001 0010 - {XRAX, "(HL)" }, // 93: 0111 0000 1001 0011 - {XRAX, "(DE+)" }, // 94: 0111 0000 1001 0100 - {XRAX, "(HL+)" }, // 95: 0111 0000 1001 0101 - {XRAX, "(DE-)" }, // 96: 0111 0000 1001 0110 - {XRAX, "(HL-)" }, // 97: 0111 0000 1001 0111 - { }, // 98: 0111 0000 1001 1000 - {ORAX, "(BC)" }, // 99: 0111 0000 1001 1001 - {ORAX, "(DE)" }, // 9a: 0111 0000 1001 1010 - {ORAX, "(HL)" }, // 9b: 0111 0000 1001 1011 - {ORAX, "(DE+)" }, // 9c: 0111 0000 1001 1100 - {ORAX, "(HL+)" }, // 9d: 0111 0000 1001 1101 - {ORAX, "(DE-)" }, // 9e: 0111 0000 1001 1110 - {ORAX, "(HL-)" }, // 9f: 0111 0000 1001 1111 - - { }, // a0: 0111 0000 1010 0000 - {ADDNCX, "(BC)" }, // a1: 0111 0000 1010 0001 - {ADDNCX, "(DE)" }, // a2: 0111 0000 1010 0010 - {ADDNCX, "(HL)" }, // a3: 0111 0000 1010 0011 - {ADDNCX, "(DE+)" }, // a4: 0111 0000 1010 0100 - {ADDNCX, "(HL+)" }, // a5: 0111 0000 1010 0101 - {ADDNCX, "(DE-)" }, // a6: 0111 0000 1010 0110 - {ADDNCX, "(HL-)" }, // a7: 0111 0000 1010 0111 - { }, // a8: 0111 0000 1010 1000 - {GTAX, "(BC)" }, // a9: 0111 0000 1010 1001 - {GTAX, "(DE)" }, // aa: 0111 0000 1010 1010 - {GTAX, "(HL)" }, // ab: 0111 0000 1010 1011 - {GTAX, "(DE+)" }, // ac: 0111 0000 1010 1100 - {GTAX, "(HL+)" }, // ad: 0111 0000 1010 1101 - {GTAX, "(DE-)" }, // ae: 0111 0000 1010 1110 - {GTAX, "(HL-)" }, // af: 0111 0000 1010 1111 - - { }, // b0: 0111 0000 1011 0000 - {SUBNBX, "(BC)" }, // b1: 0111 0000 1011 0001 - {SUBNBX, "(DE)" }, // b2: 0111 0000 1011 0010 - {SUBNBX, "(HL)" }, // b3: 0111 0000 1011 0011 - {SUBNBX, "(DE+)" }, // b4: 0111 0000 1011 0100 - {SUBNBX, "(HL+)" }, // b5: 0111 0000 1011 0101 - {SUBNBX, "(DE-)" }, // b6: 0111 0000 1011 0110 - {SUBNBX, "(HL-)" }, // b7: 0111 0000 1011 0111 - { }, // b8: 0111 0000 1011 1000 - {LTAX, "(BC)" }, // b9: 0111 0000 1011 1001 - {LTAX, "(DE)" }, // ba: 0111 0000 1011 1010 - {LTAX, "(HL)" }, // bb: 0111 0000 1011 1011 - {LTAX, "(DE+)" }, // bc: 0111 0000 1011 1100 - {LTAX, "(HL+)" }, // bd: 0111 0000 1011 1101 - {LTAX, "(DE-)" }, // be: 0111 0000 1011 1110 - {LTAX, "(HL-)" }, // bf: 0111 0000 1011 1111 - - { }, // c0: 0111 0000 1100 0000 - {ADDX, "(BC)" }, // c1: 0111 0000 1100 0001 - {ADDX, "(DE)" }, // c2: 0111 0000 1100 0010 - {ADDX, "(HL)" }, // c3: 0111 0000 1100 0011 - {ADDX, "(DE+)" }, // c4: 0111 0000 1100 0100 - {ADDX, "(HL+)" }, // c5: 0111 0000 1100 0101 - {ADDX, "(DE-)" }, // c6: 0111 0000 1100 0110 - {ADDX, "(HL-)" }, // c7: 0111 0000 1100 0111 - { }, // c8: 0111 0000 1100 1000 - {ONAX, "(BC)" }, // c9: 0111 0000 1100 1001 - {ONAX, "(DE)" }, // ca: 0111 0000 1100 1010 - {ONAX, "(HL)" }, // cb: 0111 0000 1100 1011 - {ONAX, "(DE+)" }, // cc: 0111 0000 1100 1100 - {ONAX, "(HL+)" }, // cd: 0111 0000 1100 1101 - {ONAX, "(DE-)" }, // ce: 0111 0000 1100 1110 - {ONAX, "(HL-)" }, // cf: 0111 0000 1100 1111 - - { }, // d0: 0111 0000 1101 0000 - {ADCX, "(BC)" }, // d1: 0111 0000 1101 0001 - {ADCX, "(DE)" }, // d2: 0111 0000 1101 0010 - {ADCX, "(HL)" }, // d3: 0111 0000 1101 0011 - {ADCX, "(DE+)" }, // d4: 0111 0000 1101 0100 - {ADCX, "(HL+)" }, // d5: 0111 0000 1101 0101 - {ADCX, "(DE-)" }, // d6: 0111 0000 1101 0110 - {ADCX, "(HL-)" }, // d7: 0111 0000 1101 0111 - { }, // d8: 0111 0000 1101 1000 - {OFFAX, "(BC)" }, // d9: 0111 0000 1101 1001 - {OFFAX, "(DE)" }, // da: 0111 0000 1101 1010 - {OFFAX, "(HL)" }, // db: 0111 0000 1101 1011 - {OFFAX, "(DE+)" }, // dc: 0111 0000 1101 1100 - {OFFAX, "(HL+)" }, // dd: 0111 0000 1101 1101 - {OFFAX, "(DE-)" }, // de: 0111 0000 1101 1110 - {OFFAX, "(HL-)" }, // df: 0111 0000 1101 1111 - - { }, // e0: 0111 0000 1110 0000 - {SUBX, "(BC)" }, // e1: 0111 0000 1110 0001 - {SUBX, "(DE)" }, // e2: 0111 0000 1110 0010 - {SUBX, "(HL)" }, // e3: 0111 0000 1110 0011 - {SUBX, "(DE+)" }, // e4: 0111 0000 1110 0100 - {SUBX, "(HL+)" }, // e5: 0111 0000 1110 0101 - {SUBX, "(DE-)" }, // e6: 0111 0000 1110 0110 - {SUBX, "(HL-)" }, // e7: 0111 0000 1110 0111 - { }, // e8: 0111 0000 1110 1000 - {NEAX, "(BC)" }, // e9: 0111 0000 1110 1001 - {NEAX, "(DE)" }, // ea: 0111 0000 1110 1010 - {NEAX, "(HL)" }, // eb: 0111 0000 1110 1011 - {NEAX, "(DE+)" }, // ec: 0111 0000 1110 1100 - {NEAX, "(HL+)" }, // ed: 0111 0000 1110 1101 - {NEAX, "(DE-)" }, // ee: 0111 0000 1110 1110 - {NEAX, "(HL-)" }, // ef: 0111 0000 1110 1111 - - { }, // f0: 0111 0000 1111 0000 - {SBBX, "(BC)" }, // f1: 0111 0000 1111 0001 - {SBBX, "(DE)" }, // f2: 0111 0000 1111 0010 - {SBBX, "(HL)" }, // f3: 0111 0000 1111 0011 - {SBBX, "(DE+)" }, // f4: 0111 0000 1111 0100 - {SBBX, "(HL+)" }, // f5: 0111 0000 1111 0101 - {SBBX, "(DE-)" }, // f6: 0111 0000 1111 0110 - {SBBX, "(HL-)" }, // f7: 0111 0000 1111 0111 - { }, // f8: 0111 0000 1111 1000 - {EQAX, "(BC)" }, // f9: 0111 0000 1111 1001 - {EQAX, "(DE)" }, // fa: 0111 0000 1111 1010 - {EQAX, "(HL)" }, // fb: 0111 0000 1111 1011 - {EQAX, "(DE+)" }, // fc: 0111 0000 1111 1100 - {EQAX, "(HL+)" }, // fd: 0111 0000 1111 1101 - {EQAX, "(DE-)" }, // fe: 0111 0000 1111 1110 - {EQAX, "(HL-)" } // ff: 0111 0000 1111 1111 -}; - -// prefix 74 -const dasm_s dasm_s::d74[256] = -{ - { }, // 00: 0111 0100 0000 0000 - { }, // 01: 0111 0100 0000 0001 - { }, // 02: 0111 0100 0000 0010 - { }, // 03: 0111 0100 0000 0011 - { }, // 04: 0111 0100 0000 0100 - { }, // 05: 0111 0100 0000 0101 - { }, // 06: 0111 0100 0000 0110 - { }, // 07: 0111 0100 0000 0111 - {ANI, "V,%b" }, // 08: 0111 0100 0000 1000 xxxx xxxx - {ANI, "A,%b" }, // 09: 0111 0100 0000 1001 xxxx xxxx - {ANI, "B,%b" }, // 0a: 0111 0100 0000 1010 xxxx xxxx - {ANI, "C,%b" }, // 0b: 0111 0100 0000 1011 xxxx xxxx - {ANI, "D,%b" }, // 0c: 0111 0100 0000 1100 xxxx xxxx - {ANI, "E,%b" }, // 0d: 0111 0100 0000 1101 xxxx xxxx - {ANI, "H,%b" }, // 0e: 0111 0100 0000 1110 xxxx xxxx - {ANI, "L,%b" }, // 0f: 0111 0100 0000 1111 xxxx xxxx - - {XRI, "V,%b" }, // 10: 0111 0100 0001 0000 xxxx xxxx - {XRI, "A,%b" }, // 11: 0111 0100 0001 0001 xxxx xxxx - {XRI, "B,%b" }, // 12: 0111 0100 0001 0010 xxxx xxxx - {XRI, "C,%b" }, // 13: 0111 0100 0001 0011 xxxx xxxx - {XRI, "D,%b" }, // 14: 0111 0100 0001 0100 xxxx xxxx - {XRI, "E,%b" }, // 15: 0111 0100 0001 0101 xxxx xxxx - {XRI, "H,%b" }, // 16: 0111 0100 0001 0110 xxxx xxxx - {XRI, "L,%b" }, // 17: 0111 0100 0001 0111 xxxx xxxx - {ORI, "V,%b" }, // 18: 0111 0100 0001 1000 xxxx xxxx - {ORI, "A,%b" }, // 19: 0111 0100 0001 1001 xxxx xxxx - {ORI, "B,%b" }, // 1a: 0111 0100 0001 1010 xxxx xxxx - {ORI, "C,%b" }, // 1b: 0111 0100 0001 1011 xxxx xxxx - {ORI, "D,%b" }, // 1c: 0111 0100 0001 1100 xxxx xxxx - {ORI, "E,%b" }, // 1d: 0111 0100 0001 1101 xxxx xxxx - {ORI, "H,%b" }, // 1e: 0111 0100 0001 1110 xxxx xxxx - {ORI, "L,%b" }, // 1f: 0111 0100 0001 1111 xxxx xxxx - - {ADINC, "V,%b" }, // 20: 0111 0100 0010 0000 xxxx xxxx - {ADINC, "A,%b" }, // 21: 0111 0100 0010 0001 xxxx xxxx - {ADINC, "B,%b" }, // 22: 0111 0100 0010 0010 xxxx xxxx - {ADINC, "C,%b" }, // 23: 0111 0100 0010 0011 xxxx xxxx - {ADINC, "D,%b" }, // 24: 0111 0100 0010 0100 xxxx xxxx - {ADINC, "E,%b" }, // 25: 0111 0100 0010 0101 xxxx xxxx - {ADINC, "H,%b" }, // 26: 0111 0100 0010 0110 xxxx xxxx - {ADINC, "L,%b" }, // 27: 0111 0100 0010 0111 xxxx xxxx - {GTI, "V,%b" }, // 28: 0111 0100 0010 1000 xxxx xxxx - {GTI, "A,%b" }, // 29: 0111 0100 0010 1001 xxxx xxxx - {GTI, "B,%b" }, // 2a: 0111 0100 0010 1010 xxxx xxxx - {GTI, "C,%b" }, // 2b: 0111 0100 0010 1011 xxxx xxxx - {GTI, "D,%b" }, // 2c: 0111 0100 0010 1100 xxxx xxxx - {GTI, "E,%b" }, // 2d: 0111 0100 0010 1101 xxxx xxxx - {GTI, "H,%b" }, // 2e: 0111 0100 0010 1110 xxxx xxxx - {GTI, "L,%b" }, // 2f: 0111 0100 0010 1111 xxxx xxxx - - {SUINB, "V,%b" }, // 30: 0111 0100 0011 0000 xxxx xxxx - {SUINB, "A,%b" }, // 31: 0111 0100 0011 0001 xxxx xxxx - {SUINB, "B,%b" }, // 32: 0111 0100 0011 0010 xxxx xxxx - {SUINB, "C,%b" }, // 33: 0111 0100 0011 0011 xxxx xxxx - {SUINB, "D,%b" }, // 34: 0111 0100 0011 0100 xxxx xxxx - {SUINB, "E,%b" }, // 35: 0111 0100 0011 0101 xxxx xxxx - {SUINB, "H,%b" }, // 36: 0111 0100 0011 0110 xxxx xxxx - {SUINB, "L,%b" }, // 37: 0111 0100 0011 0111 xxxx xxxx - {LTI, "V,%b" }, // 37: 0111 0100 0011 1000 xxxx xxxx - {LTI, "A,%b" }, // 39: 0111 0100 0011 1001 xxxx xxxx - {LTI, "B,%b" }, // 3a: 0111 0100 0011 1010 xxxx xxxx - {LTI, "C,%b" }, // 3b: 0111 0100 0011 1011 xxxx xxxx - {LTI, "D,%b" }, // 3c: 0111 0100 0011 1100 xxxx xxxx - {LTI, "E,%b" }, // 3d: 0111 0100 0011 1101 xxxx xxxx - {LTI, "H,%b" }, // 3e: 0111 0100 0011 1110 xxxx xxxx - {LTI, "L,%b" }, // 3f: 0111 0100 0011 1111 xxxx xxxx - - {ADI, "V,%b" }, // 40: 0111 0100 0100 0000 xxxx xxxx - {ADI, "A,%b" }, // 41: 0111 0100 0100 0001 xxxx xxxx - {ADI, "B,%b" }, // 42: 0111 0100 0100 0010 xxxx xxxx - {ADI, "C,%b" }, // 43: 0111 0100 0100 0011 xxxx xxxx - {ADI, "D,%b" }, // 44: 0111 0100 0100 0100 xxxx xxxx - {ADI, "E,%b" }, // 45: 0111 0100 0100 0101 xxxx xxxx - {ADI, "H,%b" }, // 46: 0111 0100 0100 0110 xxxx xxxx - {ADI, "L,%b" }, // 47: 0111 0100 0100 0111 xxxx xxxx - {ONI, "V,%b" }, // 48: 0111 0100 0100 1000 xxxx xxxx - {ONI, "A,%b" }, // 49: 0111 0100 0100 1001 xxxx xxxx - {ONI, "B,%b" }, // 4a: 0111 0100 0100 1010 xxxx xxxx - {ONI, "C,%b" }, // 4b: 0111 0100 0100 1011 xxxx xxxx - {ONI, "D,%b" }, // 4c: 0111 0100 0100 1100 xxxx xxxx - {ONI, "E,%b" }, // 4d: 0111 0100 0100 1101 xxxx xxxx - {ONI, "H,%b" }, // 4e: 0111 0100 0100 1110 xxxx xxxx - {ONI, "L,%b" }, // 4f: 0111 0100 0100 1111 xxxx xxxx - - {ACI, "V,%b" }, // 50: 0111 0100 0101 0000 xxxx xxxx - {ACI, "A,%b" }, // 51: 0111 0100 0101 0001 xxxx xxxx - {ACI, "B,%b" }, // 52: 0111 0100 0101 0010 xxxx xxxx - {ACI, "C,%b" }, // 53: 0111 0100 0101 0011 xxxx xxxx - {ACI, "D,%b" }, // 54: 0111 0100 0101 0100 xxxx xxxx - {ACI, "E,%b" }, // 55: 0111 0100 0101 0101 xxxx xxxx - {ACI, "H,%b" }, // 56: 0111 0100 0101 0110 xxxx xxxx - {ACI, "L,%b" }, // 57: 0111 0100 0101 0111 xxxx xxxx - {OFFI, "V,%b" }, // 58: 0111 0100 0101 1000 xxxx xxxx - {OFFI, "A,%b" }, // 59: 0111 0100 0101 1001 xxxx xxxx - {OFFI, "B,%b" }, // 5a: 0111 0100 0101 1010 xxxx xxxx - {OFFI, "C,%b" }, // 5b: 0111 0100 0101 1011 xxxx xxxx - {OFFI, "D,%b" }, // 5c: 0111 0100 0101 1100 xxxx xxxx - {OFFI, "E,%b" }, // 5d: 0111 0100 0101 1101 xxxx xxxx - {OFFI, "H,%b" }, // 5e: 0111 0100 0101 1110 xxxx xxxx - {OFFI, "L,%b" }, // 5f: 0111 0100 0101 1111 xxxx xxxx - - {SUI, "V,%b" }, // 60: 0111 0100 0110 0000 xxxx xxxx - {SUI, "A,%b" }, // 61: 0111 0100 0110 0001 xxxx xxxx - {SUI, "B,%b" }, // 62: 0111 0100 0110 0010 xxxx xxxx - {SUI, "C,%b" }, // 63: 0111 0100 0110 0011 xxxx xxxx - {SUI, "D,%b" }, // 64: 0111 0100 0110 0100 xxxx xxxx - {SUI, "E,%b" }, // 65: 0111 0100 0110 0101 xxxx xxxx - {SUI, "H,%b" }, // 66: 0111 0100 0110 0110 xxxx xxxx - {SUI, "L,%b" }, // 67: 0111 0100 0110 0111 xxxx xxxx - {NEI, "V,%b" }, // 68: 0111 0100 0110 1000 xxxx xxxx - {NEI, "A,%b" }, // 69: 0111 0100 0110 1001 xxxx xxxx - {NEI, "B,%b" }, // 6a: 0111 0100 0110 1010 xxxx xxxx - {NEI, "C,%b" }, // 6b: 0111 0100 0110 1011 xxxx xxxx - {NEI, "D,%b" }, // 6c: 0111 0100 0110 1100 xxxx xxxx - {NEI, "E,%b" }, // 6d: 0111 0100 0110 1101 xxxx xxxx - {NEI, "H,%b" }, // 6e: 0111 0100 0110 1110 xxxx xxxx - {NEI, "L,%b" }, // 6f: 0111 0100 0110 1111 xxxx xxxx - - {SBI, "V,%b" }, // 70: 0111 0100 0111 0000 xxxx xxxx - {SBI, "A,%b" }, // 71: 0111 0100 0111 0001 xxxx xxxx - {SBI, "B,%b" }, // 72: 0111 0100 0111 0010 xxxx xxxx - {SBI, "C,%b" }, // 73: 0111 0100 0111 0011 xxxx xxxx - {SBI, "D,%b" }, // 74: 0111 0100 0111 0100 xxxx xxxx - {SBI, "E,%b" }, // 75: 0111 0100 0111 0101 xxxx xxxx - {SBI, "H,%b" }, // 76: 0111 0100 0111 0110 xxxx xxxx - {SBI, "L,%b" }, // 77: 0111 0100 0111 0111 xxxx xxxx - {EQI, "V,%b" }, // 78: 0111 0100 0111 1000 xxxx xxxx - {EQI, "A,%b" }, // 79: 0111 0100 0111 1001 xxxx xxxx - {EQI, "B,%b" }, // 7a: 0111 0100 0111 1010 xxxx xxxx - {EQI, "C,%b" }, // 7b: 0111 0100 0111 1011 xxxx xxxx - {EQI, "D,%b" }, // 7c: 0111 0100 0111 1100 xxxx xxxx - {EQI, "E,%b" }, // 7d: 0111 0100 0111 1101 xxxx xxxx - {EQI, "H,%b" }, // 7e: 0111 0100 0111 1110 xxxx xxxx - {EQI, "L,%b" }, // 7f: 0111 0100 0111 1111 xxxx xxxx - - { }, // 80: 0111 0100 1000 0000 - { }, // 81: 0111 0100 1000 0001 - { }, // 82: 0111 0100 1000 0010 - { }, // 83: 0111 0100 1000 0011 - { }, // 84: 0111 0100 1000 0100 - { }, // 85: 0111 0100 1000 0101 - { }, // 86: 0111 0100 1000 0110 - { }, // 87: 0111 0100 1000 0111 - {ANAW, "%a" }, // 88: 0111 0100 1000 1000 oooo oooo - { }, // 89: 0111 0100 1000 1001 - { }, // 8a: 0111 0100 1000 1010 - { }, // 8b: 0111 0100 1000 1011 - { }, // 8c: 0111 0100 1000 1100 - {DAN, "EA,BC" }, // 8d: 0111 0100 1000 1101 - {DAN, "EA,DE" }, // 8e: 0111 0100 1000 1110 - {DAN, "EA,HL" }, // 8f: 0111 0100 1000 1111 - - {XRAW, "%a" }, // 90: 0111 0100 1001 0000 oooo oooo - { }, // 91: 0111 0100 1001 0001 - { }, // 92: 0111 0100 1001 0010 - { }, // 93: 0111 0100 1001 0011 - { }, // 94: 0111 0100 1001 0100 - {DXR, "EA,BC" }, // 95: 0111 0100 1001 0101 - {DXR, "EA,DE" }, // 96: 0111 0100 1001 0110 - {DXR, "EA,HL" }, // 97: 0111 0100 1001 0111 - {ORAW, "%a" }, // 98: 0111 0100 1001 1000 oooo oooo - { }, // 99: 0111 0100 1001 1001 - { }, // 9a: 0111 0100 1001 1010 - { }, // 9b: 0111 0100 1001 1011 - { }, // 9c: 0111 0100 1001 1100 - {DOR, "EA,BC" }, // 9d: 0111 0100 1001 1101 - {DOR, "EA,DE" }, // 9e: 0111 0100 1001 1110 - {DOR, "EA,HL" }, // 9f: 0111 0100 1001 1111 - - {ADDNCW, "%a" }, // a0: 0111 0100 1010 0000 oooo oooo - { }, // a1: 0111 0100 1010 0001 - { }, // a2: 0111 0100 1010 0010 - { }, // a3: 0111 0100 1010 0011 - { }, // a4: 0111 0100 1010 0100 - {DADDNC, "EA,BC" }, // a5: 0111 0100 1010 0101 - {DADDNC, "EA,DE" }, // a6: 0111 0100 1010 0110 - {DADDNC, "EA,HL" }, // a7: 0111 0100 1010 0111 - {GTAW, "%a" }, // a8: 0111 0100 1010 1000 oooo oooo - { }, // a9: 0111 0100 1010 1001 - { }, // aa: 0111 0100 1010 1010 - { }, // ab: 0111 0100 1010 1011 - { }, // ac: 0111 0100 1010 1100 - {DGT, "EA,BC" }, // ad: 0111 0100 1010 1101 - {DGT, "EA,DE" }, // ae: 0111 0100 1010 1110 - {DGT, "EA,HL" }, // af: 0111 0100 1010 1111 - {SUBNBW, "%a" }, // b0: 0111 0100 1011 0000 oooo oooo - { }, // b1: 0111 0100 1011 0001 - { }, // b2: 0111 0100 1011 0010 - { }, // b3: 0111 0100 1011 0011 - { }, // b4: 0111 0100 1011 0100 - {DSUBNB, "EA,BC" }, // b5: 0111 0100 1011 0101 - {DSUBNB, "EA,DE" }, // b6: 0111 0100 1011 0110 - {DSUBNB, "EA,HL" }, // b7: 0111 0100 1011 0111 - {LTAW, "%a" }, // b8: 0111 0100 1011 1000 oooo oooo - { }, // b9: 0111 0100 1011 1001 - { }, // ba: 0111 0100 1011 1010 - { }, // bb: 0111 0100 1011 1011 - { }, // bc: 0111 0100 1011 1100 - {DLT, "EA,BC" }, // bd: 0111 0100 1011 1101 - {DLT, "EA,DE" }, // be: 0111 0100 1011 1110 - {DLT, "EA,HL" }, // bf: 0111 0100 1011 1111 - - {ADDW, "%a" }, // c0: 0111 0100 1100 0000 oooo oooo - { }, // c1: 0111 0100 1100 0001 - { }, // c2: 0111 0100 1100 0010 - { }, // c3: 0111 0100 1100 0011 - { }, // c4: 0111 0100 1100 0100 - {DADD, "EA,BC" }, // c5: 0111 0100 1100 0101 - {DADD, "EA,DE" }, // c6: 0111 0100 1100 0110 - {DADD, "EA,HL" }, // c7: 0111 0100 1100 0111 - {ONAW, "%a" }, // c8: 0111 0100 1100 1000 oooo oooo - { }, // c9: 0111 0100 1100 1001 - { }, // ca: 0111 0100 1100 1010 - { }, // cb: 0111 0100 1100 1011 - { }, // cc: 0111 0100 1100 1100 - {DON, "EA,BC" }, // cd: 0111 0100 1100 1101 - {DON, "EA,DE" }, // ce: 0111 0100 1100 1110 - {DON, "EA,HL" }, // cf: 0111 0100 1100 1111 - - {ADCW, "%a" }, // d0: 0111 0100 1101 0000 oooo oooo - { }, // d1: 0111 0100 1101 0001 - { }, // d2: 0111 0100 1101 0010 - { }, // d3: 0111 0100 1101 0011 - { }, // d4: 0111 0100 1101 0100 - {DADC, "EA,BC" }, // d5: 0111 0100 1101 0101 - {DADC, "EA,DE" }, // d6: 0111 0100 1101 0110 - {DADC, "EA,HL" }, // d7: 0111 0100 1101 0111 - {OFFAW, "%a" }, // d8: 0111 0100 1101 1000 oooo oooo - { }, // d9: 0111 0100 1101 1001 - { }, // da: 0111 0100 1101 1010 - { }, // db: 0111 0100 1101 1011 - { }, // dc: 0111 0100 1101 1100 - {DOFF, "EA,BC" }, // dd: 0111 0100 1101 1101 - {DOFF, "EA,DE" }, // de: 0111 0100 1101 1110 - {DOFF, "EA,HL" }, // df: 0111 0100 1101 1111 - - {SUBW, "%a" }, // e0: 0111 0100 1110 0000 oooo oooo - { }, // e1: 0111 0100 1110 0001 - { }, // e2: 0111 0100 1110 0010 - { }, // e3: 0111 0100 1110 0011 - { }, // e4: 0111 0100 1110 0100 - {DSUB, "EA,BC" }, // e5: 0111 0100 1110 0101 - {DSUB, "EA,DE" }, // e6: 0111 0100 1110 0110 - {DSUB, "EA,HL" }, // e7: 0111 0100 1110 0111 - {NEAW, "%a" }, // e8: 0111 0100 1110 1000 oooo oooo - { }, // e9: 0111 0100 1110 1001 - { }, // ea: 0111 0100 1110 1010 - { }, // eb: 0111 0100 1110 1011 - { }, // ec: 0111 0100 1110 1100 - {DNE, "EA,BC" }, // ed: 0111 0100 1110 1101 - {DNE, "EA,DE" }, // ee: 0111 0100 1110 1110 - {DNE, "EA,HL" }, // ef: 0111 0100 1110 1111 - - {SBBW, "%a" }, // f0: 0111 0100 1111 0000 oooo oooo - { }, // f1: 0111 0100 1111 0001 - { }, // f2: 0111 0100 1111 0010 - { }, // f3: 0111 0100 1111 0011 - { }, // f4: 0111 0100 1111 0100 - {DSBB, "EA,BC" }, // f5: 0111 0100 1111 0101 - {DSBB, "EA,DE" }, // f6: 0111 0100 1111 0110 - {DSBB, "EA,HL" }, // f7: 0111 0100 1111 0111 - {EQAW, "%a" }, // f8: 0111 0100 1111 1000 oooo oooo - { }, // f9: 0111 0100 1111 1001 - { }, // fa: 0111 0100 1111 1010 - { }, // fb: 0111 0100 1111 1011 - { }, // fc: 0111 0100 1111 1100 - {DEQ, "EA,BC" }, // fd: 0111 0100 1111 1101 - {DEQ, "EA,DE" }, // fe: 0111 0100 1111 1110 - {DEQ, "EA,HL" } // ff: 0111 0100 1111 1111 -}; // main opcodes -const dasm_s dasm_s::XX_7810[256] = +const upd7810_base_disassembler::dasm_s upd7810_disassembler::XX_7810[256] = { {NOP, nullptr }, // 00: 0000 0000 {LDAW, "%a" }, // 01: 0000 0001 oooo oooo @@ -3740,7 +2447,1107 @@ const dasm_s dasm_s::XX_7810[256] = {JR, "%o" } // ff: 11oo oooo }; -const dasm_s dasm_s::XX_7807[256] = +const upd7810_base_disassembler::dasm_s upd7807_disassembler::d48_7807[256] = +{ + { }, // 00: 0100 1000 0000 0000 + {SLRC, "A" }, // 01: 0100 1000 0000 0001 + {SLRC, "B" }, // 02: 0100 1000 0000 0010 + {SLRC, "C" }, // 03: 0100 1000 0000 0011 + { }, // 04: 0100 1000 0000 0100 + {SLLC, "A" }, // 05: 0100 1000 0000 0101 + {SLLC, "B" }, // 06: 0100 1000 0000 0110 + {SLLC, "C" }, // 07: 0100 1000 0000 0111 + {SK, "NV" }, // 08: 0100 1000 0000 1000 + { }, // 09: 0100 1000 0000 1001 + {SK, "CY" }, // 0a: 0100 1000 0000 1010 + {SK, "HC" }, // 0b: 0100 1000 0000 1011 + {SK, "Z" }, // 0c: 0100 1000 0000 1100 + { }, // 0d: 0100 1000 0000 1101 + { }, // 0e: 0100 1000 0000 1110 + { }, // 0f: 0100 1000 0000 1111 + + { }, // 10: 0100 1000 0001 0000 + { }, // 11: 0100 1000 0001 0001 + { }, // 12: 0100 1000 0001 0010 + { }, // 13: 0100 1000 0001 0011 + { }, // 14: 0100 1000 0001 0100 + { }, // 15: 0100 1000 0001 0101 + { }, // 16: 0100 1000 0001 0110 + { }, // 17: 0100 1000 0001 0111 + {SKN, "NV" }, // 18: 0100 1000 0001 1000 + { }, // 19: 0100 1000 0001 1001 + {SKN, "CY" }, // 1a: 0100 1000 0001 1010 + {SKN, "HC" }, // 1b: 0100 1000 0001 1011 + {SKN, "Z" }, // 1c: 0100 1000 0001 1100 + { }, // 1d: 0100 1000 0001 1101 + { }, // 1e: 0100 1000 0001 1110 + { }, // 1f: 0100 1000 0001 1111 + + { }, // 20: 0100 1000 0010 0000 + {SLR, "A" }, // 21: 0100 1000 0010 0001 + {SLR, "B" }, // 22: 0100 1000 0010 0010 + {SLR, "C" }, // 23: 0100 1000 0010 0011 + { }, // 24: 0100 1000 0010 0100 + {SLL, "A" }, // 25: 0100 1000 0010 0101 + {SLL, "B" }, // 26: 0100 1000 0010 0110 + {SLL, "C" }, // 27: 0100 1000 0010 0111 + {JEA, nullptr }, // 28: 0100 1000 0010 1000 + {CALB, nullptr }, // 29: 0100 1000 0010 1001 + {CLC, nullptr }, // 2a: 0100 1000 0010 1010 + {STC, nullptr }, // 2b: 0100 1000 0010 1011 + { }, // 2c: 0100 1000 0010 1100 + {MUL, "A" }, // 2d: 0100 1000 0010 1101 + {MUL, "B" }, // 2e: 0100 1000 0010 1110 + {MUL, "C" }, // 2f: 0100 1000 0010 1111 + + { }, // 30: 0100 1000 0011 0000 + {RLR, "A" }, // 31: 0100 1000 0011 0001 + {RLR, "B" }, // 32: 0100 1000 0011 0010 + {RLR, "C" }, // 33: 0100 1000 0011 0011 + { }, // 34: 0100 1000 0011 0100 + {RLL, "A" }, // 35: 0100 1000 0011 0101 + {RLL, "B" }, // 36: 0100 1000 0011 0110 + {RLL, "C" }, // 37: 0100 1000 0011 0111 + {RLD, nullptr }, // 38: 0100 1000 0011 1000 + {RRD, nullptr }, // 39: 0100 1000 0011 1001 + {NEGA, nullptr }, // 3a: 0100 1000 0011 1010 + {HALT, nullptr }, // 3b: 0100 1000 0011 1011 + { }, // 3c: 0100 1000 0011 1100 + {DIV, "A" }, // 3d: 0100 1000 0011 1101 + {DIV, "B" }, // 3e: 0100 1000 0011 1110 + {DIV, "C" }, // 3f: 0100 1000 0011 1111 + + {SKIT, "NMI" }, // 40: 0100 1000 0100 0000 + {SKIT, "FT0" }, // 41: 0100 1000 0100 0001 + {SKIT, "FT1" }, // 42: 0100 1000 0100 0010 + {SKIT, "F1" }, // 43: 0100 1000 0100 0011 + {SKIT, "F2" }, // 44: 0100 1000 0100 0100 + {SKIT, "FE0" }, // 45: 0100 1000 0100 0101 + {SKIT, "FE1" }, // 46: 0100 1000 0100 0110 + {SKIT, "FEIN" }, // 47: 0100 1000 0100 0111 + {SKIT, "FAD" }, // 48: 0100 1000 0100 1000 + {SKIT, "FSR" }, // 49: 0100 1000 0100 1001 + {SKIT, "FST" }, // 4a: 0100 1000 0100 1010 + {SKIT, "ER" }, // 4b: 0100 1000 0100 1011 + {SKIT, "OV" }, // 4c: 0100 1000 0100 1100 + { }, // 4d: 0100 1000 0100 1101 + { }, // 4e: 0100 1000 0100 1110 + { }, // 4f: 0100 1000 0100 1111 + + {SKIT, "AN4" }, // 50: 0100 1000 0101 0000 + {SKIT, "AN5" }, // 51: 0100 1000 0101 0001 + {SKIT, "AN6" }, // 52: 0100 1000 0101 0010 + {SKIT, "AN7" }, // 53: 0100 1000 0101 0011 + {SKIT, "SB" }, // 54: 0100 1000 0101 0100 + { }, // 55: 0100 1000 0101 0101 + { }, // 56: 0100 1000 0101 0110 + { }, // 57: 0100 1000 0101 0111 + { }, // 58: 0100 1000 0101 1000 + { }, // 59: 0100 1000 0101 1001 + { }, // 5a: 0100 1000 0101 1010 + { }, // 5b: 0100 1000 0101 1011 + { }, // 5c: 0100 1000 0101 1100 + { }, // 5d: 0100 1000 0101 1101 + { }, // 5e: 0100 1000 0101 1110 + { }, // 5f: 0100 1000 0101 1111 + + {SKNIT, "NMI" }, // 60: 0100 1000 0110 0000 + {SKNIT, "FT0" }, // 61: 0100 1000 0110 0001 + {SKNIT, "FT1" }, // 62: 0100 1000 0110 0010 + {SKNIT, "F1" }, // 63: 0100 1000 0110 0011 + {SKNIT, "F2" }, // 64: 0100 1000 0110 0100 + {SKNIT, "FE0" }, // 65: 0100 1000 0110 0101 + {SKNIT, "FE1" }, // 66: 0100 1000 0110 0110 + {SKNIT, "FEIN" }, // 67: 0100 1000 0110 0111 + {SKNIT, "FAD" }, // 68: 0100 1000 0110 1000 + {SKNIT, "FSR" }, // 69: 0100 1000 0110 1001 + {SKNIT, "FST" }, // 6a: 0100 1000 0110 1010 + {SKNIT, "ER" }, // 6b: 0100 1000 0110 1011 + {SKNIT, "OV" }, // 6c: 0100 1000 0110 1100 + { }, // 6d: 0100 1000 0110 1101 + { }, // 6e: 0100 1000 0110 1110 + { }, // 6f: 0100 1000 0110 1111 + + {SKNIT, "AN4" }, // 70: 0100 1000 0111 0000 + {SKNIT, "AN5" }, // 71: 0100 1000 0111 0001 + {SKNIT, "AN6" }, // 72: 0100 1000 0111 0010 + {SKNIT, "AN7" }, // 73: 0100 1000 0111 0011 + {SKNIT, "SB" }, // 74: 0100 1000 0111 0100 + { }, // 75: 0100 1000 0111 0101 + { }, // 76: 0100 1000 0111 0110 + { }, // 77: 0100 1000 0111 0111 + { }, // 78: 0100 1000 0111 1000 + { }, // 79: 0100 1000 0111 1001 + { }, // 7a: 0100 1000 0111 1010 + { }, // 7b: 0100 1000 0111 1011 + { }, // 7c: 0100 1000 0111 1100 + { }, // 7d: 0100 1000 0111 1101 + { }, // 7e: 0100 1000 0111 1110 + { }, // 7f: 0100 1000 0111 1111 + + { }, // 80: 0100 1000 1000 0000 + { }, // 81: 0100 1000 1000 0001 + {LDEAX, "(DE)" }, // 82: 0100 1000 1000 0010 + {LDEAX, "(HL)" }, // 83: 0100 1000 1000 0011 + {LDEAX, "(DE++)" }, // 84: 0100 1000 1000 0100 + {LDEAX, "(HL++)" }, // 85: 0100 1000 1000 0101 + { }, // 86: 0100 1000 1000 0110 + { }, // 87: 0100 1000 1000 0111 + { }, // 88: 0100 1000 1000 1000 + { }, // 89: 0100 1000 1000 1001 + { }, // 8a: 0100 1000 1000 1010 + {LDEAX, "(DE+%b)" }, // 8b: 0100 1000 1000 1011 xxxx xxxx + {LDEAX, "(HL+A)" }, // 8c: 0100 1000 1000 1100 + {LDEAX, "(HL+B)" }, // 8d: 0100 1000 1000 1101 + {LDEAX, "(HL+EA)" }, // 8e: 0100 1000 1000 1110 + {LDEAX, "(HL+%b)" }, // 8f: 0100 1000 1000 1111 xxxx xxxx + + { }, // 90: 0100 1000 1000 0000 + { }, // 91: 0100 1000 1000 0001 + {STEAX, "(DE)" }, // 92: 0100 1000 1000 0010 + {STEAX, "(HL)" }, // 93: 0100 1000 1000 0011 + {STEAX, "(DE++)" }, // 94: 0100 1000 1000 0100 + {STEAX, "(HL++)" }, // 95: 0100 1000 1000 0101 + { }, // 96: 0100 1000 1000 0110 + { }, // 97: 0100 1000 1000 0111 + { }, // 98: 0100 1000 1000 1000 + { }, // 99: 0100 1000 1000 1001 + { }, // 9a: 0100 1000 1000 1010 + {STEAX, "(DE+%b)" }, // 9b: 0100 1000 1000 1011 xxxx xxxx + {STEAX, "(HL+A)" }, // 9c: 0100 1000 1000 1100 + {STEAX, "(HL+B)" }, // 9d: 0100 1000 1000 1101 + {STEAX, "(HL+EA)" }, // 9e: 0100 1000 1000 1110 + {STEAX, "(HL+%b)" }, // 9f: 0100 1000 1000 1111 xxxx xxxx + + {DSLR, "EA" }, // a0: 0100 1000 1010 0000 + { }, // a1: 0100 1000 1010 0001 + { }, // a2: 0100 1000 1010 0010 + { }, // a3: 0100 1000 1010 0011 + {DSLL, "EA" }, // a4: 0100 1000 1010 0100 + { }, // a5: 0100 1000 1010 0101 + { }, // a6: 0100 1000 1010 0110 + { }, // a7: 0100 1000 1010 0111 + {TABLE, nullptr }, // a8: 0100 1000 1010 1000 + { }, // a9: 0100 1000 1010 1001 + {CMC, nullptr }, // aa: 0100 1000 1010 1010 7807 + { }, // ab: 0100 1000 1010 1011 + {EXA, nullptr }, // ac: 0100 1000 1010 1100 7807 + {EXR, nullptr }, // ad: 0100 1000 1010 1101 7807 + {EXH, nullptr }, // ae: 0100 1000 1010 1110 7807 + {EXX, nullptr }, // af: 0100 1000 1010 1111 7807 + + {DRLR, "EA" }, // b0: 0100 1000 1011 0000 + { }, // b1: 0100 1000 1011 0001 + { }, // b2: 0100 1000 1011 0010 + { }, // b3: 0100 1000 1011 0011 + {DRLL, "EA" }, // b4: 0100 1000 1011 0100 + { }, // b5: 0100 1000 1011 0101 + { }, // b6: 0100 1000 1011 0110 + { }, // b7: 0100 1000 1011 0111 + { }, // b8: 0100 1000 1011 1000 + { }, // b9: 0100 1000 1011 1001 + { }, // ba: 0100 1000 1011 1010 + { }, // bb: 0100 1000 1011 1011 + { }, // bc: 0100 1000 1011 1100 + { }, // bd: 0100 1000 1011 1101 + { }, // be: 0100 1000 1011 1110 + { }, // bf: 0100 1000 1011 1111 + + {DMOV, "EA,ECNT" }, // c0: 0100 1000 1100 0000 + {DMOV, "EA,ECPT0"}, // c1: 0100 1000 1100 0001 7807 + {DMOV, "EA,ECPT1"}, // c2: 0100 1000 1100 0010 7807 + { }, // c3: 0100 1000 1100 0011 + { }, // c4: 0100 1000 1100 0100 + { }, // c5: 0100 1000 1100 0101 + { }, // c6: 0100 1000 1100 0110 + { }, // c7: 0100 1000 1100 0111 + { }, // c8: 0100 1000 1100 1000 + { }, // c9: 0100 1000 1100 1001 + { }, // ca: 0100 1000 1100 1010 + { }, // cb: 0100 1000 1100 1011 + { }, // cc: 0100 1000 1100 1100 + { }, // cd: 0100 1000 1100 1101 + { }, // ce: 0100 1000 1100 1110 + { }, // cf: 0100 1000 1100 1111 + + { }, // d0: 0100 1000 1101 0000 + { }, // d1: 0100 1000 1101 0001 + {DMOV, "ETM0,EA" }, // d2: 0100 1000 1101 0010 + {DMOV, "ETM1,EA" }, // d3: 0100 1000 1101 0011 + { }, // d4: 0100 1000 1101 0100 + { }, // d5: 0100 1000 1101 0101 + { }, // d6: 0100 1000 1101 0110 + { }, // d7: 0100 1000 1101 0111 + { }, // d8: 0100 1000 1101 1000 + { }, // d9: 0100 1000 1101 1001 + { }, // da: 0100 1000 1101 1010 + { }, // db: 0100 1000 1101 1011 + { }, // dc: 0100 1000 1101 1100 + { }, // dd: 0100 1000 1101 1101 + { }, // de: 0100 1000 1101 1110 + { }, // df: 0100 1000 1101 1111 + + { }, // e0: 0100 1000 1110 0000 + { }, // e1: 0100 1000 1110 0001 + { }, // e2: 0100 1000 1110 0010 + { }, // e3: 0100 1000 1110 0011 + { }, // e4: 0100 1000 1110 0100 + { }, // e5: 0100 1000 1110 0101 + { }, // e6: 0100 1000 1110 0110 + { }, // e7: 0100 1000 1110 0111 + { }, // e8: 0100 1000 1110 1000 + { }, // e9: 0100 1000 1110 1001 + { }, // ea: 0100 1000 1110 1010 + { }, // eb: 0100 1000 1110 1011 + { }, // ec: 0100 1000 1110 1100 + { }, // ed: 0100 1000 1110 1101 + { }, // ee: 0100 1000 1110 1110 + { }, // ef: 0100 1000 1110 1111 + + { }, // f0: 0100 1000 1111 0000 + { }, // f1: 0100 1000 1111 0001 + { }, // f2: 0100 1000 1111 0010 + { }, // f3: 0100 1000 1111 0011 + { }, // f4: 0100 1000 1111 0100 + { }, // f5: 0100 1000 1111 0101 + { }, // f6: 0100 1000 1111 0110 + { }, // f7: 0100 1000 1111 0111 + { }, // f8: 0100 1000 1111 1000 + { }, // f9: 0100 1000 1111 1001 + { }, // fa: 0100 1000 1111 1010 + { }, // fb: 0100 1000 1111 1011 + { }, // fc: 0100 1000 1111 1100 + { }, // fd: 0100 1000 1111 1101 + { }, // fe: 0100 1000 1111 1110 + { } // ff: 0100 1000 1111 1111 +}; + +const upd7810_base_disassembler::dasm_s upd7807_disassembler::d4C_7807[256] = +{ + { }, // 00: 0100 1100 0000 0000 + { }, // 01: 0100 1100 0000 0001 + { }, // 02: 0100 1100 0000 0010 + { }, // 03: 0100 1100 0000 0011 + { }, // 04: 0100 1100 0000 0100 + { }, // 05: 0100 1100 0000 0101 + { }, // 06: 0100 1100 0000 0110 + { }, // 07: 0100 1100 0000 0111 + { }, // 08: 0100 1100 0000 1000 + { }, // 09: 0100 1100 0000 1001 + { }, // 0a: 0100 1100 0000 1010 + { }, // 0b: 0100 1100 0000 1011 + { }, // 0c: 0100 1100 0000 1100 + { }, // 0d: 0100 1100 0000 1101 + { }, // 0e: 0100 1100 0000 1110 + { }, // 0f: 0100 1100 0000 1111 + + { }, // 10: 0100 1100 0001 0000 + { }, // 11: 0100 1100 0001 0001 + { }, // 12: 0100 1100 0001 0010 + { }, // 13: 0100 1100 0001 0011 + { }, // 14: 0100 1100 0001 0100 + { }, // 15: 0100 1100 0001 0101 + { }, // 16: 0100 1100 0001 0110 + { }, // 17: 0100 1100 0001 0111 + { }, // 18: 0100 1100 0001 1000 + { }, // 19: 0100 1100 0001 1001 + { }, // 1a: 0100 1100 0001 1010 + { }, // 1b: 0100 1100 0001 1011 + { }, // 1c: 0100 1100 0001 1100 + { }, // 1d: 0100 1100 0001 1101 + { }, // 1e: 0100 1100 0001 1110 + { }, // 1f: 0100 1100 0001 1111 + + { }, // 20: 0100 1100 0010 0000 + { }, // 21: 0100 1100 0010 0001 + { }, // 22: 0100 1100 0010 0010 + { }, // 23: 0100 1100 0010 0011 + { }, // 24: 0100 1100 0010 0100 + { }, // 25: 0100 1100 0010 0101 + { }, // 26: 0100 1100 0010 0110 + { }, // 27: 0100 1100 0010 0111 + { }, // 28: 0100 1100 0010 1000 + { }, // 29: 0100 1100 0010 1001 + { }, // 2a: 0100 1100 0010 1010 + { }, // 2b: 0100 1100 0010 1011 + { }, // 2c: 0100 1100 0010 1100 + { }, // 2d: 0100 1100 0010 1101 + { }, // 2e: 0100 1100 0010 1110 + { }, // 2f: 0100 1100 0010 1111 + + { }, // 30: 0100 1100 0011 0000 + { }, // 31: 0100 1100 0011 0001 + { }, // 32: 0100 1100 0011 0010 + { }, // 33: 0100 1100 0011 0011 + { }, // 34: 0100 1100 0011 0100 + { }, // 35: 0100 1100 0011 0101 + { }, // 36: 0100 1100 0011 0110 + { }, // 37: 0100 1100 0011 0111 + { }, // 38: 0100 1100 0011 1000 + { }, // 39: 0100 1100 0011 1001 + { }, // 3a: 0100 1100 0011 1010 + { }, // 3b: 0100 1100 0011 1011 + { }, // 3c: 0100 1100 0011 1100 + { }, // 3d: 0100 1100 0011 1101 + { }, // 3e: 0100 1100 0011 1110 + { }, // 3f: 0100 1100 0011 1111 + + { }, // 40: 0100 1100 0100 0000 + { }, // 41: 0100 1100 0100 0001 + { }, // 42: 0100 1100 0100 0010 + { }, // 43: 0100 1100 0100 0011 + { }, // 44: 0100 1100 0100 0100 + { }, // 45: 0100 1100 0100 0101 + { }, // 46: 0100 1100 0100 0110 + { }, // 47: 0100 1100 0100 0111 + { }, // 48: 0100 1100 0100 1000 + { }, // 49: 0100 1100 0100 1001 + { }, // 4a: 0100 1100 0100 1010 + { }, // 4b: 0100 1100 0100 1011 + { }, // 4c: 0100 1100 0100 1100 + { }, // 4d: 0100 1100 0100 1101 + { }, // 4e: 0100 1100 0100 1110 + { }, // 4f: 0100 1100 0100 1111 + + { }, // 50: 0100 1100 0101 0000 + { }, // 51: 0100 1100 0101 0001 + { }, // 52: 0100 1100 0101 0010 + { }, // 53: 0100 1100 0101 0011 + { }, // 54: 0100 1100 0101 0100 + { }, // 55: 0100 1100 0101 0101 + { }, // 56: 0100 1100 0101 0110 + { }, // 57: 0100 1100 0101 0111 + { }, // 58: 0100 1100 0101 1000 + { }, // 59: 0100 1100 0101 1001 + { }, // 5a: 0100 1100 0101 1010 + { }, // 5b: 0100 1100 0101 1011 + { }, // 5c: 0100 1100 0101 1100 + { }, // 5d: 0100 1100 0101 1101 + { }, // 5e: 0100 1100 0101 1110 + { }, // 5f: 0100 1100 0101 1111 + + { }, // 60: 0100 1100 0110 0000 + { }, // 61: 0100 1100 0110 0001 + { }, // 62: 0100 1100 0110 0010 + { }, // 63: 0100 1100 0110 0011 + { }, // 64: 0100 1100 0110 0100 + { }, // 65: 0100 1100 0110 0101 + { }, // 66: 0100 1100 0110 0110 + { }, // 67: 0100 1100 0110 0111 + { }, // 68: 0100 1100 0110 1000 + { }, // 69: 0100 1100 0110 1001 + { }, // 6a: 0100 1100 0110 1010 + { }, // 6b: 0100 1100 0110 1011 + { }, // 6c: 0100 1100 0110 1100 + { }, // 6d: 0100 1100 0110 1101 + { }, // 6e: 0100 1100 0110 1110 + { }, // 6f: 0100 1100 0110 1111 + + { }, // 70: 0100 1100 0111 0000 + { }, // 71: 0100 1100 0111 0001 + { }, // 72: 0100 1100 0111 0010 + { }, // 73: 0100 1100 0111 0011 + { }, // 74: 0100 1100 0111 0100 + { }, // 75: 0100 1100 0111 0101 + { }, // 76: 0100 1100 0111 0110 + { }, // 77: 0100 1100 0111 0111 + { }, // 78: 0100 1100 0111 1000 + { }, // 79: 0100 1100 0111 1001 + { }, // 7a: 0100 1100 0111 1010 + { }, // 7b: 0100 1100 0111 1011 + { }, // 7c: 0100 1100 0111 1100 + { }, // 7d: 0100 1100 0111 1101 + { }, // 7e: 0100 1100 0111 1110 + { }, // 7f: 0100 1100 0111 1111 + + { }, // 80: 0100 1100 1000 0000 + { }, // 81: 0100 1100 1000 0001 + { }, // 82: 0100 1100 1000 0010 + { }, // 83: 0100 1100 1000 0011 + { }, // 84: 0100 1100 1000 0100 + { }, // 85: 0100 1100 1000 0101 + { }, // 86: 0100 1100 1000 0110 + { }, // 87: 0100 1100 1000 0111 + { }, // 88: 0100 1100 1000 1000 + { }, // 89: 0100 1100 1000 1001 + { }, // 8a: 0100 1100 1000 1010 + { }, // 8b: 0100 1100 1000 1011 + { }, // 8c: 0100 1100 1000 1100 + { }, // 8d: 0100 1100 1000 1101 + { }, // 8e: 0100 1100 1000 1110 + { }, // 8f: 0100 1100 1000 1111 + + { }, // 90: 0100 1100 1001 0000 + { }, // 91: 0100 1100 1001 0001 + { }, // 92: 0100 1100 1001 0010 + { }, // 93: 0100 1100 1001 0011 + { }, // 94: 0100 1100 1001 0100 + { }, // 95: 0100 1100 1001 0101 + { }, // 96: 0100 1100 1001 0110 + { }, // 97: 0100 1100 1001 0111 + { }, // 98: 0100 1100 1001 1000 + { }, // 99: 0100 1100 1001 1001 + { }, // 9a: 0100 1100 1001 1010 + { }, // 9b: 0100 1100 1001 1011 + { }, // 9c: 0100 1100 1001 1100 + { }, // 9d: 0100 1100 1001 1101 + { }, // 9e: 0100 1100 1001 1110 + { }, // 9f: 0100 1100 1001 1111 + + { }, // a0: 0100 1100 1010 0000 + { }, // a1: 0100 1100 1010 0001 + { }, // a2: 0100 1100 1010 0010 + { }, // a3: 0100 1100 1010 0011 + { }, // a4: 0100 1100 1010 0100 + { }, // a5: 0100 1100 1010 0101 + { }, // a6: 0100 1100 1010 0110 + { }, // a7: 0100 1100 1010 0111 + { }, // a8: 0100 1100 1010 1000 + { }, // a9: 0100 1100 1010 1001 + { }, // aa: 0100 1100 1010 1010 + { }, // ab: 0100 1100 1010 1011 + { }, // ac: 0100 1100 1010 1100 + { }, // ad: 0100 1100 1010 1101 + { }, // ae: 0100 1100 1010 1110 + { }, // af: 0100 1100 1010 1111 + + { }, // b0: 0100 1100 1011 0000 + { }, // b1: 0100 1100 1011 0001 + { }, // b2: 0100 1100 1011 0010 + { }, // b3: 0100 1100 1011 0011 + { }, // b4: 0100 1100 1011 0100 + { }, // b5: 0100 1100 1011 0101 + { }, // b6: 0100 1100 1011 0110 + { }, // b7: 0100 1100 1011 0111 + { }, // b8: 0100 1100 1011 1000 + { }, // b9: 0100 1100 1011 1001 + { }, // ba: 0100 1100 1011 1010 + { }, // bb: 0100 1100 1011 1011 + { }, // bc: 0100 1100 1011 1100 + { }, // bd: 0100 1100 1011 1101 + { }, // be: 0100 1100 1011 1110 + { }, // bf: 0100 1100 1011 1111 + + {MOV, "A,PA" }, // c0: 0100 1100 1100 0000 + {MOV, "A,PB" }, // c1: 0100 1100 1100 0001 + {MOV, "A,PC" }, // c2: 0100 1100 1100 0010 + {MOV, "A,PD" }, // c3: 0100 1100 1100 0011 + { }, // c4: 0100 1100 1100 0100 + {MOV, "A,PF" }, // c5: 0100 1100 1100 0101 + {MOV, "A,MKH" }, // c6: 0100 1100 1100 0110 + {MOV, "A,MKL" }, // c7: 0100 1100 1100 0111 + { }, // c8: 0100 1100 1100 1000 + {MOV, "A,SMH" }, // c9: 0100 1100 1100 1001 + { }, // ca: 0100 1100 1100 1010 + {MOV, "A,EOM" }, // cb: 0100 1100 1100 1011 + { }, // cc: 0100 1100 1100 1100 + {MOV, "A,TMM" }, // cd: 0100 1100 1100 1101 + {MOV, "A,PT" }, // ce: 0100 1100 1100 1110 7807 + { }, // cf: 0100 1100 1100 1111 + + { }, // d0: 0100 1100 1101 0000 + { }, // d1: 0100 1100 1101 0001 + { }, // d2: 0100 1100 1101 0010 + { }, // d3: 0100 1100 1101 0011 + { }, // d4: 0100 1100 1101 0100 + { }, // d5: 0100 1100 1101 0101 + { }, // d6: 0100 1100 1101 0110 + { }, // d7: 0100 1100 1101 0111 + { }, // d8: 0100 1100 1101 1000 + {MOV, "A,RXB" }, // d9: 0100 1100 1101 1001 + { }, // da: 0100 1100 1101 1010 + { }, // db: 0100 1100 1101 1011 + { }, // dc: 0100 1100 1101 1100 + { }, // dd: 0100 1100 1101 1101 + { }, // de: 0100 1100 1101 1110 + { }, // df: 0100 1100 1101 1111 + + { }, // e0: 0100 1100 1110 0000 + { }, // e1: 0100 1100 1110 0001 + { }, // e2: 0100 1100 1110 0010 + { }, // e3: 0100 1100 1110 0011 + { }, // e4: 0100 1100 1110 0100 + { }, // e5: 0100 1100 1110 0101 + { }, // e6: 0100 1100 1110 0110 + { }, // e7: 0100 1100 1110 0111 + { }, // e8: 0100 1100 1110 1000 + { }, // e9: 0100 1100 1110 1001 + { }, // ea: 0100 1100 1110 1010 + { }, // eb: 0100 1100 1110 1011 + { }, // ec: 0100 1100 1110 1100 + { }, // ed: 0100 1100 1110 1101 + { }, // ee: 0100 1100 1110 1110 + { }, // ef: 0100 1100 1110 1111 + + { }, // f0: 0100 1100 1111 0000 + { }, // f1: 0100 1100 1111 0001 + { }, // f2: 0100 1100 1111 0010 + { }, // f3: 0100 1100 1111 0011 + { }, // f4: 0100 1100 1111 0100 + { }, // f5: 0100 1100 1111 0101 + { }, // f6: 0100 1100 1111 0110 + { }, // f7: 0100 1100 1111 0111 + { }, // f8: 0100 1100 1111 1000 + { }, // f9: 0100 1100 1111 1001 + { }, // fa: 0100 1100 1111 1010 + { }, // fb: 0100 1100 1111 1011 + { }, // fc: 0100 1100 1111 1100 + { }, // fd: 0100 1100 1111 1101 + { }, // fe: 0100 1100 1111 1110 + { } // ff: 0100 1100 1111 1111 +}; + +const upd7810_base_disassembler::dasm_s upd7807_disassembler::d4D_7807[256] = +{ + { }, // 00: 0100 1101 0000 0000 + { }, // 01: 0100 1101 0000 0001 + { }, // 02: 0100 1101 0000 0010 + { }, // 03: 0100 1101 0000 0011 + { }, // 04: 0100 1101 0000 0100 + { }, // 05: 0100 1101 0000 0101 + { }, // 06: 0100 1101 0000 0110 + { }, // 07: 0100 1101 0000 0111 + { }, // 08: 0100 1101 0000 1000 + { }, // 09: 0100 1101 0000 1001 + { }, // 0a: 0100 1101 0000 1010 + { }, // 0b: 0100 1101 0000 1011 + { }, // 0c: 0100 1101 0000 1100 + { }, // 0d: 0100 1101 0000 1101 + { }, // 0e: 0100 1101 0000 1110 + { }, // 0f: 0100 1101 0000 1111 + + { }, // 10: 0100 1101 0001 0000 + { }, // 11: 0100 1101 0001 0001 + { }, // 12: 0100 1101 0001 0010 + { }, // 13: 0100 1101 0001 0011 + { }, // 14: 0100 1101 0001 0100 + { }, // 15: 0100 1101 0001 0101 + { }, // 16: 0100 1101 0001 0110 + { }, // 17: 0100 1101 0001 0111 + { }, // 18: 0100 1101 0001 1000 + { }, // 19: 0100 1101 0001 1001 + { }, // 1a: 0100 1101 0001 1010 + { }, // 1b: 0100 1101 0001 1011 + { }, // 1c: 0100 1101 0001 1100 + { }, // 1d: 0100 1101 0001 1101 + { }, // 1e: 0100 1101 0001 1110 + { }, // 1f: 0100 1101 0001 1111 + + { }, // 20: 0100 1101 0010 0000 + { }, // 21: 0100 1101 0010 0001 + { }, // 22: 0100 1101 0010 0010 + { }, // 23: 0100 1101 0010 0011 + { }, // 24: 0100 1101 0010 0100 + { }, // 25: 0100 1101 0010 0101 + { }, // 26: 0100 1101 0010 0110 + { }, // 27: 0100 1101 0010 0111 + { }, // 28: 0100 1101 0010 1000 + { }, // 29: 0100 1101 0010 1001 + { }, // 2a: 0100 1101 0010 1010 + { }, // 2b: 0100 1101 0010 1011 + { }, // 2c: 0100 1101 0010 1100 + { }, // 2d: 0100 1101 0010 1101 + { }, // 2e: 0100 1101 0010 1110 + { }, // 2f: 0100 1101 0010 1111 + + { }, // 30: 0100 1101 0011 0000 + { }, // 31: 0100 1101 0011 0001 + { }, // 32: 0100 1101 0011 0010 + { }, // 33: 0100 1101 0011 0011 + { }, // 34: 0100 1101 0011 0100 + { }, // 35: 0100 1101 0011 0101 + { }, // 36: 0100 1101 0011 0110 + { }, // 37: 0100 1101 0011 0111 + { }, // 38: 0100 1101 0011 1000 + { }, // 39: 0100 1101 0011 1001 + { }, // 3a: 0100 1101 0011 1010 + { }, // 3b: 0100 1101 0011 1011 + { }, // 3c: 0100 1101 0011 1100 + { }, // 3d: 0100 1101 0011 1101 + { }, // 3e: 0100 1101 0011 1110 + { }, // 3f: 0100 1101 0011 1111 + + { }, // 40: 0100 1101 0100 0000 + { }, // 41: 0100 1101 0100 0001 + { }, // 42: 0100 1101 0100 0010 + { }, // 43: 0100 1101 0100 0011 + { }, // 44: 0100 1101 0100 0100 + { }, // 45: 0100 1101 0100 0101 + { }, // 46: 0100 1101 0100 0110 + { }, // 47: 0100 1101 0100 0111 + { }, // 48: 0100 1101 0100 1000 + { }, // 49: 0100 1101 0100 1001 + { }, // 4a: 0100 1101 0100 1010 + { }, // 4b: 0100 1101 0100 1011 + { }, // 4c: 0100 1101 0100 1100 + { }, // 4d: 0100 1101 0100 1101 + { }, // 4e: 0100 1101 0100 1110 + { }, // 4f: 0100 1101 0100 1111 + + { }, // 50: 0100 1101 0101 0000 + { }, // 51: 0100 1101 0101 0001 + { }, // 52: 0100 1101 0101 0010 + { }, // 53: 0100 1101 0101 0011 + { }, // 54: 0100 1101 0101 0100 + { }, // 55: 0100 1101 0101 0101 + { }, // 56: 0100 1101 0101 0110 + { }, // 57: 0100 1101 0101 0111 + { }, // 58: 0100 1101 0101 1000 + { }, // 59: 0100 1101 0101 1001 + { }, // 5a: 0100 1101 0101 1010 + { }, // 5b: 0100 1101 0101 1011 + { }, // 5c: 0100 1101 0101 1100 + { }, // 5d: 0100 1101 0101 1101 + { }, // 5e: 0100 1101 0101 1110 + { }, // 5f: 0100 1101 0101 1111 + + { }, // 60: 0100 1101 0110 0000 + { }, // 61: 0100 1101 0110 0001 + { }, // 62: 0100 1101 0110 0010 + { }, // 63: 0100 1101 0110 0011 + { }, // 64: 0100 1101 0110 0100 + { }, // 65: 0100 1101 0110 0101 + { }, // 66: 0100 1101 0110 0110 + { }, // 67: 0100 1101 0110 0111 + { }, // 68: 0100 1101 0110 1000 + { }, // 69: 0100 1101 0110 1001 + { }, // 6a: 0100 1101 0110 1010 + { }, // 6b: 0100 1101 0110 1011 + { }, // 6c: 0100 1101 0110 1100 + { }, // 6d: 0100 1101 0110 1101 + { }, // 6e: 0100 1101 0110 1110 + { }, // 6f: 0100 1101 0110 1111 + + { }, // 70: 0100 1101 0111 0000 + { }, // 71: 0100 1101 0111 0001 + { }, // 72: 0100 1101 0111 0010 + { }, // 73: 0100 1101 0111 0011 + { }, // 74: 0100 1101 0111 0100 + { }, // 75: 0100 1101 0111 0101 + { }, // 76: 0100 1101 0111 0110 + { }, // 77: 0100 1101 0111 0111 + { }, // 78: 0100 1101 0111 1000 + { }, // 79: 0100 1101 0111 1001 + { }, // 7a: 0100 1101 0111 1010 + { }, // 7b: 0100 1101 0111 1011 + { }, // 7c: 0100 1101 0111 1100 + { }, // 7d: 0100 1101 0111 1101 + { }, // 7e: 0100 1101 0111 1110 + { }, // 7f: 0100 1101 0111 1111 + + { }, // 80: 0100 1101 1000 0000 + { }, // 81: 0100 1101 1000 0001 + { }, // 82: 0100 1101 1000 0010 + { }, // 83: 0100 1101 1000 0011 + { }, // 84: 0100 1101 1000 0100 + { }, // 85: 0100 1101 1000 0101 + { }, // 86: 0100 1101 1000 0110 + { }, // 87: 0100 1101 1000 0111 + { }, // 88: 0100 1101 1000 1000 + { }, // 89: 0100 1101 1000 1001 + { }, // 8a: 0100 1101 1000 1010 + { }, // 8b: 0100 1101 1000 1011 + { }, // 8c: 0100 1101 1000 1100 + { }, // 8d: 0100 1101 1000 1101 + { }, // 8e: 0100 1101 1000 1110 + { }, // 8f: 0100 1101 1000 1111 + + { }, // 90: 0100 1101 1001 0000 + { }, // 91: 0100 1101 1001 0001 + { }, // 92: 0100 1101 1001 0010 + { }, // 93: 0100 1101 1001 0011 + { }, // 94: 0100 1101 1001 0100 + { }, // 95: 0100 1101 1001 0101 + { }, // 96: 0100 1101 1001 0110 + { }, // 97: 0100 1101 1001 0111 + { }, // 98: 0100 1101 1001 1000 + { }, // 99: 0100 1101 1001 1001 + { }, // 9a: 0100 1101 1001 1010 + { }, // 9b: 0100 1101 1001 1011 + { }, // 9c: 0100 1101 1001 1100 + { }, // 9d: 0100 1101 1001 1101 + { }, // 9e: 0100 1101 1001 1110 + { }, // 9f: 0100 1101 1001 1111 + + { }, // a0: 0100 1101 1010 0000 + { }, // a1: 0100 1101 1010 0001 + { }, // a2: 0100 1101 1010 0010 + { }, // a3: 0100 1101 1010 0011 + { }, // a4: 0100 1101 1010 0100 + { }, // a5: 0100 1101 1010 0101 + { }, // a6: 0100 1101 1010 0110 + { }, // a7: 0100 1101 1010 0111 + { }, // a8: 0100 1101 1010 1000 + { }, // a9: 0100 1101 1010 1001 + { }, // aa: 0100 1101 1010 1010 + { }, // ab: 0100 1101 1010 1011 + { }, // ac: 0100 1101 1010 1100 + { }, // ad: 0100 1101 1010 1101 + { }, // ae: 0100 1101 1010 1110 + { }, // af: 0100 1101 1010 1111 + + { }, // b0: 0100 1101 1011 0000 + { }, // b1: 0100 1101 1011 0001 + { }, // b2: 0100 1101 1011 0010 + { }, // b3: 0100 1101 1011 0011 + { }, // b4: 0100 1101 1011 0100 + { }, // b5: 0100 1101 1011 0101 + { }, // b6: 0100 1101 1011 0110 + { }, // b7: 0100 1101 1011 0111 + { }, // b8: 0100 1101 1011 1000 + { }, // b9: 0100 1101 1011 1001 + { }, // ba: 0100 1101 1011 1010 + { }, // bb: 0100 1101 1011 1011 + { }, // bc: 0100 1101 1011 1100 + { }, // bd: 0100 1101 1011 1101 + { }, // be: 0100 1101 1011 1110 + { }, // bf: 0100 1101 1011 1111 + + {MOV, "PA,A" }, // c0: 0100 1101 1100 0000 + {MOV, "PB,A" }, // c1: 0100 1101 1100 0001 + {MOV, "PC,A" }, // c2: 0100 1101 1100 0010 + {MOV, "PD,A" }, // c3: 0100 1101 1100 0011 + { }, // c4: 0100 1101 1100 0100 + {MOV, "PF,A" }, // c5: 0100 1101 1100 0101 + {MOV, "MKH,A" }, // c6: 0100 1101 1100 0110 + {MOV, "MKL,A" }, // c7: 0100 1101 1100 0111 + { }, // c8: 0100 1101 1100 1000 + {MOV, "SMH,A" }, // c9: 0100 1101 1100 1001 + {MOV, "SML,A" }, // ca: 0100 1101 1100 1010 + {MOV, "EOM,A" }, // cb: 0100 1101 1100 1011 + {MOV, "ETMM,A" }, // cc: 0100 1101 1100 1100 + {MOV, "TMM,A" }, // cd: 0100 1101 1100 1101 + { }, // ce: 0100 1101 1100 1110 + { }, // cf: 0100 1101 1100 1111 + + {MOV, "MM,A" }, // d0: 0100 1101 1101 0000 + {MOV, "MCC,A" }, // d1: 0100 1101 1101 0001 + {MOV, "MA,A" }, // d2: 0100 1101 1101 0010 + {MOV, "MB,A" }, // d3: 0100 1101 1101 0011 + {MOV, "MC,A" }, // d4: 0100 1101 1101 0100 + { }, // d5: 0100 1101 1101 0101 + { }, // d6: 0100 1101 1101 0110 + {MOV, "MF,A" }, // d7: 0100 1101 1101 0111 + {MOV, "TXB,A" }, // d8: 0100 1101 1101 1000 + { }, // d9: 0100 1101 1101 1001 + {MOV, "TM0,A" }, // da: 0100 1101 1101 1010 + {MOV, "TM1,A" }, // db: 0100 1101 1101 1011 + { }, // dc: 0100 1101 1101 1100 + { }, // dd: 0100 1101 1101 1101 + { }, // de: 0100 1101 1101 1110 + { }, // df: 0100 1101 1101 1111 + + { }, // e0: 0100 1101 1110 0000 + { }, // e1: 0100 1101 1110 0001 + { }, // e2: 0100 1101 1110 0010 + { }, // e3: 0100 1101 1110 0011 + { }, // e4: 0100 1101 1110 0100 + {MOV, "MT,A" }, // e5: 0100 1101 1110 0101 7807 + { }, // e6: 0100 1101 1110 0110 + { }, // e7: 0100 1101 1110 0111 + { }, // e8: 0100 1101 1110 1000 + { }, // e9: 0100 1101 1110 1001 + { }, // ea: 0100 1101 1110 1010 + { }, // eb: 0100 1101 1110 1011 + { }, // ec: 0100 1101 1110 1100 + { }, // ed: 0100 1101 1110 1101 + { }, // ee: 0100 1101 1110 1110 + { }, // ef: 0100 1101 1110 1111 + + { }, // f0: 0100 1101 1111 0000 + { }, // f1: 0100 1101 1111 0001 + { }, // f2: 0100 1101 1111 0010 + { }, // f3: 0100 1101 1111 0011 + { }, // f4: 0100 1101 1111 0100 + { }, // f5: 0100 1101 1111 0101 + { }, // f6: 0100 1101 1111 0110 + { }, // f7: 0100 1101 1111 0111 + { }, // f8: 0100 1101 1111 1000 + { }, // f9: 0100 1101 1111 1001 + { }, // fa: 0100 1101 1111 1010 + { }, // fb: 0100 1101 1111 1011 + { }, // fc: 0100 1101 1111 1100 + { }, // fd: 0100 1101 1111 1101 + { }, // fe: 0100 1101 1111 1110 + { } // ff: 0100 1101 1111 1111 +}; + +const upd7810_base_disassembler::dasm_s upd7807_disassembler::d64_7807[256] = +{ + {MVI, "PA,%b" }, // 00: 0110 0100 0000 0000 xxxx xxxx + {MVI, "PB,%b" }, // 01: 0110 0100 0000 0001 xxxx xxxx + {MVI, "PC,%b" }, // 02: 0110 0100 0000 0010 xxxx xxxx + {MVI, "PD,%b" }, // 03: 0110 0100 0000 0011 xxxx xxxx + { }, // 04: 0110 0100 0000 0100 xxxx xxxx + {MVI, "PF,%b" }, // 05: 0110 0100 0000 0101 xxxx xxxx + {MVI, "MKH,%b" }, // 06: 0110 0100 0000 0110 xxxx xxxx + {MVI, "MKL,%b" }, // 07: 0110 0100 0000 0111 xxxx xxxx + {ANI, "PA,%b" }, // 08: 0110 0100 0000 1000 xxxx xxxx + {ANI, "PB,%b" }, // 09: 0110 0100 0000 1001 xxxx xxxx + {ANI, "PC,%b" }, // 0a: 0110 0100 0000 1010 xxxx xxxx + {ANI, "PD,%b" }, // 0b: 0110 0100 0000 1011 xxxx xxxx + { }, // 0c: 0110 0100 0000 1100 xxxx xxxx + {ANI, "PF,%b" }, // 0d: 0110 0100 0000 1101 xxxx xxxx + {ANI, "MKH,%b" }, // 0e: 0110 0100 0000 1110 xxxx xxxx + {ANI, "MKL,%b" }, // 0f: 0110 0100 0000 1111 xxxx xxxx + + {XRI, "PA,%b" }, // 10: 0110 0100 0001 0000 xxxx xxxx + {XRI, "PB,%b" }, // 11: 0110 0100 0001 0001 xxxx xxxx + {XRI, "PC,%b" }, // 12: 0110 0100 0001 0010 xxxx xxxx + {XRI, "PD,%b" }, // 13: 0110 0100 0001 0011 xxxx xxxx + { }, // 14: 0110 0100 0001 0100 xxxx xxxx + {XRI, "PF,%b" }, // 15: 0110 0100 0001 0101 xxxx xxxx + {XRI, "MKH,%b" }, // 16: 0110 0100 0001 0110 xxxx xxxx + {XRI, "MKL,%b" }, // 17: 0110 0100 0001 0111 xxxx xxxx + {ORI, "PA,%b" }, // 18: 0110 0100 0001 1000 xxxx xxxx + {ORI, "PB,%b" }, // 19: 0110 0100 0001 1001 xxxx xxxx + {ORI, "PC,%b" }, // 1a: 0110 0100 0001 1010 xxxx xxxx + {ORI, "PD,%b" }, // 1b: 0110 0100 0001 1011 xxxx xxxx + { }, // 1c: 0110 0100 0001 1100 xxxx xxxx + {ORI, "PF,%b" }, // 1d: 0110 0100 0001 1101 xxxx xxxx + {ORI, "MKH,%b" }, // 1e: 0110 0100 0001 1110 xxxx xxxx + {ORI, "MKL,%b" }, // 1f: 0110 0100 0001 1111 xxxx xxxx + + {ADINC, "PA,%b" }, // 20: 0110 0100 0010 0000 xxxx xxxx + {ADINC, "PB,%b" }, // 21: 0110 0100 0010 0001 xxxx xxxx + {ADINC, "PC,%b" }, // 22: 0110 0100 0010 0010 xxxx xxxx + {ADINC, "PD,%b" }, // 23: 0110 0100 0010 0011 xxxx xxxx + { }, // 24: 0110 0100 0010 0100 xxxx xxxx + {ADINC, "PF,%b" }, // 25: 0110 0100 0010 0101 xxxx xxxx + {ADINC, "MKH,%b" }, // 26: 0110 0100 0010 0110 xxxx xxxx + {ADINC, "MKL,%b" }, // 27: 0110 0100 0010 0111 xxxx xxxx + {GTI, "PA,%b" }, // 28: 0110 0100 0010 1000 xxxx xxxx + {GTI, "PB,%b" }, // 29: 0110 0100 0010 1001 xxxx xxxx + {GTI, "PC,%b" }, // 2a: 0110 0100 0010 1010 xxxx xxxx + {GTI, "PD,%b" }, // 2b: 0110 0100 0010 1011 xxxx xxxx + { }, // 2c: 0110 0100 0010 1100 xxxx xxxx + {GTI, "PF,%b" }, // 2d: 0110 0100 0010 1101 xxxx xxxx + {GTI, "MKH,%b" }, // 2e: 0110 0100 0010 1110 xxxx xxxx + {GTI, "MKL,%b" }, // 2f: 0110 0100 0010 1111 xxxx xxxx + + {SUINB, "PA,%b" }, // 30: 0110 0100 0011 0000 xxxx xxxx + {SUINB, "PB,%b" }, // 31: 0110 0100 0011 0001 xxxx xxxx + {SUINB, "PC,%b" }, // 32: 0110 0100 0011 0010 xxxx xxxx + {SUINB, "PD,%b" }, // 33: 0110 0100 0011 0011 xxxx xxxx + { }, // 34: 0110 0100 0011 0100 xxxx xxxx + {SUINB, "PF,%b" }, // 35: 0110 0100 0011 0101 xxxx xxxx + {SUINB, "MKH,%b" }, // 36: 0110 0100 0011 0110 xxxx xxxx + {SUINB, "MKL,%b" }, // 37: 0110 0100 0011 0111 xxxx xxxx + {LTI, "PA,%b" }, // 38: 0110 0100 0011 1000 xxxx xxxx + {LTI, "PB,%b" }, // 39: 0110 0100 0011 1001 xxxx xxxx + {LTI, "PC,%b" }, // 3a: 0110 0100 0011 1010 xxxx xxxx + {LTI, "PD,%b" }, // 3b: 0110 0100 0011 1011 xxxx xxxx + { }, // 3c: 0110 0100 0011 1100 xxxx xxxx + {LTI, "PF,%b" }, // 3d: 0110 0100 0011 1101 xxxx xxxx + {LTI, "MKH,%b" }, // 3e: 0110 0100 0011 1110 xxxx xxxx + {LTI, "MKL,%b" }, // 3f: 0110 0100 0011 1111 xxxx xxxx + + {ADI, "PA,%b" }, // 40: 0110 0100 0100 0000 xxxx xxxx + {ADI, "PB,%b" }, // 41: 0110 0100 0100 0001 xxxx xxxx + {ADI, "PC,%b" }, // 42: 0110 0100 0100 0010 xxxx xxxx + {ADI, "PD,%b" }, // 43: 0110 0100 0100 0011 xxxx xxxx + { }, // 44: 0110 0100 0100 0100 xxxx xxxx + {ADI, "PF,%b" }, // 45: 0110 0100 0100 0101 xxxx xxxx + {ADI, "MKH,%b" }, // 46: 0110 0100 0100 0110 xxxx xxxx + {ADI, "MKL,%b" }, // 47: 0110 0100 0100 0111 xxxx xxxx + {ONI, "PA,%b" }, // 48: 0110 0100 0100 1000 xxxx xxxx + {ONI, "PB,%b" }, // 49: 0110 0100 0100 1001 xxxx xxxx + {ONI, "PC,%b" }, // 4a: 0110 0100 0100 1010 xxxx xxxx + {ONI, "PD,%b" }, // 4b: 0110 0100 0100 1011 xxxx xxxx + { }, // 4c: 0110 0100 0100 1100 xxxx xxxx + {ONI, "PF,%b" }, // 4d: 0110 0100 0100 1101 xxxx xxxx + {ONI, "MKH,%b" }, // 4e: 0110 0100 0100 1110 xxxx xxxx + {ONI, "MKL,%b" }, // 4f: 0110 0100 0100 1111 xxxx xxxx + + {ACI, "PA,%b" }, // 50: 0110 0100 0101 0000 xxxx xxxx + {ACI, "PB,%b" }, // 51: 0110 0100 0101 0001 xxxx xxxx + {ACI, "PC,%b" }, // 52: 0110 0100 0101 0010 xxxx xxxx + {ACI, "PD,%b" }, // 53: 0110 0100 0101 0011 xxxx xxxx + { }, // 54: 0110 0100 0101 0100 xxxx xxxx + {ACI, "PF,%b" }, // 55: 0110 0100 0101 0101 xxxx xxxx + {ACI, "MKH,%b" }, // 56: 0110 0100 0101 0110 xxxx xxxx + {ACI, "MKL,%b" }, // 57: 0110 0100 0101 0111 xxxx xxxx + {OFFI, "PA,%b" }, // 58: 0110 0100 0101 1000 xxxx xxxx + {OFFI, "PB,%b" }, // 59: 0110 0100 0101 1001 xxxx xxxx + {OFFI, "PC,%b" }, // 5a: 0110 0100 0101 1010 xxxx xxxx + {OFFI, "PD,%b" }, // 5b: 0110 0100 0101 1011 xxxx xxxx + { }, // 5c: 0110 0100 0101 1100 xxxx xxxx + {OFFI, "PF,%b" }, // 5d: 0110 0100 0101 1101 xxxx xxxx + {OFFI, "MKH,%b" }, // 5e: 0110 0100 0101 1110 xxxx xxxx + {OFFI, "MKL,%b" }, // 5f: 0110 0100 0101 1111 xxxx xxxx + + {SUI, "PA,%b" }, // 60: 0110 0100 0110 0000 xxxx xxxx + {SUI, "PB,%b" }, // 61: 0110 0100 0110 0001 xxxx xxxx + {SUI, "PC,%b" }, // 62: 0110 0100 0110 0010 xxxx xxxx + {SUI, "PD,%b" }, // 63: 0110 0100 0110 0011 xxxx xxxx + { }, // 64: 0110 0100 0110 0100 xxxx xxxx + {SUI, "PF,%b" }, // 65: 0110 0100 0110 0101 xxxx xxxx + {SUI, "MKH,%b" }, // 66: 0110 0100 0110 0110 xxxx xxxx + {SUI, "MKL,%b" }, // 67: 0110 0100 0110 0111 xxxx xxxx + {NEI, "PA,%b" }, // 68: 0110 0100 0110 1000 xxxx xxxx + {NEI, "PB,%b" }, // 69: 0110 0100 0110 1001 xxxx xxxx + {NEI, "PC,%b" }, // 6a: 0110 0100 0110 1010 xxxx xxxx + {NEI, "PD,%b" }, // 6b: 0110 0100 0110 1011 xxxx xxxx + { }, // 6c: 0110 0100 0110 1100 xxxx xxxx + {NEI, "PF,%b" }, // 6d: 0110 0100 0110 1101 xxxx xxxx + {NEI, "MKH,%b" }, // 6e: 0110 0100 0110 1110 xxxx xxxx + {NEI, "MKL,%b" }, // 6f: 0110 0100 0110 1111 xxxx xxxx + + {SBI, "PA,%b" }, // 70: 0110 0100 0111 0000 xxxx xxxx + {SBI, "PB,%b" }, // 71: 0110 0100 0111 0001 xxxx xxxx + {SBI, "PC,%b" }, // 72: 0110 0100 0111 0010 xxxx xxxx + {SBI, "PD,%b" }, // 73: 0110 0100 0111 0011 xxxx xxxx + { }, // 74: 0110 0100 0111 0100 xxxx xxxx + {SBI, "PF,%b" }, // 75: 0110 0100 0111 0101 xxxx xxxx + {SBI, "MKH,%b" }, // 76: 0110 0100 0111 0110 xxxx xxxx + {SBI, "MKL,%b" }, // 77: 0110 0100 0111 0111 xxxx xxxx + {EQI, "PA,%b" }, // 78: 0110 0100 0111 1000 xxxx xxxx + {EQI, "PB,%b" }, // 79: 0110 0100 0111 1001 xxxx xxxx + {EQI, "PC,%b" }, // 7a: 0110 0100 0111 1010 xxxx xxxx + {EQI, "PD,%b" }, // 7b: 0110 0100 0111 1011 xxxx xxxx + { }, // 7c: 0110 0100 0111 1100 xxxx xxxx + {EQI, "PF,%b" }, // 7d: 0110 0100 0111 1101 xxxx xxxx + {EQI, "MKH,%b" }, // 7e: 0110 0100 0111 1110 xxxx xxxx + {EQI, "MKL,%b" }, // 7f: 0110 0100 0111 1111 xxxx xxxx + + { }, // 80: 0110 0100 1000 0000 xxxx xxxx + {MVI, "SMH,%b" }, // 81: 0110 0100 1000 0001 xxxx xxxx + { }, // 82: 0110 0100 1000 0010 xxxx xxxx + {MVI, "EOM,%b" }, // 83: 0110 0100 1000 0011 xxxx xxxx + { }, // 84: 0110 0100 1000 0100 xxxx xxxx + {MVI, "TMM,%b" }, // 85: 0110 0100 1000 0101 xxxx xxxx + { }, // 86: 0110 0100 1000 0110 xxxx xxxx + { }, // 87: 0110 0100 1000 0111 xxxx xxxx + { }, // 88: 0110 0100 1000 1000 xxxx xxxx + {ANI, "SMH,%b" }, // 89: 0110 0100 1000 1001 xxxx xxxx + { }, // 8a: 0110 0100 1000 1010 xxxx xxxx + {ANI, "EOM,%b" }, // 8b: 0110 0100 1000 1011 xxxx xxxx + { }, // 8c: 0110 0100 1000 1100 xxxx xxxx + {ANI, "TMM,%b" }, // 8d: 0110 0100 1000 1101 xxxx xxxx + { }, // 8e: 0110 0100 1000 1110 xxxx xxxx + { }, // 8f: 0110 0100 1000 1111 xxxx xxxx + + { }, // 90: 0110 0100 1001 0000 xxxx xxxx + {XRI, "SMH,%b" }, // 91: 0110 0100 1001 0001 xxxx xxxx + { }, // 92: 0110 0100 1001 0010 xxxx xxxx + {XRI, "EOM,%b" }, // 93: 0110 0100 1001 0011 xxxx xxxx + { }, // 94: 0110 0100 1001 0100 xxxx xxxx + {XRI, "TMM,%b" }, // 95: 0110 0100 1001 0101 xxxx xxxx + { }, // 96: 0110 0100 1001 0110 xxxx xxxx + { }, // 97: 0110 0100 1001 0111 xxxx xxxx + { }, // 98: 0110 0100 1001 1000 xxxx xxxx + {ORI, "SMH,%b" }, // 99: 0110 0100 1001 1001 xxxx xxxx + { }, // 9a: 0110 0100 1001 1010 xxxx xxxx + {ORI, "EOM,%b" }, // 9b: 0110 0100 1001 1011 xxxx xxxx + { }, // 9c: 0110 0100 1001 1100 xxxx xxxx + {ORI, "TMM,%b" }, // 9d: 0110 0100 1001 1101 xxxx xxxx + { }, // 9e: 0110 0100 1001 1110 xxxx xxxx + { }, // 9f: 0110 0100 1001 1111 xxxx xxxx + + { }, // a0: 0110 0100 1010 0000 xxxx xxxx + {ADINC, "SMH,%b" }, // a1: 0110 0100 1010 0001 xxxx xxxx + { }, // a2: 0110 0100 1010 0010 xxxx xxxx + {ADINC, "EOM,%b" }, // a3: 0110 0100 1010 0011 xxxx xxxx + { }, // a4: 0110 0100 1010 0100 xxxx xxxx + {ADINC, "TMM,%b" }, // a5: 0110 0100 1010 0101 xxxx xxxx + { }, // a6: 0110 0100 1010 0110 xxxx xxxx + { }, // a7: 0110 0100 1010 0111 xxxx xxxx + { }, // a8: 0110 0100 1010 1000 xxxx xxxx + {GTI, "SMH,%b" }, // a9: 0110 0100 1010 1001 xxxx xxxx + { }, // aa: 0110 0100 1010 1010 xxxx xxxx + {GTI, "EOM,%b" }, // ab: 0110 0100 1010 1011 xxxx xxxx + { }, // ac: 0110 0100 1010 1100 xxxx xxxx + {GTI, "TMM,%b" }, // ad: 0110 0100 1010 1101 xxxx xxxx + {GTI, "PT,%b" }, // ae: 0110 0100 1010 1110 xxxx xxxx + { }, // af: 0110 0100 1010 1111 xxxx xxxx + + { }, // b0: 0110 0100 1011 0000 xxxx xxxx + {SUINB, "SMH,%b" }, // b1: 0110 0100 1011 0001 xxxx xxxx + { }, // b2: 0110 0100 1011 0010 xxxx xxxx + {SUINB, "EOM,%b" }, // b3: 0110 0100 1011 0011 xxxx xxxx + { }, // b4: 0110 0100 1011 0100 xxxx xxxx + {SUINB, "TMM,%b" }, // b5: 0110 0100 1011 0101 xxxx xxxx + { }, // b6: 0110 0100 1011 0110 xxxx xxxx + { }, // b7: 0110 0100 1011 0111 xxxx xxxx + { }, // b8: 0110 0100 1011 1000 xxxx xxxx + {LTI, "SMH,%b" }, // b9: 0110 0100 1011 1001 xxxx xxxx + { }, // ba: 0110 0100 1011 1010 xxxx xxxx + {LTI, "EOM,%b" }, // bb: 0110 0100 1011 1011 xxxx xxxx + { }, // bc: 0110 0100 1011 1100 xxxx xxxx + {LTI, "TMM,%b" }, // bd: 0110 0100 1011 1101 xxxx xxxx + {LTI, "PT,%b" }, // be: 0110 0100 1011 1110 xxxx xxxx + { }, // bf: 0110 0100 1011 1111 xxxx xxxx + + { }, // c0: 0110 0100 1100 0000 xxxx xxxx + {ADI, "SMH,%b" }, // c1: 0110 0100 1100 0001 xxxx xxxx + { }, // c2: 0110 0100 1100 0010 xxxx xxxx + {ADI, "EOM,%b" }, // c3: 0110 0100 1100 0011 xxxx xxxx + { }, // c4: 0110 0100 1100 0100 xxxx xxxx + {ADI, "TMM,%b" }, // c5: 0110 0100 1100 0101 xxxx xxxx + { }, // c6: 0110 0100 1100 0110 xxxx xxxx + { }, // c7: 0110 0100 1100 0111 xxxx xxxx + { }, // c8: 0110 0100 1100 1000 xxxx xxxx + {ONI, "SMH,%b" }, // c9: 0110 0100 1100 1001 xxxx xxxx + { }, // ca: 0110 0100 1100 1010 xxxx xxxx + {ONI, "EOM,%b" }, // cb: 0110 0100 1100 1011 xxxx xxxx + { }, // cc: 0110 0100 1100 1100 xxxx xxxx + {ONI, "TMM,%b" }, // cd: 0110 0100 1100 1101 xxxx xxxx + {ONI, "PT,%b" }, // ce: 0110 0100 1100 1110 xxxx xxxx + { }, // cf: 0110 0100 1100 1111 xxxx xxxx + + { }, // d0: 0110 0100 1101 0000 xxxx xxxx + {ACI, "SMH,%b" }, // d1: 0110 0100 1101 0001 xxxx xxxx + { }, // d2: 0110 0100 1101 0010 xxxx xxxx + {ACI, "EOM,%b" }, // d3: 0110 0100 1101 0011 xxxx xxxx + { }, // d4: 0110 0100 1101 0100 xxxx xxxx + {ACI, "TMM,%b" }, // d5: 0110 0100 1101 0101 xxxx xxxx + { }, // d6: 0110 0100 1101 0110 xxxx xxxx + { }, // d7: 0110 0100 1101 0111 xxxx xxxx + { }, // d8: 0110 0100 1101 1000 xxxx xxxx + {OFFI, "SMH,%b" }, // d9: 0110 0100 1101 1001 xxxx xxxx + { }, // da: 0110 0100 1101 1010 xxxx xxxx + {OFFI, "EOM,%b" }, // db: 0110 0100 1101 1011 xxxx xxxx + { }, // dc: 0110 0100 1101 1100 xxxx xxxx + {OFFI, "TMM,%b" }, // dd: 0110 0100 1101 1101 xxxx xxxx + {OFFI, "PT,%b" }, // de: 0110 0100 1101 1110 xxxx xxxx + { }, // df: 0110 0100 1101 1111 xxxx xxxx + + { }, // e0: 0110 0100 1110 0000 xxxx xxxx + {SUI, "SMH,%b" }, // e1: 0110 0100 1110 0001 xxxx xxxx + { }, // e2: 0110 0100 1110 0010 xxxx xxxx + {SUI, "EOM,%b" }, // e3: 0110 0100 1110 0011 xxxx xxxx + { }, // e4: 0110 0100 1110 0100 xxxx xxxx + {SUI, "TMM,%b" }, // e5: 0110 0100 1110 0101 xxxx xxxx + { }, // e6: 0110 0100 1110 0110 xxxx xxxx + { }, // e7: 0110 0100 1110 0111 xxxx xxxx + { }, // e8: 0110 0100 1110 1000 xxxx xxxx + {NEI, "SMH,%b" }, // e9: 0110 0100 1110 1001 xxxx xxxx + { }, // ea: 0110 0100 1110 1010 xxxx xxxx + {NEI, "EOM,%b" }, // eb: 0110 0100 1110 1011 xxxx xxxx + { }, // ec: 0110 0100 1110 1100 xxxx xxxx + {NEI, "TMM,%b" }, // ed: 0110 0100 1110 1101 xxxx xxxx + {NEI, "PT,%b" }, // ee: 0110 0100 1110 1110 xxxx xxxx + { }, // ef: 0110 0100 1110 1111 xxxx xxxx + + { }, // f0: 0110 0100 1111 0000 xxxx xxxx + {SBI, "SMH,%b" }, // f1: 0110 0100 1111 0001 xxxx xxxx + { }, // f2: 0110 0100 1111 0010 xxxx xxxx + {SBI, "EOM,%b" }, // f3: 0110 0100 1111 0011 xxxx xxxx + { }, // f4: 0110 0100 1111 0100 xxxx xxxx + {SBI, "TMM,%b" }, // f5: 0110 0100 1111 0101 xxxx xxxx + { }, // f6: 0110 0100 1111 0110 xxxx xxxx + { }, // f7: 0110 0100 1111 0111 xxxx xxxx + { }, // f8: 0110 0100 1111 1000 xxxx xxxx + {EQI, "SMH,%b" }, // f9: 0110 0100 1111 1001 xxxx xxxx + { }, // fa: 0110 0100 1111 1010 xxxx xxxx + {EQI, "EOM,%b" }, // fb: 0110 0100 1111 1011 xxxx xxxx + { }, // fc: 0110 0100 1111 1100 xxxx xxxx + {EQI, "TMM,%b" }, // fd: 0110 0100 1111 1101 xxxx xxxx + {EQI, "PT,%b" }, // fe: 0110 0100 1111 1110 xxxx xxxx + { } // ff: 0110 0100 1111 1111 xxxx xxxx +}; + +const upd7810_base_disassembler::dasm_s upd7807_disassembler::XX_7807[256] = { {NOP, nullptr }, // 00: 0000 0000 {LDAW, "%a" }, // 01: 0000 0001 oooo oooo @@ -4020,7 +3827,7 @@ const dasm_s dasm_s::XX_7807[256] = * *********************************************************/ -const dasm_s dasm_s::d48_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d48_7801[256] = { // 0x00 - 0x3F { SKIT, "F0" }, { SKIT, "FT" }, { SKIT, "F1" }, { SKIT, "F2" }, { SKIT, "FS" }, { }, { }, { }, @@ -4106,7 +3913,7 @@ const dasm_s dasm_s::d48_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d4C_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d4C_7801[256] = { // 0x00 - 0x3F { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, { IN, nullptr }, @@ -4192,7 +3999,7 @@ const dasm_s dasm_s::d4C_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d4D_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d4D_7801[256] = { // 0x00 - 0x3F { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, { OUT, nullptr }, @@ -4278,7 +4085,7 @@ const dasm_s dasm_s::d4D_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d60_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d60_7801[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4364,7 +4171,7 @@ const dasm_s dasm_s::d60_7801[256] = { { EQA, "A,D" }, { EQA, "A,E" }, { EQA, "A,H" }, { EQA, "A,L" } }; -const dasm_s dasm_s::d64_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d64_7801[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4450,7 +4257,7 @@ const dasm_s dasm_s::d64_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d70_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d70_7801[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4536,7 +4343,7 @@ const dasm_s dasm_s::d70_7801[256] = { { EQAX, "DE+" }, { EQAX, "HL+" }, { EQAX, "DE-" }, { EQAX, "HL-" }, }; -const dasm_s dasm_s::d74_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::d74_7801[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4622,7 +4429,7 @@ const dasm_s dasm_s::d74_7801[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::XX_7801[256] = { +const upd7810_base_disassembler::dasm_s upd7801_disassembler::XX_7801[256] = { // 0x00 - 0x3F { NOP, nullptr }, { HALT, nullptr }, { INX, "SP" }, { DCX, "SP" }, { LXI, "SP,%w" }, { ANIW, "%a,%b" }, { }, { ANI, "A,%b" }, @@ -4714,7 +4521,7 @@ const dasm_s dasm_s::XX_7801[256] = { * *********************************************************/ -const dasm_s dasm_s::d48_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d48_78c05[256] = { // 0x00 - 0x3F { SKIT, "F0" }, { SKIT, "FT" }, { SKIT, "F1" }, { }, // TODO: PDF doesn't mention SKIT and SK { SKIT, "FS" }, { }, { }, { }, @@ -4800,7 +4607,7 @@ const dasm_s dasm_s::d48_78c05[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d4C_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d4C_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4867,7 +4674,7 @@ const dasm_s dasm_s::d4C_78c05[256] = { // 0xC0 - 0xFF { MOV, "A,PA" }, { MOV, "A,PB" }, { MOV, "A,PC" }, { MOV, "A,MK" }, { MOV, "A,MB" }, { MOV, "A,MC" }, { MOV, "A,TM0" }, { MOV, "A,TM1" }, - { MOV, "A,S" }, { }, { }, { }, // TODO: Figure out what regsiter C9 indicates + { MOV, "A,S" }, { }, { }, { }, // TODO: Figure out what register C9 indicates { }, { }, { }, { }, { }, { }, { }, { }, @@ -4886,7 +4693,7 @@ const dasm_s dasm_s::d4C_78c05[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d4D_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d4D_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -4972,7 +4779,7 @@ const dasm_s dasm_s::d4D_78c05[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d60_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d60_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -5058,7 +4865,7 @@ const dasm_s dasm_s::d60_78c05[256] = { { EQA, "A,D" }, { EQA, "A,E" }, { EQA, "A,H" }, { EQA, "A,L" } }; -const dasm_s dasm_s::d64_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d64_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -5144,7 +4951,7 @@ const dasm_s dasm_s::d64_78c05[256] = { { }, { }, { }, { } }; -const dasm_s dasm_s::d70_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d70_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -5230,7 +5037,7 @@ const dasm_s dasm_s::d70_78c05[256] = { { EQAX, "DE+" }, { EQAX, "HL+" }, { EQAX, "DE-" }, { EQAX, "HL-" }, }; -const dasm_s dasm_s::d74_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::d74_78c05[256] = { // 0x00 - 0x3F { }, { }, { }, { }, { }, { }, { }, { }, @@ -5316,7 +5123,7 @@ const dasm_s dasm_s::d74_78c05[256] = { { }, { }, { }, { }, }; -const dasm_s dasm_s::XX_78c05[256] = { +const upd7810_base_disassembler::dasm_s upd78c05_disassembler::XX_78c05[256] = { // 0x00 - 0x3F { NOP, nullptr }, { HALT, nullptr }, { INX, "SP" }, { DCX, "SP" }, { LXI, "SP,%w" }, { ANIW, "%a,%b" }, { }, { ANI, "A,%b" }, @@ -5404,7 +5211,7 @@ const dasm_s dasm_s::XX_78c05[256] = { // register names for bit manipulation instructions -const char *const regname[32] = +const char *const upd7810_base_disassembler::regname[32] = { "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", "illegal", @@ -5416,17 +5223,17 @@ const char *const regname[32] = "illegal", "TMM", "PT", "illegal" }; -offs_t Dasm( std::ostream &stream, offs_t pc, const dasm_s (&dasmXX)[256], const uint8_t *oprom, const uint8_t *opram, bool is_7810 ) +offs_t upd7810_base_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - unsigned idx = 0; - const uint8_t op = oprom[idx++]; - const dasm_s *desc = &dasmXX[op]; + offs_t idx = pc; + const uint8_t op = opcodes.r8(idx++); + const dasm_s *desc = &m_dasmXX[op]; if (desc->is_prefix()) - desc = &desc->prefix_get(oprom[idx++]); + desc = &desc->prefix_get(opcodes.r8(idx++)); util::stream_format(stream, "%-8.8s", desc->name()); - uint32_t flags = desc->is_call() ? DASMFLAG_STEP_OVER : desc->is_return() ? DASMFLAG_STEP_OUT : 0; + uint32_t flags = desc->is_call() ? STEP_OVER : desc->is_return() ? STEP_OUT : 0; uint8_t op2; int offset; uint16_t ea; @@ -5439,28 +5246,28 @@ offs_t Dasm( std::ostream &stream, offs_t pc, const dasm_s (&dasmXX)[256], const switch (*a) { case 'a': /* address V * 256 + offset */ - op2 = opram[idx++]; + op2 = params.r8(idx++); util::stream_format(stream, "VV:%02X", op2); break; case 'b': /* immediate byte */ - util::stream_format(stream, "$%02X", opram[idx++]); + util::stream_format(stream, "$%02X", params.r8(idx++)); break; case 'w': /* immediate word */ - ea = opram[idx++]; - ea += opram[idx++] << 8; + ea = params.r8(idx++); + ea += params.r8(idx++) << 8; util::stream_format(stream, "$%04X", ea); break; case 'd': /* JRE address */ - op2 = oprom[idx++]; + op2 = opcodes.r8(idx++); offset = (op & 1) ? -(256 - op2): + op2; util::stream_format(stream, "$%04X", ( pc + idx + offset ) & 0xFFFF ); break; case 't': /* CALT address */ - ea = 0x80 + 2 * (op & (is_7810 ? 0x1f : 0x3f)); + ea = 0x80 + 2 * (op & (m_is_7810 ? 0x1f : 0x3f)); util::stream_format(stream, "($%04X)", ea); break; case 'f': /* CALF address */ - op2 = oprom[idx++]; + op2 = opcodes.r8(idx++); ea = 0x800 + 0x100 * (op & 0x07) + op2; util::stream_format(stream, "$%04X", ea); break; @@ -5469,7 +5276,7 @@ offs_t Dasm( std::ostream &stream, offs_t pc, const dasm_s (&dasmXX)[256], const util::stream_format(stream, "$%04X", ( pc + idx + offset ) & 0xFFFF ); break; case 'i': /* bit manipulation */ - op2 = oprom[idx++]; + op2 = opcodes.r8(idx++); util::stream_format(stream, "%s,%d", regname[op2 & 0x1f], op2 >> 5); break; default: @@ -5480,27 +5287,30 @@ offs_t Dasm( std::ostream &stream, offs_t pc, const dasm_s (&dasmXX)[256], const stream << *a; } - return idx | flags | DASMFLAG_SUPPORTED; + return (idx - pc) | flags | SUPPORTED; } -} // anonymous namespace +upd7810_base_disassembler::upd7810_base_disassembler(const dasm_s *table, bool is_7810) : m_is_7810(is_7810), m_dasmXX(table) +{ +} + +uint32_t upd7810_base_disassembler::opcode_alignment() const +{ + return 1; +} -CPU_DISASSEMBLE( upd7810 ) +upd7810_disassembler::upd7810_disassembler() : upd7810_base_disassembler(XX_7810, true) { - return Dasm( stream, pc, dasm_s::XX_7810, oprom, opram, true ); } -CPU_DISASSEMBLE( upd7807 ) +upd7807_disassembler::upd7807_disassembler() : upd7810_base_disassembler(XX_7807, true) { - return Dasm( stream, pc, dasm_s::XX_7807, oprom, opram, true ); } -CPU_DISASSEMBLE( upd7801 ) +upd7801_disassembler::upd7801_disassembler() : upd7810_base_disassembler(XX_7801, false) { - return Dasm( stream, pc, dasm_s::XX_7801, oprom, opram, false ); } -CPU_DISASSEMBLE( upd78c05 ) +upd78c05_disassembler::upd78c05_disassembler() : upd7810_base_disassembler(XX_78c05, false) { - return Dasm( stream, pc, dasm_s::XX_78c05, oprom, opram, false ); } diff --git a/src/devices/cpu/upd7810/upd7810_dasm.h b/src/devices/cpu/upd7810/upd7810_dasm.h new file mode 100644 index 00000000000..a367ab24a48 --- /dev/null +++ b/src/devices/cpu/upd7810/upd7810_dasm.h @@ -0,0 +1,291 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * Portable uPD7810/11, 7810H/11H, 78C10/C11/C14 disassembler + * + * NS20030112: added 7807. + * + *****************************************************************************/ + +#ifndef MAME_CPU_UPD7810_UPD7810DASM_H +#define MAME_CPU_UPD7810_UPD7810DASM_H + +#pragma once + +class upd7810_base_disassembler : public util::disasm_interface +{ +public: + struct dasm_s { + public: + dasm_s(); + dasm_s(uint8_t t, const char *a); + dasm_s(const dasm_s (&a)[256]); + + const char *name() const; + const char *args() const; + + bool is_prefix() const; + bool is_call() const; + bool is_return() const; + + const dasm_s &prefix_get(uint8_t op) const; + + uint8_t m_token; + const void *m_args; + + static const char *const token_names[]; + }; + + enum + { + prefix = 0, + illegal, + ACI, + ADC, + ADCW, + ADCX, + ADD, + ADDNC, + ADDNCW, + ADDNCX, + ADDW, + ADDX, + ADI, + ADINC, + ANA, + ANAW, + ANAX, + AND, + ANI, + ANIW, + BIT, + BLOCK, + CALB, + CALF, + CALL, + CALT, + CLC, + CLR, /* 7807 */ + CMC, /* 7807 */ + DAA, + DADC, + DADD, + DADDNC, + DAN, + DCR, + DCRW, + DCX, + DEQ, + DGT, + DI, + DIV, + DLT, + DMOV, + DNE, + DOFF, + DON, + DOR, + DRLL, + DRLR, + DSBB, + DSLL, + DSLR, + DSUB, + DSUBNB, + DXR, + EADD, + EI, + EQA, + EQAW, + EQAX, + EQI, + EQIW, + ESUB, + EX, /* 7801 */ + EXA, + EXH, + EXX, + EXR, /* 7807 */ + GTA, + GTAW, + GTAX, + GTI, + GTIW, + HALT, + IN, /* 7801 */ + INR, + INRW, + INX, + JB, + JEA, + JMP, + JR, + JRE, + LBCD, + LDAW, + LDAX, + LDEAX, + LDED, + LHLD, + LSPD, + LTA, + LTAW, + LTAX, + LTI, + LTIW, + LXI, + MOV, + MUL, + MVI, + MVIW, + MVIX, + NEA, + NEAW, + NEAX, + NEGA, + NEI, + NEIW, + NOP, + NOT, /* 7807 */ + OFFA, + OFFAW, + OFFAX, + OFFI, + OFFIW, + ONA, + ONAW, + ONAX, + ONI, + ONIW, + OR, /* 7807 */ + ORA, + ORAW, + ORAX, + ORI, + ORIW, + OUT, /* 7801 */ + PER, /* 7801 */ + PEX, /* 7801 */ + POP, + PUSH, + RET, + RETI, + RETS, + RLD, + RLL, + RLR, + RRD, + SBB, + SBBW, + SBBX, + SBCD, + SBI, + SDED, + SETB, /* 7807 */ + SHLD, + SIO, /* 7801 */ + SK, + SKIT, + SKN, + SKNIT, + SLL, + SLLC, + SLR, + SLRC, + SOFTI, + SSPD, + STAW, + STAX, + STC, + STEAX, + STM, /* 7801 */ + STOP, + SUB, + SUBNB, + SUBNBW, + SUBNBX, + SUBW, + SUBX, + SUI, + SUINB, + TABLE, + XOR, /* 7807 */ + XRA, + XRAW, + XRAX, + XRI + }; + + upd7810_base_disassembler(const dasm_s *table, bool is_7810); + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + + static const char *const regname[32]; + static const dasm_s d60[256]; + static const dasm_s d70[256]; + static const dasm_s d74[256]; + + bool m_is_7810; + const dasm_s *m_dasmXX; +}; + +class upd7810_disassembler : public upd7810_base_disassembler +{ +public: + static const dasm_s XX_7810[256]; + static const dasm_s d48_7810[256]; + static const dasm_s d4C_7810[256]; + static const dasm_s d4D_7810[256]; + static const dasm_s d64_7810[256]; + + upd7810_disassembler(); + virtual ~upd7810_disassembler() = default; +}; + +class upd7807_disassembler : public upd7810_base_disassembler +{ +public: + static const dasm_s XX_7807[256]; + static const dasm_s d48_7807[256]; + static const dasm_s d4C_7807[256]; + static const dasm_s d4D_7807[256]; + static const dasm_s d64_7807[256]; + + upd7807_disassembler(); + virtual ~upd7807_disassembler() = default; +}; + +class upd7801_disassembler : public upd7810_base_disassembler +{ +public: + static const dasm_s XX_7801[256]; + static const dasm_s d48_7801[256]; + static const dasm_s d4C_7801[256]; + static const dasm_s d4D_7801[256]; + static const dasm_s d60_7801[256]; + static const dasm_s d64_7801[256]; + static const dasm_s d70_7801[256]; + static const dasm_s d74_7801[256]; + + upd7801_disassembler(); + virtual ~upd7801_disassembler() = default; +}; + +class upd78c05_disassembler : public upd7810_base_disassembler +{ +public: + static const dasm_s XX_78c05[256]; + static const dasm_s d48_78c05[256]; + static const dasm_s d4C_78c05[256]; + static const dasm_s d4D_78c05[256]; + static const dasm_s d60_78c05[256]; + static const dasm_s d64_78c05[256]; + static const dasm_s d70_78c05[256]; + static const dasm_s d74_78c05[256]; + + upd78c05_disassembler(); + virtual ~upd78c05_disassembler() = default; +}; + +#endif diff --git a/src/devices/cpu/v30mz/v30mz.cpp b/src/devices/cpu/v30mz/v30mz.cpp index 718c07a2ec8..de393ea5f9f 100644 --- a/src/devices/cpu/v30mz/v30mz.cpp +++ b/src/devices/cpu/v30mz/v30mz.cpp @@ -44,6 +44,7 @@ #include "emu.h" #include "v30mz.h" +#include "cpu/nec/necdasm.h" #include "debugger.h" @@ -146,7 +147,7 @@ device_memory_interface::space_config_vector v30mz_cpu_device::memory_space_conf void v30mz_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_regs.w)); @@ -1304,10 +1305,9 @@ void v30mz_cpu_device::execute_set_input( int inptnum, int state ) } -offs_t v30mz_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *v30mz_cpu_device::create_disassembler() { - extern CPU_DISASSEMBLE( nec ); - return CPU_DISASSEMBLE_NAME(nec)(this, stream, pc, oprom, opram, options); + return new nec_disassembler; } diff --git a/src/devices/cpu/v30mz/v30mz.h b/src/devices/cpu/v30mz/v30mz.h index 1b8665fd0ea..7afee5907b0 100644 --- a/src/devices/cpu/v30mz/v30mz.h +++ b/src/devices/cpu/v30mz/v30mz.h @@ -47,9 +47,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 7; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; void interrupt(int int_num); @@ -189,7 +187,7 @@ protected: uint8_t m_fire_trap; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; int m_icount; diff --git a/src/devices/cpu/v60/v60.cpp b/src/devices/cpu/v60/v60.cpp index dbe8ed08599..7891f5daa25 100644 --- a/src/devices/cpu/v60/v60.cpp +++ b/src/devices/cpu/v60/v60.cpp @@ -75,6 +75,7 @@ Package: 132-pin PGA, 200-pin QFP #include "emu.h" #include "v60.h" +#include "v60d.h" #include "debugger.h" DEFINE_DEVICE_TYPE(V60, v60_device, "v60", "V60") @@ -115,17 +116,9 @@ device_memory_interface::space_config_vector v60_device::memory_space_config() c } -offs_t v60_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *v60_device::create_disassembler() { - extern CPU_DISASSEMBLE( v60 ); - return CPU_DISASSEMBLE_NAME(v60)(this, stream, pc, oprom, opram, options); -} - - -offs_t v70_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( v70 ); - return CPU_DISASSEMBLE_NAME(v70)(this, stream, pc, oprom, opram, options); + return new v60_disassembler; } @@ -428,7 +421,7 @@ void v60_device::device_start() m_moddim = 0; m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); save_item(NAME(m_fetch_xor)); diff --git a/src/devices/cpu/v60/v60.h b/src/devices/cpu/v60/v60.h index b891630f048..727972d7d99 100644 --- a/src/devices/cpu/v60/v60.h +++ b/src/devices/cpu/v60/v60.h @@ -110,9 +110,7 @@ protected: virtual void state_export(const device_state_entry &entry) override; // device_disasm_interface overrides - virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 22; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; private: typedef uint32_t (v60_device::*am_func)(); @@ -164,7 +162,7 @@ private: uint8_t m_irq_line; uint8_t m_nmi_line; address_space *m_program; - direct_read_data * m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint32_t m_PPC; int m_icount; @@ -777,9 +775,6 @@ class v70_device : public v60_device public: // construction/destruction v70_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -protected: - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; }; diff --git a/src/devices/cpu/v60/v60d.cpp b/src/devices/cpu/v60/v60d.cpp index 70fcdab8296..2a14f65436f 100644 --- a/src/devices/cpu/v60/v60d.cpp +++ b/src/devices/cpu/v60/v60d.cpp @@ -2,11 +2,10 @@ // copyright-holders:Farfetch'd, R. Belmont #include "emu.h" -#include "debugger.h" -#include "v60.h" +#include "v60d.h" // Register names -static const char *const v60_reg_names[69] = { +const char *const v60_disassembler::v60_reg_names[69] = { "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", @@ -26,39 +25,19 @@ static const char *const v60_reg_names[69] = { "ADTMR1","Reserved","Reserved","Reserved" }; -static const uint8_t *rombase; -static offs_t pcbase; - -#define readop(a) rombase[(a) - pcbase] - -static signed char read8(unsigned pc) -{ - return readop(pc); -} - -static signed short read16(unsigned pc) -{ - return readop(pc) | (readop(pc+1) << 8); -} - -static signed int read32(unsigned pc) -{ - return readop(pc) | (readop(pc+1) << 8)| (readop(pc+2) << 16)| (readop(pc+3) << 24); -} - -static void out_AM_Register(int reg, std::ostream &stream) +void v60_disassembler::out_AM_Register(int reg, std::ostream &stream) { stream << v60_reg_names[reg]; } -static void out_AM_RegisterIndirect(int reg, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_RegisterIndirect(int reg, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "[%s]", v60_reg_names[reg]); } -static void out_AM_RegisterIndirectIndexed(int rn, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_RegisterIndirectIndexed(int rn, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@[%s]", v60_reg_names[rx], v60_reg_names[rn]); @@ -67,21 +46,21 @@ static void out_AM_RegisterIndirectIndexed(int rn, int rx, int opsize, std::ostr } -static void out_AM_Autoincrement(int reg, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_Autoincrement(int reg, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "[%s+]", v60_reg_names[reg]); } -static void out_AM_Autodecrement(int reg, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_Autodecrement(int reg, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "[-%s]", v60_reg_names[reg]); } -static void out_AM_Displacement(int reg, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_Displacement(int reg, int disp, int opsize, std::ostream &stream) { util::stream_format(stream, "%s%X%s[%s]", disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp, @@ -89,7 +68,7 @@ static void out_AM_Displacement(int reg, int disp, int opsize, std::ostream &str v60_reg_names[reg]); } -static void out_AM_DisplacementIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DisplacementIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@%s%X[%s]", v60_reg_names[rx], disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp,v60_reg_names[rn]); @@ -97,12 +76,12 @@ static void out_AM_DisplacementIndexed(int rn, int rx, int disp, int opsize, std util::stream_format(stream, "%s%X[%s](%s)", disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp,v60_reg_names[rn], v60_reg_names[rx]); } -static void out_AM_PCDisplacement(unsigned pc, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDisplacement(offs_t pc, int disp, int opsize, std::ostream &stream) { util::stream_format(stream, "%X%s[PC]", pc+disp, opsize & 0x80 ? "@" : ""); } -static void out_AM_PCDisplacementIndexed(unsigned pc, int disp, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDisplacementIndexed(offs_t pc, int disp, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@%X[PC]", v60_reg_names[rx], pc+disp); @@ -110,7 +89,7 @@ static void out_AM_PCDisplacementIndexed(unsigned pc, int disp, int rx, int opsi util::stream_format(stream, "%X[PC](%s)", pc+disp, v60_reg_names[rx]); } -static void out_AM_DisplacementIndirect(int reg, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DisplacementIndirect(int reg, int disp, int opsize, std::ostream &stream) { util::stream_format(stream, "%s[%s%X[%s]]", opsize & 0x80 ? "@" : "", @@ -118,7 +97,7 @@ static void out_AM_DisplacementIndirect(int reg, int disp, int opsize, std::ostr v60_reg_names[reg]); } -static void out_AM_DisplacementIndirectIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DisplacementIndirectIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@[%s%X[%s]]", v60_reg_names[rx], disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp,v60_reg_names[rn]); @@ -126,12 +105,12 @@ static void out_AM_DisplacementIndirectIndexed(int rn, int rx, int disp, int ops util::stream_format(stream, "[%s%X[%s]](%s)", disp >= 0 ? "" : "-", disp >= 0 ? disp : -disp,v60_reg_names[rn], v60_reg_names[rx]); } -static void out_AM_PCDisplacementIndirect(unsigned pc, int disp, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDisplacementIndirect(offs_t pc, int disp, int opsize, std::ostream &stream) { util::stream_format(stream, "%s[%X[PC]]", opsize & 0x80 ? "@" : "", pc+disp); } -static void out_AM_PCDisplacementIndirectIndexed(unsigned pc, int disp, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDisplacementIndirectIndexed(offs_t pc, int disp, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@[%X[PC]]", v60_reg_names[rx], pc+disp); @@ -139,7 +118,7 @@ static void out_AM_PCDisplacementIndirectIndexed(unsigned pc, int disp, int rx, util::stream_format(stream, "[%X[PC]](%s)", pc+disp, v60_reg_names[rx]); } -static void out_AM_DoubleDisplacement(int reg, int disp2, int disp1, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DoubleDisplacement(int reg, int disp2, int disp1, int opsize, std::ostream &stream) { util::stream_format(stream, "%s%X%s[%s%X[%s]]", disp1 >= 0 ? "" : "-", disp1 >= 0 ? disp1 : -disp1, @@ -148,7 +127,7 @@ static void out_AM_DoubleDisplacement(int reg, int disp2, int disp1, int opsize, v60_reg_names[reg]); } -static void out_AM_PCDoubleDisplacement(unsigned pc, int disp2, int disp1, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_PCDoubleDisplacement(offs_t pc, int disp2, int disp1, int opsize, std::ostream &stream) { util::stream_format(stream, "%s%X%s[%X[PC]]", disp1 >= 0 ? "" : "-", disp1 >= 0 ? disp1 : -disp1, @@ -156,14 +135,14 @@ static void out_AM_PCDoubleDisplacement(unsigned pc, int disp2, int disp1, int o disp2 + pc); } -static void out_AM_DirectAddress(unsigned addr, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DirectAddress(unsigned addr, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "%X", addr); } -static void out_AM_DirectAddressIndexed(unsigned addr, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DirectAddressIndexed(unsigned addr, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@%X", v60_reg_names[rx], addr); @@ -171,14 +150,14 @@ static void out_AM_DirectAddressIndexed(unsigned addr, int rx, int opsize, std:: util::stream_format(stream, "%X(%s)", addr, v60_reg_names[rx]); } -static void out_AM_DirectAddressDeferred(unsigned addr, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DirectAddressDeferred(unsigned addr, int opsize, std::ostream &stream) { if(opsize & 0x80) stream << '@'; util::stream_format(stream, "[%X]", addr); } -static void out_AM_DirectAddressDeferredIndexed(unsigned addr, int rx, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_DirectAddressDeferredIndexed(unsigned addr, int rx, int opsize, std::ostream &stream) { if(opsize & 0x80) util::stream_format(stream, "%s@[%X]", v60_reg_names[rx], addr); @@ -186,7 +165,7 @@ static void out_AM_DirectAddressDeferredIndexed(unsigned addr, int rx, int opsiz util::stream_format(stream, "[%X](%s)", addr, v60_reg_names[rx]); } -static void out_AM_Immediate(unsigned value, int opsize, std::ostream &stream) +void v60_disassembler::out_AM_Immediate(unsigned value, int opsize, std::ostream &stream) { if(opsize == 0) value &= 0xff; @@ -196,21 +175,21 @@ static void out_AM_Immediate(unsigned value, int opsize, std::ostream &stream) util::stream_format(stream, "#%X", value); } -static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream &stream) +u32 v60_disassembler::decode_AM(unsigned ipc, offs_t pc, int m, int opsize, const data_buffer &opcodes, std::ostream &stream) { - unsigned char mod = readop(pc); + unsigned char mod = opcodes.r8(pc); if(m) { switch(mod>>5) { case 0: // Double displacement (8 bit) - out_AM_DoubleDisplacement(mod&0x1F, read8(pc+1), read8(pc+2), opsize, stream); + out_AM_DoubleDisplacement(mod&0x1F, opcodes.r8(pc+1), opcodes.r8(pc+2), opsize, stream); return 3; case 1: // Double displacement (16 bit) - out_AM_DoubleDisplacement(mod&0x1F, read16(pc+1), read16(pc+3), opsize, stream); + out_AM_DoubleDisplacement(mod&0x1F, opcodes.r16(pc+1), opcodes.r16(pc+3), opsize, stream); return 5; case 2: // Double displacement (32 bit) - out_AM_DoubleDisplacement(mod&0x1F, read32(pc+1), read32(pc+5), opsize, stream); + out_AM_DoubleDisplacement(mod&0x1F, opcodes.r32(pc+1), opcodes.r32(pc+5), opsize, stream); return 9; case 3: // Register @@ -226,69 +205,69 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream return 1; case 6: - switch (readop(pc+1)>>5) + switch (opcodes.r8(pc+1)>>5) { case 0: // Displacement indexed (8 bit) - out_AM_DisplacementIndexed(readop(pc+1)&0x1F, mod&0x1F, read8(pc+2), opsize, stream); + out_AM_DisplacementIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r8(pc+2), opsize, stream); return 3; case 1: // Displacement indexed (16 bit) - out_AM_DisplacementIndexed(readop(pc+1)&0x1F, mod&0x1F, read16(pc+2), opsize, stream); + out_AM_DisplacementIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r16(pc+2), opsize, stream); return 4; case 2: // Displacement indexed (32 bit) - out_AM_DisplacementIndexed(readop(pc+1)&0x1F, mod&0x1F, read32(pc+2), opsize, stream); + out_AM_DisplacementIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r32(pc+2), opsize, stream); return 6; case 3: // Register indirect indexed - out_AM_RegisterIndirectIndexed(readop(pc+1)&0x1F, mod&0x1F, opsize, stream); + out_AM_RegisterIndirectIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opsize, stream); return 2; case 4: // Displacement indirect indexed (8 bit) - out_AM_DisplacementIndirectIndexed(readop(pc+1)&0x1F, mod&0x1F, read8(pc+2), opsize, stream); + out_AM_DisplacementIndirectIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r8(pc+2), opsize, stream); return 3; case 5: // Displacement indirect indexed (16 bit) - out_AM_DisplacementIndirectIndexed(readop(pc+1)&0x1F, mod&0x1F, read16(pc+2), opsize, stream); + out_AM_DisplacementIndirectIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r16(pc+2), opsize, stream); return 4; case 6: // Displacement indirect indexed (32 bit) - out_AM_DisplacementIndirectIndexed(readop(pc+1)&0x1F, mod&0x1F, read32(pc+2), opsize, stream); + out_AM_DisplacementIndirectIndexed(opcodes.r8(pc+1)&0x1F, mod&0x1F, opcodes.r32(pc+2), opsize, stream); return 6; case 7: - switch (readop(pc+1)&0x1F) + switch (opcodes.r8(pc+1)&0x1F) { case 16: // PC Displacement Indexed (8 bit) - out_AM_PCDisplacementIndexed(ipc, read8(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndexed(ipc, opcodes.r8(pc+2), mod&0x1F, opsize, stream); return 3; case 17: // PC Displacement Indexed (16 bit) - out_AM_PCDisplacementIndexed(ipc, read16(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndexed(ipc, opcodes.r16(pc+2), mod&0x1F, opsize, stream); return 4; case 18: // PC Displacement Indexed (32 bit) - out_AM_PCDisplacementIndexed(ipc, read32(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndexed(ipc, opcodes.r32(pc+2), mod&0x1F, opsize, stream); return 6; case 19: // Direct Address Indexed - out_AM_DirectAddressIndexed(read32(pc+2), mod&0x1F, opsize, stream); + out_AM_DirectAddressIndexed(opcodes.r32(pc+2), mod&0x1F, opsize, stream); return 6; case 24: // PC Displacement Indirect Indexed(8 bit) - out_AM_PCDisplacementIndirectIndexed(ipc, read8(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndirectIndexed(ipc, opcodes.r8(pc+2), mod&0x1F, opsize, stream); return 3; case 25: // PC Displacement Indirect Indexed (16 bit) - out_AM_PCDisplacementIndirectIndexed(ipc, read16(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndirectIndexed(ipc, opcodes.r16(pc+2), mod&0x1F, opsize, stream); return 4; case 26: // PC Displacement Indirect Indexed (32 bit) - out_AM_PCDisplacementIndirectIndexed(ipc, read32(pc+2), mod&0x1F, opsize, stream); + out_AM_PCDisplacementIndirectIndexed(ipc, opcodes.r32(pc+2), mod&0x1F, opsize, stream); return 6; case 27: // Direct Address Deferred Indexed - out_AM_DirectAddressDeferredIndexed(read32(pc+2), mod&0x1F, opsize, stream); + out_AM_DirectAddressDeferredIndexed(opcodes.r32(pc+2), mod&0x1F, opsize, stream); return 6; default: @@ -308,15 +287,15 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream } else { switch(mod>>5) { case 0: // Displacement (8 bit) - out_AM_Displacement(mod&0x1F, read8(pc+1), opsize, stream); + out_AM_Displacement(mod&0x1F, opcodes.r8(pc+1), opsize, stream); return 2; case 1: // Displacement (16 bit) - out_AM_Displacement(mod&0x1F, read16(pc+1), opsize, stream); + out_AM_Displacement(mod&0x1F, opcodes.r16(pc+1), opsize, stream); return 3; case 2: // Displacement (32 bit) - out_AM_Displacement(mod&0x1F, read32(pc+1), opsize, stream); + out_AM_Displacement(mod&0x1F, opcodes.r32(pc+1), opsize, stream); return 5; case 3: // Register indirect @@ -324,15 +303,15 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream return 1; case 4: // Displacement indirect (8 bit) - out_AM_DisplacementIndirect(mod&0x1F, read8(pc+1), opsize, stream); + out_AM_DisplacementIndirect(mod&0x1F, opcodes.r8(pc+1), opsize, stream); return 2; case 5: // Displacement indirect (16 bit) - out_AM_DisplacementIndirect(mod&0x1F, read16(pc+1), opsize, stream); + out_AM_DisplacementIndirect(mod&0x1F, opcodes.r16(pc+1), opsize, stream); return 3; case 6: // Displacement indirect (32 bit) - out_AM_DisplacementIndirect(mod&0x1F, read32(pc+1), opsize, stream); + out_AM_DisplacementIndirect(mod&0x1F, opcodes.r32(pc+1), opsize, stream); return 5; case 7: @@ -357,34 +336,34 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream return 1; case 16: // PC Displacement (8 bit) - out_AM_PCDisplacement(ipc, read8(pc+1), opsize, stream); + out_AM_PCDisplacement(ipc, opcodes.r8(pc+1), opsize, stream); return 2; case 17: // PC Displacement (16 bit) - out_AM_PCDisplacement(ipc, read16(pc+1), opsize, stream); + out_AM_PCDisplacement(ipc, opcodes.r16(pc+1), opsize, stream); return 3; case 18: // PC Displacement (32 bit) - out_AM_PCDisplacement(ipc, read32(pc+1), opsize, stream); + out_AM_PCDisplacement(ipc, opcodes.r32(pc+1), opsize, stream); return 5; case 19: // Direct Address - out_AM_DirectAddress(read32(pc+1), opsize, stream); + out_AM_DirectAddress(opcodes.r32(pc+1), opsize, stream); return 5; case 20: switch(opsize&0x7F) { case 0: // Immediate (8 bit) - out_AM_Immediate(read8(pc+1), opsize, stream); + out_AM_Immediate(opcodes.r8(pc+1), opsize, stream); return 2; case 1: // Immediate (16 bit) - out_AM_Immediate(read16(pc+1), opsize, stream); + out_AM_Immediate(opcodes.r16(pc+1), opsize, stream); return 3; case 2: // Immediate (32 bit) - out_AM_Immediate(read32(pc+1), opsize, stream); + out_AM_Immediate(opcodes.r32(pc+1), opsize, stream); return 5; default: @@ -393,31 +372,31 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream } case 24: // PC Displacement Indirect (8 bit) - out_AM_PCDisplacementIndirect(ipc, read8(pc+1), opsize, stream); + out_AM_PCDisplacementIndirect(ipc, opcodes.r8(pc+1), opsize, stream); return 2; case 25: // PC Displacement Indirect (16 bit) - out_AM_PCDisplacementIndirect(ipc, read16(pc+1), opsize, stream); + out_AM_PCDisplacementIndirect(ipc, opcodes.r16(pc+1), opsize, stream); return 3; case 26: // PC Displacement Indirect (32 bit) - out_AM_PCDisplacementIndirect(ipc, read32(pc+1), opsize, stream); + out_AM_PCDisplacementIndirect(ipc, opcodes.r32(pc+1), opsize, stream); return 5; case 27: // Direct Address Deferred - out_AM_DirectAddressDeferred(read32(pc+1), opsize, stream); + out_AM_DirectAddressDeferred(opcodes.r32(pc+1), opsize, stream); return 5; case 28: // PC Double Displacement (8 bit) - out_AM_PCDoubleDisplacement(ipc, read8(pc+1), read8(pc+2), opsize, stream); + out_AM_PCDoubleDisplacement(ipc, opcodes.r8(pc+1), opcodes.r8(pc+2), opsize, stream); return 3; case 29: // PC Double Displacement (16 bit) - out_AM_PCDoubleDisplacement(ipc, read16(pc+1), read16(pc+3), opsize, stream); + out_AM_PCDoubleDisplacement(ipc, opcodes.r16(pc+1), opcodes.r16(pc+3), opsize, stream); return 5; case 30: // PC Double Displacement (32 bit) - out_AM_PCDoubleDisplacement(ipc, read32(pc+1), read32(pc+5), opsize, stream); + out_AM_PCDoubleDisplacement(ipc, opcodes.r32(pc+1), opcodes.r32(pc+5), opsize, stream); return 9; default: @@ -433,92 +412,92 @@ static int decode_AM(unsigned ipc, unsigned pc, int m, int opsize, std::ostream } -static int decode_F1(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F1(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); util::stream_format(stream, "%-8s", opnm); if(code & 0x20) { - int ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream) + 2; + int ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream) + 2; stream << ", "; out_AM_Register(code & 0x1f, stream); return ret; } else { out_AM_Register(code & 0x1f, stream); stream << ", "; - return decode_AM(ipc, pc+1, code & 0x40, opsize1, stream) + 2; + return decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream) + 2; } } -static int decode_F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { int ret; - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); util::stream_format(stream, "%-8s", opnm); - ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream); + ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream); stream << ", "; - ret += decode_AM(ipc, pc+1+ret, code & 0x20, opsize2, stream); + ret += decode_AM(ipc, pc+1+ret, code & 0x20, opsize2, opcodes, stream); return ret+2; } -static int decode_F1F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F1F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - if(readop(pc) & 0x80) - return decode_F2(opnm, opsize1, opsize2, ipc, pc, stream); + if(opcodes.r8(pc) & 0x80) + return decode_F2(opnm, opsize1, opsize2, ipc, pc, opcodes, stream); else - return decode_F1(opnm, opsize1, opsize2, ipc, pc, stream); + return decode_F1(opnm, opsize1, opsize2, ipc, pc, opcodes, stream); } -static int decode_F3(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F3(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "%-8s", opnm); - return decode_AM(ipc, pc, readop(pc-1) & 1, opsize1, stream) + 1; + return decode_AM(ipc, pc, opcodes.r8(pc-1) & 1, opsize1, opcodes, stream) + 1; } -static int decode_F4a(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F4a(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - util::stream_format(stream, "%-8s%X", opnm, ipc+read8(pc)); + util::stream_format(stream, "%-8s%X", opnm, ipc+opcodes.r8(pc)); return 2; } -static int decode_F4b(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F4b(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - util::stream_format(stream, "%-8s%X", opnm, ipc+read16(pc)); + util::stream_format(stream, "%-8s%X", opnm, ipc+opcodes.r16(pc)); return 3; } -static int decode_F5(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F5(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { stream << opnm; return 1; } -static int decode_F6(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F6(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - util::stream_format(stream, "%-8s%s, %X[PC]", opnm, v60_reg_names[readop(pc) & 0x1f], ipc+read16(pc+1)); + util::stream_format(stream, "%-8s%s, %X[PC]", opnm, v60_reg_names[opcodes.r8(pc) & 0x1f], ipc+opcodes.r16(pc+1)); return 4; } -static int decode_F7a(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F7a(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { int ret; - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); unsigned char code2; util::stream_format(stream, "%-8s", opnm); - ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream); + ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream); stream << ", "; - code2 = readop(pc+1+ret); + code2 = opcodes.r8(pc+1+ret); if(code2 & 0x80) out_AM_Register(code2 & 0x1f, stream); else out_AM_Immediate(code2, 1, stream); stream << ", "; - ret += decode_AM(ipc, pc+2+ret, code & 0x20, opsize2, stream); + ret += decode_AM(ipc, pc+2+ret, code & 0x20, opsize2, opcodes, stream); stream << ", "; - code2 = readop(pc+2+ret); + code2 = opcodes.r8(pc+2+ret); if(code2 & 0x80) out_AM_Register(code2 & 0x1f, stream); else @@ -527,42 +506,42 @@ static int decode_F7a(const char *opnm, int opsize1, int opsize2, unsigned ipc, return ret+4; } -static int decode_F7b(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F7b(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { int ret; - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); unsigned char code2; util::stream_format(stream, "%-8s", opnm); - ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream); + ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream); stream << ", "; - code2 = readop(pc+1+ret); + code2 = opcodes.r8(pc+1+ret); if(code2 & 0x80) out_AM_Register(code2 & 0x1f, stream); else out_AM_Immediate(code2, 1, stream); stream << ", "; - ret += decode_AM(ipc, pc+2+ret, code & 0x20, opsize2, stream); + ret += decode_AM(ipc, pc+2+ret, code & 0x20, opsize2, opcodes, stream); return ret+3; } -static int decode_F7c(const char *opnm, int opsize1, int opsize2, unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::decode_F7c(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { int ret; - unsigned char code = readop(pc); + unsigned char code = opcodes.r8(pc); unsigned char code2; util::stream_format(stream, "%-8s", opnm); - ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, stream); + ret = decode_AM(ipc, pc+1, code & 0x40, opsize1, opcodes, stream); stream << ", "; - ret += decode_AM(ipc, pc+1+ret, code & 0x20, opsize2, stream); + ret += decode_AM(ipc, pc+1+ret, code & 0x20, opsize2, opcodes, stream); stream << ", "; - code2 = readop(pc+1+ret); + code2 = opcodes.r8(pc+1+ret); if(code2 & 0x80) out_AM_Register(code2 & 0x1f, stream); else @@ -571,70 +550,70 @@ static int decode_F7c(const char *opnm, int opsize1, int opsize2, unsigned ipc, return ret+3; } -static int dopUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dopUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - util::stream_format(stream, "$%02X", readop(pc)); + util::stream_format(stream, "$%02X", opcodes.r8(pc)); return 1; } -static int dop58UNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop58UNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$58"); return 1; } -static int dop59UNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop59UNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$59"); return 1; } -static int dop5AUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5AUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5A"); return 1; } -static int dop5BUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5BUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5B"); return 1; } -static int dop5CUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5CUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5C"); return 1; } -static int dop5DUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5DUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5D"); return 1; } -static int dop5EUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5EUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5E"); return 1; } -static int dop5FUNHANDLED(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5FUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { util::stream_format(stream, "$5F"); return 1; } #define DEFINE_EASY_OPCODE(name, opnm, ftype, opsize1, opsize2) \ - static int dop ## name(unsigned ipc, unsigned pc, std::ostream &stream) \ + u32 v60_disassembler::dop ## name(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) \ { \ - return decode_ ## ftype(opnm, opsize1, opsize2, ipc, pc, stream); \ + return decode_ ## ftype(opnm, opsize1, opsize2, ipc, pc, opcodes, stream); \ } #define DEFINE_EASY_OPCODE_EX(name, opnm, ftype, opsize1, opsize2, flags) \ - static int dop ## name(unsigned ipc, unsigned pc, std::ostream &stream) \ + u32 v60_disassembler::dop ## name(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) \ { \ - return decode_ ## ftype(opnm, opsize1, opsize2, ipc, pc, stream) | (flags); \ + return decode_ ## ftype(opnm, opsize1, opsize2, ipc, pc, opcodes, stream) | (flags); \ } #define DEFINE_TRIPLE_OPCODE(name, string, ftype) \ @@ -693,8 +672,8 @@ DEFINE_EASY_OPCODE(BR8, "br", F4a, 0, 0) DEFINE_EASY_OPCODE(BR16, "br", F4b, 0, 0) DEFINE_EASY_OPCODE(BRK, "brk", F5, 0, 0) DEFINE_EASY_OPCODE(BRKV, "brkv", F5, 0, 0) -DEFINE_EASY_OPCODE_EX(BSR, "bsr", F4b, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(CALL, "call", F1F2, 0, 2, DASMFLAG_STEP_OVER) +DEFINE_EASY_OPCODE_EX(BSR, "bsr", F4b, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(CALL, "call", F1F2, 0, 2, STEP_OVER) DEFINE_EASY_OPCODE(CAXI, "caxi", F1, 2, 2) DEFINE_EASY_OPCODE(CHKAR, "chkar", F1F2, 0, 0) // ? DEFINE_EASY_OPCODE(CHKAW, "chkaw", F1F2, 0, 0) // ? @@ -719,21 +698,21 @@ DEFINE_EASY_OPCODE(CVTSW, "cvt.sw", F2, 0, 2) DEFINE_EASY_OPCODE(CVTLW, "cvt.lw", F2, 1, 2) DEFINE_EASY_OPCODE(CVTDPZ, "cvtd.pz", F7c, 0, 1) DEFINE_EASY_OPCODE(CVTDZP, "cvtd.zp", F7c, 1, 0) -DEFINE_EASY_OPCODE_EX(DBGT, "dbgt", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBGE, "dbge", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBLT, "dbgt", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBLE, "dbge", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBH, "dbh", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBNL, "dbnl", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBL, "dbl", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBNH, "dbnh", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBE, "dbe", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBNE, "dbne", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBV, "dbe", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBNV, "dbne", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBN, "dbn", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBP, "dbp", F6, 0, 0, DASMFLAG_STEP_OVER) -DEFINE_EASY_OPCODE_EX(DBR, "dbr", F6, 0, 0, DASMFLAG_STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBGT, "dbgt", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBGE, "dbge", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBLT, "dbgt", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBLE, "dbge", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBH, "dbh", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBNL, "dbnl", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBL, "dbl", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBNH, "dbnh", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBE, "dbe", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBNE, "dbne", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBV, "dbe", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBNV, "dbne", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBN, "dbn", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBP, "dbp", F6, 0, 0, STEP_OVER) +DEFINE_EASY_OPCODE_EX(DBR, "dbr", F6, 0, 0, STEP_OVER) DEFINE_TRIPLE_OPCODE(DEC, "dec", F3) DEFINE_EASY_OPCODE(DISPOSE, "dispose", F5, 0, 0) DEFINE_TRIPLE_OPCODE(DIV, "div", F1F2) @@ -754,7 +733,7 @@ DEFINE_TRIPLE_OPCODE(INC, "inc", F3) DEFINE_EASY_OPCODE(INSBFL, "insbfl", F7c, 2, 0x82) DEFINE_EASY_OPCODE(INSBFR, "insbfr", F7c, 2, 0x82) DEFINE_EASY_OPCODE(JMP, "jmp", F3, 0, 0) -DEFINE_EASY_OPCODE_EX(JSR, "jsr", F3, 0, 0, DASMFLAG_STEP_OVER) +DEFINE_EASY_OPCODE_EX(JSR, "jsr", F3, 0, 0, STEP_OVER) DEFINE_EASY_OPCODE(LDPR, "ldpr", F1F2, 2, 2) DEFINE_EASY_OPCODE(LDTASK, "ldtask", F1F2, 2, 2) DEFINE_TRIPLE_OPCODE(MOV, "mov", F1F2) @@ -804,16 +783,16 @@ DEFINE_EASY_OPCODE(PUSH, "push", F3, 2, 0) DEFINE_EASY_OPCODE(PUSHM, "pushm", F3, 2, 0) DEFINE_TRIPLE_OPCODE(REM, "rem", F1F2) DEFINE_TRIPLE_OPCODE(REMU, "remu", F1F2) -DEFINE_EASY_OPCODE_EX(RET, "ret", F3, 2, 0, DASMFLAG_STEP_OUT) -DEFINE_EASY_OPCODE_EX(RETIU, "retiu", F3, 1, 0, DASMFLAG_STEP_OUT) -DEFINE_EASY_OPCODE_EX(RETIS, "retis", F3, 1, 0, DASMFLAG_STEP_OUT) +DEFINE_EASY_OPCODE_EX(RET, "ret", F3, 2, 0, STEP_OUT) +DEFINE_EASY_OPCODE_EX(RETIU, "retiu", F3, 1, 0, STEP_OUT) +DEFINE_EASY_OPCODE_EX(RETIS, "retis", F3, 1, 0, STEP_OUT) DEFINE_EASY_OPCODE(ROTB, "rot.b", F1F2, 0, 0) DEFINE_EASY_OPCODE(ROTH, "rot.h", F1F2, 0, 1) DEFINE_EASY_OPCODE(ROTW, "rot.w", F1F2, 0, 2) DEFINE_EASY_OPCODE(ROTCB, "rotc.b", F1F2, 0, 0) DEFINE_EASY_OPCODE(ROTCH, "rotc.h", F1F2, 0, 1) DEFINE_EASY_OPCODE(ROTCW, "rotc.w", F1F2, 0, 2) -DEFINE_EASY_OPCODE_EX(RSR, "rsr", F5, 0, 0, DASMFLAG_STEP_OUT) +DEFINE_EASY_OPCODE_EX(RSR, "rsr", F5, 0, 0, STEP_OUT) DEFINE_EASY_OPCODE(RVBIT, "rvbit", F1F2, 0, 0) DEFINE_EASY_OPCODE(RVBYT, "rvbyt", F1F2, 2, 2) DEFINE_EASY_OPCODE(SCH0BSU, "sch0bsu", F7b, 0x80, 2) @@ -849,7 +828,7 @@ DEFINE_EASY_OPCODE(TASI, "tasi", F3, 0, 0) DEFINE_EASY_OPCODE(TB, "tb", F6, 0, 0) DEFINE_TRIPLE_OPCODE(TEST, "test", F3) DEFINE_EASY_OPCODE(TEST1, "test1", F1F2, 2, 2) -DEFINE_EASY_OPCODE_EX(TRAP, "trap", F3, 0, 0, DASMFLAG_STEP_OVER) +DEFINE_EASY_OPCODE_EX(TRAP, "trap", F3, 0, 0, STEP_OVER) DEFINE_EASY_OPCODE(TRAPFL, "trapfl", F5, 0, 0) DEFINE_EASY_OPCODE(UPDATE, "update", F1F2, 0, 3) // ? DEFINE_EASY_OPCODE(UPDPSWH, "updpsw.h", F1F2, 2, 2) @@ -862,638 +841,634 @@ DEFINE_EASY_OPCODE(XORBSD, "xorbsd", F7b, 0x80, 0x80) DEFINE_EASY_OPCODE(XORNBSU, "xornbsu", F7b, 0x80, 0x80) DEFINE_EASY_OPCODE(XORNBSD, "xornbsd", F7b, 0x80, 0x80) -static int (*const dasm_optable_58[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPCB, - /* 0x01 */ dopCMPCFB, - /* 0x02 */ dopCMPCSB, - /* 0x03 */ dop58UNHANDLED, - /* 0x04 */ dop58UNHANDLED, - /* 0x05 */ dop58UNHANDLED, - /* 0x06 */ dop58UNHANDLED, - /* 0x07 */ dop58UNHANDLED, - /* 0x08 */ dopMOVCUB, - /* 0x09 */ dopMOVCDB, - /* 0x0A */ dopMOVCFUB, - /* 0x0B */ dopMOVCFDB, - /* 0x0C */ dopMOVCSB, - /* 0x0D */ dop58UNHANDLED, - /* 0x0E */ dop58UNHANDLED, - /* 0x0F */ dop58UNHANDLED, - /* 0x10 */ dop58UNHANDLED, - /* 0x11 */ dop58UNHANDLED, - /* 0x12 */ dop58UNHANDLED, - /* 0x13 */ dop58UNHANDLED, - /* 0x14 */ dop58UNHANDLED, - /* 0x15 */ dop58UNHANDLED, - /* 0x16 */ dop58UNHANDLED, - /* 0x17 */ dop58UNHANDLED, - /* 0x18 */ dopSCHCUB, - /* 0x19 */ dopSCHCDB, - /* 0x1A */ dopSKPCUB, - /* 0x1B */ dopSKPCDB, - /* 0x1C */ dop58UNHANDLED, - /* 0x1D */ dop58UNHANDLED, - /* 0x1E */ dop58UNHANDLED, - /* 0x1F */ dop58UNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_58[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPCB, + /* 0x01 */ &v60_disassembler::dopCMPCFB, + /* 0x02 */ &v60_disassembler::dopCMPCSB, + /* 0x03 */ &v60_disassembler::dop58UNHANDLED, + /* 0x04 */ &v60_disassembler::dop58UNHANDLED, + /* 0x05 */ &v60_disassembler::dop58UNHANDLED, + /* 0x06 */ &v60_disassembler::dop58UNHANDLED, + /* 0x07 */ &v60_disassembler::dop58UNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVCUB, + /* 0x09 */ &v60_disassembler::dopMOVCDB, + /* 0x0A */ &v60_disassembler::dopMOVCFUB, + /* 0x0B */ &v60_disassembler::dopMOVCFDB, + /* 0x0C */ &v60_disassembler::dopMOVCSB, + /* 0x0D */ &v60_disassembler::dop58UNHANDLED, + /* 0x0E */ &v60_disassembler::dop58UNHANDLED, + /* 0x0F */ &v60_disassembler::dop58UNHANDLED, + /* 0x10 */ &v60_disassembler::dop58UNHANDLED, + /* 0x11 */ &v60_disassembler::dop58UNHANDLED, + /* 0x12 */ &v60_disassembler::dop58UNHANDLED, + /* 0x13 */ &v60_disassembler::dop58UNHANDLED, + /* 0x14 */ &v60_disassembler::dop58UNHANDLED, + /* 0x15 */ &v60_disassembler::dop58UNHANDLED, + /* 0x16 */ &v60_disassembler::dop58UNHANDLED, + /* 0x17 */ &v60_disassembler::dop58UNHANDLED, + /* 0x18 */ &v60_disassembler::dopSCHCUB, + /* 0x19 */ &v60_disassembler::dopSCHCDB, + /* 0x1A */ &v60_disassembler::dopSKPCUB, + /* 0x1B */ &v60_disassembler::dopSKPCDB, + /* 0x1C */ &v60_disassembler::dop58UNHANDLED, + /* 0x1D */ &v60_disassembler::dop58UNHANDLED, + /* 0x1E */ &v60_disassembler::dop58UNHANDLED, + /* 0x1F */ &v60_disassembler::dop58UNHANDLED }; -static int (*const dasm_optable_59[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopADDDC, - /* 0x01 */ dopSUBDC, - /* 0x02 */ dopSUBRDC, - /* 0x03 */ dop59UNHANDLED, - /* 0x04 */ dop59UNHANDLED, - /* 0x05 */ dop59UNHANDLED, - /* 0x06 */ dop59UNHANDLED, - /* 0x07 */ dop59UNHANDLED, - /* 0x08 */ dop59UNHANDLED, - /* 0x09 */ dop59UNHANDLED, - /* 0x0A */ dop59UNHANDLED, - /* 0x0B */ dop59UNHANDLED, - /* 0x0C */ dop59UNHANDLED, - /* 0x0D */ dop59UNHANDLED, - /* 0x0E */ dop59UNHANDLED, - /* 0x0F */ dop59UNHANDLED, - /* 0x10 */ dopCVTDPZ, - /* 0x11 */ dop59UNHANDLED, - /* 0x12 */ dop59UNHANDLED, - /* 0x13 */ dop59UNHANDLED, - /* 0x14 */ dop59UNHANDLED, - /* 0x15 */ dop59UNHANDLED, - /* 0x16 */ dop59UNHANDLED, - /* 0x17 */ dop59UNHANDLED, - /* 0x18 */ dopCVTDZP, - /* 0x19 */ dop59UNHANDLED, - /* 0x1A */ dop59UNHANDLED, - /* 0x1B */ dop59UNHANDLED, - /* 0x1C */ dop59UNHANDLED, - /* 0x1D */ dop59UNHANDLED, - /* 0x1E */ dop59UNHANDLED, - /* 0x1F */ dop59UNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_59[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopADDDC, + /* 0x01 */ &v60_disassembler::dopSUBDC, + /* 0x02 */ &v60_disassembler::dopSUBRDC, + /* 0x03 */ &v60_disassembler::dop59UNHANDLED, + /* 0x04 */ &v60_disassembler::dop59UNHANDLED, + /* 0x05 */ &v60_disassembler::dop59UNHANDLED, + /* 0x06 */ &v60_disassembler::dop59UNHANDLED, + /* 0x07 */ &v60_disassembler::dop59UNHANDLED, + /* 0x08 */ &v60_disassembler::dop59UNHANDLED, + /* 0x09 */ &v60_disassembler::dop59UNHANDLED, + /* 0x0A */ &v60_disassembler::dop59UNHANDLED, + /* 0x0B */ &v60_disassembler::dop59UNHANDLED, + /* 0x0C */ &v60_disassembler::dop59UNHANDLED, + /* 0x0D */ &v60_disassembler::dop59UNHANDLED, + /* 0x0E */ &v60_disassembler::dop59UNHANDLED, + /* 0x0F */ &v60_disassembler::dop59UNHANDLED, + /* 0x10 */ &v60_disassembler::dopCVTDPZ, + /* 0x11 */ &v60_disassembler::dop59UNHANDLED, + /* 0x12 */ &v60_disassembler::dop59UNHANDLED, + /* 0x13 */ &v60_disassembler::dop59UNHANDLED, + /* 0x14 */ &v60_disassembler::dop59UNHANDLED, + /* 0x15 */ &v60_disassembler::dop59UNHANDLED, + /* 0x16 */ &v60_disassembler::dop59UNHANDLED, + /* 0x17 */ &v60_disassembler::dop59UNHANDLED, + /* 0x18 */ &v60_disassembler::dopCVTDZP, + /* 0x19 */ &v60_disassembler::dop59UNHANDLED, + /* 0x1A */ &v60_disassembler::dop59UNHANDLED, + /* 0x1B */ &v60_disassembler::dop59UNHANDLED, + /* 0x1C */ &v60_disassembler::dop59UNHANDLED, + /* 0x1D */ &v60_disassembler::dop59UNHANDLED, + /* 0x1E */ &v60_disassembler::dop59UNHANDLED, + /* 0x1F */ &v60_disassembler::dop59UNHANDLED }; -static int (*const dasm_optable_5A[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPCH, - /* 0x01 */ dopCMPCFH, - /* 0x02 */ dopCMPCSH, - /* 0x03 */ dop5AUNHANDLED, - /* 0x04 */ dop5AUNHANDLED, - /* 0x05 */ dop5AUNHANDLED, - /* 0x06 */ dop5AUNHANDLED, - /* 0x07 */ dop5AUNHANDLED, - /* 0x08 */ dopMOVCUH, - /* 0x09 */ dopMOVCDH, - /* 0x0A */ dopMOVCFUH, - /* 0x0B */ dopMOVCFDH, - /* 0x0C */ dopMOVCSH, - /* 0x0D */ dop5AUNHANDLED, - /* 0x0E */ dop5AUNHANDLED, - /* 0x0F */ dop5AUNHANDLED, - /* 0x10 */ dop5AUNHANDLED, - /* 0x11 */ dop5AUNHANDLED, - /* 0x12 */ dop5AUNHANDLED, - /* 0x13 */ dop5AUNHANDLED, - /* 0x14 */ dop5AUNHANDLED, - /* 0x15 */ dop5AUNHANDLED, - /* 0x16 */ dop5AUNHANDLED, - /* 0x17 */ dop5AUNHANDLED, - /* 0x18 */ dopSCHCUH, - /* 0x19 */ dopSCHCDH, - /* 0x1A */ dopSKPCUH, - /* 0x1B */ dopSKPCDH, - /* 0x1C */ dop5AUNHANDLED, - /* 0x1D */ dop5AUNHANDLED, - /* 0x1E */ dop5AUNHANDLED, - /* 0x1F */ dop5AUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5A[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPCH, + /* 0x01 */ &v60_disassembler::dopCMPCFH, + /* 0x02 */ &v60_disassembler::dopCMPCSH, + /* 0x03 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVCUH, + /* 0x09 */ &v60_disassembler::dopMOVCDH, + /* 0x0A */ &v60_disassembler::dopMOVCFUH, + /* 0x0B */ &v60_disassembler::dopMOVCFDH, + /* 0x0C */ &v60_disassembler::dopMOVCSH, + /* 0x0D */ &v60_disassembler::dop5AUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5AUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5AUNHANDLED, + /* 0x10 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x11 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x12 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5AUNHANDLED, + /* 0x18 */ &v60_disassembler::dopSCHCUH, + /* 0x19 */ &v60_disassembler::dopSCHCDH, + /* 0x1A */ &v60_disassembler::dopSKPCUH, + /* 0x1B */ &v60_disassembler::dopSKPCDH, + /* 0x1C */ &v60_disassembler::dop5AUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5AUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5AUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5AUNHANDLED }; -static int (*const dasm_optable_5B[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopSCH0BSU, - /* 0x01 */ dopSCH0BSD, - /* 0x02 */ dopSCH1BSU, - /* 0x03 */ dopSCH1BSD, - /* 0x04 */ dop5BUNHANDLED, - /* 0x05 */ dop5BUNHANDLED, - /* 0x06 */ dop5BUNHANDLED, - /* 0x07 */ dop5BUNHANDLED, - /* 0x08 */ dopMOVBSU, - /* 0x09 */ dopMOVBSD, - /* 0x0A */ dopNOTBSU, - /* 0x0B */ dopNOTBSD, - /* 0x0C */ dop5BUNHANDLED, - /* 0x0D */ dop5BUNHANDLED, - /* 0x0E */ dop5BUNHANDLED, - /* 0x0F */ dop5BUNHANDLED, - /* 0x10 */ dopANDBSU, - /* 0x11 */ dopANDBSD, - /* 0x12 */ dopANDNBSU, - /* 0x13 */ dopANDNBSD, - /* 0x14 */ dopORBSU, - /* 0x15 */ dopORBSD, - /* 0x16 */ dopORNBSU, - /* 0x17 */ dopORNBSD, - /* 0x18 */ dopXORBSU, - /* 0x19 */ dopXORBSD, - /* 0x1A */ dopXORNBSU, - /* 0x1B */ dopXORNBSD, - /* 0x1C */ dop5BUNHANDLED, - /* 0x1D */ dop5BUNHANDLED, - /* 0x1E */ dop5BUNHANDLED, - /* 0x1F */ dop5BUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5B[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopSCH0BSU, + /* 0x01 */ &v60_disassembler::dopSCH0BSD, + /* 0x02 */ &v60_disassembler::dopSCH1BSU, + /* 0x03 */ &v60_disassembler::dopSCH1BSD, + /* 0x04 */ &v60_disassembler::dop5BUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5BUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5BUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5BUNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVBSU, + /* 0x09 */ &v60_disassembler::dopMOVBSD, + /* 0x0A */ &v60_disassembler::dopNOTBSU, + /* 0x0B */ &v60_disassembler::dopNOTBSD, + /* 0x0C */ &v60_disassembler::dop5BUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5BUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5BUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5BUNHANDLED, + /* 0x10 */ &v60_disassembler::dopANDBSU, + /* 0x11 */ &v60_disassembler::dopANDBSD, + /* 0x12 */ &v60_disassembler::dopANDNBSU, + /* 0x13 */ &v60_disassembler::dopANDNBSD, + /* 0x14 */ &v60_disassembler::dopORBSU, + /* 0x15 */ &v60_disassembler::dopORBSD, + /* 0x16 */ &v60_disassembler::dopORNBSU, + /* 0x17 */ &v60_disassembler::dopORNBSD, + /* 0x18 */ &v60_disassembler::dopXORBSU, + /* 0x19 */ &v60_disassembler::dopXORBSD, + /* 0x1A */ &v60_disassembler::dopXORNBSU, + /* 0x1B */ &v60_disassembler::dopXORNBSD, + /* 0x1C */ &v60_disassembler::dop5BUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5BUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5BUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5BUNHANDLED }; -static int (*const dasm_optable_5C[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPFS, - /* 0x01 */ dop5CUNHANDLED, - /* 0x02 */ dop5CUNHANDLED, - /* 0x03 */ dop5CUNHANDLED, - /* 0x04 */ dop5CUNHANDLED, - /* 0x05 */ dop5CUNHANDLED, - /* 0x06 */ dop5CUNHANDLED, - /* 0x07 */ dop5CUNHANDLED, - /* 0x08 */ dopMOVFS, - /* 0x09 */ dopNEGFS, - /* 0x0A */ dopABSFS, - /* 0x0B */ dop5CUNHANDLED, - /* 0x0C */ dop5CUNHANDLED, - /* 0x0D */ dop5CUNHANDLED, - /* 0x0E */ dop5CUNHANDLED, - /* 0x0F */ dop5CUNHANDLED, - /* 0x10 */ dopSCLFS, - /* 0x11 */ dop5CUNHANDLED, - /* 0x12 */ dop5CUNHANDLED, - /* 0x13 */ dop5CUNHANDLED, - /* 0x14 */ dop5CUNHANDLED, - /* 0x15 */ dop5CUNHANDLED, - /* 0x16 */ dop5CUNHANDLED, - /* 0x17 */ dop5CUNHANDLED, - /* 0x18 */ dopADDFS, - /* 0x19 */ dopSUBFS, - /* 0x1A */ dopMULFS, - /* 0x1B */ dopDIVFS, - /* 0x1C */ dop5CUNHANDLED, - /* 0x1D */ dop5CUNHANDLED, - /* 0x1E */ dop5CUNHANDLED, - /* 0x1F */ dop5CUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5C[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPFS, + /* 0x01 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x02 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x03 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVFS, + /* 0x09 */ &v60_disassembler::dopNEGFS, + /* 0x0A */ &v60_disassembler::dopABSFS, + /* 0x0B */ &v60_disassembler::dop5CUNHANDLED, + /* 0x0C */ &v60_disassembler::dop5CUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5CUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5CUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5CUNHANDLED, + /* 0x10 */ &v60_disassembler::dopSCLFS, + /* 0x11 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x12 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5CUNHANDLED, + /* 0x18 */ &v60_disassembler::dopADDFS, + /* 0x19 */ &v60_disassembler::dopSUBFS, + /* 0x1A */ &v60_disassembler::dopMULFS, + /* 0x1B */ &v60_disassembler::dopDIVFS, + /* 0x1C */ &v60_disassembler::dop5CUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5CUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5CUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5CUNHANDLED }; -static int (*const dasm_optable_5D[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPBFS, - /* 0x01 */ dopCMPBFZ, - /* 0x02 */ dopCMPBFL, - /* 0x03 */ dop5DUNHANDLED, - /* 0x04 */ dop5DUNHANDLED, - /* 0x05 */ dop5DUNHANDLED, - /* 0x06 */ dop5DUNHANDLED, - /* 0x07 */ dop5DUNHANDLED, - /* 0x08 */ dopEXTBFS, - /* 0x09 */ dopEXTBFZ, - /* 0x0A */ dopEXTBFL, - /* 0x0B */ dop5DUNHANDLED, - /* 0x0C */ dop5DUNHANDLED, - /* 0x0D */ dop5DUNHANDLED, - /* 0x0E */ dop5DUNHANDLED, - /* 0x0F */ dop5DUNHANDLED, - /* 0x10 */ dop5DUNHANDLED, - /* 0x11 */ dop5DUNHANDLED, - /* 0x12 */ dop5DUNHANDLED, - /* 0x13 */ dop5DUNHANDLED, - /* 0x14 */ dop5DUNHANDLED, - /* 0x15 */ dop5DUNHANDLED, - /* 0x16 */ dop5DUNHANDLED, - /* 0x17 */ dop5DUNHANDLED, - /* 0x18 */ dopINSBFR, - /* 0x19 */ dopINSBFL, - /* 0x1A */ dop5DUNHANDLED, - /* 0x1B */ dop5DUNHANDLED, - /* 0x1C */ dop5DUNHANDLED, - /* 0x1D */ dop5DUNHANDLED, - /* 0x1E */ dop5DUNHANDLED, - /* 0x1F */ dop5DUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5D[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPBFS, + /* 0x01 */ &v60_disassembler::dopCMPBFZ, + /* 0x02 */ &v60_disassembler::dopCMPBFL, + /* 0x03 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x08 */ &v60_disassembler::dopEXTBFS, + /* 0x09 */ &v60_disassembler::dopEXTBFZ, + /* 0x0A */ &v60_disassembler::dopEXTBFL, + /* 0x0B */ &v60_disassembler::dop5DUNHANDLED, + /* 0x0C */ &v60_disassembler::dop5DUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5DUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5DUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5DUNHANDLED, + /* 0x10 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x11 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x12 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5DUNHANDLED, + /* 0x18 */ &v60_disassembler::dopINSBFR, + /* 0x19 */ &v60_disassembler::dopINSBFL, + /* 0x1A */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1B */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1C */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5DUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5DUNHANDLED }; -static int (*const dasm_optable_5E[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCMPFL, - /* 0x01 */ dop5EUNHANDLED, - /* 0x02 */ dop5EUNHANDLED, - /* 0x03 */ dop5EUNHANDLED, - /* 0x04 */ dop5EUNHANDLED, - /* 0x05 */ dop5EUNHANDLED, - /* 0x06 */ dop5EUNHANDLED, - /* 0x07 */ dop5EUNHANDLED, - /* 0x08 */ dopMOVFL, - /* 0x09 */ dopNEGFL, - /* 0x0A */ dopABSFL, - /* 0x0B */ dop5EUNHANDLED, - /* 0x0C */ dop5EUNHANDLED, - /* 0x0D */ dop5EUNHANDLED, - /* 0x0E */ dop5EUNHANDLED, - /* 0x0F */ dop5EUNHANDLED, - /* 0x10 */ dopSCLFL, - /* 0x11 */ dop5EUNHANDLED, - /* 0x12 */ dop5EUNHANDLED, - /* 0x13 */ dop5EUNHANDLED, - /* 0x14 */ dop5EUNHANDLED, - /* 0x15 */ dop5EUNHANDLED, - /* 0x16 */ dop5EUNHANDLED, - /* 0x17 */ dop5EUNHANDLED, - /* 0x18 */ dopADDFL, - /* 0x19 */ dopSUBFL, - /* 0x1A */ dopMULFL, - /* 0x1B */ dopDIVFL, - /* 0x1C */ dop5EUNHANDLED, - /* 0x1D */ dop5EUNHANDLED, - /* 0x1E */ dop5EUNHANDLED, - /* 0x1F */ dop5EUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5E[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCMPFL, + /* 0x01 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x02 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x03 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x08 */ &v60_disassembler::dopMOVFL, + /* 0x09 */ &v60_disassembler::dopNEGFL, + /* 0x0A */ &v60_disassembler::dopABSFL, + /* 0x0B */ &v60_disassembler::dop5EUNHANDLED, + /* 0x0C */ &v60_disassembler::dop5EUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5EUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5EUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5EUNHANDLED, + /* 0x10 */ &v60_disassembler::dopSCLFL, + /* 0x11 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x12 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5EUNHANDLED, + /* 0x18 */ &v60_disassembler::dopADDFL, + /* 0x19 */ &v60_disassembler::dopSUBFL, + /* 0x1A */ &v60_disassembler::dopMULFL, + /* 0x1B */ &v60_disassembler::dopDIVFL, + /* 0x1C */ &v60_disassembler::dop5EUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5EUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5EUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5EUNHANDLED }; -static int (*const dasm_optable_5F[32])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopCVTWS, - /* 0x01 */ dopCVTSW, - /* 0x02 */ dop5FUNHANDLED, - /* 0x03 */ dop5FUNHANDLED, - /* 0x04 */ dop5FUNHANDLED, - /* 0x05 */ dop5FUNHANDLED, - /* 0x06 */ dop5FUNHANDLED, - /* 0x07 */ dop5FUNHANDLED, - /* 0x08 */ dopCVTLS, - /* 0x09 */ dopCVTLW, - /* 0x0A */ dop5FUNHANDLED, - /* 0x0B */ dop5FUNHANDLED, - /* 0x0C */ dop5FUNHANDLED, - /* 0x0D */ dop5FUNHANDLED, - /* 0x0E */ dop5FUNHANDLED, - /* 0x0F */ dop5FUNHANDLED, - /* 0x10 */ dopCVTSL, - /* 0x11 */ dopCVTWL, - /* 0x12 */ dop5FUNHANDLED, - /* 0x13 */ dop5FUNHANDLED, - /* 0x14 */ dop5FUNHANDLED, - /* 0x15 */ dop5FUNHANDLED, - /* 0x16 */ dop5FUNHANDLED, - /* 0x17 */ dop5FUNHANDLED, - /* 0x18 */ dop5FUNHANDLED, - /* 0x19 */ dop5FUNHANDLED, - /* 0x1A */ dop5FUNHANDLED, - /* 0x1B */ dop5FUNHANDLED, - /* 0x1C */ dop5FUNHANDLED, - /* 0x1D */ dop5FUNHANDLED, - /* 0x1E */ dop5FUNHANDLED, - /* 0x1F */ dop5FUNHANDLED +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_5F[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopCVTWS, + /* 0x01 */ &v60_disassembler::dopCVTSW, + /* 0x02 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x03 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x04 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x05 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x06 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x07 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x08 */ &v60_disassembler::dopCVTLS, + /* 0x09 */ &v60_disassembler::dopCVTLW, + /* 0x0A */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0B */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0C */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0D */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0E */ &v60_disassembler::dop5FUNHANDLED, + /* 0x0F */ &v60_disassembler::dop5FUNHANDLED, + /* 0x10 */ &v60_disassembler::dopCVTSL, + /* 0x11 */ &v60_disassembler::dopCVTWL, + /* 0x12 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x13 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x14 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x15 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x16 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x17 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x18 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x19 */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1A */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1B */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1C */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1D */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1E */ &v60_disassembler::dop5FUNHANDLED, + /* 0x1F */ &v60_disassembler::dop5FUNHANDLED }; -static int (*const dasm_optable_C6[8])(unsigned ipc, unsigned pc, std::ostream &stream) = +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_C6[8])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = { - /* 0x0 */ dopDBV, - /* 0x1 */ dopDBL, - /* 0x2 */ dopDBE, - /* 0x3 */ dopDBNH, - /* 0x4 */ dopDBN, - /* 0x5 */ dopDBR, - /* 0x6 */ dopDBLT, - /* 0x7 */ dopDBLE + /* 0x0 */ &v60_disassembler::dopDBV, + /* 0x1 */ &v60_disassembler::dopDBL, + /* 0x2 */ &v60_disassembler::dopDBE, + /* 0x3 */ &v60_disassembler::dopDBNH, + /* 0x4 */ &v60_disassembler::dopDBN, + /* 0x5 */ &v60_disassembler::dopDBR, + /* 0x6 */ &v60_disassembler::dopDBLT, + /* 0x7 */ &v60_disassembler::dopDBLE }; -static int (*const dasm_optable_C7[8])(unsigned ipc, unsigned pc, std::ostream &stream) = +u32 (v60_disassembler::*const v60_disassembler::dasm_optable_C7[8])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = { - /* 0x0 */ dopDBNV, - /* 0x1 */ dopDBNL, - /* 0x2 */ dopDBNE, - /* 0x3 */ dopDBH, - /* 0x4 */ dopDBP, - /* 0x5 */ dopTB, - /* 0x6 */ dopDBGE, - /* 0x7 */ dopDBGT + /* 0x0 */ &v60_disassembler::dopDBNV, + /* 0x1 */ &v60_disassembler::dopDBNL, + /* 0x2 */ &v60_disassembler::dopDBNE, + /* 0x3 */ &v60_disassembler::dopDBH, + /* 0x4 */ &v60_disassembler::dopDBP, + /* 0x5 */ &v60_disassembler::dopTB, + /* 0x6 */ &v60_disassembler::dopDBGE, + /* 0x7 */ &v60_disassembler::dopDBGT }; -static int dop58(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop58(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_58[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_58[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop59(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop59(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_59[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_59[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5A(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5A(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5A[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5A[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5B(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5B(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5B[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5B[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5C(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5C(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5C[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5C[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5D(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5D(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5D[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5D[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5E(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5E(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5E[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5E[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dop5F(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dop5F(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_5F[readop(pc) & 0x1f](ipc, pc, stream); + return (this->*dasm_optable_5F[opcodes.r8(pc) & 0x1f])(ipc, pc, opcodes, stream); } -static int dopC6(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dopC6(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_C6[readop(pc) >> 5](ipc, pc, stream); + return (this->*dasm_optable_C6[opcodes.r8(pc) >> 5])(ipc, pc, opcodes, stream); } -static int dopC7(unsigned ipc, unsigned pc, std::ostream &stream) +u32 v60_disassembler::dopC7(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) { - return dasm_optable_C7[readop(pc) >> 5](ipc, pc, stream); + return (this->*dasm_optable_C7[opcodes.r8(pc) >> 5])(ipc, pc, opcodes, stream); } -static int (*const dasm_optable[256])(unsigned ipc, unsigned pc, std::ostream &stream) = -{ - /* 0x00 */ dopHALT, - /* 0x01 */ dopLDTASK, - /* 0x02 */ dopSTPR, - /* 0x03 */ dopGETRA, - /* 0x04 */ dopGETPTE, - /* 0x05 */ dopGETATE, - /* 0x06 */ dopUNHANDLED, - /* 0x07 */ dopUNHANDLED, - /* 0x08 */ dopRVBIT, - /* 0x09 */ dopMOVB, - /* 0x0A */ dopMOVSBH, - /* 0x0B */ dopMOVZBH, - /* 0x0C */ dopMOVSBW, - /* 0x0D */ dopMOVZBW, - /* 0x0E */ dopUNHANDLED, - /* 0x0F */ dopUNHANDLED, - /* 0x10 */ dopCLRTLBA, - /* 0x11 */ dopUNHANDLED, - /* 0x12 */ dopLDPR, - /* 0x13 */ dopUPDPSWW, - /* 0x14 */ dopUPDPTE, - /* 0x15 */ dopUPDATE, - /* 0x16 */ dopUNHANDLED, - /* 0x17 */ dopUNHANDLED, - /* 0x18 */ dopUNHANDLED, - /* 0x19 */ dopMOVTHB, - /* 0x1A */ dopUNHANDLED, - /* 0x1B */ dopMOVH, - /* 0x1C */ dopMOVSHW, - /* 0x1D */ dopMOVZHW, - /* 0x1E */ dopUNHANDLED, - /* 0x1F */ dopUNHANDLED, - /* 0x20 */ dopINB, - /* 0x21 */ dopOUTB, - /* 0x22 */ dopINH, - /* 0x23 */ dopOUTH, - /* 0x24 */ dopINW, - /* 0x25 */ dopOUTW, - /* 0x26 */ dopUNHANDLED, - /* 0x27 */ dopUNHANDLED, - /* 0x28 */ dopUNHANDLED, - /* 0x29 */ dopMOVTWB, - /* 0x2A */ dopUNHANDLED, - /* 0x2B */ dopMOVTWH, - /* 0x2C */ dopRVBYT, - /* 0x2D */ dopMOVW, - /* 0x2E */ dopUNHANDLED, - /* 0x2F */ dopUNHANDLED, - /* 0x30 */ dopUNHANDLED, - /* 0x31 */ dopUNHANDLED, - /* 0x32 */ dopUNHANDLED, - /* 0x33 */ dopUNHANDLED, - /* 0x34 */ dopUNHANDLED, - /* 0x35 */ dopUNHANDLED, - /* 0x36 */ dopUNHANDLED, - /* 0x37 */ dopUNHANDLED, - /* 0x38 */ dopNOTB, - /* 0x39 */ dopNEGB, - /* 0x3A */ dopNOTH, - /* 0x3B */ dopNEGH, - /* 0x3C */ dopNOTW, - /* 0x3D */ dopNEGW, - /* 0x3E */ dopUNHANDLED, - /* 0x3F */ dopMOVD, - /* 0x40 */ dopMOVEAB, - /* 0x41 */ dopXCHB, - /* 0x42 */ dopMOVEAH, - /* 0x43 */ dopXCHH, - /* 0x44 */ dopMOVEAW, - /* 0x45 */ dopXCHW, - /* 0x46 */ dopUNHANDLED, - /* 0x47 */ dopSETF, - /* 0x48 */ dopBSR, - /* 0x49 */ dopCALL, - /* 0x4A */ dopUPDPSWH, - /* 0x4B */ dopCHLVL, - /* 0x4C */ dopCAXI, - /* 0x4D */ dopCHKAR, - /* 0x4E */ dopCHKAW, - /* 0x4F */ dopCHKAE, - /* 0x50 */ dopREMB, - /* 0x51 */ dopREMUB, - /* 0x52 */ dopREMH, - /* 0x53 */ dopREMUH, - /* 0x54 */ dopREMW, - /* 0x55 */ dopREMUW, - /* 0x56 */ dopUNHANDLED, - /* 0x57 */ dopUNHANDLED, - /* 0x58 */ dop58, - /* 0x59 */ dop59, - /* 0x5A */ dop5A, - /* 0x5B */ dop5B, - /* 0x5C */ dop5C, - /* 0x5D */ dop5D, - /* 0x5E */ dop5E, - /* 0x5F */ dop5F, - /* 0x60 */ dopBV8, - /* 0x61 */ dopBNV8, - /* 0x62 */ dopBL8, - /* 0x63 */ dopBNL8, - /* 0x64 */ dopBE8, - /* 0x65 */ dopBNE8, - /* 0x66 */ dopBNH8, - /* 0x67 */ dopBH8, - /* 0x68 */ dopBN8, - /* 0x69 */ dopBP8, - /* 0x6A */ dopBR8, - /* 0x6B */ dopUNHANDLED, - /* 0x6C */ dopBLT8, - /* 0x6D */ dopBGE8, - /* 0x6E */ dopBLE8, - /* 0x6F */ dopBGT8, - /* 0x70 */ dopBV16, - /* 0x71 */ dopBNV16, - /* 0x72 */ dopBL16, - /* 0x73 */ dopBNL16, - /* 0x74 */ dopBE16, - /* 0x75 */ dopBNE16, - /* 0x76 */ dopBNH16, - /* 0x77 */ dopBH16, - /* 0x78 */ dopBN16, - /* 0x79 */ dopBP16, - /* 0x7A */ dopBR16, - /* 0x7B */ dopUNHANDLED, - /* 0x7C */ dopBLT16, - /* 0x7D */ dopBGE16, - /* 0x7E */ dopBLE16, - /* 0x7F */ dopBGT16, - /* 0x80 */ dopADDB, - /* 0x81 */ dopMULB, - /* 0x82 */ dopADDH, - /* 0x83 */ dopMULH, - /* 0x84 */ dopADDW, - /* 0x85 */ dopMULW, - /* 0x86 */ dopMULX, - /* 0x87 */ dopTEST1, - /* 0x88 */ dopORB, - /* 0x89 */ dopROTB, - /* 0x8A */ dopORH, - /* 0x8B */ dopROTH, - /* 0x8C */ dopORW, - /* 0x8D */ dopROTW, - /* 0x8E */ dopUNHANDLED, - /* 0x8F */ dopUNHANDLED, - /* 0x90 */ dopADDCB, - /* 0x91 */ dopMULUB, - /* 0x92 */ dopADDCH, - /* 0x93 */ dopMULUH, - /* 0x94 */ dopADDCW, - /* 0x95 */ dopMULUW, - /* 0x96 */ dopMULUX, - /* 0x97 */ dopSET1, - /* 0x98 */ dopSUBCB, - /* 0x99 */ dopROTCB, - /* 0x9A */ dopSUBCH, - /* 0x9B */ dopROTCH, - /* 0x9C */ dopSUBCW, - /* 0x9D */ dopROTCW, - /* 0x9E */ dopUNHANDLED, - /* 0x9F */ dopUNHANDLED, - /* 0xA0 */ dopANDB, - /* 0xA1 */ dopDIVB, - /* 0xA2 */ dopANDH, - /* 0xA3 */ dopDIVH, - /* 0xA4 */ dopANDW, - /* 0xA5 */ dopDIVW, - /* 0xA6 */ dopDIVX, - /* 0xA7 */ dopCLR1, - /* 0xA8 */ dopSUBB, - /* 0xA9 */ dopSHLB, - /* 0xAA */ dopSUBH, - /* 0xAB */ dopSHLH, - /* 0xAC */ dopSUBW, - /* 0xAD */ dopSHLW, - /* 0xAE */ dopUNHANDLED, - /* 0xAF */ dopUNHANDLED, - /* 0xB0 */ dopXORB, - /* 0xB1 */ dopDIVUB, - /* 0xB2 */ dopXORH, - /* 0xB3 */ dopDIVUH, - /* 0xB4 */ dopXORW, - /* 0xB5 */ dopDIVUW, - /* 0xB6 */ dopDIVUX, - /* 0xB7 */ dopNOT1, - /* 0xB8 */ dopCMPB, - /* 0xB9 */ dopSHAB, - /* 0xBA */ dopCMPH, - /* 0xBB */ dopSHAH, - /* 0xBC */ dopCMPW, - /* 0xBD */ dopSHAW, - /* 0xBE */ dopUNHANDLED, - /* 0xBF */ dopUNHANDLED, - /* 0xC0 */ dopUNHANDLED, - /* 0xC1 */ dopUNHANDLED, - /* 0xC2 */ dopUNHANDLED, - /* 0xC3 */ dopUNHANDLED, - /* 0xC4 */ dopUNHANDLED, - /* 0xC5 */ dopUNHANDLED, - /* 0xC6 */ dopC6, - /* 0xC7 */ dopC7, - /* 0xC8 */ dopBRK, - /* 0xC9 */ dopBRKV, - /* 0xCA */ dopRSR, - /* 0xCB */ dopTRAPFL, - /* 0xCC */ dopDISPOSE, - /* 0xCD */ dopNOP, - /* 0xCE */ dopUNHANDLED, - /* 0xCF */ dopUNHANDLED, - /* 0xD0 */ dopDECB, - /* 0xD1 */ dopDECB, - /* 0xD2 */ dopDECH, - /* 0xD3 */ dopDECH, - /* 0xD4 */ dopDECW, - /* 0xD5 */ dopDECW, - /* 0xD6 */ dopJMP, - /* 0xD7 */ dopJMP, - /* 0xD8 */ dopINCB, - /* 0xD9 */ dopINCB, - /* 0xDA */ dopINCH, - /* 0xDB */ dopINCH, - /* 0xDC */ dopINCW, - /* 0xDD */ dopINCW, - /* 0xDE */ dopPREPARE, - /* 0xDF */ dopPREPARE, - /* 0xE0 */ dopTASI, - /* 0xE1 */ dopTASI, - /* 0xE2 */ dopRET, - /* 0xE3 */ dopRET, - /* 0xE4 */ dopPOPM, - /* 0xE5 */ dopPOPM, - /* 0xE6 */ dopPOP, - /* 0xE7 */ dopPOP, - /* 0xE8 */ dopJSR, - /* 0xE9 */ dopJSR, - /* 0xEA */ dopRETIU, - /* 0xEB */ dopRETIU, - /* 0xEC */ dopPUSHM, - /* 0xED */ dopPUSHM, - /* 0xEE */ dopPUSH, - /* 0xEF */ dopPUSH, - /* 0xF0 */ dopTESTB, - /* 0xF1 */ dopTESTB, - /* 0xF2 */ dopTESTH, - /* 0xF3 */ dopTESTH, - /* 0xF4 */ dopTESTW, - /* 0xF5 */ dopTESTW, - /* 0xF6 */ dopGETPSW, - /* 0xF7 */ dopGETPSW, - /* 0xF8 */ dopTRAP, - /* 0xF9 */ dopTRAP, - /* 0xFA */ dopRETIS, - /* 0xFB */ dopRETIS, - /* 0xFC */ dopSTTASK, - /* 0xFD */ dopSTTASK, - /* 0xFE */ dopCLRTLB, - /* 0xFF */ dopCLRTLB +u32 (v60_disassembler::*const v60_disassembler::dasm_optable[256])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream) = +{ + /* 0x00 */ &v60_disassembler::dopHALT, + /* 0x01 */ &v60_disassembler::dopLDTASK, + /* 0x02 */ &v60_disassembler::dopSTPR, + /* 0x03 */ &v60_disassembler::dopGETRA, + /* 0x04 */ &v60_disassembler::dopGETPTE, + /* 0x05 */ &v60_disassembler::dopGETATE, + /* 0x06 */ &v60_disassembler::dopUNHANDLED, + /* 0x07 */ &v60_disassembler::dopUNHANDLED, + /* 0x08 */ &v60_disassembler::dopRVBIT, + /* 0x09 */ &v60_disassembler::dopMOVB, + /* 0x0A */ &v60_disassembler::dopMOVSBH, + /* 0x0B */ &v60_disassembler::dopMOVZBH, + /* 0x0C */ &v60_disassembler::dopMOVSBW, + /* 0x0D */ &v60_disassembler::dopMOVZBW, + /* 0x0E */ &v60_disassembler::dopUNHANDLED, + /* 0x0F */ &v60_disassembler::dopUNHANDLED, + /* 0x10 */ &v60_disassembler::dopCLRTLBA, + /* 0x11 */ &v60_disassembler::dopUNHANDLED, + /* 0x12 */ &v60_disassembler::dopLDPR, + /* 0x13 */ &v60_disassembler::dopUPDPSWW, + /* 0x14 */ &v60_disassembler::dopUPDPTE, + /* 0x15 */ &v60_disassembler::dopUPDATE, + /* 0x16 */ &v60_disassembler::dopUNHANDLED, + /* 0x17 */ &v60_disassembler::dopUNHANDLED, + /* 0x18 */ &v60_disassembler::dopUNHANDLED, + /* 0x19 */ &v60_disassembler::dopMOVTHB, + /* 0x1A */ &v60_disassembler::dopUNHANDLED, + /* 0x1B */ &v60_disassembler::dopMOVH, + /* 0x1C */ &v60_disassembler::dopMOVSHW, + /* 0x1D */ &v60_disassembler::dopMOVZHW, + /* 0x1E */ &v60_disassembler::dopUNHANDLED, + /* 0x1F */ &v60_disassembler::dopUNHANDLED, + /* 0x20 */ &v60_disassembler::dopINB, + /* 0x21 */ &v60_disassembler::dopOUTB, + /* 0x22 */ &v60_disassembler::dopINH, + /* 0x23 */ &v60_disassembler::dopOUTH, + /* 0x24 */ &v60_disassembler::dopINW, + /* 0x25 */ &v60_disassembler::dopOUTW, + /* 0x26 */ &v60_disassembler::dopUNHANDLED, + /* 0x27 */ &v60_disassembler::dopUNHANDLED, + /* 0x28 */ &v60_disassembler::dopUNHANDLED, + /* 0x29 */ &v60_disassembler::dopMOVTWB, + /* 0x2A */ &v60_disassembler::dopUNHANDLED, + /* 0x2B */ &v60_disassembler::dopMOVTWH, + /* 0x2C */ &v60_disassembler::dopRVBYT, + /* 0x2D */ &v60_disassembler::dopMOVW, + /* 0x2E */ &v60_disassembler::dopUNHANDLED, + /* 0x2F */ &v60_disassembler::dopUNHANDLED, + /* 0x30 */ &v60_disassembler::dopUNHANDLED, + /* 0x31 */ &v60_disassembler::dopUNHANDLED, + /* 0x32 */ &v60_disassembler::dopUNHANDLED, + /* 0x33 */ &v60_disassembler::dopUNHANDLED, + /* 0x34 */ &v60_disassembler::dopUNHANDLED, + /* 0x35 */ &v60_disassembler::dopUNHANDLED, + /* 0x36 */ &v60_disassembler::dopUNHANDLED, + /* 0x37 */ &v60_disassembler::dopUNHANDLED, + /* 0x38 */ &v60_disassembler::dopNOTB, + /* 0x39 */ &v60_disassembler::dopNEGB, + /* 0x3A */ &v60_disassembler::dopNOTH, + /* 0x3B */ &v60_disassembler::dopNEGH, + /* 0x3C */ &v60_disassembler::dopNOTW, + /* 0x3D */ &v60_disassembler::dopNEGW, + /* 0x3E */ &v60_disassembler::dopUNHANDLED, + /* 0x3F */ &v60_disassembler::dopMOVD, + /* 0x40 */ &v60_disassembler::dopMOVEAB, + /* 0x41 */ &v60_disassembler::dopXCHB, + /* 0x42 */ &v60_disassembler::dopMOVEAH, + /* 0x43 */ &v60_disassembler::dopXCHH, + /* 0x44 */ &v60_disassembler::dopMOVEAW, + /* 0x45 */ &v60_disassembler::dopXCHW, + /* 0x46 */ &v60_disassembler::dopUNHANDLED, + /* 0x47 */ &v60_disassembler::dopSETF, + /* 0x48 */ &v60_disassembler::dopBSR, + /* 0x49 */ &v60_disassembler::dopCALL, + /* 0x4A */ &v60_disassembler::dopUPDPSWH, + /* 0x4B */ &v60_disassembler::dopCHLVL, + /* 0x4C */ &v60_disassembler::dopCAXI, + /* 0x4D */ &v60_disassembler::dopCHKAR, + /* 0x4E */ &v60_disassembler::dopCHKAW, + /* 0x4F */ &v60_disassembler::dopCHKAE, + /* 0x50 */ &v60_disassembler::dopREMB, + /* 0x51 */ &v60_disassembler::dopREMUB, + /* 0x52 */ &v60_disassembler::dopREMH, + /* 0x53 */ &v60_disassembler::dopREMUH, + /* 0x54 */ &v60_disassembler::dopREMW, + /* 0x55 */ &v60_disassembler::dopREMUW, + /* 0x56 */ &v60_disassembler::dopUNHANDLED, + /* 0x57 */ &v60_disassembler::dopUNHANDLED, + /* 0x58 */ &v60_disassembler::dop58, + /* 0x59 */ &v60_disassembler::dop59, + /* 0x5A */ &v60_disassembler::dop5A, + /* 0x5B */ &v60_disassembler::dop5B, + /* 0x5C */ &v60_disassembler::dop5C, + /* 0x5D */ &v60_disassembler::dop5D, + /* 0x5E */ &v60_disassembler::dop5E, + /* 0x5F */ &v60_disassembler::dop5F, + /* 0x60 */ &v60_disassembler::dopBV8, + /* 0x61 */ &v60_disassembler::dopBNV8, + /* 0x62 */ &v60_disassembler::dopBL8, + /* 0x63 */ &v60_disassembler::dopBNL8, + /* 0x64 */ &v60_disassembler::dopBE8, + /* 0x65 */ &v60_disassembler::dopBNE8, + /* 0x66 */ &v60_disassembler::dopBNH8, + /* 0x67 */ &v60_disassembler::dopBH8, + /* 0x68 */ &v60_disassembler::dopBN8, + /* 0x69 */ &v60_disassembler::dopBP8, + /* 0x6A */ &v60_disassembler::dopBR8, + /* 0x6B */ &v60_disassembler::dopUNHANDLED, + /* 0x6C */ &v60_disassembler::dopBLT8, + /* 0x6D */ &v60_disassembler::dopBGE8, + /* 0x6E */ &v60_disassembler::dopBLE8, + /* 0x6F */ &v60_disassembler::dopBGT8, + /* 0x70 */ &v60_disassembler::dopBV16, + /* 0x71 */ &v60_disassembler::dopBNV16, + /* 0x72 */ &v60_disassembler::dopBL16, + /* 0x73 */ &v60_disassembler::dopBNL16, + /* 0x74 */ &v60_disassembler::dopBE16, + /* 0x75 */ &v60_disassembler::dopBNE16, + /* 0x76 */ &v60_disassembler::dopBNH16, + /* 0x77 */ &v60_disassembler::dopBH16, + /* 0x78 */ &v60_disassembler::dopBN16, + /* 0x79 */ &v60_disassembler::dopBP16, + /* 0x7A */ &v60_disassembler::dopBR16, + /* 0x7B */ &v60_disassembler::dopUNHANDLED, + /* 0x7C */ &v60_disassembler::dopBLT16, + /* 0x7D */ &v60_disassembler::dopBGE16, + /* 0x7E */ &v60_disassembler::dopBLE16, + /* 0x7F */ &v60_disassembler::dopBGT16, + /* 0x80 */ &v60_disassembler::dopADDB, + /* 0x81 */ &v60_disassembler::dopMULB, + /* 0x82 */ &v60_disassembler::dopADDH, + /* 0x83 */ &v60_disassembler::dopMULH, + /* 0x84 */ &v60_disassembler::dopADDW, + /* 0x85 */ &v60_disassembler::dopMULW, + /* 0x86 */ &v60_disassembler::dopMULX, + /* 0x87 */ &v60_disassembler::dopTEST1, + /* 0x88 */ &v60_disassembler::dopORB, + /* 0x89 */ &v60_disassembler::dopROTB, + /* 0x8A */ &v60_disassembler::dopORH, + /* 0x8B */ &v60_disassembler::dopROTH, + /* 0x8C */ &v60_disassembler::dopORW, + /* 0x8D */ &v60_disassembler::dopROTW, + /* 0x8E */ &v60_disassembler::dopUNHANDLED, + /* 0x8F */ &v60_disassembler::dopUNHANDLED, + /* 0x90 */ &v60_disassembler::dopADDCB, + /* 0x91 */ &v60_disassembler::dopMULUB, + /* 0x92 */ &v60_disassembler::dopADDCH, + /* 0x93 */ &v60_disassembler::dopMULUH, + /* 0x94 */ &v60_disassembler::dopADDCW, + /* 0x95 */ &v60_disassembler::dopMULUW, + /* 0x96 */ &v60_disassembler::dopMULUX, + /* 0x97 */ &v60_disassembler::dopSET1, + /* 0x98 */ &v60_disassembler::dopSUBCB, + /* 0x99 */ &v60_disassembler::dopROTCB, + /* 0x9A */ &v60_disassembler::dopSUBCH, + /* 0x9B */ &v60_disassembler::dopROTCH, + /* 0x9C */ &v60_disassembler::dopSUBCW, + /* 0x9D */ &v60_disassembler::dopROTCW, + /* 0x9E */ &v60_disassembler::dopUNHANDLED, + /* 0x9F */ &v60_disassembler::dopUNHANDLED, + /* 0xA0 */ &v60_disassembler::dopANDB, + /* 0xA1 */ &v60_disassembler::dopDIVB, + /* 0xA2 */ &v60_disassembler::dopANDH, + /* 0xA3 */ &v60_disassembler::dopDIVH, + /* 0xA4 */ &v60_disassembler::dopANDW, + /* 0xA5 */ &v60_disassembler::dopDIVW, + /* 0xA6 */ &v60_disassembler::dopDIVX, + /* 0xA7 */ &v60_disassembler::dopCLR1, + /* 0xA8 */ &v60_disassembler::dopSUBB, + /* 0xA9 */ &v60_disassembler::dopSHLB, + /* 0xAA */ &v60_disassembler::dopSUBH, + /* 0xAB */ &v60_disassembler::dopSHLH, + /* 0xAC */ &v60_disassembler::dopSUBW, + /* 0xAD */ &v60_disassembler::dopSHLW, + /* 0xAE */ &v60_disassembler::dopUNHANDLED, + /* 0xAF */ &v60_disassembler::dopUNHANDLED, + /* 0xB0 */ &v60_disassembler::dopXORB, + /* 0xB1 */ &v60_disassembler::dopDIVUB, + /* 0xB2 */ &v60_disassembler::dopXORH, + /* 0xB3 */ &v60_disassembler::dopDIVUH, + /* 0xB4 */ &v60_disassembler::dopXORW, + /* 0xB5 */ &v60_disassembler::dopDIVUW, + /* 0xB6 */ &v60_disassembler::dopDIVUX, + /* 0xB7 */ &v60_disassembler::dopNOT1, + /* 0xB8 */ &v60_disassembler::dopCMPB, + /* 0xB9 */ &v60_disassembler::dopSHAB, + /* 0xBA */ &v60_disassembler::dopCMPH, + /* 0xBB */ &v60_disassembler::dopSHAH, + /* 0xBC */ &v60_disassembler::dopCMPW, + /* 0xBD */ &v60_disassembler::dopSHAW, + /* 0xBE */ &v60_disassembler::dopUNHANDLED, + /* 0xBF */ &v60_disassembler::dopUNHANDLED, + /* 0xC0 */ &v60_disassembler::dopUNHANDLED, + /* 0xC1 */ &v60_disassembler::dopUNHANDLED, + /* 0xC2 */ &v60_disassembler::dopUNHANDLED, + /* 0xC3 */ &v60_disassembler::dopUNHANDLED, + /* 0xC4 */ &v60_disassembler::dopUNHANDLED, + /* 0xC5 */ &v60_disassembler::dopUNHANDLED, + /* 0xC6 */ &v60_disassembler::dopC6, + /* 0xC7 */ &v60_disassembler::dopC7, + /* 0xC8 */ &v60_disassembler::dopBRK, + /* 0xC9 */ &v60_disassembler::dopBRKV, + /* 0xCA */ &v60_disassembler::dopRSR, + /* 0xCB */ &v60_disassembler::dopTRAPFL, + /* 0xCC */ &v60_disassembler::dopDISPOSE, + /* 0xCD */ &v60_disassembler::dopNOP, + /* 0xCE */ &v60_disassembler::dopUNHANDLED, + /* 0xCF */ &v60_disassembler::dopUNHANDLED, + /* 0xD0 */ &v60_disassembler::dopDECB, + /* 0xD1 */ &v60_disassembler::dopDECB, + /* 0xD2 */ &v60_disassembler::dopDECH, + /* 0xD3 */ &v60_disassembler::dopDECH, + /* 0xD4 */ &v60_disassembler::dopDECW, + /* 0xD5 */ &v60_disassembler::dopDECW, + /* 0xD6 */ &v60_disassembler::dopJMP, + /* 0xD7 */ &v60_disassembler::dopJMP, + /* 0xD8 */ &v60_disassembler::dopINCB, + /* 0xD9 */ &v60_disassembler::dopINCB, + /* 0xDA */ &v60_disassembler::dopINCH, + /* 0xDB */ &v60_disassembler::dopINCH, + /* 0xDC */ &v60_disassembler::dopINCW, + /* 0xDD */ &v60_disassembler::dopINCW, + /* 0xDE */ &v60_disassembler::dopPREPARE, + /* 0xDF */ &v60_disassembler::dopPREPARE, + /* 0xE0 */ &v60_disassembler::dopTASI, + /* 0xE1 */ &v60_disassembler::dopTASI, + /* 0xE2 */ &v60_disassembler::dopRET, + /* 0xE3 */ &v60_disassembler::dopRET, + /* 0xE4 */ &v60_disassembler::dopPOPM, + /* 0xE5 */ &v60_disassembler::dopPOPM, + /* 0xE6 */ &v60_disassembler::dopPOP, + /* 0xE7 */ &v60_disassembler::dopPOP, + /* 0xE8 */ &v60_disassembler::dopJSR, + /* 0xE9 */ &v60_disassembler::dopJSR, + /* 0xEA */ &v60_disassembler::dopRETIU, + /* 0xEB */ &v60_disassembler::dopRETIU, + /* 0xEC */ &v60_disassembler::dopPUSHM, + /* 0xED */ &v60_disassembler::dopPUSHM, + /* 0xEE */ &v60_disassembler::dopPUSH, + /* 0xEF */ &v60_disassembler::dopPUSH, + /* 0xF0 */ &v60_disassembler::dopTESTB, + /* 0xF1 */ &v60_disassembler::dopTESTB, + /* 0xF2 */ &v60_disassembler::dopTESTH, + /* 0xF3 */ &v60_disassembler::dopTESTH, + /* 0xF4 */ &v60_disassembler::dopTESTW, + /* 0xF5 */ &v60_disassembler::dopTESTW, + /* 0xF6 */ &v60_disassembler::dopGETPSW, + /* 0xF7 */ &v60_disassembler::dopGETPSW, + /* 0xF8 */ &v60_disassembler::dopTRAP, + /* 0xF9 */ &v60_disassembler::dopTRAP, + /* 0xFA */ &v60_disassembler::dopRETIS, + /* 0xFB */ &v60_disassembler::dopRETIS, + /* 0xFC */ &v60_disassembler::dopSTTASK, + /* 0xFD */ &v60_disassembler::dopSTTASK, + /* 0xFE */ &v60_disassembler::dopCLRTLB, + /* 0xFF */ &v60_disassembler::dopCLRTLB }; -CPU_DISASSEMBLE(v60) +offs_t v60_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - rombase = oprom; - pcbase = pc; - return dasm_optable[oprom[0]](pc, pc+1, stream) | DASMFLAG_SUPPORTED; + return (this->*dasm_optable[opcodes.r8(pc)])(pc, pc+1, opcodes, stream) | SUPPORTED; } -CPU_DISASSEMBLE(v70) +u32 v60_disassembler::opcode_alignment() const { - rombase = oprom; - pcbase = pc; - return dasm_optable[oprom[0]](pc, pc+1, stream) | DASMFLAG_SUPPORTED; + return 1; } diff --git a/src/devices/cpu/v60/v60d.h b/src/devices/cpu/v60/v60d.h new file mode 100644 index 00000000000..6bbef76f47c --- /dev/null +++ b/src/devices/cpu/v60/v60d.h @@ -0,0 +1,359 @@ +// license:BSD-3-Clause +// copyright-holders:Farfetch'd, R. Belmont + +#ifndef MAME_CPU_V60_V60D_H +#define MAME_CPU_V60_V60D_H + +#pragma once + +class v60_disassembler : public util::disasm_interface +{ +public: + v60_disassembler() = default; + virtual ~v60_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const v60_reg_names[69]; + static u32 (v60_disassembler::*const dasm_optable_58[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_59[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5A[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5B[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5C[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5D[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5E[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_5F[32])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_C6[8])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable_C7[8])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + static u32 (v60_disassembler::*const dasm_optable[256])(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + + u32 dop58(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop58UNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop59(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop59UNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5A(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5AUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5B(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5BUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5C(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5CUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5D(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5DUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5E(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5EUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5F(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dop5FUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopABSFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopABSFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDCW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDDC(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopADDW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDNBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDNBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopANDW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBE16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBE8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBGE16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBGE8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBGT16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBGT8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBH16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBH8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBL16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBL8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBLE16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBLE8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBLT16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBLT8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBN16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBN8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNE16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNE8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNH16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNH8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNL16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNL8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNV16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBNV8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBP16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBP8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBR16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBR8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBRK(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBRKV(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBSR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBV16(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopBV8(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopC6(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopC7(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCALL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCAXI(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCHKAE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCHKAR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCHKAW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCHLVL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCLR1(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCLRTLB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCLRTLBA(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPBFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPBFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPBFZ(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCFB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCFH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCSB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPCSH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCMPW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTDPZ(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTDZP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTLS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTLW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTSL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTSW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTWL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopCVTWS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBGE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBGT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBLE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBLT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBN(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBNE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBNH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBNL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBNV(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDBV(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDECB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDECH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDECW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDISPOSE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVUW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVUX(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopDIVX(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopEXTBFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopEXTBFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopEXTBFZ(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopGETATE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopGETPSW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopGETPTE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopGETRA(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopHALT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINCW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINSBFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINSBFR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopINW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopJMP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopJSR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopLDPR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopLDTASK(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCFDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCFDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCFUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCFUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCSB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCSH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVCUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVEAB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVEAH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVEAW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVSBH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVSBW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVSHW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVTHB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVTWB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVTWH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVZBH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVZBW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMOVZHW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULUW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULUX(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopMULX(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNEGW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOT1(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopNOTW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORNBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORNBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopORW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopOUTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopOUTH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopOUTW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPOP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPOPM(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPREPARE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPUSH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopPUSHM(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMUW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopREMW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRET(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRETIS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRETIU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTCW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopROTW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRSR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRVBIT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopRVBYT(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCH0BSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCH0BSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCH1BSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCH1BSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCHCDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCHCDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCHCUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCHCUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCLFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSCLFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSET1(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSETF(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHAB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHAH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHAW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHLB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHLH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSHLW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSKPCDB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSKPCDH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSKPCUB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSKPCUH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSTPR(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSTTASK(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBCB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBCH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBCW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBDC(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBFS(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBRDC(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopSUBW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTASI(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTEST1(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTESTB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTESTH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTESTW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTRAP(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopTRAPFL(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUNHANDLED(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUPDATE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUPDPSWH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUPDPSWW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopUPDPTE(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXCHB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXCHH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXCHW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORB(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORH(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORNBSD(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORNBSU(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 dopXORW(unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + + void out_AM_Register(int reg, std::ostream &stream); + void out_AM_RegisterIndirect(int reg, int opsize, std::ostream &stream); + void out_AM_RegisterIndirectIndexed(int rn, int rx, int opsize, std::ostream &stream); + void out_AM_Autoincrement(int reg, int opsize, std::ostream &stream); + void out_AM_Autodecrement(int reg, int opsize, std::ostream &stream); + void out_AM_Displacement(int reg, int disp, int opsize, std::ostream &stream); + void out_AM_DisplacementIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream); + void out_AM_PCDisplacement(offs_t pc, int disp, int opsize, std::ostream &stream); + void out_AM_PCDisplacementIndexed(offs_t pc, int disp, int rx, int opsize, std::ostream &stream); + void out_AM_DisplacementIndirect(int reg, int disp, int opsize, std::ostream &stream); + void out_AM_DisplacementIndirectIndexed(int rn, int rx, int disp, int opsize, std::ostream &stream); + void out_AM_PCDisplacementIndirect(offs_t pc, int disp, int opsize, std::ostream &stream); + void out_AM_PCDisplacementIndirectIndexed(offs_t pc, int disp, int rx, int opsize, std::ostream &stream); + void out_AM_DoubleDisplacement(int reg, int disp2, int disp1, int opsize, std::ostream &stream); + void out_AM_PCDoubleDisplacement(offs_t pc, int disp2, int disp1, int opsize, std::ostream &stream); + void out_AM_DirectAddress(unsigned addr, int opsize, std::ostream &stream); + void out_AM_DirectAddressIndexed(unsigned addr, int rx, int opsize, std::ostream &stream); + void out_AM_DirectAddressDeferred(unsigned addr, int opsize, std::ostream &stream); + void out_AM_DirectAddressDeferredIndexed(unsigned addr, int rx, int opsize, std::ostream &stream); + void out_AM_Immediate(unsigned value, int opsize, std::ostream &stream); + u32 decode_AM(unsigned ipc, offs_t pc, int m, int opsize, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F1(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F1F2(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F3(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F4a(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F4b(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F5(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F6(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F7a(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F7b(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + u32 decode_F7c(const char *opnm, int opsize1, int opsize2, unsigned ipc, offs_t pc, const data_buffer &opcodes, std::ostream &stream); + +}; + +#endif diff --git a/src/devices/cpu/v810/v810.cpp b/src/devices/cpu/v810/v810.cpp index fc6aa5897fe..a7662cb251d 100644 --- a/src/devices/cpu/v810/v810.cpp +++ b/src/devices/cpu/v810/v810.cpp @@ -29,6 +29,7 @@ #include "emu.h" #include "v810.h" +#include "v810dasm.h" #include "debugger.h" #define clkIF 3 @@ -54,10 +55,9 @@ device_memory_interface::space_config_vector v810_device::memory_space_config() } -offs_t v810_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *v810_device::create_disassembler() { - extern CPU_DISASSEMBLE( v810 ); - return CPU_DISASSEMBLE_NAME(v810)(this, stream, pc, oprom, opram, options); + return new v810_disassembler; } @@ -1256,7 +1256,7 @@ const v810_device::opcode_func v810_device::s_OpCodeTable[64] = void v810_device::device_start() { m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); m_irq_line = 0; diff --git a/src/devices/cpu/v810/v810.h b/src/devices/cpu/v810/v810.h index e136259cc4a..ad2e91a6617 100644 --- a/src/devices/cpu/v810/v810.h +++ b/src/devices/cpu/v810/v810.h @@ -104,9 +104,7 @@ protected: 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 2; } - 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; + virtual util::disasm_interface *create_disassembler() override; private: typedef uint32_t (v810_device::*opcode_func)(uint32_t op); @@ -120,7 +118,7 @@ private: uint8_t m_irq_state; uint8_t m_nmi_line; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; uint32_t m_PPC; int m_icount; diff --git a/src/devices/cpu/v810/v810dasm.cpp b/src/devices/cpu/v810/v810dasm.cpp index b88600d353e..3e8410881d5 100644 --- a/src/devices/cpu/v810/v810dasm.cpp +++ b/src/devices/cpu/v810/v810dasm.cpp @@ -6,8 +6,7 @@ *******************************************/ #include "emu.h" -#include "debugger.h" -#include "v810.h" +#include "v810dasm.h" #define I5(x) (((x)&0x1f)|(((x)&0x10)?0xffffffe0:0)) #define UI5(x) ((x)&0x1f) @@ -17,7 +16,7 @@ #define D26(x,y) ((y)|((x&0x3ff)<<16 )|((x&0x200)?0xfc000000:0)) #define D9(x) ((x&0x1ff)|((x&0x100)?0xfffffe00:0)) -static const char *const dRegs[]= +const char *const v810_disassembler::dRegs[]= { "R0","R1","R2","SP","R4", "R5","R6","R7","R8","R9", @@ -39,13 +38,18 @@ static const char *const dRegs[]= #define GET2s(opcode) dRegs[((opcode)>>5)&0x1f] #define GETRs(opcode) dRegs[32+((opcode)&0x1f)] -CPU_DISASSEMBLE(v810) +u32 v810_disassembler::opcode_alignment() const +{ + return 2; +} + +offs_t v810_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; uint32_t opc,opc2; unsigned size; - opc = oprom[0] | (oprom[1] << 8); - opc2 = oprom[2] | (oprom[3] << 8); + opc = opcodes.r16(pc); + opc2 = opcodes.r16(pc+2); switch(opc>>10) { @@ -55,7 +59,7 @@ CPU_DISASSEMBLE(v810) case 0x03: util::stream_format(stream,"CMP %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x04: util::stream_format(stream,"SHL %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x05: util::stream_format(stream,"SHR %s,%s",GET1s(opc),GET2s(opc)); size=2; break; - case 0x06: util::stream_format(stream,"JMP [%s]",GET1s(opc)); size=2; if ((opc&0x1f) == 31) flags = DASMFLAG_STEP_OUT; break; + case 0x06: util::stream_format(stream,"JMP [%s]",GET1s(opc)); size=2; if ((opc&0x1f) == 31) flags = STEP_OUT; break; case 0x07: util::stream_format(stream,"SAR %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x08: util::stream_format(stream,"MUL %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x09: util::stream_format(stream,"DIV %s,%s",GET1s(opc),GET2s(opc)); size=2; break; @@ -74,7 +78,7 @@ CPU_DISASSEMBLE(v810) case 0x16: util::stream_format(stream,"EI"); size=2; break; case 0x17: util::stream_format(stream,"SAR %X,%s",UI5(opc),GET2s(opc)); size=2; break; case 0x18: util::stream_format(stream,"TRAP %X",I5(opc)); size=2; break; - case 0x19: util::stream_format(stream,"RETI"); size=2; flags = DASMFLAG_STEP_OUT; break; + case 0x19: util::stream_format(stream,"RETI"); size=2; flags = STEP_OUT; break; case 0x1a: util::stream_format(stream,"HALT"); size=2; break; case 0x1b: util::stream_format(stream,"Unk 0x1B"); size=2; break; case 0x1c: util::stream_format(stream,"LDSR %s,%s",GET2s(opc),GETRs(opc));size=2; break; @@ -134,7 +138,7 @@ CPU_DISASSEMBLE(v810) case 0x28: util::stream_format(stream,"MOVEA %X, %s, %s",I16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x29: util::stream_format(stream,"ADDI %X, %s, %s",I16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2a: util::stream_format(stream,"JR %X",pc+D26(opc,opc2));size=4; break; - case 0x2b: util::stream_format(stream,"JAL %X",pc+D26(opc,opc2));size=4; flags = DASMFLAG_STEP_OVER; break; + case 0x2b: util::stream_format(stream,"JAL %X",pc+D26(opc,opc2));size=4; flags = STEP_OVER; break; case 0x2c: util::stream_format(stream,"ORI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2d: util::stream_format(stream,"ANDI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2e: util::stream_format(stream,"XORI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; @@ -173,5 +177,5 @@ CPU_DISASSEMBLE(v810) default : size=2; } - return size | flags | DASMFLAG_SUPPORTED; + return size | flags | SUPPORTED; } diff --git a/src/devices/cpu/v810/v810dasm.h b/src/devices/cpu/v810/v810dasm.h new file mode 100644 index 00000000000..3daed05a131 --- /dev/null +++ b/src/devices/cpu/v810/v810dasm.h @@ -0,0 +1,27 @@ +// license:BSD-3-Clause +// copyright-holders:Tomasz Slanina +/******************************************** + NEC V810 (upd70732) disassembler + Tomasz Slanina - analog[at]op.pl +*******************************************/ + + +#ifndef MAME_CPU_V810_V810DASM_H +#define MAME_CPU_V810_V810DASM_H + +#pragma once + +class v810_disassembler : public util::disasm_interface +{ +public: + v810_disassembler() = default; + virtual ~v810_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const dRegs[]; +}; + +#endif diff --git a/src/devices/cpu/x86log.cpp b/src/devices/cpu/x86log.cpp index 03552877128..b97f2553f11 100644 --- a/src/devices/cpu/x86log.cpp +++ b/src/devices/cpu/x86log.cpp @@ -96,6 +96,30 @@ void x86log_mark_as_data(x86log_context *log, x86code *base, x86code *end, int s of code and reset accumulated information -------------------------------------------------*/ +namespace { + class x86_buf : public util::disasm_interface::data_buffer { + public: + x86_buf(offs_t _base_pc, const u8 *_buf) : base_pc(_base_pc), buf(_buf) {} + ~x86_buf() = default; + + // We know we're on a x86, so we can go short + virtual u8 r8 (offs_t pc) const override { return *(u8 *)(buf + pc - base_pc); } + virtual u16 r16(offs_t pc) const override { return *(u16 *)(buf + pc - base_pc); } + virtual u32 r32(offs_t pc) const override { return *(u32 *)(buf + pc - base_pc); } + virtual u64 r64(offs_t pc) const override { return *(u64 *)(buf + pc - base_pc); } + + private: + offs_t base_pc; + const u8 *buf; + }; + + class x86_config : public i386_disassembler::config { + public: + ~x86_config() = default; + virtual int get_mode() const override { return sizeof(void *) * 8; }; + }; +} + void x86log_disasm_code_range(x86log_context *log, const char *label, x86code *start, x86code *stop) { const log_comment *lastcomment = &log->comment_list[log->comment_count]; @@ -147,7 +171,11 @@ void x86log_disasm_code_range(x86log_context *log, const char *label, x86code *s else { std::stringstream strbuffer; - bytes = i386_dasm_one_ex(strbuffer, (uintptr_t)cur, cur, sizeof(void *) * 8) & DASMFLAG_LENGTHMASK; + offs_t pc = (uintptr_t)cur; + x86_buf buf(pc, cur); + x86_config conf; + i386_disassembler dis(&conf); + bytes = dis.disassemble(strbuffer, pc, buf, buf) & util::disasm_interface::LENGTHMASK; buffer = strbuffer.str(); } diff --git a/src/devices/cpu/z180/z180.cpp b/src/devices/cpu/z180/z180.cpp index a1dda238c60..ba25e51152e 100644 --- a/src/devices/cpu/z180/z180.cpp +++ b/src/devices/cpu/z180/z180.cpp @@ -34,7 +34,7 @@ Package: P = 60-Pin Plastic DIP Temp: S = 0C to +70C E = -40C to +85C -Environmanetal Flow: C = Plastic Standard +Environmental Flow: C = Plastic Standard Example from Ms.Pac-Man/Galaga - 20 year Reunion hardare (see src/mame/drivers/20pacgal.c): @@ -52,6 +52,7 @@ Hitachi HD647180 series: #include "emu.h" #include "z180.h" +#include "z180dasm.h" #include "debugger.h" //#define VERBOSE 1 @@ -89,14 +90,11 @@ z180_device::z180_device(const machine_config &mconfig, const char *tag, device_ { } - -offs_t z180_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *z180_device::create_disassembler() { - extern CPU_DISASSEMBLE( z180 ); - return CPU_DISASSEMBLE_NAME(z180)(this, stream, pc, oprom, opram, options); + return new z180_disassembler; } - #define CF 0x01 #define NF 0x02 #define PF 0x04 @@ -683,7 +681,7 @@ bool z180_device::get_tend1() /* 36 refresh control register */ #define Z180_RCR_REFE 0x80 -#define Z180_RCR_REFW 0x80 +#define Z180_RCR_REFW 0x40 #define Z180_RCR_CYC 0x03 #define Z180_RCR_RESET 0xc0 @@ -1602,6 +1600,7 @@ int z180_device::z180_dma0(int max_cycles) while (count > 0) { + m_extra_cycles = 0; /* last transfer happening now? */ if (bcr0 == 1) { @@ -1611,20 +1610,24 @@ int z180_device::z180_dma0(int max_cycles) { case 0x00: /* memory SAR0+1 to memory DAR0+1 */ m_program->write_byte(dar0++, m_program->read_byte(sar0++)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x04: /* memory SAR0-1 to memory DAR0+1 */ m_program->write_byte(dar0++, m_program->read_byte(sar0--)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x08: /* memory SAR0 fixed to memory DAR0+1 */ m_program->write_byte(dar0++, m_program->read_byte(sar0)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x0c: /* I/O SAR0 fixed to memory DAR0+1 */ if (m_iol & Z180_DREQ0) { m_program->write_byte(dar0++, IN(sar0)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1636,20 +1639,24 @@ int z180_device::z180_dma0(int max_cycles) break; case 0x10: /* memory SAR0+1 to memory DAR0-1 */ m_program->write_byte(dar0--, m_program->read_byte(sar0++)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x14: /* memory SAR0-1 to memory DAR0-1 */ m_program->write_byte(dar0--, m_program->read_byte(sar0--)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x18: /* memory SAR0 fixed to memory DAR0-1 */ m_program->write_byte(dar0--, m_program->read_byte(sar0)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x1c: /* I/O SAR0 fixed to memory DAR0-1 */ if (m_iol & Z180_DREQ0) { m_program->write_byte(dar0--, IN(sar0)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1661,10 +1668,12 @@ int z180_device::z180_dma0(int max_cycles) break; case 0x20: /* memory SAR0+1 to memory DAR0 fixed */ m_program->write_byte(dar0, m_program->read_byte(sar0++)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x24: /* memory SAR0-1 to memory DAR0 fixed */ m_program->write_byte(dar0, m_program->read_byte(sar0--)); + cycles += (IO_DCNTL >> 6) * 2; // memory wait states bcr0--; break; case 0x28: /* reserved */ @@ -1675,6 +1684,7 @@ int z180_device::z180_dma0(int max_cycles) if (m_iol & Z180_DREQ0) { OUT(dar0, m_program->read_byte(sar0++)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1688,6 +1698,7 @@ int z180_device::z180_dma0(int max_cycles) if (m_iol & Z180_DREQ0) { OUT(dar0, m_program->read_byte(sar0--)); + cycles += IO_DCNTL >> 6; // memory wait states bcr0--; /* edge sensitive DREQ0 ? */ if (IO_DCNTL & Z180_DCNTL_DMS0) @@ -1703,7 +1714,7 @@ int z180_device::z180_dma0(int max_cycles) break; } count--; - cycles += 6; + cycles += 6 + m_extra_cycles; // use extra_cycles for I/O wait states if (cycles > max_cycles) break; } @@ -1756,6 +1767,8 @@ int z180_device::z180_dma1() m_iol |= Z180_TEND1; } + m_extra_cycles = 0; + switch (IO_DCNTL & (Z180_DCNTL_DIM1 | Z180_DCNTL_DIM0)) { case 0x00: /* memory MAR1+1 to I/O IAR1 fixed */ @@ -1772,6 +1785,9 @@ int z180_device::z180_dma1() break; } + cycles += IO_DCNTL >> 6; // memory wait states + cycles += m_extra_cycles; // use extra_cycles for I/O wait states + /* edge sensitive DREQ1 ? */ if (IO_DCNTL & Z180_DCNTL_DIM1) m_iol &= ~Z180_DREQ1; @@ -1919,7 +1935,6 @@ void z180_device::z180_write_iolines(uint32_t data) } } - void z180_device::device_start() { int i, p; @@ -2001,9 +2016,9 @@ void z180_device::device_start() } m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_oprogram = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program; - m_odirect = &m_oprogram->direct(); + m_odirect = m_oprogram->direct<0>(); m_iospace = &space(AS_IO); /* set up the state table */ @@ -2503,14 +2518,16 @@ again: ****************************************************************************/ void z180_device::execute_burn(int32_t cycles) { + int extra_cycles = IO_DCNTL >> 6; // memory wait states + /* FIXME: This is not appropriate for dma */ while ( (cycles > 0) ) { - handle_io_timers(3); + handle_io_timers(3 + extra_cycles); /* NOP takes 3 cycles per instruction */ m_R += 1; - m_icount -= 3; - cycles -= 3; + m_icount -= 3 + extra_cycles; + cycles -= 3 + extra_cycles; } } @@ -2538,12 +2555,12 @@ void z180_device::execute_set_input(int irqline, int state) /* the main execute loop will take the interrupt */ } else if(irqline == Z180_INPUT_LINE_DREQ0) { - auto iol = m_iol & ~Z180_DREQ0; + uint32_t iol = m_iol & ~Z180_DREQ0; if(state == ASSERT_LINE) iol |= Z180_DREQ0; z180_write_iolines(iol); } else if(irqline == Z180_INPUT_LINE_DREQ1) { - auto iol = m_iol & ~Z180_DREQ1; + uint32_t iol = m_iol & ~Z180_DREQ1; if(state == ASSERT_LINE) iol |= Z180_DREQ1; z180_write_iolines(iol); diff --git a/src/devices/cpu/z180/z180.h b/src/devices/cpu/z180/z180.h index dca5c963539..57ee654efa8 100644 --- a/src/devices/cpu/z180/z180.h +++ b/src/devices/cpu/z180/z180.h @@ -158,9 +158,7 @@ protected: 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 1; } - 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; + virtual util::disasm_interface *create_disassembler() override; private: address_space_config m_program_config; @@ -188,9 +186,9 @@ private: uint8_t m_dma0_cnt; /* dma0 counter / divide by 20 */ uint8_t m_dma1_cnt; /* dma1 counter / divide by 20 */ address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_oprogram; - direct_read_data *m_odirect; + direct_read_data<0> *m_odirect; address_space *m_iospace; uint8_t m_rtemp; uint32_t m_ioltemp; @@ -202,6 +200,9 @@ private: static const opcode_func s_z180ops[6][0x100]; inline void z180_mmu(); + inline u8 RM(offs_t addr); + inline u8 IN(u16 port); + inline void OUT(u16 port, u8 value); inline void RM16( offs_t addr, PAIR *r ); inline void WM16( offs_t addr, PAIR *r ); inline uint8_t ROP(); diff --git a/src/devices/cpu/z180/z180dasm.cpp b/src/devices/cpu/z180/z180dasm.cpp index c5a3d9f0186..521ec1bfe41 100644 --- a/src/devices/cpu/z180/z180dasm.cpp +++ b/src/devices/cpu/z180/z180dasm.cpp @@ -8,23 +8,9 @@ *****************************************************************************/ #include "emu.h" -#include "debugger.h" -#include "z180.h" +#include "z180dasm.h" -enum e_mnemonics { - zADC ,zADD ,zAND ,zBIT ,zCALL ,zCCF ,zCP ,zCPD , - zCPDR ,zCPI ,zCPIR ,zCPL ,zDAA ,zDB ,zDEC ,zDI , - zDJNZ ,zEI ,zEX ,zEXX ,zHLT ,zIM ,zIN ,zIN0 , - zINC ,zIND ,zINDR ,zINI ,zINIR ,zJP ,zJR ,zLD , - zLDD ,zLDDR ,zLDI ,zLDIR ,zMLT ,zNEG ,zNOP ,zOR , - zOTDM ,zOTDMR ,zOTDR ,zOTIM ,zOTIMR ,zOTIR ,zOUT ,zOUT0 , - zOUTD ,zOUTI ,zPOP ,zPUSH ,zRES ,zRET ,zRETI ,zRETN , - zRL ,zRLA ,zRLC ,zRLCA ,zRLD ,zRR ,zRRA ,zRRC , - zRRCA ,zRRD ,zRST ,zSBC ,zSCF ,zSET ,zSLA ,zSLL , - zSLP ,zSRA ,zSRL ,zSUB ,zTST ,zTSTIO ,zXOR -}; - -static const char *const s_mnemonic[] = { +const char *const z180_disassembler::s_mnemonic[] = { "adc" ,"add" ,"and" ,"bit" ,"call" ,"ccf" ,"cp" ,"cpd" , "cpdr" ,"cpi" ,"cpir" ,"cpl" ,"daa" ,"db" ,"dec" ,"di" , "djnz" ,"ei" ,"ex" ,"exx" ,"halt" ,"im" ,"in" ,"in0" , @@ -37,12 +23,7 @@ static const char *const s_mnemonic[] = { "slp" ,"sra" ,"srl" ,"sub" ,"tst" ,"tstio","xor " }; -struct z80dasm { - uint8_t mnemonic; - const char *arguments; -}; - -static const z80dasm mnemonic_xx_cb[256]= { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_xx_cb[256]= { {zRLC,"b=Y"}, {zRLC,"c=Y"}, {zRLC,"d=Y"}, {zRLC,"e=Y"}, {zRLC,"h=Y"}, {zRLC,"l=Y"}, {zRLC,"Y"}, {zRLC,"a=Y"}, {zRRC,"b=Y"}, {zRRC,"c=Y"}, {zRRC,"d=Y"}, {zRRC,"e=Y"}, @@ -109,7 +90,7 @@ static const z80dasm mnemonic_xx_cb[256]= { {zSET,"h=7,Y"}, {zSET,"l=7,Y"}, {zSET,"7,Y"}, {zSET,"a=7,Y"} }; -static const z80dasm mnemonic_cb[256] = { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_cb[256] = { {zRLC,"b"}, {zRLC,"c"}, {zRLC,"d"}, {zRLC,"e"}, {zRLC,"h"}, {zRLC,"l"}, {zRLC,"(hl)"}, {zRLC,"a"}, {zRRC,"b"}, {zRRC,"c"}, {zRRC,"d"}, {zRRC,"e"}, @@ -176,7 +157,7 @@ static const z80dasm mnemonic_cb[256] = { {zSET,"7,h"}, {zSET,"7,l"}, {zSET,"7,(hl)"},{zSET,"7,a"} }; -static const z80dasm mnemonic_ed[256]= { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_ed[256]= { {zIN0,"b,(B)"}, {zOUT0,"(B),b"},{zDB,"?"}, {zDB,"?"}, {zTST,"b"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zIN0,"c,(B)"}, {zOUT0,"(B),c"},{zDB,"?"}, {zDB,"?"}, @@ -243,7 +224,7 @@ static const z80dasm mnemonic_ed[256]= { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"} }; -static const z80dasm mnemonic_xx[256]= { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_xx[256]= { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zADD,"I,bc"}, {zDB,"?"}, {zDB,"?"}, @@ -310,7 +291,7 @@ static const z80dasm mnemonic_xx[256]= { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"} }; -static const z80dasm mnemonic_main[256]= { +const z180_disassembler::z80dasm z180_disassembler::mnemonic_main[256]= { {zNOP,nullptr}, {zLD,"bc,N"}, {zLD,"(bc),a"}, {zINC,"bc"}, {zINC,"b"}, {zDEC,"b"}, {zLD,"b,B"}, {zRLCA,nullptr}, {zEX,"af,af'"}, {zADD,"hl,bc"}, {zLD,"a,(bc)"}, {zDEC,"bc"}, @@ -377,12 +358,12 @@ static const z80dasm mnemonic_main[256]= { {zCALL,"m,A"}, {zDB,"fd"}, {zCP,"B"}, {zRST,"V"} }; -static char sign(int8_t offset) +char z180_disassembler::sign(int8_t offset) { return (offset < 0)? '-':'+'; } -static int offs(int8_t offset) +int z180_disassembler::offs(int8_t offset) { if (offset < 0) return -offset; return offset; @@ -391,49 +372,48 @@ static int offs(int8_t offset) /**************************************************************************** * Disassemble opcode at PC and return number of bytes it takes ****************************************************************************/ -CPU_DISASSEMBLE(z180) +offs_t z180_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { const z80dasm *d; const char *src, *ixy; - unsigned PC = pc; int8_t offset = 0; uint8_t op, op1 = 0; uint16_t ea; - int pos = 0; + offs_t pos = pc; uint32_t flags = 0; ixy = "oops!!"; - op = oprom[pos++]; + op = opcodes.r8(pos++); switch (op) { case 0xcb: - op = oprom[pos++]; + op = opcodes.r8(pos++); d = &mnemonic_cb[op]; break; case 0xed: - op1 = oprom[pos++]; + op1 = opcodes.r8(pos++); d = &mnemonic_ed[op1]; break; case 0xdd: ixy = "ix"; - op1 = oprom[pos++]; + op1 = opcodes.r8(pos++); if( op1 == 0xcb ) { - offset = (int8_t) opram[pos++]; - op1 = opram[pos++]; /* fourth byte from opbase.ram! */ + offset = (int8_t) params.r8(pos++); + op1 = params.r8(pos++); /* fourth byte from opbase.ram! */ d = &mnemonic_xx_cb[op1]; } else d = &mnemonic_xx[op1]; break; case 0xfd: ixy = "iy"; - op1 = oprom[pos++]; + op1 = opcodes.r8(pos++); if( op1 == 0xcb ) { - offset = (int8_t) opram[pos++]; - op1 = opram[pos++]; /* fourth byte from opbase.ram! */ + offset = (int8_t) params.r8(pos++); + op1 = params.r8(pos++); /* fourth byte from opbase.ram! */ d = &mnemonic_xx_cb[op1]; } else d = &mnemonic_xx[op1]; @@ -455,25 +435,25 @@ CPU_DISASSEMBLE(z180) util::stream_format(stream, "$%02x,$%02x", op, op1); break; case 'A': - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; case 'B': /* Byte op arg */ - ea = opram[pos++]; + ea = params.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case 'N': /* Immediate 16 bit */ - ea = opram[pos] + ( opram[pos+1] << 8 ); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%04X", ea); break; case 'O': /* Offset relative to PC */ - offset = (int8_t) opram[pos++]; - util::stream_format(stream, "$%05X", PC + offset + 2); + offset = (int8_t) params.r8(pos++); + util::stream_format(stream, "$%05X", pc + offset + 2); break; case 'P': /* Port number */ - ea = opram[pos++]; + ea = params.r8(pos++); util::stream_format(stream, "$%02X", ea); break; case 'V': /* Restart vector */ @@ -481,12 +461,12 @@ CPU_DISASSEMBLE(z180) util::stream_format(stream, "$%02X", ea); break; case 'W': /* Memory address word */ - ea = opram[pos] + (opram[pos+1] << 8); + ea = params.r16(pos); pos += 2; util::stream_format(stream, "$%05X", ea); break; case 'X': - offset = (int8_t) opram[pos++]; + offset = (int8_t) params.r8(pos++); case 'Y': util::stream_format(stream,"(%s%c$%02x)", ixy, sign(offset), offs(offset)); break; @@ -507,9 +487,14 @@ CPU_DISASSEMBLE(z180) if (d->mnemonic == zCALL || d->mnemonic == zCPDR || d->mnemonic == zCPIR || d->mnemonic == zDJNZ || d->mnemonic == zHLT || d->mnemonic == zINDR || d->mnemonic == zINIR || d->mnemonic == zLDDR || d->mnemonic == zLDIR || d->mnemonic == zOTDR || d->mnemonic == zOTIR || d->mnemonic == zRST) - flags = DASMFLAG_STEP_OVER; + flags = STEP_OVER; else if (d->mnemonic == zRETN || d->mnemonic == zRET || d->mnemonic == zRETI) - flags = DASMFLAG_STEP_OUT; + flags = STEP_OUT; - return pos | flags | DASMFLAG_SUPPORTED; + return (pos - pc) | flags | SUPPORTED; +} + +u32 z180_disassembler::opcode_alignment() const +{ + return 1; } diff --git a/src/devices/cpu/z180/z180dasm.h b/src/devices/cpu/z180/z180dasm.h new file mode 100644 index 00000000000..a13c7d92fe1 --- /dev/null +++ b/src/devices/cpu/z180/z180dasm.h @@ -0,0 +1,54 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * z180dasm.c + * Portable Z8x180 disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_Z180_Z180DASM_H +#define MAME_CPU_Z180_Z180DASM_H + +#pragma once + +class z180_disassembler : public util::disasm_interface +{ +public: + z180_disassembler() = default; + virtual ~z180_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct z80dasm { + uint8_t mnemonic; + const char *arguments; + }; + + enum e_mnemonics { + zADC ,zADD ,zAND ,zBIT ,zCALL ,zCCF ,zCP ,zCPD , + zCPDR ,zCPI ,zCPIR ,zCPL ,zDAA ,zDB ,zDEC ,zDI , + zDJNZ ,zEI ,zEX ,zEXX ,zHLT ,zIM ,zIN ,zIN0 , + zINC ,zIND ,zINDR ,zINI ,zINIR ,zJP ,zJR ,zLD , + zLDD ,zLDDR ,zLDI ,zLDIR ,zMLT ,zNEG ,zNOP ,zOR , + zOTDM ,zOTDMR ,zOTDR ,zOTIM ,zOTIMR ,zOTIR ,zOUT ,zOUT0 , + zOUTD ,zOUTI ,zPOP ,zPUSH ,zRES ,zRET ,zRETI ,zRETN , + zRL ,zRLA ,zRLC ,zRLCA ,zRLD ,zRR ,zRRA ,zRRC , + zRRCA ,zRRD ,zRST ,zSBC ,zSCF ,zSET ,zSLA ,zSLL , + zSLP ,zSRA ,zSRL ,zSUB ,zTST ,zTSTIO ,zXOR + }; + + static const char *const s_mnemonic[]; + static const z80dasm mnemonic_xx_cb[256]; + static const z80dasm mnemonic_cb[256]; + static const z80dasm mnemonic_ed[256]; + static const z80dasm mnemonic_xx[256]; + static const z80dasm mnemonic_main[256]; + + static char sign(int8_t offset); + static int offs(int8_t offset); +}; + +#endif diff --git a/src/devices/cpu/z180/z180ops.h b/src/devices/cpu/z180/z180ops.h index 9ffe45cc42d..1c1fa8322f6 100644 --- a/src/devices/cpu/z180/z180ops.h +++ b/src/devices/cpu/z180/z180ops.h @@ -22,17 +22,27 @@ /*************************************************************** * Input a byte from given I/O port ***************************************************************/ -#define IN(port) \ - (((port ^ IO_IOCR) & 0xffc0) == 0) ? \ - z180_readcontrol(port) : m_iospace->read_byte(port) +inline u8 z180_device::IN(u16 port) +{ + if(((port ^ IO_IOCR) & 0xffc0) == 0) + return z180_readcontrol(port); + m_extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states + return m_iospace->read_byte(port); +} /*************************************************************** * Output a byte to given I/O port ***************************************************************/ -#define OUT(port,value) \ - if (((port ^ IO_IOCR) & 0xffc0) == 0) \ - z180_writecontrol(port,value); \ - else m_iospace->write_byte(port,value) +inline void z180_device::OUT(u16 port, u8 value) +{ + if (((port ^ IO_IOCR) & 0xffc0) == 0) { + z180_writecontrol(port,value); + } else + { + m_extra_cycles += ((IO_DCNTL & (Z180_DCNTL_IWI1 | Z180_DCNTL_IWI0)) >> 4) + 1; // external I/O wait states + m_iospace->write_byte(port, value); + } +} /*************************************************************** * MMU calculate the memory management lookup table @@ -68,12 +78,16 @@ void z180_device::z180_mmu() /*************************************************************** * Read a byte from given memory location ***************************************************************/ -#define RM(addr) m_program->read_byte(MMU_REMAP_ADDR(addr)) +inline u8 z180_device::RM(offs_t addr) +{ + m_extra_cycles += IO_DCNTL >> 6; // memory wait states + return m_program->read_byte(MMU_REMAP_ADDR(addr)); +} /*************************************************************** * Write a byte to given memory location ***************************************************************/ -#define WM(addr,value) m_program->write_byte(MMU_REMAP_ADDR(addr),value) +#define WM(addr,value) m_extra_cycles += IO_DCNTL >> 6; /* memory wait states */ m_program->write_byte(MMU_REMAP_ADDR(addr),value) /*************************************************************** * Read a word from given memory location @@ -102,6 +116,7 @@ uint8_t z180_device::ROP() { offs_t addr = _PCD; _PC++; + m_extra_cycles += IO_DCNTL >> 6; // memory wait states return m_odirect->read_byte(MMU_REMAP_ADDR(addr)); } @@ -115,6 +130,7 @@ uint8_t z180_device::ARG() { offs_t addr = _PCD; _PC++; + m_extra_cycles += IO_DCNTL >> 6; // memory wait states return m_direct->read_byte(MMU_REMAP_ADDR(addr)); } @@ -122,6 +138,7 @@ uint32_t z180_device::ARG16() { offs_t addr = _PCD; _PC += 2; + m_extra_cycles += (IO_DCNTL >> 6) * 2; // memory wait states return m_direct->read_byte(MMU_REMAP_ADDR(addr)) | (m_direct->read_byte(MMU_REMAP_ADDR(addr+1)) << 8); } diff --git a/src/devices/cpu/z8/z8.cpp b/src/devices/cpu/z8/z8.cpp index 5ef2c5c505d..1f21ebbab49 100644 --- a/src/devices/cpu/z8/z8.cpp +++ b/src/devices/cpu/z8/z8.cpp @@ -22,6 +22,7 @@ #include "emu.h" #include "z8.h" +#include "z8dasm.h" #include "debugger.h" /*************************************************************************** @@ -207,13 +208,12 @@ z8681_device::z8681_device(const machine_config &mconfig, const char *tag, devic { } - -offs_t z8_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +util::disasm_interface *z8_device::create_disassembler() { - extern CPU_DISASSEMBLE( z8 ); - return CPU_DISASSEMBLE_NAME(z8)(this, stream, pc, oprom, opram, options); + return new z8_disassembler; } + device_memory_interface::space_config_vector z8_device::memory_space_config() const { // Separate data space is optional @@ -778,7 +778,7 @@ void z8_device::device_start() /* find address spaces */ m_program = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_data = has_space(AS_DATA) ? &space(AS_DATA) : m_program; /* allocate timers */ diff --git a/src/devices/cpu/z8/z8.h b/src/devices/cpu/z8/z8.h index b7064c82ae7..1f6f8a7c890 100644 --- a/src/devices/cpu/z8/z8.h +++ b/src/devices/cpu/z8/z8.h @@ -91,9 +91,7 @@ protected: 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 1; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 3; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; DECLARE_ADDRESS_MAP(program_2kb, 8); DECLARE_ADDRESS_MAP(program_4kb, 8); @@ -103,7 +101,7 @@ private: address_space_config m_data_config; address_space *m_program; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_data; // callbacks diff --git a/src/devices/cpu/z8/z8dasm.cpp b/src/devices/cpu/z8/z8dasm.cpp index 8cd29344f2a..a832dab8fe9 100644 --- a/src/devices/cpu/z8/z8dasm.cpp +++ b/src/devices/cpu/z8/z8dasm.cpp @@ -1,14 +1,14 @@ // license:BSD-3-Clause // copyright-holders:Curt Coder + #include "emu.h" -#include "debugger.h" -#include "z8.h" +#include "z8dasm.h" /*************************************************************************** CONSTANTS ***************************************************************************/ -static const char *const REGISTER_NAME[256] = +const char *const z8_disassembler::REGISTER_NAME[256] = { "P0", "P1", "P2", "P3", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", @@ -28,7 +28,7 @@ static const char *const REGISTER_NAME[256] = "SIO", "TMR", "T1", "PRE1", "T0", "PRE0", "P2M", "P3M", "P01M", "IPR", "IRQ", "IMR", "FLAGS", "RP", "SPH", "SPL" }; -static const char *const CONDITION_CODE[16] = +const char *const z8_disassembler::CONDITION_CODE[16] = { "F", "LT", "LE", "ULE", "OV", "MI", "Z", "C", "", "GE", "GT", "UGT", "NOV", "PL", "NZ", "NC" @@ -50,8 +50,8 @@ static const char *const CONDITION_CODE[16] = #define DA "%04Xh" #define RA "%04Xh" -#define B0 oprom[0] -#define B1 oprom[1] +#define B0 opcodes.r8(pos) +#define B1 opcodes.r8(pos+1) #define B0H (B0 >> 4) #define B0L (B0 & 0x0f) #define OPH (opcode >> 4) @@ -74,19 +74,24 @@ static const char *const CONDITION_CODE[16] = #define illegal util::stream_format(stream, "Illegal") #define mnemonic(_mnemonic) util::stream_format(stream, "%-5s", _mnemonic) -#define bytes(_count) oprom += (_count - 1) -#define step_over flags = DASMFLAG_STEP_OVER -#define step_out flags = DASMFLAG_STEP_OUT +#define bytes(_count) pos += (_count - 1) +#define step_over flags = STEP_OVER +#define step_out flags = STEP_OUT /*************************************************************************** DISASSEMBLER ***************************************************************************/ -CPU_DISASSEMBLE(z8) +u32 z8_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t z8_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - const uint8_t *startrom = oprom; + offs_t pos = pc; uint32_t flags = 0; - uint8_t opcode = *oprom++; + uint8_t opcode = opcodes.r8(pos++); int argc = 0; switch (pc) @@ -97,7 +102,7 @@ CPU_DISASSEMBLE(z8) case 0x0006: case 0x0008: case 0x000a: - util::stream_format(stream, "IRQ%u Vector %04Xh", pc / 2, opcode << 8 | *oprom++); break; + util::stream_format(stream, "IRQ%u Vector %04Xh", pc / 2, opcode << 8 | opcodes.r8(pos++)); break; default: switch (opcode) { @@ -375,5 +380,5 @@ CPU_DISASSEMBLE(z8) } } - return (oprom - startrom) | flags | DASMFLAG_SUPPORTED; + return (pos - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/z8/z8dasm.h b/src/devices/cpu/z8/z8dasm.h new file mode 100644 index 00000000000..653b6e0cb26 --- /dev/null +++ b/src/devices/cpu/z8/z8dasm.h @@ -0,0 +1,24 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder + +#ifndef MAME_CPU_Z8_Z8DASM_H +#define MAME_CPU_Z8_Z8DASM_H + +#pragma once + +class z8_disassembler : public util::disasm_interface +{ +public: + z8_disassembler() = default; + virtual ~z8_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + static const char *const REGISTER_NAME[256]; + static const char *const CONDITION_CODE[16]; + +}; + +#endif diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp index 794c7800800..3b2fcd99761 100644 --- a/src/devices/cpu/z80/z80.cpp +++ b/src/devices/cpu/z80/z80.cpp @@ -110,6 +110,7 @@ #include "emu.h" #include "debugger.h" #include "z80.h" +#include "z80dasm.h" #define VERBOSE 0 @@ -208,7 +209,7 @@ static const uint8_t cc_op[0x100] = { 5,10,10,10,10,11, 7,11, 5,10,10, 0,10,17, 7,11, /* cb -> cc_cb */ 5,10,10,11,10,11, 7,11, 5, 4,10,11,10, 0, 7,11, /* dd -> cc_xy */ 5,10,10,19,10,11, 7,11, 5, 4,10, 4,10, 0, 7,11, /* ed -> cc_ed */ - 5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11 /* fd -> cc_xy */ + 5,10,10, 4,10,11, 7,11, 5, 6,10, 4,10, 0, 7,11 /* fd -> cc_xy */ }; static const uint8_t cc_cb[0x100] = { @@ -235,14 +236,14 @@ static const uint8_t cc_ed[0x100] = { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -12,12,15,20, 8,14, 8, 9,12,12,15,20, 8,14, 8, 9, -12,12,15,20, 8,14, 8, 9,12,12,15,20, 8,14, 8, 9, -12,12,15,20, 8,14, 8,18,12,12,15,20, 8,14, 8,18, -12,12,15,20, 8,14, 8, 8,12,12,15,20, 8,14, 8, 8, + 12,12,15,20,8,14, 8, 9,12,12,15,20, 8,14, 8, 9, + 12,12,15,20,8,14, 8, 9,12,12,15,20, 8,14, 8, 9, + 12,12,15,20,8,14, 8,18,12,12,15,20, 8,14, 8,18, + 12,12,15,20,8,14, 8, 8,12,12,15,20, 8,14, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8, -16,16,16,16, 8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8, + 16,16,16,16,8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8, + 16,16,16,16,8, 8, 8, 8,16,16,16,16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, @@ -258,7 +259,7 @@ static const uint8_t cc_xy[0x100] = { 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, -19 ,19 ,19 ,19 ,19 ,19 , 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, + 19 ,19 ,19 ,19 ,19 ,19 , 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, 4+4, 4+4, 4+4, 4+4, 4+4, 4+4,19 , 4+4, @@ -266,26 +267,26 @@ static const uint8_t cc_xy[0x100] = { 5+4,10+4,10+4,10+4,10+4,11+4, 7+4,11+4, 5+4,10+4,10+4, 0 ,10+4,17+4, 7+4,11+4, /* cb -> cc_xycb */ 5+4,10+4,10+4,11+4,10+4,11+4, 7+4,11+4, 5+4, 4+4,10+4,11+4,10+4, 4 , 7+4,11+4, /* dd -> cc_xy again */ 5+4,10+4,10+4,19+4,10+4,11+4, 7+4,11+4, 5+4, 4+4,10+4, 4+4,10+4, 4 , 7+4,11+4, /* ed -> cc_ed */ - 5+4,10+4,10+4, 4+4,10+4,11+4, 7+4,11+4, 5+4, 6+4,10+4, 4+4,10+4, 4 , 7+4,11+4 /* fd -> cc_xy again */ + 5+4,10+4,10+4, 4+4,10+4,11+4, 7+4,11+4, 5+4, 6+4,10+4, 4+4,10+4, 4 , 7+4,11+4 /* fd -> cc_xy again */ }; static const uint8_t cc_xycb[0x100] = { -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, -20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, -20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, -20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, -23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23 + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23, + 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23 }; /* extra cycles if jr/jp/call taken and 'interrupt latency' on rst 0-7 */ @@ -569,8 +570,8 @@ inline void z80_device::jp_cond(bool cond) ***************************************************************/ inline void z80_device::jr() { - int8_t a = (int8_t)arg(); /* arg() also increments PC */ - PC += a; /* so don't do PC += arg() */ + int8_t a = (int8_t)arg(); /* arg() also increments PC */ + PC += a; /* so don't do PC += arg() */ WZ = PC; } @@ -614,7 +615,7 @@ inline void z80_device::call_cond(bool cond, uint8_t opcode) } else { - WZ = arg16(); /* implicit call PC+=2; */ + WZ = arg16(); /* implicit call PC+=2; */ } } @@ -660,7 +661,7 @@ inline void z80_device::reti() inline void z80_device::ld_r_a() { m_r = A; - m_r2 = A & 0x80; /* keep bit 7 of r */ + m_r2 = A & 0x80; /* keep bit 7 of r */ } /*************************************************************** @@ -3406,12 +3407,12 @@ void z80_device::device_start() m_program = &space(AS_PROGRAM); m_decrypted_opcodes = has_space(AS_OPCODES) ? &space(AS_OPCODES) : m_program; - m_direct = &m_program->direct(); - m_decrypted_opcodes_direct = &m_decrypted_opcodes->direct(); + m_direct = m_program->direct<0>(); + m_decrypted_opcodes_direct = m_decrypted_opcodes->direct<0>(); m_io = &space(AS_IO); IX = IY = 0xffff; /* IX and IY are FFFF after a reset! */ - F = ZF; /* Zero flag is set */ + F = ZF; /* Zero flag is set */ /* set up the state table */ state_add(STATE_GENPC, "PC", m_pc.w.l).callimport(); @@ -3667,14 +3668,13 @@ void z80_device::state_string_export(const device_state_entry &entry, std::strin } //------------------------------------------------- -// disasm_disassemble - call the disassembly +// disassemble - call the disassembly // helper function //------------------------------------------------- -offs_t z80_device::disasm_disassemble( std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options ) +util::disasm_interface *z80_device::create_disassembler() { - extern CPU_DISASSEMBLE( z80 ); - return CPU_DISASSEMBLE_NAME(z80)(this, stream, pc, oprom, opram, options); + return new z80_disassembler; } diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h index dba8c294040..732e425fd86 100644 --- a/src/devices/cpu/z80/z80.h +++ b/src/devices/cpu/z80/z80.h @@ -70,9 +70,7 @@ protected: 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 1; } - 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; + virtual util::disasm_interface *create_disassembler() override; #undef PROTOTYPES #define PROTOTYPES(prefix) \ @@ -246,8 +244,8 @@ protected: address_space *m_program; address_space *m_decrypted_opcodes; address_space *m_io; - direct_read_data *m_direct; - direct_read_data *m_decrypted_opcodes_direct; + direct_read_data<0> *m_direct; + direct_read_data<0> *m_decrypted_opcodes_direct; devcb_write_line m_irqack_cb; devcb_write16 m_refresh_cb; devcb_write_line m_halt_cb; diff --git a/src/devices/cpu/z80/z80daisy_generic.cpp b/src/devices/cpu/z80/z80daisy_generic.cpp new file mode 100644 index 00000000000..57d08c13066 --- /dev/null +++ b/src/devices/cpu/z80/z80daisy_generic.cpp @@ -0,0 +1,117 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Generic Z80 daisy chain device + +***************************************************************************/ + +#include "emu.h" +#include "z80daisy_generic.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(Z80DAISY_GENERIC, z80daisy_generic_device, "z80daisy_generic", "Generic Z80 daisy chain device") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// z80daisy_generic_device - constructor +//------------------------------------------------- + +z80daisy_generic_device::z80daisy_generic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, Z80DAISY_GENERIC, tag, owner, clock), + device_z80daisy_interface(mconfig, *this), + m_int_handler(*this), + m_int(0), m_mask(0), m_vector(0xff) +{ +} + +//------------------------------------------------- +// static_set_vector - static configuration +//------------------------------------------------- + +void z80daisy_generic_device::static_set_vector(device_t &device, uint8_t vector) +{ + z80daisy_generic_device &dev = downcast<z80daisy_generic_device &>(device); + dev.m_vector = vector; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void z80daisy_generic_device::device_start() +{ + // resolve callbacks + m_int_handler.resolve_safe(); + + // register for save states + save_item(NAME(m_int)); + save_item(NAME(m_mask)); + save_item(NAME(m_vector)); +} + +//------------------------------------------------- +// z80daisy_irq_state - return the overall IRQ +// state for this device +//------------------------------------------------- + +int z80daisy_generic_device::z80daisy_irq_state() +{ + if (m_int & ~m_mask) + return Z80_DAISY_INT; + + return 0; +} + +//------------------------------------------------- +// z80daisy_irq_ack - acknowledge an IRQ and +// return the appropriate vector +//------------------------------------------------- + +int z80daisy_generic_device::z80daisy_irq_ack() +{ + return m_vector; +} + +//------------------------------------------------- +// z80daisy_irq_reti - clear the interrupt +// pending state to allow other interrupts through +//------------------------------------------------- + +void z80daisy_generic_device::z80daisy_irq_reti() +{ +} + +//------------------------------------------------- +// update_interrupt() - check interrupt status +//------------------------------------------------- + +void z80daisy_generic_device::update_interrupt() +{ + m_int_handler(m_int & ~m_mask ? ASSERT_LINE : CLEAR_LINE); +} + + +//************************************************************************** +// INTERFACE +//************************************************************************** + +WRITE_LINE_MEMBER( z80daisy_generic_device::int_w ) +{ + m_int = state; + update_interrupt(); +} + +WRITE_LINE_MEMBER( z80daisy_generic_device::mask_w ) +{ + m_mask = state; + update_interrupt(); +} diff --git a/src/devices/cpu/z80/z80daisy_generic.h b/src/devices/cpu/z80/z80daisy_generic.h new file mode 100644 index 00000000000..389c5eda43f --- /dev/null +++ b/src/devices/cpu/z80/z80daisy_generic.h @@ -0,0 +1,71 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Generic Z80 daisy chain device + +***************************************************************************/ + +#ifndef MAME_DEVICES_CPU_Z80_Z80DAISY_GENERIC_H +#define MAME_DEVICES_CPU_Z80_Z80DAISY_GENERIC_H + +#pragma once + +#include "z80daisy.h" + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_Z80DAISY_GENERIC_ADD(_tag, _vector) \ + MCFG_DEVICE_ADD(_tag, Z80DAISY_GENERIC, 0) \ + z80daisy_generic_device::static_set_vector(*device, _vector); \ + +#define MCFG_Z80DAISY_GENERIC_INT_CB(_devcb) \ + devcb = &z80daisy_generic_device::set_int_handler(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class z80daisy_generic_device : public device_t, public device_z80daisy_interface +{ +public: + // construction/destruction + z80daisy_generic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // callbacks + template <class Object> static devcb_base &set_int_handler(device_t &device, Object &&cb) + { return downcast<z80daisy_generic_device &>(device).m_int_handler.set_callback(std::forward<Object>(cb)); } + + // configuration + static void static_set_vector(device_t &device, uint8_t vector); + + DECLARE_WRITE_LINE_MEMBER(int_w); + DECLARE_WRITE_LINE_MEMBER(mask_w); + +protected: + // device-level overrides + virtual void device_start() override; + + // z80daisy_interface overrides + virtual int z80daisy_irq_state() override; + virtual int z80daisy_irq_ack() override; + virtual void z80daisy_irq_reti() override; + +private: + void update_interrupt(); + + devcb_write_line m_int_handler; + + int m_int; + int m_mask; + int m_vector; +}; + +// device type definition +DECLARE_DEVICE_TYPE(Z80DAISY_GENERIC, z80daisy_generic_device) + +#endif // MAME_DEVICES_CPU_Z80_Z80DAISY_GENERIC_H diff --git a/src/devices/cpu/z80/z80dasm.cpp b/src/devices/cpu/z80/z80dasm.cpp index 2af88954943..b59b3a38eb6 100644 --- a/src/devices/cpu/z80/z80dasm.cpp +++ b/src/devices/cpu/z80/z80dasm.cpp @@ -9,20 +9,8 @@ #include "emu.h" #include "debugger.h" -#include "z80.h" +#include "z80dasm.h" -enum e_mnemonics -{ - zADC ,zADD ,zAND ,zBIT ,zCALL ,zCCF ,zCP ,zCPD , - zCPDR ,zCPI ,zCPIR ,zCPL ,zDAA ,zDB ,zDEC ,zDI , - zDJNZ ,zEI ,zEX ,zEXX ,zHLT ,zIM ,zIN ,zINC , - zIND ,zINDR ,zINI ,zINIR ,zJP ,zJR ,zLD ,zLDD , - zLDDR ,zLDI ,zLDIR ,zNEG ,zNOP ,zOR ,zOTDR ,zOTIR , - zOUT ,zOUTD ,zOUTI ,zPOP ,zPUSH ,zRES ,zRET ,zRETI , - zRETN ,zRL ,zRLA ,zRLC ,zRLCA ,zRLD ,zRR ,zRRA , - zRRC ,zRRCA ,zRRD ,zRST ,zSBC ,zSCF ,zSET ,zSLA , - zSLL ,zSRA ,zSRL ,zSUB ,zXOR -}; static const char *const s_mnemonic[] = { @@ -37,29 +25,20 @@ static const char *const s_mnemonic[] = "sll" ,"sra" ,"srl" ,"sub" ,"xor " }; -#define _OVER DASMFLAG_STEP_OVER -#define _OUT DASMFLAG_STEP_OUT - -static const uint32_t s_flags[] = -{ - 0 ,0 ,0 ,0 ,_OVER,0 ,0 ,0 , - _OVER,0 ,_OVER,0 ,0 ,0 ,0 ,0 , - _OVER,0 ,0 ,0 ,_OVER,0 ,0 ,0 , - 0 ,_OVER,0 ,_OVER,0 ,0 ,0 ,0 , - _OVER,0 ,_OVER,0 ,0 ,0 ,_OVER,_OVER, - 0 ,0 ,0 ,0 ,0 ,0 ,_OUT ,_OUT , - _OUT ,0 ,0 ,0 ,0 ,0 ,0 ,0 , - 0 ,0 ,0 ,_OVER,0 ,0 ,0 ,0 , - 0 ,0 ,0 ,0 ,0 -}; - -struct z80dasm +const u32 z80_disassembler::s_flags[] = { - uint8_t mnemonic; - const char *arguments; + 0 ,0 ,0 ,0 ,STEP_OVER,0 ,0 ,0 , + STEP_OVER,0 ,STEP_OVER,0 ,0 ,0 ,0 ,0 , + STEP_OVER,0 ,0 ,0 ,STEP_OVER,0 ,0 ,0 , + 0 ,STEP_OVER,0 ,STEP_OVER,0 ,0 ,0 ,0 , + STEP_OVER,0 ,STEP_OVER,0 ,0 ,0 ,STEP_OVER,STEP_OVER, + 0 ,0 ,0 ,0 ,0 ,0 ,STEP_OUT ,STEP_OUT , + STEP_OUT ,0 ,0 ,0 ,0 ,0 ,0 ,0 , + 0 ,0 ,0 ,STEP_OVER,0 ,0 ,0 ,0 , + 0 ,0 ,0 ,0 ,0 }; -static const z80dasm mnemonic_xx_cb[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_xx_cb[256] = { {zRLC,"b=Y"}, {zRLC,"c=Y"}, {zRLC,"d=Y"}, {zRLC,"e=Y"}, {zRLC,"h=Y"}, {zRLC,"l=Y"}, {zRLC,"Y"}, {zRLC,"a=Y"}, @@ -127,7 +106,7 @@ static const z80dasm mnemonic_xx_cb[256] = {zSET,"h=7,Y"}, {zSET,"l=7,Y"}, {zSET,"7,Y"}, {zSET,"a=7,Y"} }; -static const z80dasm mnemonic_cb[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_cb[256] = { {zRLC,"b"}, {zRLC,"c"}, {zRLC,"d"}, {zRLC,"e"}, {zRLC,"h"}, {zRLC,"l"}, {zRLC,"(hl)"}, {zRLC,"a"}, @@ -195,7 +174,7 @@ static const z80dasm mnemonic_cb[256] = {zSET,"7,h"}, {zSET,"7,l"}, {zSET,"7,(hl)"},{zSET,"7,a"} }; -static const z80dasm mnemonic_ed[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_ed[256] = { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, @@ -214,21 +193,21 @@ static const z80dasm mnemonic_ed[256] = {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zIN,"b,(c)"}, {zOUT,"(c),b"}, {zSBC,"hl,bc"}, {zLD,"(W),bc"}, - {zNEG,nullptr}, {zRETN,nullptr}, {zIM,"0"}, {zLD,"i,a"}, + {zNEG,nullptr}, {zRETN,nullptr},{zIM,"0"}, {zLD,"i,a"}, {zIN,"c,(c)"}, {zOUT,"(c),c"}, {zADC,"hl,bc"}, {zLD,"bc,(W)"}, - {zNEG,"*"}, {zRETI,nullptr}, {zIM,"0"}, {zLD,"r,a"}, + {zNEG,"*"}, {zRETI,nullptr},{zIM,"0"}, {zLD,"r,a"}, {zIN,"d,(c)"}, {zOUT,"(c),d"}, {zSBC,"hl,de"}, {zLD,"(W),de"}, - {zNEG,"*"}, {zRETN,nullptr}, {zIM,"1"}, {zLD,"a,i"}, + {zNEG,"*"}, {zRETN,nullptr},{zIM,"1"}, {zLD,"a,i"}, {zIN,"e,(c)"}, {zOUT,"(c),e"}, {zADC,"hl,de"}, {zLD,"de,(W)"}, - {zNEG,"*"}, {zRETI,nullptr}, {zIM,"2"}, {zLD,"a,r"}, + {zNEG,"*"}, {zRETI,nullptr},{zIM,"2"}, {zLD,"a,r"}, {zIN,"h,(c)"}, {zOUT,"(c),h"}, {zSBC,"hl,hl"}, {zLD,"(W),hl"}, - {zNEG,"*"}, {zRETN,nullptr}, {zIM,"0"}, {zRRD,"(hl)"}, + {zNEG,"*"}, {zRETN,nullptr},{zIM,"0"}, {zRRD,"(hl)"}, {zIN,"l,(c)"}, {zOUT,"(c),l"}, {zADC,"hl,hl"}, {zLD,"hl,(W)"}, - {zNEG,"*"}, {zRETI,nullptr}, {zIM,"0"}, {zRLD,"(hl)"}, + {zNEG,"*"}, {zRETI,nullptr},{zIM,"0"}, {zRLD,"(hl)"}, {zIN,"0,(c)"}, {zOUT,"(c),0"}, {zSBC,"hl,sp"}, {zLD,"(W),sp"}, - {zNEG,"*"}, {zRETN,nullptr}, {zIM,"1"}, {zDB,"?"}, + {zNEG,"*"}, {zRETN,nullptr},{zIM,"1"}, {zDB,"?"}, {zIN,"a,(c)"}, {zOUT,"(c),a"}, {zADC,"hl,sp"}, {zLD,"sp,(W)"}, - {zNEG,"*"}, {zRETI,nullptr}, {zIM,"2"}, {zDB,"?"}, + {zNEG,"*"}, {zRETI,nullptr},{zIM,"2"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, @@ -263,7 +242,7 @@ static const z80dasm mnemonic_ed[256] = {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"} }; -static const z80dasm mnemonic_xx[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_xx[256] = { {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, @@ -331,9 +310,9 @@ static const z80dasm mnemonic_xx[256] = {zDB,"?"}, {zDB,"?"}, {zDB,"?"}, {zDB,"?"} }; -static const z80dasm mnemonic_main[256] = +const z80_disassembler::z80dasm z80_disassembler::mnemonic_main[256] = { - {zNOP,nullptr}, {zLD,"bc,N"}, {zLD,"(bc),a"}, {zINC,"bc"}, + {zNOP,nullptr}, {zLD,"bc,N"}, {zLD,"(bc),a"}, {zINC,"bc"}, {zINC,"b"}, {zDEC,"b"}, {zLD,"b,B"}, {zRLCA,nullptr}, {zEX,"af,af'"}, {zADD,"hl,bc"}, {zLD,"a,(bc)"}, {zDEC,"bc"}, {zINC,"c"}, {zDEC,"c"}, {zLD,"c,B"}, {zRRCA,nullptr}, @@ -383,11 +362,11 @@ static const z80dasm mnemonic_main[256] = {zCP,"h"}, {zCP,"l"}, {zCP,"(hl)"}, {zCP,"a"}, {zRET,"nz"}, {zPOP,"bc"}, {zJP,"nz,A"}, {zJP,"A"}, {zCALL,"nz,A"}, {zPUSH,"bc"}, {zADD,"a,B"}, {zRST,"V"}, - {zRET,"z"}, {zRET,nullptr}, {zJP,"z,A"}, {zDB,"cb"}, + {zRET,"z"}, {zRET,nullptr}, {zJP,"z,A"}, {zDB,"cb"}, {zCALL,"z,A"}, {zCALL,"A"}, {zADC,"a,B"}, {zRST,"V"}, {zRET,"nc"}, {zPOP,"de"}, {zJP,"nc,A"}, {zOUT,"(P),a"}, {zCALL,"nc,A"}, {zPUSH,"de"}, {zSUB,"B"}, {zRST,"V"}, - {zRET,"c"}, {zEXX,nullptr}, {zJP,"c,A"}, {zIN,"a,(P)"}, + {zRET,"c"}, {zEXX,nullptr}, {zJP,"c,A"}, {zIN,"a,(P)"}, {zCALL,"c,A"}, {zDB,"dd"}, {zSBC,"a,B"}, {zRST,"V"}, {zRET,"po"}, {zPOP,"hl"}, {zJP,"po,A"}, {zEX,"(sp),hl"}, {zCALL,"po,A"}, {zPUSH,"hl"}, {zAND,"B"}, {zRST,"V"}, @@ -399,65 +378,73 @@ static const z80dasm mnemonic_main[256] = {zCALL,"m,A"}, {zDB,"fd"}, {zCP,"B"}, {zRST,"V"} }; -static char sign(int8_t offset) +char z80_disassembler::sign(s8 offset) { return (offset < 0)? '-':'+'; } -static int offs(int8_t offset) +u32 z80_disassembler::offs(s8 offset) { - if (offset < 0) return -offset; + if (offset < 0) + return -offset; return offset; } -/**************************************************************************** - * Disassemble opcode at PC and return number of bytes it takes - ****************************************************************************/ -CPU_DISASSEMBLE(z80) +z80_disassembler::z80_disassembler() { - const z80dasm *d; - const char *src, *ixy; - int8_t offset = 0; - uint8_t op, op1 = 0; - uint16_t ea; - int pos = 0; +} - ixy = "oops!!"; +u32 z80_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t z80_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + s8 offset = 0; - op = oprom[pos++]; + offs_t pos = pc; + std::string ixy = "oops!!"; + const z80dasm *d = nullptr; + u8 op = opcodes.r8(pos++); switch (op) { case 0xcb: - op = oprom[pos++]; + op = opcodes.r8(pos++); d = &mnemonic_cb[op]; break; case 0xed: - op1 = oprom[pos++]; - d = &mnemonic_ed[op1]; + d = &mnemonic_ed[opcodes.r8(pos++)]; break; case 0xdd: + { ixy = "ix"; - op1 = oprom[pos++]; + u8 op1 = opcodes.r8(pos++); if( op1 == 0xcb ) { - offset = (int8_t) opram[pos++]; - op1 = opram[pos++]; /* fourth byte from opbase.ram! */ + offset = params.r8(pos++); + op1 = params.r8(pos++); d = &mnemonic_xx_cb[op1]; } - else d = &mnemonic_xx[op1]; + else + d = &mnemonic_xx[op1]; break; + } case 0xfd: + { ixy = "iy"; - op1 = oprom[pos++]; + u8 op1 = opcodes.r8(pos++); if( op1 == 0xcb ) { - offset = (int8_t) opram[pos++]; - op1 = opram[pos++]; /* fourth byte from opbase.ram! */ + offset = params.r8(pos++); + op1 = params.r8(pos++); d = &mnemonic_xx_cb[op1]; } - else d = &mnemonic_xx[op1]; + else + d = &mnemonic_xx[op1]; break; + } default: d = &mnemonic_main[op]; break; @@ -466,47 +453,40 @@ CPU_DISASSEMBLE(z80) if( d->arguments ) { util::stream_format(stream, "%-4s ", s_mnemonic[d->mnemonic]); - src = d->arguments; + const char *src = d->arguments; while( *src ) { switch( *src ) { case '?': /* illegal opcode */ - util::stream_format(stream, "$%02x,$%02x", op, op1 ); + util::stream_format(stream, "$%02x", op ); break; case 'A': - ea = opram[pos+0] + ( opram[pos+1] << 8 ); + util::stream_format(stream, "$%04X", params.r16(pos) ); pos += 2; - util::stream_format(stream, "$%04X", ea ); break; case 'B': /* Byte op arg */ - ea = opram[pos++]; - util::stream_format(stream, "$%02X", ea ); + util::stream_format(stream, "$%02X", params.r8(pos++) ); break; case 'N': /* Immediate 16 bit */ - ea = opram[pos+0] + ( opram[pos+1] << 8 ); + util::stream_format(stream, "$%04X", params.r16(pos) ); pos += 2; - util::stream_format(stream, "$%04X", ea ); break; case 'O': /* Offset relative to PC */ - offset = (int8_t) opram[pos++]; - util::stream_format(stream, "$%04X", (pc + offset + 2) & 0xffff); + util::stream_format(stream, "$%04X", (pc + s8(params.r8(pos++)) + 2) & 0xffff); break; case 'P': /* Port number */ - ea = opram[pos++]; - util::stream_format(stream, "$%02X", ea ); + util::stream_format(stream, "$%02X", params.r8(pos++) ); break; case 'V': /* Restart vector */ - ea = op & 0x38; - util::stream_format(stream, "$%02X", ea ); + util::stream_format(stream, "$%02X", op & 0x38 ); break; case 'W': /* Memory address word */ - ea = opram[pos+0] + ( opram[pos+1] << 8 ); + util::stream_format(stream, "$%04X", params.r16(pos) ); pos += 2; - util::stream_format(stream, "$%04X", ea ); break; case 'X': - offset = (int8_t) opram[pos++]; + offset = params.r8(pos++); /* fall through */ case 'Y': util::stream_format(stream,"(%s%c$%02x)", ixy, sign(offset), offs(offset) ); @@ -525,5 +505,5 @@ CPU_DISASSEMBLE(z80) util::stream_format(stream, "%s", s_mnemonic[d->mnemonic]); } - return pos | s_flags[d->mnemonic] | DASMFLAG_SUPPORTED; + return (pos - pc) | s_flags[d->mnemonic] | SUPPORTED; } diff --git a/src/devices/cpu/z80/z80dasm.h b/src/devices/cpu/z80/z80dasm.h new file mode 100644 index 00000000000..774f4df89a8 --- /dev/null +++ b/src/devices/cpu/z80/z80dasm.h @@ -0,0 +1,56 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller +/***************************************************************************** + * + * z80dasm.h + * Portable Z80 disassembler + * + *****************************************************************************/ + +#ifndef MAME_CPU_Z80_Z80DASM_H +#define MAME_CPU_Z80_Z80DASM_H + +#pragma once + +class z80_disassembler : public util::disasm_interface +{ +public: + z80_disassembler(); + virtual ~z80_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +protected: + struct z80dasm + { + u8 mnemonic; + const char *arguments; + }; + + enum e_mnemonics + { + zADC ,zADD ,zAND ,zBIT ,zCALL ,zCCF ,zCP ,zCPD , + zCPDR ,zCPI ,zCPIR ,zCPL ,zDAA ,zDB ,zDEC ,zDI , + zDJNZ ,zEI ,zEX ,zEXX ,zHLT ,zIM ,zIN ,zINC , + zIND ,zINDR ,zINI ,zINIR ,zJP ,zJR ,zLD ,zLDD , + zLDDR ,zLDI ,zLDIR ,zNEG ,zNOP ,zOR ,zOTDR ,zOTIR , + zOUT ,zOUTD ,zOUTI ,zPOP ,zPUSH ,zRES ,zRET ,zRETI , + zRETN ,zRL ,zRLA ,zRLC ,zRLCA ,zRLD ,zRR ,zRRA , + zRRC ,zRRCA ,zRRD ,zRST ,zSBC ,zSCF ,zSET ,zSLA , + zSLL ,zSRA ,zSRL ,zSUB ,zXOR + }; + + static inline char sign(s8 offset); + static inline u32 offs(s8 offset); + + static const u32 s_flags[]; + static const z80dasm mnemonic_xx_cb[256]; + static const z80dasm mnemonic_cb[256]; + static const z80dasm mnemonic_ed[256]; + static const z80dasm mnemonic_xx[256]; + static const z80dasm mnemonic_main[256]; + +}; + +#endif diff --git a/src/devices/cpu/z8000/8000dasm.cpp b/src/devices/cpu/z8000/8000dasm.cpp index a84d5d285e8..42a7d0abeb3 100644 --- a/src/devices/cpu/z8000/8000dasm.cpp +++ b/src/devices/cpu/z8000/8000dasm.cpp @@ -9,21 +9,543 @@ *****************************************************************************/ #include "emu.h" -#include "z8000.h" -#include "z8000cpu.h" +#include "8000dasm.h" -#include "debugger.h" -#include "debug/debugvw.h" -#include "debug/debugcon.h" +const z8000_disassembler::opcode z8000_disassembler::table[] = { + { 0x0000, 0xffff, 1, 1, ".word %#w0", 0 }, + { 0x0000, 0x000f, 1, 2, "addb %rb3,%#b3", 0 }, + { 0x0010, 0x00ff, 1, 1, "addb %rb3,@%rw2", 0 }, + { 0x0100, 0x010f, 1, 2, "add %rw3,%#w1", 0 }, + { 0x0110, 0x01ff, 1, 1, "add %rw3,@%rw2", 0 }, + { 0x0200, 0x020f, 1, 2, "subb %rb3,%#b3", 0 }, + { 0x0210, 0x02ff, 1, 1, "subb %rb3,@%rw2", 0 }, + { 0x0300, 0x030f, 1, 2, "sub %rw3,%#w1", 0 }, + { 0x0310, 0x03ff, 1, 1, "sub %rw3,@%rw2", 0 }, + { 0x0400, 0x040f, 1, 2, "orb %rb3,%#b3", 0 }, + { 0x0410, 0x04ff, 1, 1, "orb %rb3,@%rw2", 0 }, + { 0x0500, 0x050f, 1, 2, "or %rw3,%#w1", 0 }, + { 0x0510, 0x05ff, 1, 1, "or %rw3,@%rw2", 0 }, + { 0x0600, 0x060f, 1, 2, "andb %rb3,%#b3", 0 }, + { 0x0610, 0x06ff, 1, 1, "andb %rb3,@%rw2", 0 }, + { 0x0700, 0x070f, 1, 2, "and %rw3,%#w1", 0 }, + { 0x0710, 0x07ff, 1, 1, "and %rw3,@%rw2", 0 }, + { 0x0800, 0x080f, 1, 2, "xorb %rb3,%#b3", 0 }, + { 0x0810, 0x08ff, 1, 1, "xorb %rb3,@%rw2", 0 }, + { 0x0900, 0x090f, 1, 2, "xor %rw3,%#w1", 0 }, + { 0x0910, 0x09ff, 1, 1, "xor %rw3,@%rw2", 0 }, + { 0x0a00, 0x0a0f, 1, 2, "cpb %rb3,%#b3", 0 }, + { 0x0a10, 0x0aff, 1, 1, "cpb %rb3,@%rw2", 0 }, + { 0x0b00, 0x0b0f, 1, 2, "cp %rw3,%#w1", 0 }, + { 0x0b10, 0x0bff, 1, 1, "cp %rw3,@%rw2", 0 }, + { 0x0c10, 0x0cf0, 16, 1, "comb @%rw2", 0 }, + { 0x0c11, 0x0cf1, 16, 2, "cpb @%rw2,%#b3", 0 }, + { 0x0c12, 0x0cf2, 16, 1, "negb @%rw2", 0 }, + { 0x0c14, 0x0cf4, 16, 1, "testb @%rw2", 0 }, + { 0x0c15, 0x0cf5, 16, 2, "ldb @%rw2,%#b3", 0 }, + { 0x0c16, 0x0cf6, 16, 1, "tsetb @%rw2", 0 }, + { 0x0c18, 0x0cf8, 16, 1, "clrb @%rw2", 0 }, + { 0x0d10, 0x0df0, 16, 1, "com @%rw2", 0 }, + { 0x0d11, 0x0df1, 16, 2, "cp @%rw2,%#w1", 0 }, + { 0x0d12, 0x0df2, 16, 1, "neg @%rw2", 0 }, + { 0x0d14, 0x0df4, 16, 1, "test @%rw2", 0 }, + { 0x0d15, 0x0df5, 16, 2, "ld @%rw2,%#w1", 0 }, + { 0x0d16, 0x0df6, 16, 1, "tset @%rw2", 0 }, + { 0x0d18, 0x0df8, 16, 1, "clr @%rw2", 0 }, + { 0x0d19, 0x0df9, 16, 2, "push @%rw2,%#w1", 0 }, + { 0x0e00, 0x0eff, 1, 1, "ext0e %#b1", 0 }, + { 0x0f00, 0x0fff, 1, 1, "ext0f %#b1", 0 }, + { 0x1000, 0x100f, 1, 3, "cpl %rl3,%#l1", 0 }, + { 0x1010, 0x10ff, 1, 1, "cpl %rl3,@%rw2", 0 }, + { 0x1111, 0x11ff, 1, 1, "pushl @%rw2,@%rw3", 0 }, + { 0x1200, 0x120f, 1, 3, "subl %rl3,%#l1", 0 }, + { 0x1210, 0x12ff, 1, 1, "subl %rl3,@%rw2", 0 }, + { 0x1311, 0x13ff, 1, 1, "push @%rw2,@%rw3", 0 }, + { 0x1400, 0x140f, 1, 3, "ldl %rl3,%#l1", 0 }, + { 0x1410, 0x14ff, 1, 1, "ldl %rl3,@%rw2", 0 }, + { 0x1511, 0x15ff, 1, 1, "popl @%rw3,@%rw2", 0 }, + { 0x1600, 0x160f, 1, 3, "addl %rl3,%#l1", 0 }, + { 0x1610, 0x16ff, 1, 1, "addl %rl3,@%rw2", 0 }, + { 0x1711, 0x17ff, 1, 1, "pop @%rw3,@%rw2", 0 }, + { 0x1800, 0x180f, 1, 1, "multl %rq3,@%l#1", 0 }, + { 0x1810, 0x18ff, 1, 1, "multl %rq3,@%rw2", 0 }, + { 0x1900, 0x190f, 1, 2, "mult %rl3,%#w1", 0 }, + { 0x1910, 0x19ff, 1, 1, "mult %rl3,@%rw2", 0 }, + { 0x1a00, 0x1a0f, 1, 3, "divl %rq3,%#l1", 0 }, + { 0x1a10, 0x1aff, 1, 1, "divl %rq3,@%rw2", 0 }, + { 0x1b00, 0x1b0f, 1, 2, "div %rl3,%#w1", 0 }, + { 0x1b10, 0x1bff, 1, 1, "div %rl3,@%rw2", 0 }, + { 0x1c11, 0x1cf1, 16, 2, "ldm %rw5,@%rw2,#%n", 0 }, + { 0x1c18, 0x1cf8, 16, 1, "testl @%rw2", 0 }, + { 0x1c19, 0x1cf9, 16, 2, "ldm @%rw2,%rw5,#%n", 0 }, + { 0x1d10, 0x1dff, 1, 1, "ldl @%rw2,%rl3", 0 }, + { 0x1e10, 0x1eff, 1, 1, "jp %c3,@%rl2", 0 }, + { 0x1f10, 0x1ff0, 16, 1, "call %rw2", STEP_OVER }, + { 0x2000, 0x200f, 1, 2, "ldb %rb3,%#b3", 0 }, + { 0x2010, 0x20ff, 1, 1, "ldb %rb3,@%rw2", 0 }, + { 0x2100, 0x210f, 1, 2, "ld %rw3,%#w1", 0 }, + { 0x2110, 0x21ff, 1, 1, "ld %rw3,@%rw2", 0 }, + { 0x2200, 0x220f, 1, 2, "resb %rb5,%rw3", 0 }, + { 0x2210, 0x22ff, 1, 1, "resb @%rw2,%3", 0 }, + { 0x2300, 0x230f, 1, 2, "res %rw5,%rw3", 0 }, + { 0x2310, 0x23ff, 1, 1, "res @%rw2,%3", 0 }, + { 0x2400, 0x240f, 1, 2, "setb %rb5,%rw3", 0 }, + { 0x2410, 0x24ff, 1, 1, "setb @%rw2,%3", 0 }, + { 0x2500, 0x250f, 1, 2, "set %rw5,%rw3", 0 }, + { 0x2510, 0x25ff, 1, 1, "set @%rw2,%3", 0 }, + { 0x2600, 0x260f, 1, 2, "bitb %rb5,%rw3", 0 }, + { 0x2610, 0x26ff, 1, 1, "bitb @%rw2,%3", 0 }, + { 0x2700, 0x270f, 1, 2, "bit %rw5,%rw3", 0 }, + { 0x2710, 0x27ff, 1, 1, "bit @%rw2,%3", 0 }, + { 0x2810, 0x28ff, 1, 1, "incb @%rw2,%+3", 0 }, + { 0x2910, 0x29ff, 1, 1, "inc @%rw2,%+3", 0 }, + { 0x2a10, 0x2aff, 1, 1, "decb @%rw2,%+3", 0 }, + { 0x2b10, 0x2bff, 1, 1, "dec @%rw2,%+3", 0 }, + { 0x2c10, 0x2cff, 1, 1, "exb %rb3,@%rw2", 0 }, + { 0x2d10, 0x2dff, 1, 1, "ex %rw3,@%rw2", 0 }, + { 0x2e10, 0x2eff, 1, 1, "ldb @%rw2,%rb3", 0 }, + { 0x2f10, 0x2fff, 1, 1, "ld @%rw2,%rw3", 0 }, + { 0x3000, 0x300f, 1, 2, "ldrb %rb3,%p1", 0 }, + { 0x3010, 0x30ff, 1, 2, "ldb %rb3,%rw2(%#w1)", 0 }, + { 0x3100, 0x310f, 1, 2, "ldr %rw3,%p1", 0 }, + { 0x3110, 0x31ff, 1, 2, "ld %rw3,%rw2(%#w1)", 0 }, + { 0x3200, 0x320f, 1, 2, "ldrb %p1,%rb3", 0 }, + { 0x3210, 0x32ff, 1, 2, "ldb %rw2(%#w1),%rb3", 0 }, + { 0x3300, 0x330f, 1, 2, "ldr %p1,%rw3", 0 }, + { 0x3310, 0x33ff, 1, 2, "ld %rw2(%#w1),%rw3", 0 }, + { 0x3400, 0x340f, 1, 2, "ldar p%rw3,%p1", 0 }, + { 0x3410, 0x34ff, 1, 2, "lda p%rw3,%rw2(%#w1)", 0 }, + { 0x3500, 0x350f, 1, 2, "ldrl %rl3,%p1", 0 }, + { 0x3510, 0x35ff, 1, 2, "ldl %rl3,%rw2(%#w1)", 0 }, + { 0x3600, 0x3600, 1, 1, "bpt", 0 }, + { 0x3601, 0x36ff, 1, 1, "rsvd36", 0 }, + { 0x3700, 0x370f, 1, 2, "ldrl %p1,%rl3", 0 }, + { 0x3710, 0x37ff, 1, 2, "ldl %rw2(%#w1),%rl3", 0 }, + { 0x3800, 0x38ff, 1, 1, "rsvd38", 0 }, + { 0x3910, 0x39f0, 16, 1, "ldps @%rw2", 0 }, + { 0x3a00, 0x3af0, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a01, 0x3af1, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a02, 0x3af2, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a03, 0x3af3, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a04, 0x3af4, 16, 2, "%R %rb2,%#w1", 0 }, + { 0x3a05, 0x3af5, 16, 2, "%R %rb2,%#w1", 0 }, + { 0x3a06, 0x3af6, 16, 2, "%R %#w1,%rb2", 0 }, + { 0x3a07, 0x3af7, 16, 2, "%R %#w1,%rb2", 0 }, + { 0x3a08, 0x3af8, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a09, 0x3af9, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a0a, 0x3afa, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3a0b, 0x3afb, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b00, 0x3bf0, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b01, 0x3bf1, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b02, 0x3bf2, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b03, 0x3bf3, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b04, 0x3bf4, 16, 2, "%R %rw2,%#w1", 0 }, + { 0x3b05, 0x3bf5, 16, 2, "%R %rw2,%#w1", 0 }, + { 0x3b06, 0x3bf6, 16, 2, "%R %#w1,%rw2", 0 }, + { 0x3b07, 0x3bf7, 16, 2, "%R %#w1,%rw2", 0 }, + { 0x3b08, 0x3bf8, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b09, 0x3bf9, 16, 2, "%R @%rw6,@%rw2,%rw5", 0 }, + { 0x3b0a, 0x3bfa, 16, 2, "%R @%rw6,@%rw2,%rb5", 0 }, + { 0x3b0b, 0x3bfb, 16, 2, "%R @%rw6,@%rw2,%rb5", 0 }, + { 0x3c00, 0x3cff, 1, 1, "inb %rb3,@%rw2", 0 }, + { 0x3d00, 0x3dff, 1, 1, "in %rw3,@%rw2", 0 }, + { 0x3e00, 0x3eff, 1, 1, "outb @%rw2,%rb3", 0 }, + { 0x3f00, 0x3fff, 1, 1, "out @%rw2,%rw3", 0 }, + { 0x4000, 0x400f, 1, 2, "addb %rb3,%a1", 0 }, + { 0x4010, 0x40ff, 1, 2, "addb %rb3,%a1(%rw2)", 0 }, + { 0x4100, 0x410f, 1, 2, "add %rw3,%a1", 0 }, + { 0x4110, 0x41ff, 1, 2, "add %rw3,%a1(%rw2)", 0 }, + { 0x4200, 0x420f, 1, 2, "subb %rb3,%a1", 0 }, + { 0x4210, 0x42ff, 1, 2, "subb %rb3,%a1(%rw2)", 0 }, + { 0x4300, 0x430f, 1, 2, "sub %rw3,%a1", 0 }, + { 0x4310, 0x43ff, 1, 2, "sub %rw3,%a1(%rw2)", 0 }, + { 0x4400, 0x440f, 1, 2, "orb %rb3,%a1", 0 }, + { 0x4410, 0x44ff, 1, 2, "orb %rb3,%a1(%rw2)", 0 }, + { 0x4500, 0x450f, 1, 2, "or %rw3,%a1", 0 }, + { 0x4510, 0x45ff, 1, 2, "or %rw3,%a1(%rw2)", 0 }, + { 0x4600, 0x460f, 1, 2, "andb %rb3,%a1", 0 }, + { 0x4610, 0x46ff, 1, 2, "andb %rb3,%a1(%rw2)", 0 }, + { 0x4700, 0x470f, 1, 2, "and %rw3,%a1", 0 }, + { 0x4710, 0x47ff, 1, 2, "and %rw3,%a1(%rw2)", 0 }, + { 0x4800, 0x480f, 1, 2, "xorb %rb3,%a1", 0 }, + { 0x4810, 0x48ff, 1, 2, "xorb %rb3,%a1(%rw2)", 0 }, + { 0x4900, 0x490f, 1, 2, "xor %rw3,%a1", 0 }, + { 0x4910, 0x49ff, 1, 2, "xor %rw3,%a1(%rw2)", 0 }, + { 0x4a00, 0x4a0f, 1, 2, "cpb %rb3,%a1", 0 }, + { 0x4a10, 0x4aff, 1, 2, "cpb %rb3,%a1(%rw2)", 0 }, + { 0x4b00, 0x4b0f, 1, 2, "cp %rw3,%a1", 0 }, + { 0x4b10, 0x4bff, 1, 2, "cp %rw3,%a1(%rw2)", 0 }, + { 0x4c00, 0x4c00, 1, 2, "comb %a1", 0 }, + { 0x4c01, 0x4c01, 1, 3, "cpb %a1,%#b3", 0 }, + { 0x4c02, 0x4c02, 1, 2, "negb %a1", 0 }, + { 0x4c04, 0x4c04, 1, 2, "testb %a1", 0 }, + { 0x4c05, 0x4c05, 1, 3, "ldb %a1,%#b3", 0 }, + { 0x4c06, 0x4c06, 1, 2, "tsetb %a1", 0 }, + { 0x4c08, 0x4c08, 1, 2, "clrb %a1", 0 }, + { 0x4c10, 0x4cf0, 16, 2, "comb %a1(%rw2)", 0 }, + { 0x4c11, 0x4cf1, 16, 3, "cpb %a1(%rw2),%#b3", 0 }, + { 0x4c12, 0x4cf2, 16, 2, "negb %a1(%rw2)", 0 }, + { 0x4c14, 0x4cf4, 16, 2, "testb %a1(%rw2)", 0 }, + { 0x4c15, 0x4cf5, 16, 3, "ldb %a1(%rw2),%#b3", 0 }, + { 0x4c16, 0x4cf6, 16, 2, "tsetb %a1(%rw2)", 0 }, + { 0x4c18, 0x4cf8, 16, 2, "clrb %a1(%rw2)", 0 }, + { 0x4d00, 0x4d00, 1, 2, "com %a1", 0 }, + { 0x4d01, 0x4d01, 1, 3, "cp %a1,%#w2", 0 }, + { 0x4d02, 0x4d02, 1, 2, "neg %a1", 0 }, + { 0x4d04, 0x4d04, 1, 2, "test %a1", 0 }, + { 0x4d05, 0x4d05, 1, 3, "ld %a1,%#w2", 0 }, + { 0x4d06, 0x4d06, 1, 2, "tset %a1", 0 }, + { 0x4d08, 0x4d08, 1, 2, "clr %a1", 0 }, + { 0x4d10, 0x4df0, 16, 2, "com %a1(%rw2)", 0 }, + { 0x4d11, 0x4df1, 16, 3, "cp %a1(%rw2),%#w2", 0 }, + { 0x4d12, 0x4df2, 16, 2, "neg %a1(%rw2)", 0 }, + { 0x4d14, 0x4df4, 16, 2, "test %a1(%rw2)", 0 }, + { 0x4d15, 0x4df5, 16, 3, "ld %a1(%rw2),%#w2", 0 }, + { 0x4d16, 0x4df6, 16, 2, "tset %a1(%rw2)", 0 }, + { 0x4d18, 0x4df8, 16, 2, "clr %a1(%rw2)", 0 }, + { 0x4e11, 0x4ef0, 16, 2, "ldb %a1(%rw2),%rb3", 0 }, + { 0x5000, 0x500f, 1, 2, "cpl %rl3,%a1", 0 }, + { 0x5010, 0x50ff, 1, 2, "cpl %rl3,%a1(%rw2)", 0 }, + { 0x5110, 0x51f0, 16, 2, "pushl @%rw2,%a1", 0 }, + { 0x5111, 0x51f1, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5112, 0x51f2, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5113, 0x51f3, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5114, 0x51f4, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5115, 0x51f5, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5116, 0x51f6, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5117, 0x51f7, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5118, 0x51f8, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5119, 0x51f9, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511a, 0x51fa, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511b, 0x51fb, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511c, 0x51fc, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511d, 0x51fd, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511e, 0x51fe, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x511f, 0x51ff, 16, 2, "pushl @%rw2,%a1(%rw3)", 0 }, + { 0x5200, 0x520f, 1, 2, "subl %rl3,%a1", 0 }, + { 0x5210, 0x52ff, 1, 2, "subl %rl3,%a1(%rw2)", 0 }, + { 0x5310, 0x53f0, 16, 2, "push @%rw2,%a1", 0 }, + { 0x5311, 0x53f1, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5312, 0x53f2, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5313, 0x53f3, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5314, 0x53f4, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5315, 0x53f5, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5316, 0x53f6, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5317, 0x53f7, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5318, 0x53f8, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5319, 0x53f9, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531a, 0x53fa, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531b, 0x53fb, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531c, 0x53fc, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531d, 0x53fd, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531e, 0x53fe, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x531f, 0x53ff, 16, 2, "push @%rw2,%a1(%rw3)", 0 }, + { 0x5400, 0x540f, 1, 2, "ldl %rl3,%a1", 0 }, + { 0x5410, 0x54ff, 1, 2, "ldl %rl3,%a1(%rw2)", 0 }, + { 0x5510, 0x55f0, 16, 2, "popl %a1,@%rw2", 0 }, + { 0x5511, 0x55f1, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5512, 0x55f2, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5513, 0x55f3, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5514, 0x55f4, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5515, 0x55f5, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5516, 0x55f6, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5517, 0x55f7, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5518, 0x55f8, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5519, 0x55f9, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551a, 0x55fa, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551b, 0x55fb, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551c, 0x55fc, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551d, 0x55fd, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551e, 0x55fe, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x551f, 0x55ff, 16, 2, "popl %a1(%rw3),@%rw2", 0 }, + { 0x5600, 0x560f, 1, 2, "addl %rl3,%a1", 0 }, + { 0x5610, 0x56ff, 1, 2, "addl %rl3,%a1(%rw2)", 0 }, + { 0x5710, 0x57f0, 16, 2, "pop %a1,@%rw2", 0 }, + { 0x5711, 0x57f1, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5712, 0x57f2, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5713, 0x57f3, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5714, 0x57f4, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5715, 0x57f5, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5716, 0x57f6, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5717, 0x57f7, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5718, 0x57f8, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5719, 0x57f9, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571a, 0x57fa, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571b, 0x57fb, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571c, 0x57fc, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571d, 0x57fd, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571e, 0x57fe, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x571f, 0x57ff, 16, 2, "pop %a1(%rw3),@%rw2", 0 }, + { 0x5800, 0x580f, 1, 2, "multl %rq3,%a1", 0 }, + { 0x5810, 0x58ff, 1, 2, "multl %rq3,%a1(%rw2)", 0 }, + { 0x5900, 0x590f, 1, 2, "mult %rl3,%a1", 0 }, + { 0x5910, 0x59ff, 1, 2, "mult %rl3,%a1(%rw2)", 0 }, + { 0x5a00, 0x5a0f, 1, 2, "divl %rq3,%a1", 0 }, + { 0x5a10, 0x5aff, 1, 2, "divl %rq3,%a1(%rw2)", 0 }, + { 0x5b00, 0x5b0f, 1, 2, "div %rl3,%a1", 0 }, + { 0x5b10, 0x5bff, 1, 2, "div %rl3,%a1(%rw2)", 0 }, + { 0x5c01, 0x5c01, 1, 3, "ldm %rw5,%a2,#%n", 0 }, + { 0x5c08, 0x5c08, 1, 2, "testl %a1", 0 }, + { 0x5c09, 0x5c09, 1, 3, "ldm %a2,%rw5,#%n", 0 }, + { 0x5c11, 0x5cf1, 16, 3, "ldm %rw5,%a2(%rw2),#%n", 0 }, + { 0x5c18, 0x5cf8, 16, 2, "testl %a1(%rw2)", 0 }, + { 0x5c19, 0x5cf9, 16, 3, "ldm %a2(%rw2),%rw5,#%n", 0 }, + { 0x5d00, 0x5d0f, 1, 2, "ldl %a1,%rl3", 0 }, + { 0x5d10, 0x5dff, 1, 2, "ldl %a1(%rw2),%rl3", 0 }, + { 0x5e00, 0x5e0f, 1, 2, "jp %c3,%a1", 0 }, + { 0x5e10, 0x5eff, 1, 2, "jp %c3,%a1(%rw2)", 0 }, + { 0x5f00, 0x5f00, 1, 2, "call %a1", STEP_OVER }, + { 0x5f10, 0x5ff0, 16, 2, "call %a1(%rw2)", STEP_OVER }, + { 0x6000, 0x600f, 1, 2, "ldb %rb3,%a1", 0 }, + { 0x6010, 0x60ff, 1, 2, "ldb %rb3,%a1(%rw2)", 0 }, + { 0x6100, 0x610f, 1, 2, "ld %rw3,%a1", 0 }, + { 0x6110, 0x61ff, 1, 2, "ld %rw3,%a1(%rw2)", 0 }, + { 0x6200, 0x620f, 1, 2, "resb %a1,%3", 0 }, + { 0x6210, 0x62ff, 1, 2, "resb %a1(%rw2),%3", 0 }, + { 0x6300, 0x630f, 1, 2, "res %a1,%3", 0 }, + { 0x6310, 0x63ff, 1, 2, "res %a1(%rw2),%3", 0 }, + { 0x6400, 0x640f, 1, 2, "setb %a1,%3", 0 }, + { 0x6410, 0x64ff, 1, 2, "setb %a1(%rw2),%3", 0 }, + { 0x6500, 0x650f, 1, 2, "set %a1,%3", 0 }, + { 0x6510, 0x65ff, 1, 2, "set %a1(%rw2),%3", 0 }, + { 0x6600, 0x660f, 1, 2, "bitb %a1,%3", 0 }, + { 0x6610, 0x66ff, 1, 2, "bitb %a1(%rw2),%3", 0 }, + { 0x6700, 0x670f, 1, 2, "bit %a1,%3", 0 }, + { 0x6710, 0x67ff, 1, 2, "bit %a1(%rw2),%3", 0 }, + { 0x6800, 0x680f, 1, 2, "incb %a1,%+3", 0 }, + { 0x6810, 0x68ff, 1, 2, "incb %a1(%rw2),%+3", 0 }, + { 0x6900, 0x690f, 1, 2, "inc %a1,%+3", 0 }, + { 0x6910, 0x69ff, 1, 2, "inc %a1(%rw2),%+3", 0 }, + { 0x6a00, 0x6a0f, 1, 2, "decb %a1,%+3", 0 }, + { 0x6a10, 0x6aff, 1, 2, "decb %a1(%rw2),%+3", 0 }, + { 0x6b00, 0x6b0f, 1, 2, "dec %a1,%+3", 0 }, + { 0x6b10, 0x6bff, 1, 2, "dec %a1(%rw2),%+3", 0 }, + { 0x6c00, 0x6c0f, 1, 2, "exb %rb3,%a1", 0 }, + { 0x6c10, 0x6cff, 1, 2, "exb %rb3,%a1(%rw2)", 0 }, + { 0x6d00, 0x6d0f, 1, 2, "ex %rw3,%a1", 0 }, + { 0x6d10, 0x6dff, 1, 2, "ex %rw3,%a1(%rw2)", 0 }, + { 0x6e00, 0x6e0f, 1, 2, "ldb %a1,%rb3", 0 }, + { 0x6e10, 0x6eff, 1, 2, "ldb %a1(%rw2),%rb3", 0 }, + { 0x6f00, 0x6f0f, 1, 2, "ld %a1,%rw3", 0 }, + { 0x6f10, 0x6fff, 1, 2, "ld %a1(%rw2),%rw3", 0 }, + { 0x7010, 0x70ff, 1, 2, "ldb %rb3,%rw2(%rw5)", 0 }, + { 0x7110, 0x71ff, 1, 2, "ld %rw3,%rw2(%rw5)", 0 }, + { 0x7210, 0x72ff, 1, 2, "ldb %rw2(%rw5),%rb3", 0 }, + { 0x7310, 0x73ff, 1, 2, "ld %rw2(%rw5),%rw3", 0 }, + { 0x7410, 0x74ff, 1, 2, "lda p%rw3,%rw2(%rw5)", 0 }, + { 0x7510, 0x75ff, 1, 2, "ldl %rl3,%rw2(%rw5)", 0 }, + { 0x7600, 0x760f, 1, 2, "lda p%rw3,%a1", 0 }, + { 0x7610, 0x76ff, 1, 2, "lda p%rw3,%a1(%rw2)", 0 }, + { 0x7710, 0x77ff, 1, 2, "ldl %rw2(%rw5),%rl3", 0 }, + { 0x7800, 0x78ff, 1, 1, "rsvd78", 0 }, + { 0x7900, 0x7900, 1, 2, "ldps %a1", 0 }, + { 0x7910, 0x79f0, 16, 2, "ldps %a1(%rw2)", 0 }, + { 0x7a00, 0x7a00, 1, 1, "halt", STEP_OVER }, + { 0x7b00, 0x7b00, 1, 1, "iret", STEP_OUT }, + { 0x7b08, 0x7b08, 1, 1, "mset", 0 }, + { 0x7b09, 0x7b09, 1, 1, "mres", 0 }, + { 0x7b0a, 0x7b0a, 1, 1, "mbit", 0 }, + { 0x7b0d, 0x7bfd, 16, 1, "mreq %rw2", 0 }, + { 0x7c00, 0x7c03, 1, 1, "di %i3", 0 }, + { 0x7c04, 0x7c07, 1, 1, "ei %i3", 0 }, + { 0x7d00, 0x7df0, 16, 1, "ldctl %rw2,ctrl0", 0 }, + { 0x7d01, 0x7df1, 16, 1, "ldctl %rw2,ctrl1", 0 }, + { 0x7d02, 0x7df2, 16, 1, "ldctl %rw2,fcw", 0 }, + { 0x7d03, 0x7df3, 16, 1, "ldctl %rw2,refresh", 0 }, + { 0x7d04, 0x7df4, 16, 1, "ldctl %rw2,psapseg", 0 }, + { 0x7d05, 0x7df5, 16, 1, "ldctl %rw2,psapoff", 0 }, + { 0x7d06, 0x7df6, 16, 1, "ldctl %rw2,nspseg", 0 }, + { 0x7d07, 0x7df7, 16, 1, "ldctl %rw2,nspoff", 0 }, + { 0x7d08, 0x7df8, 16, 1, "ldctl ctrl0,%rw2", 0 }, + { 0x7d09, 0x7df9, 16, 1, "ldctl ctrl1,%rw2", 0 }, + { 0x7d0a, 0x7dfa, 16, 1, "ldctl fcw,%rw2", 0 }, + { 0x7d0b, 0x7dfb, 16, 1, "ldctl refresh,%rw2", 0 }, + { 0x7d0c, 0x7dfc, 16, 1, "ldctl psapseg,%rw2", 0 }, + { 0x7d0d, 0x7dfd, 16, 1, "ldctl psapoff,%rw2", 0 }, + { 0x7d0e, 0x7dfe, 16, 1, "ldctl nspseg,%rw2", 0 }, + { 0x7d0f, 0x7dff, 16, 1, "ldctl nspoff,%rw2", 0 }, + { 0x7e00, 0x7eff, 1, 1, "rsvd7e %#b1", 0 }, + { 0x7f00, 0x7fff, 1, 1, "sc %#b1", STEP_OVER }, + { 0x8000, 0x80ff, 1, 1, "addb %rb3,%rb2", 0 }, + { 0x8100, 0x81ff, 1, 1, "add %rw3,%rw2", 0 }, + { 0x8200, 0x82ff, 1, 1, "subb %rb3,%rb2", 0 }, + { 0x8300, 0x83ff, 1, 1, "sub %rw3,%rw2", 0 }, + { 0x8400, 0x84ff, 1, 1, "orb %rb3,%rb2", 0 }, + { 0x8500, 0x85ff, 1, 1, "or %rw3,%rw2", 0 }, + { 0x8600, 0x86ff, 1, 1, "andb %rb3,%rb2", 0 }, + { 0x8700, 0x87ff, 1, 1, "and %rw3,%rw2", 0 }, + { 0x8800, 0x88ff, 1, 1, "xorb %rb3,%rb2", 0 }, + { 0x8900, 0x89ff, 1, 1, "xor %rw3,%rw2", 0 }, + { 0x8a00, 0x8aff, 1, 1, "cpb %rb3,%rb2", 0 }, + { 0x8b00, 0x8bff, 1, 1, "cp %rw3,%rw2", 0 }, + { 0x8c00, 0x8cf0, 16, 1, "comb %rb2", 0 }, + { 0x8c02, 0x8cf2, 16, 1, "negb %rb2", 0 }, + { 0x8c04, 0x8cf4, 16, 1, "testb %rb2", 0 }, + { 0x8c06, 0x8cf6, 16, 1, "tsetb %rb2", 0 }, + { 0x8c01, 0x8cf1, 16, 1, "ldctlb %rb2,flags", 0 }, + { 0x8c08, 0x8cf8, 16, 1, "clrb %rb2", 0 }, + { 0x8c09, 0x8cf9, 16, 1, "ldctlb flags,%rb2", 0 }, + { 0x8d00, 0x8df0, 16, 1, "com %rw2", 0 }, + { 0x8d01, 0x8df1, 16, 1, "setflg %f2", 0 }, + { 0x8d02, 0x8df2, 16, 1, "neg %rw2", 0 }, + { 0x8d03, 0x8df3, 16, 1, "resflg %f2", 0 }, + { 0x8d04, 0x8df4, 16, 1, "test %rw2", 0 }, + { 0x8d05, 0x8df5, 16, 1, "comflg %f2", 0 }, + { 0x8d06, 0x8df6, 16, 1, "tset %rw2", 0 }, + { 0x8d07, 0x8d07, 1, 1, "nop", 0 }, + { 0x8d08, 0x8df8, 16, 1, "clr %rw2", 0 }, + { 0x8e00, 0x8eff, 1, 1, "ext8e %#b1", 0 }, + { 0x8f00, 0x8fff, 1, 1, "ext8f %#b1", 0 }, + { 0x9000, 0x90ff, 1, 1, "cpl %rl3,%rl2", 0 }, + { 0x9110, 0x91ff, 1, 1, "pushl @%rw2,%rl3", 0 }, + { 0x9200, 0x92ff, 1, 1, "subl %rl3,%rl2", 0 }, + { 0x9310, 0x93ff, 1, 1, "push @%rw2,%rw3", 0 }, + { 0x9400, 0x94ff, 1, 1, "ldl %rl3,%rl2", 0 }, + { 0x9510, 0x95ff, 1, 1, "popl %rl3,@%rw2", 0 }, + { 0x9600, 0x96ff, 1, 1, "addl %rl3,%rl2", 0 }, + { 0x9710, 0x97ff, 1, 1, "pop %rw3,@%rw2", 0 }, + { 0x9800, 0x98ff, 1, 1, "multl %rq3,%rl2", 0 }, + { 0x9900, 0x99ff, 1, 1, "mult %rl3,%rw2", 0 }, + { 0x9a00, 0x9aff, 1, 1, "divl %rq3,%rl2", 0 }, + { 0x9b00, 0x9bff, 1, 1, "div %rl3,%rw2", 0 }, + { 0x9c00, 0x9cf8, 8, 1, "testl %rl2", 0 }, + { 0x9d00, 0x9dff, 1, 1, "rsvd9d", 0 }, + { 0x9e00, 0x9e0f, 1, 1, "ret %c3", STEP_OUT }, + { 0x9f00, 0x9fff, 1, 1, "rsvd9f", 0 }, + { 0xa000, 0xa0ff, 1, 1, "ldb %rb3,%rb2", 0 }, + { 0xa100, 0xa1ff, 1, 1, "ld %rw3,%rw2", 0 }, + { 0xa200, 0xa2ff, 1, 1, "resb %rb2,%3", 0 }, + { 0xa300, 0xa3ff, 1, 1, "res %rw2,%3", 0 }, + { 0xa400, 0xa4ff, 1, 1, "setb %rb2,%3", 0 }, + { 0xa500, 0xa5ff, 1, 1, "set %rw2,%3", 0 }, + { 0xa600, 0xa6ff, 1, 1, "bitb %rb2,%3", 0 }, + { 0xa700, 0xa7ff, 1, 1, "bit %rw2,%3", 0 }, + { 0xa800, 0xa8ff, 1, 1, "incb %rb2,%+3", 0 }, + { 0xa900, 0xa9ff, 1, 1, "inc %rw2,%+3", 0 }, + { 0xaa00, 0xaaff, 1, 1, "decb %rb2,%+3", 0 }, + { 0xab00, 0xabff, 1, 1, "dec %rw2,%+3", 0 }, + { 0xac00, 0xacff, 1, 1, "exb %rb3,%rb2", 0 }, + { 0xad00, 0xadff, 1, 1, "ex %rw3,%rw2", 0 }, + { 0xae00, 0xaeff, 1, 1, "tccb %c3,%rb2", 0 }, + { 0xaf00, 0xafff, 1, 1, "tcc %c3,%rw2", 0 }, + { 0xb000, 0xb0f0, 16, 1, "dab %rb2", 0 }, + { 0xb100, 0xb1f0, 16, 1, "extsb %rw2", 0 }, + { 0xb107, 0xb1f7, 16, 1, "extsl %rq2", 0 }, + { 0xb10a, 0xb1fa, 16, 1, "exts %rl2", 0 }, + { 0xb200, 0xb2f0, 16, 1, "rlb %rb2,%?3", 0 }, + { 0xb201, 0xb2f1, 16, 2, "s%*lb %rb2,%$3", 0 }, + { 0xb202, 0xb2f2, 16, 1, "rlb %rb2,%?3", 0 }, + { 0xb203, 0xb2f3, 16, 2, "sdlb %rb2,%rw5", 0 }, + { 0xb204, 0xb2f4, 16, 1, "rrb %rb2,%?3", 0 }, + { 0xb206, 0xb2f6, 16, 1, "rrb %rb2,%?3", 0 }, + { 0xb208, 0xb2f8, 16, 1, "rlcb %rb2,%?3", 0 }, + { 0xb209, 0xb2f9, 16, 2, "s%*ab %rb2,%$3", 0 }, + { 0xb20a, 0xb2fa, 16, 1, "rlcb %rb2,%?3", 0 }, + { 0xb20b, 0xb2fb, 16, 2, "sdab %rb2,%rw5", 0 }, + { 0xb20c, 0xb2fc, 16, 1, "rrcb %rb2,%?3", 0 }, + { 0xb20e, 0xb2fe, 16, 1, "rrcb %rb2,%?3", 0 }, + { 0xb300, 0xb3f0, 16, 1, "rl %rw2,%?3", 0 }, + { 0xb301, 0xb3f1, 16, 2, "s%*l %rw2,%$3", 0 }, + { 0xb302, 0xb3f2, 16, 1, "rl %rw2,%?3", 0 }, + { 0xb303, 0xb3f3, 16, 2, "sdl %rw2,%rw5", 0 }, + { 0xb304, 0xb3f4, 16, 1, "rr %rw2,%?3", 0 }, + { 0xb305, 0xb3f5, 16, 2, "s%*ll %rl2,%$3", 0 }, + { 0xb306, 0xb3f6, 16, 1, "rr %rw2,%?3", 0 }, + { 0xb307, 0xb3f7, 16, 2, "sdll %rl2,%rw5", 0 }, + { 0xb308, 0xb3f8, 16, 1, "rlc %rw2,%?3", 0 }, + { 0xb309, 0xb3f9, 16, 2, "s%*a %rw2,%$3", 0 }, + { 0xb30a, 0xb3fa, 16, 1, "rlc %rw2,%?3", 0 }, + { 0xb30b, 0xb3fb, 16, 2, "sda %rw2,%rw5", 0 }, + { 0xb30c, 0xb3fc, 16, 1, "rrc %rw2,%?3", 0 }, + { 0xb30d, 0xb3fd, 16, 2, "s%*al %rl2,%$3", 0 }, + { 0xb30e, 0xb3fe, 16, 1, "rrc %rw2,%?3", 0 }, + { 0xb30f, 0xb3ff, 16, 2, "sdal %rl2,%rw5", 0 }, + { 0xb400, 0xb4ff, 1, 1, "adcb %rb3,%rb2", 0 }, + { 0xb500, 0xb5ff, 1, 1, "adc %rw3,%rw2", 0 }, + { 0xb600, 0xb6ff, 1, 1, "sbcb %rb3,%rb2", 0 }, + { 0xb700, 0xb7ff, 1, 1, "sbc %rw3,%rw2", 0 }, + { 0xb810, 0xb8f0, 16, 2, "trib @%rw2,@%rw6,%rb5", 0 }, + { 0xb812, 0xb8f2, 16, 2, "trtib @%rw2,@%rw6,%rb5", 0 }, + { 0xb814, 0xb8f4, 16, 2, "trirb @%rw2,@%rw6,%rb5", 0 }, + { 0xb816, 0xb8f6, 16, 2, "trtirb @%rw2,@%rw6,%rb5", 0 }, + { 0xb818, 0xb8f8, 16, 2, "trdb @%rw2,@%rw6,%rb5", 0 }, + { 0xb81a, 0xb8fa, 16, 2, "trtrb @%rw2,@%rw6,%rb5", 0 }, + { 0xb81c, 0xb8fc, 16, 2, "trdrb @%rw2,@%rw6,%rb5", 0 }, + { 0xb81e, 0xb8fe, 16, 2, "trtdrb @%rw2,@%rw6,%rb5", 0 }, + { 0xb900, 0xb9ff, 16, 1, "rsvdb9", 0 }, + { 0xba10, 0xbaf0, 16, 2, "cpib %rb6,@%rw2,%rw5,%c7", 0 }, + { 0xba11, 0xbaf1, 16, 2, "ldirb @%rw6,@%rw2,%rw5", STEP_OVER }, + { 0xba12, 0xbaf2, 16, 2, "cpsib @%rw6,@%rw2,%rw5,%c7", 0 }, + { 0xba14, 0xbaf4, 16, 2, "cpirb %rb6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xba16, 0xbaf6, 16, 2, "cpsirb @%rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xba18, 0xbaf8, 16, 2, "cpdb %rb6,@%rw2,%rw5,%c7", 0 }, + { 0xba19, 0xbaf9, 16, 2, "lddrb @%rw2,@%rw6,%rw5", STEP_OVER }, + { 0xba1a, 0xbafa, 16, 2, "cpsdb @%rw6,@%rw2,%rw5,%c7", 0 }, + { 0xba1c, 0xbafc, 16, 2, "cpdrb %rb6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xba1e, 0xbafe, 16, 2, "cpsdrb @%rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbb10, 0xbbf0, 16, 2, "cpi %rw6,@%rw2,%rw5,%c7", 0 }, + { 0xbb11, 0xbbf1, 16, 2, "ldir @%rw6,@%rw2,%rw5", STEP_OVER }, + { 0xbb12, 0xbbf2, 16, 2, "cpsi @%rw6,@%rw2,%rw5,%c7", 0 }, + { 0xbb14, 0xbbf4, 16, 2, "cpir %rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbb16, 0xbbf6, 16, 2, "cpsir @%rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbb18, 0xbbf8, 16, 2, "cpd %rw6,@%rw2,%rw5,%c7", 0 }, + { 0xbb19, 0xbbf9, 16, 2, "lddr @%rw2,@%rw6,%rw5", STEP_OVER }, + { 0xbb1a, 0xbbfa, 16, 2, "cpsd @%rw6,@%rw2,%rw5,%c7", 0 }, + { 0xbb1c, 0xbbfc, 16, 2, "cpdr %rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbb1e, 0xbbfe, 16, 2, "cpsdr @%rw6,@%rw2,%rw5,%c7", STEP_OVER }, + { 0xbc00, 0xbcff, 1, 1, "rrdb %rb3,%rb2", 0 }, + { 0xbd00, 0xbdff, 1, 1, "ldk %rw2,%3", 0 }, + { 0xbe00, 0xbeff, 1, 1, "rldb %rb3,%rb2", 0 }, + { 0xbf00, 0xbfff, 1, 1, "rsvdbf", 0 }, + { 0xc000, 0xcfff, 1, 1, "ldb %rb1,%#b1", 0 }, + { 0xd000, 0xdfff, 1, 1, "calr %d2", STEP_OVER }, + { 0xe000, 0xefff, 1, 1, "jr %c1,%d1", 0 }, + { 0xf000, 0xf07f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf100, 0xf17f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf200, 0xf27f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf300, 0xf37f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf400, 0xf47f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf500, 0xf57f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf600, 0xf67f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf700, 0xf77f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf800, 0xf87f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf900, 0xf97f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfa00, 0xfa7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfb00, 0xfb7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfc00, 0xfc7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfd00, 0xfd7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xfe00, 0xfe7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xff00, 0xff7f, 1, 1, "dbjnz %rb1,%d0", STEP_OVER }, + { 0xf080, 0xf0ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf180, 0xf1ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf280, 0xf2ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf380, 0xf3ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf480, 0xf4ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf580, 0xf5ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf680, 0xf6ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf780, 0xf7ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf880, 0xf8ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xf980, 0xf9ff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfa80, 0xfaff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfb80, 0xfbff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfc80, 0xfcff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfd80, 0xfdff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xfe80, 0xfeff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0xff80, 0xffff, 1, 1, "djnz %rw1,%d0", STEP_OVER }, + { 0, 0, 0, 0, nullptr, 0} +}; + +z8000_disassembler::z8000_disassembler(config *conf) : m_config(conf) +{ + for (const opcode *opc = table; opc->size; opc++) + for (u32 val = opc->beg; val <= opc->end; val += opc->step) + oplist[val] = opc - table; +} -static int n[16]; /* opcode nibbles */ -static int b[8]; /* opcode bytes */ -static int w[4]; /* opcode words */ -static void GET_OP(const uint8_t *oprom, int i, unsigned offset) +void z8000_disassembler::get_op(const data_buffer &opcodes, int i, offs_t &new_pc, u16 *w, u8 *b, u8 *n) { - uint16_t opcode = (oprom[offset] << 8) | oprom[offset + 1]; + uint16_t opcode = opcodes.r16(new_pc); w[i] = opcode; b[i*2+0] = opcode >> 8; b[i*2+1] = opcode & 0xff; @@ -31,37 +553,40 @@ static void GET_OP(const uint8_t *oprom, int i, unsigned offset) n[i*4+1] = (opcode >> 8) & 0x0f; n[i*4+2] = (opcode >> 4) & 0x0f; n[i*4+3] = opcode & 0x0f; + new_pc += 2; } -static const char *const cc[16] = { +const char *const z8000_disassembler::cc[16] = { "n", "lt", "le", "ule", "pe/ov", "mi", "eq/z", "c/ult", "a", "ge", "gt", "ugt", "po/nov", "pl", "ne/nz", "nc/uge" }; -static const char *const flg[16] = { +const char *const z8000_disassembler::flg[16] = { "", "p/v", "s", "p/v,s", "z", "p/v,z", "s,z", "p/v,s,z", "c", "p/v,c","s,c", "p/v,s,c", "z,c", "p/v,z,c","s,z,c","p/v,s,z,c" }; -static const char *const ints[4] = { +const char *const z8000_disassembler::ints[4] = { "", "vi", "nvi", "vi,nvi" }; -int z8k_segm; /* Current disassembler mode: 0 - non-segmented, 1 - segmented */ -int z8k_segm_mode = Z8K_SEGM_MODE_AUTO; /* User disassembler mode setting: segmented, non-segmented, auto */ +u32 z8000_disassembler::opcode_alignment() const +{ + return 2; +} -CPU_DISASSEMBLE(z8000) +offs_t z8000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - int new_pc = pc, i, j, tmp; + u8 n[16]; /* opcode nibbles */ + u8 b[8]; /* opcode bytes */ + u16 w[4]; /* opcode words */ + + offs_t new_pc = pc, i, j, tmp; const char *src; - z8002_device::Z8000_dasm o; uint32_t flags = 0; uint32_t old_w; - z8002_device::init_tables(); - - GET_OP(oprom, 0, new_pc - pc); - new_pc += 2; + get_op(opcodes, 0, new_pc, w, b, n); switch (pc) { case 0x0000: @@ -74,11 +599,14 @@ CPU_DISASSEMBLE(z8000) util::stream_format(stream, ".word #%%%04x ;RST PC", w[0]); break; default: - o = z8002_device::dasm(w[0]); - if (o.size > 1) { GET_OP(oprom, 1, new_pc - pc); new_pc += 2; } - if (o.size > 2) { GET_OP(oprom, 2, new_pc - pc); new_pc += 2; } + { + const opcode &o = table[oplist[w[0]]]; + if (o.size > 1) + get_op(opcodes, 1, new_pc, w, b, n); + if (o.size > 2) + get_op(opcodes, 2, new_pc, w, b, n); src = o.dasm; - flags = o.flags; + flags = o.dasmflags; while (*src) { @@ -139,14 +667,14 @@ CPU_DISASSEMBLE(z8000) tmp = ((n[1] & 0x01) << 8) + (n[3] << 4) + (n[7] & 0x08); switch (tmp) { - case 0x000: util::stream_format(stream, "inirb "); flags = DASMFLAG_STEP_OVER; break; + case 0x000: util::stream_format(stream, "inirb "); flags = STEP_OVER; break; case 0x008: util::stream_format(stream, "inib "); break; - case 0x010: util::stream_format(stream, "sinirb"); flags = DASMFLAG_STEP_OVER; break; + case 0x010: util::stream_format(stream, "sinirb"); flags = STEP_OVER; break; case 0x018: util::stream_format(stream, "sinib "); break; - case 0x020: util::stream_format(stream, "otirb "); flags = DASMFLAG_STEP_OVER; break; + case 0x020: util::stream_format(stream, "otirb "); flags = STEP_OVER; break; case 0x028: util::stream_format(stream, "outib "); break; case 0x030: util::stream_format(stream, "soutib"); break; - case 0x038: util::stream_format(stream, "sotirb"); flags = DASMFLAG_STEP_OVER; break; + case 0x038: util::stream_format(stream, "sotirb"); flags = STEP_OVER; break; case 0x040: util::stream_format(stream, "inb "); break; case 0x048: util::stream_format(stream, "inb "); break; case 0x050: util::stream_format(stream, "sinb "); break; @@ -155,22 +683,22 @@ CPU_DISASSEMBLE(z8000) case 0x068: util::stream_format(stream, "outb "); break; case 0x070: util::stream_format(stream, "soutb "); break; case 0x078: util::stream_format(stream, "soutb "); break; - case 0x080: util::stream_format(stream, "indrb "); flags = DASMFLAG_STEP_OVER; break; + case 0x080: util::stream_format(stream, "indrb "); flags = STEP_OVER; break; case 0x088: util::stream_format(stream, "indb "); break; - case 0x090: util::stream_format(stream, "sindrb"); flags = DASMFLAG_STEP_OVER; break; + case 0x090: util::stream_format(stream, "sindrb"); flags = STEP_OVER; break; case 0x098: util::stream_format(stream, "sindb "); break; - case 0x0a0: util::stream_format(stream, "otdrb "); flags = DASMFLAG_STEP_OVER; break; + case 0x0a0: util::stream_format(stream, "otdrb "); flags = STEP_OVER; break; case 0x0a8: util::stream_format(stream, "outdb "); break; case 0x0b0: util::stream_format(stream, "soutdb"); break; - case 0x0b8: util::stream_format(stream, "sotdrb"); flags = DASMFLAG_STEP_OVER; break; - case 0x100: util::stream_format(stream, "inir "); flags = DASMFLAG_STEP_OVER; break; + case 0x0b8: util::stream_format(stream, "sotdrb"); flags = STEP_OVER; break; + case 0x100: util::stream_format(stream, "inir "); flags = STEP_OVER; break; case 0x108: util::stream_format(stream, "ini "); break; - case 0x110: util::stream_format(stream, "sinir "); flags = DASMFLAG_STEP_OVER; break; + case 0x110: util::stream_format(stream, "sinir "); flags = STEP_OVER; break; case 0x118: util::stream_format(stream, "sini "); break; - case 0x120: util::stream_format(stream, "otir "); flags = DASMFLAG_STEP_OVER; break; + case 0x120: util::stream_format(stream, "otir "); flags = STEP_OVER; break; case 0x128: util::stream_format(stream, "outi "); break; case 0x130: util::stream_format(stream, "souti "); break; - case 0x138: util::stream_format(stream, "sotir "); flags = DASMFLAG_STEP_OVER; break; + case 0x138: util::stream_format(stream, "sotir "); flags = STEP_OVER; break; case 0x140: util::stream_format(stream, "in "); break; case 0x148: util::stream_format(stream, "in "); break; case 0x150: util::stream_format(stream, "sin "); break; @@ -179,14 +707,14 @@ CPU_DISASSEMBLE(z8000) case 0x168: util::stream_format(stream, "out "); break; case 0x170: util::stream_format(stream, "sout "); break; case 0x178: util::stream_format(stream, "sout "); break; - case 0x180: util::stream_format(stream, "indr "); flags = DASMFLAG_STEP_OVER; break; + case 0x180: util::stream_format(stream, "indr "); flags = STEP_OVER; break; case 0x188: util::stream_format(stream, "ind "); break; - case 0x190: util::stream_format(stream, "sindr "); flags = DASMFLAG_STEP_OVER; break; + case 0x190: util::stream_format(stream, "sindr "); flags = STEP_OVER; break; case 0x198: util::stream_format(stream, "sind "); break; - case 0x1a0: util::stream_format(stream, "otdr "); flags = DASMFLAG_STEP_OVER; break; + case 0x1a0: util::stream_format(stream, "otdr "); flags = STEP_OVER; break; case 0x1a8: util::stream_format(stream, "outd "); break; case 0x1b0: util::stream_format(stream, "soutd "); break; - case 0x1b8: util::stream_format(stream, "sotdr "); flags = DASMFLAG_STEP_OVER; break; + case 0x1b8: util::stream_format(stream, "sotdr "); flags = STEP_OVER; break; default: util::stream_format(stream, "unk(0x%x)", tmp); } @@ -195,19 +723,19 @@ CPU_DISASSEMBLE(z8000) /* address */ src++; i = *src++ - '0'; - if (z8k_segm) { + if (m_config->get_segmented_mode()) { + uint32_t address; if (w[i] & 0x8000) { old_w = w[i]; for (j = i; j < o.size; j++) w[j] = w[j + 1]; - GET_OP(oprom, o.size - 1, new_pc - pc); - new_pc += 2; - w[i] = ((old_w & 0x7f00) << 16) | (w[i] & 0xffff); + get_op(opcodes, o.size - 1, new_pc, w, b, n); + address = ((old_w & 0x7f00) << 16) | (w[i] & 0xffff); } else { - w[i] = ((w[i] & 0x7f00) << 16) | (w[i] & 0xff); + address = ((w[i] & 0x7f00) << 16) | (w[i] & 0xff); } - util::stream_format(stream, "<%%%02X>%%%04X", (w[i] >> 24) & 0xff, w[i] & 0xffff); + util::stream_format(stream, "<%%%02X>%%%04X", (address >> 24) & 0xff, address & 0xffff); } else util::stream_format(stream, "%%%04x", w[i]); break; @@ -244,7 +772,7 @@ CPU_DISASSEMBLE(z8000) tmp = 0; abort(); } - if (z8k_segm) + if (m_config->get_segmented_mode()) util::stream_format(stream, "<%%%02X>%%%04X", (tmp >> 16) & 0xff, tmp & 0xffff); else util::stream_format(stream, "%%%04x", tmp); @@ -307,7 +835,8 @@ CPU_DISASSEMBLE(z8000) } } else stream << *src++; } - break; + } + break; } - return (new_pc - pc) | flags | DASMFLAG_SUPPORTED; + return (new_pc - pc) | flags | SUPPORTED; } diff --git a/src/devices/cpu/z8000/8000dasm.h b/src/devices/cpu/z8000/8000dasm.h new file mode 100644 index 00000000000..16a2f0974e1 --- /dev/null +++ b/src/devices/cpu/z8000/8000dasm.h @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:Juergen Buchmueller,Ernesto Corvi +/***************************************************************************** + * + * 8000dasm.c + * Portable Z8000(2) emulator + * + *****************************************************************************/ + +#ifndef MAME_CPU_Z8000_8000DASM_H +#define MAME_CPU_Z8000_8000DASM_H + +#pragma once + +class z8000_disassembler : public util::disasm_interface +{ +public: + struct config { + virtual ~config() = default; + virtual bool get_segmented_mode() const = 0; + }; + + z8000_disassembler(config *conf); + virtual ~z8000_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + struct opcode { + u16 beg, end, step; + u16 size; + const char *dasm; + offs_t dasmflags; + }; + + static const opcode table[]; + static const char *const cc[16]; + static const char *const flg[16]; + static const char *const ints[4]; + + config *m_config; + + u16 oplist[0x10000]; + + void get_op(const data_buffer &opcodes, int i, offs_t &new_pc, u16 *w, u8 *b, u8 *n); + +}; + +#endif diff --git a/src/devices/cpu/z8000/z8000.cpp b/src/devices/cpu/z8000/z8000.cpp index ab42e44539e..ce2751723a8 100644 --- a/src/devices/cpu/z8000/z8000.cpp +++ b/src/devices/cpu/z8000/z8000.cpp @@ -22,10 +22,6 @@ //#define VERBOSE 1 #include "logmacro.h" - -extern int z8k_segm; -extern int z8k_segm_mode; - DEFINE_DEVICE_TYPE(Z8001, z8001_device, "z8001", "Zilog Z8001") DEFINE_DEVICE_TYPE(Z8002, z8002_device, "z8002", "Zilog Z8002") @@ -54,12 +50,6 @@ z8001_device::z8001_device(const machine_config &mconfig, const char *tag, devic } -offs_t z8002_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - extern CPU_DISASSEMBLE( z8000 ); - return CPU_DISASSEMBLE_NAME(z8000)(this, stream, pc, oprom, opram, options); -} - device_memory_interface::space_config_vector z8002_device::memory_space_config() const { return space_config_vector { @@ -77,21 +67,14 @@ device_memory_interface::space_config_vector z8001_device::memory_space_config() }; } -/* opcode execution table */ -std::unique_ptr<z8002_device::Z8000_exec const []> z8002_device::z8000_exec; - -/* zero, sign and parity flags for logical byte operations */ -static uint8_t z8000_zsp[256]; - - -int z8002_device::segmented_mode() +bool z8002_device::get_segmented_mode() const { - return 0; + return false; } -int z8001_device::segmented_mode() +bool z8001_device::get_segmented_mode() const { - return (m_fcw & F_SEG) ? 1 : 0; + return (m_fcw & F_SEG) ? true : false; } uint32_t z8002_device::addr_add(uint32_t addr, uint32_t addend) @@ -145,7 +128,7 @@ uint32_t z8002_device::get_addr_operand(int opnum) { uint32_t seg = m_program->read_word(m_pc); m_pc += 2; - if (segmented_mode()) + if (get_segmented_mode()) { if (seg & 0x8000) { @@ -175,7 +158,7 @@ uint32_t z8002_device::get_raw_addr_operand(int opnum) { uint32_t seg = m_program->read_word(m_pc); m_pc += 2; - if (segmented_mode()) + if (get_segmented_mode()) { if (seg & 0x8000) { @@ -651,47 +634,22 @@ void z8002_device::state_string_export(const device_state_entry &entry, std::str } } -void z8001_device::z8k_disass_mode(int ref, const std::vector<std::string> ¶ms) +void z8002_device::init_tables() { - size_t len; - if (params.size() == 1) - { - len = params[0].length(); - if (!core_strnicmp(params[0].c_str(), "segmented", len) || !core_stricmp(params[0].c_str(), "z8001")) { - z8k_segm = true; - z8k_segm_mode = Z8K_SEGM_MODE_SEG; - machine().debugger().console().printf("Disassembler mode set to Z8001/segmented\n"); - } - else if (!core_strnicmp(params[0].c_str(), "non-segmented", len) || !core_stricmp(params[0].c_str(), "z8002")) - { - z8k_segm = false; - z8k_segm_mode = Z8K_SEGM_MODE_NONSEG; - machine().debugger().console().printf("Disassembler mode set to Z8002/non-segmented\n"); - } - else if (!core_strnicmp(params[0].c_str(), "automatic", len)) - { - z8k_segm_mode = Z8K_SEGM_MODE_AUTO; - machine().debugger().console().printf("Disassembler mode set to automatic\n"); - } - else - goto usage; - } - else if (params.size() > 1) - { - usage: - machine().debugger().console().printf("Usage: z8k_disass_mode <mode>\n"); - machine().debugger().console().printf(" set disassembler mode\n"); - machine().debugger().console().printf(" mode: \"segmented\" or \"z8001\" - Z8001 mode\n"); - machine().debugger().console().printf(" \"non-segmented\" or \"z8002\" - Z8002 mode\n"); - machine().debugger().console().printf(" \"automatic\" - automatic mode\n"); - } - else - { - machine().debugger().console().printf("Current disassembler mode: "); - if (z8k_segm_mode == Z8K_SEGM_MODE_AUTO) - machine().debugger().console().printf("automatic, currently "); - machine().debugger().console().printf("%s\n", z8k_segm ? "Z8001/segmented" : "Z8002/non-segmented"); - } + /* set up the zero, sign, parity lookup table */ + for (int i = 0; i < 256; i++) + z8000_zsp[i] = ((i == 0) ? F_Z : 0) | + ((i & 128) ? F_S : 0) | + ((((i>>7)^(i>>6)^(i>>5)^(i>>4)^(i>>3)^(i>>2)^(i>>1)^i) & 1) ? 0 : F_PV); + + for (const Z8000_init *opc = table; opc->size; opc++) + for (u32 val = opc->beg; val <= opc->end; val += opc->step) + z8000_exec[val] = opc - table; +} + +util::disasm_interface *z8002_device::create_disassembler() +{ + return new z8000_disassembler(this); } void z8001_device::device_start() @@ -705,19 +663,11 @@ void z8001_device::device_start() m_data = &space(AS_DATA); else m_data = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); init_tables(); - if (machine().debug_flags & DEBUG_FLAG_ENABLED) - { - using namespace std::placeholders; - machine().debugger().console().register_command("z8k_disass_mode", CMDFLAG_NONE, 0, 0, 1, std::bind(&z8001_device::z8k_disass_mode, this, _1, _2)); - } - - z8k_segm = true; - register_debug_state(); m_icountptr = &m_icount; @@ -736,13 +686,11 @@ void z8002_device::device_start() m_data = &space(AS_DATA); else m_data = &space(AS_PROGRAM); - m_direct = &m_program->direct(); + m_direct = m_program->direct<0>(); m_io = &space(AS_IO); init_tables(); - z8k_segm = false; - register_debug_state(); m_icountptr = &m_icount; @@ -773,8 +721,6 @@ void z8002_device::device_reset() z8002_device::~z8002_device() { - // FIXME: assumes that these CPUs can't outlive each other - deinit_tables(); } void z8002_device::execute_run() @@ -785,9 +731,6 @@ void z8002_device::execute_run() if (m_irq_req) Interrupt(); - if (z8k_segm_mode == Z8K_SEGM_MODE_AUTO) - z8k_segm = (m_fcw & F_SEG_Z8001()) ? 1 : 0; - m_ppc = m_pc; debugger_instruction_hook(this, m_pc); @@ -799,10 +742,10 @@ void z8002_device::execute_run() { m_op[0] = RDOP(); m_op_valid = 1; - Z8000_exec const *const exec = &z8000_exec[m_op[0]]; + const Z8000_init &exec = table[z8000_exec[m_op[0]]]; - m_icount -= exec->cycles; - (this->*exec->opcode)(); + m_icount -= exec.cycles; + (this->*exec.opcode)(); m_op_valid = 0; } } while (m_icount > 0); diff --git a/src/devices/cpu/z8000/z8000.h b/src/devices/cpu/z8000/z8000.h index a782efbaf18..4e3f69e5858 100644 --- a/src/devices/cpu/z8000/z8000.h +++ b/src/devices/cpu/z8000/z8000.h @@ -5,6 +5,7 @@ #pragma once +#include "8000dasm.h" enum { @@ -31,7 +32,7 @@ enum #define MCFG_Z8000_MO(_devcb) \ devcb = &z8002_device::set_mo_callback(*device, DEVCB_##_devcb); -class z8002_device : public cpu_device +class z8002_device : public cpu_device, public z8000_disassembler::config { public: // construction/destruction @@ -41,12 +42,6 @@ public: template <class Object> static devcb_base &set_mo_callback(device_t &device, Object &&cb) { return downcast<z8002_device &>(device).m_mo_out.set_callback(std::forward<Object>(cb)); } DECLARE_WRITE_LINE_MEMBER(mi_w) { m_mi = state; } // XXX: this has to apply in the middle of an insn for now - struct Z8000_dasm { char const *dasm; uint32_t flags; int size; }; - - static void init_tables(); - static void deinit_tables(); - static Z8000_dasm dasm(unsigned w); - protected: z8002_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int addrbits, int iobits, int vecmult); @@ -69,9 +64,9 @@ protected: 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 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 6; } - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; + + void init_tables(); address_space_config m_program_config; address_space_config m_io_config; @@ -101,14 +96,14 @@ protected: int m_mi; address_space *m_program; address_space *m_data; - direct_read_data *m_direct; + direct_read_data<0> *m_direct; address_space *m_io; int m_icount; int m_vector_mult; void clear_internal_state(); void register_debug_state(); - virtual int segmented_mode(); + virtual bool get_segmented_mode() const override; static inline uint32_t addr_add(uint32_t addr, uint32_t addend); static inline uint32_t addr_sub(uint32_t addr, uint32_t subtrahend); inline uint16_t RDOP(); @@ -628,22 +623,14 @@ private: int beg, end, step; int size, cycles; opcode_func opcode; - const char *dasm; - uint32_t dasmflags; - }; - - /* structure for the opcode execution table / disassembler */ - struct Z8000_exec { - opcode_func opcode; - int cycles; - int size; - const char *dasm; - uint32_t dasmflags; }; /* opcode execution table */ static const Z8000_init table[]; - static std::unique_ptr<Z8000_exec const []> z8000_exec; + u16 z8000_exec[0x10000]; + + /* zero, sign and parity flags for logical byte operations */ + u8 z8000_zsp[256]; }; @@ -661,12 +648,9 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - // device_disasm_interface overrides - virtual uint32_t disasm_max_opcode_bytes() const override { return 8; } - address_space_config m_data_config; - virtual int segmented_mode() override; + virtual bool get_segmented_mode() const override; virtual uint32_t adjust_addr_for_nonseg_mode(uint32_t addr) override; virtual uint16_t RDPORT_W(int mode, uint16_t addr) override; virtual void WRPORT_W(int mode, uint16_t addr, uint16_t value) override; @@ -677,9 +661,6 @@ protected: virtual uint32_t F_SEG_Z8001() override; virtual uint32_t PSA_ADDR() override; virtual uint32_t read_irq_vector() override; - -private: - void z8k_disass_mode(int ref, const std::vector<std::string> ¶ms); }; diff --git a/src/devices/cpu/z8000/z8000cpu.h b/src/devices/cpu/z8000/z8000cpu.h index 102cac41f0e..dc65a8dc3df 100644 --- a/src/devices/cpu/z8000/z8000cpu.h +++ b/src/devices/cpu/z8000/z8000cpu.h @@ -42,7 +42,7 @@ #define RQ(n) m_regs.Q[(n) >> 2] /* the register used as stack pointer */ -#define SP (segmented_mode() ? 14 : 15) +#define SP (get_segmented_mode() ? 14 : 15) /* these vectors are based on m_psap */ #define RST (PSA_ADDR() + 0) /* start up m_fcw and m_pc */ diff --git a/src/devices/cpu/z8000/z8000ops.hxx b/src/devices/cpu/z8000/z8000ops.hxx index bde18d4d70b..4599538525f 100644 --- a/src/devices/cpu/z8000/z8000ops.hxx +++ b/src/devices/cpu/z8000/z8000ops.hxx @@ -96,7 +96,7 @@ uint32_t z8002_device::segmented_addr(uint32_t addr) uint32_t z8002_device::addr_from_reg(int regno) { - if (segmented_mode()) + if (get_segmented_mode()) return segmented_addr(RL(regno)); else return RW(regno); @@ -104,7 +104,7 @@ uint32_t z8002_device::addr_from_reg(int regno) void z8002_device::addr_to_reg(int regno, uint32_t addr) { - if (segmented_mode()) { + if (get_segmented_mode()) { uint32_t segaddr = make_segmented_addr(addr); RW(regno) = (RW(regno) & 0x80ff) | ((segaddr >> 16) & 0x7f00); RW(regno | 1) = segaddr & 0xffff; @@ -115,21 +115,21 @@ void z8002_device::addr_to_reg(int regno, uint32_t addr) void z8002_device::add_to_addr_reg(int regno, uint16_t addend) { - if (segmented_mode()) + if (get_segmented_mode()) regno |= 1; RW(regno) += addend; } void z8002_device::sub_from_addr_reg(int regno, uint16_t subtrahend) { - if (segmented_mode()) + if (get_segmented_mode()) regno |= 1; RW(regno) -= subtrahend; } void z8002_device::set_pc(uint32_t addr) { - if (segmented_mode()) + if (get_segmented_mode()) m_pc = addr; else m_pc = (m_pc & 0xffff0000) | (addr & 0xffff); @@ -137,7 +137,7 @@ void z8002_device::set_pc(uint32_t addr) void z8002_device::PUSHW(uint8_t dst, uint16_t value) { - if (segmented_mode()) + if (get_segmented_mode()) RW(dst | 1) -= 2; else RW(dst) -= 2; @@ -147,7 +147,7 @@ void z8002_device::PUSHW(uint8_t dst, uint16_t value) uint16_t z8002_device::POPW(uint8_t src) { uint16_t result = RDMEM_W(AS_DATA, addr_from_reg(src)); - if (segmented_mode()) + if (get_segmented_mode()) RW(src | 1) += 2; else RW(src) += 2; @@ -156,7 +156,7 @@ uint16_t z8002_device::POPW(uint8_t src) void z8002_device::PUSHL(uint8_t dst, uint32_t value) { - if (segmented_mode()) + if (get_segmented_mode()) RW(dst | 1) -= 4; else RW(dst) -= 4; @@ -166,7 +166,7 @@ void z8002_device::PUSHL(uint8_t dst, uint32_t value) uint32_t z8002_device::POPL(uint8_t src) { uint32_t result = RDMEM_L(AS_DATA, addr_from_reg(src)); - if (segmented_mode()) + if (get_segmented_mode()) RW(src | 1) += 4; else RW(src) += 4; @@ -1971,7 +1971,7 @@ void z8002_device::Z1E_ddN0_cccc() void z8002_device::Z1F_ddN0_0000() { GET_DST(OP0,NIB2); - if (segmented_mode()) + if (get_segmented_mode()) PUSHL(SP, make_segmented_addr(m_pc)); else PUSHW(SP, m_pc); @@ -2361,7 +2361,7 @@ void z8002_device::Z34_ssN0_dddd_imm16() GET_DST(OP0,NIB3); GET_SRC(OP0,NIB2); GET_IDX16(OP1); - if (segmented_mode()) { + if (get_segmented_mode()) { RL(dst) = RL(src); } else { @@ -2465,7 +2465,7 @@ void z8002_device::Z39_ssN0_0000() CHECK_PRIVILEGED_INSTR(); GET_SRC(OP0,NIB2); uint16_t fcw; - if (segmented_mode()) { + if (get_segmented_mode()) { uint32_t addr = addr_from_reg(src); fcw = RDMEM_W(AS_DATA, addr + 2); set_pc(segmented_addr(RDMEM_L(AS_DATA, addr + 4))); @@ -3995,7 +3995,7 @@ void z8002_device::Z5E_ddN0_cccc_addr() void z8002_device::Z5F_0000_0000_addr() { GET_ADDR(OP1); - if (segmented_mode()) + if (get_segmented_mode()) PUSHL(SP, make_segmented_addr(m_pc)); else PUSHW(SP, m_pc); @@ -4010,7 +4010,7 @@ void z8002_device::Z5F_ddN0_0000_addr() { GET_DST(OP0,NIB2); GET_ADDR(OP1); - if (segmented_mode()) + if (get_segmented_mode()) PUSHL(SP, make_segmented_addr(m_pc)); else PUSHW(SP, m_pc); @@ -4469,7 +4469,7 @@ void z8002_device::Z74_ssN0_dddd_0000_xxxx_0000_0000() GET_DST(OP0,NIB3); GET_SRC(OP0,NIB2); GET_IDX(OP1,NIB1); - if (segmented_mode()) { + if (get_segmented_mode()) { RL(dst) = RL(src); } else { @@ -4498,7 +4498,7 @@ void z8002_device::Z76_0000_dddd_addr() { GET_DST(OP0,NIB3); GET_ADDR_RAW(OP1); - if (segmented_mode()) { + if (get_segmented_mode()) { RL(dst) = addr; } else { @@ -4516,7 +4516,7 @@ void z8002_device::Z76_ssN0_dddd_addr() GET_SRC(OP0,NIB2); GET_ADDR_RAW(OP1); uint16_t temp = RW(src); // store src in case dst == src - if (segmented_mode()) { + if (get_segmented_mode()) { RL(dst) = addr; } else { @@ -4560,7 +4560,7 @@ void z8002_device::Z79_0000_0000_addr() CHECK_PRIVILEGED_INSTR(); GET_ADDR(OP1); uint16_t fcw; - if (segmented_mode()) { + if (get_segmented_mode()) { fcw = RDMEM_W(AS_DATA, addr + 2); set_pc(segmented_addr(RDMEM_L(AS_DATA, addr + 4))); } @@ -4582,7 +4582,7 @@ void z8002_device::Z79_ssN0_0000_addr() GET_ADDR(OP1); uint16_t fcw; addr = addr_add(addr, RW(src)); - if (segmented_mode()) { + if (get_segmented_mode()) { fcw = RDMEM_W(AS_DATA, addr + 2); set_pc(segmented_addr(RDMEM_L(AS_DATA, addr + 4))); } @@ -4615,7 +4615,7 @@ void z8002_device::Z7B_0000_0000() CHECK_PRIVILEGED_INSTR(); tag = POPW(SP); /* get type tag */ fcw = POPW(SP); /* get m_fcw */ - if (segmented_mode()) + if (get_segmented_mode()) set_pc(segmented_addr(POPL(SP))); else m_pc = POPW(SP); /* get m_pc */ @@ -5289,7 +5289,7 @@ void z8002_device::Z9D_imm8() void z8002_device::Z9E_0000_cccc() { GET_CCC(OP0,NIB3); - if (segmented_mode()) + if (get_segmented_mode()) switch (cc) { case 0: if (CC0) set_pc(segmented_addr(POPL(SP))); break; case 1: if (CC1) set_pc(segmented_addr(POPL(SP))); break; @@ -6746,7 +6746,7 @@ void z8002_device::ZC_dddd_imm8() void z8002_device::ZD_dsp12() { int16_t dsp12 = m_op[0] & 0xfff; - if (segmented_mode()) + if (get_segmented_mode()) PUSHL(SP, make_segmented_addr(m_pc)); else PUSHW(SP, m_pc); diff --git a/src/devices/cpu/z8000/z8000tbl.hxx b/src/devices/cpu/z8000/z8000tbl.hxx index 7ebbeb4d071..0d54009a7f4 100644 --- a/src/devices/cpu/z8000/z8000tbl.hxx +++ b/src/devices/cpu/z8000/z8000tbl.hxx @@ -9,583 +9,525 @@ *****************************************************************************/ const z8002_device::Z8000_init z8002_device::table[] = { -{0x0000,0x000f, 1,2, 7,&z8002_device::Z00_0000_dddd_imm8, "addb %rb3,%#b3", 0}, -{0x0010,0x00ff, 1,1, 7,&z8002_device::Z00_ssN0_dddd, "addb %rb3,@%rw2", 0}, -{0x0100,0x010f, 1,2, 7,&z8002_device::Z01_0000_dddd_imm16, "add %rw3,%#w1", 0}, -{0x0110,0x01ff, 1,1, 7,&z8002_device::Z01_ssN0_dddd, "add %rw3,@%rw2", 0}, -{0x0200,0x020f, 1,2, 7,&z8002_device::Z02_0000_dddd_imm8, "subb %rb3,%#b3", 0}, -{0x0210,0x02ff, 1,1, 7,&z8002_device::Z02_ssN0_dddd, "subb %rb3,@%rw2", 0}, -{0x0300,0x030f, 1,2, 7,&z8002_device::Z03_0000_dddd_imm16, "sub %rw3,%#w1", 0}, -{0x0310,0x03ff, 1,1, 7,&z8002_device::Z03_ssN0_dddd, "sub %rw3,@%rw2", 0}, -{0x0400,0x040f, 1,2, 7,&z8002_device::Z04_0000_dddd_imm8, "orb %rb3,%#b3", 0}, -{0x0410,0x04ff, 1,1, 7,&z8002_device::Z04_ssN0_dddd, "orb %rb3,@%rw2", 0}, -{0x0500,0x050f, 1,2, 7,&z8002_device::Z05_0000_dddd_imm16, "or %rw3,%#w1", 0}, -{0x0510,0x05ff, 1,1, 7,&z8002_device::Z05_ssN0_dddd, "or %rw3,@%rw2", 0}, -{0x0600,0x060f, 1,2, 7,&z8002_device::Z06_0000_dddd_imm8, "andb %rb3,%#b3", 0}, -{0x0610,0x06ff, 1,1, 7,&z8002_device::Z06_ssN0_dddd, "andb %rb3,@%rw2", 0}, -{0x0700,0x070f, 1,2, 7,&z8002_device::Z07_0000_dddd_imm16, "and %rw3,%#w1", 0}, -{0x0710,0x07ff, 1,1, 7,&z8002_device::Z07_ssN0_dddd, "and %rw3,@%rw2", 0}, -{0x0800,0x080f, 1,2, 7,&z8002_device::Z08_0000_dddd_imm8, "xorb %rb3,%#b3", 0}, -{0x0810,0x08ff, 1,1, 7,&z8002_device::Z08_ssN0_dddd, "xorb %rb3,@%rw2", 0}, -{0x0900,0x090f, 1,2, 7,&z8002_device::Z09_0000_dddd_imm16, "xor %rw3,%#w1", 0}, -{0x0910,0x09ff, 1,1, 7,&z8002_device::Z09_ssN0_dddd, "xor %rw3,@%rw2", 0}, -{0x0a00,0x0a0f, 1,2, 7,&z8002_device::Z0A_0000_dddd_imm8, "cpb %rb3,%#b3", 0}, -{0x0a10,0x0aff, 1,1, 7,&z8002_device::Z0A_ssN0_dddd, "cpb %rb3,@%rw2", 0}, -{0x0b00,0x0b0f, 1,2, 7,&z8002_device::Z0B_0000_dddd_imm16, "cp %rw3,%#w1", 0}, -{0x0b10,0x0bff, 1,1, 7,&z8002_device::Z0B_ssN0_dddd, "cp %rw3,@%rw2", 0}, -{0x0c10,0x0cf0,16,1, 12,&z8002_device::Z0C_ddN0_0000, "comb @%rw2", 0}, -{0x0c11,0x0cf1,16,2, 11,&z8002_device::Z0C_ddN0_0001_imm8, "cpb @%rw2,%#b3", 0}, -{0x0c12,0x0cf2,16,1, 12,&z8002_device::Z0C_ddN0_0010, "negb @%rw2", 0}, -{0x0c14,0x0cf4,16,1, 8,&z8002_device::Z0C_ddN0_0100, "testb @%rw2", 0}, -{0x0c15,0x0cf5,16,2, 7,&z8002_device::Z0C_ddN0_0101_imm8, "ldb @%rw2,%#b3", 0}, -{0x0c16,0x0cf6,16,1, 11,&z8002_device::Z0C_ddN0_0110, "tsetb @%rw2", 0}, -{0x0c18,0x0cf8,16,1, 8,&z8002_device::Z0C_ddN0_1000, "clrb @%rw2", 0}, -{0x0d10,0x0df0,16,1, 12,&z8002_device::Z0D_ddN0_0000, "com @%rw2", 0}, -{0x0d11,0x0df1,16,2, 11,&z8002_device::Z0D_ddN0_0001_imm16, "cp @%rw2,%#w1", 0}, -{0x0d12,0x0df2,16,1, 12,&z8002_device::Z0D_ddN0_0010, "neg @%rw2", 0}, -{0x0d14,0x0df4,16,1, 8,&z8002_device::Z0D_ddN0_0100, "test @%rw2", 0}, -{0x0d15,0x0df5,16,2, 11,&z8002_device::Z0D_ddN0_0101_imm16, "ld @%rw2,%#w1", 0}, /* fix cycles ld IR,IM */ -{0x0d16,0x0df6,16,1, 11,&z8002_device::Z0D_ddN0_0110, "tset @%rw2", 0}, -{0x0d18,0x0df8,16,1, 8,&z8002_device::Z0D_ddN0_1000, "clr @%rw2", 0}, -{0x0d19,0x0df9,16,2, 12,&z8002_device::Z0D_ddN0_1001_imm16, "push @%rw2,%#w1", 0}, -{0x0e00,0x0eff, 1,1, 10,&z8002_device::Z0E_imm8, "ext0e %#b1", 0}, -{0x0f00,0x0fff, 1,1, 10,&z8002_device::Z0F_imm8, "ext0f %#b1", 0}, -{0x1000,0x100f, 1,3, 14,&z8002_device::Z10_0000_dddd_imm32, "cpl %rl3,%#l1", 0}, -{0x1010,0x10ff, 1,1, 14,&z8002_device::Z10_ssN0_dddd, "cpl %rl3,@%rw2", 0}, -{0x1111,0x11ff, 1,1, 20,&z8002_device::Z11_ddN0_ssN0, "pushl @%rw2,@%rw3", 0}, -{0x1200,0x120f, 1,3, 14,&z8002_device::Z12_0000_dddd_imm32, "subl %rl3,%#l1", 0}, -{0x1210,0x12ff, 1,1, 14,&z8002_device::Z12_ssN0_dddd, "subl %rl3,@%rw2", 0}, -{0x1311,0x13ff, 1,1, 13,&z8002_device::Z13_ddN0_ssN0, "push @%rw2,@%rw3", 0}, -{0x1400,0x140f, 1,3, 11,&z8002_device::Z14_0000_dddd_imm32, "ldl %rl3,%#l1", 0}, -{0x1410,0x14ff, 1,1, 11,&z8002_device::Z14_ssN0_dddd, "ldl %rl3,@%rw2", 0}, -{0x1511,0x15ff, 1,1, 19,&z8002_device::Z15_ssN0_ddN0, "popl @%rw3,@%rw2", 0}, -{0x1600,0x160f, 1,3, 14,&z8002_device::Z16_0000_dddd_imm32, "addl %rl3,%#l1", 0}, -{0x1610,0x16ff, 1,1, 14,&z8002_device::Z16_ssN0_dddd, "addl %rl3,@%rw2", 0}, -{0x1711,0x17ff, 1,1, 12,&z8002_device::Z17_ssN0_ddN0, "pop @%rw3,@%rw2", 0}, -{0x1800,0x180f, 1,1,282,&z8002_device::Z18_00N0_dddd_imm32, "multl %rq3,@%l#1", 0}, -{0x1810,0x18ff, 1,1,282,&z8002_device::Z18_ssN0_dddd, "multl %rq3,@%rw2", 0}, -{0x1900,0x190f, 1,2, 70,&z8002_device::Z19_0000_dddd_imm16, "mult %rl3,%#w1", 0}, -{0x1910,0x19ff, 1,1, 70,&z8002_device::Z19_ssN0_dddd, "mult %rl3,@%rw2", 0}, -{0x1a00,0x1a0f, 1,3,744,&z8002_device::Z1A_0000_dddd_imm32, "divl %rq3,%#l1", 0}, -{0x1a10,0x1aff, 1,1,744,&z8002_device::Z1A_ssN0_dddd, "divl %rq3,@%rw2", 0}, -{0x1b00,0x1b0f, 1,2,107,&z8002_device::Z1B_0000_dddd_imm16, "div %rl3,%#w1", 0}, -{0x1b10,0x1bff, 1,1,107,&z8002_device::Z1B_ssN0_dddd, "div %rl3,@%rw2", 0}, -{0x1c11,0x1cf1,16,2, 11,&z8002_device::Z1C_ssN0_0001_0000_dddd_0000_nmin1, "ldm %rw5,@%rw2,#%n", 0}, -{0x1c18,0x1cf8,16,1, 13,&z8002_device::Z1C_ddN0_1000, "testl @%rw2", 0}, -{0x1c19,0x1cf9,16,2, 11,&z8002_device::Z1C_ddN0_1001_0000_ssss_0000_nmin1, "ldm @%rw2,%rw5,#%n", 0}, -{0x1d10,0x1dff, 1,1, 11,&z8002_device::Z1D_ddN0_ssss, "ldl @%rw2,%rl3", 0}, -{0x1e10,0x1eff, 1,1, 10,&z8002_device::Z1E_ddN0_cccc, "jp %c3,@%rl2", 0}, -{0x1f10,0x1ff0,16,1, 10,&z8002_device::Z1F_ddN0_0000, "call %rw2", DASMFLAG_STEP_OVER}, -{0x2000,0x200f, 1,2, 7,&z8002_device::Z20_0000_dddd_imm8, "ldb %rb3,%#b3", 0}, -{0x2010,0x20ff, 1,1, 7,&z8002_device::Z20_ssN0_dddd, "ldb %rb3,@%rw2", 0}, -{0x2100,0x210f, 1,2, 7,&z8002_device::Z21_0000_dddd_imm16, "ld %rw3,%#w1", 0}, -{0x2110,0x21ff, 1,1, 7,&z8002_device::Z21_ssN0_dddd, "ld %rw3,@%rw2", 0}, -{0x2200,0x220f, 1,2, 10,&z8002_device::Z22_0000_ssss_0000_dddd_0000_0000, "resb %rb5,%rw3", 0}, -{0x2210,0x22ff, 1,1, 11,&z8002_device::Z22_ddN0_imm4, "resb @%rw2,%3", 0}, -{0x2300,0x230f, 1,2, 10,&z8002_device::Z23_0000_ssss_0000_dddd_0000_0000, "res %rw5,%rw3", 0}, -{0x2310,0x23ff, 1,1, 11,&z8002_device::Z23_ddN0_imm4, "res @%rw2,%3", 0}, -{0x2400,0x240f, 1,2, 10,&z8002_device::Z24_0000_ssss_0000_dddd_0000_0000, "setb %rb5,%rw3", 0}, -{0x2410,0x24ff, 1,1, 11,&z8002_device::Z24_ddN0_imm4, "setb @%rw2,%3", 0}, -{0x2500,0x250f, 1,2, 10,&z8002_device::Z25_0000_ssss_0000_dddd_0000_0000, "set %rw5,%rw3", 0}, -{0x2510,0x25ff, 1,1, 11,&z8002_device::Z25_ddN0_imm4, "set @%rw2,%3", 0}, -{0x2600,0x260f, 1,2, 10,&z8002_device::Z26_0000_ssss_0000_dddd_0000_0000, "bitb %rb5,%rw3", 0}, -{0x2610,0x26ff, 1,1, 8,&z8002_device::Z26_ddN0_imm4, "bitb @%rw2,%3", 0}, -{0x2700,0x270f, 1,2, 10,&z8002_device::Z27_0000_ssss_0000_dddd_0000_0000, "bit %rw5,%rw3", 0}, -{0x2710,0x27ff, 1,1, 8,&z8002_device::Z27_ddN0_imm4, "bit @%rw2,%3", 0}, -{0x2810,0x28ff, 1,1, 11,&z8002_device::Z28_ddN0_imm4m1, "incb @%rw2,%+3", 0}, -{0x2910,0x29ff, 1,1, 11,&z8002_device::Z29_ddN0_imm4m1, "inc @%rw2,%+3", 0}, -{0x2a10,0x2aff, 1,1, 11,&z8002_device::Z2A_ddN0_imm4m1, "decb @%rw2,%+3", 0}, -{0x2b10,0x2bff, 1,1, 11,&z8002_device::Z2B_ddN0_imm4m1, "dec @%rw2,%+3", 0}, -{0x2c10,0x2cff, 1,1, 12,&z8002_device::Z2C_ssN0_dddd, "exb %rb3,@%rw2", 0}, -{0x2d10,0x2dff, 1,1, 12,&z8002_device::Z2D_ssN0_dddd, "ex %rw3,@%rw2", 0}, -{0x2e10,0x2eff, 1,1, 8,&z8002_device::Z2E_ddN0_ssss, "ldb @%rw2,%rb3", 0}, -{0x2f10,0x2fff, 1,1, 8,&z8002_device::Z2F_ddN0_ssss, "ld @%rw2,%rw3", 0}, -{0x3000,0x300f, 1,2, 14,&z8002_device::Z30_0000_dddd_dsp16, "ldrb %rb3,%p1", 0}, -{0x3010,0x30ff, 1,2, 14,&z8002_device::Z30_ssN0_dddd_imm16, "ldb %rb3,%rw2(%#w1)", 0}, -{0x3100,0x310f, 1,2, 14,&z8002_device::Z31_0000_dddd_dsp16, "ldr %rw3,%p1", 0}, -{0x3110,0x31ff, 1,2, 14,&z8002_device::Z31_ssN0_dddd_imm16, "ld %rw3,%rw2(%#w1)", 0}, -{0x3200,0x320f, 1,2, 14,&z8002_device::Z32_0000_ssss_dsp16, "ldrb %p1,%rb3", 0}, -{0x3210,0x32ff, 1,2, 14,&z8002_device::Z32_ddN0_ssss_imm16, "ldb %rw2(%#w1),%rb3", 0}, -{0x3300,0x330f, 1,2, 14,&z8002_device::Z33_0000_ssss_dsp16, "ldr %p1,%rw3", 0}, -{0x3310,0x33ff, 1,2, 14,&z8002_device::Z33_ddN0_ssss_imm16, "ld %rw2(%#w1),%rw3", 0}, -{0x3400,0x340f, 1,2, 15,&z8002_device::Z34_0000_dddd_dsp16, "ldar p%rw3,%p1", 0}, -{0x3410,0x34ff, 1,2, 15,&z8002_device::Z34_ssN0_dddd_imm16, "lda p%rw3,%rw2(%#w1)", 0}, -{0x3500,0x350f, 1,2, 17,&z8002_device::Z35_0000_dddd_dsp16, "ldrl %rl3,%p1", 0}, -{0x3510,0x35ff, 1,2, 17,&z8002_device::Z35_ssN0_dddd_imm16, "ldl %rl3,%rw2(%#w1)", 0}, -{0x3600,0x3600, 1,1, 2,&z8002_device::Z36_0000_0000, "bpt", 0}, -{0x3601,0x36ff, 1,1, 10,&z8002_device::Z36_imm8, "rsvd36", 0}, -{0x3700,0x370f, 1,2, 17,&z8002_device::Z37_0000_ssss_dsp16, "ldrl %p1,%rl3", 0}, -{0x3710,0x37ff, 1,2, 17,&z8002_device::Z37_ddN0_ssss_imm16, "ldl %rw2(%#w1),%rl3", 0}, -{0x3800,0x38ff, 1,1, 10,&z8002_device::Z38_imm8, "rsvd38", 0}, -{0x3910,0x39f0,16,1, 12,&z8002_device::Z39_ssN0_0000, "ldps @%rw2", 0}, -{0x3a00,0x3af0,16,2, 21,&z8002_device::Z3A_ssss_0000_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a01,0x3af1,16,2, 21,&z8002_device::Z3A_ssss_0001_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a02,0x3af2,16,2, 21,&z8002_device::Z3A_ssss_0010_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a03,0x3af3,16,2, 21,&z8002_device::Z3A_ssss_0011_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a04,0x3af4,16,2, 10,&z8002_device::Z3A_dddd_0100_imm16, "%R %rb2,%#w1", 0}, -{0x3a05,0x3af5,16,2, 10,&z8002_device::Z3A_dddd_0101_imm16, "%R %rb2,%#w1", 0}, -{0x3a06,0x3af6,16,2, 12,&z8002_device::Z3A_ssss_0110_imm16, "%R %#w1,%rb2", 0}, -{0x3a07,0x3af7,16,2, 12,&z8002_device::Z3A_ssss_0111_imm16, "%R %#w1,%rb2", 0}, -{0x3a08,0x3af8,16,2, 21,&z8002_device::Z3A_ssss_1000_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a09,0x3af9,16,2, 21,&z8002_device::Z3A_ssss_1001_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a0a,0x3afa,16,2, 21,&z8002_device::Z3A_ssss_1010_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3a0b,0x3afb,16,2, 21,&z8002_device::Z3A_ssss_1011_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b00,0x3bf0,16,2, 21,&z8002_device::Z3B_ssss_0000_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b01,0x3bf1,16,2, 21,&z8002_device::Z3B_ssss_0001_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b02,0x3bf2,16,2, 21,&z8002_device::Z3B_ssss_0010_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b03,0x3bf3,16,2, 21,&z8002_device::Z3B_ssss_0011_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b04,0x3bf4,16,2, 12,&z8002_device::Z3B_dddd_0100_imm16, "%R %rw2,%#w1", 0}, -{0x3b05,0x3bf5,16,2, 12,&z8002_device::Z3B_dddd_0101_imm16, "%R %rw2,%#w1", 0}, -{0x3b06,0x3bf6,16,2, 12,&z8002_device::Z3B_ssss_0110_imm16, "%R %#w1,%rw2", 0}, -{0x3b07,0x3bf7,16,2, 12,&z8002_device::Z3B_ssss_0111_imm16, "%R %#w1,%rw2", 0}, -{0x3b08,0x3bf8,16,2, 21,&z8002_device::Z3B_ssss_1000_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b09,0x3bf9,16,2, 21,&z8002_device::Z3B_ssss_1001_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rw5", 0}, -{0x3b0a,0x3bfa,16,2, 21,&z8002_device::Z3B_ssss_1010_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rb5", 0}, -{0x3b0b,0x3bfb,16,2, 21,&z8002_device::Z3B_ssss_1011_0000_aaaa_dddd_x000, "%R @%rw6,@%rw2,%rb5", 0}, -{0x3c00,0x3cff, 1,1, 10,&z8002_device::Z3C_ssss_dddd, "inb %rb3,@%rw2", 0}, -{0x3d00,0x3dff, 1,1, 10,&z8002_device::Z3D_ssss_dddd, "in %rw3,@%rw2", 0}, -{0x3e00,0x3eff, 1,1, 12,&z8002_device::Z3E_dddd_ssss, "outb @%rw2,%rb3", 0}, -{0x3f00,0x3fff, 1,1, 12,&z8002_device::Z3F_dddd_ssss, "out @%rw2,%rw3", 0}, -{0x4000,0x400f, 1,2, 9,&z8002_device::Z40_0000_dddd_addr, "addb %rb3,%a1", 0}, -{0x4010,0x40ff, 1,2, 10,&z8002_device::Z40_ssN0_dddd_addr, "addb %rb3,%a1(%rw2)", 0}, -{0x4100,0x410f, 1,2, 9,&z8002_device::Z41_0000_dddd_addr, "add %rw3,%a1", 0}, -{0x4110,0x41ff, 1,2, 10,&z8002_device::Z41_ssN0_dddd_addr, "add %rw3,%a1(%rw2)", 0}, -{0x4200,0x420f, 1,2, 9,&z8002_device::Z42_0000_dddd_addr, "subb %rb3,%a1", 0}, -{0x4210,0x42ff, 1,2, 10,&z8002_device::Z42_ssN0_dddd_addr, "subb %rb3,%a1(%rw2)", 0}, -{0x4300,0x430f, 1,2, 9,&z8002_device::Z43_0000_dddd_addr, "sub %rw3,%a1", 0}, -{0x4310,0x43ff, 1,2, 10,&z8002_device::Z43_ssN0_dddd_addr, "sub %rw3,%a1(%rw2)", 0}, -{0x4400,0x440f, 1,2, 9,&z8002_device::Z44_0000_dddd_addr, "orb %rb3,%a1", 0}, -{0x4410,0x44ff, 1,2, 10,&z8002_device::Z44_ssN0_dddd_addr, "orb %rb3,%a1(%rw2)", 0}, -{0x4500,0x450f, 1,2, 9,&z8002_device::Z45_0000_dddd_addr, "or %rw3,%a1", 0}, -{0x4510,0x45ff, 1,2, 10,&z8002_device::Z45_ssN0_dddd_addr, "or %rw3,%a1(%rw2)", 0}, -{0x4600,0x460f, 1,2, 9,&z8002_device::Z46_0000_dddd_addr, "andb %rb3,%a1", 0}, -{0x4610,0x46ff, 1,2, 10,&z8002_device::Z46_ssN0_dddd_addr, "andb %rb3,%a1(%rw2)", 0}, -{0x4700,0x470f, 1,2, 9,&z8002_device::Z47_0000_dddd_addr, "and %rw3,%a1", 0}, -{0x4710,0x47ff, 1,2, 10,&z8002_device::Z47_ssN0_dddd_addr, "and %rw3,%a1(%rw2)", 0}, -{0x4800,0x480f, 1,2, 9,&z8002_device::Z48_0000_dddd_addr, "xorb %rb3,%a1", 0}, -{0x4810,0x48ff, 1,2, 10,&z8002_device::Z48_ssN0_dddd_addr, "xorb %rb3,%a1(%rw2)", 0}, -{0x4900,0x490f, 1,2, 9,&z8002_device::Z49_0000_dddd_addr, "xor %rw3,%a1", 0}, -{0x4910,0x49ff, 1,2, 10,&z8002_device::Z49_ssN0_dddd_addr, "xor %rw3,%a1(%rw2)", 0}, -{0x4a00,0x4a0f, 1,2, 9,&z8002_device::Z4A_0000_dddd_addr, "cpb %rb3,%a1", 0}, -{0x4a10,0x4aff, 1,2, 10,&z8002_device::Z4A_ssN0_dddd_addr, "cpb %rb3,%a1(%rw2)", 0}, -{0x4b00,0x4b0f, 1,2, 9,&z8002_device::Z4B_0000_dddd_addr, "cp %rw3,%a1", 0}, -{0x4b10,0x4bff, 1,2, 10,&z8002_device::Z4B_ssN0_dddd_addr, "cp %rw3,%a1(%rw2)", 0}, -{0x4c00,0x4c00, 1,2, 15,&z8002_device::Z4C_0000_0000_addr, "comb %a1", 0}, -{0x4c01,0x4c01, 1,3, 14,&z8002_device::Z4C_0000_0001_addr_imm8, "cpb %a1,%#b3", 0}, -{0x4c02,0x4c02, 1,2, 15,&z8002_device::Z4C_0000_0010_addr, "negb %a1", 0}, -{0x4c04,0x4c04, 1,2, 11,&z8002_device::Z4C_0000_0100_addr, "testb %a1", 0}, -{0x4c05,0x4c05, 1,3, 14,&z8002_device::Z4C_0000_0101_addr_imm8, "ldb %a1,%#b3", 0}, -{0x4c06,0x4c06, 1,2, 14,&z8002_device::Z4C_0000_0110_addr, "tsetb %a1", 0}, -{0x4c08,0x4c08, 1,2, 11,&z8002_device::Z4C_0000_1000_addr, "clrb %a1", 0}, -{0x4c10,0x4cf0,16,2, 16,&z8002_device::Z4C_ddN0_0000_addr, "comb %a1(%rw2)", 0}, -{0x4c11,0x4cf1,16,3, 15,&z8002_device::Z4C_ddN0_0001_addr_imm8, "cpb %a1(%rw2),%#b3", 0}, -{0x4c12,0x4cf2,16,2, 16,&z8002_device::Z4C_ddN0_0010_addr, "negb %a1(%rw2)", 0}, -{0x4c14,0x4cf4,16,2, 12,&z8002_device::Z4C_ddN0_0100_addr, "testb %a1(%rw2)", 0}, -{0x4c15,0x4cf5,16,3, 15,&z8002_device::Z4C_ddN0_0101_addr_imm8, "ldb %a1(%rw2),%#b3", 0}, -{0x4c16,0x4cf6,16,2, 15,&z8002_device::Z4C_ddN0_0110_addr, "tsetb %a1(%rw2)", 0}, -{0x4c18,0x4cf8,16,2, 12,&z8002_device::Z4C_ddN0_1000_addr, "clrb %a1(%rw2)", 0}, -{0x4d00,0x4d00, 1,2, 15,&z8002_device::Z4D_0000_0000_addr, "com %a1", 0}, -{0x4d01,0x4d01, 1,3, 14,&z8002_device::Z4D_0000_0001_addr_imm16, "cp %a1,%#w2", 0}, -{0x4d02,0x4d02, 1,2, 15,&z8002_device::Z4D_0000_0010_addr, "neg %a1", 0}, -{0x4d04,0x4d04, 1,2, 11,&z8002_device::Z4D_0000_0100_addr, "test %a1", 0}, -{0x4d05,0x4d05, 1,3, 14,&z8002_device::Z4D_0000_0101_addr_imm16, "ld %a1,%#w2", 0}, -{0x4d06,0x4d06, 1,2, 14,&z8002_device::Z4D_0000_0110_addr, "tset %a1", 0}, -{0x4d08,0x4d08, 1,2, 11,&z8002_device::Z4D_0000_1000_addr, "clr %a1", 0}, -{0x4d10,0x4df0,16,2, 16,&z8002_device::Z4D_ddN0_0000_addr, "com %a1(%rw2)", 0}, -{0x4d11,0x4df1,16,3, 15,&z8002_device::Z4D_ddN0_0001_addr_imm16, "cp %a1(%rw2),%#w2", 0}, -{0x4d12,0x4df2,16,2, 16,&z8002_device::Z4D_ddN0_0010_addr, "neg %a1(%rw2)", 0}, -{0x4d14,0x4df4,16,2, 12,&z8002_device::Z4D_ddN0_0100_addr, "test %a1(%rw2)", 0}, -{0x4d15,0x4df5,16,3, 15,&z8002_device::Z4D_ddN0_0101_addr_imm16, "ld %a1(%rw2),%#w2", 0}, -{0x4d16,0x4df6,16,2, 15,&z8002_device::Z4D_ddN0_0110_addr, "tset %a1(%rw2)", 0}, -{0x4d18,0x4df8,16,2, 12,&z8002_device::Z4D_ddN0_1000_addr, "clr %a1(%rw2)", 0}, -{0x4e11,0x4ef0,16,2, 12,&z8002_device::Z4E_ddN0_ssN0_addr, "ldb %a1(%rw2),%rb3", 0}, -{0x5000,0x500f, 1,2, 15,&z8002_device::Z50_0000_dddd_addr, "cpl %rl3,%a1", 0}, -{0x5010,0x50ff, 1,2, 16,&z8002_device::Z50_ssN0_dddd_addr, "cpl %rl3,%a1(%rw2)", 0}, -{0x5110,0x51f0,16,2, 21,&z8002_device::Z51_ddN0_0000_addr, "pushl @%rw2,%a1", 0}, -{0x5111,0x51f1,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5112,0x51f2,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5113,0x51f3,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5114,0x51f4,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5115,0x51f5,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5116,0x51f6,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5117,0x51f7,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5118,0x51f8,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5119,0x51f9,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511a,0x51fa,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511b,0x51fb,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511c,0x51fc,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511d,0x51fd,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511e,0x51fe,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x511f,0x51ff,16,2, 21,&z8002_device::Z51_ddN0_ssN0_addr, "pushl @%rw2,%a1(%rw3)", 0}, -{0x5200,0x520f, 1,2, 15,&z8002_device::Z52_0000_dddd_addr, "subl %rl3,%a1", 0}, -{0x5210,0x52ff, 1,2, 16,&z8002_device::Z52_ssN0_dddd_addr, "subl %rl3,%a1(%rw2)", 0}, -{0x5310,0x53f0,16,2, 14,&z8002_device::Z53_ddN0_0000_addr, "push @%rw2,%a1", 0}, -{0x5311,0x53f1,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5312,0x53f2,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5313,0x53f3,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5314,0x53f4,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5315,0x53f5,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5316,0x53f6,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5317,0x53f7,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5318,0x53f8,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5319,0x53f9,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531a,0x53fa,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531b,0x53fb,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531c,0x53fc,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531d,0x53fd,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531e,0x53fe,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x531f,0x53ff,16,2, 14,&z8002_device::Z53_ddN0_ssN0_addr, "push @%rw2,%a1(%rw3)", 0}, -{0x5400,0x540f, 1,2, 12,&z8002_device::Z54_0000_dddd_addr, "ldl %rl3,%a1", 0}, -{0x5410,0x54ff, 1,2, 13,&z8002_device::Z54_ssN0_dddd_addr, "ldl %rl3,%a1(%rw2)", 0}, -{0x5510,0x55f0,16,2, 23,&z8002_device::Z55_ssN0_0000_addr, "popl %a1,@%rw2", 0}, -{0x5511,0x55f1,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5512,0x55f2,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5513,0x55f3,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5514,0x55f4,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5515,0x55f5,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5516,0x55f6,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5517,0x55f7,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5518,0x55f8,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5519,0x55f9,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551a,0x55fa,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551b,0x55fb,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551c,0x55fc,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551d,0x55fd,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551e,0x55fe,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x551f,0x55ff,16,2, 23,&z8002_device::Z55_ssN0_ddN0_addr, "popl %a1(%rw3),@%rw2", 0}, -{0x5600,0x560f, 1,2, 15,&z8002_device::Z56_0000_dddd_addr, "addl %rl3,%a1", 0}, -{0x5610,0x56ff, 1,2, 16,&z8002_device::Z56_ssN0_dddd_addr, "addl %rl3,%a1(%rw2)", 0}, -{0x5710,0x57f0,16,2, 16,&z8002_device::Z57_ssN0_0000_addr, "pop %a1,@%rw2", 0}, -{0x5711,0x57f1,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5712,0x57f2,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5713,0x57f3,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5714,0x57f4,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5715,0x57f5,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5716,0x57f6,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5717,0x57f7,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5718,0x57f8,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5719,0x57f9,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571a,0x57fa,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571b,0x57fb,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571c,0x57fc,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571d,0x57fd,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571e,0x57fe,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x571f,0x57ff,16,2, 16,&z8002_device::Z57_ssN0_ddN0_addr, "pop %a1(%rw3),@%rw2", 0}, -{0x5800,0x580f, 1,2,283,&z8002_device::Z58_0000_dddd_addr, "multl %rq3,%a1", 0}, -{0x5810,0x58ff, 1,2,284,&z8002_device::Z58_ssN0_dddd_addr, "multl %rq3,%a1(%rw2)", 0}, -{0x5900,0x590f, 1,2, 71,&z8002_device::Z59_0000_dddd_addr, "mult %rl3,%a1", 0}, -{0x5910,0x59ff, 1,2, 72,&z8002_device::Z59_ssN0_dddd_addr, "mult %rl3,%a1(%rw2)", 0}, -{0x5a00,0x5a0f, 1,2,745,&z8002_device::Z5A_0000_dddd_addr, "divl %rq3,%a1", 0}, -{0x5a10,0x5aff, 1,2,746,&z8002_device::Z5A_ssN0_dddd_addr, "divl %rq3,%a1(%rw2)", 0}, -{0x5b00,0x5b0f, 1,2,108,&z8002_device::Z5B_0000_dddd_addr, "div %rl3,%a1", 0}, -{0x5b10,0x5bff, 1,2,109,&z8002_device::Z5B_ssN0_dddd_addr, "div %rl3,%a1(%rw2)", 0}, -{0x5c01,0x5c01, 1,3, 14,&z8002_device::Z5C_0000_0001_0000_dddd_0000_nmin1_addr, "ldm %rw5,%a2,#%n", 0}, -{0x5c08,0x5c08, 1,2, 16,&z8002_device::Z5C_0000_1000_addr, "testl %a1", 0}, -{0x5c09,0x5c09, 1,3, 14,&z8002_device::Z5C_0000_1001_0000_ssss_0000_nmin1_addr, "ldm %a2,%rw5,#%n", 0}, -{0x5c11,0x5cf1,16,3, 15,&z8002_device::Z5C_ssN0_0001_0000_dddd_0000_nmin1_addr, "ldm %rw5,%a2(%rw2),#%n", 0}, -{0x5c18,0x5cf8,16,2, 17,&z8002_device::Z5C_ddN0_1000_addr, "testl %a1(%rw2)", 0}, -{0x5c19,0x5cf9,16,3, 15,&z8002_device::Z5C_ddN0_1001_0000_ssN0_0000_nmin1_addr, "ldm %a2(%rw2),%rw5,#%n", 0}, -{0x5d00,0x5d0f, 1,2, 15,&z8002_device::Z5D_0000_ssss_addr, "ldl %a1,%rl3", 0}, -{0x5d10,0x5dff, 1,2, 14,&z8002_device::Z5D_ddN0_ssss_addr, "ldl %a1(%rw2),%rl3", 0}, -{0x5e00,0x5e0f, 1,2, 7,&z8002_device::Z5E_0000_cccc_addr, "jp %c3,%a1", 0}, -{0x5e10,0x5eff, 1,2, 8,&z8002_device::Z5E_ddN0_cccc_addr, "jp %c3,%a1(%rw2)", 0}, -{0x5f00,0x5f00, 1,2, 12,&z8002_device::Z5F_0000_0000_addr, "call %a1", DASMFLAG_STEP_OVER}, -{0x5f10,0x5ff0,16,2, 13,&z8002_device::Z5F_ddN0_0000_addr, "call %a1(%rw2)", DASMFLAG_STEP_OVER}, -{0x6000,0x600f, 1,2, 9,&z8002_device::Z60_0000_dddd_addr, "ldb %rb3,%a1", 0}, -{0x6010,0x60ff, 1,2, 10,&z8002_device::Z60_ssN0_dddd_addr, "ldb %rb3,%a1(%rw2)", 0}, -{0x6100,0x610f, 1,2, 9,&z8002_device::Z61_0000_dddd_addr, "ld %rw3,%a1", 0}, -{0x6110,0x61ff, 1,2, 10,&z8002_device::Z61_ssN0_dddd_addr, "ld %rw3,%a1(%rw2)", 0}, -{0x6200,0x620f, 1,2, 13,&z8002_device::Z62_0000_imm4_addr, "resb %a1,%3", 0}, -{0x6210,0x62ff, 1,2, 14,&z8002_device::Z62_ddN0_imm4_addr, "resb %a1(%rw2),%3", 0}, -{0x6300,0x630f, 1,2, 13,&z8002_device::Z63_0000_imm4_addr, "res %a1,%3", 0}, -{0x6310,0x63ff, 1,2, 14,&z8002_device::Z63_ddN0_imm4_addr, "res %a1(%rw2),%3", 0}, -{0x6400,0x640f, 1,2, 13,&z8002_device::Z64_0000_imm4_addr, "setb %a1,%3", 0}, -{0x6410,0x64ff, 1,2, 14,&z8002_device::Z64_ddN0_imm4_addr, "setb %a1(%rw2),%3", 0}, -{0x6500,0x650f, 1,2, 13,&z8002_device::Z65_0000_imm4_addr, "set %a1,%3", 0}, -{0x6510,0x65ff, 1,2, 14,&z8002_device::Z65_ddN0_imm4_addr, "set %a1(%rw2),%3", 0}, -{0x6600,0x660f, 1,2, 10,&z8002_device::Z66_0000_imm4_addr, "bitb %a1,%3", 0}, -{0x6610,0x66ff, 1,2, 11,&z8002_device::Z66_ddN0_imm4_addr, "bitb %a1(%rw2),%3", 0}, -{0x6700,0x670f, 1,2, 10,&z8002_device::Z67_0000_imm4_addr, "bit %a1,%3", 0}, -{0x6710,0x67ff, 1,2, 11,&z8002_device::Z67_ddN0_imm4_addr, "bit %a1(%rw2),%3", 0}, -{0x6800,0x680f, 1,2, 13,&z8002_device::Z68_0000_imm4m1_addr, "incb %a1,%+3", 0}, -{0x6810,0x68ff, 1,2, 14,&z8002_device::Z68_ddN0_imm4m1_addr, "incb %a1(%rw2),%+3", 0}, -{0x6900,0x690f, 1,2, 13,&z8002_device::Z69_0000_imm4m1_addr, "inc %a1,%+3", 0}, -{0x6910,0x69ff, 1,2, 14,&z8002_device::Z69_ddN0_imm4m1_addr, "inc %a1(%rw2),%+3", 0}, -{0x6a00,0x6a0f, 1,2, 13,&z8002_device::Z6A_0000_imm4m1_addr, "decb %a1,%+3", 0}, -{0x6a10,0x6aff, 1,2, 14,&z8002_device::Z6A_ddN0_imm4m1_addr, "decb %a1(%rw2),%+3", 0}, -{0x6b00,0x6b0f, 1,2, 13,&z8002_device::Z6B_0000_imm4m1_addr, "dec %a1,%+3", 0}, -{0x6b10,0x6bff, 1,2, 14,&z8002_device::Z6B_ddN0_imm4m1_addr, "dec %a1(%rw2),%+3", 0}, -{0x6c00,0x6c0f, 1,2, 15,&z8002_device::Z6C_0000_dddd_addr, "exb %rb3,%a1", 0}, -{0x6c10,0x6cff, 1,2, 16,&z8002_device::Z6C_ssN0_dddd_addr, "exb %rb3,%a1(%rw2)", 0}, -{0x6d00,0x6d0f, 1,2, 15,&z8002_device::Z6D_0000_dddd_addr, "ex %rw3,%a1", 0}, -{0x6d10,0x6dff, 1,2, 16,&z8002_device::Z6D_ssN0_dddd_addr, "ex %rw3,%a1(%rw2)", 0}, -{0x6e00,0x6e0f, 1,2, 11,&z8002_device::Z6E_0000_ssss_addr, "ldb %a1,%rb3", 0}, -{0x6e10,0x6eff, 1,2, 11,&z8002_device::Z6E_ddN0_ssss_addr, "ldb %a1(%rw2),%rb3", 0}, -{0x6f00,0x6f0f, 1,2, 11,&z8002_device::Z6F_0000_ssss_addr, "ld %a1,%rw3", 0}, -{0x6f10,0x6fff, 1,2, 12,&z8002_device::Z6F_ddN0_ssss_addr, "ld %a1(%rw2),%rw3", 0}, -{0x7010,0x70ff, 1,2, 14,&z8002_device::Z70_ssN0_dddd_0000_xxxx_0000_0000, "ldb %rb3,%rw2(%rw5)", 0}, -{0x7110,0x71ff, 1,2, 14,&z8002_device::Z71_ssN0_dddd_0000_xxxx_0000_0000, "ld %rw3,%rw2(%rw5)", 0}, -{0x7210,0x72ff, 1,2, 14,&z8002_device::Z72_ddN0_ssss_0000_xxxx_0000_0000, "ldb %rw2(%rw5),%rb3", 0}, -{0x7310,0x73ff, 1,2, 14,&z8002_device::Z73_ddN0_ssss_0000_xxxx_0000_0000, "ld %rw2(%rw5),%rw3", 0}, -{0x7410,0x74ff, 1,2, 15,&z8002_device::Z74_ssN0_dddd_0000_xxxx_0000_0000, "lda p%rw3,%rw2(%rw5)", 0}, -{0x7510,0x75ff, 1,2, 17,&z8002_device::Z75_ssN0_dddd_0000_xxxx_0000_0000, "ldl %rl3,%rw2(%rw5)", 0}, -{0x7600,0x760f, 1,2, 12,&z8002_device::Z76_0000_dddd_addr, "lda p%rw3,%a1", 0}, -{0x7610,0x76ff, 1,2, 13,&z8002_device::Z76_ssN0_dddd_addr, "lda p%rw3,%a1(%rw2)", 0}, -{0x7710,0x77ff, 1,2, 17,&z8002_device::Z77_ddN0_ssss_0000_xxxx_0000_0000, "ldl %rw2(%rw5),%rl3", 0}, -{0x7800,0x78ff, 1,1, 10,&z8002_device::Z78_imm8, "rsvd78", 0}, -{0x7900,0x7900, 1,2, 16,&z8002_device::Z79_0000_0000_addr, "ldps %a1", 0}, -{0x7910,0x79f0,16,2, 17,&z8002_device::Z79_ssN0_0000_addr, "ldps %a1(%rw2)", 0}, -{0x7a00,0x7a00, 1,1, 8,&z8002_device::Z7A_0000_0000, "halt", DASMFLAG_STEP_OVER}, -{0x7b00,0x7b00, 1,1, 13,&z8002_device::Z7B_0000_0000, "iret", DASMFLAG_STEP_OUT}, -{0x7b08,0x7b08, 1,1, 5,&z8002_device::Z7B_0000_1000, "mset", 0}, -{0x7b09,0x7b09, 1,1, 5,&z8002_device::Z7B_0000_1001, "mres", 0}, -{0x7b0a,0x7b0a, 1,1, 7,&z8002_device::Z7B_0000_1010, "mbit", 0}, -{0x7b0d,0x7bfd,16,1, 12,&z8002_device::Z7B_dddd_1101, "mreq %rw2", 0}, -{0x7c00,0x7c03, 1,1, 7,&z8002_device::Z7C_0000_00ii, "di %i3", 0}, -{0x7c04,0x7c07, 1,1, 7,&z8002_device::Z7C_0000_01ii, "ei %i3", 0}, -{0x7d00,0x7df0,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,ctrl0", 0}, -{0x7d01,0x7df1,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,ctrl1", 0}, -{0x7d02,0x7df2,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,fcw", 0}, -{0x7d03,0x7df3,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,refresh", 0}, -{0x7d04,0x7df4,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,psapseg", 0}, -{0x7d05,0x7df5,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,psapoff", 0}, -{0x7d06,0x7df6,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,nspseg", 0}, -{0x7d07,0x7df7,16,1, 7,&z8002_device::Z7D_dddd_0ccc, "ldctl %rw2,nspoff", 0}, -{0x7d08,0x7df8,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl ctrl0,%rw2", 0}, -{0x7d09,0x7df9,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl ctrl1,%rw2", 0}, -{0x7d0a,0x7dfa,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl fcw,%rw2", 0}, -{0x7d0b,0x7dfb,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl refresh,%rw2", 0}, -{0x7d0c,0x7dfc,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl psapseg,%rw2", 0}, -{0x7d0d,0x7dfd,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl psapoff,%rw2", 0}, -{0x7d0e,0x7dfe,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl nspseg,%rw2", 0}, -{0x7d0f,0x7dff,16,1, 7,&z8002_device::Z7D_ssss_1ccc, "ldctl nspoff,%rw2", 0}, -{0x7e00,0x7eff, 1,1, 10,&z8002_device::Z7E_imm8, "rsvd7e %#b1", 0}, -{0x7f00,0x7fff, 1,1, 33,&z8002_device::Z7F_imm8, "sc %#b1", DASMFLAG_STEP_OVER}, -{0x8000,0x80ff, 1,1, 4,&z8002_device::Z80_ssss_dddd, "addb %rb3,%rb2", 0}, -{0x8100,0x81ff, 1,1, 4,&z8002_device::Z81_ssss_dddd, "add %rw3,%rw2", 0}, -{0x8200,0x82ff, 1,1, 4,&z8002_device::Z82_ssss_dddd, "subb %rb3,%rb2", 0}, -{0x8300,0x83ff, 1,1, 4,&z8002_device::Z83_ssss_dddd, "sub %rw3,%rw2", 0}, -{0x8400,0x84ff, 1,1, 4,&z8002_device::Z84_ssss_dddd, "orb %rb3,%rb2", 0}, -{0x8500,0x85ff, 1,1, 4,&z8002_device::Z85_ssss_dddd, "or %rw3,%rw2", 0}, -{0x8600,0x86ff, 1,1, 4,&z8002_device::Z86_ssss_dddd, "andb %rb3,%rb2", 0}, -{0x8700,0x87ff, 1,1, 4,&z8002_device::Z87_ssss_dddd, "and %rw3,%rw2", 0}, -{0x8800,0x88ff, 1,1, 4,&z8002_device::Z88_ssss_dddd, "xorb %rb3,%rb2", 0}, -{0x8900,0x89ff, 1,1, 4,&z8002_device::Z89_ssss_dddd, "xor %rw3,%rw2", 0}, -{0x8a00,0x8aff, 1,1, 4,&z8002_device::Z8A_ssss_dddd, "cpb %rb3,%rb2", 0}, -{0x8b00,0x8bff, 1,1, 4,&z8002_device::Z8B_ssss_dddd, "cp %rw3,%rw2", 0}, -{0x8c00,0x8cf0,16,1, 7,&z8002_device::Z8C_dddd_0000, "comb %rb2", 0}, -{0x8c02,0x8cf2,16,1, 7,&z8002_device::Z8C_dddd_0010, "negb %rb2", 0}, -{0x8c04,0x8cf4,16,1, 7,&z8002_device::Z8C_dddd_0100, "testb %rb2", 0}, -{0x8c06,0x8cf6,16,1, 7,&z8002_device::Z8C_dddd_0110, "tsetb %rb2", 0}, -{0x8c01,0x8cf1,16,1, 7,&z8002_device::Z8C_dddd_0001, "ldctlb %rb2,flags", 0}, -{0x8c08,0x8cf8,16,1, 7,&z8002_device::Z8C_dddd_1000, "clrb %rb2", 0}, -{0x8c09,0x8cf9,16,1, 7,&z8002_device::Z8C_dddd_1001, "ldctlb flags,%rb2", 0}, -{0x8d00,0x8df0,16,1, 7,&z8002_device::Z8D_dddd_0000, "com %rw2", 0}, -{0x8d01,0x8df1,16,1, 7,&z8002_device::Z8D_imm4_0001, "setflg %f2", 0}, -{0x8d02,0x8df2,16,1, 7,&z8002_device::Z8D_dddd_0010, "neg %rw2", 0}, -{0x8d03,0x8df3,16,1, 7,&z8002_device::Z8D_imm4_0011, "resflg %f2", 0}, -{0x8d04,0x8df4,16,1, 7,&z8002_device::Z8D_dddd_0100, "test %rw2", 0}, -{0x8d05,0x8df5,16,1, 7,&z8002_device::Z8D_imm4_0101, "comflg %f2", 0}, -{0x8d06,0x8df6,16,1, 7,&z8002_device::Z8D_dddd_0110, "tset %rw2", 0}, -{0x8d07,0x8d07, 1,1, 7,&z8002_device::Z8D_0000_0111, "nop", 0}, -{0x8d08,0x8df8,16,1, 7,&z8002_device::Z8D_dddd_1000, "clr %rw2", 0}, -{0x8e00,0x8eff, 1,1, 10,&z8002_device::Z8E_imm8, "ext8e %#b1", 0}, -{0x8f00,0x8fff, 1,1, 10,&z8002_device::Z8F_imm8, "ext8f %#b1", 0}, -{0x9000,0x90ff, 1,1, 8,&z8002_device::Z90_ssss_dddd, "cpl %rl3,%rl2", 0}, -{0x9110,0x91ff, 1,1, 12,&z8002_device::Z91_ddN0_ssss, "pushl @%rw2,%rl3", 0}, -{0x9200,0x92ff, 1,1, 8,&z8002_device::Z92_ssss_dddd, "subl %rl3,%rl2", 0}, -{0x9310,0x93ff, 1,1, 9,&z8002_device::Z93_ddN0_ssss, "push @%rw2,%rw3", 0}, -{0x9400,0x94ff, 1,1, 5,&z8002_device::Z94_ssss_dddd, "ldl %rl3,%rl2", 0}, -{0x9510,0x95ff, 1,1, 12,&z8002_device::Z95_ssN0_dddd, "popl %rl3,@%rw2", 0}, -{0x9600,0x96ff, 1,1, 8,&z8002_device::Z96_ssss_dddd, "addl %rl3,%rl2", 0}, -{0x9710,0x97ff, 1,1, 8,&z8002_device::Z97_ssN0_dddd, "pop %rw3,@%rw2", 0}, -{0x9800,0x98ff, 1,1,282,&z8002_device::Z98_ssss_dddd, "multl %rq3,%rl2", 0}, -{0x9900,0x99ff, 1,1, 70,&z8002_device::Z99_ssss_dddd, "mult %rl3,%rw2", 0}, -{0x9a00,0x9aff, 1,1,744,&z8002_device::Z9A_ssss_dddd, "divl %rq3,%rl2", 0}, -{0x9b00,0x9bff, 1,1,107,&z8002_device::Z9B_ssss_dddd, "div %rl3,%rw2", 0}, -{0x9c00,0x9cf8, 8,1, 13,&z8002_device::Z9C_dddd_1000, "testl %rl2", 0}, -{0x9d00,0x9dff, 1,1, 10,&z8002_device::Z9D_imm8, "rsvd9d", 0}, -{0x9e00,0x9e0f, 1,1, 10,&z8002_device::Z9E_0000_cccc, "ret %c3", DASMFLAG_STEP_OUT}, -{0x9f00,0x9fff, 1,1, 10,&z8002_device::Z9F_imm8, "rsvd9f", 0}, -{0xa000,0xa0ff, 1,1, 3,&z8002_device::ZA0_ssss_dddd, "ldb %rb3,%rb2", 0}, -{0xa100,0xa1ff, 1,1, 3,&z8002_device::ZA1_ssss_dddd, "ld %rw3,%rw2", 0}, -{0xa200,0xa2ff, 1,1, 4,&z8002_device::ZA2_dddd_imm4, "resb %rb2,%3", 0}, -{0xa300,0xa3ff, 1,1, 4,&z8002_device::ZA3_dddd_imm4, "res %rw2,%3", 0}, -{0xa400,0xa4ff, 1,1, 4,&z8002_device::ZA4_dddd_imm4, "setb %rb2,%3", 0}, -{0xa500,0xa5ff, 1,1, 4,&z8002_device::ZA5_dddd_imm4, "set %rw2,%3", 0}, -{0xa600,0xa6ff, 1,1, 4,&z8002_device::ZA6_dddd_imm4, "bitb %rb2,%3", 0}, -{0xa700,0xa7ff, 1,1, 4,&z8002_device::ZA7_dddd_imm4, "bit %rw2,%3", 0}, -{0xa800,0xa8ff, 1,1, 4,&z8002_device::ZA8_dddd_imm4m1, "incb %rb2,%+3", 0}, -{0xa900,0xa9ff, 1,1, 4,&z8002_device::ZA9_dddd_imm4m1, "inc %rw2,%+3", 0}, -{0xaa00,0xaaff, 1,1, 4,&z8002_device::ZAA_dddd_imm4m1, "decb %rb2,%+3", 0}, -{0xab00,0xabff, 1,1, 4,&z8002_device::ZAB_dddd_imm4m1, "dec %rw2,%+3", 0}, -{0xac00,0xacff, 1,1, 6,&z8002_device::ZAC_ssss_dddd, "exb %rb3,%rb2", 0}, -{0xad00,0xadff, 1,1, 6,&z8002_device::ZAD_ssss_dddd, "ex %rw3,%rw2", 0}, -{0xae00,0xaeff, 1,1, 5,&z8002_device::ZAE_dddd_cccc, "tccb %c3,%rb2", 0}, -{0xaf00,0xafff, 1,1, 5,&z8002_device::ZAF_dddd_cccc, "tcc %c3,%rw2", 0}, -{0xb000,0xb0f0,16,1, 5,&z8002_device::ZB0_dddd_0000, "dab %rb2", 0}, -{0xb100,0xb1f0,16,1, 11,&z8002_device::ZB1_dddd_0000, "extsb %rw2", 0}, -{0xb107,0xb1f7,16,1, 11,&z8002_device::ZB1_dddd_0111, "extsl %rq2", 0}, -{0xb10a,0xb1fa,16,1, 11,&z8002_device::ZB1_dddd_1010, "exts %rl2", 0}, -{0xb200,0xb2f0,16,1, 6,&z8002_device::ZB2_dddd_00I0, "rlb %rb2,%?3", 0}, -{0xb201,0xb2f1,16,2, 13,&z8002_device::ZB2_dddd_0001_imm8, "s%*lb %rb2,%$3", 0}, -{0xb202,0xb2f2,16,1, 6,&z8002_device::ZB2_dddd_00I0, "rlb %rb2,%?3", 0}, -{0xb203,0xb2f3,16,2, 15,&z8002_device::ZB2_dddd_0011_0000_ssss_0000_0000, "sdlb %rb2,%rw5", 0}, -{0xb204,0xb2f4,16,1, 6,&z8002_device::ZB2_dddd_01I0, "rrb %rb2,%?3", 0}, -{0xb206,0xb2f6,16,1, 6,&z8002_device::ZB2_dddd_01I0, "rrb %rb2,%?3", 0}, -{0xb208,0xb2f8,16,1, 9,&z8002_device::ZB2_dddd_10I0, "rlcb %rb2,%?3", 0}, -{0xb209,0xb2f9,16,2, 13,&z8002_device::ZB2_dddd_1001_imm8, "s%*ab %rb2,%$3", 0}, -{0xb20a,0xb2fa,16,1, 9,&z8002_device::ZB2_dddd_10I0, "rlcb %rb2,%?3", 0}, -{0xb20b,0xb2fb,16,2, 15,&z8002_device::ZB2_dddd_1011_0000_ssss_0000_0000, "sdab %rb2,%rw5", 0}, -{0xb20c,0xb2fc,16,1, 9,&z8002_device::ZB2_dddd_11I0, "rrcb %rb2,%?3", 0}, -{0xb20e,0xb2fe,16,1, 9,&z8002_device::ZB2_dddd_11I0, "rrcb %rb2,%?3", 0}, -{0xb300,0xb3f0,16,1, 6,&z8002_device::ZB3_dddd_00I0, "rl %rw2,%?3", 0}, -{0xb301,0xb3f1,16,2, 13,&z8002_device::ZB3_dddd_0001_imm8, "s%*l %rw2,%$3", 0}, -{0xb302,0xb3f2,16,1, 6,&z8002_device::ZB3_dddd_00I0, "rl %rw2,%?3", 0}, -{0xb303,0xb3f3,16,2, 15,&z8002_device::ZB3_dddd_0011_0000_ssss_0000_0000, "sdl %rw2,%rw5", 0}, -{0xb304,0xb3f4,16,1, 6,&z8002_device::ZB3_dddd_01I0, "rr %rw2,%?3", 0}, -{0xb305,0xb3f5,16,2, 13,&z8002_device::ZB3_dddd_0101_imm8, "s%*ll %rl2,%$3", 0}, -{0xb306,0xb3f6,16,1, 6,&z8002_device::ZB3_dddd_01I0, "rr %rw2,%?3", 0}, -{0xb307,0xb3f7,16,2, 15,&z8002_device::ZB3_dddd_0111_0000_ssss_0000_0000, "sdll %rl2,%rw5", 0}, -{0xb308,0xb3f8,16,1, 6,&z8002_device::ZB3_dddd_10I0, "rlc %rw2,%?3", 0}, -{0xb309,0xb3f9,16,2, 13,&z8002_device::ZB3_dddd_1001_imm8, "s%*a %rw2,%$3", 0}, -{0xb30a,0xb3fa,16,1, 6,&z8002_device::ZB3_dddd_10I0, "rlc %rw2,%?3", 0}, -{0xb30b,0xb3fb,16,2, 15,&z8002_device::ZB3_dddd_1011_0000_ssss_0000_0000, "sda %rw2,%rw5", 0}, -{0xb30c,0xb3fc,16,1, 6,&z8002_device::ZB3_dddd_11I0, "rrc %rw2,%?3", 0}, -{0xb30d,0xb3fd,16,2, 13,&z8002_device::ZB3_dddd_1101_imm8, "s%*al %rl2,%$3", 0}, -{0xb30e,0xb3fe,16,1, 6,&z8002_device::ZB3_dddd_11I0, "rrc %rw2,%?3", 0}, -{0xb30f,0xb3ff,16,2, 15,&z8002_device::ZB3_dddd_1111_0000_ssss_0000_0000, "sdal %rl2,%rw5", 0}, -{0xb400,0xb4ff, 1,1, 5,&z8002_device::ZB4_ssss_dddd, "adcb %rb3,%rb2", 0}, -{0xb500,0xb5ff, 1,1, 5,&z8002_device::ZB5_ssss_dddd, "adc %rw3,%rw2", 0}, -{0xb600,0xb6ff, 1,1, 5,&z8002_device::ZB6_ssss_dddd, "sbcb %rb3,%rb2", 0}, -{0xb700,0xb7ff, 1,1, 5,&z8002_device::ZB7_ssss_dddd, "sbc %rw3,%rw2", 0}, -{0xb810,0xb8f0,16,2, 25,&z8002_device::ZB8_ddN0_0000_0000_rrrr_ssN0_0000, "trib @%rw2,@%rw6,%rb5", 0}, -{0xb812,0xb8f2,16,2, 25,&z8002_device::ZB8_ddN0_0010_0000_rrrr_ssN0_0000, "trtib @%rw2,@%rw6,%rb5", 0}, -{0xb814,0xb8f4,16,2, 25,&z8002_device::ZB8_ddN0_0100_0000_rrrr_ssN0_0000, "trirb @%rw2,@%rw6,%rb5", 0}, -{0xb816,0xb8f6,16,2, 25,&z8002_device::ZB8_ddN0_0110_0000_rrrr_ssN0_1110, "trtirb @%rw2,@%rw6,%rb5", 0}, -{0xb818,0xb8f8,16,2, 25,&z8002_device::ZB8_ddN0_1000_0000_rrrr_ssN0_0000, "trdb @%rw2,@%rw6,%rb5", 0}, -{0xb81a,0xb8fa,16,2, 25,&z8002_device::ZB8_ddN0_1010_0000_rrrr_ssN0_0000, "trtrb @%rw2,@%rw6,%rb5", 0}, -{0xb81c,0xb8fc,16,2, 25,&z8002_device::ZB8_ddN0_1100_0000_rrrr_ssN0_0000, "trdrb @%rw2,@%rw6,%rb5", 0}, -{0xb81e,0xb8fe,16,2, 25,&z8002_device::ZB8_ddN0_1110_0000_rrrr_ssN0_1110, "trtdrb @%rw2,@%rw6,%rb5", 0}, -{0xb900,0xb9ff,16,1, 10,&z8002_device::ZB9_imm8, "rsvdb9", 0}, -{0xba10,0xbaf0,16,2, 11,&z8002_device::ZBA_ssN0_0000_0000_rrrr_dddd_cccc, "cpib %rb6,@%rw2,%rw5,%c7", 0}, -{0xba11,0xbaf1,16,2, 11,&z8002_device::ZBA_ssN0_0001_0000_rrrr_ddN0_x000, "ldirb @%rw6,@%rw2,%rw5", DASMFLAG_STEP_OVER}, -{0xba12,0xbaf2,16,2, 11,&z8002_device::ZBA_ssN0_0010_0000_rrrr_ddN0_cccc, "cpsib @%rw6,@%rw2,%rw5,%c7", 0}, -{0xba14,0xbaf4,16,2, 11,&z8002_device::ZBA_ssN0_0100_0000_rrrr_dddd_cccc, "cpirb %rb6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xba16,0xbaf6,16,2, 11,&z8002_device::ZBA_ssN0_0110_0000_rrrr_ddN0_cccc, "cpsirb @%rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xba18,0xbaf8,16,2, 11,&z8002_device::ZBA_ssN0_1000_0000_rrrr_dddd_cccc, "cpdb %rb6,@%rw2,%rw5,%c7", 0}, -{0xba19,0xbaf9,16,2, 11,&z8002_device::ZBA_ssN0_1001_0000_rrrr_ddN0_x000, "lddrb @%rw2,@%rw6,%rw5", DASMFLAG_STEP_OVER}, -{0xba1a,0xbafa,16,2, 11,&z8002_device::ZBA_ssN0_1010_0000_rrrr_ddN0_cccc, "cpsdb @%rw6,@%rw2,%rw5,%c7", 0}, -{0xba1c,0xbafc,16,2, 11,&z8002_device::ZBA_ssN0_1100_0000_rrrr_dddd_cccc, "cpdrb %rb6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xba1e,0xbafe,16,2, 11,&z8002_device::ZBA_ssN0_1110_0000_rrrr_ddN0_cccc, "cpsdrb @%rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbb10,0xbbf0,16,2, 11,&z8002_device::ZBB_ssN0_0000_0000_rrrr_dddd_cccc, "cpi %rw6,@%rw2,%rw5,%c7", 0}, -{0xbb11,0xbbf1,16,2, 11,&z8002_device::ZBB_ssN0_0001_0000_rrrr_ddN0_x000, "ldir @%rw6,@%rw2,%rw5", DASMFLAG_STEP_OVER}, -{0xbb12,0xbbf2,16,2, 11,&z8002_device::ZBB_ssN0_0010_0000_rrrr_ddN0_cccc, "cpsi @%rw6,@%rw2,%rw5,%c7", 0}, -{0xbb14,0xbbf4,16,2, 11,&z8002_device::ZBB_ssN0_0100_0000_rrrr_dddd_cccc, "cpir %rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbb16,0xbbf6,16,2, 11,&z8002_device::ZBB_ssN0_0110_0000_rrrr_ddN0_cccc, "cpsir @%rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbb18,0xbbf8,16,2, 11,&z8002_device::ZBB_ssN0_1000_0000_rrrr_dddd_cccc, "cpd %rw6,@%rw2,%rw5,%c7", 0}, -{0xbb19,0xbbf9,16,2, 11,&z8002_device::ZBB_ssN0_1001_0000_rrrr_ddN0_x000, "lddr @%rw2,@%rw6,%rw5", DASMFLAG_STEP_OVER}, -{0xbb1a,0xbbfa,16,2, 11,&z8002_device::ZBB_ssN0_1010_0000_rrrr_ddN0_cccc, "cpsd @%rw6,@%rw2,%rw5,%c7", 0}, -{0xbb1c,0xbbfc,16,2, 11,&z8002_device::ZBB_ssN0_1100_0000_rrrr_dddd_cccc, "cpdr %rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbb1e,0xbbfe,16,2, 11,&z8002_device::ZBB_ssN0_1110_0000_rrrr_ddN0_cccc, "cpsdr @%rw6,@%rw2,%rw5,%c7", DASMFLAG_STEP_OVER}, -{0xbc00,0xbcff, 1,1, 9,&z8002_device::ZBC_aaaa_bbbb, "rrdb %rb3,%rb2", 0}, -{0xbd00,0xbdff, 1,1, 5,&z8002_device::ZBD_dddd_imm4, "ldk %rw2,%3", 0}, -{0xbe00,0xbeff, 1,1, 9,&z8002_device::ZBE_aaaa_bbbb, "rldb %rb3,%rb2", 0}, -{0xbf00,0xbfff, 1,1, 10,&z8002_device::ZBF_imm8, "rsvdbf", 0}, -{0xc000,0xcfff, 1,1, 5,&z8002_device::ZC_dddd_imm8, "ldb %rb1,%#b1", 0}, -{0xd000,0xdfff, 1,1, 10,&z8002_device::ZD_dsp12, "calr %d2", DASMFLAG_STEP_OVER}, -{0xe000,0xefff, 1,1, 6,&z8002_device::ZE_cccc_dsp8, "jr %c1,%d1", 0}, -{0xf000,0xf07f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf100,0xf17f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf200,0xf27f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf300,0xf37f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf400,0xf47f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf500,0xf57f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf600,0xf67f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf700,0xf77f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf800,0xf87f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf900,0xf97f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfa00,0xfa7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfb00,0xfb7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfc00,0xfc7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfd00,0xfd7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xfe00,0xfe7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xff00,0xff7f, 1,1, 11,&z8002_device::ZF_dddd_0dsp7, "dbjnz %rb1,%d0", DASMFLAG_STEP_OVER}, -{0xf080,0xf0ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf180,0xf1ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf280,0xf2ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf380,0xf3ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf480,0xf4ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf580,0xf5ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf680,0xf6ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf780,0xf7ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf880,0xf8ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xf980,0xf9ff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfa80,0xfaff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfb80,0xfbff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfc80,0xfcff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfd80,0xfdff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xfe80,0xfeff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0xff80,0xffff, 1,1, 11,&z8002_device::ZF_dddd_1dsp7, "djnz %rw1,%d0", DASMFLAG_STEP_OVER}, -{0, 0, 0,0, 0,nullptr, nullptr, 0} -}; - - -void z8002_device::init_tables() -{ - /* already initialized? */ - if (z8000_exec) - return; - - const Z8000_init *init; - int i; - - /* allocate the opcode execution and disassembler array */ - std::unique_ptr<Z8000_exec []> exec(new Z8000_exec[0x10000]); - - /* set up the zero, sign, parity lookup table */ - for (i = 0; i < 256; i++) - z8000_zsp[i] = ((i == 0) ? F_Z : 0) | - ((i & 128) ? F_S : 0) | - ((((i>>7)^(i>>6)^(i>>5)^(i>>4)^(i>>3)^(i>>2)^(i>>1)^i) & 1) ? 0 : F_PV); + { 0x0000, 0xffff, 1, 1, 4, &z8002_device::zinvalid }, - /* first set all 64K opcodes to invalid */ - for (i = 0; i < 0x10000; i++) - { - exec[i].opcode = &z8002_device::zinvalid; - exec[i].cycles = 4; - exec[i].size = 1; - exec[i].dasm = ".word %#w0"; - exec[i].dasmflags = 0; - } - - /* now decompose the initialization table */ - for (init = table; init->size; init++) - { - for (i = init->beg; i <= init->end; i += init->step) - { - if (exec[i].opcode != &z8002_device::zinvalid) - osd_printf_error("Z8000 opcode %04x clash '%s'\n", i, exec[i].dasm); - - exec[i].opcode = init->opcode; - exec[i].cycles = init->cycles; - exec[i].size = init->size; - exec[i].dasm = init->dasm; - exec[i].dasmflags = init->dasmflags; - } - } - - z8000_exec = std::move(exec); -} - -void z8002_device::deinit_tables() -{ - z8000_exec = nullptr; -} - -z8002_device::Z8000_dasm z8002_device::dasm(unsigned w) -{ - init_tables(); - Z8000_exec const &exec(z8000_exec[w]); - return Z8000_dasm{ exec.dasm, exec.dasmflags, exec.size }; -} + { 0x0000, 0x000f, 1, 2, 7, &z8002_device::Z00_0000_dddd_imm8 }, + { 0x0010, 0x00ff, 1, 1, 7, &z8002_device::Z00_ssN0_dddd }, + { 0x0100, 0x010f, 1, 2, 7, &z8002_device::Z01_0000_dddd_imm16 }, + { 0x0110, 0x01ff, 1, 1, 7, &z8002_device::Z01_ssN0_dddd }, + { 0x0200, 0x020f, 1, 2, 7, &z8002_device::Z02_0000_dddd_imm8 }, + { 0x0210, 0x02ff, 1, 1, 7, &z8002_device::Z02_ssN0_dddd }, + { 0x0300, 0x030f, 1, 2, 7, &z8002_device::Z03_0000_dddd_imm16 }, + { 0x0310, 0x03ff, 1, 1, 7, &z8002_device::Z03_ssN0_dddd }, + { 0x0400, 0x040f, 1, 2, 7, &z8002_device::Z04_0000_dddd_imm8 }, + { 0x0410, 0x04ff, 1, 1, 7, &z8002_device::Z04_ssN0_dddd }, + { 0x0500, 0x050f, 1, 2, 7, &z8002_device::Z05_0000_dddd_imm16 }, + { 0x0510, 0x05ff, 1, 1, 7, &z8002_device::Z05_ssN0_dddd }, + { 0x0600, 0x060f, 1, 2, 7, &z8002_device::Z06_0000_dddd_imm8 }, + { 0x0610, 0x06ff, 1, 1, 7, &z8002_device::Z06_ssN0_dddd }, + { 0x0700, 0x070f, 1, 2, 7, &z8002_device::Z07_0000_dddd_imm16 }, + { 0x0710, 0x07ff, 1, 1, 7, &z8002_device::Z07_ssN0_dddd }, + { 0x0800, 0x080f, 1, 2, 7, &z8002_device::Z08_0000_dddd_imm8 }, + { 0x0810, 0x08ff, 1, 1, 7, &z8002_device::Z08_ssN0_dddd }, + { 0x0900, 0x090f, 1, 2, 7, &z8002_device::Z09_0000_dddd_imm16 }, + { 0x0910, 0x09ff, 1, 1, 7, &z8002_device::Z09_ssN0_dddd }, + { 0x0a00, 0x0a0f, 1, 2, 7, &z8002_device::Z0A_0000_dddd_imm8 }, + { 0x0a10, 0x0aff, 1, 1, 7, &z8002_device::Z0A_ssN0_dddd }, + { 0x0b00, 0x0b0f, 1, 2, 7, &z8002_device::Z0B_0000_dddd_imm16 }, + { 0x0b10, 0x0bff, 1, 1, 7, &z8002_device::Z0B_ssN0_dddd }, + { 0x0c10, 0x0cf0, 16, 1, 12, &z8002_device::Z0C_ddN0_0000 }, + { 0x0c11, 0x0cf1, 16, 2, 11, &z8002_device::Z0C_ddN0_0001_imm8 }, + { 0x0c12, 0x0cf2, 16, 1, 12, &z8002_device::Z0C_ddN0_0010 }, + { 0x0c14, 0x0cf4, 16, 1, 8, &z8002_device::Z0C_ddN0_0100 }, + { 0x0c15, 0x0cf5, 16, 2, 7, &z8002_device::Z0C_ddN0_0101_imm8 }, + { 0x0c16, 0x0cf6, 16, 1, 11, &z8002_device::Z0C_ddN0_0110 }, + { 0x0c18, 0x0cf8, 16, 1, 8, &z8002_device::Z0C_ddN0_1000 }, + { 0x0d10, 0x0df0, 16, 1, 12, &z8002_device::Z0D_ddN0_0000 }, + { 0x0d11, 0x0df1, 16, 2, 11, &z8002_device::Z0D_ddN0_0001_imm16 }, + { 0x0d12, 0x0df2, 16, 1, 12, &z8002_device::Z0D_ddN0_0010 }, + { 0x0d14, 0x0df4, 16, 1, 8, &z8002_device::Z0D_ddN0_0100 }, + { 0x0d15, 0x0df5, 16, 2, 11, &z8002_device::Z0D_ddN0_0101_imm16 }, /* fix cycles ld IR,IM */ + { 0x0d16, 0x0df6, 16, 1, 11, &z8002_device::Z0D_ddN0_0110 }, + { 0x0d18, 0x0df8, 16, 1, 8, &z8002_device::Z0D_ddN0_1000 }, + { 0x0d19, 0x0df9, 16, 2, 12, &z8002_device::Z0D_ddN0_1001_imm16 }, + { 0x0e00, 0x0eff, 1, 1, 10, &z8002_device::Z0E_imm8 }, + { 0x0f00, 0x0fff, 1, 1, 10, &z8002_device::Z0F_imm8 }, + { 0x1000, 0x100f, 1, 3, 14, &z8002_device::Z10_0000_dddd_imm32 }, + { 0x1010, 0x10ff, 1, 1, 14, &z8002_device::Z10_ssN0_dddd }, + { 0x1111, 0x11ff, 1, 1, 20, &z8002_device::Z11_ddN0_ssN0 }, + { 0x1200, 0x120f, 1, 3, 14, &z8002_device::Z12_0000_dddd_imm32 }, + { 0x1210, 0x12ff, 1, 1, 14, &z8002_device::Z12_ssN0_dddd }, + { 0x1311, 0x13ff, 1, 1, 13, &z8002_device::Z13_ddN0_ssN0 }, + { 0x1400, 0x140f, 1, 3, 11, &z8002_device::Z14_0000_dddd_imm32 }, + { 0x1410, 0x14ff, 1, 1, 11, &z8002_device::Z14_ssN0_dddd }, + { 0x1511, 0x15ff, 1, 1, 19, &z8002_device::Z15_ssN0_ddN0 }, + { 0x1600, 0x160f, 1, 3, 14, &z8002_device::Z16_0000_dddd_imm32 }, + { 0x1610, 0x16ff, 1, 1, 14, &z8002_device::Z16_ssN0_dddd }, + { 0x1711, 0x17ff, 1, 1, 12, &z8002_device::Z17_ssN0_ddN0 }, + { 0x1800, 0x180f, 1, 1, 282, &z8002_device::Z18_00N0_dddd_imm32 }, + { 0x1810, 0x18ff, 1, 1, 282, &z8002_device::Z18_ssN0_dddd }, + { 0x1900, 0x190f, 1, 2, 70, &z8002_device::Z19_0000_dddd_imm16 }, + { 0x1910, 0x19ff, 1, 1, 70, &z8002_device::Z19_ssN0_dddd }, + { 0x1a00, 0x1a0f, 1, 3, 744, &z8002_device::Z1A_0000_dddd_imm32 }, + { 0x1a10, 0x1aff, 1, 1, 744, &z8002_device::Z1A_ssN0_dddd }, + { 0x1b00, 0x1b0f, 1, 2, 107, &z8002_device::Z1B_0000_dddd_imm16 }, + { 0x1b10, 0x1bff, 1, 1, 107, &z8002_device::Z1B_ssN0_dddd }, + { 0x1c11, 0x1cf1, 16, 2, 11, &z8002_device::Z1C_ssN0_0001_0000_dddd_0000_nmin1 }, + { 0x1c18, 0x1cf8, 16, 1, 13, &z8002_device::Z1C_ddN0_1000 }, + { 0x1c19, 0x1cf9, 16, 2, 11, &z8002_device::Z1C_ddN0_1001_0000_ssss_0000_nmin1 }, + { 0x1d10, 0x1dff, 1, 1, 11, &z8002_device::Z1D_ddN0_ssss }, + { 0x1e10, 0x1eff, 1, 1, 10, &z8002_device::Z1E_ddN0_cccc }, + { 0x1f10, 0x1ff0, 16, 1, 10, &z8002_device::Z1F_ddN0_0000 }, + { 0x2000, 0x200f, 1, 2, 7, &z8002_device::Z20_0000_dddd_imm8 }, + { 0x2010, 0x20ff, 1, 1, 7, &z8002_device::Z20_ssN0_dddd }, + { 0x2100, 0x210f, 1, 2, 7, &z8002_device::Z21_0000_dddd_imm16 }, + { 0x2110, 0x21ff, 1, 1, 7, &z8002_device::Z21_ssN0_dddd }, + { 0x2200, 0x220f, 1, 2, 10, &z8002_device::Z22_0000_ssss_0000_dddd_0000_0000 }, + { 0x2210, 0x22ff, 1, 1, 11, &z8002_device::Z22_ddN0_imm4 }, + { 0x2300, 0x230f, 1, 2, 10, &z8002_device::Z23_0000_ssss_0000_dddd_0000_0000 }, + { 0x2310, 0x23ff, 1, 1, 11, &z8002_device::Z23_ddN0_imm4 }, + { 0x2400, 0x240f, 1, 2, 10, &z8002_device::Z24_0000_ssss_0000_dddd_0000_0000 }, + { 0x2410, 0x24ff, 1, 1, 11, &z8002_device::Z24_ddN0_imm4 }, + { 0x2500, 0x250f, 1, 2, 10, &z8002_device::Z25_0000_ssss_0000_dddd_0000_0000 }, + { 0x2510, 0x25ff, 1, 1, 11, &z8002_device::Z25_ddN0_imm4 }, + { 0x2600, 0x260f, 1, 2, 10, &z8002_device::Z26_0000_ssss_0000_dddd_0000_0000 }, + { 0x2610, 0x26ff, 1, 1, 8, &z8002_device::Z26_ddN0_imm4 }, + { 0x2700, 0x270f, 1, 2, 10, &z8002_device::Z27_0000_ssss_0000_dddd_0000_0000 }, + { 0x2710, 0x27ff, 1, 1, 8, &z8002_device::Z27_ddN0_imm4 }, + { 0x2810, 0x28ff, 1, 1, 11, &z8002_device::Z28_ddN0_imm4m1 }, + { 0x2910, 0x29ff, 1, 1, 11, &z8002_device::Z29_ddN0_imm4m1 }, + { 0x2a10, 0x2aff, 1, 1, 11, &z8002_device::Z2A_ddN0_imm4m1 }, + { 0x2b10, 0x2bff, 1, 1, 11, &z8002_device::Z2B_ddN0_imm4m1 }, + { 0x2c10, 0x2cff, 1, 1, 12, &z8002_device::Z2C_ssN0_dddd }, + { 0x2d10, 0x2dff, 1, 1, 12, &z8002_device::Z2D_ssN0_dddd }, + { 0x2e10, 0x2eff, 1, 1, 8, &z8002_device::Z2E_ddN0_ssss }, + { 0x2f10, 0x2fff, 1, 1, 8, &z8002_device::Z2F_ddN0_ssss }, + { 0x3000, 0x300f, 1, 2, 14, &z8002_device::Z30_0000_dddd_dsp16 }, + { 0x3010, 0x30ff, 1, 2, 14, &z8002_device::Z30_ssN0_dddd_imm16 }, + { 0x3100, 0x310f, 1, 2, 14, &z8002_device::Z31_0000_dddd_dsp16 }, + { 0x3110, 0x31ff, 1, 2, 14, &z8002_device::Z31_ssN0_dddd_imm16 }, + { 0x3200, 0x320f, 1, 2, 14, &z8002_device::Z32_0000_ssss_dsp16 }, + { 0x3210, 0x32ff, 1, 2, 14, &z8002_device::Z32_ddN0_ssss_imm16 }, + { 0x3300, 0x330f, 1, 2, 14, &z8002_device::Z33_0000_ssss_dsp16 }, + { 0x3310, 0x33ff, 1, 2, 14, &z8002_device::Z33_ddN0_ssss_imm16 }, + { 0x3400, 0x340f, 1, 2, 15, &z8002_device::Z34_0000_dddd_dsp16 }, + { 0x3410, 0x34ff, 1, 2, 15, &z8002_device::Z34_ssN0_dddd_imm16 }, + { 0x3500, 0x350f, 1, 2, 17, &z8002_device::Z35_0000_dddd_dsp16 }, + { 0x3510, 0x35ff, 1, 2, 17, &z8002_device::Z35_ssN0_dddd_imm16 }, + { 0x3600, 0x3600, 1, 1, 2, &z8002_device::Z36_0000_0000 }, + { 0x3601, 0x36ff, 1, 1, 10, &z8002_device::Z36_imm8 }, + { 0x3700, 0x370f, 1, 2, 17, &z8002_device::Z37_0000_ssss_dsp16 }, + { 0x3710, 0x37ff, 1, 2, 17, &z8002_device::Z37_ddN0_ssss_imm16 }, + { 0x3800, 0x38ff, 1, 1, 10, &z8002_device::Z38_imm8 }, + { 0x3910, 0x39f0, 16, 1, 12, &z8002_device::Z39_ssN0_0000 }, + { 0x3a00, 0x3af0, 16, 2, 21, &z8002_device::Z3A_ssss_0000_0000_aaaa_dddd_x000 }, + { 0x3a01, 0x3af1, 16, 2, 21, &z8002_device::Z3A_ssss_0001_0000_aaaa_dddd_x000 }, + { 0x3a02, 0x3af2, 16, 2, 21, &z8002_device::Z3A_ssss_0010_0000_aaaa_dddd_x000 }, + { 0x3a03, 0x3af3, 16, 2, 21, &z8002_device::Z3A_ssss_0011_0000_aaaa_dddd_x000 }, + { 0x3a04, 0x3af4, 16, 2, 10, &z8002_device::Z3A_dddd_0100_imm16 }, + { 0x3a05, 0x3af5, 16, 2, 10, &z8002_device::Z3A_dddd_0101_imm16 }, + { 0x3a06, 0x3af6, 16, 2, 12, &z8002_device::Z3A_ssss_0110_imm16 }, + { 0x3a07, 0x3af7, 16, 2, 12, &z8002_device::Z3A_ssss_0111_imm16 }, + { 0x3a08, 0x3af8, 16, 2, 21, &z8002_device::Z3A_ssss_1000_0000_aaaa_dddd_x000 }, + { 0x3a09, 0x3af9, 16, 2, 21, &z8002_device::Z3A_ssss_1001_0000_aaaa_dddd_x000 }, + { 0x3a0a, 0x3afa, 16, 2, 21, &z8002_device::Z3A_ssss_1010_0000_aaaa_dddd_x000 }, + { 0x3a0b, 0x3afb, 16, 2, 21, &z8002_device::Z3A_ssss_1011_0000_aaaa_dddd_x000 }, + { 0x3b00, 0x3bf0, 16, 2, 21, &z8002_device::Z3B_ssss_0000_0000_aaaa_dddd_x000 }, + { 0x3b01, 0x3bf1, 16, 2, 21, &z8002_device::Z3B_ssss_0001_0000_aaaa_dddd_x000 }, + { 0x3b02, 0x3bf2, 16, 2, 21, &z8002_device::Z3B_ssss_0010_0000_aaaa_dddd_x000 }, + { 0x3b03, 0x3bf3, 16, 2, 21, &z8002_device::Z3B_ssss_0011_0000_aaaa_dddd_x000 }, + { 0x3b04, 0x3bf4, 16, 2, 12, &z8002_device::Z3B_dddd_0100_imm16 }, + { 0x3b05, 0x3bf5, 16, 2, 12, &z8002_device::Z3B_dddd_0101_imm16 }, + { 0x3b06, 0x3bf6, 16, 2, 12, &z8002_device::Z3B_ssss_0110_imm16 }, + { 0x3b07, 0x3bf7, 16, 2, 12, &z8002_device::Z3B_ssss_0111_imm16 }, + { 0x3b08, 0x3bf8, 16, 2, 21, &z8002_device::Z3B_ssss_1000_0000_aaaa_dddd_x000 }, + { 0x3b09, 0x3bf9, 16, 2, 21, &z8002_device::Z3B_ssss_1001_0000_aaaa_dddd_x000 }, + { 0x3b0a, 0x3bfa, 16, 2, 21, &z8002_device::Z3B_ssss_1010_0000_aaaa_dddd_x000 }, + { 0x3b0b, 0x3bfb, 16, 2, 21, &z8002_device::Z3B_ssss_1011_0000_aaaa_dddd_x000 }, + { 0x3c00, 0x3cff, 1, 1, 10, &z8002_device::Z3C_ssss_dddd }, + { 0x3d00, 0x3dff, 1, 1, 10, &z8002_device::Z3D_ssss_dddd }, + { 0x3e00, 0x3eff, 1, 1, 12, &z8002_device::Z3E_dddd_ssss }, + { 0x3f00, 0x3fff, 1, 1, 12, &z8002_device::Z3F_dddd_ssss }, + { 0x4000, 0x400f, 1, 2, 9, &z8002_device::Z40_0000_dddd_addr }, + { 0x4010, 0x40ff, 1, 2, 10, &z8002_device::Z40_ssN0_dddd_addr }, + { 0x4100, 0x410f, 1, 2, 9, &z8002_device::Z41_0000_dddd_addr }, + { 0x4110, 0x41ff, 1, 2, 10, &z8002_device::Z41_ssN0_dddd_addr }, + { 0x4200, 0x420f, 1, 2, 9, &z8002_device::Z42_0000_dddd_addr }, + { 0x4210, 0x42ff, 1, 2, 10, &z8002_device::Z42_ssN0_dddd_addr }, + { 0x4300, 0x430f, 1, 2, 9, &z8002_device::Z43_0000_dddd_addr }, + { 0x4310, 0x43ff, 1, 2, 10, &z8002_device::Z43_ssN0_dddd_addr }, + { 0x4400, 0x440f, 1, 2, 9, &z8002_device::Z44_0000_dddd_addr }, + { 0x4410, 0x44ff, 1, 2, 10, &z8002_device::Z44_ssN0_dddd_addr }, + { 0x4500, 0x450f, 1, 2, 9, &z8002_device::Z45_0000_dddd_addr }, + { 0x4510, 0x45ff, 1, 2, 10, &z8002_device::Z45_ssN0_dddd_addr }, + { 0x4600, 0x460f, 1, 2, 9, &z8002_device::Z46_0000_dddd_addr }, + { 0x4610, 0x46ff, 1, 2, 10, &z8002_device::Z46_ssN0_dddd_addr }, + { 0x4700, 0x470f, 1, 2, 9, &z8002_device::Z47_0000_dddd_addr }, + { 0x4710, 0x47ff, 1, 2, 10, &z8002_device::Z47_ssN0_dddd_addr }, + { 0x4800, 0x480f, 1, 2, 9, &z8002_device::Z48_0000_dddd_addr }, + { 0x4810, 0x48ff, 1, 2, 10, &z8002_device::Z48_ssN0_dddd_addr }, + { 0x4900, 0x490f, 1, 2, 9, &z8002_device::Z49_0000_dddd_addr }, + { 0x4910, 0x49ff, 1, 2, 10, &z8002_device::Z49_ssN0_dddd_addr }, + { 0x4a00, 0x4a0f, 1, 2, 9, &z8002_device::Z4A_0000_dddd_addr }, + { 0x4a10, 0x4aff, 1, 2, 10, &z8002_device::Z4A_ssN0_dddd_addr }, + { 0x4b00, 0x4b0f, 1, 2, 9, &z8002_device::Z4B_0000_dddd_addr }, + { 0x4b10, 0x4bff, 1, 2, 10, &z8002_device::Z4B_ssN0_dddd_addr }, + { 0x4c00, 0x4c00, 1, 2, 15, &z8002_device::Z4C_0000_0000_addr }, + { 0x4c01, 0x4c01, 1, 3, 14, &z8002_device::Z4C_0000_0001_addr_imm8 }, + { 0x4c02, 0x4c02, 1, 2, 15, &z8002_device::Z4C_0000_0010_addr }, + { 0x4c04, 0x4c04, 1, 2, 11, &z8002_device::Z4C_0000_0100_addr }, + { 0x4c05, 0x4c05, 1, 3, 14, &z8002_device::Z4C_0000_0101_addr_imm8 }, + { 0x4c06, 0x4c06, 1, 2, 14, &z8002_device::Z4C_0000_0110_addr }, + { 0x4c08, 0x4c08, 1, 2, 11, &z8002_device::Z4C_0000_1000_addr }, + { 0x4c10, 0x4cf0, 16, 2, 16, &z8002_device::Z4C_ddN0_0000_addr }, + { 0x4c11, 0x4cf1, 16, 3, 15, &z8002_device::Z4C_ddN0_0001_addr_imm8 }, + { 0x4c12, 0x4cf2, 16, 2, 16, &z8002_device::Z4C_ddN0_0010_addr }, + { 0x4c14, 0x4cf4, 16, 2, 12, &z8002_device::Z4C_ddN0_0100_addr }, + { 0x4c15, 0x4cf5, 16, 3, 15, &z8002_device::Z4C_ddN0_0101_addr_imm8 }, + { 0x4c16, 0x4cf6, 16, 2, 15, &z8002_device::Z4C_ddN0_0110_addr }, + { 0x4c18, 0x4cf8, 16, 2, 12, &z8002_device::Z4C_ddN0_1000_addr }, + { 0x4d00, 0x4d00, 1, 2, 15, &z8002_device::Z4D_0000_0000_addr }, + { 0x4d01, 0x4d01, 1, 3, 14, &z8002_device::Z4D_0000_0001_addr_imm16 }, + { 0x4d02, 0x4d02, 1, 2, 15, &z8002_device::Z4D_0000_0010_addr }, + { 0x4d04, 0x4d04, 1, 2, 11, &z8002_device::Z4D_0000_0100_addr }, + { 0x4d05, 0x4d05, 1, 3, 14, &z8002_device::Z4D_0000_0101_addr_imm16 }, + { 0x4d06, 0x4d06, 1, 2, 14, &z8002_device::Z4D_0000_0110_addr }, + { 0x4d08, 0x4d08, 1, 2, 11, &z8002_device::Z4D_0000_1000_addr }, + { 0x4d10, 0x4df0, 16, 2, 16, &z8002_device::Z4D_ddN0_0000_addr }, + { 0x4d11, 0x4df1, 16, 3, 15, &z8002_device::Z4D_ddN0_0001_addr_imm16 }, + { 0x4d12, 0x4df2, 16, 2, 16, &z8002_device::Z4D_ddN0_0010_addr }, + { 0x4d14, 0x4df4, 16, 2, 12, &z8002_device::Z4D_ddN0_0100_addr }, + { 0x4d15, 0x4df5, 16, 3, 15, &z8002_device::Z4D_ddN0_0101_addr_imm16 }, + { 0x4d16, 0x4df6, 16, 2, 15, &z8002_device::Z4D_ddN0_0110_addr }, + { 0x4d18, 0x4df8, 16, 2, 12, &z8002_device::Z4D_ddN0_1000_addr }, + { 0x4e11, 0x4ef0, 16, 2, 12, &z8002_device::Z4E_ddN0_ssN0_addr }, + { 0x5000, 0x500f, 1, 2, 15, &z8002_device::Z50_0000_dddd_addr }, + { 0x5010, 0x50ff, 1, 2, 16, &z8002_device::Z50_ssN0_dddd_addr }, + { 0x5110, 0x51f0, 16, 2, 21, &z8002_device::Z51_ddN0_0000_addr }, + { 0x5111, 0x51f1, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5112, 0x51f2, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5113, 0x51f3, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5114, 0x51f4, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5115, 0x51f5, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5116, 0x51f6, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5117, 0x51f7, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5118, 0x51f8, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5119, 0x51f9, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511a, 0x51fa, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511b, 0x51fb, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511c, 0x51fc, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511d, 0x51fd, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511e, 0x51fe, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x511f, 0x51ff, 16, 2, 21, &z8002_device::Z51_ddN0_ssN0_addr }, + { 0x5200, 0x520f, 1, 2, 15, &z8002_device::Z52_0000_dddd_addr }, + { 0x5210, 0x52ff, 1, 2, 16, &z8002_device::Z52_ssN0_dddd_addr }, + { 0x5310, 0x53f0, 16, 2, 14, &z8002_device::Z53_ddN0_0000_addr }, + { 0x5311, 0x53f1, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5312, 0x53f2, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5313, 0x53f3, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5314, 0x53f4, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5315, 0x53f5, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5316, 0x53f6, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5317, 0x53f7, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5318, 0x53f8, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5319, 0x53f9, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531a, 0x53fa, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531b, 0x53fb, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531c, 0x53fc, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531d, 0x53fd, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531e, 0x53fe, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x531f, 0x53ff, 16, 2, 14, &z8002_device::Z53_ddN0_ssN0_addr }, + { 0x5400, 0x540f, 1, 2, 12, &z8002_device::Z54_0000_dddd_addr }, + { 0x5410, 0x54ff, 1, 2, 13, &z8002_device::Z54_ssN0_dddd_addr }, + { 0x5510, 0x55f0, 16, 2, 23, &z8002_device::Z55_ssN0_0000_addr }, + { 0x5511, 0x55f1, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5512, 0x55f2, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5513, 0x55f3, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5514, 0x55f4, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5515, 0x55f5, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5516, 0x55f6, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5517, 0x55f7, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5518, 0x55f8, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5519, 0x55f9, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551a, 0x55fa, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551b, 0x55fb, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551c, 0x55fc, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551d, 0x55fd, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551e, 0x55fe, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x551f, 0x55ff, 16, 2, 23, &z8002_device::Z55_ssN0_ddN0_addr }, + { 0x5600, 0x560f, 1, 2, 15, &z8002_device::Z56_0000_dddd_addr }, + { 0x5610, 0x56ff, 1, 2, 16, &z8002_device::Z56_ssN0_dddd_addr }, + { 0x5710, 0x57f0, 16, 2, 16, &z8002_device::Z57_ssN0_0000_addr }, + { 0x5711, 0x57f1, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5712, 0x57f2, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5713, 0x57f3, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5714, 0x57f4, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5715, 0x57f5, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5716, 0x57f6, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5717, 0x57f7, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5718, 0x57f8, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5719, 0x57f9, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571a, 0x57fa, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571b, 0x57fb, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571c, 0x57fc, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571d, 0x57fd, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571e, 0x57fe, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x571f, 0x57ff, 16, 2, 16, &z8002_device::Z57_ssN0_ddN0_addr }, + { 0x5800, 0x580f, 1, 2, 283, &z8002_device::Z58_0000_dddd_addr }, + { 0x5810, 0x58ff, 1, 2, 284, &z8002_device::Z58_ssN0_dddd_addr }, + { 0x5900, 0x590f, 1, 2, 71, &z8002_device::Z59_0000_dddd_addr }, + { 0x5910, 0x59ff, 1, 2, 72, &z8002_device::Z59_ssN0_dddd_addr }, + { 0x5a00, 0x5a0f, 1, 2, 745, &z8002_device::Z5A_0000_dddd_addr }, + { 0x5a10, 0x5aff, 1, 2, 746, &z8002_device::Z5A_ssN0_dddd_addr }, + { 0x5b00, 0x5b0f, 1, 2, 108, &z8002_device::Z5B_0000_dddd_addr }, + { 0x5b10, 0x5bff, 1, 2, 109, &z8002_device::Z5B_ssN0_dddd_addr }, + { 0x5c01, 0x5c01, 1, 3, 14, &z8002_device::Z5C_0000_0001_0000_dddd_0000_nmin1_addr }, + { 0x5c08, 0x5c08, 1, 2, 16, &z8002_device::Z5C_0000_1000_addr }, + { 0x5c09, 0x5c09, 1, 3, 14, &z8002_device::Z5C_0000_1001_0000_ssss_0000_nmin1_addr }, + { 0x5c11, 0x5cf1, 16, 3, 15, &z8002_device::Z5C_ssN0_0001_0000_dddd_0000_nmin1_addr }, + { 0x5c18, 0x5cf8, 16, 2, 17, &z8002_device::Z5C_ddN0_1000_addr }, + { 0x5c19, 0x5cf9, 16, 3, 15, &z8002_device::Z5C_ddN0_1001_0000_ssN0_0000_nmin1_addr }, + { 0x5d00, 0x5d0f, 1, 2, 15, &z8002_device::Z5D_0000_ssss_addr }, + { 0x5d10, 0x5dff, 1, 2, 14, &z8002_device::Z5D_ddN0_ssss_addr }, + { 0x5e00, 0x5e0f, 1, 2, 7, &z8002_device::Z5E_0000_cccc_addr }, + { 0x5e10, 0x5eff, 1, 2, 8, &z8002_device::Z5E_ddN0_cccc_addr }, + { 0x5f00, 0x5f00, 1, 2, 12, &z8002_device::Z5F_0000_0000_addr }, + { 0x5f10, 0x5ff0, 16, 2, 13, &z8002_device::Z5F_ddN0_0000_addr }, + { 0x6000, 0x600f, 1, 2, 9, &z8002_device::Z60_0000_dddd_addr }, + { 0x6010, 0x60ff, 1, 2, 10, &z8002_device::Z60_ssN0_dddd_addr }, + { 0x6100, 0x610f, 1, 2, 9, &z8002_device::Z61_0000_dddd_addr }, + { 0x6110, 0x61ff, 1, 2, 10, &z8002_device::Z61_ssN0_dddd_addr }, + { 0x6200, 0x620f, 1, 2, 13, &z8002_device::Z62_0000_imm4_addr }, + { 0x6210, 0x62ff, 1, 2, 14, &z8002_device::Z62_ddN0_imm4_addr }, + { 0x6300, 0x630f, 1, 2, 13, &z8002_device::Z63_0000_imm4_addr }, + { 0x6310, 0x63ff, 1, 2, 14, &z8002_device::Z63_ddN0_imm4_addr }, + { 0x6400, 0x640f, 1, 2, 13, &z8002_device::Z64_0000_imm4_addr }, + { 0x6410, 0x64ff, 1, 2, 14, &z8002_device::Z64_ddN0_imm4_addr }, + { 0x6500, 0x650f, 1, 2, 13, &z8002_device::Z65_0000_imm4_addr }, + { 0x6510, 0x65ff, 1, 2, 14, &z8002_device::Z65_ddN0_imm4_addr }, + { 0x6600, 0x660f, 1, 2, 10, &z8002_device::Z66_0000_imm4_addr }, + { 0x6610, 0x66ff, 1, 2, 11, &z8002_device::Z66_ddN0_imm4_addr }, + { 0x6700, 0x670f, 1, 2, 10, &z8002_device::Z67_0000_imm4_addr }, + { 0x6710, 0x67ff, 1, 2, 11, &z8002_device::Z67_ddN0_imm4_addr }, + { 0x6800, 0x680f, 1, 2, 13, &z8002_device::Z68_0000_imm4m1_addr }, + { 0x6810, 0x68ff, 1, 2, 14, &z8002_device::Z68_ddN0_imm4m1_addr }, + { 0x6900, 0x690f, 1, 2, 13, &z8002_device::Z69_0000_imm4m1_addr }, + { 0x6910, 0x69ff, 1, 2, 14, &z8002_device::Z69_ddN0_imm4m1_addr }, + { 0x6a00, 0x6a0f, 1, 2, 13, &z8002_device::Z6A_0000_imm4m1_addr }, + { 0x6a10, 0x6aff, 1, 2, 14, &z8002_device::Z6A_ddN0_imm4m1_addr }, + { 0x6b00, 0x6b0f, 1, 2, 13, &z8002_device::Z6B_0000_imm4m1_addr }, + { 0x6b10, 0x6bff, 1, 2, 14, &z8002_device::Z6B_ddN0_imm4m1_addr }, + { 0x6c00, 0x6c0f, 1, 2, 15, &z8002_device::Z6C_0000_dddd_addr }, + { 0x6c10, 0x6cff, 1, 2, 16, &z8002_device::Z6C_ssN0_dddd_addr }, + { 0x6d00, 0x6d0f, 1, 2, 15, &z8002_device::Z6D_0000_dddd_addr }, + { 0x6d10, 0x6dff, 1, 2, 16, &z8002_device::Z6D_ssN0_dddd_addr }, + { 0x6e00, 0x6e0f, 1, 2, 11, &z8002_device::Z6E_0000_ssss_addr }, + { 0x6e10, 0x6eff, 1, 2, 11, &z8002_device::Z6E_ddN0_ssss_addr }, + { 0x6f00, 0x6f0f, 1, 2, 11, &z8002_device::Z6F_0000_ssss_addr }, + { 0x6f10, 0x6fff, 1, 2, 12, &z8002_device::Z6F_ddN0_ssss_addr }, + { 0x7010, 0x70ff, 1, 2, 14, &z8002_device::Z70_ssN0_dddd_0000_xxxx_0000_0000 }, + { 0x7110, 0x71ff, 1, 2, 14, &z8002_device::Z71_ssN0_dddd_0000_xxxx_0000_0000 }, + { 0x7210, 0x72ff, 1, 2, 14, &z8002_device::Z72_ddN0_ssss_0000_xxxx_0000_0000 }, + { 0x7310, 0x73ff, 1, 2, 14, &z8002_device::Z73_ddN0_ssss_0000_xxxx_0000_0000 }, + { 0x7410, 0x74ff, 1, 2, 15, &z8002_device::Z74_ssN0_dddd_0000_xxxx_0000_0000 }, + { 0x7510, 0x75ff, 1, 2, 17, &z8002_device::Z75_ssN0_dddd_0000_xxxx_0000_0000 }, + { 0x7600, 0x760f, 1, 2, 12, &z8002_device::Z76_0000_dddd_addr }, + { 0x7610, 0x76ff, 1, 2, 13, &z8002_device::Z76_ssN0_dddd_addr }, + { 0x7710, 0x77ff, 1, 2, 17, &z8002_device::Z77_ddN0_ssss_0000_xxxx_0000_0000 }, + { 0x7800, 0x78ff, 1, 1, 10, &z8002_device::Z78_imm8 }, + { 0x7900, 0x7900, 1, 2, 16, &z8002_device::Z79_0000_0000_addr }, + { 0x7910, 0x79f0, 16, 2, 17, &z8002_device::Z79_ssN0_0000_addr }, + { 0x7a00, 0x7a00, 1, 1, 8, &z8002_device::Z7A_0000_0000 }, + { 0x7b00, 0x7b00, 1, 1, 13, &z8002_device::Z7B_0000_0000 }, + { 0x7b08, 0x7b08, 1, 1, 5, &z8002_device::Z7B_0000_1000 }, + { 0x7b09, 0x7b09, 1, 1, 5, &z8002_device::Z7B_0000_1001 }, + { 0x7b0a, 0x7b0a, 1, 1, 7, &z8002_device::Z7B_0000_1010 }, + { 0x7b0d, 0x7bfd, 16, 1, 12, &z8002_device::Z7B_dddd_1101 }, + { 0x7c00, 0x7c03, 1, 1, 7, &z8002_device::Z7C_0000_00ii }, + { 0x7c04, 0x7c07, 1, 1, 7, &z8002_device::Z7C_0000_01ii }, + { 0x7d00, 0x7df0, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d01, 0x7df1, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d02, 0x7df2, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d03, 0x7df3, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d04, 0x7df4, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d05, 0x7df5, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d06, 0x7df6, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d07, 0x7df7, 16, 1, 7, &z8002_device::Z7D_dddd_0ccc }, + { 0x7d08, 0x7df8, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d09, 0x7df9, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0a, 0x7dfa, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0b, 0x7dfb, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0c, 0x7dfc, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0d, 0x7dfd, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0e, 0x7dfe, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7d0f, 0x7dff, 16, 1, 7, &z8002_device::Z7D_ssss_1ccc }, + { 0x7e00, 0x7eff, 1, 1, 10, &z8002_device::Z7E_imm8 }, + { 0x7f00, 0x7fff, 1, 1, 33, &z8002_device::Z7F_imm8 }, + { 0x8000, 0x80ff, 1, 1, 4, &z8002_device::Z80_ssss_dddd }, + { 0x8100, 0x81ff, 1, 1, 4, &z8002_device::Z81_ssss_dddd }, + { 0x8200, 0x82ff, 1, 1, 4, &z8002_device::Z82_ssss_dddd }, + { 0x8300, 0x83ff, 1, 1, 4, &z8002_device::Z83_ssss_dddd }, + { 0x8400, 0x84ff, 1, 1, 4, &z8002_device::Z84_ssss_dddd }, + { 0x8500, 0x85ff, 1, 1, 4, &z8002_device::Z85_ssss_dddd }, + { 0x8600, 0x86ff, 1, 1, 4, &z8002_device::Z86_ssss_dddd }, + { 0x8700, 0x87ff, 1, 1, 4, &z8002_device::Z87_ssss_dddd }, + { 0x8800, 0x88ff, 1, 1, 4, &z8002_device::Z88_ssss_dddd }, + { 0x8900, 0x89ff, 1, 1, 4, &z8002_device::Z89_ssss_dddd }, + { 0x8a00, 0x8aff, 1, 1, 4, &z8002_device::Z8A_ssss_dddd }, + { 0x8b00, 0x8bff, 1, 1, 4, &z8002_device::Z8B_ssss_dddd }, + { 0x8c00, 0x8cf0, 16, 1, 7, &z8002_device::Z8C_dddd_0000 }, + { 0x8c02, 0x8cf2, 16, 1, 7, &z8002_device::Z8C_dddd_0010 }, + { 0x8c04, 0x8cf4, 16, 1, 7, &z8002_device::Z8C_dddd_0100 }, + { 0x8c06, 0x8cf6, 16, 1, 7, &z8002_device::Z8C_dddd_0110 }, + { 0x8c01, 0x8cf1, 16, 1, 7, &z8002_device::Z8C_dddd_0001 }, + { 0x8c08, 0x8cf8, 16, 1, 7, &z8002_device::Z8C_dddd_1000 }, + { 0x8c09, 0x8cf9, 16, 1, 7, &z8002_device::Z8C_dddd_1001 }, + { 0x8d00, 0x8df0, 16, 1, 7, &z8002_device::Z8D_dddd_0000 }, + { 0x8d01, 0x8df1, 16, 1, 7, &z8002_device::Z8D_imm4_0001 }, + { 0x8d02, 0x8df2, 16, 1, 7, &z8002_device::Z8D_dddd_0010 }, + { 0x8d03, 0x8df3, 16, 1, 7, &z8002_device::Z8D_imm4_0011 }, + { 0x8d04, 0x8df4, 16, 1, 7, &z8002_device::Z8D_dddd_0100 }, + { 0x8d05, 0x8df5, 16, 1, 7, &z8002_device::Z8D_imm4_0101 }, + { 0x8d06, 0x8df6, 16, 1, 7, &z8002_device::Z8D_dddd_0110 }, + { 0x8d07, 0x8d07, 1, 1, 7, &z8002_device::Z8D_0000_0111 }, + { 0x8d08, 0x8df8, 16, 1, 7, &z8002_device::Z8D_dddd_1000 }, + { 0x8e00, 0x8eff, 1, 1, 10, &z8002_device::Z8E_imm8 }, + { 0x8f00, 0x8fff, 1, 1, 10, &z8002_device::Z8F_imm8 }, + { 0x9000, 0x90ff, 1, 1, 8, &z8002_device::Z90_ssss_dddd }, + { 0x9110, 0x91ff, 1, 1, 12, &z8002_device::Z91_ddN0_ssss }, + { 0x9200, 0x92ff, 1, 1, 8, &z8002_device::Z92_ssss_dddd }, + { 0x9310, 0x93ff, 1, 1, 9, &z8002_device::Z93_ddN0_ssss }, + { 0x9400, 0x94ff, 1, 1, 5, &z8002_device::Z94_ssss_dddd }, + { 0x9510, 0x95ff, 1, 1, 12, &z8002_device::Z95_ssN0_dddd }, + { 0x9600, 0x96ff, 1, 1, 8, &z8002_device::Z96_ssss_dddd }, + { 0x9710, 0x97ff, 1, 1, 8, &z8002_device::Z97_ssN0_dddd }, + { 0x9800, 0x98ff, 1, 1, 282, &z8002_device::Z98_ssss_dddd }, + { 0x9900, 0x99ff, 1, 1, 70, &z8002_device::Z99_ssss_dddd }, + { 0x9a00, 0x9aff, 1, 1, 744, &z8002_device::Z9A_ssss_dddd }, + { 0x9b00, 0x9bff, 1, 1, 107, &z8002_device::Z9B_ssss_dddd }, + { 0x9c00, 0x9cf8, 8, 1, 13, &z8002_device::Z9C_dddd_1000 }, + { 0x9d00, 0x9dff, 1, 1, 10, &z8002_device::Z9D_imm8 }, + { 0x9e00, 0x9e0f, 1, 1, 10, &z8002_device::Z9E_0000_cccc }, + { 0x9f00, 0x9fff, 1, 1, 10, &z8002_device::Z9F_imm8 }, + { 0xa000, 0xa0ff, 1, 1, 3, &z8002_device::ZA0_ssss_dddd }, + { 0xa100, 0xa1ff, 1, 1, 3, &z8002_device::ZA1_ssss_dddd }, + { 0xa200, 0xa2ff, 1, 1, 4, &z8002_device::ZA2_dddd_imm4 }, + { 0xa300, 0xa3ff, 1, 1, 4, &z8002_device::ZA3_dddd_imm4 }, + { 0xa400, 0xa4ff, 1, 1, 4, &z8002_device::ZA4_dddd_imm4 }, + { 0xa500, 0xa5ff, 1, 1, 4, &z8002_device::ZA5_dddd_imm4 }, + { 0xa600, 0xa6ff, 1, 1, 4, &z8002_device::ZA6_dddd_imm4 }, + { 0xa700, 0xa7ff, 1, 1, 4, &z8002_device::ZA7_dddd_imm4 }, + { 0xa800, 0xa8ff, 1, 1, 4, &z8002_device::ZA8_dddd_imm4m1 }, + { 0xa900, 0xa9ff, 1, 1, 4, &z8002_device::ZA9_dddd_imm4m1 }, + { 0xaa00, 0xaaff, 1, 1, 4, &z8002_device::ZAA_dddd_imm4m1 }, + { 0xab00, 0xabff, 1, 1, 4, &z8002_device::ZAB_dddd_imm4m1 }, + { 0xac00, 0xacff, 1, 1, 6, &z8002_device::ZAC_ssss_dddd }, + { 0xad00, 0xadff, 1, 1, 6, &z8002_device::ZAD_ssss_dddd }, + { 0xae00, 0xaeff, 1, 1, 5, &z8002_device::ZAE_dddd_cccc }, + { 0xaf00, 0xafff, 1, 1, 5, &z8002_device::ZAF_dddd_cccc }, + { 0xb000, 0xb0f0, 16, 1, 5, &z8002_device::ZB0_dddd_0000 }, + { 0xb100, 0xb1f0, 16, 1, 11, &z8002_device::ZB1_dddd_0000 }, + { 0xb107, 0xb1f7, 16, 1, 11, &z8002_device::ZB1_dddd_0111 }, + { 0xb10a, 0xb1fa, 16, 1, 11, &z8002_device::ZB1_dddd_1010 }, + { 0xb200, 0xb2f0, 16, 1, 6, &z8002_device::ZB2_dddd_00I0 }, + { 0xb201, 0xb2f1, 16, 2, 13, &z8002_device::ZB2_dddd_0001_imm8 }, + { 0xb202, 0xb2f2, 16, 1, 6, &z8002_device::ZB2_dddd_00I0 }, + { 0xb203, 0xb2f3, 16, 2, 15, &z8002_device::ZB2_dddd_0011_0000_ssss_0000_0000 }, + { 0xb204, 0xb2f4, 16, 1, 6, &z8002_device::ZB2_dddd_01I0 }, + { 0xb206, 0xb2f6, 16, 1, 6, &z8002_device::ZB2_dddd_01I0 }, + { 0xb208, 0xb2f8, 16, 1, 9, &z8002_device::ZB2_dddd_10I0 }, + { 0xb209, 0xb2f9, 16, 2, 13, &z8002_device::ZB2_dddd_1001_imm8 }, + { 0xb20a, 0xb2fa, 16, 1, 9, &z8002_device::ZB2_dddd_10I0 }, + { 0xb20b, 0xb2fb, 16, 2, 15, &z8002_device::ZB2_dddd_1011_0000_ssss_0000_0000 }, + { 0xb20c, 0xb2fc, 16, 1, 9, &z8002_device::ZB2_dddd_11I0 }, + { 0xb20e, 0xb2fe, 16, 1, 9, &z8002_device::ZB2_dddd_11I0 }, + { 0xb300, 0xb3f0, 16, 1, 6, &z8002_device::ZB3_dddd_00I0 }, + { 0xb301, 0xb3f1, 16, 2, 13, &z8002_device::ZB3_dddd_0001_imm8 }, + { 0xb302, 0xb3f2, 16, 1, 6, &z8002_device::ZB3_dddd_00I0 }, + { 0xb303, 0xb3f3, 16, 2, 15, &z8002_device::ZB3_dddd_0011_0000_ssss_0000_0000 }, + { 0xb304, 0xb3f4, 16, 1, 6, &z8002_device::ZB3_dddd_01I0 }, + { 0xb305, 0xb3f5, 16, 2, 13, &z8002_device::ZB3_dddd_0101_imm8 }, + { 0xb306, 0xb3f6, 16, 1, 6, &z8002_device::ZB3_dddd_01I0 }, + { 0xb307, 0xb3f7, 16, 2, 15, &z8002_device::ZB3_dddd_0111_0000_ssss_0000_0000 }, + { 0xb308, 0xb3f8, 16, 1, 6, &z8002_device::ZB3_dddd_10I0 }, + { 0xb309, 0xb3f9, 16, 2, 13, &z8002_device::ZB3_dddd_1001_imm8 }, + { 0xb30a, 0xb3fa, 16, 1, 6, &z8002_device::ZB3_dddd_10I0 }, + { 0xb30b, 0xb3fb, 16, 2, 15, &z8002_device::ZB3_dddd_1011_0000_ssss_0000_0000 }, + { 0xb30c, 0xb3fc, 16, 1, 6, &z8002_device::ZB3_dddd_11I0 }, + { 0xb30d, 0xb3fd, 16, 2, 13, &z8002_device::ZB3_dddd_1101_imm8 }, + { 0xb30e, 0xb3fe, 16, 1, 6, &z8002_device::ZB3_dddd_11I0 }, + { 0xb30f, 0xb3ff, 16, 2, 15, &z8002_device::ZB3_dddd_1111_0000_ssss_0000_0000 }, + { 0xb400, 0xb4ff, 1, 1, 5, &z8002_device::ZB4_ssss_dddd }, + { 0xb500, 0xb5ff, 1, 1, 5, &z8002_device::ZB5_ssss_dddd }, + { 0xb600, 0xb6ff, 1, 1, 5, &z8002_device::ZB6_ssss_dddd }, + { 0xb700, 0xb7ff, 1, 1, 5, &z8002_device::ZB7_ssss_dddd }, + { 0xb810, 0xb8f0, 16, 2, 25, &z8002_device::ZB8_ddN0_0000_0000_rrrr_ssN0_0000 }, + { 0xb812, 0xb8f2, 16, 2, 25, &z8002_device::ZB8_ddN0_0010_0000_rrrr_ssN0_0000 }, + { 0xb814, 0xb8f4, 16, 2, 25, &z8002_device::ZB8_ddN0_0100_0000_rrrr_ssN0_0000 }, + { 0xb816, 0xb8f6, 16, 2, 25, &z8002_device::ZB8_ddN0_0110_0000_rrrr_ssN0_1110 }, + { 0xb818, 0xb8f8, 16, 2, 25, &z8002_device::ZB8_ddN0_1000_0000_rrrr_ssN0_0000 }, + { 0xb81a, 0xb8fa, 16, 2, 25, &z8002_device::ZB8_ddN0_1010_0000_rrrr_ssN0_0000 }, + { 0xb81c, 0xb8fc, 16, 2, 25, &z8002_device::ZB8_ddN0_1100_0000_rrrr_ssN0_0000 }, + { 0xb81e, 0xb8fe, 16, 2, 25, &z8002_device::ZB8_ddN0_1110_0000_rrrr_ssN0_1110 }, + { 0xb900, 0xb9ff, 16, 1, 10, &z8002_device::ZB9_imm8 }, + { 0xba10, 0xbaf0, 16, 2, 11, &z8002_device::ZBA_ssN0_0000_0000_rrrr_dddd_cccc }, + { 0xba11, 0xbaf1, 16, 2, 11, &z8002_device::ZBA_ssN0_0001_0000_rrrr_ddN0_x000 }, + { 0xba12, 0xbaf2, 16, 2, 11, &z8002_device::ZBA_ssN0_0010_0000_rrrr_ddN0_cccc }, + { 0xba14, 0xbaf4, 16, 2, 11, &z8002_device::ZBA_ssN0_0100_0000_rrrr_dddd_cccc }, + { 0xba16, 0xbaf6, 16, 2, 11, &z8002_device::ZBA_ssN0_0110_0000_rrrr_ddN0_cccc }, + { 0xba18, 0xbaf8, 16, 2, 11, &z8002_device::ZBA_ssN0_1000_0000_rrrr_dddd_cccc }, + { 0xba19, 0xbaf9, 16, 2, 11, &z8002_device::ZBA_ssN0_1001_0000_rrrr_ddN0_x000 }, + { 0xba1a, 0xbafa, 16, 2, 11, &z8002_device::ZBA_ssN0_1010_0000_rrrr_ddN0_cccc }, + { 0xba1c, 0xbafc, 16, 2, 11, &z8002_device::ZBA_ssN0_1100_0000_rrrr_dddd_cccc }, + { 0xba1e, 0xbafe, 16, 2, 11, &z8002_device::ZBA_ssN0_1110_0000_rrrr_ddN0_cccc }, + { 0xbb10, 0xbbf0, 16, 2, 11, &z8002_device::ZBB_ssN0_0000_0000_rrrr_dddd_cccc }, + { 0xbb11, 0xbbf1, 16, 2, 11, &z8002_device::ZBB_ssN0_0001_0000_rrrr_ddN0_x000 }, + { 0xbb12, 0xbbf2, 16, 2, 11, &z8002_device::ZBB_ssN0_0010_0000_rrrr_ddN0_cccc }, + { 0xbb14, 0xbbf4, 16, 2, 11, &z8002_device::ZBB_ssN0_0100_0000_rrrr_dddd_cccc }, + { 0xbb16, 0xbbf6, 16, 2, 11, &z8002_device::ZBB_ssN0_0110_0000_rrrr_ddN0_cccc }, + { 0xbb18, 0xbbf8, 16, 2, 11, &z8002_device::ZBB_ssN0_1000_0000_rrrr_dddd_cccc }, + { 0xbb19, 0xbbf9, 16, 2, 11, &z8002_device::ZBB_ssN0_1001_0000_rrrr_ddN0_x000 }, + { 0xbb1a, 0xbbfa, 16, 2, 11, &z8002_device::ZBB_ssN0_1010_0000_rrrr_ddN0_cccc }, + { 0xbb1c, 0xbbfc, 16, 2, 11, &z8002_device::ZBB_ssN0_1100_0000_rrrr_dddd_cccc }, + { 0xbb1e, 0xbbfe, 16, 2, 11, &z8002_device::ZBB_ssN0_1110_0000_rrrr_ddN0_cccc }, + { 0xbc00, 0xbcff, 1, 1, 9, &z8002_device::ZBC_aaaa_bbbb }, + { 0xbd00, 0xbdff, 1, 1, 5, &z8002_device::ZBD_dddd_imm4 }, + { 0xbe00, 0xbeff, 1, 1, 9, &z8002_device::ZBE_aaaa_bbbb }, + { 0xbf00, 0xbfff, 1, 1, 10, &z8002_device::ZBF_imm8 }, + { 0xc000, 0xcfff, 1, 1, 5, &z8002_device::ZC_dddd_imm8 }, + { 0xd000, 0xdfff, 1, 1, 10, &z8002_device::ZD_dsp12 }, + { 0xe000, 0xefff, 1, 1, 6, &z8002_device::ZE_cccc_dsp8 }, + { 0xf000, 0xf07f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf100, 0xf17f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf200, 0xf27f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf300, 0xf37f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf400, 0xf47f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf500, 0xf57f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf600, 0xf67f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf700, 0xf77f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf800, 0xf87f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf900, 0xf97f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfa00, 0xfa7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfb00, 0xfb7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfc00, 0xfc7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfd00, 0xfd7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xfe00, 0xfe7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xff00, 0xff7f, 1, 1, 11, &z8002_device::ZF_dddd_0dsp7 }, + { 0xf080, 0xf0ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf180, 0xf1ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf280, 0xf2ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf380, 0xf3ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf480, 0xf4ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf580, 0xf5ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf680, 0xf6ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf780, 0xf7ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf880, 0xf8ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xf980, 0xf9ff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfa80, 0xfaff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfb80, 0xfbff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfc80, 0xfcff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfd80, 0xfdff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xfe80, 0xfeff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0xff80, 0xffff, 1, 1, 11, &z8002_device::ZF_dddd_1dsp7 }, + { 0, 0, 0, 0, 0, nullptr }, +}; diff --git a/src/devices/imagedev/floppy.cpp b/src/devices/imagedev/floppy.cpp index 549dc4b7cbd..deaf8400aec 100644 --- a/src/devices/imagedev/floppy.cpp +++ b/src/devices/imagedev/floppy.cpp @@ -100,6 +100,9 @@ DEFINE_DEVICE_TYPE(SONY_OA_D31V, sony_oa_d31v, "sony_oa_d31v", "Sony OA-D31V Mic DEFINE_DEVICE_TYPE(SONY_OA_D32W, sony_oa_d32w, "sony_oa_d32w", "Sony OA-D32W Micro Floppydisk Drive") DEFINE_DEVICE_TYPE(SONY_OA_D32V, sony_oa_d32v, "sony_oa_d32v", "Sony OA-D32V Micro Floppydisk Drive") +// TEAC 3" drives +DEFINE_DEVICE_TYPE(TEAC_FD_30A, teac_fd_30a, "teac_fd_30a", "TEAC FD-30A FDD") + // TEAC 5.25" drives #if 0 DEFINE_DEVICE_TYPE(TEAC_FD_55A, teac_fd_55a, "teac_fd_55a", "TEAC FD-55A FDD") @@ -2151,6 +2154,39 @@ void sony_oa_d32v::handled_variants(uint32_t *variants, int &var_count) const } //------------------------------------------------- +// TEAC FD-30A +// +// track to track: 12 ms +// average: 171 ms +// setting time: 15 ms +// motor start time: 400 ms +// +//------------------------------------------------- + +teac_fd_30a::teac_fd_30a(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + floppy_image_device(mconfig, TEAC_FD_30A, tag, owner, clock) +{ +} + +teac_fd_30a::~teac_fd_30a() +{ +} + +void teac_fd_30a::setup_characteristics() +{ + form_factor = floppy_image::FF_3; + tracks = 40; + sides = 1; + set_rpm(300); +} + +void teac_fd_30a::handled_variants(uint32_t *variants, int &var_count) const +{ + var_count = 0; + variants[var_count++] = floppy_image::SSSD; +} + +//------------------------------------------------- // TEAC FD-55E // // track to track: 3 ms diff --git a/src/devices/imagedev/floppy.h b/src/devices/imagedev/floppy.h index d30b338c6e9..9e458b141cc 100644 --- a/src/devices/imagedev/floppy.h +++ b/src/devices/imagedev/floppy.h @@ -261,6 +261,7 @@ DECLARE_FLOPPY_IMAGE_DEVICE(EPSON_SD_321, epson_sd_321, "floppy_5_ DECLARE_FLOPPY_IMAGE_DEVICE(SONY_OA_D31V, sony_oa_d31v, "floppy_3_5") DECLARE_FLOPPY_IMAGE_DEVICE(SONY_OA_D32W, sony_oa_d32w, "floppy_3_5") DECLARE_FLOPPY_IMAGE_DEVICE(SONY_OA_D32V, sony_oa_d32v, "floppy_3_5") +DECLARE_FLOPPY_IMAGE_DEVICE(TEAC_FD_30A, teac_fd_30a, "floppy_3") DECLARE_FLOPPY_IMAGE_DEVICE(TEAC_FD_55E, teac_fd_55e, "floppy_5_25") DECLARE_FLOPPY_IMAGE_DEVICE(TEAC_FD_55F, teac_fd_55f, "floppy_5_25") DECLARE_FLOPPY_IMAGE_DEVICE(TEAC_FD_55G, teac_fd_55g, "floppy_5_25") diff --git a/src/devices/machine/1mb5.cpp b/src/devices/machine/1mb5.cpp index 0aa151251d2..50a3ea59365 100644 --- a/src/devices/machine/1mb5.cpp +++ b/src/devices/machine/1mb5.cpp @@ -23,19 +23,19 @@ DEFINE_DEVICE_TYPE(HP_1MB5, hp_1mb5_device, "hp_1mb5", "HP 1MB5") // Bit manipulation namespace { - static constexpr unsigned BIT_MASK(unsigned n) + template<typename T> constexpr T BIT_MASK(unsigned n) { - return 1U << n; + return (T)1U << n; } template<typename T> void BIT_CLR(T& w , unsigned n) { - w &= ~(T)BIT_MASK(n); + w &= ~BIT_MASK<T>(n); } template<typename T> void BIT_SET(T& w , unsigned n) { - w |= (T)BIT_MASK(n); + w |= BIT_MASK<T>(n); } template<typename T> void COPY_BIT(bool bit , T& w , unsigned n) diff --git a/src/devices/machine/28fxxx.cpp b/src/devices/machine/28fxxx.cpp new file mode 100644 index 00000000000..9ef279dcd44 --- /dev/null +++ b/src/devices/machine/28fxxx.cpp @@ -0,0 +1,236 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +/* + * An implementation of the 28Fxxx flash memory devices, fabricated by many + * suppliers including Intel, Atmel, AMD, SGS, TI and Toshiba. Range includes: + * + * Part Bits Org. + * ------ ----- ------ + * 28F256 256K 32Kx8 + * 28F512 512K 64Kx8 + * 28F010 1024K 128Kx8 + * 28F020 2048K 256Kx8 + * 28F040 4096K 512Kx8 + * + * These devices use a JEDEC-standard pinout allowing them to be fitted to a + * standard EPROM socket, but have their own command set which is not + * compatible with the set implemented by the intelfsh devices. It appears the + * command set used here is a variation on the one defined by JEDEC standard + * 21-C, as "dual power supply eeprom command set", in figure 3.5.1-11 on page + * 23, here: https://www.jedec.org/system/files/docs/3_05_01R14.pdf + * + * This implementation has been developed primarily against Intel's datasheet, + * with some minor adjustments to match details in the AMD equivalent. + * + * TODO + * - implement more variants + * - testing in systems other than InterPro + * + */ + +#include "emu.h" +#include "28fxxx.h" + +#define VERBOSE 0 +#include "logmacro.h" + +// manufacturer codes defined by JEDEC: https://www.jedec.org/system/files/docs/JEP106AV.pdf +enum manufacturer_codes +{ + MFG_AMD = 0x01, + MFG_INTEL = 0x89, +}; + +DEFINE_DEVICE_TYPE(INTEL_28F010, intel_28f010_device, "intel_28f010", "Intel 28F010 1024K (128K x 8) CMOS Flash Memory") +DEFINE_DEVICE_TYPE(AMD_28F010, amd_28f010_device, "amd_28f010", "Am28F010 1 Megabit (128K x 8-Bit) CMOS 12.0 Volt, Bulk Erase Flash Memory") + +ALLOW_SAVE_TYPE(base_28fxxx_device::state); + +base_28fxxx_device::base_28fxxx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 size, u8 manufacturer_code, u8 device_code) + : device_t(mconfig, type, tag, owner, clock) + , device_nvram_interface(mconfig, *this) + , m_region(*this, DEVICE_SELF) + , m_size(size) + , m_manufacturer_code(manufacturer_code) + , m_device_code(device_code) + , m_program_power(CLEAR_LINE) + , m_state(STATE_READ_MEMORY) +{ + assert_always((m_size & (m_size - 1)) == 0, "memory size must be an exact power of two"); +} + +intel_28f010_device::intel_28f010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : base_28fxxx_device(mconfig, INTEL_28F010, tag, owner, clock, 0x20000, MFG_INTEL, 0xb4) +{ +} + +amd_28f010_device::amd_28f010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : base_28fxxx_device(mconfig, AMD_28F010, tag, owner, clock, 0x20000, MFG_AMD, 0xa7) +{ +} + +void base_28fxxx_device::device_start() +{ + m_data = std::make_unique<u8[]>(m_size); + + save_item(NAME(m_program_power)); + save_pointer(NAME(m_data.get()), m_size); + + save_item(NAME(m_state)); + save_item(NAME(m_address_latch)); +} + +void base_28fxxx_device::nvram_default() +{ + if (m_region.found()) + { + u32 bytes = m_region->bytes(); + if (bytes > m_size) + bytes = m_size; + + for (offs_t offs = 0; offs < bytes; offs++) + m_data[offs] = m_region->as_u8(offs); + } + else + erase(); +} + +void base_28fxxx_device::nvram_read(emu_file &file) +{ + file.read(m_data.get(), m_size); +} + +void base_28fxxx_device::nvram_write(emu_file &file) +{ + file.write(m_data.get(), m_size); +} + +void base_28fxxx_device::erase() +{ + memset(m_data.get(), 0xff, m_size); +} + +READ8_MEMBER(base_28fxxx_device::read) +{ + switch (m_state) + { + case STATE_READ_MEMORY: + return m_data.get()[offset & (m_size - 1)]; + + case STATE_READ_IDENTIFIER: + switch (offset) + { + case 0: return m_manufacturer_code; + case 1: return m_device_code; + } + LOG("unknown read identifier offset 0x%08x (%s)\n", offset, machine().describe_context()); + return space.unmap(); + + case STATE_ERASE_VERIFY: + return m_data.get()[m_address_latch]; + + case STATE_PROGRAM_VERIFY: + return m_data.get()[m_address_latch]; + + default: + LOG("unexpected read offset 0x%08x mask 0x%08x state %d (%s)\n", offset, mem_mask, m_state, machine().describe_context()); + return space.unmap(); + } +} + +WRITE8_MEMBER(base_28fxxx_device::write) +{ + // writes are ignored unless Vpp is asserted + if (!m_program_power) + return; + + switch (m_state) + { + case STATE_ERASE_SETUP: + if (data == ERASE) + { + LOG("erase command initiated (%s)\n", machine().describe_context()); + erase(); + m_state = STATE_ERASE; + } + else if (data == RESET) + { + LOG("erase command reset (%s)\n", machine().describe_context()); + m_state = STATE_READ_MEMORY; + } + else + LOG("unexpected command 0x%02x in erase setup state (%s)\n", data, machine().describe_context()); + break; + + case STATE_ERASE: + if (data == ERASE_VERIFY) + { + m_address_latch = offset & (m_size - 1); + m_state = STATE_ERASE_VERIFY; + } + else + LOG("unexpected command 0x%02x in erase state (%s)\n", data, machine().describe_context()); + break; + + case STATE_PROGRAM_SETUP: + m_address_latch = offset & (m_size - 1); + + LOG("programming address 0x%08x data 0x%02x\n", m_address_latch, data); + + // bits can only be written from uncharged (logical 1) to charged (logical 0) state + m_data.get()[m_address_latch] &= data; + + m_state = STATE_PROGRAM; + break; + + case STATE_PROGRAM: + if (data == PROGRAM_VERIFY) + m_state = STATE_PROGRAM_VERIFY; + else if (data == RESET) + { + LOG("program command reset (%s)\n", machine().describe_context()); + + m_state = STATE_READ_MEMORY; + } + else + LOG("unexpected command 0x%02x in program state (%s)\n", data, machine().describe_context()); + break; + + default: + // start a new command + switch (data) + { + case READ_MEMORY: + m_state = STATE_READ_MEMORY; + break; + + case READ_IDENTIFIER: + case READ_IDENTIFIER_ALT: + m_state = STATE_READ_IDENTIFIER; + break; + + case ERASE: + m_state = STATE_ERASE_SETUP; + break; + + case ERASE_VERIFY: + m_address_latch = offset & (m_size - 1); + m_state = STATE_ERASE_VERIFY; + break; + + case PROGRAM: + m_state = STATE_PROGRAM_SETUP; + break; + + case RESET: + m_state = STATE_READ_MEMORY; + break; + + default: + LOG("unexpected command 0x%02x in state %d (%s)\n", data, m_state, machine().describe_context()); + break; + } + break; + } +} diff --git a/src/devices/machine/28fxxx.h b/src/devices/machine/28fxxx.h new file mode 100644 index 00000000000..313cda82873 --- /dev/null +++ b/src/devices/machine/28fxxx.h @@ -0,0 +1,84 @@ +// license:BSD-3-Clause +// copyright-holders:Patrick Mackinlay + +#ifndef MAME_MACHINE_28FXXX_H +#define MAME_MACHINE_28FXXX_H + +#pragma once + +class base_28fxxx_device : public device_t, public device_nvram_interface +{ +public: + enum commands + { + READ_MEMORY = 0x00, + ERASE = 0x20, + PROGRAM = 0x40, + READ_IDENTIFIER_ALT = 0x80, // defined in AMD datasheet, but not Intel + READ_IDENTIFIER = 0x90, + ERASE_VERIFY = 0xa0, + PROGRAM_VERIFY = 0xc0, + RESET = 0xff + }; + + DECLARE_WRITE_LINE_MEMBER(vpp) { m_program_power = state; } + DECLARE_READ8_MEMBER(read); + DECLARE_WRITE8_MEMBER(write); + +protected: + base_28fxxx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 size, u8 manufacturer_code, u8 device_code); + + virtual void device_start() override; + + virtual void nvram_default() override; + virtual void nvram_read(emu_file &file) override; + virtual void nvram_write(emu_file &file) override; + + optional_memory_region m_region; + +private: + void erase(); + + // device specific parameters + const u32 m_size; + const u8 m_manufacturer_code; + const u8 m_device_code; + + // accessible device state + int m_program_power; + std::unique_ptr<u8[]> m_data; + + // internal state + enum state : u8 + { + STATE_READ_MEMORY, + STATE_READ_IDENTIFIER, + STATE_ERASE_SETUP, + STATE_ERASE, + STATE_ERASE_RESET, + STATE_ERASE_VERIFY, + STATE_PROGRAM_SETUP, + STATE_PROGRAM, + STATE_PROGRAM_VERIFY + }; + state m_state; + + u32 m_address_latch; +}; + +class intel_28f010_device : public base_28fxxx_device +{ +public: + intel_28f010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +class amd_28f010_device : public base_28fxxx_device +{ +public: + amd_28f010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); +}; + +DECLARE_DEVICE_TYPE(INTEL_28F010, intel_28f010_device) +DECLARE_DEVICE_TYPE(AMD_28F010, amd_28f010_device) + +#endif // MAME_MACHINE_28FXXX_H diff --git a/src/devices/machine/68307.cpp b/src/devices/machine/68307.cpp index 64e52ebb295..adc65ce199b 100644 --- a/src/devices/machine/68307.cpp +++ b/src/devices/machine/68307.cpp @@ -44,7 +44,7 @@ ADDRESS_MAP_END MACHINE_CONFIG_MEMBER( m68307_cpu_device::device_add_mconfig ) - MCFG_MC68681_ADD("internal68681", 16000000/4) // ?? Mhz - should be specified in inline config + MCFG_DEVICE_ADD("internal68681", MC68681, 16000000/4) // ?? Mhz - should be specified in inline config MCFG_MC68681_IRQ_CALLBACK(WRITELINE(m68307_cpu_device, m68307_duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(WRITELINE(m68307_cpu_device, m68307_duart_txa)) MCFG_MC68681_B_TX_CALLBACK(WRITELINE(m68307_cpu_device, m68307_duart_txb)) @@ -158,7 +158,7 @@ void m68307_cpu_device::write_dword_m68307(offs_t address, uint32_t data) void m68307_cpu_device::init16_m68307(address_space &space) { m_space = &space; - m_direct = &space.direct(); + m_direct = space.direct<0>(); opcode_xor = 0; readimm16 = m68k_readimm16_delegate(&m68307_cpu_device::simple_read_immediate_16_m68307, this); diff --git a/src/devices/machine/68307.h b/src/devices/machine/68307.h index 3ed993ea3f7..a64c9985ce9 100644 --- a/src/devices/machine/68307.h +++ b/src/devices/machine/68307.h @@ -77,9 +77,6 @@ protected: virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; - virtual uint32_t disasm_min_opcode_bytes() const override { return 2; } - virtual uint32_t disasm_max_opcode_bytes() const override { return 10; } - virtual uint32_t execute_min_cycles() const override { return 4; } virtual uint32_t execute_max_cycles() const override { return 158; } diff --git a/src/devices/machine/6850acia.cpp b/src/devices/machine/6850acia.cpp index ccbda9e9878..0671dd04ecc 100644 --- a/src/devices/machine/6850acia.cpp +++ b/src/devices/machine/6850acia.cpp @@ -277,6 +277,19 @@ READ8_MEMBER( acia6850_device::data_r ) return m_rdr; } +WRITE8_MEMBER( acia6850_device::write ) +{ + if (BIT(offset, 0)) + data_w(space, 0, data); + else + control_w(space, 0, data); +} + +READ8_MEMBER( acia6850_device::read ) +{ + return BIT(offset, 0) ? data_r(space, 0) : status_r(space, 0); +} + DECLARE_WRITE_LINE_MEMBER( acia6850_device::write_cts ) { if (state) diff --git a/src/devices/machine/6850acia.h b/src/devices/machine/6850acia.h index 8ec75cf5e6e..119dc330ceb 100644 --- a/src/devices/machine/6850acia.h +++ b/src/devices/machine/6850acia.h @@ -38,6 +38,8 @@ public: DECLARE_READ8_MEMBER( status_r ); DECLARE_WRITE8_MEMBER( data_w ); DECLARE_READ8_MEMBER( data_r ); + DECLARE_WRITE8_MEMBER( write ); + DECLARE_READ8_MEMBER( read ); DECLARE_WRITE_LINE_MEMBER( write_cts ); DECLARE_WRITE_LINE_MEMBER( write_dcd ); diff --git a/src/devices/machine/68561mpcc.cpp b/src/devices/machine/68561mpcc.cpp index 3f500827cdf..8b93885ffc2 100644 --- a/src/devices/machine/68561mpcc.cpp +++ b/src/devices/machine/68561mpcc.cpp @@ -587,7 +587,7 @@ void mpcc_device::tra_complete() } //------------------------------------------------- -// rcv_callback - called when it is time to sample incomming data bit +// rcv_callback - called when it is time to sample incoming data bit //------------------------------------------------- void mpcc_device::rcv_callback() { diff --git a/src/devices/machine/74123.cpp b/src/devices/machine/74123.cpp index 5efb34ec085..6596bf58bf3 100644 --- a/src/devices/machine/74123.cpp +++ b/src/devices/machine/74123.cpp @@ -121,7 +121,7 @@ int ttl74123_device::timer_running() TIMER_CALLBACK_MEMBER( ttl74123_device::output_callback ) { - m_output_changed_cb((offs_t)0, param); + m_output_changed_cb(param); } @@ -147,7 +147,7 @@ TIMER_CALLBACK_MEMBER( ttl74123_device::clear_callback ) { int output = timer_running(); - m_output_changed_cb((offs_t)0, output); + m_output_changed_cb(output); } //------------------------------------------------- @@ -190,15 +190,15 @@ void ttl74123_device::start_pulse() // a_w - write register a data //------------------------------------------------- -WRITE8_MEMBER( ttl74123_device::a_w ) +WRITE_LINE_MEMBER( ttl74123_device::a_w ) { /* start/regtrigger pulse if B=HI and falling edge on A (while clear is HI) */ - if (!data && m_a && m_b && m_clear) + if (!state && m_a && m_b && m_clear) { start_pulse(); } - m_a = data; + m_a = state; } @@ -206,15 +206,15 @@ WRITE8_MEMBER( ttl74123_device::a_w ) // b_w - write register b data //------------------------------------------------- -WRITE8_MEMBER( ttl74123_device::b_w) +WRITE_LINE_MEMBER( ttl74123_device::b_w) { /* start/regtrigger pulse if A=LO and rising edge on B (while clear is HI) */ - if (data && !m_b && !m_a && m_clear) + if (state && !m_b && !m_a && m_clear) { start_pulse(); } - m_b = data; + m_b = state; } @@ -222,20 +222,20 @@ WRITE8_MEMBER( ttl74123_device::b_w) // clear_w - write register clear data //------------------------------------------------- -WRITE8_MEMBER( ttl74123_device::clear_w) +WRITE_LINE_MEMBER( ttl74123_device::clear_w) { /* start/regtrigger pulse if B=HI and A=LO and rising edge on clear */ - if (data && !m_a && m_b && !m_clear) + if (state && !m_a && m_b && !m_clear) { start_pulse(); } - else if (!data) /* clear the output */ + else if (!state) /* clear the output */ { m_timer->adjust(attotime::zero); LOG("74123: Cleared\n"); } - m_clear = data; + m_clear = state; } @@ -243,7 +243,7 @@ WRITE8_MEMBER( ttl74123_device::clear_w) // reset_w - reset device //------------------------------------------------- -WRITE8_MEMBER( ttl74123_device::reset_w) +WRITE_LINE_MEMBER( ttl74123_device::reset_w) { set_output(); } diff --git a/src/devices/machine/74123.h b/src/devices/machine/74123.h index 0da73384cef..1316249070b 100644 --- a/src/devices/machine/74123.h +++ b/src/devices/machine/74123.h @@ -105,10 +105,10 @@ public: static void set_clear_pin_value(device_t &device, int value) { downcast<ttl74123_device &>(device).m_clear = value; } template <class Object> static devcb_base &set_output_changed_callback(device_t &device, Object &&cb) { return downcast<ttl74123_device &>(device).m_output_changed_cb.set_callback(std::forward<Object>(cb)); } - DECLARE_WRITE8_MEMBER(a_w); - DECLARE_WRITE8_MEMBER(b_w); - DECLARE_WRITE8_MEMBER(clear_w); - DECLARE_WRITE8_MEMBER(reset_w); + DECLARE_WRITE_LINE_MEMBER(a_w); + DECLARE_WRITE_LINE_MEMBER(b_w); + DECLARE_WRITE_LINE_MEMBER(clear_w); + DECLARE_WRITE_LINE_MEMBER(reset_w); protected: // device-level overrides @@ -133,7 +133,7 @@ private: int m_a; /* initial/constant value of the A pin */ int m_b; /* initial/constant value of the B pin */ int m_clear; /* initial/constant value of the Clear pin */ - devcb_write8 m_output_changed_cb; + devcb_write_line m_output_changed_cb; }; diff --git a/src/devices/machine/adc083x.cpp b/src/devices/machine/adc083x.cpp index 317e2dbb18a..26323a1d146 100644 --- a/src/devices/machine/adc083x.cpp +++ b/src/devices/machine/adc083x.cpp @@ -46,10 +46,10 @@ enum TYPE DEFINITIONS ***************************************************************************/ -DEFINE_DEVICE_TYPE(ADC0831, adc0831_device, "adc0831", "ADC0831") -DEFINE_DEVICE_TYPE(ADC0832, adc0832_device, "adc0832", "ADC0832") -DEFINE_DEVICE_TYPE(ADC0834, adc0834_device, "adc0834", "ADC0834") -DEFINE_DEVICE_TYPE(ADC0838, adc0838_device, "adc0838", "ADC0838") +DEFINE_DEVICE_TYPE(ADC0831, adc0831_device, "adc0831", "ADC0831 A/D Converter") +DEFINE_DEVICE_TYPE(ADC0832, adc0832_device, "adc0832", "ADC0832 A/D Converter") +DEFINE_DEVICE_TYPE(ADC0834, adc0834_device, "adc0834", "ADC0834 A/D Converter") +DEFINE_DEVICE_TYPE(ADC0838, adc0838_device, "adc0838", "ADC0838 A/D Converter") adc083x_device::adc083x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t mux_bits) : device_t(mconfig, type, tag, owner, clock), diff --git a/src/devices/machine/adc0844.cpp b/src/devices/machine/adc0844.cpp new file mode 100644 index 00000000000..103702a8d14 --- /dev/null +++ b/src/devices/machine/adc0844.cpp @@ -0,0 +1,208 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + ADC0844/ADC0848 + + A/D Converter With Multiplexer Options + +***************************************************************************/ + +#include "emu.h" +#include "adc0844.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(ADC0844, adc0844_device, "adc0844", "ADC0844 A/D Converter") +DEFINE_DEVICE_TYPE(ADC0848, adc0848_device, "adc0848", "ADC0848 A/D Converter") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// adc0844_device - constructor +//------------------------------------------------- + +adc0844_device::adc0844_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + m_intr_cb(*this), + m_ch1_cb(*this), m_ch2_cb(*this), m_ch3_cb(*this), m_ch4_cb(*this), + m_conversion_timer(nullptr), + m_channel(0x0f), + m_result(0xff) +{ +} + +adc0844_device::adc0844_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + adc0844_device(mconfig, ADC0844, tag, owner, clock) +{ +} + +//------------------------------------------------- +// adc0848_device - constructor +//------------------------------------------------- + +adc0848_device::adc0848_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + adc0844_device(mconfig, ADC0848, tag, owner, clock), + m_ch5_cb(*this), m_ch6_cb(*this), m_ch7_cb(*this), m_ch8_cb(*this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void adc0844_device::device_start() +{ + // resolve callbacks + m_intr_cb.resolve_safe(); + m_ch1_cb.resolve_safe(0xff); + m_ch2_cb.resolve_safe(0xff); + m_ch3_cb.resolve_safe(0xff); + m_ch4_cb.resolve_safe(0xff); + + // allocate timers + m_conversion_timer = timer_alloc(); + + // register for save states + save_item(NAME(m_channel)); + save_item(NAME(m_result)); +} + +void adc0848_device::device_start() +{ + adc0844_device::device_start(); + + // resolve callbacks + m_ch5_cb.resolve_safe(0xff); + m_ch6_cb.resolve_safe(0xff); + m_ch7_cb.resolve_safe(0xff); + m_ch8_cb.resolve_safe(0xff); +} + +//------------------------------------------------- +// clamp - restrict value to 0..255 +//------------------------------------------------- + +uint8_t adc0844_device::clamp(int value) +{ + if (value > 0xff) + return 0xff; + else if (value < 0) + return 0x00; + else + return value; +} + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void adc0844_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (m_channel) + { + // differential + case 0x00: + case 0x08: m_result = clamp(0xff - (m_ch2_cb(0) - m_ch1_cb(0))); break; + case 0x01: + case 0x09: m_result = clamp(0xff - (m_ch1_cb(0) - m_ch2_cb(0))); break; + case 0x02: + case 0x0a: m_result = clamp(0xff - (m_ch4_cb(0) - m_ch3_cb(0))); break; + case 0x03: + case 0x0b: m_result = clamp(0xff - (m_ch3_cb(0) - m_ch4_cb(0))); break; + // single-ended + case 0x04: m_result = m_ch1_cb(0); break; + case 0x05: m_result = m_ch2_cb(0); break; + case 0x06: m_result = m_ch3_cb(0); break; + case 0x07: m_result = m_ch4_cb(0); break; + // pseudo-differential + case 0x0c: m_result = clamp(0xff - (m_ch4_cb(0) - m_ch1_cb(0))); break; + case 0x0d: m_result = clamp(0xff - (m_ch4_cb(0) - m_ch2_cb(0))); break; + case 0x0e: m_result = clamp(0xff - (m_ch4_cb(0) - m_ch3_cb(0))); break; + // undefined + case 0x0f: m_result = 0x00; break; + } + + m_intr_cb(ASSERT_LINE); +} + +void adc0848_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (m_channel) + { + // differential + case 0x00: + case 0x10: m_result = clamp(0xff - (m_ch2_cb(0) - m_ch1_cb(0))); break; + case 0x01: + case 0x11: m_result = clamp(0xff - (m_ch1_cb(0) - m_ch2_cb(0))); break; + case 0x02: + case 0x12: m_result = clamp(0xff - (m_ch4_cb(0) - m_ch3_cb(0))); break; + case 0x03: + case 0x13: m_result = clamp(0xff - (m_ch3_cb(0) - m_ch4_cb(0))); break; + case 0x04: + case 0x14: m_result = clamp(0xff - (m_ch6_cb(0) - m_ch5_cb(0))); break; + case 0x05: + case 0x15: m_result = clamp(0xff - (m_ch5_cb(0) - m_ch6_cb(0))); break; + case 0x06: + case 0x16: m_result = clamp(0xff - (m_ch8_cb(0) - m_ch7_cb(0))); break; + case 0x07: + case 0x17: m_result = clamp(0xff - (m_ch7_cb(0) - m_ch8_cb(0))); break; + // single-ended + case 0x08: m_result = m_ch1_cb(0); break; + case 0x09: m_result = m_ch2_cb(0); break; + case 0x0a: m_result = m_ch3_cb(0); break; + case 0x0b: m_result = m_ch4_cb(0); break; + case 0x0c: m_result = m_ch5_cb(0); break; + case 0x0d: m_result = m_ch6_cb(0); break; + case 0x0e: m_result = m_ch7_cb(0); break; + case 0x0f: m_result = m_ch8_cb(0); break; + // pseudo-differential + case 0x18: m_result = clamp(0xff - (m_ch8_cb(0) - m_ch1_cb(0))); break; + case 0x19: m_result = clamp(0xff - (m_ch8_cb(0) - m_ch2_cb(0))); break; + case 0x1a: m_result = clamp(0xff - (m_ch8_cb(0) - m_ch3_cb(0))); break; + case 0x1b: m_result = clamp(0xff - (m_ch8_cb(0) - m_ch4_cb(0))); break; + case 0x1c: m_result = clamp(0xff - (m_ch8_cb(0) - m_ch5_cb(0))); break; + case 0x1d: m_result = clamp(0xff - (m_ch8_cb(0) - m_ch6_cb(0))); break; + case 0x1e: m_result = clamp(0xff - (m_ch8_cb(0) - m_ch7_cb(0))); break; + // undefined + case 0x1f: m_result = 0x00; break; + } + + m_intr_cb(ASSERT_LINE); +} + + +//************************************************************************** +// INTERFACE +//************************************************************************** + +READ8_MEMBER( adc0844_device::read ) +{ + m_intr_cb(CLEAR_LINE); + + return m_result; +} + +WRITE8_MEMBER( adc0844_device::write ) +{ + m_intr_cb(CLEAR_LINE); + + // set channel and start conversion + m_channel = data & 0x0f; + m_conversion_timer->adjust(attotime::from_usec(40)); +} + +WRITE8_MEMBER( adc0848_device::write ) +{ + m_intr_cb(CLEAR_LINE); + + // set channel and start conversion + m_channel = data & 0x1f; + m_conversion_timer->adjust(attotime::from_usec(40)); +} diff --git a/src/devices/machine/adc0844.h b/src/devices/machine/adc0844.h new file mode 100644 index 00000000000..404a4cfa7a4 --- /dev/null +++ b/src/devices/machine/adc0844.h @@ -0,0 +1,156 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + ADC0844 + + A/D Converter With Multiplexer Options + + ___ ___ + /RD 1 |* u | 20 VCC + /CS 2 | | 19 /WR + CH1 3 | | 18 /INTR + CH2 4 | | 17 DB0/MA0 + CH3 5 | | 16 DB1/MA1 + CH4 6 | | 15 DB2/MA2 + AGND 7 | | 14 DB3/MA3 + VREF 8 | | 13 DB4 + DB7 9 | | 12 DB5 + DGND 10 |_______| 11 DB6 + +***************************************************************************/ + +#ifndef MAME_DEVICES_MACHINE_ADC0844_H +#define MAME_DEVICES_MACHINE_ADC0844_H + +#pragma once + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_ADC0844_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, ADC0844, 0) + +#define MCFG_ADC0844_INTR_CB(_devcb) \ + devcb = &adc0844_device::set_intr_callback(*device, DEVCB_##_devcb); + +#define MCFG_ADC0844_CH1_CB(_devcb) \ + devcb = &adc0844_device::set_ch1_callback(*device, DEVCB_##_devcb); + +#define MCFG_ADC0844_CH2_CB(_devcb) \ + devcb = &adc0844_device::set_ch2_callback(*device, DEVCB_##_devcb); + +#define MCFG_ADC0844_CH3_CB(_devcb) \ + devcb = &adc0844_device::set_ch3_callback(*device, DEVCB_##_devcb); + +#define MCFG_ADC0844_CH4_CB(_devcb) \ + devcb = &adc0844_device::set_ch4_callback(*device, DEVCB_##_devcb); + +#define MCFG_ADC0848_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, ADC0848, 0) + +#define MCFG_ADC0848_INTR_CB MCFG_ADC0844_INTR_CB +#define MCFG_ADC0848_CH1_CB MCFG_ADC0844_CH1_CB +#define MCFG_ADC0848_CH2_CB MCFG_ADC0844_CH2_CB +#define MCFG_ADC0848_CH3_CB MCFG_ADC0844_CH3_CB +#define MCFG_ADC0848_CH4_CB MCFG_ADC0844_CH4_CB + +#define MCFG_ADC0848_CH5_CB(_devcb) \ + devcb = &adc0848_device::set_ch5_callback(*device, DEVCB_##_devcb); + +#define MCFG_ADC0848_CH6_CB(_devcb) \ + devcb = &adc0848_device::set_ch6_callback(*device, DEVCB_##_devcb); + +#define MCFG_ADC0848_CH7_CB(_devcb) \ + devcb = &adc0848_device::set_ch7_callback(*device, DEVCB_##_devcb); + +#define MCFG_ADC0848_CH8_CB(_devcb) \ + devcb = &adc0848_device::set_ch8_callback(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class adc0844_device : public device_t +{ +public: + // construction/destruction + adc0844_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // configuration + template <class Object> static devcb_base &set_intr_callback(device_t &device, Object &&cb) + { return downcast<adc0844_device &>(device).m_intr_cb.set_callback(std::forward<Object>(cb)); } + + template <class Object> static devcb_base &set_ch1_callback(device_t &device, Object &&cb) + { return downcast<adc0844_device &>(device).m_ch1_cb.set_callback(std::forward<Object>(cb)); } + + template <class Object> static devcb_base &set_ch2_callback(device_t &device, Object &&cb) + { return downcast<adc0844_device &>(device).m_ch2_cb.set_callback(std::forward<Object>(cb)); } + + template <class Object> static devcb_base &set_ch3_callback(device_t &device, Object &&cb) + { return downcast<adc0844_device &>(device).m_ch3_cb.set_callback(std::forward<Object>(cb)); } + + template <class Object> static devcb_base &set_ch4_callback(device_t &device, Object &&cb) + { return downcast<adc0844_device &>(device).m_ch4_cb.set_callback(std::forward<Object>(cb)); } + + DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); + +protected: + adc0844_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + + uint8_t clamp(int value); + + // callbacks + devcb_write_line m_intr_cb; + devcb_read8 m_ch1_cb, m_ch2_cb, m_ch3_cb, m_ch4_cb; + + emu_timer *m_conversion_timer; + + // state + int m_channel; + uint8_t m_result; +}; + +class adc0848_device : public adc0844_device +{ +public: + // construction/destruction + adc0848_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // configuration + template <class Object> static devcb_base &set_ch5_callback(device_t &device, Object &&cb) + { return downcast<adc0848_device &>(device).m_ch5_cb.set_callback(std::forward<Object>(cb)); } + + template <class Object> static devcb_base &set_ch6_callback(device_t &device, Object &&cb) + { return downcast<adc0848_device &>(device).m_ch6_cb.set_callback(std::forward<Object>(cb)); } + + template <class Object> static devcb_base &set_ch7_callback(device_t &device, Object &&cb) + { return downcast<adc0848_device &>(device).m_ch7_cb.set_callback(std::forward<Object>(cb)); } + + template <class Object> static devcb_base &set_ch8_callback(device_t &device, Object &&cb) + { return downcast<adc0848_device &>(device).m_ch8_cb.set_callback(std::forward<Object>(cb)); } + + virtual DECLARE_WRITE8_MEMBER(write) override; + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +private: + devcb_read8 m_ch5_cb, m_ch6_cb, m_ch7_cb, m_ch8_cb; +}; + +// device type definition +DECLARE_DEVICE_TYPE(ADC0844, adc0844_device) +DECLARE_DEVICE_TYPE(ADC0848, adc0848_device) + +#endif // MAME_DEVICES_MACHINE_ADC0844_H diff --git a/src/devices/machine/atmel_arm_aic.cpp b/src/devices/machine/atmel_arm_aic.cpp new file mode 100644 index 00000000000..27c2dcbb826 --- /dev/null +++ b/src/devices/machine/atmel_arm_aic.cpp @@ -0,0 +1,93 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +/* + ARM AIC (Advanced Interrupt Controller) from Atmel + typically integrated into the AM91SAM series of chips + + see http://sam7-ex256.narod.ru/include/HTML/AT91SAM7X256_AIC.html + current implementation only handles basics needed for pgm2 (pgm2.cpp) + if this peripheral is not available as a standalone chip it could also be moved to + the CPU folder alongside the ARM instead +*/ + +#include "emu.h" +#include "atmel_arm_aic.h" + +DEFINE_DEVICE_TYPE(ARM_AIC, arm_aic_device, "arm_aic", "ARM Advanced Interrupt Controller") + + +DEVICE_ADDRESS_MAP_START( regs_map, 32, arm_aic_device ) + AM_RANGE(0x000, 0x07f) AM_READWRITE(aic_smr_r, aic_smr_w) // AIC_SMR[32] (AIC_SMR) Source Mode Register + AM_RANGE(0x080, 0x0ff) AM_READWRITE(aic_svr_r, aic_svr_w) // AIC_SVR[32] (AIC_SVR) Source Vector Register + AM_RANGE(0x100, 0x103) AM_READ(irq_vector_r) // AIC_IVR IRQ Vector Register + AM_RANGE(0x104, 0x107) AM_READ(firq_vector_r) // AIC_FVR FIQ Vector Register +// 0x108 AIC_ISR Interrupt Status Register +// 0x10C AIC_IPR Interrupt Pending Register +// 0x110 AIC_IMR Interrupt Mask Register +// 0x114 AIC_CISR Core Interrupt Status Register + AM_RANGE(0x120, 0x123) AM_WRITE(aic_iecr_w) // 0x120 AIC_IECR Interrupt Enable Command Register + AM_RANGE(0x124, 0x127) AM_WRITE(aic_idcr_w) // 0x124 AIC_IDCR Interrupt Disable Command Register + AM_RANGE(0x128, 0x12b) AM_WRITE(aic_iccr_w) // 0x128 AIC_ICCR Interrupt Clear Command Register +// 0x12C AIC_ISCR Interrupt Set Command Register + AM_RANGE(0x130, 0x133) AM_WRITE(aic_eoicr_w) // 0x130 AIC_EOICR End of Interrupt Command Register +// 0x134 AIC_SPU Spurious Vector Register +// 0x138 AIC_DCR Debug Control Register (Protect) +// 0x140 AIC_FFER Fast Forcing Enable Register +// 0x144 AIC_FFDR Fast Forcing Disable Register +// 0x148 AIC_FFSR Fast Forcing Status Register +ADDRESS_MAP_END + +READ32_MEMBER(arm_aic_device::irq_vector_r) +{ + return m_current_irq_vector; +} + +READ32_MEMBER(arm_aic_device::firq_vector_r) +{ + return m_current_firq_vector; +} + +void arm_aic_device::device_start() +{ + m_irq_out.resolve_safe(); + + save_item(NAME(m_irqs_enabled)); + save_item(NAME(m_current_irq_vector)); + save_item(NAME(m_current_firq_vector)); + + save_item(NAME(m_aic_smr)); + save_item(NAME(m_aic_svr)); +} + +void arm_aic_device::device_reset() +{ + m_irqs_enabled = 0; + m_current_irq_vector = 0; + m_current_firq_vector = 0; + + for(auto & elem : m_aic_smr) { elem = 0; } + for(auto & elem : m_aic_svr) { elem = 0; } +} + +void arm_aic_device::set_irq(int identity) +{ + for (int i = 0;i < 32;i++) + { + if (m_aic_smr[i] == identity) + { + if ((m_irqs_enabled >> i) & 1) + { + m_current_irq_vector = m_aic_svr[i]; + m_irq_out(ASSERT_LINE); + return; + } + } + } +} + +WRITE32_MEMBER(arm_aic_device::aic_iccr_w) +{ + //logerror("%s: aic_iccr_w %08x (Interrupt Clear Command Register)\n", machine().describe_context().c_str(), data); + m_irq_out(CLEAR_LINE); +}; diff --git a/src/devices/machine/atmel_arm_aic.h b/src/devices/machine/atmel_arm_aic.h new file mode 100644 index 00000000000..101c57cc672 --- /dev/null +++ b/src/devices/machine/atmel_arm_aic.h @@ -0,0 +1,63 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#ifndef MAME_MACHINE_ATMEL_ARM_AIC_H +#define MAME_MACHINE_ATMEL_ARM_AIC_H + +#pragma once + +DECLARE_DEVICE_TYPE(ARM_AIC, arm_aic_device) + +#define MCFG_ARM_AIC_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, ARM_AIC, 0) + +#define MCFG_IRQ_LINE_CB(_devcb) \ + devcb = &arm_aic_device::set_line_callback(*device, DEVCB_##_devcb); + +class arm_aic_device : public device_t +{ +public: + // construction/destruction + arm_aic_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, ARM_AIC, tag, owner, clock), + m_irq_out(*this) + { + } + + // configuration + template <class Object> static devcb_base &set_line_callback(device_t &device, Object &&cb) { return downcast<arm_aic_device &>(device).m_irq_out.set_callback(std::forward<Object>(cb)); } + + DECLARE_ADDRESS_MAP(regs_map, 32); + + DECLARE_READ32_MEMBER(irq_vector_r); + DECLARE_READ32_MEMBER(firq_vector_r); + + // can't use AM_RAM and AM_SHARE in device submaps + DECLARE_READ32_MEMBER(aic_smr_r) { return m_aic_smr[offset]; }; + DECLARE_READ32_MEMBER(aic_svr_r) { return m_aic_svr[offset]; }; + DECLARE_WRITE32_MEMBER(aic_smr_w) { COMBINE_DATA(&m_aic_smr[offset]); }; + DECLARE_WRITE32_MEMBER(aic_svr_w) { COMBINE_DATA(&m_aic_svr[offset]); }; + + DECLARE_WRITE32_MEMBER(aic_iecr_w) { /*logerror("%s: aic_iecr_w %08x (Interrupt Enable Command Register)\n", machine().describe_context().c_str(), data);*/ COMBINE_DATA(&m_irqs_enabled); }; + DECLARE_WRITE32_MEMBER(aic_idcr_w) { /*logerror("%s: aic_idcr_w %08x (Interrupt Disable Command Register)\n", machine().describe_context().c_str(), data);*/ }; + DECLARE_WRITE32_MEMBER(aic_iccr_w); + DECLARE_WRITE32_MEMBER(aic_eoicr_w){ /*logerror("%s: aic_eoicr_w (End of Interrupt Command Register)\n", machine().describe_context().c_str());*/ }; // value doesn't matter + + void set_irq(int identity); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + uint32_t m_irqs_enabled; + uint32_t m_current_irq_vector; + uint32_t m_current_firq_vector; + + uint32_t m_aic_smr[32]; + uint32_t m_aic_svr[32]; + + devcb_write_line m_irq_out; +}; + +#endif diff --git a/src/devices/machine/ay31015.cpp b/src/devices/machine/ay31015.cpp index 4e3e96312a8..30dd0164e60 100644 --- a/src/devices/machine/ay31015.cpp +++ b/src/devices/machine/ay31015.cpp @@ -8,8 +8,9 @@ and AY-6-1013 UARTs (Universal Asynchronous Receiver/Transmitters). Compatible UARTs were produced by Harris (HD6402), TI (TMS6011), - Western Digital (TR1602/TR1402/TR1863/TR1865), AMI (S1883), Standard - Microsystems (COM2502/COM2017), Tesla (MHB1012) and other companies. + Western Digital (TR1602/TR1402/TR1863/TR1865), AMI (S1883), Signetics + (2536), National (MM5303), Standard Microsystems (COM2502/COM2017), + Tesla (MHB1012) and other companies. This is cycle-accurate according to the specifications. diff --git a/src/devices/machine/bankdev.cpp b/src/devices/machine/bankdev.cpp index 7abd6e9f5c2..c9b2c5fcfe5 100644 --- a/src/devices/machine/bankdev.cpp +++ b/src/devices/machine/bankdev.cpp @@ -10,8 +10,8 @@ address_map_bank_device::address_map_bank_device( const machine_config &mconfig, : device_t(mconfig, ADDRESS_MAP_BANK, tag, owner, clock), device_memory_interface(mconfig, *this), m_endianness(ENDIANNESS_NATIVE), - m_databus_width(0), - m_addrbus_width(32), + m_data_width(0), + m_addr_width(32), m_stride(1), m_program(nullptr), m_offset(0) @@ -83,7 +83,7 @@ READ64_MEMBER(address_map_bank_device::read64) void address_map_bank_device::device_config_complete() { - m_program_config = address_space_config( "program", m_endianness, m_databus_width, m_addrbus_width ); + m_program_config = address_space_config( "program", m_endianness, m_data_width, m_addr_width ); } void address_map_bank_device::device_start() diff --git a/src/devices/machine/bankdev.h b/src/devices/machine/bankdev.h index c51c46bc686..6c6e036aaa5 100644 --- a/src/devices/machine/bankdev.h +++ b/src/devices/machine/bankdev.h @@ -9,11 +9,11 @@ #define MCFG_ADDRESS_MAP_BANK_ENDIANNESS(_endianness) \ address_map_bank_device::set_endianness(*device, _endianness); -#define MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(_databus_width) \ - address_map_bank_device::set_databus_width(*device, _databus_width); +#define MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(_data_width) \ + address_map_bank_device::set_data_width(*device, _data_width); -#define MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(_addrbus_width) \ - address_map_bank_device::set_addrbus_width(*device, _addrbus_width); +#define MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(_addr_width) \ + address_map_bank_device::set_addr_width(*device, _addr_width); #define MCFG_ADDRESS_MAP_BANK_STRIDE(_stride) \ address_map_bank_device::set_stride(*device, _stride); @@ -28,8 +28,8 @@ public: // static configuration helpers static void set_endianness(device_t &device, endianness_t endianness) { downcast<address_map_bank_device &>(device).m_endianness = endianness; } - static void set_databus_width(device_t &device, uint8_t databus_width) { downcast<address_map_bank_device &>(device).m_databus_width = databus_width; } - static void set_addrbus_width(device_t &device, uint8_t addrbus_width) { downcast<address_map_bank_device &>(device).m_addrbus_width = addrbus_width; } + static void set_data_width(device_t &device, uint8_t data_width) { downcast<address_map_bank_device &>(device).m_data_width = data_width; } + static void set_addr_width(device_t &device, uint8_t addr_width) { downcast<address_map_bank_device &>(device).m_addr_width = addr_width; } static void set_stride(device_t &device, uint32_t stride) { downcast<address_map_bank_device &>(device).m_stride = stride; } DECLARE_ADDRESS_MAP(amap8, 8); @@ -59,8 +59,8 @@ protected: private: // internal state endianness_t m_endianness; - uint8_t m_databus_width; - uint8_t m_addrbus_width; + uint8_t m_data_width; + uint8_t m_addr_width; uint32_t m_stride; address_space_config m_program_config; address_space *m_program; diff --git a/src/devices/machine/cdp1852.h b/src/devices/machine/cdp1852.h index d017aaa2482..ba63cd2efb8 100644 --- a/src/devices/machine/cdp1852.h +++ b/src/devices/machine/cdp1852.h @@ -67,6 +67,8 @@ public: DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); + uint8_t do_r() { return m_data; } + protected: // device-level overrides virtual void device_start() override; diff --git a/src/devices/machine/ds1204.cpp b/src/devices/machine/ds1204.cpp index 17ff81b8c0b..cd722bc8929 100644 --- a/src/devices/machine/ds1204.cpp +++ b/src/devices/machine/ds1204.cpp @@ -29,7 +29,7 @@ inline void ATTR_PRINTF( 3, 4 ) ds1204_device::verboselog( int n_level, const ch } // device type definition -DEFINE_DEVICE_TYPE(DS1204, ds1204_device, "ds1204", "DS1204") +DEFINE_DEVICE_TYPE(DS1204, ds1204_device, "ds1204", "DS1204 Electronic Key") ds1204_device::ds1204_device( const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock ) : device_t(mconfig, DS1204, tag, owner, clock), diff --git a/src/devices/machine/ds128x.cpp b/src/devices/machine/ds128x.cpp index 7c824aba638..7a397aab303 100644 --- a/src/devices/machine/ds128x.cpp +++ b/src/devices/machine/ds128x.cpp @@ -3,8 +3,6 @@ #include "emu.h" #include "ds128x.h" -/// TODO: Only DV2/DV1/DV0 == 0/1/0 is supported as the chip only has a 15 stage divider and not 22. - DEFINE_DEVICE_TYPE(DS12885, ds12885_device, "ds12885", "DS12885 RTC/NVRAM") //------------------------------------------------- @@ -15,3 +13,13 @@ ds12885_device::ds12885_device(const machine_config &mconfig, const char *tag, d : mc146818_device(mconfig, DS12885, tag, owner, clock) { } + +int ds12885_device::get_timer_bypass() +{ + if( !( m_data[REG_A] & REG_A_DV0 ) ) //DV0 must be 0 for timekeeping + { + return 7; // Fixed at 1 Hz with clock at 32768Hz + } + + return 22; // No tick +} diff --git a/src/devices/machine/ds128x.h b/src/devices/machine/ds128x.h index e74227e58b1..e525d7a79d3 100644 --- a/src/devices/machine/ds128x.h +++ b/src/devices/machine/ds128x.h @@ -18,6 +18,7 @@ public: protected: virtual int data_size() override { return 128; } + virtual int get_timer_bypass() override; }; // device type definition diff --git a/src/devices/machine/ds1315.cpp b/src/devices/machine/ds1315.cpp index 7be26b1a19e..6b37957f9eb 100644 --- a/src/devices/machine/ds1315.cpp +++ b/src/devices/machine/ds1315.cpp @@ -1,12 +1,16 @@ // license:BSD-3-Clause -// copyright-holders:Tim Lindner +// copyright-holders:Tim Lindner, R. Belmont /***************************************************************************************** - ds1315.c + ds1315.cpp Dallas Semiconductor's Phantom Time Chip DS1315. NOTE: writes are decoded, but the host's time will always be returned when asked. + November 2017: R. Belmont added capability to emulate DS1216 and other DS121x + parts where the clock sits in the same place as a ROM. The backing callback + returns the ROM contents when the RTC is locked. + April 2015: chip enable / chip reset / phantom writes by Karl-Ludwig Deisenhofer November 2001: implementation by Tim Lindner @@ -29,7 +33,10 @@ DEFINE_DEVICE_TYPE(DS1315, ds1315_device, "ds1315", "Dallas DS1315 Phantom Time Chip") ds1315_device::ds1315_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, DS1315, tag, owner, clock), m_mode(), m_count(0) + : device_t(mconfig, DS1315, tag, owner, clock), + m_backing_read(*this), + m_mode(), + m_count(0) { } @@ -39,6 +46,8 @@ ds1315_device::ds1315_device(const machine_config &mconfig, const char *tag, dev void ds1315_device::device_start() { + m_backing_read.resolve_safe(0xff); + save_item(NAME(m_count)); save_item(NAME(m_mode)); save_item(NAME(m_raw_data)); @@ -77,6 +86,37 @@ static const uint8_t ds1315_pattern[] = IMPLEMENTATION ***************************************************************************/ +// automated read, does all the work the real Dallas chip does +READ8_MEMBER( ds1315_device::read ) +{ + if (m_mode == DS_SEEK_MATCHING) + { + if (offset & 1) + { + read_1(space, 0); + } + else + { + read_0(space, 0); + } + + if (offset & 4) + { + m_count = 0; + m_mode = DS_SEEK_MATCHING; + } + + return m_backing_read(offset); + } + else if (m_mode == DS_CALENDAR_IO) + { + return read_data(space, offset); + } + + return 0xff; // shouldn't happen, but compilers don't know that +} + + /*------------------------------------------------- read_0 (actual data) -------------------------------------------------*/ @@ -92,7 +132,6 @@ READ8_MEMBER( ds1315_device::read_0 ) m_mode = DS_CALENDAR_IO; fill_raw_data(); } - return 0; } @@ -246,7 +285,7 @@ void ds1315_device::input_raw_data() raw[6] = bcd_2_dec(raw[6]); // month raw[7] = bcd_2_dec(raw[7]); // year (two digits) - printf("\nDS1315 RTC INPUT (WILL BE IGNORED) mm/dd/yy hh:mm:ss - %02d/%02d/%02d %02d/%02d/%02d", + logerror("\nDS1315 RTC INPUT (WILL BE IGNORED) mm/dd/yy hh:mm:ss - %02d/%02d/%02d %02d/%02d/%02d", raw[6], raw[5], raw[7], raw[3], raw[2], raw[1] ); } diff --git a/src/devices/machine/ds1315.h b/src/devices/machine/ds1315.h index 0468232cf31..132056e46b3 100644 --- a/src/devices/machine/ds1315.h +++ b/src/devices/machine/ds1315.h @@ -15,7 +15,15 @@ #pragma once +/*************************************************************************** + DEVICE CONFIGURATION MACROS +***************************************************************************/ +#define MCFG_DS1315_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, DS1315, 0) + +#define MCFG_DS1315_BACKING_HANDLER(_devcb) \ + devcb = &ds1315_device::set_backing_handler(*device, DEVCB_##_devcb); /*************************************************************************** MACROS @@ -27,6 +35,9 @@ public: ds1315_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); ~ds1315_device() {} + // this handler automates the bits 0/2 stuff + DECLARE_READ8_MEMBER(read); + DECLARE_READ8_MEMBER(read_0); DECLARE_READ8_MEMBER(read_1); DECLARE_READ8_MEMBER(read_data); @@ -35,12 +46,17 @@ public: bool chip_enable(); void chip_reset(); + template <class Object> static devcb_base &set_backing_handler(device_t &device, Object &&cb) + { return downcast<ds1315_device &>(device).m_backing_read.set_callback(std::forward<Object>(cb)); } + protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; private: + devcb_read8 m_backing_read; + enum mode_t : u8 { DS_SEEK_MATCHING, @@ -61,12 +77,4 @@ ALLOW_SAVE_TYPE(ds1315_device::mode_t); DECLARE_DEVICE_TYPE(DS1315, ds1315_device) -/*************************************************************************** - DEVICE CONFIGURATION MACROS -***************************************************************************/ - -#define MCFG_DS1315_ADD(_tag) \ - MCFG_DEVICE_ADD(_tag, DS1315, 0) - - #endif // MAME_MACHINE_DS1315_H diff --git a/src/devices/machine/eepromser.cpp b/src/devices/machine/eepromser.cpp index 74d51e980f3..5e6e08a6a2b 100644 --- a/src/devices/machine/eepromser.cpp +++ b/src/devices/machine/eepromser.cpp @@ -90,6 +90,18 @@ 93Cxx has ERASE command; this maps to WRITE on ER5911 93Cxx has WRITEALL command; no equivalent on ER5911 + The Xicor X2444 NOVRAM (static RAM/EEPROM overlay) has a pin-compatible + serial interface, but its commands follow a rather different format: + + Start Address Opcode Command + 1 aaaa 011 WRITE data + 1 aaaa 11x READ data + 1 xxxx 000 WRDS = WRite DiSable + 1 xxxx 001 STO = STOre RAM data in EEPROM + 1 xxxx 010 SLEEP mode (not in CMOS version) + 1 xxxx 100 WREN = WRite ENable + 1 xxxx 101 RCL = ReCaLl RAM data from EEPROM + **************************************************************************** Issues with: @@ -148,6 +160,7 @@ eeprom_serial_base_device::eeprom_serial_base_device(const machine_config &mconf m_command_address_bits(0), m_streaming_enabled(false), m_output_on_falling_clock_enabled(false), + m_do_cb(*this), m_state(STATE_IN_RESET), m_cs_state(CLEAR_LINE), m_last_cs_rising_edge_time(attotime::zero), @@ -211,6 +224,9 @@ void eeprom_serial_base_device::device_start() // start the base class eeprom_base_device::device_start(); + // resolve callback + m_do_cb.resolve_safe(); + // save the current state save_item(NAME(m_state)); save_item(NAME(m_cs_state)); @@ -368,6 +384,9 @@ void eeprom_serial_base_device::set_state(eeprom_state newstate) // switch to the new state m_state = newstate; + + // set DO high (actually high impedance; pullup assumed) + m_do_cb(1); } @@ -443,6 +462,9 @@ void eeprom_serial_base_device::handle_event(eeprom_event event) m_shift_register = read((m_address + m_bits_accum / m_data_bits) & ((1 << m_address_bits) - 1)) << (32 - m_data_bits); else m_shift_register = (m_shift_register << 1) | 1; + + // update DO + m_do_cb(BIT(m_shift_register, 31)); } else if (event == EVENT_CS_FALLING_EDGE) { @@ -785,12 +807,8 @@ eeprom_serial_x24c44_device::eeprom_serial_x24c44_device(const machine_config &m void eeprom_serial_x24c44_device::device_start() { - // if no command address bits set, just inherit from the address bits - if (m_command_address_bits == 0) - m_command_address_bits = m_address_bits; - // start the base class - eeprom_base_device::device_start(); + eeprom_serial_base_device::device_start(); int16_t i=0; m_ram_length=0xf; @@ -800,18 +818,8 @@ void eeprom_serial_x24c44_device::device_start() } m_reading=0; m_store_latch=0; + // save the current state - save_item(NAME(m_state)); - save_item(NAME(m_cs_state)); - save_item(NAME(m_oe_state)); - save_item(NAME(m_clk_state)); - save_item(NAME(m_di_state)); - save_item(NAME(m_locked)); - save_item(NAME(m_bits_accum)); - save_item(NAME(m_command_address_accum)); - save_item(NAME(m_command)); - save_item(NAME(m_address)); - save_item(NAME(m_shift_register)); save_item(NAME(m_ram_data)); save_item(NAME(m_reading)); save_item(NAME(m_store_latch)); @@ -1012,6 +1020,9 @@ void eeprom_serial_x24c44_device::handle_event(eeprom_event event) m_shift_register = (m_shift_register << 1) | 1; } + + // update DO + m_do_cb(BIT(m_shift_register, 31)); } else if (event == EVENT_CS_FALLING_EDGE) { diff --git a/src/devices/machine/eepromser.h b/src/devices/machine/eepromser.h index 529fbeb5b04..d0d662948d8 100644 --- a/src/devices/machine/eepromser.h +++ b/src/devices/machine/eepromser.h @@ -91,6 +91,8 @@ #define MCFG_EEPROM_SERIAL_DATA MCFG_EEPROM_DATA #define MCFG_EEPROM_SERIAL_DEFAULT_VALUE MCFG_EEPROM_DEFAULT_VALUE +#define MCFG_EEPROM_SERIAL_DO_CALLBACK(_devcb) \ + devcb = &eeprom_serial_base_device::static_set_do_callback(*device, DEVCB_##_devcb); //************************************************************************** @@ -107,6 +109,10 @@ public: static void static_set_address_bits(device_t &device, int addrbits); static void static_enable_streaming(device_t &device); static void static_enable_output_on_falling_clock(device_t &device); + template<class Object> static devcb_base &static_set_do_callback(device_t &device, Object &&object) + { + return downcast<eeprom_serial_base_device &>(device).m_do_cb.set_callback(std::forward<Object>(object)); + } protected: // construction/destruction @@ -174,6 +180,7 @@ protected: uint8_t m_command_address_bits; // number of address bits in a command bool m_streaming_enabled; // true if streaming is enabled bool m_output_on_falling_clock_enabled; // true if the output pin is updated on the falling edge of the clock + devcb_write_line m_do_cb; // callback to push state of DO line // runtime state eeprom_state m_state; // current internal state diff --git a/src/devices/machine/genpc.cpp b/src/devices/machine/genpc.cpp index 12457166cc6..74180d23423 100644 --- a/src/devices/machine/genpc.cpp +++ b/src/devices/machine/genpc.cpp @@ -164,6 +164,11 @@ WRITE_LINE_MEMBER(ibm5160_mb_device::pc_speaker_set_spkrdata) m_speaker->level_w(m_pc_spkrdata & m_pit_out2); } +WRITE_LINE_MEMBER(ibm5160_mb_device::pic_int_w) +{ + m_maincpu->set_input_line(0, state); +} + /************************************************************* * @@ -427,7 +432,7 @@ MACHINE_CONFIG_MEMBER( ibm5160_mb_device::device_add_mconfig ) MCFG_I8237_OUT_DACK_3_CB(WRITELINE(ibm5160_mb_device, pc_dack3_w)) MCFG_DEVICE_ADD("pic8259", PIC8259, 0) - MCFG_PIC8259_OUT_INT_CB(INPUTLINE(":maincpu", 0)) + MCFG_PIC8259_OUT_INT_CB(WRITELINE(ibm5160_mb_device, pic_int_w)) MCFG_DEVICE_ADD("ppi8255", I8255A, 0) MCFG_I8255_IN_PORTA_CB(READ8(ibm5160_mb_device, pc_ppi_porta_r)) @@ -494,7 +499,7 @@ ioport_constructor ibm5160_mb_device::device_input_ports() const void ibm5160_mb_device::static_set_cputag(device_t &device, const char *tag) { ibm5160_mb_device &board = downcast<ibm5160_mb_device &>(device); - board.m_cputag = tag; + board.m_maincpu.set_tag(tag); } //************************************************************************** @@ -517,7 +522,7 @@ ibm5160_mb_device::ibm5160_mb_device( device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) - , m_maincpu(*owner, "maincpu") + , m_maincpu(*this, finder_base::DUMMY_TAG) , m_pic8259(*this, "pic8259") , m_pit8253(*this, "pit8253") , m_dma8237(*this, "dma8237") diff --git a/src/devices/machine/genpc.h b/src/devices/machine/genpc.h index c3e53283e75..22e53130bf1 100644 --- a/src/devices/machine/genpc.h +++ b/src/devices/machine/genpc.h @@ -25,7 +25,9 @@ #define MCFG_IBM5160_MOTHERBOARD_ADD(_tag, _cputag) \ MCFG_DEVICE_ADD(_tag, IBM5160_MOTHERBOARD, 0) \ - ibm5160_mb_device::static_set_cputag(*device, _cputag); + ibm5160_mb_device::static_set_cputag(*device, "^" _cputag); \ + isa8_device::static_set_cputag(*device->subdevice("isa"), "^^" _cputag); + // ======================> ibm5160_mb_device class ibm5160_mb_device : public device_t { @@ -48,6 +50,8 @@ public: DECLARE_WRITE_LINE_MEMBER( pc_pit8253_out1_changed ); DECLARE_WRITE_LINE_MEMBER( pc_pit8253_out2_changed ); + DECLARE_WRITE_LINE_MEMBER( pic_int_w ); + protected: ibm5160_mb_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -116,8 +120,6 @@ protected: DECLARE_WRITE_LINE_MEMBER( pc_dack2_w ); DECLARE_WRITE_LINE_MEMBER( pc_dack3_w ); - const char *m_cputag; - void pc_select_dma_channel(int channel, bool state); }; @@ -128,7 +130,8 @@ DECLARE_DEVICE_TYPE(IBM5160_MOTHERBOARD, ibm5160_mb_device) #define MCFG_IBM5150_MOTHERBOARD_ADD(_tag, _cputag) \ MCFG_DEVICE_ADD(_tag, IBM5150_MOTHERBOARD, 0) \ - ibm5150_mb_device::static_set_cputag(*device, _cputag); + ibm5150_mb_device::static_set_cputag(*device, "^" _cputag); \ + isa8_device::static_set_cputag(*device->subdevice("isa"), "^^" _cputag); // ======================> ibm5150_mb_device class ibm5150_mb_device : public ibm5160_mb_device @@ -160,7 +163,8 @@ DECLARE_DEVICE_TYPE(IBM5150_MOTHERBOARD, ibm5150_mb_device) #define MCFG_EC1841_MOTHERBOARD_ADD(_tag, _cputag) \ MCFG_DEVICE_ADD(_tag, EC1841_MOTHERBOARD, 0) \ - ec1841_mb_device::static_set_cputag(*device, _cputag); + ec1841_mb_device::static_set_cputag(*device, "^" _cputag); \ + isa8_device::static_set_cputag(*device->subdevice("isa"), "^^" _cputag); class ec1841_mb_device : public ibm5160_mb_device { @@ -185,7 +189,8 @@ DECLARE_DEVICE_TYPE(EC1841_MOTHERBOARD, ec1841_mb_device) #define MCFG_PCNOPPI_MOTHERBOARD_ADD(_tag, _cputag) \ MCFG_DEVICE_ADD(_tag, PCNOPPI_MOTHERBOARD, 0) \ - pc_noppi_mb_device::static_set_cputag(*device, _cputag); + pc_noppi_mb_device::static_set_cputag(*device, "^" _cputag); \ + isa8_device::static_set_cputag(*device->subdevice("isa"), "^^" _cputag); class pc_noppi_mb_device : public ibm5160_mb_device { diff --git a/src/devices/machine/mc146818.cpp b/src/devices/machine/mc146818.cpp index 4cdb4f37b5e..afe912a7d0d 100644 --- a/src/devices/machine/mc146818.cpp +++ b/src/devices/machine/mc146818.cpp @@ -412,31 +412,7 @@ void mc146818_device::update_timer() { int bypass; - switch (m_data[REG_A] & (REG_A_DV2 | REG_A_DV1 | REG_A_DV0)) - { - case 0: - bypass = 0; - break; - - case REG_A_DV0: - bypass = 2; - break; - - case REG_A_DV1: - bypass = 7; - break; - - case REG_A_DV2 | REG_A_DV1: - case REG_A_DV2 | REG_A_DV1 | REG_A_DV0: - bypass = 22; - break; - - default: - // TODO: other combinations of divider bits are used for test purposes only - bypass = 22; - break; - } - + bypass = get_timer_bypass(); attotime update_period = attotime::never; attotime update_interval = attotime::never; @@ -472,6 +448,41 @@ void mc146818_device::update_timer() m_periodic_timer->adjust(periodic_period, 0, periodic_interval); } +//--------------------------------------------------------------- +// get_timer_bypass - get main clock divisor based on A register +//--------------------------------------------------------------- + +int mc146818_device::get_timer_bypass() +{ + int bypass; + + switch (m_data[REG_A] & (REG_A_DV2 | REG_A_DV1 | REG_A_DV0)) + { + case 0: + bypass = 0; + break; + + case REG_A_DV0: + bypass = 2; + break; + + case REG_A_DV1: + bypass = 7; + break; + + case REG_A_DV2 | REG_A_DV1: + case REG_A_DV2 | REG_A_DV1 | REG_A_DV0: + bypass = 22; + break; + + default: + // TODO: other combinations of divider bits are used for test purposes only + bypass = 22; + break; + } + + return bypass; +} //------------------------------------------------- // update_irq - Update irq based on B & C register diff --git a/src/devices/machine/mc146818.h b/src/devices/machine/mc146818.h index 408f9f717d8..85256106abf 100644 --- a/src/devices/machine/mc146818.h +++ b/src/devices/machine/mc146818.h @@ -91,7 +91,6 @@ protected: virtual int data_size() { return 64; } -private: enum { REG_SECONDS = 0, @@ -153,7 +152,7 @@ private: void set_base_datetime(); void update_irq(); void update_timer(); - + virtual int get_timer_bypass(); int get_seconds(); void set_seconds(int seconds); int get_minutes(); diff --git a/src/devices/machine/mc68681.cpp b/src/devices/machine/mc68681.cpp index da860478f6d..a75d9acbade 100644 --- a/src/devices/machine/mc68681.cpp +++ b/src/devices/machine/mc68681.cpp @@ -11,6 +11,16 @@ Improved interrupt handling by R. Belmont Rewrite and modernization in progress by R. Belmont Addition of the duart compatible 68340 serial module support by Edstrom + + The main incompatibility between the 2681 and 68681 (Signetics and Motorola each + manufactured both versions of the chip) is that the 68681 has a R/W input and + generates a 68000-compatible DTACK signal, instead of using generic RD and WR + strobes as the 2681 does. The 68681 also adds a programmable interrupt vector, + with an IACK input replacing IP6. + + The command register addresses should never be read from. Doing so may place + the baud rate generator into a test mode which drives the parallel outputs with + internal counters and causes serial ports to operate at uncontrollable rates. */ #include "emu.h" @@ -60,17 +70,18 @@ static const int baud_rate_ACR_1[] = { 75, 110, 134, 150, 300, 600, 1200, 2000, #define CHAND_TAG "chd" // device type definition +DEFINE_DEVICE_TYPE(SCN2681, scn2681_device, "scn2681", "SCN2681 DUART") DEFINE_DEVICE_TYPE(MC68681, mc68681_device, "mc68681", "MC68681 DUART") DEFINE_DEVICE_TYPE(SC28C94, sc28c94_device, "sc28c94", "SC28C94 QUART") DEFINE_DEVICE_TYPE(MC68340_DUART, mc68340_duart_device, "mc68340duart", "MC68340 DUART Device") -DEFINE_DEVICE_TYPE(MC68681_CHANNEL, mc68681_channel, "mc68681_channel", "MC68681 DUART channel") +DEFINE_DEVICE_TYPE(DUART_CHANNEL, duart_channel, "duart_channel", "DUART channel") //************************************************************************** // LIVE DEVICE //************************************************************************** -mc68681_base_device::mc68681_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +duart_base_device::duart_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock), m_chanA(*this, CHANA_TAG), m_chanB(*this, CHANB_TAG), @@ -88,18 +99,23 @@ mc68681_base_device::mc68681_base_device(const machine_config &mconfig, device_t ip5clk(0), ip6clk(0), ACR(0), - m_read_vector(false), IP_last_state(0) { } +scn2681_device::scn2681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : duart_base_device(mconfig, SCN2681, tag, owner, clock) +{ +} + mc68681_device::mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : mc68681_base_device(mconfig, MC68681, tag, owner, clock) + : duart_base_device(mconfig, MC68681, tag, owner, clock), + m_read_vector(false) { } sc28c94_device::sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : mc68681_base_device(mconfig, SC28C94, tag, owner, clock) + : duart_base_device(mconfig, SC28C94, tag, owner, clock) { } @@ -111,7 +127,7 @@ sc28c94_device::sc28c94_device(const machine_config &mconfig, const char *tag, d // TODO: A lot of subtle differences and also detect misuse of unavailable registers as they should be ignored //-------------------------------------------------------------------------------------------------------------------- mc68340_duart_device::mc68340_duart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : mc68681_base_device(mconfig, type, tag, owner, clock) + : duart_base_device(mconfig, type, tag, owner, clock) { } @@ -125,9 +141,9 @@ mc68340_duart_device::mc68340_duart_device(const machine_config &mconfig, const // the external clocks //------------------------------------------------- -void mc68681_base_device::static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6) +void duart_base_device::static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6) { - mc68681_base_device &duart = downcast<mc68681_base_device &>(device); + duart_base_device &duart = downcast<duart_base_device &>(device); duart.ip3clk = clk3; duart.ip4clk = clk4; duart.ip5clk = clk5; @@ -138,7 +154,7 @@ void mc68681_base_device::static_set_clocks(device_t &device, int clk3, int clk4 device start callback -------------------------------------------------*/ -void mc68681_base_device::device_start() +void duart_base_device::device_start() { write_irq.resolve_safe(); write_a_tx.resolve_safe(); @@ -148,56 +164,70 @@ void mc68681_base_device::device_start() read_inport.resolve(); write_outport.resolve_safe(); - duart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mc68681_base_device::duart_timer_callback),this), nullptr); + duart_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(duart_base_device::duart_timer_callback),this), nullptr); save_item(NAME(ACR)); save_item(NAME(IMR)); save_item(NAME(ISR)); - save_item(NAME(IVR)); save_item(NAME(OPCR)); save_item(NAME(CTR)); save_item(NAME(IP_last_state)); save_item(NAME(half_period)); } +void mc68681_device::device_start() +{ + duart_base_device::device_start(); + + save_item(NAME(m_read_vector)); + save_item(NAME(IVR)); +} + /*------------------------------------------------- device reset callback -------------------------------------------------*/ -void mc68681_base_device::device_reset() +void duart_base_device::device_reset() { ACR = 0; /* Interrupt Vector Register */ - IVR = 0x0f; /* Interrupt Vector Register */ IMR = 0; /* Interrupt Mask Register */ ISR = 0; /* Interrupt Status Register */ OPCR = 0; /* Output Port Conf. Register */ OPR = 0; /* Output Port Register */ CTR.d = 0; /* Counter/Timer Preset Value */ - m_read_vector = false; // "reset clears internal registers (SRA, SRB, IMR, ISR, OPR, OPCR) puts OP0-7 in the high state, stops the counter/timer, and puts channels a/b in the inactive state" IPCR = 0; + write_irq(CLEAR_LINE); write_outport(OPR ^ 0xff); } -MACHINE_CONFIG_MEMBER( mc68681_base_device::device_add_mconfig ) - MCFG_DEVICE_ADD(CHANA_TAG, MC68681_CHANNEL, 0) - MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0) +void mc68681_device::device_reset() +{ + duart_base_device::device_reset(); + + IVR = 0x0f; /* Interrupt Vector Register */ + m_read_vector = false; +} + +MACHINE_CONFIG_MEMBER( duart_base_device::device_add_mconfig ) + MCFG_DEVICE_ADD(CHANA_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANB_TAG, DUART_CHANNEL, 0) MACHINE_CONFIG_END MACHINE_CONFIG_MEMBER( sc28c94_device::device_add_mconfig ) - MCFG_DEVICE_ADD(CHANA_TAG, MC68681_CHANNEL, 0) - MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0) - MCFG_DEVICE_ADD(CHANC_TAG, MC68681_CHANNEL, 0) - MCFG_DEVICE_ADD(CHAND_TAG, MC68681_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANA_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANB_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANC_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHAND_TAG, DUART_CHANNEL, 0) MACHINE_CONFIG_END MACHINE_CONFIG_MEMBER( mc68340_duart_device::device_add_mconfig ) - MCFG_DEVICE_ADD(CHANA_TAG, MC68681_CHANNEL, 0) - MCFG_DEVICE_ADD(CHANB_TAG, MC68681_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANA_TAG, DUART_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANB_TAG, DUART_CHANNEL, 0) MACHINE_CONFIG_END -void mc68681_base_device::update_interrupts() +void duart_base_device::update_interrupts() { /* update SR state and update interrupt ISR state for the following bits: SRn: bits 7-4: handled elsewhere. @@ -223,7 +253,6 @@ void mc68681_base_device::update_interrupts() { LOG( "68681: Interrupt line not active (IMR & ISR = %02X)\n", ISR & IMR); write_irq(CLEAR_LINE); - m_read_vector = false; // clear IACK too } if(OPCR & 0xf0) { @@ -259,7 +288,15 @@ void mc68681_base_device::update_interrupts() } } -double mc68681_base_device::duart68681_get_ct_rate() +void mc68681_device::update_interrupts() +{ + duart_base_device::update_interrupts(); + + if (!irq_pending()) + m_read_vector = false; // clear IACK too +} + +double duart_base_device::get_ct_rate() { double rate = 0.0f; @@ -301,19 +338,19 @@ double mc68681_base_device::duart68681_get_ct_rate() return rate; } -uint16_t mc68681_base_device::duart68681_get_ct_count() +uint16_t duart_base_device::get_ct_count() { - double clock = duart68681_get_ct_rate(); + double clock = get_ct_rate(); return (duart_timer->remaining() * clock).as_double(); } -void mc68681_base_device::duart68681_start_ct(int count) +void duart_base_device::start_ct(int count) { - double clock = duart68681_get_ct_rate(); + double clock = get_ct_rate(); duart_timer->adjust(attotime::from_hz(clock) * count, 0); } -TIMER_CALLBACK_MEMBER( mc68681_base_device::duart_timer_callback ) +TIMER_CALLBACK_MEMBER( duart_base_device::duart_timer_callback ) { if (ACR & 0x40) { @@ -353,22 +390,37 @@ TIMER_CALLBACK_MEMBER( mc68681_base_device::duart_timer_callback ) } if (!half_period) - { - ISR |= INT_COUNTER_READY; - update_interrupts(); - } + set_ISR_bits(INT_COUNTER_READY); int count = std::max(CTR.w.l, uint16_t(1)); - duart68681_start_ct(count); + start_ct(count); } else { // Counter mode - ISR |= INT_COUNTER_READY; - update_interrupts(); - duart68681_start_ct(0xffff); + set_ISR_bits(INT_COUNTER_READY); + start_ct(0xffff); + } + +} + +READ8_MEMBER( mc68681_device::read ) +{ + if (offset == 0x0c) + return IVR; + + uint8_t r = duart_base_device::read(space, offset, mem_mask); + + if (offset == 0x0d) + { + // bit 6 is /IACK (note the active-low) + if (m_read_vector) + r &= ~0x40; + else + r |= 0x40; } + return r; } READ8_MEMBER( mc68340_duart_device::read ) @@ -390,7 +442,7 @@ READ8_MEMBER( mc68340_duart_device::read ) r = m_chanB->read_MR2(); break; default: - r = mc68681_base_device::read(space, offset, mem_mask); + r = duart_base_device::read(space, offset, mem_mask); } return r; } @@ -402,7 +454,7 @@ READ8_MEMBER( sc28c94_device::read ) if (offset < 0x10) { - return mc68681_base_device::read(space, offset, mem_mask); + return duart_base_device::read(space, offset, mem_mask); } switch (offset) @@ -423,7 +475,7 @@ READ8_MEMBER( sc28c94_device::read ) return r; } -READ8_MEMBER( mc68681_base_device::read ) +READ8_MEMBER( duart_base_device::read ) { uint8_t r = 0xff; @@ -445,8 +497,7 @@ READ8_MEMBER( mc68681_base_device::read ) // reading this clears all the input change bits IPCR &= 0x0f; - ISR &= ~INT_INPUT_PORT_CHANGE; - update_interrupts(); + clear_ISR_bits(INT_INPUT_PORT_CHANGE); } break; @@ -455,11 +506,11 @@ READ8_MEMBER( mc68681_base_device::read ) break; case 0x06: /* CUR */ - r = duart68681_get_ct_count() >> 8; + r = get_ct_count() >> 8; break; case 0x07: /* CLR */ - r = duart68681_get_ct_count() & 0xff; + r = get_ct_count() & 0xff; break; case 0x08: /* MR1B/MR2B */ @@ -483,16 +534,6 @@ READ8_MEMBER( mc68681_base_device::read ) } r |= 0x80; // bit 7 is always set - - // bit 6 is /IACK (note the active-low) - if (m_read_vector) - { - r &= ~0x40; - } - else - { - r |= 0x40; - } break; case 0x0e: /* Start counter command */ @@ -504,18 +545,17 @@ READ8_MEMBER( mc68681_base_device::read ) } int count = std::max(CTR.w.l, uint16_t(1)); - duart68681_start_ct(count); + start_ct(count); break; } case 0x0f: /* Stop counter command */ - ISR &= ~INT_COUNTER_READY; + clear_ISR_bits(INT_COUNTER_READY); // Stop the counter only if (!(ACR & 0x40)) duart_timer->adjust(attotime::never); - update_interrupts(); break; default: @@ -527,6 +567,14 @@ READ8_MEMBER( mc68681_base_device::read ) return r; } +WRITE8_MEMBER( mc68681_device::write ) +{ + if (offset == 0x0c) + IVR = data; + else + duart_base_device::write(space, offset, data, mem_mask); +} + WRITE8_MEMBER( mc68340_duart_device::write ) { //printf("Duart write %02x -> %02x\n", data, offset); @@ -546,7 +594,7 @@ WRITE8_MEMBER( mc68340_duart_device::write ) m_chanB->write_MR2(data); break; default: - mc68681_base_device::write(space, offset, data, mem_mask); + duart_base_device::write(space, offset, data, mem_mask); } } @@ -556,7 +604,7 @@ WRITE8_MEMBER( sc28c94_device::write ) if (offset < 0x10) { - mc68681_base_device::write(space, offset, data, mem_mask); + duart_base_device::write(space, offset, data, mem_mask); } switch(offset) @@ -577,7 +625,7 @@ WRITE8_MEMBER( sc28c94_device::write ) } } -WRITE8_MEMBER( mc68681_base_device::write ) +WRITE8_MEMBER( duart_base_device::write ) { offset &= 0x0f; LOG( "Writing 68681 (%s) reg %x (%s) with %04x\n", tag(), offset, duart68681_reg_write_names[offset], data ); @@ -605,7 +653,7 @@ WRITE8_MEMBER( mc68681_base_device::write ) uint16_t count = std::max(CTR.w.l, uint16_t(1)); half_period = 0; - duart68681_start_ct(count); + start_ct(count); } else { @@ -616,15 +664,12 @@ WRITE8_MEMBER( mc68681_base_device::write ) // check for pending input port delta interrupts if ((((IPCR>>4) & data) & 0x0f) != 0) - { - ISR |= INT_INPUT_PORT_CHANGE; - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); m_chanA->ACR_updated(); m_chanB->ACR_updated(); m_chanA->update_interrupts(); m_chanB->update_interrupts(); - update_interrupts(); break; } case 0x05: /* IMR */ @@ -647,10 +692,6 @@ WRITE8_MEMBER( mc68681_base_device::write ) m_chanB->write_chan_reg(offset&3, data); break; - case 0x0c: /* IVR */ - IVR = data; - break; - case 0x0d: /* OPCR */ if (((data & 0xf) != 0x00) && ((data & 0xc) != 0x4)) logerror( "68681 (%s): Unhandled OPCR value: %02x\n", tag(), data); @@ -669,7 +710,7 @@ WRITE8_MEMBER( mc68681_base_device::write ) } } -WRITE_LINE_MEMBER( mc68681_base_device::ip0_w ) +WRITE_LINE_MEMBER( duart_base_device::ip0_w ) { uint8_t newIP = (IP_last_state & ~0x01) | ((state == ASSERT_LINE) ? 1 : 0); @@ -680,16 +721,13 @@ WRITE_LINE_MEMBER( mc68681_base_device::ip0_w ) IPCR |= 0x10; if (ACR & 1) - { - ISR |= INT_INPUT_PORT_CHANGE; - update_interrupts(); - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); } IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip1_w ) +WRITE_LINE_MEMBER( duart_base_device::ip1_w ) { uint8_t newIP = (IP_last_state & ~0x02) | ((state == ASSERT_LINE) ? 2 : 0); @@ -700,16 +738,13 @@ WRITE_LINE_MEMBER( mc68681_base_device::ip1_w ) IPCR |= 0x20; if (ACR & 2) - { - ISR |= INT_INPUT_PORT_CHANGE; - update_interrupts(); - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); } IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip2_w ) +WRITE_LINE_MEMBER( duart_base_device::ip2_w ) { uint8_t newIP = (IP_last_state & ~0x04) | ((state == ASSERT_LINE) ? 4 : 0); @@ -720,16 +755,13 @@ WRITE_LINE_MEMBER( mc68681_base_device::ip2_w ) IPCR |= 0x40; if (ACR & 4) - { - ISR |= INT_INPUT_PORT_CHANGE; - update_interrupts(); - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); } IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip3_w ) +WRITE_LINE_MEMBER( duart_base_device::ip3_w ) { uint8_t newIP = (IP_last_state & ~0x08) | ((state == ASSERT_LINE) ? 8 : 0); @@ -740,30 +772,34 @@ WRITE_LINE_MEMBER( mc68681_base_device::ip3_w ) IPCR |= 0x80; if (ACR & 8) - { - ISR |= INT_INPUT_PORT_CHANGE; - update_interrupts(); - } + set_ISR_bits(INT_INPUT_PORT_CHANGE); } IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip4_w ) +WRITE_LINE_MEMBER( duart_base_device::ip4_w ) { uint8_t newIP = (IP_last_state & ~0x10) | ((state == ASSERT_LINE) ? 0x10 : 0); // TODO: special mode for ip4 (Ch. A Rx clock) IP_last_state = newIP; } -WRITE_LINE_MEMBER( mc68681_base_device::ip5_w ) +WRITE_LINE_MEMBER( duart_base_device::ip5_w ) { uint8_t newIP = (IP_last_state & ~0x20) | ((state == ASSERT_LINE) ? 0x20 : 0); // TODO: special mode for ip5 (Ch. B Tx clock) IP_last_state = newIP; } -mc68681_channel *mc68681_base_device::get_channel(int chan) +WRITE_LINE_MEMBER( duart_base_device::ip6_w ) +{ + uint8_t newIP = (IP_last_state & ~0x40) | ((state == ASSERT_LINE) ? 0x40 : 0); +// TODO: special mode for ip6 (Ch. B Rx clock) + IP_last_state = newIP; +} + +duart_channel *duart_base_device::get_channel(int chan) { if (chan == 0) { @@ -773,7 +809,7 @@ mc68681_channel *mc68681_base_device::get_channel(int chan) return m_chanB; } -int mc68681_base_device::calc_baud(int ch, uint8_t data) +int duart_base_device::calc_baud(int ch, uint8_t data) { int baud_rate; @@ -818,20 +854,28 @@ int mc68681_base_device::calc_baud(int ch, uint8_t data) return baud_rate; } -void mc68681_base_device::clear_ISR_bits(int mask) +void duart_base_device::clear_ISR_bits(int mask) { - ISR &= ~mask; + if ((ISR & mask) != 0) + { + ISR &= ~mask; + update_interrupts(); + } } -void mc68681_base_device::set_ISR_bits(int mask) +void duart_base_device::set_ISR_bits(int mask) { - ISR |= mask; + if ((~ISR & mask) != 0) + { + ISR |= mask; + update_interrupts(); + } } // DUART channel class stuff -mc68681_channel::mc68681_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, MC68681_CHANNEL, tag, owner, clock), +duart_channel::duart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, DUART_CHANNEL, tag, owner, clock), device_serial_interface(mconfig, *this), MR1(0), MR2(0), @@ -842,9 +886,9 @@ mc68681_channel::mc68681_channel(const machine_config &mconfig, const char *tag, { } -void mc68681_channel::device_start() +void duart_channel::device_start() { - m_uart = downcast<mc68681_base_device *>(owner()); + m_uart = downcast<duart_base_device *>(owner()); m_ch = m_uart->get_ch(this); // get our channel number save_item(NAME(CR)); @@ -865,7 +909,7 @@ void mc68681_channel::device_start() save_item(NAME(tx_ready)); } -void mc68681_channel::device_reset() +void duart_channel::device_reset() { write_CR(0x10); // reset MR write_CR(0x20); // reset Rx @@ -879,7 +923,7 @@ void mc68681_channel::device_reset() } // serial device virtual overrides -void mc68681_channel::rcv_complete() +void duart_channel::rcv_complete() { receive_register_extract(); @@ -903,7 +947,7 @@ void mc68681_channel::rcv_complete() } } -void mc68681_channel::tra_complete() +void duart_channel::tra_complete() { //printf("%s ch %d Tx complete\n", tag(), m_ch); tx_ready = 1; @@ -936,7 +980,7 @@ void mc68681_channel::tra_complete() update_interrupts(); } -void mc68681_channel::tra_callback() +void duart_channel::tra_callback() { // don't actually send in loopback mode if ((MR2&0xC0) != 0x80) @@ -966,7 +1010,7 @@ void mc68681_channel::tra_callback() } } -void mc68681_channel::update_interrupts() +void duart_channel::update_interrupts() { if (rx_enabled) { @@ -1060,12 +1104,10 @@ void mc68681_channel::update_interrupts() } } - m_uart->update_interrupts(); - //logerror("DEBUG: 68681 int check: after receiver test, SR%c is %02X, ISR is %02X\n", (ch+0x41), duart68681->channel[ch].SR, duart68681->ISR); } -uint8_t mc68681_channel::read_rx_fifo() +uint8_t duart_channel::read_rx_fifo() { uint8_t rv; @@ -1092,7 +1134,7 @@ uint8_t mc68681_channel::read_rx_fifo() return rv; } -uint8_t mc68681_channel::read_chan_reg(int reg) +uint8_t duart_channel::read_chan_reg(int reg) { uint8_t rv = 0xff; @@ -1125,7 +1167,7 @@ uint8_t mc68681_channel::read_chan_reg(int reg) return rv; } -void mc68681_channel::write_chan_reg(int reg, uint8_t data) +void duart_channel::write_chan_reg(int reg, uint8_t data) { switch (reg) { @@ -1152,7 +1194,7 @@ void mc68681_channel::write_chan_reg(int reg, uint8_t data) } } -void mc68681_channel::write_MR(uint8_t data) +void duart_channel::write_MR(uint8_t data) { if ( MR_ptr == 0 ) { @@ -1167,7 +1209,7 @@ void mc68681_channel::write_MR(uint8_t data) update_interrupts(); } -void mc68681_channel::recalc_framing() +void duart_channel::recalc_framing() { parity_t parity = PARITY_NONE; switch ((MR1>>3) & 3) @@ -1227,7 +1269,7 @@ void mc68681_channel::recalc_framing() set_data_frame(1, (MR1 & 3)+5, parity, stopbits); } -void mc68681_channel::write_CR(uint8_t data) +void duart_channel::write_CR(uint8_t data) { CR = data; @@ -1305,7 +1347,7 @@ void mc68681_channel::write_CR(uint8_t data) update_interrupts(); } -void mc68681_channel::write_TX(uint8_t data) +void duart_channel::write_TX(uint8_t data) { tx_data = data; @@ -1330,12 +1372,12 @@ void mc68681_channel::write_TX(uint8_t data) update_interrupts(); } -void mc68681_channel::ACR_updated() +void duart_channel::ACR_updated() { write_chan_reg(1, CSR); } -uint8_t mc68681_channel::get_chan_CSR() +uint8_t duart_channel::get_chan_CSR() { return CSR; } diff --git a/src/devices/machine/mc68681.h b/src/devices/machine/mc68681.h index ebc29c98fd1..452b67cb64f 100644 --- a/src/devices/machine/mc68681.h +++ b/src/devices/machine/mc68681.h @@ -6,30 +6,24 @@ #pragma once -#define MCFG_MC68681_ADD(_tag, _clock) \ - MCFG_DEVICE_ADD(_tag, MC68681, _clock) - -#define MCFG_MC68681_REPLACE(_tag, _clock) \ - MCFG_DEVICE_REPLACE(_tag, MC68681, _clock) - #define MCFG_MC68681_IRQ_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_irq_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_irq_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_A_TX_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_a_tx_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_a_tx_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_B_TX_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_b_tx_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_b_tx_cb(*device, DEVCB_##_cb); // deprecated: use ipX_w() instead #define MCFG_MC68681_INPORT_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_inport_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_inport_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_OUTPORT_CALLBACK(_cb) \ - devcb = &mc68681_base_device::set_outport_cb(*device, DEVCB_##_cb); + devcb = &duart_base_device::set_outport_cb(*device, DEVCB_##_cb); #define MCFG_MC68681_SET_EXTERNAL_CLOCKS(_a, _b, _c, _d) \ - mc68681_base_device::static_set_clocks(*device, _a, _b, _c, _d); + duart_base_device::static_set_clocks(*device, _a, _b, _c, _d); // SC28C94 specific callbacks #define MCFG_SC28C94_ADD(_tag, _clock) \ @@ -48,13 +42,13 @@ #define MC68681_RX_FIFO_SIZE 3 // forward declaration -class mc68681_base_device; +class duart_base_device; -// mc68681_channel class -class mc68681_channel : public device_t, public device_serial_interface +// duart_channel class +class duart_channel : public device_t, public device_serial_interface { public: - mc68681_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + duart_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_start() override; @@ -107,7 +101,7 @@ private: uint8_t tx_data; uint8_t tx_ready; - mc68681_base_device *m_uart; + duart_base_device *m_uart; void write_MR(uint8_t data); void write_CR(uint8_t data); @@ -115,15 +109,15 @@ private: void recalc_framing(); }; -class mc68681_base_device : public device_t +class duart_base_device : public device_t { - friend class mc68681_channel; + friend class duart_channel; public: - required_device<mc68681_channel> m_chanA; - required_device<mc68681_channel> m_chanB; - optional_device<mc68681_channel> m_chanC; - optional_device<mc68681_channel> m_chanD; + required_device<duart_channel> m_chanA; + required_device<duart_channel> m_chanB; + optional_device<duart_channel> m_chanC; + optional_device<duart_channel> m_chanD; // inline configuration helpers static void static_set_clocks(device_t &device, int clk3, int clk4, int clk5, int clk6); @@ -131,16 +125,15 @@ public: // API virtual DECLARE_READ8_MEMBER(read); virtual DECLARE_WRITE8_MEMBER(write); - uint8_t get_irq_vector() { m_read_vector = true; return IVR; } DECLARE_WRITE_LINE_MEMBER( rx_a_w ) { m_chanA->device_serial_interface::rx_w((uint8_t)state); } DECLARE_WRITE_LINE_MEMBER( rx_b_w ) { m_chanB->device_serial_interface::rx_w((uint8_t)state); } - template <class Object> static devcb_base &set_irq_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).write_irq.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_a_tx_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).write_a_tx.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_b_tx_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).write_b_tx.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_inport_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).read_inport.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_outport_cb(device_t &device, Object &&cb) { return downcast<mc68681_base_device &>(device).write_outport.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_irq_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).write_irq.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_a_tx_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).write_a_tx.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_b_tx_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).write_b_tx.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_inport_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).read_inport.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_outport_cb(device_t &device, Object &&cb) { return downcast<duart_base_device &>(device).write_outport.set_callback(std::forward<Object>(cb)); } // new-style push handlers for input port bits DECLARE_WRITE_LINE_MEMBER( ip0_w ); @@ -149,9 +142,12 @@ public: DECLARE_WRITE_LINE_MEMBER( ip3_w ); DECLARE_WRITE_LINE_MEMBER( ip4_w ); DECLARE_WRITE_LINE_MEMBER( ip5_w ); + DECLARE_WRITE_LINE_MEMBER( ip6_w ); + + bool irq_pending() const { return (ISR & IMR) != 0; } protected: - mc68681_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + duart_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_start() override; @@ -163,6 +159,9 @@ protected: devcb_write8 write_outport; int32_t ip3clk, ip4clk, ip5clk, ip6clk; +protected: + virtual void update_interrupts(); + private: TIMER_CALLBACK_MEMBER( duart_timer_callback ); @@ -170,14 +169,11 @@ private: uint8_t ACR; /* Auxiliary Control Register */ uint8_t IMR; /* Interrupt Mask Register */ uint8_t ISR; /* Interrupt Status Register */ - uint8_t IVR; /* Interrupt Vector Register */ uint8_t OPCR; /* Output Port Conf. Register */ uint8_t OPR; /* Output Port Register */ PAIR CTR; /* Counter/Timer Preset Value */ uint8_t IPCR; /* Input Port Control Register */ - bool m_read_vector; // if this is read and IRQ is active, it counts as pulling IACK - /* state */ uint8_t IP_last_state; /* last state of IP bits */ @@ -185,15 +181,14 @@ private: uint8_t half_period; emu_timer *duart_timer; - double duart68681_get_ct_rate(); - uint16_t duart68681_get_ct_count(); - void duart68681_start_ct(int count); + double get_ct_rate(); + uint16_t get_ct_count(); + void start_ct(int count); int calc_baud(int ch, uint8_t data); void clear_ISR_bits(int mask); void set_ISR_bits(int mask); - void update_interrupts(); - int get_ch(mc68681_channel *ch) + int get_ch(duart_channel *ch) { if (ch == m_chanA) { @@ -211,16 +206,36 @@ private: return 3; } - mc68681_channel *get_channel(int chan); + duart_channel *get_channel(int chan); +}; + +class scn2681_device : public duart_base_device +{ +public: + scn2681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -class mc68681_device : public mc68681_base_device +class mc68681_device : public duart_base_device { public: mc68681_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual DECLARE_READ8_MEMBER(read) override; + virtual DECLARE_WRITE8_MEMBER(write) override; + uint8_t get_irq_vector() { m_read_vector = true; return IVR; } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void update_interrupts() override; + +private: + bool m_read_vector; // if this is read and IRQ is active, it counts as pulling IACK + + uint8_t IVR; /* Interrupt Vector Register */ }; -class sc28c94_device : public mc68681_base_device +class sc28c94_device : public duart_base_device { public: sc28c94_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -240,10 +255,10 @@ protected: private: }; -class mc68340_duart_device : public mc68681_base_device +class mc68340_duart_device : public duart_base_device { public: - mc68340_duart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + mc68340_duart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); virtual DECLARE_READ8_MEMBER(read) override; virtual DECLARE_WRITE8_MEMBER(write) override; @@ -253,9 +268,10 @@ protected: mc68340_duart_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); }; +DECLARE_DEVICE_TYPE(SCN2681, scn2681_device) DECLARE_DEVICE_TYPE(MC68681, mc68681_device) DECLARE_DEVICE_TYPE(SC28C94, sc28c94_device) DECLARE_DEVICE_TYPE(MC68340_DUART, mc68340_duart_device) -DECLARE_DEVICE_TYPE(MC68681_CHANNEL, mc68681_channel) +DECLARE_DEVICE_TYPE(DUART_CHANNEL, duart_channel) #endif // MAME_MACHINE_MC68681_H diff --git a/src/devices/machine/mc68901.cpp b/src/devices/machine/mc68901.cpp index 8da39d3a4bd..02011fe447f 100644 --- a/src/devices/machine/mc68901.cpp +++ b/src/devices/machine/mc68901.cpp @@ -211,10 +211,6 @@ inline void mc68901_device::rx_error() { take_interrupt(IR_RCV_ERROR); } - else - { - rx_buffer_full(); - } } inline void mc68901_device::timer_count(int index) @@ -414,7 +410,7 @@ void mc68901_device::device_start() save_item(NAME(m_transmit_buffer)); save_item(NAME(m_transmit_pending)); save_item(NAME(m_receive_buffer)); - save_item(NAME(m_receive_pending)); + save_item(NAME(m_overrun_pending)); save_item(NAME(m_gpio_input)); save_item(NAME(m_gpio_output)); save_item(NAME(m_rsr_read)); @@ -429,7 +425,8 @@ void mc68901_device::device_start() void mc68901_device::device_reset() { m_tsr = 0; - m_transmit_pending = 0; + m_transmit_pending = false; + m_overrun_pending = false; // Avoid read-before-write m_ipr = m_imr = 0; @@ -496,7 +493,7 @@ void mc68901_device::tra_complete() if (m_transmit_pending) { transmit_register_setup(m_transmit_buffer); - m_transmit_pending = 0; + m_transmit_pending = false; m_tsr |= TSR_BUFFER_EMPTY; if (m_ier & IR_XMIT_BUFFER_EMPTY) @@ -524,10 +521,16 @@ void mc68901_device::tra_complete() void mc68901_device::rcv_complete() { receive_register_extract(); - m_receive_buffer = get_received_char(); - //if (m_receive_pending) TODO: error? - - m_receive_pending = 1; + if (m_rsr & RSR_BUFFER_FULL) + { + m_overrun_pending = true; + } + else + { + m_receive_buffer = get_received_char(); + m_rsr |= RSR_BUFFER_FULL; + LOG("Received Character: %02x\n", m_receive_buffer); + } rx_buffer_full(); } @@ -565,19 +568,34 @@ READ8_MEMBER( mc68901_device::read ) case REGISTER_SCR: return m_scr; case REGISTER_UCR: return m_ucr; - case REGISTER_RSR: return m_rsr; + case REGISTER_RSR: + { + uint8_t rsr = m_rsr; + if (!machine().side_effect_disabled()) + m_rsr &= ~RSR_OVERRUN_ERROR; + return rsr; + } case REGISTER_TSR: { /* clear UE bit (in reality, this won't be cleared until one full clock cycle of the transmitter has passed since the bit was set) */ uint8_t tsr = m_tsr; - m_tsr &= ~TSR_UNDERRUN_ERROR; - + if (!machine().side_effect_disabled()) + m_tsr &= ~TSR_UNDERRUN_ERROR; return tsr; } case REGISTER_UDR: - m_receive_pending = 0; + if (!machine().side_effect_disabled()) + { + m_rsr &= ~RSR_BUFFER_FULL; + if (m_overrun_pending) + { + m_overrun_pending = false; + m_rsr |= RSR_OVERRUN_ERROR; + rx_error(); + } + } return m_receive_buffer; default: return 0; @@ -966,6 +984,7 @@ void mc68901_device::register_w(offs_t offset, uint8_t data) } set_data_frame(start_bits, data_bit_count, parity, stop_bits); + receive_register_reset(); m_ucr = data; } @@ -1052,22 +1071,23 @@ void mc68901_device::register_w(offs_t offset, uint8_t data) if (m_transmit_pending && is_transmit_register_empty()) { transmit_register_setup(m_transmit_buffer); - m_transmit_pending = 0; - m_tsr |= TSR_BUFFER_EMPTY; + m_transmit_pending = false; } + if (!m_transmit_pending) + m_tsr |= TSR_BUFFER_EMPTY; } break; case REGISTER_UDR: LOG("MC68901 UDR %x\n", data); m_transmit_buffer = data; - m_transmit_pending = 1; + m_transmit_pending = true; m_tsr &= ~TSR_BUFFER_EMPTY; if ((m_tsr & TSR_XMIT_ENABLE) && is_transmit_register_empty()) { transmit_register_setup(m_transmit_buffer); - m_transmit_pending = 0; + m_transmit_pending = false; m_tsr |= TSR_BUFFER_EMPTY; } break; diff --git a/src/devices/machine/mc68901.h b/src/devices/machine/mc68901.h index b98d2de8e5c..cccd257b2ee 100644 --- a/src/devices/machine/mc68901.h +++ b/src/devices/machine/mc68901.h @@ -279,9 +279,9 @@ private: uint8_t m_tsr; /* transmitter status register */ uint8_t m_rsr; /* receiver status register */ uint8_t m_transmit_buffer; /* USART data register */ - int m_transmit_pending; + bool m_transmit_pending; uint8_t m_receive_buffer; - int m_receive_pending; + bool m_overrun_pending; uint8_t m_gpio_input; uint8_t m_gpio_output; diff --git a/src/devices/machine/netlist.cpp b/src/devices/machine/netlist.cpp index 6674efee841..30ef04433f2 100644 --- a/src/devices/machine/netlist.cpp +++ b/src/devices/machine/netlist.cpp @@ -1045,23 +1045,6 @@ ATTR_COLD uint64_t netlist_mame_cpu_device::execute_cycles_to_clocks(uint64_t cy return cycles; } -ATTR_COLD offs_t netlist_mame_cpu_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) -{ - //char tmp[16]; - unsigned startpc = pc; - int relpc = pc - m_genPC; - if (relpc >= 0 && relpc < netlist().queue().size()) - { - int dpc = netlist().queue().size() - relpc - 1; - // FIXME: 50 below fixes crash in mame-debugger. It's based on try on error. - util::stream_format(stream, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', netlist().queue()[dpc].m_object->name().c_str(), - netlist().queue()[dpc].m_exec_time.as_double()); - } - - pc+=1; - return (pc - startpc); -} - ATTR_HOT void netlist_mame_cpu_device::execute_run() { bool check_debugger = ((device_t::machine().debug_flags & DEBUG_FLAG_ENABLED) != 0); @@ -1085,6 +1068,35 @@ ATTR_HOT void netlist_mame_cpu_device::execute_run() } } +util::disasm_interface *netlist_mame_cpu_device::create_disassembler() +{ + return new netlist_disassembler(this); +} + +netlist_disassembler::netlist_disassembler(netlist_mame_cpu_device *dev) : m_dev(dev) +{ +} + +u32 netlist_disassembler::opcode_alignment() const +{ + return 1; +} + +offs_t netlist_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + unsigned startpc = pc; + int relpc = pc - m_dev->genPC(); + if (relpc >= 0 && relpc < m_dev->netlist().queue().size()) + { + int dpc = m_dev->netlist().queue().size() - relpc - 1; + util::stream_format(stream, "%c %s @%10.7f", (relpc == 0) ? '*' : ' ', m_dev->netlist().queue()[dpc].m_object->name().c_str(), + m_dev->netlist().queue()[dpc].m_exec_time.as_double()); + } + + pc+=1; + return (pc - startpc); +} + // ---------------------------------------------------------------------------------------- // netlist_mame_sound_device // ---------------------------------------------------------------------------------------- diff --git a/src/devices/machine/netlist.h b/src/devices/machine/netlist.h index bf6fd084056..18a13d31f41 100644 --- a/src/devices/machine/netlist.h +++ b/src/devices/machine/netlist.h @@ -151,6 +151,21 @@ private: // netlist_mame_cpu_device // ---------------------------------------------------------------------------------------- +class netlist_mame_cpu_device; + +class netlist_disassembler : public util::disasm_interface +{ +public: + netlist_disassembler(netlist_mame_cpu_device *dev); + virtual ~netlist_disassembler() = default; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + netlist_mame_cpu_device *m_dev; +}; + class netlist_mame_cpu_device : public netlist_mame_device, public device_execute_interface, public device_state_interface, @@ -161,6 +176,8 @@ public: // construction/destruction netlist_mame_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + offs_t genPC() const { return m_genPC; } + protected: // netlist_mame_device virtual void nl_register_devices() override; @@ -175,9 +192,7 @@ protected: ATTR_HOT virtual void execute_run() override; // device_disasm_interface overrides - ATTR_COLD virtual uint32_t disasm_min_opcode_bytes() const override { return 1; } - ATTR_COLD virtual uint32_t disasm_max_opcode_bytes() const override { return 1; } - ATTR_COLD virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; @@ -188,7 +203,7 @@ protected: address_space_config m_program_config; private: - int m_genPC; + offs_t m_genPC; }; // ---------------------------------------------------------------------------------------- diff --git a/src/devices/machine/sdlc.cpp b/src/devices/machine/sdlc.cpp new file mode 100644 index 00000000000..e3cc8cc99ed --- /dev/null +++ b/src/devices/machine/sdlc.cpp @@ -0,0 +1,302 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb + +#include "emu.h" +#include "sdlc.h" + +#include <sstream> + + +#define LOG_GENERAL (1U << 0) +#define LOG_RXBIT (1U << 1) +#define LOG_RXFLAG (1U << 2) +#define LOG_LINESTATE (1U << 3) +#define LOG_FRAMING (1U << 4) + +//#define VERBOSE (LOG_GENERAL | LOG_RXBIT | LOG_RXFLAG | LOG_LINESTATE | LOG_FRAMING) +#include "logmacro.h" + +#define LOGRXBIT(...) LOGMASKED(LOG_RXBIT, __VA_ARGS__) +#define LOGRXFLAG(...) LOGMASKED(LOG_RXFLAG, __VA_ARGS__) +#define LOGLINESTATE(...) LOGMASKED(LOG_LINESTATE, __VA_ARGS__) +#define LOGFRAMING(...) LOGMASKED(LOG_FRAMING, __VA_ARGS__) + + +DEFINE_DEVICE_TYPE(SDLC_LOGGER, sdlc_logger_device, "sdlc_logger", "SDLC/HDLC logger") + + +constexpr std::uint16_t device_sdlc_consumer_interface::POLY_SDLC; + + +device_sdlc_consumer_interface::device_sdlc_consumer_interface(machine_config const &mconfig, device_t &device) : + device_interface(device, "sdlc_consumer"), + m_line_active(0U), + m_discard_bits(0U), + m_in_frame(0U), + m_shift_register(0xffffU), + m_frame_check(0xffffU) +{ +} + +void device_sdlc_consumer_interface::interface_post_start() +{ + device().save_item(NAME(m_line_active)); + device().save_item(NAME(m_discard_bits)); + device().save_item(NAME(m_in_frame)); + device().save_item(NAME(m_shift_register)); + device().save_item(NAME(m_frame_check)); +} + +void device_sdlc_consumer_interface::rx_bit(bool state) +{ + LOGRXBIT("Received bit %u\n", state ? 1U : 0U); + + m_shift_register = (m_shift_register >> 1) | (state ? 0x8000U : 0x0000U); + if (!state && !m_line_active) + { + // any zero bit means the line has become active + LOGLINESTATE("Line became active\n"); + m_line_active = 1U; + line_active(); + } + + if ((m_shift_register & 0xff00U) == 0x7e00U) + { + // a flag opens and closes frames + LOGRXFLAG("Received flag\n"); + if (m_in_frame) + { + LOGFRAMING("End of frame\n"); + m_in_frame = 0U; + frame_end(); + } + m_discard_bits = 8U; + m_frame_check = 0xffffU; + } + else if ((m_shift_register & 0xfffeU) == 0xfffeU) + { + // fifteen consecutive ones is an inactive line condition + if (m_line_active) + { + LOGLINESTATE("Line became inactive\n"); + m_line_active = 0U; + line_inactive(); + } + } + else if ((m_shift_register & 0xfe00U) == 0xfe00U) + { + // seven consecutive ones is a frame abort + if (m_in_frame || m_discard_bits) + { + LOGFRAMING("Received frame abort\n"); + m_in_frame = 0U; + m_discard_bits = 0U; + frame_abort(); + } + } + else + { + // discard the flag as it shifts off + if (m_discard_bits && !--m_discard_bits) + { + LOGFRAMING("Start of frame\n"); + m_in_frame = 1U; + frame_start(); + } + + // discard a zero after five consecutive ones + if (m_in_frame && ((m_shift_register & 0x01f8U) != 0x00f8U)) + { + bool const bit(BIT(m_shift_register, 8)); + m_frame_check = update_frame_check(POLY_SDLC, m_frame_check, bit); + data_bit(bit); + } + } +} + +void device_sdlc_consumer_interface::rx_reset() +{ + LOG("Receive reset\n"); + + m_line_active = 0U; + m_in_frame = 0U; + m_discard_bits = 0U; + m_shift_register = 0xffffU; + m_frame_check = 0xffffU; +} + + +sdlc_logger_device::sdlc_logger_device(machine_config const &mconfig, char const *tag, device_t *owner, std::uint32_t clock) : + device_t(mconfig, SDLC_LOGGER, tag, owner, clock), + device_sdlc_consumer_interface(mconfig, *this), + m_data_nrzi(0U), + m_clock_active(1U), + m_current_data(1U), + m_last_data(1U), + m_current_clock(1U), + m_frame_bits(0U), + m_expected_fcs(0U), + m_buffer() +{ +} + +WRITE_LINE_MEMBER(sdlc_logger_device::clock_w) +{ + if (bool(state) != bool(m_current_clock)) + { + m_current_clock = state ? 1U : 0U; + if (m_current_clock == m_clock_active) + { + bool const bit(m_data_nrzi ? (m_current_data == m_last_data) : m_current_data); + LOGRXBIT("Received bit: %u (%u -> %u)\n", bit ? 1U : 0U, m_last_data, m_current_data); + m_last_data = m_current_data; + rx_bit(bit); + } + } +} + +void sdlc_logger_device::device_start() +{ + m_buffer.reset(new std::uint8_t[BUFFER_BYTES]); + + save_item(NAME(m_data_nrzi)); + save_item(NAME(m_clock_active)); + save_item(NAME(m_current_data)); + save_item(NAME(m_last_data)); + save_item(NAME(m_current_clock)); + save_item(NAME(m_frame_bits)); + save_item(NAME(m_expected_fcs)); + save_pointer(NAME(m_buffer.get()), BUFFER_BYTES); +} + +void sdlc_logger_device::device_reset() +{ +} + +void sdlc_logger_device::frame_start() +{ + m_frame_bits = 0U; + m_expected_fcs = 0xffffU; +} + +void sdlc_logger_device::frame_end() +{ + shift_residual_bits(); + log_frame(false); + m_frame_bits = 0; +} + +void sdlc_logger_device::frame_abort() +{ + logerror("Frame aborted!\n"); + shift_residual_bits(); + log_frame(true); + m_frame_bits = 0U; +} + +void sdlc_logger_device::data_bit(bool value) +{ + if (BUFFER_BITS > m_frame_bits) + { + m_buffer[m_frame_bits >> 3] >>= 1; + m_buffer[m_frame_bits >> 3] |= value ? 0x80U : 0x00U; + } + else if (BUFFER_BITS == m_frame_bits) + { + logerror("Frame buffer overrun!\n"); + } + + if ((16U <= m_frame_bits) && ((BUFFER_BITS + 16U) > m_frame_bits)) + m_expected_fcs = update_frame_check(POLY_SDLC, m_expected_fcs, BIT(m_buffer[(m_frame_bits - 16U) >> 3], m_frame_bits & 0x0007U)); + + ++m_frame_bits; +} + +void sdlc_logger_device::shift_residual_bits() +{ + if (BUFFER_BITS > m_frame_bits) + { + uint32_t const residual_bits(m_frame_bits & 0x0007U); + if (residual_bits) + m_buffer[m_frame_bits >> 3] >>= 8 - residual_bits; + } +} + +void sdlc_logger_device::log_frame(bool partial) const +{ + if (m_frame_bits) + { + std::ostringstream msg; + std::uint32_t const frame_bytes(m_frame_bits >> 3); + std::uint32_t const residual_bits(m_frame_bits & 0x0007U); + util::stream_format(msg, "Received %u-bit %sframe (%u bytes + %u bits)", m_frame_bits, partial ? "partial " : "", frame_bytes, residual_bits); + + if (8U <= m_frame_bits) + { + std::uint8_t const addr(m_buffer[0]); + util::stream_format(msg, " A=%02X%s", addr, (0xffU == addr) ? " (broadcast)" : !addr ? " (no station)" : ""); + } + + if (16U <= m_frame_bits) + { + std::uint8_t const ctrl(m_buffer[1]); + if (!BIT(ctrl, 0)) + { + msg << " I"; + } + else if (!BIT(ctrl, 1)) + { + msg << " S"; + switch (ctrl & 0x0cU) + { + case 0x00U: msg << " RR"; break; + case 0x04U: msg << " RNR"; break; + case 0x08U: msg << " REJ"; break; + } + } + else + { + msg << " U"; + switch (ctrl & 0xecU) + { + case 0x00U: msg << " UI"; break; + case 0x04U: msg << " RIM/SIM"; break; + case 0x0cU: msg << " DM"; break; + case 0x20U: msg << " UP"; break; + case 0x40U: msg << " DISC/RD"; break; + case 0x60U: msg << " UA"; break; + case 0x80U: msg << " SNRM"; break; + case 0x84U: msg << " FRMR"; break; + case 0x9cU: msg << " XID"; break; + case 0xc4U: msg << " CFGR"; break; + case 0xccU: msg << " SNRME"; break; + case 0xe0U: msg << " TEST"; break; + case 0xecU: msg << " BCN"; break; + } + } + + if (!partial && (BUFFER_BITS >= m_frame_bits)) + { + std::uint16_t fcs; + fcs = std::uint16_t(m_buffer[frame_bytes - 2]) >> residual_bits; + fcs |= std::uint16_t(m_buffer[frame_bytes - 1]) << (8 - residual_bits); + if (residual_bits) + fcs |= (std::uint16_t(m_buffer[frame_bytes]) & ((1U << residual_bits) - 1U)) << (16 - residual_bits); + fcs = ~BITSWAP16(fcs, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + util::stream_format(msg, " FCS=%04X", fcs); + if (!is_frame_check_good()) + util::stream_format(msg, " (expected %04X)", m_expected_fcs); + } + } + + if (!partial) + msg << (is_frame_check_good() ? " (good)" : " (bad)"); + + for (std::uint32_t i = 0U; (frame_bytes > i) && (BUFFER_BYTES > i); ++i) + util::stream_format(msg, (i & 0x000fU) ? " %02X" : "\n %02X", m_buffer[i]); + if (residual_bits && (BUFFER_BITS >= m_frame_bits)) + util::stream_format(msg, (residual_bits > 4) ? "%s %02X&%02X" : "%s %01X&%01X", (frame_bytes & 0x000fU) ? "" : "\n ", m_buffer[frame_bytes], (1U << residual_bits) - 1); + + logerror("%s\n", msg.str()); + } +} diff --git a/src/devices/machine/sdlc.h b/src/devices/machine/sdlc.h new file mode 100644 index 00000000000..1b9b8efa832 --- /dev/null +++ b/src/devices/machine/sdlc.h @@ -0,0 +1,116 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +#ifndef MAME_MACHINE_SDLC_H +#define MAME_MACHINE_SDLC_H + +#pragma once + +#include <cstdint> +#include <memory> +#include <utility> + + +#define MCFG_SDLC_LOGGER_DATA_NRZL \ + downcast<sdlc_logger_device &>(*device).clock_active(0); + +#define MCFG_SDLC_LOGGER_DATA_NRZI \ + downcast<sdlc_logger_device &>(*device).clock_active(1); + +#define MCFG_SDLC_LOGGER_CLOCK_ACTIVE_RISING \ + downcast<sdlc_logger_device &>(*device).clock_active(1); + +#define MCFG_SDLC_LOGGER_CLOCK_ACTIVE_FALLING \ + downcast<sdlc_logger_device &>(*device).clock_active(0); + + +class device_sdlc_consumer_interface : public device_interface +{ +public: + static constexpr std::uint16_t POLY_SDLC = 0x1021U; + + template <typename T> + static constexpr u16 update_frame_check(u16 poly, u16 current, T bit) + { + return (current << 1) ^ ((bool(bit) != bool(BIT(current, 15))) ? poly : 0U); + } + +protected: + device_sdlc_consumer_interface(machine_config const &mconfig, device_t &device); + + virtual void interface_post_start() override; + + void rx_bit(bool state); + void rx_reset(); + + bool is_line_active() const { return bool(m_line_active); } + uint16_t get_frame_check() const { return m_frame_check; } + bool is_frame_check_good() const { return 0x1d0fU == m_frame_check; } + +private: + template <typename... Params> void logerror(Params &&... args) { device().logerror(std::forward<Params>(args)...); } + + virtual void frame_start() { } + virtual void frame_end() { } + virtual void frame_abort() { } + virtual void line_active() { } + virtual void line_inactive() { } + virtual void data_bit(bool value) { } + + std::uint8_t m_line_active; + std::uint8_t m_discard_bits; + std::uint8_t m_in_frame; + std::uint16_t m_shift_register; + std::uint16_t m_frame_check; +}; + + +class sdlc_logger_device : public device_t, public device_sdlc_consumer_interface +{ +public: + sdlc_logger_device(machine_config const &mconfig, char const *tag, device_t *owner, std::uint32_t clock); + + // input signals + DECLARE_WRITE_LINE_MEMBER(data_w) { m_current_data = state ? 1U : 0U; } + DECLARE_WRITE_LINE_MEMBER(clock_w); + + // input format configuration + DECLARE_WRITE_LINE_MEMBER(data_nrzi) { m_data_nrzi = state ? 1U : 0U; } + DECLARE_WRITE_LINE_MEMBER(clock_active) { m_clock_active = state ? 1U : 0U; } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + using device_t::logerror; + +private: + enum : std::size_t + { + BUFFER_BYTES = 1024U, + BUFFER_BITS = BUFFER_BYTES << 3 + }; + + virtual void frame_start() override; + virtual void frame_end() override; + virtual void frame_abort() override; + virtual void data_bit(bool value) override; + + void shift_residual_bits(); + void log_frame(bool partial) const; + + std::uint8_t m_data_nrzi; + std::uint8_t m_clock_active; + + std::uint8_t m_current_data; + std::uint8_t m_last_data; + std::uint8_t m_current_clock; + + std::uint32_t m_frame_bits; + std::uint16_t m_expected_fcs; + std::unique_ptr<std::uint8_t []> m_buffer; +}; + + +DECLARE_DEVICE_TYPE(SDLC_LOGGER, sdlc_logger_device) + +#endif // MAME_MACHINE_SDLC_H diff --git a/src/devices/machine/smc91c9x.cpp b/src/devices/machine/smc91c9x.cpp index ee5214d2323..b94f7a29d1f 100644 --- a/src/devices/machine/smc91c9x.cpp +++ b/src/devices/machine/smc91c9x.cpp @@ -4,12 +4,12 @@ SMC91C9X ethernet controller implementation - by Aaron Giles + by Aaron Giles, Jean-François DEL NERO *************************************************************************** Notes: - * only loopback mode really works + * Connected mode working **************************************************************************/ @@ -22,7 +22,9 @@ DEBUGGING ***************************************************************************/ -#define LOG_ETHERNET (0) +//#define VERBOSE 1 +#include "logmacro.h" + #define DISPLAY_STATS (0) @@ -68,14 +70,15 @@ #define EREG_ERCV (3*8 + 6) /* Ethernet MMU commands */ -#define ECMD_NOP 0 -#define ECMD_ALLOCATE 1 -#define ECMD_RESET_MMU 2 -#define ECMD_REMOVE 3 -#define ECMD_REMOVE_RELEASE 4 -#define ECMD_RELEASE_PACKET 5 -#define ECMD_ENQUEUE_PACKET 6 -#define ECMD_RESET_FIFOS 7 +#define ECMD_NOP 0 +#define ECMD_ALLOCATE 2 +#define ECMD_RESET_MMU 4 +#define ECMD_REMOVE_TOPFRAME_RX 6 +#define ECMD_REMOVE_TOPFRAME_TX 7 +#define ECMD_REMOVE_RELEASE_TOPFRAME_RX 8 +#define ECMD_RELEASE_PACKET 10 +#define ECMD_ENQUEUE_PACKET 12 +#define ECMD_RESET_FIFOS 14 /* Ethernet interrupt bits */ #define EINT_RCV 0x01 @@ -99,16 +102,15 @@ static const char *const ethernet_regname[64] = "(7.0)", "(7.1)", "(7.2)", "(7.3)", "(7.4)", "(7.5)", "(7.6)", "BANK" }; - - /*************************************************************************** DEVICE INTERFACE ***************************************************************************/ smc91c9x_device::smc91c9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) + , device_network_interface(mconfig, *this, 10.0f) , m_irq_handler(*this) - , m_link_unconnected(true) + , m_link_unconnected(false) { } @@ -119,15 +121,12 @@ smc91c9x_device::smc91c9x_device(const machine_config &mconfig, device_type type void smc91c9x_device::device_start() { m_irq_handler.resolve_safe(); - // TX timer - m_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(smc91c9x_device::finish_enqueue), this)); /* register ide states */ save_item(NAME(m_reg)); save_item(NAME(m_regmask)); save_item(NAME(m_irq_state)); save_item(NAME(m_alloc_count)); - save_item(NAME(m_fifo_count)); save_item(NAME(m_rx)); save_item(NAME(m_tx)); save_item(NAME(m_sent)); @@ -140,14 +139,39 @@ void smc91c9x_device::device_start() void smc91c9x_device::device_reset() { - memset(m_reg, 0, sizeof(m_reg)); - memset(m_regmask, 0, sizeof(m_regmask)); + std::fill(std::begin(m_reg), std::end(m_reg), 0); + + std::fill(std::begin(m_rx), std::end(m_rx), 0); + std::fill(std::begin(m_tx), std::end(m_tx), 0); + + std::fill(std::begin(m_regmask), std::end(m_regmask), 0); + m_irq_state = 0; m_alloc_count = 0; - m_fifo_count = 0; + rx_fifo_out = 0; + rx_fifo_in = 0; + + tx_fifo_out = 0; + tx_fifo_in = 0; + m_sent = 0; m_recd = 0; + osd_list_network_adapters(); + + unsigned char const *const mac = (const unsigned char *)get_mac(); + + if (VERBOSE & LOG_GENERAL) + { + logerror("MAC : "); + for (int i = 0; i < ETHERNET_ADDR_SIZE; i++) + logerror("%.2X", mac[i]); + + logerror("\n"); + } + + set_promisc(true); + m_reg[EREG_TCR] = 0x0000; m_regmask[EREG_TCR] = 0x3d87; m_reg[EREG_EPH_STATUS] = 0x0000; m_regmask[EREG_EPH_STATUS] = 0x0000; m_reg[EREG_RCR] = 0x0000; m_regmask[EREG_RCR] = 0xc307; @@ -158,9 +182,17 @@ void smc91c9x_device::device_reset() m_reg[EREG_CONFIG] = 0x0030; m_regmask[EREG_CONFIG] = 0x17c6; m_reg[EREG_BASE] = 0x1866; m_regmask[EREG_BASE] = 0xfffe; - m_reg[EREG_IA0_1] = 0x0000; m_regmask[EREG_IA0_1] = 0xffff; - m_reg[EREG_IA2_3] = 0x0000; m_regmask[EREG_IA2_3] = 0xffff; - m_reg[EREG_IA4_5] = 0x0000; m_regmask[EREG_IA4_5] = 0xffff; + + // Default MAC + m_reg[EREG_IA0_1] = 0x1300; m_regmask[EREG_IA0_1] = 0xffff; + m_reg[EREG_IA2_3] = 0x12F7; m_regmask[EREG_IA2_3] = 0xffff; + m_reg[EREG_IA4_5] = 0x5634; m_regmask[EREG_IA4_5] = 0xffff; + + // Interface MAC + m_reg[EREG_IA0_1] = mac[0] | (mac[1]<<8); + m_reg[EREG_IA2_3] = mac[2] | (mac[3]<<8); + m_reg[EREG_IA4_5] = mac[4] | (mac[5]<<8); + m_reg[EREG_GENERAL_PURP] = 0x0000; m_regmask[EREG_GENERAL_PURP] = 0xffff; m_reg[EREG_CONTROL] = 0x0100; m_regmask[EREG_CONTROL] = 0x68e7; @@ -181,7 +213,6 @@ void smc91c9x_device::device_reset() m_reg[EREG_ERCV] = 0x331f; m_regmask[EREG_ERCV] = 0x009f; update_ethernet_irq(); - m_tx_timer->adjust(attotime::never); } @@ -192,7 +223,6 @@ smc91c94_device::smc91c94_device(const machine_config &mconfig, const char *tag, { } - DEFINE_DEVICE_TYPE(SMC91C96, smc91c96_device, "smc91c96", "SMC91C96 Ethernet Controller") smc91c96_device::smc91c96_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) @@ -200,6 +230,182 @@ smc91c96_device::smc91c96_device(const machine_config &mconfig, const char *tag, { } +void smc91c9x_device::clear_tx_fifo() +{ + tx_fifo_in = 0; + tx_fifo_out = 0; + std::fill(std::begin(m_tx), std::end(m_tx), 0); +} + +void smc91c9x_device::clear_rx_fifo() +{ + rx_fifo_in = 0; + rx_fifo_out = 0; + std::fill(std::begin(m_rx), std::end(m_rx), 0); +} + +int smc91c9x_device::is_broadcast(uint8_t mac_address[]) +{ + int i; + + i = 0; + + while(mac_address[i] == 0xFF) + { + i++; + } + + if ( i == 6 ) + return 1; + + return 0; +} + + +int smc91c9x_device::ethernet_packet_is_for_me(const uint8_t mac_address[]) +{ + // tcpdump -i eth0 -q ether host 08:00:1e:01:ae:a5 or ether broadcast or ether dst 09:00:1e:00:00:00 or ether dst 09:00:1e:00:00:01 + // wireshark filter: eth.addr eq 08:00:1e:01:ae:a5 or eth.dst eq ff:ff:ff:ff:ff:ff or eth.dst eq 09:00:1e:00:00:00 or eth.dst eq 09:00:1e:00:00:01 + + int i; + uint8_t local_address[ETHERNET_ADDR_SIZE]; + + LOG("\n"); + + local_address[0] = (m_reg[EREG_IA0_1]>>0) & 0xFF; + local_address[1] = (m_reg[EREG_IA0_1]>>8) & 0xFF; + local_address[2] = (m_reg[EREG_IA2_3]>>0) & 0xFF; + local_address[3] = (m_reg[EREG_IA2_3]>>8) & 0xFF; + local_address[4] = (m_reg[EREG_IA4_5]>>0) & 0xFF; + local_address[5] = (m_reg[EREG_IA4_5]>>8) & 0xFF; + + if (VERBOSE & LOG_GENERAL) + { + for ( i = 0 ; i < ETHERNET_ADDR_SIZE ; i++ ) + { + logerror("%.2X",local_address[i]); + } + logerror("="); + for ( i = 0 ; i < ETHERNET_ADDR_SIZE ; i++ ) + { + logerror("%.2X",mac_address[i]); + } + logerror("?"); + } + + // skip Ethernet broadcast packets if RECV_BROAD is not set + if (is_broadcast((uint8_t *)mac_address)) + { + LOG(" -- Broadcast rx\n"); + return 2; + } + + if (memcmp(mac_address, local_address, ETHERNET_ADDR_SIZE) == 0) + { + LOG(" -- Address Match\n"); + return 1; + } + + LOG(" -- Not Matching\n"); + + return 0; +} + +/*************************************************************************** + recv_cb - receive callback - receive and process an ethernet packet + ***************************************************************************/ + +void smc91c9x_device::recv_cb(uint8_t *data, int length) +{ + LOG("recv_cb : %d/0x%x\n",length,length); + + int const isforme = ethernet_packet_is_for_me( data ); + + if (isforme==1 && (length >= ETHERNET_ADDR_SIZE) && (VERBOSE & LOG_GENERAL)) + { + logerror("RX: "); + for (int i = 0; i < ETHERNET_ADDR_SIZE; i++) + logerror("%.2X", data[i]); + + logerror(" "); + + for (int i = 0; i < length-ETHERNET_ADDR_SIZE; i++) + logerror("%.2X", data[ETHERNET_ADDR_SIZE + i]); + + logerror(" - IsForMe %d - %d/0x%x bytes\n", isforme, length, length); + } + + if ( (length < ETHERNET_ADDR_SIZE || !isforme) && !(m_reg[EREG_RCR] & 0x0100) ) + { + LOG("\n"); + + // skip packet + return; + } + + /* signal a receive */ + + /* compute the packet length */ + + if ( ( length < ( ETHER_BUFFER_SIZE - ( 2+2+2 ) ) ) ) + { + uint8_t *const packet = &m_rx[ ( rx_fifo_in & ( ETHER_RX_BUFFERS - 1 ) ) * ETHER_BUFFER_SIZE]; + + std::fill_n(packet, ETHER_BUFFER_SIZE, 0); + + int dst = 0; + + // build up the packet + + // Status word + packet[dst++] = 0x00; + + // set the broadcast flag + if ( isforme == 2 ) + packet[dst++] |= 0x40; + else + packet[dst++] = 0x00; + + //bytes count + packet[dst++] = 0x00; + packet[dst++] = 0x00; + + memcpy(&packet[dst], data, length ); + dst += length; + + if ( dst & 1 ) + { + // ODD Frame + packet[dst++] = 0x40 | 0x20; // Control + } + else + { + packet[dst++] = 0x00; // Pad + packet[dst++] = 0x40 | 0x00; // Control + } + + dst += 2; + + dst &= 0x7FF; + + packet[2] = (dst&0xFF); + packet[3] = (dst) >> 8; + + m_reg[EREG_INTERRUPT] |= EINT_RCV; + m_reg[EREG_FIFO_PORTS] &= ~0x8000; + + rx_fifo_in = (rx_fifo_in + 1) & ( ETHER_RX_BUFFERS - 1 ); + } + else + { + LOG("Rejected ! Fifo Full ?"); + } + + update_ethernet_irq(); + + LOG("\n"); +} + /*************************************************************************** INTERNAL HELPERS ***************************************************************************/ @@ -210,14 +416,12 @@ smc91c96_device::smc91c96_device(const machine_config &mconfig, const char *tag, void smc91c9x_device::update_ethernet_irq() { - uint8_t mask = m_reg[EREG_INTERRUPT] >> 8; - uint8_t state = m_reg[EREG_INTERRUPT] & 0xff; + uint8_t const mask = m_reg[EREG_INTERRUPT] >> 8; + uint8_t const state = m_reg[EREG_INTERRUPT] & 0xff; /* update the IRQ state */ m_irq_state = ((mask & state) != 0); - if (!m_irq_handler.isnull()) { - m_irq_handler(m_irq_state ? ASSERT_LINE : CLEAR_LINE); - } + m_irq_handler(m_irq_state ? ASSERT_LINE : CLEAR_LINE); } @@ -227,97 +431,84 @@ void smc91c9x_device::update_ethernet_irq() void smc91c9x_device::update_stats() { - if (DISPLAY_STATS) + if ( DISPLAY_STATS ) popmessage("Sent:%d Rec'd:%d", m_sent, m_recd); } /*------------------------------------------------- - finish_enqueue - complete an enqueued packet + send_frame - push a frame to the interface -------------------------------------------------*/ -TIMER_CALLBACK_MEMBER(smc91c9x_device::finish_enqueue) +int smc91c9x_device::send_frame() { - int is_broadcast = (m_tx[4] == 0xff && m_tx[5] == 0xff && m_tx[6] == 0xff && + bool const is_broadcast = (m_tx[4] == 0xff && m_tx[5] == 0xff && m_tx[6] == 0xff && m_tx[7] == 0xff && m_tx[8] == 0xff && m_tx[9] == 0xff); + tx_fifo_in = ( tx_fifo_in + 1 ) & ( ETHER_TX_BUFFERS - 1 ); + + uint8_t *const tx_buffer = &m_tx[(tx_fifo_out & (ETHER_TX_BUFFERS-1))* ETHER_BUFFER_SIZE]; + tx_fifo_out = ((tx_fifo_out + 1)& (ETHER_TX_BUFFERS-1)); + /* update the EPH register and stuff it in the first transmit word */ m_reg[EREG_EPH_STATUS] = 0x0001; + if (is_broadcast) m_reg[EREG_EPH_STATUS] |= 0x0040; - m_tx[0] = m_reg[EREG_EPH_STATUS]; - m_tx[1] = m_reg[EREG_EPH_STATUS] >> 8; + + tx_buffer[0] = m_reg[EREG_EPH_STATUS]; + tx_buffer[1] = m_reg[EREG_EPH_STATUS] >> 8; /* signal a transmit interrupt and mark the transmit buffer empty */ m_reg[EREG_INTERRUPT] |= EINT_TX; m_reg[EREG_INTERRUPT] |= EINT_TX_EMPTY; m_reg[EREG_FIFO_PORTS] |= 0x0080; m_sent++; + update_stats(); - /* loopback? */ - if (m_reg[EREG_TCR] & 0x2002) { - if (m_fifo_count < ETHER_RX_BUFFERS) - { - int buffer_len = ((m_tx[3] << 8) | m_tx[2]) & 0x7ff; - uint8_t *packet = &m_rx[m_fifo_count++ * ETHER_BUFFER_SIZE]; - int packet_len; - - /* compute the packet length */ - packet_len = buffer_len - 6; - if (packet[buffer_len - 1] & 0x20) - packet_len++; - - /* build up the packet */ - packet[0] = 0x0000; - packet[1] = 0x0000; - packet[2] = buffer_len; - packet[3] = buffer_len >> 8; - memcpy(&packet[4], &m_tx[4], 6); - memcpy(&packet[10], &m_tx[10], 6); - memcpy(&packet[16], &m_tx[16], buffer_len - 16); - - /* set the broadcast flag */ - if (is_broadcast) - packet[1] |= 0x40; - - /* pad? */ - if (m_reg[EREG_TCR & 0x0080]) - if (packet_len < 64) - { - memset(&packet[buffer_len], 0, 64 + 6 - buffer_len); - packet[buffer_len - 1] = 0; - buffer_len = 64 + 6; - packet[2] = buffer_len; - packet[3] = buffer_len >> 8; - } + int buffer_len = ((tx_buffer[3] << 8) | tx_buffer[2]) & 0x7ff; - /* signal a receive */ - m_reg[EREG_INTERRUPT] |= EINT_RCV; - m_reg[EREG_FIFO_PORTS] &= ~0x8000; - } + if (VERBOSE & LOG_GENERAL) + { + logerror("TX: "); + for (int i = 4; i < (4 + ETHERNET_ADDR_SIZE); i++) + logerror("%.2X", tx_buffer[i]); + + logerror(" "); + + for (int i = 0; i < (buffer_len - (ETHERNET_ADDR_SIZE + 4)); i++) + logerror("%.2X", tx_buffer[4 + ETHERNET_ADDR_SIZE + i]); + + logerror("--- %d/0x%x bytes\n", buffer_len, buffer_len); } - else if (m_link_unconnected) { - // Set lost carrier - if (m_reg[EREG_TCR] & 0x0400) { - m_reg[EREG_EPH_STATUS] |= 0x400; - // Clear Tx Enable on error - m_reg[EREG_TCR] &= ~0x1; + + if ( buffer_len > 4 ) + { + // odd or even sized frame ? + if (tx_buffer[buffer_len-1] & 0x20) + buffer_len--; + else + buffer_len -= 2; + + if (!(m_reg[EREG_TCR] & 0x2002)) + { + // No loopback... Send the frame + if ( !send(&tx_buffer[4], buffer_len-4) ) + { + // FIXME: failed to send the Ethernet packet + //logerror("failed to send Ethernet packet\n"); + //LOG(this,("read_command_port(): !!! failed to send Ethernet packet")); + } } - // Set signal quality error - if (m_reg[EREG_TCR] & 0x1000) { - m_reg[EREG_EPH_STATUS] |= 0x20; - // Clear Tx Enable on error - m_reg[EREG_TCR] &= ~0x1; + else + { + // TODO loopback mode : Push the frame to the RX FIFO. } - // signal a no transmit - m_reg[EREG_INTERRUPT] &= ~EINT_TX; - // Set a ethernet phy status interrupt - m_reg[EREG_INTERRUPT] |= EINT_EPH; } - update_ethernet_irq(); -} + return 0; +} /*------------------------------------------------- process_command - handle MMU commands @@ -325,66 +516,114 @@ TIMER_CALLBACK_MEMBER(smc91c9x_device::finish_enqueue) void smc91c9x_device::process_command(uint16_t data) { - switch ((data >> 5) & 7) + switch ((data >> 4) & 0xF) { case ECMD_NOP: - if (LOG_ETHERNET) - logerror(" NOP\n"); + LOG(" NOP\n"); break; case ECMD_ALLOCATE: - if (LOG_ETHERNET) - logerror(" ALLOCATE MEMORY FOR TX (%d)\n", (data & 7)); + LOG(" ALLOCATE MEMORY FOR TX (%d)\n", (data & 7)); m_reg[EREG_PNR_ARR] &= ~0xff00; - m_reg[EREG_PNR_ARR] |= m_alloc_count++ << 8; + m_reg[EREG_PNR_ARR] |= (m_alloc_count++ & 0x7F) << 8; m_reg[EREG_INTERRUPT] |= 0x0008; update_ethernet_irq(); break; case ECMD_RESET_MMU: - if (LOG_ETHERNET) - logerror(" RESET MMU\n"); + /* + 0100 + - RESET MMU TO INITIAL STATE - + Frees all memory allocations, clears relevant + interrupts, resets packet FIFO pointers. + */ + + LOG(" RESET MMU\n"); + // Flush fifos. + clear_tx_fifo(); + clear_rx_fifo(); break; - case ECMD_REMOVE: - if (LOG_ETHERNET) - logerror(" REMOVE FRAME FROM RX FIFO\n"); + case ECMD_REMOVE_TOPFRAME_TX: + LOG(" REMOVE FRAME FROM TX FIFO\n"); break; - case ECMD_REMOVE_RELEASE: - if (LOG_ETHERNET) - logerror(" REMOVE AND RELEASE FRAME FROM RX FIFO\n"); + case ECMD_REMOVE_TOPFRAME_RX: + LOG(" REMOVE FRAME FROM RX FIFO\n"); + + case ECMD_REMOVE_RELEASE_TOPFRAME_RX: + LOG(" REMOVE AND RELEASE FRAME FROM RX FIFO (RXI=%d RXO=%d)\n", rx_fifo_in & (ETHER_RX_BUFFERS - 1), rx_fifo_out & (ETHER_RX_BUFFERS - 1)); + m_reg[EREG_INTERRUPT] &= ~EINT_RCV; - if (m_fifo_count > 0) - m_fifo_count--; - if (m_fifo_count > 0) + + if ( (rx_fifo_in & ( ETHER_RX_BUFFERS - 1 ) ) != (rx_fifo_out & ( ETHER_RX_BUFFERS - 1 ) ) ) + rx_fifo_out = ( (rx_fifo_out + 1) & ( ETHER_RX_BUFFERS - 1 ) ); + + if ( (rx_fifo_in & ( ETHER_RX_BUFFERS - 1 ) ) != (rx_fifo_out & ( ETHER_RX_BUFFERS - 1 ) ) ) { - memmove(&m_rx[0], &m_rx[ETHER_BUFFER_SIZE], m_fifo_count * ETHER_BUFFER_SIZE); m_reg[EREG_INTERRUPT] |= EINT_RCV; m_reg[EREG_FIFO_PORTS] &= ~0x8000; } else m_reg[EREG_FIFO_PORTS] |= 0x8000; + update_ethernet_irq(); m_recd++; update_stats(); break; case ECMD_RELEASE_PACKET: - if (LOG_ETHERNET) - logerror(" RELEASE SPECIFIC PACKET\n"); + LOG(" RELEASE SPECIFIC PACKET\n"); break; case ECMD_ENQUEUE_PACKET: - if (LOG_ETHERNET) - logerror(" ENQUEUE TX PACKET\n"); - // Set some delay before tranmit ends - m_tx_timer->adjust(attotime::from_usec(100)); + LOG(" ENQUEUE TX PACKET\n"); + + if ( m_link_unconnected ) + { + // Set lost carrier + if ( m_reg[EREG_TCR] & 0x0400 ) + { + m_reg[EREG_EPH_STATUS] |= 0x400; + // Clear Tx Enable on error + m_reg[EREG_TCR] &= ~0x1; + } + + // Set signal quality error + if ( m_reg[EREG_TCR] & 0x1000 ) + { + m_reg[EREG_EPH_STATUS] |= 0x20; + // Clear Tx Enable on error + m_reg[EREG_TCR] &= ~0x1; + } + + // signal a no transmit + m_reg[EREG_INTERRUPT] &= ~EINT_TX; + // Set a ethernet phy status interrupt + m_reg[EREG_INTERRUPT] |= EINT_EPH; + + // Flush fifos. + clear_tx_fifo(); + clear_rx_fifo(); + } + else + { + if ( m_reg[EREG_TCR] & 0x0001 ) // TX EN ? + { + send_frame(); + } + } + + update_ethernet_irq(); + break; case ECMD_RESET_FIFOS: - if (LOG_ETHERNET) - logerror(" RESET TX FIFOS\n"); + LOG(" RESET TX FIFOS\n"); + // Flush fifos. + clear_tx_fifo(); + clear_rx_fifo(); + break; } // Set Busy (clear on next read) @@ -407,8 +646,9 @@ READ16_MEMBER( smc91c9x_device::read ) /* determine the effective register */ offset %= 8; - if (offset != EREG_BANK) + if ( offset != EREG_BANK ) offset += 8 * (m_reg[EREG_BANK] & 7); + result = m_reg[offset]; switch (offset) @@ -419,7 +659,7 @@ READ16_MEMBER( smc91c9x_device::read ) break; case EREG_PNR_ARR: - if (ACCESSING_BITS_8_15) + if ( ACCESSING_BITS_8_15 ) { m_reg[EREG_INTERRUPT] &= ~0x0008; update_ethernet_irq(); @@ -429,19 +669,29 @@ READ16_MEMBER( smc91c9x_device::read ) case EREG_DATA_0: /* data register */ case EREG_DATA_1: /* data register */ { - uint8_t *buffer = (m_reg[EREG_POINTER] & 0x8000) ? m_rx : m_tx; + uint8_t *buffer; int addr = m_reg[EREG_POINTER] & 0x7ff; + + if ( m_reg[EREG_POINTER] & 0x8000 ) + { + buffer = &m_rx[(rx_fifo_out & ( ETHER_RX_BUFFERS - 1 )) * ETHER_BUFFER_SIZE]; + } + else + { + buffer = (uint8_t *)&m_tx[(tx_fifo_in & (ETHER_TX_BUFFERS-1))* ETHER_BUFFER_SIZE];; + } + result = buffer[addr++]; - if (ACCESSING_BITS_8_15) + if ( ACCESSING_BITS_8_15 ) result |= buffer[addr++] << 8; - if (m_reg[EREG_POINTER] & 0x4000) + if ( m_reg[EREG_POINTER] & 0x4000 ) m_reg[EREG_POINTER] = (m_reg[EREG_POINTER] & ~0x7ff) | (addr & 0x7ff); break; } } - if (LOG_ETHERNET && offset != EREG_BANK) - logerror("%s:smc91c9x_r(%s) = %04X & %04X\n", machine().describe_context(), ethernet_regname[offset], result, mem_mask); + if (offset != EREG_BANK) + LOG("%s:smc91c9x_r(%s) = %04X & %04X\n", machine().describe_context(), ethernet_regname[offset], result, mem_mask); return result; } @@ -452,95 +702,91 @@ READ16_MEMBER( smc91c9x_device::read ) WRITE16_MEMBER( smc91c9x_device::write ) { - // uint16_t olddata; - /* determine the effective register */ offset %= 8; if (offset != EREG_BANK) offset += 8 * (m_reg[EREG_BANK] & 7); /* update the data generically */ - // olddata = m_reg[offset]; + + if (offset != 7 && offset < sizeof(m_reg)) + LOG("%s:smc91c9x_w(%s) = [%04X]<-%04X & (%04X & %04X)\n", machine().describe_context(), ethernet_regname[offset], offset, data, mem_mask , m_regmask[offset]); + mem_mask &= m_regmask[offset]; COMBINE_DATA(&m_reg[offset]); - if (LOG_ETHERNET && offset != 7) - logerror("%s:smc91c9x_w(%s) = %04X & %04X\n", machine().describe_context(), ethernet_regname[offset], data, mem_mask); - /* handle it */ switch (offset) { case EREG_TCR: /* transmit control register */ // Setting Tx Enable clears some status and interrupts - if (data & 0x1) { + if ( data & 0x1 ) { m_reg[EREG_EPH_STATUS] &= ~0x420; m_reg[EREG_INTERRUPT] &= ~EINT_EPH; update_ethernet_irq(); } - if (LOG_ETHERNET) - { - if (data & 0x2000) logerror(" EPH LOOP\n"); - if (data & 0x1000) logerror(" STP SQET\n"); - if (data & 0x0800) logerror(" FDUPLX\n"); - if (data & 0x0400) logerror(" MON_CSN\n"); - if (data & 0x0100) logerror(" NOCRC\n"); - if (data & 0x0080) logerror(" PAD_EN\n"); - if (data & 0x0004) logerror(" FORCOL\n"); - if (data & 0x0002) logerror(" LOOP\n"); - if (data & 0x0001) logerror(" TXENA\n"); - } + + if (data & 0x2000) LOG(" EPH LOOP\n"); + if (data & 0x1000) LOG(" STP SQET\n"); + if (data & 0x0800) LOG(" FDUPLX\n"); + if (data & 0x0400) LOG(" MON_CSN\n"); + if (data & 0x0100) LOG(" NOCRC\n"); + if (data & 0x0080) LOG(" PAD_EN\n"); + if (data & 0x0004) LOG(" FORCOL\n"); + if (data & 0x0002) LOG(" LOOP\n"); + if (data & 0x0001) LOG(" TXENA\n"); break; case EREG_RCR: /* receive control register */ - if (LOG_ETHERNET) + + if ( data & 0x8000 ) { - if (data & 0x8000) reset(); - if (data & 0x8000) logerror(" SOFT RST\n"); - if (data & 0x4000) logerror(" FILT_CAR\n"); - if (data & 0x0200) logerror(" STRIP CRC\n"); - if (data & 0x0100) logerror(" RXEN\n"); - if (data & 0x0004) logerror(" ALMUL\n"); - if (data & 0x0002) logerror(" PRMS\n"); - if (data & 0x0001) logerror(" RX_ABORT\n"); + clear_rx_fifo(); + clear_tx_fifo(); } - break; - case EREG_CONFIG: /* configuration register */ - if (LOG_ETHERNET) + if ( !(data & 0x0100) ) { - if (data & 0x1000) logerror(" NO WAIT\n"); - if (data & 0x0400) logerror(" FULL STEP\n"); - if (data & 0x0200) logerror(" SET SQLCH\n"); - if (data & 0x0100) logerror(" AUI SELECT\n"); - if (data & 0x0080) logerror(" 16 BIT\n"); - if (data & 0x0040) logerror(" DIS LINK\n"); - if (data & 0x0004) logerror(" INT SEL1\n"); - if (data & 0x0002) logerror(" INT SEL0\n"); + clear_rx_fifo(); } + + if (data & 0x8000) reset(); + if (data & 0x8000) LOG(" SOFT RST\n"); + if (data & 0x4000) LOG(" FILT_CAR\n"); + if (data & 0x0200) LOG(" STRIP CRC\n"); + if (data & 0x0100) LOG(" RXEN\n"); + if (data & 0x0004) LOG(" ALMUL\n"); + if (data & 0x0002) LOG(" PRMS\n"); + if (data & 0x0001) LOG(" RX_ABORT\n"); + break; + + case EREG_CONFIG: /* configuration register */ + if (data & 0x1000) LOG(" NO WAIT\n"); + if (data & 0x0400) LOG(" FULL STEP\n"); + if (data & 0x0200) LOG(" SET SQLCH\n"); + if (data & 0x0100) LOG(" AUI SELECT\n"); + if (data & 0x0080) LOG(" 16 BIT\n"); + if (data & 0x0040) LOG(" DIS LINK\n"); + if (data & 0x0004) LOG(" INT SEL1\n"); + if (data & 0x0002) LOG(" INT SEL0\n"); break; case EREG_BASE: /* base address register */ - if (LOG_ETHERNET) - { - logerror(" base = $%04X\n", (data & 0xe000) | ((data & 0x1f00) >> 3)); - logerror(" romsize = %d\n", ((data & 0xc0) >> 6)); - logerror(" romaddr = $%05X\n", ((data & 0x3e) << 13)); - } + LOG(" base = $%04X\n", (data & 0xe000) | ((data & 0x1f00) >> 3)); + LOG(" romsize = %d\n", ((data & 0xc0) >> 6)); + LOG(" romaddr = $%05X\n", ((data & 0x3e) << 13)); break; case EREG_CONTROL: /* control register */ - if (LOG_ETHERNET) - { - if (data & 0x4000) logerror(" RCV_BAD\n"); - if (data & 0x2000) logerror(" PWRDN\n"); - if (data & 0x0800) logerror(" AUTO RELEASE\n"); - if (data & 0x0080) logerror(" LE ENABLE\n"); - if (data & 0x0040) logerror(" CR ENABLE\n"); - if (data & 0x0020) logerror(" TE ENABLE\n"); - if (data & 0x0004) logerror(" EEPROM SELECT\n"); - if (data & 0x0002) logerror(" RELOAD\n"); - if (data & 0x0001) logerror(" STORE\n"); - } + if (data & 0x4000) LOG(" RCV_BAD\n"); + if (data & 0x2000) LOG(" PWRDN\n"); + if (data & 0x0800) LOG(" AUTO RELEASE\n"); + if (data & 0x0080) LOG(" LE ENABLE\n"); + if (data & 0x0040) LOG(" CR ENABLE\n"); + if (data & 0x0020) LOG(" TE ENABLE\n"); + if (data & 0x0004) LOG(" EEPROM SELECT\n"); + if (data & 0x0002) LOG(" RELOAD\n"); + if (data & 0x0001) LOG(" STORE\n"); break; case EREG_MMU_COMMAND: /* command register */ @@ -550,12 +796,22 @@ WRITE16_MEMBER( smc91c9x_device::write ) case EREG_DATA_0: /* data register */ case EREG_DATA_1: /* data register */ { - uint8_t *buffer = (m_reg[EREG_POINTER] & 0x8000) ? m_rx : m_tx; + uint8_t *buffer; int addr = m_reg[EREG_POINTER] & 0x7ff; + + if ( m_reg[EREG_POINTER] & 0x8000 ) + { + buffer = &m_rx[(rx_fifo_out & ( ETHER_RX_BUFFERS - 1 )) * ETHER_BUFFER_SIZE]; + } + else + { + buffer = (uint8_t *)&m_tx[(tx_fifo_in & (ETHER_TX_BUFFERS-1))* ETHER_BUFFER_SIZE];; + } + buffer[addr++] = data; - if (ACCESSING_BITS_8_15) + if ( ACCESSING_BITS_8_15 ) buffer[addr++] = data >> 8; - if (m_reg[EREG_POINTER] & 0x4000) + if ( m_reg[EREG_POINTER] & 0x4000 ) m_reg[EREG_POINTER] = (m_reg[EREG_POINTER] & ~0x7ff) | (addr & 0x7ff); break; } @@ -563,7 +819,7 @@ WRITE16_MEMBER( smc91c9x_device::write ) case EREG_INTERRUPT: m_reg[EREG_INTERRUPT] &= ~(data & 0x56); // Need to clear tx int here for vegas cartfury - if (m_reg[EREG_FIFO_PORTS] & 0x0080) + if ( m_reg[EREG_FIFO_PORTS] & 0x0080 ) m_reg[EREG_INTERRUPT] &= ~EINT_TX; update_ethernet_irq(); break; diff --git a/src/devices/machine/smc91c9x.h b/src/devices/machine/smc91c9x.h index 78627fb58d3..9ff6229d466 100644 --- a/src/devices/machine/smc91c9x.h +++ b/src/devices/machine/smc91c9x.h @@ -4,7 +4,7 @@ SMC91C9X ethernet controller implementation - by Aaron Giles + by Aaron Giles, Jean-François DEL NERO **************************************************************************/ @@ -15,7 +15,7 @@ TYPE DEFINITIONS ***************************************************************************/ -class smc91c9x_device : public device_t +class smc91c9x_device : public device_t,public device_network_interface { public: template <class Object> static devcb_base &set_irq_callback(device_t &device, Object &&cb) { return downcast<smc91c9x_device &>(device).m_irq_handler.set_callback(std::forward<Object>(cb)); } @@ -23,6 +23,8 @@ public: DECLARE_READ16_MEMBER( read ); DECLARE_WRITE16_MEMBER( write ); + virtual void recv_cb(uint8_t *data, int length) override; + protected: smc91c9x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -32,7 +34,9 @@ protected: private: static constexpr unsigned ETHER_BUFFER_SIZE = 2048; - static constexpr unsigned ETHER_RX_BUFFERS = 4; + static constexpr unsigned ETHER_RX_BUFFERS = 16; + static constexpr unsigned ETHER_TX_BUFFERS = 16; + static constexpr unsigned ETHERNET_ADDR_SIZE = 6; // internal state devcb_write_line m_irq_handler; @@ -51,19 +55,29 @@ private: uint8_t m_alloc_count; /* transmit/receive FIFOs */ - uint8_t m_fifo_count; + uint32_t rx_fifo_out; + uint32_t rx_fifo_in; uint8_t m_rx[ETHER_BUFFER_SIZE * ETHER_RX_BUFFERS]; - uint8_t m_tx[ETHER_BUFFER_SIZE]; + + uint32_t tx_fifo_out; + uint32_t tx_fifo_in; + uint8_t m_tx[ETHER_BUFFER_SIZE * ETHER_TX_BUFFERS]; /* counters */ uint32_t m_sent; uint32_t m_recd; + int ethernet_packet_is_for_me(const uint8_t mac_address[]); + int is_broadcast(uint8_t mac_address[]); + void update_ethernet_irq(); void update_stats(); - TIMER_CALLBACK_MEMBER(finish_enqueue); + void process_command(uint16_t data); - emu_timer* m_tx_timer; + void clear_tx_fifo(); + void clear_rx_fifo(); + + int send_frame(); }; diff --git a/src/devices/machine/upd4701.cpp b/src/devices/machine/upd4701.cpp index 0875ce31861..7a02e8bf1e4 100644 --- a/src/devices/machine/upd4701.cpp +++ b/src/devices/machine/upd4701.cpp @@ -354,11 +354,12 @@ READ8_MEMBER(upd4701_device::read_y) READ8_MEMBER(upd4701_device::read_xy) { + bool old_cs = m_cs; cs_w(0); xy_w(BIT(offset, 1)); ul_w(BIT(offset, 0)); u8 result = d_r(space, 0); - cs_w(1); + cs_w(old_cs); return result; } diff --git a/src/devices/machine/vrc5074.cpp b/src/devices/machine/vrc5074.cpp index ca4b1540df7..8471d631c47 100644 --- a/src/devices/machine/vrc5074.cpp +++ b/src/devices/machine/vrc5074.cpp @@ -877,6 +877,8 @@ WRITE32_MEMBER(vrc5074_device::cpu_reg_w) map_cpu_space(); break; case NREG_CPUSTAT + 0: /* CPU status */ + if (data & 0x1) logerror("cpu_reg_w: System Cold Reset\n"); + if (data & 0x2) logerror("cpu_reg_w: CPU Warm Reset\n"); case NREG_CPUSTAT + 1: /* CPU status */ if (LOG_NILE) logerror("%08X:NILE WRITE: CPU status(%03X) = %08X & %08X\n", m_cpu_space->device().safe_pc(), offset * 4, data, mem_mask); logit = 0; @@ -1003,7 +1005,7 @@ READ32_MEMBER(vrc5074_device::serial_r) { uint32_t result = m_uart->ins8250_r(space, offset>>1); - if (LOG_NILE) + if (0 && LOG_NILE) logerror("%06X:serial_r offset %03X = %08X (%08x)\n", m_cpu_space->device().safe_pc(), offset>>1, result, offset*4); return result; } @@ -1011,8 +1013,17 @@ READ32_MEMBER(vrc5074_device::serial_r) WRITE32_MEMBER(vrc5074_device::serial_w) { m_uart->ins8250_w(space, offset>>1, data); - if (PRINTF_SERIAL && offset == NREG_UARTTHR) + if (PRINTF_SERIAL && offset == NREG_UARTTHR) { + static std::string debugStr; printf("%c", data); - if (LOG_NILE) + if (data == 0xd || debugStr.length()>=80) { + logerror("%s", debugStr.c_str()); + debugStr.clear(); + } + else { + debugStr += char(data); + } + } + if (0 && LOG_NILE) logerror("%06X:serial_w offset %03X = %08X & %08X (%08x)\n", m_cpu_space->device().safe_pc(), offset>>1, data, mem_mask, offset*4); } diff --git a/src/devices/machine/x2212.cpp b/src/devices/machine/x2212.cpp index 04a9ee5a1c9..cae221b6f94 100644 --- a/src/devices/machine/x2212.cpp +++ b/src/devices/machine/x2212.cpp @@ -31,8 +31,8 @@ ADDRESS_MAP_END //************************************************************************** // device type definition -DEFINE_DEVICE_TYPE(X2212, x2212_device, "x2212", "Xicor X2212 256x4 NVRAM") -DEFINE_DEVICE_TYPE(X2210, x2210_device, "x2210", "Xicor X2210 64x4 NVRAM") +DEFINE_DEVICE_TYPE(X2212, x2212_device, "x2212", "Xicor X2212 256x4 NOVRAM") +DEFINE_DEVICE_TYPE(X2210, x2210_device, "x2210", "Xicor X2210 64x4 NOVRAM") //------------------------------------------------- // x2212_device - constructor @@ -209,7 +209,7 @@ READ8_MEMBER( x2212_device::read ) //------------------------------------------------- // store - set the state of the store line -// (active high) +// (FIXME: actually active low, not active high) //------------------------------------------------- WRITE_LINE_MEMBER( x2212_device::store ) @@ -222,7 +222,7 @@ WRITE_LINE_MEMBER( x2212_device::store ) //------------------------------------------------- // recall - set the state of the recall line -// (active high) +// (FIXME: actually active low, not active high) //------------------------------------------------- WRITE_LINE_MEMBER( x2212_device::recall ) diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp index ebdef5e346b..af412fec149 100644 --- a/src/devices/machine/z80scc.cpp +++ b/src/devices/machine/z80scc.cpp @@ -90,8 +90,9 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC #define LOG_DCD (1U << 8) #define LOG_SYNC (1U << 9) -//#define VERBOSE (LOG_INT|LOG_READ|LOG_SETUP|LOG_TX|LOG_CMD) -//#define LOG_OUTPUT_FUNC printf +//#define VERBOSE (LOG_TX) +//#define LOG_OUTPUT_STREAM std::cout + #include "logmacro.h" #define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) @@ -111,10 +112,8 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC #ifdef _MSC_VER #define FUNCNAME __func__ -#define LLFORMAT "%I64d" #else #define FUNCNAME __PRETTY_FUNCTION__ -#define LLFORMAT "%lld" #endif /* LOCAL _BRG is set in z80scc.h, local timer based BRG is not complete and will be removed if not needed for synchrounous mode */ @@ -129,6 +128,231 @@ DONE (x) (p=partly) NMOS CMOS ESCC EMSCC #define CHANA_TAG "cha" #define CHANB_TAG "chb" +enum : uint8_t +{ + RR0_RX_CHAR_AVAILABLE = 0x01, + RR0_ZC = 0x02, + RR0_TX_BUFFER_EMPTY = 0x04, + RR0_DCD = 0x08, + RR0_SYNC_HUNT = 0x10, + RR0_CTS = 0x20, + RR0_TX_UNDERRUN = 0x40, + RR0_BREAK_ABORT = 0x80 +}; + +enum : uint8_t +{ + RR1_ALL_SENT = 0x01, + RR1_RESIDUE_CODE_MASK = 0x0e, + RR1_PARITY_ERROR = 0x10, + RR1_RX_OVERRUN_ERROR = 0x20, + RR1_CRC_FRAMING_ERROR = 0x40, + RR1_END_OF_FRAME = 0x80 +}; + +enum : uint8_t +{ + RR3_CHANB_EXT_IP = 0x01, // SCC IP pending registers + RR3_CHANB_TX_IP = 0x02, // only read in Channel A (for both channels) + RR3_CHANB_RX_IP = 0x04, // channel B return all zero + RR3_CHANA_EXT_IP = 0x08, + RR3_CHANA_TX_IP = 0x10, + RR3_CHANA_RX_IP = 0x20 +}; + +// Universal Bus WR0 commands for 85X30 +enum : uint8_t +{ + WR0_REGISTER_MASK = 0x07, + WR0_COMMAND_MASK = 0x38, // COMMANDS + WR0_NULL = 0x00, // 0 0 0 + WR0_POINT_HIGH = 0x08, // 0 0 1 + WR0_RESET_EXT_STATUS = 0x10, // 0 1 0 + WR0_SEND_ABORT = 0x18, // 0 1 1 + WR0_ENABLE_INT_NEXT_RX = 0x20, // 1 0 0 + WR0_RESET_TX_INT = 0x28, // 1 0 1 + WR0_ERROR_RESET = 0x30, // 1 1 0 + WR0_RESET_HIGHEST_IUS = 0x38, // 1 1 1 + WR0_CRC_RESET_CODE_MASK = 0xc0, // RESET + WR0_CRC_RESET_NULL = 0x00, // 0 0 + WR0_CRC_RESET_RX = 0x40, // 0 1 + WR0_CRC_RESET_TX = 0x80, // 1 0 + WR0_CRC_RESET_TX_UNDERRUN = 0xc0 // 1 1 +}; + +enum : uint8_t // ZBUS WR0 commands or 80X30 +{ + WR0_Z_COMMAND_MASK = 0x38, // COMMANDS + WR0_Z_NULL_1 = 0x00, // 0 0 0 + WR0_Z_NULL_2 = 0x08, // 0 0 1 + WR0_Z_RESET_EXT_STATUS = 0x10, // 0 1 0 + WR0_Z_SEND_ABORT = 0x18, // 0 1 1 + WR0_Z_ENABLE_INT_NEXT_RX = 0x20, // 1 0 0 + WR0_Z_RESET_TX_INT = 0x28, // 1 0 1 + WR0_Z_ERROR_RESET = 0x30, // 1 1 0 + WR0_Z_RESET_HIGHEST_IUS = 0x38, // 1 1 1 + WR0_Z_SHIFT_MASK = 0x03, // SHIFT mode SDLC chan B + WR0_Z_SEL_SHFT_LEFT = 0x02, // 1 0 + WR0_Z_SEL_SHFT_RIGHT = 0x03 // 1 1 +}; + +enum : uint8_t +{ + WR1_EXT_INT_ENABLE = 0x01, + WR1_TX_INT_ENABLE = 0x02, + WR1_PARITY_IS_SPEC_COND = 0x04, + WR1_RX_INT_MODE_MASK = 0x18, + WR1_RX_INT_DISABLE = 0x00, + WR1_RX_INT_FIRST = 0x08, + WR1_RX_INT_ALL = 0x10, + WR1_RX_INT_PARITY = 0x18, + WR1_WREQ_ON_RX_TX = 0x20, + WR1_WREQ_FUNCTION = 0x40, + WR1_WREQ_ENABLE = 0x80 +}; + +enum : uint8_t +{ + WR3_RX_ENABLE = 0x01, + WR3_SYNC_CHAR_LOAD_INHIBIT = 0x02, + WR3_ADDRESS_SEARCH_MODE = 0x04, + WR3_RX_CRC_ENABLE = 0x08, + WR3_ENTER_HUNT_MODE = 0x10, + WR3_AUTO_ENABLES = 0x20, + WR3_RX_WORD_LENGTH_MASK = 0xc0, + WR3_RX_WORD_LENGTH_5 = 0x00, + WR3_RX_WORD_LENGTH_7 = 0x40, + WR3_RX_WORD_LENGTH_6 = 0x80, + WR3_RX_WORD_LENGTH_8 = 0xc0 +}; + +enum : uint8_t +{ + WR4_PARITY_ENABLE = 0x01, + WR4_PARITY_EVEN = 0x02, + WR4_STOP_BITS_MASK = 0x0c, + WR4_STOP_BITS_1 = 0x04, + WR4_STOP_BITS_1_5 = 0x08, + WR4_STOP_BITS_2 = 0x0c, + WR4_SYNC_MODE_MASK = 0x30, + WR4_SYNC_MODE_8_BIT = 0x00, + WR4_SYNC_MODE_16_BIT = 0x10, + WR4_BIT4 = 0x10, + WR4_SYNC_MODE_SDLC = 0x20, + WR4_BIT5 = 0x20, + WR4_SYNC_MODE_EXT = 0x30, + WR4_CLOCK_RATE_MASK = 0xc0, + WR4_CLOCK_RATE_X1 = 0x00, + WR4_CLOCK_RATE_X16 = 0x40, + WR4_CLOCK_RATE_X32 = 0x80, + WR4_CLOCK_RATE_X64 = 0xc0 +}; + +enum : uint8_t +{ + WR5_TX_CRC_ENABLE = 0x01, + WR5_RTS = 0x02, + WR5_CRC16 = 0x04, + WR5_TX_ENABLE = 0x08, + WR5_SEND_BREAK = 0x10, + WR5_TX_WORD_LENGTH_MASK = 0x60, + WR5_TX_WORD_LENGTH_5 = 0x00, + WR5_TX_WORD_LENGTH_6 = 0x40, + WR5_TX_WORD_LENGTH_7 = 0x20, + WR5_TX_WORD_LENGTH_8 = 0x60, + WR5_DTR = 0x80 +}; + +enum : uint8_t +{ + WR7P_TX_FIFO_EMPTY = 0x04 +}; + +enum : uint8_t +{ + WR9_CMD_MASK = 0xC0, + WR9_CMD_NORESET = 0x00, + WR9_CMD_CHNB_RESET = 0x40, + WR9_CMD_CHNA_RESET = 0x80, + WR9_CMD_HW_RESET = 0xC0, + WR9_BIT_VIS = 0x01, + WR9_BIT_NV = 0x02, + WR9_BIT_DLC = 0x04, + WR9_BIT_MIE = 0x08, + WR9_BIT_SHSL = 0x10, + WR9_BIT_IACK = 0x20 +}; + +enum : uint8_t +{ + WR10_8_6_BIT_SYNC = 0x01, + WR10_LOOP_MODE = 0x02, + WR10_ABORT_FLAG_UNDERRUN = 0x04, + WR10_MARK_FLAG_IDLE = 0x08, + WR10_GO_ACTIVE_ON_POLL = 0x10, + WR10_ENCODING_MASK = 0x60, + WR10_NRZ_ENCODING = 0x00, + WR10_NRZI_ENCODING = 0x20, + WR10_BIT5 = 0x20, + WR10_FM1_ENCODING = 0x40, + WR10_BIT6 = 0x40, + WR10_FM0_ENCODING = 0x60, + WR10_CRC_PRESET = 0x80 +}; + +enum : uint8_t +{ + WR11_RCVCLK_TYPE = 0x80, + WR11_RCVCLK_SRC_MASK = 0x60, // RCV CLOCK + WR11_RCVCLK_SRC_RTXC = 0x00, // 0 0 + WR11_RCVCLK_SRC_TRXC = 0x20, // 0 1 + WR11_RCVCLK_SRC_BR = 0x40, // 1 0 + WR11_RCVCLK_SRC_DPLL = 0x60, // 1 1 + WR11_TRACLK_SRC_MASK = 0x18, // TRA CLOCK + WR11_TRACLK_SRC_RTXC = 0x00, // 0 0 + WR11_TRACLK_SRC_TRXC = 0x08, // 0 1 + WR11_TRACLK_SRC_BR = 0x10, // 1 0 + WR11_TRACLK_SRC_DPLL = 0x18, // 1 1 + WR11_TRXC_DIRECTION = 0x04, + WR11_TRXSRC_SRC_MASK = 0x03, // TRXX CLOCK + WR11_TRXSRC_SRC_XTAL = 0x00, // 0 0 + WR11_TRXSRC_SRC_TRA = 0x01, // 0 1 + WR11_TRXSRC_SRC_BR = 0x02, // 1 0 + WR11_TRXSRC_SRC_DPLL = 0x03 // 1 1 +}; + +enum : uint8_t +{ + WR14_DPLL_CMD_MASK = 0xe0, // Command + WR14_CMD_NULL = 0x00, // 0 0 0 + WR14_CMD_ESM = 0x20, // 0 0 1 + WR14_CMD_RMC = 0x40, // 0 1 0 + WR14_CMD_DISABLE_DPLL = 0x60, // 0 1 1 + WR14_CMD_SS_BRG = 0x80, // 1 0 0 + WR14_CMD_SS_RTXC = 0xa0, // 1 0 1 + WR14_CMD_SET_FM = 0xc0, // 1 1 0 + WR14_CMD_SET_NRZI = 0xe0, // 1 1 1 + WR14_BRG_ENABLE = 0x01, + WR14_BRG_SOURCE = 0x02, + WR14_DTR_REQ_FUNC = 0x04, + WR14_AUTO_ECHO = 0x08, + WR14_LOCAL_LOOPBACK = 0x10 +}; + +enum : uint8_t +{ + WR15_WR7PRIME = 0x01, + WR15_ZEROCOUNT = 0x02, + WR15_STATUS_FIFO = 0x04, + WR15_DCD = 0x08, + WR15_SYNC = 0x10, + WR15_CTS = 0x20, + WR15_TX_EOM = 0x40, + WR15_BREAK_ABORT = 0x80 +}; + + + //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** @@ -157,10 +381,24 @@ MACHINE_CONFIG_END // LIVE DEVICE //************************************************************************** +inline void z80scc_channel::out_txd_cb(int state) +{ + m_uart->m_out_txd_cb[m_index](state); +} + +inline void z80scc_channel::out_rts_cb(int state) +{ + m_uart->m_out_rts_cb[m_index](state); +} + +inline void z80scc_channel::out_dtr_cb(int state) +{ + m_uart->m_out_dtr_cb[m_index](state); +} + //------------------------------------------------- // z80scc_device - constructor //------------------------------------------------- - z80scc_device::z80scc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant) : device_t(mconfig, type, tag, owner, clock), device_z80daisy_interface(mconfig, *this), @@ -170,21 +408,14 @@ z80scc_device::z80scc_device(const machine_config &mconfig, device_type type, co m_txca(0), m_rxcb(0), m_txcb(0), - m_out_txda_cb(*this), - m_out_dtra_cb(*this), - m_out_rtsa_cb(*this), - m_out_wreqa_cb(*this), - m_out_synca_cb(*this), - m_out_txdb_cb(*this), - m_out_dtrb_cb(*this), - m_out_rtsb_cb(*this), - m_out_wreqb_cb(*this), - m_out_syncb_cb(*this), + m_out_txd_cb{ { *this }, { *this } }, + m_out_dtr_cb{ { *this }, { *this } }, + m_out_rts_cb{ { *this }, { *this } }, + m_out_wreq_cb{ { *this }, { *this } }, + m_out_sync_cb{ { *this }, { *this } }, + m_out_rxdrq_cb{ { *this }, { *this } }, + m_out_txdrq_cb{ { *this }, { *this } }, m_out_int_cb(*this), - m_out_rxdrqa_cb(*this), - m_out_txdrqa_cb(*this), - m_out_rxdrqb_cb(*this), - m_out_txdrqb_cb(*this), m_variant(variant), m_wr0_ptrbits(0), m_cputag(nullptr) @@ -239,28 +470,36 @@ scc8523l_device::scc8523l_device(const machine_config &mconfig, const char *tag, } //------------------------------------------------- -// device_start - device-specific startup +// device_resolve_objects - device-specific setup //------------------------------------------------- - -void z80scc_device::device_start() +void z80scc_device::device_resolve_objects() { - LOGSETUP("%s\n", FUNCNAME); + LOG("%s\n", FUNCNAME); + // resolve callbacks - m_out_txda_cb.resolve_safe(); - m_out_dtra_cb.resolve_safe(); - m_out_rtsa_cb.resolve_safe(); - m_out_wreqa_cb.resolve_safe(); - m_out_synca_cb.resolve_safe(); - m_out_txdb_cb.resolve_safe(); - m_out_dtrb_cb.resolve_safe(); - m_out_rtsb_cb.resolve_safe(); - m_out_wreqb_cb.resolve_safe(); - m_out_syncb_cb.resolve_safe(); + m_out_txd_cb[CHANNEL_A].resolve_safe(); + m_out_dtr_cb[CHANNEL_A].resolve_safe(); + m_out_rts_cb[CHANNEL_A].resolve_safe(); + m_out_wreq_cb[CHANNEL_A].resolve_safe(); + m_out_sync_cb[CHANNEL_A].resolve_safe(); + m_out_txd_cb[CHANNEL_B].resolve_safe(); + m_out_dtr_cb[CHANNEL_B].resolve_safe(); + m_out_rts_cb[CHANNEL_B].resolve_safe(); + m_out_wreq_cb[CHANNEL_B].resolve_safe(); + m_out_sync_cb[CHANNEL_B].resolve_safe(); + m_out_rxdrq_cb[CHANNEL_A].resolve_safe(); + m_out_txdrq_cb[CHANNEL_A].resolve_safe(); + m_out_rxdrq_cb[CHANNEL_B].resolve_safe(); + m_out_txdrq_cb[CHANNEL_B].resolve_safe(); m_out_int_cb.resolve_safe(); - m_out_rxdrqa_cb.resolve_safe(); - m_out_txdrqa_cb.resolve_safe(); - m_out_rxdrqb_cb.resolve_safe(); - m_out_txdrqb_cb.resolve_safe(); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- +void z80scc_device::device_start() +{ + LOG("%s", FUNCNAME); // state saving save_item(NAME(m_int_state)); @@ -274,16 +513,15 @@ void z80scc_device::device_start() //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- - void z80scc_device::device_reset() { - LOGSETUP("%s %s \n",tag(), FUNCNAME); + LOG("%s %s \n",tag(), FUNCNAME); // Do channel reset on both channels m_chanA->reset(); m_chanB->reset(); - // Fix hardware reset values for registers where it differs from channel reset values + // Hardware reset values for registers where it differs from channel reset values m_wr9 &= 0x3c; m_wr9 |= 0xc0; m_chanA->m_wr10 = 0x00; @@ -358,7 +596,7 @@ int z80scc_device::z80daisy_irq_state() } // Last chance to keep the control of the interrupt line - state |= (m_wr9 & z80scc_channel::WR9_BIT_DLC) ? Z80_DAISY_IEO : 0; + state |= (m_wr9 & WR9_BIT_DLC) ? Z80_DAISY_IEO : 0; LOGINT("- Interrupt State %u\n", state); @@ -383,7 +621,7 @@ int z80scc_device::z80daisy_irq_ack() elem = Z80_DAISY_IEO; // Set IUS bit (called IEO in z80 daisy lingo) check_interrupts(); LOGINT(" - Found an INT request, "); - if (m_wr9 & z80scc_channel::WR9_BIT_VIS) + if (m_wr9 & WR9_BIT_VIS) { LOGINT("but WR9 D1 set to use autovector, returning the default vector\n"); break; @@ -429,7 +667,6 @@ void z80scc_device::z80daisy_irq_reti() //------------------------------------------------- // check_interrupts - //------------------------------------------------- - void z80scc_device::check_interrupts() { int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE; @@ -441,7 +678,6 @@ void z80scc_device::check_interrupts() //------------------------------------------------- // reset_interrupts - //------------------------------------------------- - void z80scc_device::reset_interrupts() { LOGINT("%s %s \n",tag(), FUNCNAME); @@ -476,7 +712,7 @@ uint8_t z80scc_device::modify_vector(uint8_t vec, int i, uint8_t src) src |= (i == CHANNEL_A ? 0x04 : 0x00 ); // Modify vector according to Hi/lo bit of WR9 - if (m_wr9 & z80scc_channel::WR9_BIT_SHSL) // Affect V4-V6 + if (m_wr9 & WR9_BIT_SHSL) // Affect V4-V6 { vec &= 0x8f; vec |= src << 4; @@ -518,7 +754,7 @@ void z80scc_device::trigger_interrupt(int index, int type) LOGINT("%s %s:%c %02x \n",FUNCNAME, tag(), 'A' + index, type); /* The Master Interrupt Enable (MIE) bit, WR9 D3, must be set to enable the SCC to generate interrupts.*/ - if (!(m_wr9 & z80scc_channel::WR9_BIT_MIE)) + if (!(m_wr9 & WR9_BIT_MIE)) { LOGINT("Master Interrupt Enable is not set, blocking attempt to interrupt\n"); return; @@ -532,7 +768,7 @@ void z80scc_device::trigger_interrupt(int index, int type) return; } // Vector modification requested? - if (m_wr9 & z80scc_channel::WR9_BIT_VIS) + if (m_wr9 & WR9_BIT_VIS) { vector = modify_vector(vector, index, source); } @@ -597,7 +833,6 @@ int z80scc_device::update_extint(int index) //------------------------------------------------- // m1_r - interrupt acknowledge //------------------------------------------------- - int z80scc_device::m1_r() { return z80daisy_irq_ack(); @@ -622,8 +857,8 @@ READ8_MEMBER( z80scc_device::zbus_r ) switch ((m_chanB->m_wr0) & 7) { - case z80scc_channel::WR0_Z_SEL_SHFT_LEFT: ba = offset & 0x01; reg = (offset >> 1) & 0x0f; break; /* Shift Left mode */ - case z80scc_channel::WR0_Z_SEL_SHFT_RIGHT: ba = offset & 0x10; reg = (offset >> 1) & 0x0f; break; /* Shift Right mode */ + case WR0_Z_SEL_SHFT_LEFT: ba = offset & 0x01; reg = (offset >> 1) & 0x0f; break; /* Shift Left mode */ + case WR0_Z_SEL_SHFT_RIGHT: ba = offset & 0x10; reg = (offset >> 1) & 0x0f; break; /* Shift Right mode */ default: logerror("Malformed Z-bus SCC read: offset %02x WR0 bits %02x\n", offset, m_chanB->m_wr0); LOG("Malformed Z-bus SCC read: offset %02x WR0 bits %02x\n", offset, m_chanB->m_wr0); @@ -655,8 +890,8 @@ WRITE8_MEMBER( z80scc_device::zbus_w ) switch ((m_chanB->m_wr0) & 7) { - case z80scc_channel::WR0_Z_SEL_SHFT_LEFT: ba = offset & 0x01; reg = (offset >> 1) & 0x0f; break; /* Shift Left mode */ - case z80scc_channel::WR0_Z_SEL_SHFT_RIGHT: ba = offset & 0x10; reg = (offset >> 1) & 0x0f; break; /* Shift Right mode */ + case WR0_Z_SEL_SHFT_LEFT: ba = offset & 0x01; reg = (offset >> 1) & 0x0f; break; /* Shift Left mode */ + case WR0_Z_SEL_SHFT_RIGHT: ba = offset & 0x10; reg = (offset >> 1) & 0x0f; break; /* Shift Right mode */ default: logerror("Malformed Z-bus SCC write: offset %02x WR0 bits %02x\n", offset, m_chanB->m_wr0); LOG("Malformed Z-bus SCC write: offset %02x WR0 bits %02x\n", offset, m_chanB->m_wr0); @@ -760,7 +995,6 @@ WRITE8_MEMBER( z80scc_device::cd_ba_w ) //------------------------------------------------- // ba_cd_r - Universal Bus read //------------------------------------------------- - READ8_MEMBER( z80scc_device::ba_cd_r ) { int ba = BIT(offset, 1); @@ -782,7 +1016,6 @@ READ8_MEMBER( z80scc_device::ba_cd_r ) //------------------------------------------------- // ba_cd_w - Universal Bus write //------------------------------------------------- - WRITE8_MEMBER( z80scc_device::ba_cd_w ) { int ba = BIT(offset, 1); @@ -807,7 +1040,6 @@ WRITE8_MEMBER( z80scc_device::ba_cd_w ) //------------------------------------------------- // ba_cd_inv_r - Universal Bus read //------------------------------------------------- - READ8_MEMBER( z80scc_device::ba_cd_inv_r ) { int ba = BIT(offset, 1); @@ -829,7 +1061,6 @@ READ8_MEMBER( z80scc_device::ba_cd_inv_r ) //------------------------------------------------- // ba_cd_inv_w - Universal Bus read //------------------------------------------------- - WRITE8_MEMBER( z80scc_device::ba_cd_inv_w ) { int ba = BIT(offset, 1); @@ -858,7 +1089,6 @@ WRITE8_MEMBER( z80scc_device::ba_cd_inv_w ) //------------------------------------------------- // SCC_channel - constructor //------------------------------------------------- - z80scc_channel::z80scc_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, Z80SCC_CHANNEL, tag, owner, clock), device_serial_interface(mconfig, *this), @@ -906,7 +1136,6 @@ z80scc_channel::z80scc_channel(const machine_config &mconfig, const char *tag, d //------------------------------------------------- // start - channel startup //------------------------------------------------- - void z80scc_channel::device_start() { LOGSETUP("%s\n", FUNCNAME); @@ -987,7 +1216,6 @@ void z80scc_channel::device_start() //------------------------------------------------- // reset - reset channel status //------------------------------------------------- - void z80scc_channel::device_reset() { LOGSETUP("%s\n", FUNCNAME); @@ -1003,7 +1231,7 @@ void z80scc_channel::device_reset() m_wr4 = 0x04; m_wr5 = 0x00; if (m_uart->m_variant & (z80scc_device::TYPE_SCC85C30 | z80scc_device::SET_ESCC)) - m_wr7 = 0x20; + m_wr7 = 0x20; // WR9,WR10,WR11 and WR14 has a different hard reset (see z80scc_device::device_reset()) values m_uart->m_wr9 &= 0xdf; m_wr10 &= 0x60; @@ -1020,9 +1248,8 @@ void z80scc_channel::device_reset() m_rr10 &= 0x40; // reset external lines - set_rts(m_wr5 & WR5_RTS ? 0 : 1); - set_dtr(m_wr14 & WR14_DTR_REQ_FUNC ? 0 : (m_wr5 & WR5_DTR ? 0 : 1)); - + out_rts_cb(m_rts = m_wr5 & WR5_RTS ? 0 : 1); + out_dtr_cb(m_dtr = m_wr14 & WR14_DTR_REQ_FUNC ? 0 : (m_wr5 & WR5_DTR ? 0 : 1)); // reset interrupts if (m_index == z80scc_device::CHANNEL_A) { @@ -1067,50 +1294,38 @@ void z80scc_channel::device_timer(emu_timer &timer, device_timer_id id, int para //------------------------------------------------- // tra_callback - //------------------------------------------------- - void z80scc_channel::tra_callback() { if (!(m_wr5 & WR5_TX_ENABLE)) { - LOG(LLFORMAT " %s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); + LOGTX("%s \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); // transmit mark - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(1); - else - m_uart->m_out_txdb_cb(1); + out_txd_cb(1); } else if (m_wr5 & WR5_SEND_BREAK) { - LOG(LLFORMAT " %s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); + LOGTX("%s \"%s \"Channel %c send break 1 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); // transmit break - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(0); - else - m_uart->m_out_txdb_cb(0); + out_txd_cb(0); } else if (!is_transmit_register_empty()) { int db = transmit_register_get_data_bit(); - LOG(LLFORMAT " %s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, db, m_wr5); + LOGTX("%s \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, db, m_wr5); // transmit data - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(db); - else - m_uart->m_out_txdb_cb(db); + out_txd_cb(db); } else { - LOG(LLFORMAT " %s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); + LOGTX("%s \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); logerror("%s \"%s \"Channel %c Failed to transmit\n", FUNCNAME, owner()->tag(), 'A' + m_index); } } - //------------------------------------------------- // tra_complete - //------------------------------------------------- - void z80scc_channel::tra_complete() { // Delayed baudrate change according to SCC specs @@ -1118,7 +1333,7 @@ void z80scc_channel::tra_complete() { m_delayed_tx_brg_change = 0; set_tra_rate(m_brg_rate); - LOG("Delayed Init - Baud Rate Generator: %d mode: %dx\n", m_brg_rate, get_clock_mode() ); + LOGTX("Delayed Init - Baud Rate Generator: %d mode: %dx\n", m_brg_rate, get_clock_mode() ); } if ((m_wr5 & WR5_TX_ENABLE) && !(m_wr5 & WR5_SEND_BREAK)) @@ -1126,7 +1341,7 @@ void z80scc_channel::tra_complete() if ( (m_rr0 & RR0_TX_BUFFER_EMPTY) == 0 || // Takes care of the NMOS/CMOS 1 slot TX FIFO m_tx_fifo_rp != m_tx_fifo_wp) // or there are more characters to send in a longer FIFO. { - LOGTX(" %s() %s %c done sending, loading data from fifo:%02x '%c'\n", FUNCNAME, owner()->tag(), 'A' + m_index, + LOGTX("%s %s %c done sending, loading data from fifo:%02x '%c'\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_tx_data_fifo[m_tx_fifo_rp], isascii(m_tx_data_fifo[m_tx_fifo_rp]) ? m_tx_data_fifo[m_tx_fifo_rp] : ' '); transmit_register_setup(m_tx_data_fifo[m_tx_fifo_rp]); // Reload the shift register m_tx_fifo_rp_step(); @@ -1134,7 +1349,7 @@ void z80scc_channel::tra_complete() } else { - LOGTX(" %s() %s %c done sending, setting all sent bit\n", FUNCNAME, owner()->tag(), 'A' + m_index); + LOGTX("%s %s %c done sending, setting all sent bit\n", FUNCNAME, owner()->tag(), 'A' + m_index); m_rr1 |= RR1_ALL_SENT; // when the RTS bit is reset, the _RTS output goes high after the transmitter empties @@ -1163,21 +1378,15 @@ void z80scc_channel::tra_complete() } else if (m_wr5 & WR5_SEND_BREAK) { - LOG(LLFORMAT " %s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); + LOG("%s \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); // transmit break - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(0); - else - m_uart->m_out_txdb_cb(0); + out_txd_cb(0); } else { - LOG(LLFORMAT " %s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); + LOG("%s \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); // transmit mark - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_txda_cb(1); - else - m_uart->m_out_txdb_cb(1); + out_txd_cb(1); } } @@ -1185,18 +1394,17 @@ void z80scc_channel::tra_complete() //------------------------------------------------- // rcv_callback - //------------------------------------------------- - void z80scc_channel::rcv_callback() { if (m_wr3 & WR3_RX_ENABLE) { - LOG(LLFORMAT " %s() \"%s \"Channel %c receive data bit %d m_wr3:%02x\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, m_rxd, m_wr3); + LOG("%s \"%s \"Channel %c receive data bit %d m_wr3:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_rxd, m_wr3); receive_register_update_bit(m_rxd); } #if 1 else { - LOG(LLFORMAT " %s() \"%s \"Channel %c Received Data Bit but receiver is disabled\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index); + LOG("%s \"%s \"Channel %c Received Data Bit but receiver is disabled\n", FUNCNAME, owner()->tag(), 'A' + m_index); logerror("%s \"%s \"Channel %c Received data dit but receiver is disabled\n", FUNCNAME, owner()->tag(), 'A' + m_index); } #endif @@ -1206,14 +1414,13 @@ void z80scc_channel::rcv_callback() //------------------------------------------------- // rcv_complete - //------------------------------------------------- - void z80scc_channel::rcv_complete() { uint8_t data; receive_register_extract(); data = get_received_char(); - LOG(LLFORMAT " %s() \"%s \"Channel %c Received Data %c\n", machine().firstcpu->total_cycles(), FUNCNAME, owner()->tag(), 'A' + m_index, data); + LOG("%s \"%s \"Channel %c Received Data %c\n", FUNCNAME, owner()->tag(), 'A' + m_index, data); receive_data(data); #if START_BIT_HUNT m_rcv_mode = RCV_SEEKING; @@ -1224,7 +1431,6 @@ void z80scc_channel::rcv_complete() //------------------------------------------------- // get_clock_mode - get clock divisor //------------------------------------------------- - int z80scc_channel::get_clock_mode() { int clocks = 1; @@ -1254,10 +1460,7 @@ TODO: void z80scc_channel::set_rts(int state) { LOG("%s(%d) \"%s\": %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index); - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_rtsa_cb(state); - else - m_uart->m_out_rtsb_cb(state); + out_rts_cb(state); } void z80scc_channel::update_rts() @@ -1282,7 +1485,6 @@ void z80scc_channel::update_rts() //------------------------------------------------- // get_stop_bits - get number of stop bits //------------------------------------------------- - device_serial_interface::stop_bits_t z80scc_channel::get_stop_bits() { switch (m_wr4 & WR4_STOP_BITS_MASK) @@ -1299,7 +1501,6 @@ device_serial_interface::stop_bits_t z80scc_channel::get_stop_bits() //------------------------------------------------- // get_rx_word_length - get receive word length //------------------------------------------------- - int z80scc_channel::get_rx_word_length() { int bits = 5; @@ -1319,7 +1520,6 @@ int z80scc_channel::get_rx_word_length() //------------------------------------------------- // get_tx_word_length - get transmit word length //------------------------------------------------- - int z80scc_channel::get_tx_word_length() { int bits = 5; @@ -1482,7 +1682,7 @@ uint8_t z80scc_channel::do_sccreg_rr7() LOGR("%s\n", FUNCNAME); if (!(m_uart->m_variant & (z80scc_device::SET_NMOS))) { - logerror(" %s() not implemented feature\n", FUNCNAME); + logerror("%s not implemented feature\n", FUNCNAME); return 0; } return m_rr3; @@ -1513,7 +1713,7 @@ uint8_t z80scc_channel::do_sccreg_rr9() uint8_t z80scc_channel::do_sccreg_rr10() { LOGR("%s\n", FUNCNAME); - logerror("%s() not implemented feature\n", FUNCNAME); + logerror("%s not implemented feature\n", FUNCNAME); return m_rr10; } @@ -1606,7 +1806,7 @@ uint8_t z80scc_channel::scc_register_read( uint8_t reg) { case REG_RR0_STATUS: data = do_sccreg_rr0(); break; // TODO: verify handling of SCC specific bits: D6 and D1 case REG_RR1_SPEC_RCV_COND: data = do_sccreg_rr1(); break; - case REG_RR2_INTERRUPT_VECT: data = do_sccreg_rr2(); break; // Channel dependent and SCC specific handling compared to SIO + case REG_RR2_INTERRUPT_VECT: data = do_sccreg_rr2(); break; /* registers 3-7 are specific to SCC. TODO: Check variant and log/stop misuse */ case REG_RR3_INTERUPPT_PEND: data = wreg ? m_wr3 : do_sccreg_rr3(); break; case REG_RR4_WR4_OR_RR0: data = wreg ? m_wr4 : do_sccreg_rr4(); break; @@ -1623,7 +1823,7 @@ uint8_t z80scc_channel::scc_register_read( uint8_t reg) case REG_RR14_WR7_OR_R10: data = do_sccreg_rr14(); break; case REG_RR15_WR15_EXT_STAT: data = do_sccreg_rr15(); break; default: - logerror(" \"%s\" %s: %c : Unsupported RRx register:%02x\n", owner()->tag(), FUNCNAME, 'A' + m_index, reg); + logerror(" \"%s\"%s: %c : Unsupported RRx register:%02x\n", owner()->tag(), FUNCNAME, 'A' + m_index, reg); } return data; } @@ -1791,7 +1991,7 @@ void z80scc_channel::do_sccreg_wr0(uint8_t data) void z80scc_channel::do_sccreg_wr1(uint8_t data) { LOG("%s(%02x) \"%s\": %c : %s - %02x\n", FUNCNAME, data, owner()->tag(), 'A' + m_index, FUNCNAME, data); - /* TODO: Sort out SCC specific behaviours from legacy SIO behaviours: + /* TODO: Sort out SCC specific behaviours from legacy SIO behaviours inherited from z80dart.cpp: - Channel B only bits vs - Parity Is Special Condition, bit2 */ m_wr1 = data; @@ -1927,7 +2127,7 @@ void z80scc_channel::do_sccreg_wr7(uint8_t data) /* WR8 is the transmit buffer register */ void z80scc_channel::do_sccreg_wr8(uint8_t data) { - LOG("%s(%02x) \"%s\": %c : Transmit Buffer write %02x\n", FUNCNAME, data, owner()->tag(), 'A' + m_index, data); + LOGTX("%s(%02x) \"%s\": %c : Transmit Buffer write %02x\n", FUNCNAME, data, owner()->tag(), 'A' + m_index, data); data_write(data); } @@ -2257,7 +2457,6 @@ with 0 before accessing WR0 or RR0.*/ //------------------------------------------------- // control_write - write control register //------------------------------------------------- - void z80scc_channel::control_write(uint8_t data) { uint8_t reg = m_uart->m_wr0_ptrbits; //m_wr0; @@ -2286,7 +2485,6 @@ void z80scc_channel::control_write(uint8_t data) //------------------------------------------------- // data_read - read data register from fifo //------------------------------------------------- - uint8_t z80scc_channel::data_read() { uint8_t data = 0; @@ -2383,7 +2581,7 @@ WRITE8_MEMBER (z80scc_device::db_w) { m_chanB->data_write(data); } void z80scc_channel::data_write(uint8_t data) { /* Tx FIFO is full or...? */ - LOGTX("%s \"%s\": %c : Data Register Write: %02d '%c'\n", FUNCNAME, owner()->tag(), 'A' + m_index, data, isprint(data) ? data : ' '); + LOG("%s \"%s\": %c : Data Register Write: %02d '%c'\n", FUNCNAME, owner()->tag(), 'A' + m_index, data, isprint(data) ? data : ' '); if ( !(m_rr0 & RR0_TX_BUFFER_EMPTY) && // NMOS/CMOS 1 slot "FIFO" is controlled by the TBE bit instead of fifo logic ( (m_tx_fifo_wp + 1 == m_tx_fifo_rp) || ( (m_tx_fifo_wp + 1 == m_tx_fifo_sz) && (m_tx_fifo_rp == 0) ))) @@ -2469,7 +2667,6 @@ void z80scc_channel::data_write(uint8_t data) //------------------------------------------------- // receive_data - put received data word into fifo //------------------------------------------------- - void z80scc_channel::receive_data(uint8_t data) { LOGRCV("\"%s\": %c : Received Data Byte '%c'/%02x put into FIFO\n", owner()->tag(), 'A' + m_index, isprint(data) ? data : ' ', data); @@ -2522,10 +2719,9 @@ void z80scc_channel::receive_data(uint8_t data) //------------------------------------------------- // cts_w - clear to send handler //------------------------------------------------- - WRITE_LINE_MEMBER( z80scc_channel::cts_w ) { - LOG("\"%s\" %s: %c : CTS %u\n", owner()->tag(), FUNCNAME, 'A' + m_index, state); + LOG("\"%s\"%s: %c : CTS %u\n", owner()->tag(), FUNCNAME, 'A' + m_index, state); if ((m_rr0 & RR0_CTS) != (state ? RR0_CTS : 0)) // SCC change detection logic { @@ -2603,31 +2799,6 @@ WRITE_LINE_MEMBER( z80scc_channel::dcd_w ) WRITE_LINE_MEMBER( z80scc_channel::ri_w ) { LOGINT("\"%s\": %c : RI %u - not implemented\n", owner()->tag(), 'A' + m_index, state); - -#if 0 // TODO: This code is inherited from another device driver and not correct for SCC - if (m_ri != state) - { - // set ring indicator state - m_ri = state; - - if (!m_rx_rr0_latch) - { - if (m_ri) - m_rr0 |= RR0_RI; - else - m_rr0 &= ~RR0_RI; - - if (m_wr1 & WR1_EXT_INT_ENABLE) - { - // trigger interrupt - m_uart->trigger_interrupt(m_index, INT_EXTERNAL); - - // latch read register 0 - m_rx_rr0_latch = 1; - } - } - } -#endif } //------------------------------------------------- @@ -2782,7 +2953,7 @@ void z80scc_channel::update_serial() parity = PARITY_NONE; } - LOG(" %s() \"%s \"Channel %c setting data frame %d+%d%c%d\n", FUNCNAME, owner()->tag(), 'A' + m_index, 1, + LOG("%s \"%s \"Channel %c setting data frame %d+%d%c%d\n", FUNCNAME, owner()->tag(), 'A' + m_index, 1, data_bit_count, parity == PARITY_NONE ? 'N' : parity == PARITY_EVEN ? 'E' : 'O', (stop_bits + 1) / 2); set_data_frame(1, data_bit_count, parity, stop_bits); @@ -2841,10 +3012,7 @@ void z80scc_channel::set_dtr(int state) LOG("%s(%d)\n", FUNCNAME, state); m_dtr = state; - if (m_index == z80scc_device::CHANNEL_A) - m_uart->m_out_dtra_cb(m_dtr); - else - m_uart->m_out_dtrb_cb(m_dtr); + out_dtr_cb(m_dtr); } //------------------------------------------------- @@ -2893,8 +3061,6 @@ void z80scc_channel::check_waitrequest() if (m_wr1 & WR1_WREQ_FUNCTION) { // assert /W//REQ if transmit buffer is empty, clear if it's not - int state = (m_rr0 & RR0_TX_BUFFER_EMPTY) ? ASSERT_LINE : CLEAR_LINE; - - (m_index ? m_uart->m_out_wreqb_cb : m_uart->m_out_wreqa_cb)(state); + m_uart->m_out_wreq_cb[m_index]((m_rr0 & RR0_TX_BUFFER_EMPTY) ? ASSERT_LINE : CLEAR_LINE); } } diff --git a/src/devices/machine/z80scc.h b/src/devices/machine/z80scc.h index 33729f23efb..49ec17aab43 100644 --- a/src/devices/machine/z80scc.h +++ b/src/devices/machine/z80scc.h @@ -90,47 +90,47 @@ // Port A callbacks #define MCFG_Z80SCC_OUT_TXDA_CB(_devcb) \ - devcb = &z80scc_device::set_out_txda_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_txd_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_DTRA_CB(_devcb) \ - devcb = &z80scc_device::set_out_dtra_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_dtr_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_RTSA_CB(_devcb) \ - devcb = &z80scc_device::set_out_rtsa_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_rts_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_WREQA_CB(_devcb) \ - devcb = &z80scc_device::set_out_wreqa_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_wreq_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_SYNCA_CB(_devcb) \ - devcb = &z80scc_device::set_out_synca_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_sync_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_RXDRQA_CB(_devcb) \ - devcb = &z80scc_device::set_out_rxdrqa_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_rxdrq_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_TXDRQA_CB(_devcb) \ - devcb = &z80scc_device::set_out_txdrqa_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_txdrq_callback<0>(*device, DEVCB_##_devcb); // Port B callbacks #define MCFG_Z80SCC_OUT_TXDB_CB(_devcb) \ - devcb = &z80scc_device::set_out_txdb_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_txd_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_DTRB_CB(_devcb) \ - devcb = &z80scc_device::set_out_dtrb_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_dtr_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_RTSB_CB(_devcb) \ - devcb = &z80scc_device::set_out_rtsb_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_rts_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_WREQB_CB(_devcb) \ - devcb = &z80scc_device::set_out_wreqb_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_wreq_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_SYNCB_CB(_devcb) \ - devcb = &z80scc_device::set_out_syncb_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_sync_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_RXDRQB_CB(_devcb) \ - devcb = &z80scc_device::set_out_rxdrqb_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_rxdrq_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SCC_OUT_TXDRQB_CB(_devcb) \ - devcb = &z80scc_device::set_out_txdrqb_callback(*device, DEVCB_##_devcb); + devcb = &z80scc_device::set_out_txdrq_callback<1>(*device, DEVCB_##_devcb); //************************************************************************** @@ -242,7 +242,7 @@ public: uint8_t m_rr14; // REG_RR14_WR7_OR_R10 uint8_t m_rr15; // REG_RR15_WR15_EXT_STAT - // write registers enum + // write registers enum uint8_t m_wr0; // REG_WR0_COMMAND_REGPT uint8_t m_wr1; // REG_WR1_INT_DMA_ENABLE uint8_t m_wr2; // REG_WR2_INT_VECTOR @@ -264,45 +264,45 @@ public: protected: enum { - RCV_IDLE = 0, - RCV_SEEKING = 1, - RCV_SAMPLING = 2 + RCV_IDLE = 0, + RCV_SEEKING = 1, + RCV_SAMPLING = 2 }; enum { - INT_TRANSMIT = 0, - INT_EXTERNAL = 1, - INT_RECEIVE = 2, - INT_SPECIAL = 3, + INT_TRANSMIT = 0, + INT_EXTERNAL = 1, + INT_RECEIVE = 2, + INT_SPECIAL = 3, }; enum { - INT_TRANSMIT_PRIO = 1, - INT_EXTERNAL_PRIO = 0, - INT_RECEIVE_PRIO = 2, - INT_SPECIAL_PRIO = 0, + INT_TRANSMIT_PRIO = 1, + INT_EXTERNAL_PRIO = 0, + INT_RECEIVE_PRIO = 2, + INT_SPECIAL_PRIO = 0, }; // Read registers enum { - REG_RR0_STATUS = 0, + REG_RR0_STATUS = 0, REG_RR1_SPEC_RCV_COND = 1, REG_RR2_INTERRUPT_VECT = 2, REG_RR3_INTERUPPT_PEND = 3, - REG_RR4_WR4_OR_RR0 = 4, - REG_RR5_WR5_OR_RR0 = 5, - REG_RR6_LSB_OR_RR2 = 6, - REG_RR7_MSB_OR_RR3 = 7, + REG_RR4_WR4_OR_RR0 = 4, + REG_RR5_WR5_OR_RR0 = 5, + REG_RR6_LSB_OR_RR2 = 6, + REG_RR7_MSB_OR_RR3 = 7, REG_RR8_RECEIVE_DATA = 8, - REG_RR9_WR3_OR_RR13 = 9, + REG_RR9_WR3_OR_RR13 = 9, REG_RR10_MISC_STATUS = 10, REG_RR11_WR10_OR_RR15 = 11, REG_RR12_LO_TIME_CONST = 12, REG_RR13_HI_TIME_CONST = 13, - REG_RR14_WR7_OR_R10 = 14, + REG_RR14_WR7_OR_R10 = 14, REG_RR15_WR15_EXT_STAT = 15 }; @@ -329,237 +329,6 @@ protected: enum { - RR0_RX_CHAR_AVAILABLE = 0x01, - RR0_ZC = 0x02, - RR0_TX_BUFFER_EMPTY = 0x04, - RR0_DCD = 0x08, - RR0_SYNC_HUNT = 0x10, - RR0_CTS = 0x20, - RR0_TX_UNDERRUN = 0x40, - RR0_BREAK_ABORT = 0x80 - }; - - enum - { - RR1_ALL_SENT = 0x01, - RR1_RESIDUE_CODE_MASK = 0x0e, - RR1_PARITY_ERROR = 0x10, - RR1_RX_OVERRUN_ERROR = 0x20, - RR1_CRC_FRAMING_ERROR = 0x40, - RR1_END_OF_FRAME = 0x80 - }; - - enum - { - RR2_INT_VECTOR_MASK = 0xff, // SCC channel A, SIO channel B (special case) - RR2_INT_VECTOR_V1 = 0x02, // SIO (special case) /SCC Channel B - RR2_INT_VECTOR_V2 = 0x04, // SIO (special case) /SCC Channel B - RR2_INT_VECTOR_V3 = 0x08 // SIO (special case) /SCC Channel B - }; - - enum - { - RR3_CHANB_EXT_IP = 0x01, // SCC IP pending registers - RR3_CHANB_TX_IP = 0x02, // only read in Channel A (for both channels) - RR3_CHANB_RX_IP = 0x04, // channel B return all zero - RR3_CHANA_EXT_IP = 0x08, - RR3_CHANA_TX_IP = 0x10, - RR3_CHANA_RX_IP = 0x20 - }; - - enum // Universal Bus WR0 commands for 85X30 - { - WR0_REGISTER_MASK = 0x07, - WR0_COMMAND_MASK = 0x38, // COMMANDS - WR0_NULL = 0x00, // 0 0 0 - WR0_POINT_HIGH = 0x08, // 0 0 1 - WR0_RESET_EXT_STATUS = 0x10, // 0 1 0 - WR0_SEND_ABORT = 0x18, // 0 1 1 - WR0_ENABLE_INT_NEXT_RX = 0x20, // 1 0 0 - WR0_RESET_TX_INT = 0x28, // 1 0 1 - WR0_ERROR_RESET = 0x30, // 1 1 0 - WR0_RESET_HIGHEST_IUS = 0x38, // 1 1 1 - WR0_CRC_RESET_CODE_MASK = 0xc0, // RESET - WR0_CRC_RESET_NULL = 0x00, // 0 0 - WR0_CRC_RESET_RX = 0x40, // 0 1 - WR0_CRC_RESET_TX = 0x80, // 1 0 - WR0_CRC_RESET_TX_UNDERRUN = 0xc0 // 1 1 - }; - - enum // ZBUS WR0 commands or 80X30 - { - WR0_Z_COMMAND_MASK = 0x38, // COMMANDS - WR0_Z_NULL_1 = 0x00, // 0 0 0 - WR0_Z_NULL_2 = 0x08, // 0 0 1 - WR0_Z_RESET_EXT_STATUS = 0x10, // 0 1 0 - WR0_Z_SEND_ABORT = 0x18, // 0 1 1 - WR0_Z_ENABLE_INT_NEXT_RX= 0x20, // 1 0 0 - WR0_Z_RESET_TX_INT = 0x28, // 1 0 1 - WR0_Z_ERROR_RESET = 0x30, // 1 1 0 - WR0_Z_RESET_HIGHEST_IUS = 0x38, // 1 1 1 - WR0_Z_SHIFT_MASK = 0x03, // SHIFT mode SDLC chan B - WR0_Z_SEL_SHFT_LEFT = 0x02, // 1 0 - WR0_Z_SEL_SHFT_RIGHT = 0x03 // 1 1 - }; - - enum - { - WR1_EXT_INT_ENABLE = 0x01, - WR1_TX_INT_ENABLE = 0x02, - WR1_PARITY_IS_SPEC_COND = 0x04, - WR1_RX_INT_MODE_MASK = 0x18, - WR1_RX_INT_DISABLE = 0x00, - WR1_RX_INT_FIRST = 0x08, - WR1_RX_INT_ALL = 0x10, - WR1_RX_INT_PARITY = 0x18, - WR1_WREQ_ON_RX_TX = 0x20, - WR1_WREQ_FUNCTION = 0x40, - WR1_WREQ_ENABLE = 0x80 - }; - - enum - { - WR3_RX_ENABLE = 0x01, - WR3_SYNC_CHAR_LOAD_INHIBIT = 0x02, - WR3_ADDRESS_SEARCH_MODE = 0x04, - WR3_RX_CRC_ENABLE = 0x08, - WR3_ENTER_HUNT_MODE = 0x10, - WR3_AUTO_ENABLES = 0x20, - WR3_RX_WORD_LENGTH_MASK = 0xc0, - WR3_RX_WORD_LENGTH_5 = 0x00, - WR3_RX_WORD_LENGTH_7 = 0x40, - WR3_RX_WORD_LENGTH_6 = 0x80, - WR3_RX_WORD_LENGTH_8 = 0xc0 - }; - - enum - { - WR4_PARITY_ENABLE = 0x01, - WR4_PARITY_EVEN = 0x02, - WR4_STOP_BITS_MASK = 0x0c, - WR4_STOP_BITS_1 = 0x04, - WR4_STOP_BITS_1_5 = 0x08, - WR4_STOP_BITS_2 = 0x0c, - WR4_SYNC_MODE_MASK = 0x30, - WR4_SYNC_MODE_8_BIT = 0x00, - WR4_SYNC_MODE_16_BIT = 0x10, - WR4_BIT4 = 0x10, - WR4_SYNC_MODE_SDLC = 0x20, - WR4_BIT5 = 0x20, - WR4_SYNC_MODE_EXT = 0x30, - WR4_CLOCK_RATE_MASK = 0xc0, - WR4_CLOCK_RATE_X1 = 0x00, - WR4_CLOCK_RATE_X16 = 0x40, - WR4_CLOCK_RATE_X32 = 0x80, - WR4_CLOCK_RATE_X64 = 0xc0 - }; - - enum - { - WR5_TX_CRC_ENABLE = 0x01, - WR5_RTS = 0x02, - WR5_CRC16 = 0x04, - WR5_TX_ENABLE = 0x08, - WR5_SEND_BREAK = 0x10, - WR5_TX_WORD_LENGTH_MASK = 0x60, - WR5_TX_WORD_LENGTH_5 = 0x00, - WR5_TX_WORD_LENGTH_6 = 0x40, - WR5_TX_WORD_LENGTH_7 = 0x20, - WR5_TX_WORD_LENGTH_8 = 0x60, - WR5_DTR = 0x80 - }; - - - enum - { - WR7P_TX_FIFO_EMPTY = 0x04 - }; - - enum - { - WR9_CMD_MASK = 0xC0, - WR9_CMD_NORESET = 0x00, - WR9_CMD_CHNB_RESET = 0x40, - WR9_CMD_CHNA_RESET = 0x80, - WR9_CMD_HW_RESET = 0xC0, - WR9_BIT_VIS = 0x01, - WR9_BIT_NV = 0x02, - WR9_BIT_DLC = 0x04, - WR9_BIT_MIE = 0x08, - WR9_BIT_SHSL = 0x10, - WR9_BIT_IACK = 0x20 - }; - - enum - { - WR10_8_6_BIT_SYNC = 0x01, - WR10_LOOP_MODE = 0x02, - WR10_ABORT_FLAG_UNDERRUN = 0x04, - WR10_MARK_FLAG_IDLE = 0x08, - WR10_GO_ACTIVE_ON_POLL = 0x10, - WR10_ENCODING_MASK = 0x60, - WR10_NRZ_ENCODING = 0x00, - WR10_NRZI_ENCODING = 0x20, - WR10_BIT5 = 0x20, - WR10_FM1_ENCODING = 0x40, - WR10_BIT6 = 0x40, - WR10_FM0_ENCODING = 0x60, - WR10_CRC_PRESET = 0x80 - }; - - enum - { - WR11_RCVCLK_TYPE = 0x80, - WR11_RCVCLK_SRC_MASK = 0x60, // RCV CLOCK - WR11_RCVCLK_SRC_RTXC = 0x00, // 0 0 - WR11_RCVCLK_SRC_TRXC = 0x20, // 0 1 - WR11_RCVCLK_SRC_BR = 0x40, // 1 0 - WR11_RCVCLK_SRC_DPLL = 0x60, // 1 1 - WR11_TRACLK_SRC_MASK = 0x18, // TRA CLOCK - WR11_TRACLK_SRC_RTXC = 0x00, // 0 0 - WR11_TRACLK_SRC_TRXC = 0x08, // 0 1 - WR11_TRACLK_SRC_BR = 0x10, // 1 0 - WR11_TRACLK_SRC_DPLL = 0x18, // 1 1 - WR11_TRXC_DIRECTION = 0x04, - WR11_TRXSRC_SRC_MASK = 0x03, // TRXX CLOCK - WR11_TRXSRC_SRC_XTAL = 0x00, // 0 0 - WR11_TRXSRC_SRC_TRA = 0x01, // 0 1 - WR11_TRXSRC_SRC_BR = 0x02, // 1 0 - WR11_TRXSRC_SRC_DPLL = 0x03 // 1 1 - }; - - enum - { - WR14_DPLL_CMD_MASK = 0xe0, // Command - WR14_CMD_NULL = 0x00, // 0 0 0 - WR14_CMD_ESM = 0x20, // 0 0 1 - WR14_CMD_RMC = 0x40, // 0 1 0 - WR14_CMD_DISABLE_DPLL = 0x60, // 0 1 1 - WR14_CMD_SS_BRG = 0x80, // 1 0 0 - WR14_CMD_SS_RTXC = 0xa0, // 1 0 1 - WR14_CMD_SET_FM = 0xc0, // 1 1 0 - WR14_CMD_SET_NRZI = 0xe0, // 1 1 1 - WR14_BRG_ENABLE = 0x01, - WR14_BRG_SOURCE = 0x02, - WR14_DTR_REQ_FUNC = 0x04, - WR14_AUTO_ECHO = 0x08, - WR14_LOCAL_LOOPBACK = 0x10 - }; - - enum - { - WR15_WR7PRIME = 0x01, - WR15_ZEROCOUNT = 0x02, - WR15_STATUS_FIFO = 0x04, - WR15_DCD = 0x08, - WR15_SYNC = 0x10, - WR15_CTS = 0x20, - WR15_TX_EOM = 0x40, - WR15_BREAK_ABORT = 0x80 - }; - - enum - { TIMER_ID_BAUD, TIMER_ID_XTAL, TIMER_ID_RTXC, @@ -632,6 +401,12 @@ protected: // SCC specifics int m_ph; // Point high command to access regs 08-0f uint8_t m_zc; +private: + // helpers + void out_txd_cb(int state); + void out_rts_cb(int state); + void out_dtr_cb(int state); + }; @@ -645,21 +420,14 @@ public: // construction/destruction z80scc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <class Object> static devcb_base &set_out_txda_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txda_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_dtra_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_dtra_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_rtsa_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rtsa_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_wreqa_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_wreqa_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_synca_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_synca_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_txdb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txdb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_dtrb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_dtrb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_rtsb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rtsb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_wreqb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_wreqb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_syncb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_syncb_cb.set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_txd_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txd_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_dtr_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_dtr_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_rts_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rts_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_wreq_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_wreq_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_sync_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_sync_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_rxdrq_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rxdrq_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_txdrq_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txdrq_cb[N].set_callback(std::forward<Object>(cb)); } template <class Object> static devcb_base &set_out_int_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_int_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_rxdrqa_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rxdrqa_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_txdrqa_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txdrqa_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_rxdrqb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_rxdrqb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_txdrqb_callback(device_t &device, Object &&cb) { return downcast<z80scc_device &>(device).m_out_txdrqb_cb.set_callback(std::forward<Object>(cb)); } static void static_set_cputag(device_t &device, const char *tag) { @@ -727,6 +495,7 @@ protected: z80scc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant); // device-level overrides + virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; @@ -781,23 +550,16 @@ protected: int m_rxcb; int m_txcb; - devcb_write_line m_out_txda_cb; - devcb_write_line m_out_dtra_cb; - devcb_write_line m_out_rtsa_cb; - devcb_write_line m_out_wreqa_cb; - devcb_write_line m_out_synca_cb; - - devcb_write_line m_out_txdb_cb; - devcb_write_line m_out_dtrb_cb; - devcb_write_line m_out_rtsb_cb; - devcb_write_line m_out_wreqb_cb; - devcb_write_line m_out_syncb_cb; + // internal state + devcb_write_line m_out_txd_cb[2]; + devcb_write_line m_out_dtr_cb[2]; + devcb_write_line m_out_rts_cb[2]; + devcb_write_line m_out_wreq_cb[2]; + devcb_write_line m_out_sync_cb[2]; + devcb_write_line m_out_rxdrq_cb[2]; + devcb_write_line m_out_txdrq_cb[2]; devcb_write_line m_out_int_cb; - devcb_write_line m_out_rxdrqa_cb; - devcb_write_line m_out_txdrqa_cb; - devcb_write_line m_out_rxdrqb_cb; - devcb_write_line m_out_txdrqb_cb; int m_int_state[6]; // interrupt state int m_int_source[6]; // interrupt source diff --git a/src/devices/machine/z80sio.cpp b/src/devices/machine/z80sio.cpp index 8cf9169c6b2..ddf951161b4 100644 --- a/src/devices/machine/z80sio.cpp +++ b/src/devices/machine/z80sio.cpp @@ -50,6 +50,9 @@ #include "emu.h" #include "z80sio.h" +#include "machine/sdlc.h" + + //************************************************************************** // MACROS / CONSTANTS //************************************************************************** @@ -66,8 +69,8 @@ #define LOG_SYNC (1U << 9) #define LOG_BIT (1U << 10) -//#define VERBOSE (LOG_INT|LOG_READ|LOG_SETUP|LOG_TX|LOG_CMD) //(LOG_SETUP|LOG_INT|LOG_CMD|LOG_DCD|LOG_CTS|LOG_TX) -//#define LOG_OUTPUT_FUNC printf +//#define VERBOSE (LOG_INT | LOG_READ | LOG_SETUP | LOG_TX | LOG_CMD | LOG_CTS) +//#define LOG_OUTPUT_STREAM std::cout #include "logmacro.h" @@ -91,15 +94,150 @@ #define CHANA_TAG "cha" #define CHANB_TAG "chb" + +enum : uint8_t +{ + RR0_RX_CHAR_AVAILABLE = 0x01, + RR0_INTERRUPT_PENDING = 0x02, + RR0_TX_BUFFER_EMPTY = 0x04, + RR0_DCD = 0x08, + RR0_SYNC_HUNT = 0x10, + RR0_CTS = 0x20, + RR0_TX_UNDERRUN = 0x40, + RR0_BREAK_ABORT = 0x80 +}; + +enum : uint8_t +{ + RR1_ALL_SENT = 0x01, + RR1_RESIDUE_CODE_MASK = 0x0e, + RR1_PARITY_ERROR = 0x10, + RR1_RX_OVERRUN_ERROR = 0x20, + RR1_CRC_FRAMING_ERROR = 0x40, + RR1_END_OF_FRAME = 0x80 +}; + +enum : uint8_t +{ + RR2_INT_VECTOR_MASK = 0xff, + RR2_INT_VECTOR_V1 = 0x02, + RR2_INT_VECTOR_V2 = 0x04, + RR2_INT_VECTOR_V3 = 0x08 +}; + +enum : uint8_t +{ + WR0_REGISTER_MASK = 0x07, + WR0_COMMAND_MASK = 0x38, + WR0_NULL = 0x00, + WR0_SEND_ABORT = 0x08, + WR0_RESET_EXT_STATUS = 0x10, + WR0_CHANNEL_RESET = 0x18, + WR0_ENABLE_INT_NEXT_RX = 0x20, + WR0_RESET_TX_INT = 0x28, + WR0_ERROR_RESET = 0x30, + WR0_RETURN_FROM_INT = 0x38, + WR0_CRC_RESET_CODE_MASK = 0xc0, + WR0_CRC_RESET_NULL = 0x00, + WR0_CRC_RESET_RX = 0x40, + WR0_CRC_RESET_TX = 0x80, + WR0_CRC_RESET_TX_UNDERRUN = 0xc0 +}; + +enum : uint8_t +{ + WR1_EXT_INT_ENABLE = 0x01, + WR1_TX_INT_ENABLE = 0x02, + WR1_STATUS_VECTOR = 0x04, + WR1_RX_INT_MODE_MASK = 0x18, + WR1_RX_INT_DISABLE = 0x00, + WR1_RX_INT_FIRST = 0x08, + WR1_RX_INT_ALL_PARITY = 0x10, + WR1_RX_INT_ALL = 0x18, + WR1_WRDY_ON_RX_TX = 0x20, + WR1_WRDY_FUNCTION = 0x40, // WAIT not supported + WR1_WRDY_ENABLE = 0x80 +}; + +enum : uint8_t +{ + WR2_DATA_XFER_INT = 0x00, // not supported + WR2_DATA_XFER_DMA_INT = 0x01, // not supported + WR2_DATA_XFER_DMA = 0x02, // not supported + WR2_DATA_XFER_ILLEGAL = 0x03, // not supported + WR2_DATA_XFER_MASK = 0x03, // not supported + WR2_PRIORITY = 0x04, + WR2_MODE_8085_1 = 0x00, // not supported + WR2_MODE_8085_2 = 0x08, // not supported + WR2_MODE_8086_8088 = 0x10, // not supported + WR2_MODE_ILLEGAL = 0x18, // not supported + WR2_MODE_MASK = 0x18, // not supported + WR2_VECTORED_INT = 0x20, // partially supported + WR2_PIN10_SYNDETB_RTSB = 0x80 // not supported +}; + +enum : uint8_t +{ + WR3_RX_ENABLE = 0x01, + WR3_SYNC_CHAR_LOAD_INHIBIT= 0x02, // not supported + WR3_ADDRESS_SEARCH_MODE = 0x04, // not supported + WR3_RX_CRC_ENABLE = 0x08, // not supported + WR3_ENTER_HUNT_PHASE = 0x10, + WR3_AUTO_ENABLES = 0x20, + WR3_RX_WORD_LENGTH_MASK = 0xc0, + WR3_RX_WORD_LENGTH_5 = 0x00, + WR3_RX_WORD_LENGTH_7 = 0x40, + WR3_RX_WORD_LENGTH_6 = 0x80, + WR3_RX_WORD_LENGTH_8 = 0xc0 +}; + +enum : uint8_t +{ + WR4_PARITY_ENABLE = 0x01, + WR4_PARITY_EVEN = 0x02, + WR4_STOP_BITS_MASK = 0x0c, + WR4_STOP_BITS_SYNC = 0x00, // partially supported + WR4_STOP_BITS_1 = 0x04, + WR4_STOP_BITS_1_5 = 0x08, + WR4_STOP_BITS_2 = 0x0c, + WR4_SYNC_MODE_MASK = 0x30, // partially supported + WR4_SYNC_MODE_8_BIT = 0x00, // partially supported + WR4_SYNC_MODE_16_BIT = 0x10, // partially supported + WR4_SYNC_MODE_SDLC = 0x20, // partially supported + WR4_SYNC_MODE_EXT = 0x30, // partially supported + WR4_CLOCK_RATE_MASK = 0xc0, + WR4_CLOCK_RATE_X1 = 0x00, + WR4_CLOCK_RATE_X16 = 0x40, + WR4_CLOCK_RATE_X32 = 0x80, + WR4_CLOCK_RATE_X64 = 0xc0 +}; + +enum : uint8_t +{ + WR5_TX_CRC_ENABLE = 0x01, + WR5_RTS = 0x02, + WR5_CRC16 = 0x04, + WR5_TX_ENABLE = 0x08, + WR5_SEND_BREAK = 0x10, + WR5_TX_WORD_LENGTH_MASK = 0x60, + WR5_TX_WORD_LENGTH_5 = 0x00, + WR5_TX_WORD_LENGTH_6 = 0x40, + WR5_TX_WORD_LENGTH_7 = 0x20, + WR5_TX_WORD_LENGTH_8 = 0x60, + WR5_DTR = 0x80 +}; + + //************************************************************************** // DEVICE DEFINITIONS //************************************************************************** // device type definition -DEFINE_DEVICE_TYPE(Z80SIO, z80sio_device, "z80sio", "Z80 SIO") DEFINE_DEVICE_TYPE(Z80SIO_CHANNEL, z80sio_channel, "z80sio_channel", "Z80 SIO channel") -DEFINE_DEVICE_TYPE(UPD7201_NEW, upd7201_new_device, "upd7201_new", "NEC uPD7201 MPSC (new)") // Remove trailing N when z80dart.cpp's 7201 implementation is fully replaced +DEFINE_DEVICE_TYPE(I8274_CHANNEL, i8274_channel, "i8274_channel", "Intel 8274 MPSC channel") +DEFINE_DEVICE_TYPE(Z80SIO, z80sio_device, "z80sio", "Z80 SIO") DEFINE_DEVICE_TYPE(I8274_NEW, i8274_new_device, "i8274_new", "Intel 8274 MPSC (new)") // Remove trailing N when z80dart.cpp's 8274 implementation is fully replaced +DEFINE_DEVICE_TYPE(UPD7201_NEW, upd7201_new_device, "upd7201_new", "NEC uPD7201 MPSC (new)") // Remove trailing N when z80dart.cpp's 7201 implementation is fully replaced //------------------------------------------------- // device_add_mconfig - add device configuration @@ -109,57 +247,145 @@ MACHINE_CONFIG_MEMBER( z80sio_device::device_add_mconfig ) MCFG_DEVICE_ADD(CHANB_TAG, Z80SIO_CHANNEL, 0) MACHINE_CONFIG_END +MACHINE_CONFIG_MEMBER( i8274_new_device::device_add_mconfig ) + MCFG_DEVICE_ADD(CHANA_TAG, I8274_CHANNEL, 0) + MCFG_DEVICE_ADD(CHANB_TAG, I8274_CHANNEL, 0) +MACHINE_CONFIG_END + //************************************************************************** // LIVE DEVICE //************************************************************************** +inline void z80sio_channel::out_txd_cb(int state) +{ + m_uart->m_out_txd_cb[m_index](state); +} + +inline void z80sio_channel::out_rts_cb(int state) +{ + m_uart->m_out_rts_cb[m_index](state); +} + +inline void z80sio_channel::out_dtr_cb(int state) +{ + m_uart->m_out_dtr_cb[m_index](state); +} + +inline void z80sio_channel::set_ready(bool ready) +{ + // WAIT mode not supported yet + if (m_wr1 & WR1_WRDY_FUNCTION) + m_uart->m_out_wrdy_cb[m_index](ready ? 0 : 1); +} + +inline bool z80sio_channel::receive_allowed() const +{ + return (m_wr3 & WR3_RX_ENABLE) && (!(m_wr3 & WR3_AUTO_ENABLES) || !m_dcd); +} + +inline bool z80sio_channel::transmit_allowed() const +{ + return (m_wr5 & WR5_TX_ENABLE) && (!(m_wr3 & WR3_AUTO_ENABLES) || !m_cts); +} + +inline void z80sio_channel::set_rts(int state) +{ + if (bool(m_rts) != bool(state)) + { + LOG("%s(%d) \"%s\" Channel %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index); + out_rts_cb(m_rts = state); + } +} + +inline void z80sio_channel::set_dtr(int state) +{ + if (bool(m_dtr) != bool(state)) + { + LOG("%s(%d) \"%s\" Channel %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index); + out_dtr_cb(m_dtr = state); + } +} + +inline void z80sio_channel::tx_setup(uint16_t data, int bits, int parity, bool framing, bool special) +{ + m_tx_bits = bits; + m_tx_parity = parity; + m_tx_sr = data | (~uint16_t(0) << bits); + if (parity) + { + if (m_wr4 & WR4_PARITY_EVEN) + m_tx_sr &= ~(uint16_t(1) << m_tx_bits); + ++m_tx_bits; + } + m_tx_flags = + ((!framing && (m_wr5 & WR5_TX_CRC_ENABLE)) ? TX_FLAG_CRC : 0U) | + (framing ? TX_FLAG_FRAMING : 0U) | + (special ? TX_FLAG_SPECIAL : 0U); +} + +inline void z80sio_channel::tx_setup_idle() +{ + switch (m_wr4 & WR4_SYNC_MODE_MASK) + { + case WR4_SYNC_MODE_8_BIT: + tx_setup(m_wr6, 8, 0, true, false); + break; + case WR4_SYNC_MODE_16_BIT: + tx_setup(uint16_t(m_wr6) | (uint16_t(m_wr7) << 8), 16, 0, true, false); + break; + case WR4_SYNC_MODE_SDLC: + // SDLC transmit examples don't show flag being loaded, implying it's hard-coded on the transmit side + tx_setup(0x7e, 8, 0, true, false); + break; + case WR4_SYNC_MODE_EXT: + // TODO: what does a real chip do for sync idle in external sync mode? + // This is based on the assumption that bit 4 controls 8-/16-bit idle pattern (fits for monosync/bisync/SDLC). + tx_setup(uint16_t(m_wr6) | (uint16_t(m_wr7) << 8), 16, 0, true, false); + break; + } +} + + //------------------------------------------------- // z80sio_device - constructor //------------------------------------------------- -z80sio_device::z80sio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant) - : device_t(mconfig, type, tag, owner, clock), +z80sio_device::z80sio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), device_z80daisy_interface(mconfig, *this), m_chanA(*this, CHANA_TAG), m_chanB(*this, CHANB_TAG), - m_rxca(0), - m_txca(0), - m_rxcb(0), - m_txcb(0), - m_out_txda_cb(*this), - m_out_dtra_cb(*this), - m_out_rtsa_cb(*this), - m_out_wrdya_cb(*this), - m_out_synca_cb(*this), - m_out_txdb_cb(*this), - m_out_dtrb_cb(*this), - m_out_rtsb_cb(*this), - m_out_wrdyb_cb(*this), - m_out_syncb_cb(*this), + m_out_txd_cb{ { *this }, { *this } }, + m_out_dtr_cb{ { *this }, { *this } }, + m_out_rts_cb{ { *this }, { *this } }, + m_out_wrdy_cb{ { *this }, { *this } }, + m_out_sync_cb{ { *this }, { *this } }, m_out_int_cb(*this), - m_out_rxdrqa_cb(*this), - m_out_txdrqa_cb(*this), - m_out_rxdrqb_cb(*this), - m_out_txdrqb_cb(*this), - m_variant(variant), + m_out_rxdrq_cb{ { *this }, { *this } }, + m_out_txdrq_cb{ { *this }, { *this } }, m_cputag(nullptr) { for (auto & elem : m_int_state) elem = 0; } -z80sio_device::z80sio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : z80sio_device(mconfig, Z80SIO, tag, owner, clock, TYPE_Z80SIO) +z80sio_device::z80sio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + z80sio_device(mconfig, Z80SIO, tag, owner, clock) { } -upd7201_new_device::upd7201_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : z80sio_device(mconfig, UPD7201_NEW, tag, owner, clock, TYPE_UPD7201) +i8274_new_device::i8274_new_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + z80sio_device(mconfig, type, tag, owner, clock) { } -i8274_new_device::i8274_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : z80sio_device(mconfig, I8274_NEW, tag, owner, clock, TYPE_I8274) +i8274_new_device::i8274_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + i8274_new_device(mconfig, I8274_NEW, tag, owner, clock) +{ +} + +upd7201_new_device::upd7201_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + i8274_new_device(mconfig, UPD7201_NEW, tag, owner, clock) { } @@ -171,21 +397,21 @@ void z80sio_device::device_resolve_objects() LOG("%s\n", FUNCNAME); // resolve callbacks - m_out_txda_cb.resolve_safe(); - m_out_dtra_cb.resolve_safe(); - m_out_rtsa_cb.resolve_safe(); - m_out_wrdya_cb.resolve_safe(); - m_out_synca_cb.resolve_safe(); - m_out_txdb_cb.resolve_safe(); - m_out_dtrb_cb.resolve_safe(); - m_out_rtsb_cb.resolve_safe(); - m_out_wrdyb_cb.resolve_safe(); - m_out_syncb_cb.resolve_safe(); + m_out_txd_cb[CHANNEL_A].resolve_safe(); + m_out_dtr_cb[CHANNEL_A].resolve_safe(); + m_out_rts_cb[CHANNEL_A].resolve_safe(); + m_out_wrdy_cb[CHANNEL_A].resolve_safe(); + m_out_sync_cb[CHANNEL_A].resolve_safe(); + m_out_txd_cb[CHANNEL_B].resolve_safe(); + m_out_dtr_cb[CHANNEL_B].resolve_safe(); + m_out_rts_cb[CHANNEL_B].resolve_safe(); + m_out_wrdy_cb[CHANNEL_B].resolve_safe(); + m_out_sync_cb[CHANNEL_B].resolve_safe(); m_out_int_cb.resolve_safe(); - m_out_rxdrqa_cb.resolve_safe(); - m_out_txdrqa_cb.resolve_safe(); - m_out_rxdrqb_cb.resolve_safe(); - m_out_txdrqb_cb.resolve_safe(); + m_out_rxdrq_cb[CHANNEL_A].resolve_safe(); + m_out_txdrq_cb[CHANNEL_A].resolve_safe(); + m_out_rxdrq_cb[CHANNEL_B].resolve_safe(); + m_out_txdrq_cb[CHANNEL_B].resolve_safe(); } //------------------------------------------------- @@ -195,17 +421,8 @@ void z80sio_device::device_start() { LOG("%s\n", FUNCNAME); - // configure channel A - m_chanA->m_rxc = m_rxca; - m_chanA->m_txc = m_txca; - - // configure channel B - m_chanB->m_rxc = m_rxcb; - m_chanB->m_txc = m_txcb; - // state saving save_item(NAME(m_int_state)); - save_item(NAME(m_int_source)); } @@ -215,9 +432,6 @@ void z80sio_device::device_start() void z80sio_device::device_reset() { LOG("%s \"%s\" \n", FUNCNAME, tag()); - - m_chanA->reset(); - m_chanB->reset(); } //------------------------------------------------- @@ -225,26 +439,26 @@ void z80sio_device::device_reset() //------------------------------------------------- int z80sio_device::z80daisy_irq_state() { - int state = 0; + int const *const prio = interrupt_priorities(); LOGINT("%s %s Hi->Lo:%d%d%d%d%d%d ", tag(), FUNCNAME, - m_int_state[0], m_int_state[1], m_int_state[2], - m_int_state[3], m_int_state[4], m_int_state[5]); + m_int_state[prio[0]], m_int_state[prio[1]], m_int_state[prio[2]], + m_int_state[prio[3]], m_int_state[prio[4]], m_int_state[prio[5]]); // loop over all interrupt sources - for (auto & elem : m_int_state) + int state = 0; + for (int i = 0; ARRAY_LENGTH(m_int_state) > i; ++i) { // if we're servicing a request, don't indicate more interrupts - if (elem & Z80_DAISY_IEO) + if (m_int_state[prio[i]] & Z80_DAISY_IEO) { state |= Z80_DAISY_IEO; break; } - state |= elem; + state |= m_int_state[prio[i]]; } LOGINT("Interrupt State %u\n", state); - return state; } @@ -254,34 +468,105 @@ int z80sio_device::z80daisy_irq_state() //------------------------------------------------- int z80sio_device::z80daisy_irq_ack() { - int ret = -1; // Indicate default vector + LOGINT("%s \n", FUNCNAME); - LOGINT("%s %s \n",tag(), FUNCNAME); // loop over all interrupt sources - for (auto & elem : m_int_state) + int const *const prio = interrupt_priorities(); + for (int i = 0; ARRAY_LENGTH(m_int_state) > i; ++i) { // find the first channel with an interrupt requested - if (elem & Z80_DAISY_INT) + if (m_int_state[prio[i]] & Z80_DAISY_INT) { - elem = Z80_DAISY_IEO; // Set IUS bit (called IEO in z80 daisy lingo) - m_chanA->m_rr0 &= ~z80sio_channel::RR0_INTERRUPT_PENDING; - LOGINT(" - Found an INT request, "); - LOGINT("returning RR2: %02x\n", m_chanB->m_rr2 ); + m_int_state[prio[i]] |= Z80_DAISY_IEO; // Set IUS bit (called IEO in z80 daisy lingo) + unsigned const vector = read_vector(); + LOGINT(" - Found an INT request, returning RR2: %02x\n", vector); check_interrupts(); - ret = m_chanB->m_rr2; - break; + return vector; } } + // Did we not find a vector? Get the notion of a default vector from the CPU implementation - if (ret == -1 && m_cputag != nullptr) + logerror(" - failed to find an interrupt to ack!\n"); + if (m_cputag) + { + // default irq vector is -1 for 68000 but 0 for z80 for example... + // FIXME: use an optional_device or something + int const ret = owner()->subdevice<cpu_device>(m_cputag)->default_irq_vector(); + LOGINT(" - failed to find an interrupt to ack [%s], returning default IRQ vector: %02x\n", m_cputag, ret); + return ret; + } + + // indicate default vector + return -1; +} + +int i8274_new_device::z80daisy_irq_ack() +{ + // FIXME: we're not modelling the full behaviour of this chip + // The 8274 is designed to work with Intel processors with multiple interrupt acknowledge cycles + // Values placed on the bus depend on WR2 A mode bits and /IPI input + // +----+----+----+------+--------------+-------+--------+ + // | D5 | D4 | D3 | /IPI | Mode | Cycle | Data | + // +----+----+----+------+--------------+-------+--------+ + // | 0 | - | - | - | non-vectored | - | hi-Z | + // +----+----+----+------+--------------+-------+--------+ + // | 1 | 0 | 0 | 0 | 8085 (1) | 1 | 0xcd | + // | | | | | | 2 | vector | + // | | | | | | 3 | 0x00 | + // +----+----+----+------+--------------+-------+--------+ + // | 1 | 0 | 0 | 1 | 8085 (1) | 1 | 0xcd | + // | | | | | | 2 | hi-Z | + // | | | | | | 3 | hi-Z | + // +----+----+----+------+--------------+-------+--------+ + // | 1 | 0 | 1 | 0 | 8085 (2) | 1 | hi-Z | + // | | | | | | 2 | vector | + // | | | | | | 3 | 0x00 | + // +----+----+----+------+--------------+-------+--------+ + // | 1 | 0 | 1 | 1 | 8085 (2) | 1 | hi-Z | + // | | | | | | 2 | hi-Z | + // | | | | | | 3 | hi-Z | + // +----+----+----+------+--------------+-------+--------+ + // | 1 | 1 | 0 | 0 | 8086 | 1 | hi-Z | + // | | | | | | 2 | vector | + // +----+----+----+------+--------------+-------+--------+ + // | 1 | 1 | 0 | 1 | 8086 | 1 | hi-Z | + // | | | | | | 2 | hi-Z | + // +----+----+----+------+--------------+-------+--------+ + LOGINT("%s \n", FUNCNAME); + + // don't do this in non-vectored mode + if (m_chanB->m_wr2 & WR2_VECTORED_INT) + { + // loop over all interrupt sources + int const *const prio = interrupt_priorities(); + for (int i = 0; ARRAY_LENGTH(m_int_state) > i; ++i) + { + // find the first channel with an interrupt requested + if (m_int_state[prio[i]] & Z80_DAISY_INT) + { + m_int_state[prio[i]] |= Z80_DAISY_IEO; // Set IUS bit (called IEO in z80 daisy lingo) + unsigned const vector = read_vector(); + LOGINT(" - Found an INT request, returning RR2: %02x\n", vector); + check_interrupts(); + return vector; + } + } + + // Did we not find a vector? Get the notion of a default vector from the CPU implementation + logerror(" - failed to find an interrupt to ack!\n"); + } + + if (m_cputag) { // default irq vector is -1 for 68000 but 0 for z80 for example... - ret = owner()->subdevice<cpu_device>(m_cputag)->default_irq_vector(); - LOGINT(" - failed to find an interrupt to ack [%s], returning default IRQ vector: %02x\n", m_cputag, ret ); - logerror("z80sio_irq_ack: failed to find an interrupt to ack!\n"); + // FIXME: use an optional_device or something + int const ret = owner()->subdevice<cpu_device>(m_cputag)->default_irq_vector(); + LOGINT(" - failed to find an interrupt to ack [%s], returning default IRQ vector: %02x\n", m_cputag, ret); + return ret; } - return ret; + // indicate default vector + return -1; } @@ -290,27 +575,13 @@ int z80sio_device::z80daisy_irq_ack() //------------------------------------------------- void z80sio_device::z80daisy_irq_reti() { - LOGINT("%s %s \n",tag(), FUNCNAME); - - if((m_variant == TYPE_I8274) || (m_variant == TYPE_UPD7201)) - { - LOGINT(" - I8274 and UPD7201 lacks RETI detection, no action taken\n"); - return; - } + LOGINT("%s\n", FUNCNAME); + return_from_interrupt(); +} - // loop over all interrupt sources - for (auto & elem : m_int_state) - { - // find the first channel with an interrupt requested - if (elem & Z80_DAISY_IEO) - { - // clear the IEO state and update the IRQs - elem &= ~Z80_DAISY_IEO; - check_interrupts(); - return; - } - } - LOGINT("z80sio_irq_reti: failed to find an interrupt to clear IEO on!\n"); +void i8274_new_device::z80daisy_irq_reti() +{ + LOGINT("%s - i8274/uPD7201 lacks RETI detection, no action taken\n", FUNCNAME); } @@ -319,7 +590,7 @@ void z80sio_device::z80daisy_irq_reti() //------------------------------------------------- void z80sio_device::check_interrupts() { - LOGINT("%s %s \n",FUNCNAME, tag()); + LOGINT("%s %s \n", FUNCNAME, tag()); int state = (z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE; m_out_int_cb(state); } @@ -340,44 +611,114 @@ void z80sio_device::reset_interrupts() check_interrupts(); } -int z80sio_device::get_interrupt_prio(int index, int type) +//------------------------------------------------- +// trigger_interrupt - interrupt has fired +//------------------------------------------------- +void z80sio_device::trigger_interrupt(int index, int type) +{ + LOGINT("%s Chan:%c Type:%s\n", FUNCNAME, 'A' + index, std::array<char const *, 3> + {{"INT_TRANSMIT", "INT_EXTERNAL", "INT_RECEIVE"}}[type]); + + // trigger interrupt + m_int_state[(index * 3) + type] |= Z80_DAISY_INT; + m_chanA->m_rr0 |= RR0_INTERRUPT_PENDING; + + // check for interrupt + check_interrupts(); +} + + +//------------------------------------------------- +// clear_interrupt - interrupt has been cleared +//------------------------------------------------- +void z80sio_device::clear_interrupt(int index, int type) { - int prio_level = -1; - int priority = -1; + LOGINT("%s Chan:%c Type:%s\n", FUNCNAME, 'A' + index, std::array<char const *, 3> + {{"INT_TRANSMIT", "INT_EXTERNAL", "INT_RECEIVE"}}[type]); + + // clear interrupt + m_int_state[(index * 3) + type] &= ~Z80_DAISY_INT; + if (std::find_if(std::begin(m_int_state), std::end(m_int_state), [] (int state) { return bool(state & Z80_DAISY_INT); }) == std::end(m_int_state)) + m_chanA->m_rr0 &= ~RR0_INTERRUPT_PENDING; + + // update interrupt output + check_interrupts(); +} - if ((m_variant == TYPE_I8274) || (m_variant == TYPE_UPD7201)) + +//------------------------------------------------- +// return_from_interrupt - reset interrupt under +// service latch +//------------------------------------------------- +void z80sio_device::return_from_interrupt() +{ + // loop over all interrupt sources + int const *const prio = interrupt_priorities(); + for (int i = 0; ARRAY_LENGTH(m_int_state) > i; ++i) { - /* These CPU variants use Bit 2 of WR2 of Channnel A to determine the priority Hi to Lo: - 0: RxA TxA RxB TxB ExtA ExtB - 1: RxA RxB TxA TxB ExtA ExtB */ - switch(type) + // find the first channel with an interrupt requested + if (m_int_state[prio[i]] & (Z80_DAISY_IEO)) { - case z80sio_channel::INT_RECEIVE: - case z80sio_channel::INT_SPECIAL: prio_level = z80sio_channel::INT_RCV_SPC_PRI_LVL; break; // 0 - case z80sio_channel::INT_TRANSMIT: prio_level = z80sio_channel::INT_TRANSMIT_PRI_LVL; break; // 1 - case z80sio_channel::INT_EXTERNAL: prio_level = z80sio_channel::INT_EXTERNAL_PRI_LVL; break; // 2 - default: - logerror("Bad interrupt source being prioritized!"); - return -1; + // clear the IEO state and update the IRQs + m_int_state[prio[i]] &= ~Z80_DAISY_IEO; + check_interrupts(); + LOGINT("%s - cleared IEO\n", FUNCNAME); + return; } - // Assume that the PRIORITY bit is set - priority = (prio_level * 2) + index; + } + LOGINT("%s - failed to find an interrupt to clear IEO on!", FUNCNAME); +} + + +//------------------------------------------------- +// read_vector - read modified interrupt vector +//------------------------------------------------- +uint8_t z80sio_device::read_vector() +{ + uint8_t vec = m_chanB->m_wr2; + + // if status doesn't affect vector, return unmodified value + if (!(m_chanB->m_wr1 & WR1_STATUS_VECTOR)) + return vec; - // Check if it actually was cleared - if ( (m_chanA->m_wr2 & z80sio_channel::WR2_PRIORITY) == 0) + // modify vector for highest-priority pending interrupt + int const *const prio = interrupt_priorities(); + vec &= 0xf1U; + for (int i = 0; ARRAY_LENGTH(m_int_state) > i; ++i) + { + if (m_int_state[prio[i]] & Z80_DAISY_INT) { - // Adjust priority if needed, only affects TxA and RxB - if (index == CHANNEL_A && type == z80sio_channel::INT_TRANSMIT ) - priority--; - else if (index == CHANNEL_B && type == z80sio_channel::INT_RECEIVE ) - priority++; + constexpr uint8_t RR1_SPECIAL(RR1_RX_OVERRUN_ERROR | RR1_CRC_FRAMING_ERROR | RR1_END_OF_FRAME); + switch (prio[i]) + { + case 0 + z80sio_channel::INT_TRANSMIT: + return vec | 0x08U; + case 0 + z80sio_channel::INT_EXTERNAL: + return vec | 0x0aU; + case 0 + z80sio_channel::INT_RECEIVE: + if (((m_chanA->m_wr1 & WR1_RX_INT_MODE_MASK) == WR1_RX_INT_ALL_PARITY) && (m_chanA->m_rr1 & (RR1_SPECIAL | RR1_PARITY_ERROR))) + return vec | 0x0eU; + else if (((m_chanA->m_wr1 & WR1_RX_INT_MODE_MASK) == WR1_RX_INT_ALL) && (m_chanA->m_rr1 & RR1_SPECIAL)) + return vec | 0x0eU; + else + return vec | 0x0cU; + case 3 + z80sio_channel::INT_TRANSMIT: + return vec | 0x00U; + case 3 + z80sio_channel::INT_EXTERNAL: + return vec | 0x02U; + case 3 + z80sio_channel::INT_RECEIVE: + if (((m_chanB->m_wr1 & WR1_RX_INT_MODE_MASK) == WR1_RX_INT_ALL_PARITY) && (m_chanB->m_rr1 & (RR1_SPECIAL | RR1_PARITY_ERROR))) + return vec | 0x06U; + else if (((m_chanB->m_wr1 & WR1_RX_INT_MODE_MASK) == WR1_RX_INT_ALL) && (m_chanB->m_rr1 & RR1_SPECIAL)) + return vec | 0x06U; + else + return vec | 0x04U; + } } } - else // Plain old z80sio - { - priority = (index << 2) | type; - } - return priority; + + // no interrupt pending - stuff 011 in the variable bits + return vec | 0x06U; } /* @@ -387,59 +728,92 @@ int z80sio_device::get_interrupt_prio(int index, int type) interrrupt is generated, otherwise it will indicate the previous state." 8274: "If RR2 is specified but not read, no internal interrupts, regardless of priority, are accepted." */ -uint8_t z80sio_device::modify_vector(int index, int type) +uint8_t i8274_new_device::read_vector() { - uint8_t vector = m_chanB->m_wr2; - if((m_variant == TYPE_I8274) || (m_variant == TYPE_UPD7201)) + // 8086 and 8085 modes have different variable bits + bool const aff(m_chanB->m_wr1 & WR1_STATUS_VECTOR); + int const shift(((m_chanA->m_wr2 & WR2_MODE_MASK) == WR2_MODE_8086_8088) ? 0 : 2); + uint8_t vec(m_chanB->m_wr2); + + // if status doesn't affect vector, return unmodified value + if (aff) + vec &= ~(0x07U << shift); + + // modify vector for highest-priority pending interrupt + int const *const prio = interrupt_priorities(); + for (int i = 0; ARRAY_LENGTH(m_int_state) > i; ++i) { - if (m_chanB->m_wr1 & z80sio_channel::WR1_STATUS_VECTOR) + if (m_int_state[prio[i]] & Z80_DAISY_INT) { - vector = (!index << 2) | type; - if((m_chanA->m_wr1 & 0x18) == z80sio_channel::WR2_MODE_8086_8088) + constexpr uint8_t RR1_SPECIAL(RR1_RX_OVERRUN_ERROR | RR1_CRC_FRAMING_ERROR | RR1_END_OF_FRAME); + + // in non-vectored mode this serves the same function as the end of the second acknowldege cycle + if (!(m_chanB->m_wr2 & WR2_VECTORED_INT) && !machine().side_effect_disabled()) { - vector = (m_chanB->m_wr2 & 0xf8) | vector; // m_chanB->m_wr2; + m_int_state[prio[i]] |= Z80_DAISY_IEO; + check_interrupts(); } - else + + // if status doesn't affect vector return unmodified value + if (!aff) + return vec; + + switch (prio[i]) { - vector = (m_chanB->m_wr2 & 0xe3) | (vector << 2); //(m_chanB->m_wr2 << 2); + case 0 + z80sio_channel::INT_TRANSMIT: + return vec | (0x04U << shift); + case 0 + z80sio_channel::INT_EXTERNAL: + return vec | (0x05U << shift); + case 0 + z80sio_channel::INT_RECEIVE: + if (((m_chanA->m_wr1 & WR1_RX_INT_MODE_MASK) == WR1_RX_INT_ALL_PARITY) && (m_chanA->m_rr1 & (RR1_SPECIAL | RR1_PARITY_ERROR))) + return vec | (0x07U << shift); + else if (((m_chanA->m_wr1 & WR1_RX_INT_MODE_MASK) == WR1_RX_INT_ALL) && (m_chanA->m_rr1 & RR1_SPECIAL)) + return vec | (0x07U << shift); + else + return vec | (0x06U << shift); + case 3 + z80sio_channel::INT_TRANSMIT: + return vec | (0x00U << shift); + case 3 + z80sio_channel::INT_EXTERNAL: + return vec | (0x01U << shift); + case 3 + z80sio_channel::INT_RECEIVE: + if (((m_chanB->m_wr1 & WR1_RX_INT_MODE_MASK) == WR1_RX_INT_ALL_PARITY) && (m_chanB->m_rr1 & (RR1_SPECIAL | RR1_PARITY_ERROR))) + return vec | (0x03U << shift); + else if (((m_chanB->m_wr1 & WR1_RX_INT_MODE_MASK) == WR1_RX_INT_ALL) && (m_chanB->m_rr1 & RR1_SPECIAL)) + return vec | (0x03U << shift); + else + return vec | (0x02U << shift); } } } - else - { - if (m_chanB->m_wr1 & z80sio_channel::WR1_STATUS_VECTOR) - { - // status affects vector - vector = (m_chanB->m_wr2 & 0xf1) | (!index << 3) | (type << 1); - } - } - return vector; + + // no interrupt pending - stuff 111 in the variable bits + return aff ? (vec | (0x07 << shift)) : vec; } + //------------------------------------------------- -// trigger_interrupt - TODO: needs attention for SIO +// interrupt_priorities - get interrupt indexes +// in priority order //------------------------------------------------- -void z80sio_device::trigger_interrupt(int index, int type) +int const *z80sio_device::interrupt_priorities() const { - uint8_t priority = get_interrupt_prio(index, type); - uint8_t vector = modify_vector(index, type); - - LOGINT("%s %s Chan:%c Type:%s\n", tag(), FUNCNAME, 'A' + index, std::array<char const *, 4> - {{"INT_TRANSMIT", "INT_EXTERNAL", "INT_RECEIVE", "INT_SPECIAL"}}[type]); - LOGINT(" - Priority:%02x Vector:%02x\n", priority, vector); - - // update vector register - m_chanB->m_rr2 = vector; - - // trigger interrupt - m_int_state[priority] |= Z80_DAISY_INT; - m_chanA->m_rr0 |= z80sio_channel::RR0_INTERRUPT_PENDING; - - // remember the source and channel - m_int_source[priority] = (type & 0xff) | (index << 8); + static constexpr EQUIVALENT_ARRAY(m_int_state, int) prio{ + 0 + z80sio_channel::INT_RECEIVE, 0 + z80sio_channel::INT_TRANSMIT, 0 + z80sio_channel::INT_EXTERNAL, + 3 + z80sio_channel::INT_RECEIVE, 3 + z80sio_channel::INT_TRANSMIT, 3 + z80sio_channel::INT_EXTERNAL }; + return prio; +} - // check for interrupt - check_interrupts(); +int const *i8274_new_device::interrupt_priorities() const +{ + static constexpr EQUIVALENT_ARRAY(m_int_state, int) prio_a{ + 0 + z80sio_channel::INT_RECEIVE, 3 + z80sio_channel::INT_RECEIVE, + 0 + z80sio_channel::INT_TRANSMIT, 3 + z80sio_channel::INT_TRANSMIT, + 0 + z80sio_channel::INT_EXTERNAL, 3 + z80sio_channel::INT_EXTERNAL }; + static constexpr EQUIVALENT_ARRAY(m_int_state, int) prio_b{ + 0 + z80sio_channel::INT_RECEIVE, 0 + z80sio_channel::INT_TRANSMIT, + 3 + z80sio_channel::INT_RECEIVE, 3 + z80sio_channel::INT_TRANSMIT, + 0 + z80sio_channel::INT_EXTERNAL, 3 + z80sio_channel::INT_EXTERNAL }; + return (m_chanA->m_wr2 & WR2_PRIORITY) ? prio_a : prio_b; } @@ -449,10 +823,13 @@ void z80sio_device::trigger_interrupt(int index, int type) int z80sio_device::m1_r() { LOGINT("%s %s \n",FUNCNAME, tag()); - if((m_variant == TYPE_I8274) || (m_variant == TYPE_UPD7201)) - return 0; - else - return z80daisy_irq_ack(); + return z80daisy_irq_ack(); +} + +int i8274_new_device::m1_r() +{ + LOGINT("%s %s \n",FUNCNAME, tag()); + return 0; } @@ -520,31 +897,47 @@ WRITE8_MEMBER( z80sio_device::ba_cd_w ) //------------------------------------------------- // z80sio_channel - constructor //------------------------------------------------- -z80sio_channel::z80sio_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, Z80SIO_CHANNEL, tag, owner, clock) - , device_serial_interface(mconfig, *this) - , m_rx_error(0) +z80sio_channel::z80sio_channel( + const machine_config &mconfig, + device_type type, + const char *tag, + device_t *owner, + uint32_t clock, + uint8_t rr1_auto_reset) + : device_t(mconfig, type, tag, owner, clock) + , m_rx_fifo_depth(0) + , m_rx_data_fifo(0) + , m_rx_error_fifo(0) , m_rx_clock(0) + , m_rx_count(0) + , m_rx_bit(0) + , m_rx_sr(0) , m_rx_first(0) , m_rx_break(0) - , m_rx_rr0_latch(0) - , m_rxd(0) - , m_sh(0) - , m_cts(0) - , m_dcd(0) + , m_rxd(1) , m_tx_data(0) - , m_tx_clock(0) - , m_dtr(0) - , m_rts(0) - , m_sync(0) + , m_tx_clock(0), m_tx_count(0), m_tx_bits(0), m_tx_parity(0), m_tx_sr(0), m_tx_crc(0), m_tx_hist(0), m_tx_flags(0) + , m_txd(1), m_dtr(0), m_rts(0) + , m_ext_latched(0), m_brk_latched(0), m_cts(0), m_dcd(0), m_sync(0) + , m_rr1_auto_reset(rr1_auto_reset) { LOG("%s\n",FUNCNAME); // Reset all registers - m_rr0 = m_rr1 = m_rr2 = 0; + m_rr0 = m_rr1 = 0; m_wr0 = m_wr1 = m_wr2 = m_wr3 = m_wr4 = m_wr5 = m_wr6 = m_wr7 = 0; } +z80sio_channel::z80sio_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : z80sio_channel(mconfig, Z80SIO_CHANNEL, tag, owner, clock, RR1_CRC_FRAMING_ERROR) +{ +} + +i8274_channel::i8274_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : z80sio_channel(mconfig, I8274_CHANNEL, tag, owner, clock, RR1_RX_OVERRUN_ERROR) +{ +} + //------------------------------------------------- // resove_objects - channel setup @@ -554,7 +947,6 @@ void z80sio_channel::device_resolve_objects() LOG("%s\n",FUNCNAME); m_uart = downcast<z80sio_device *>(owner()); m_index = m_uart->get_channel_index(this); - m_variant = m_uart->m_variant; } //------------------------------------------------- @@ -567,7 +959,6 @@ void z80sio_channel::device_start() // state saving save_item(NAME(m_rr0)); save_item(NAME(m_rr1)); - save_item(NAME(m_rr2)); save_item(NAME(m_wr0)); save_item(NAME(m_wr1)); save_item(NAME(m_wr2)); @@ -576,20 +967,32 @@ void z80sio_channel::device_start() save_item(NAME(m_wr5)); save_item(NAME(m_wr6)); save_item(NAME(m_wr7)); - save_item(NAME(m_rx_error)); + save_item(NAME(m_rx_fifo_depth)); + save_item(NAME(m_rx_data_fifo)); + save_item(NAME(m_rx_error_fifo)); save_item(NAME(m_rx_clock)); + save_item(NAME(m_rx_count)); + save_item(NAME(m_rx_bit)); + save_item(NAME(m_rx_sr)); save_item(NAME(m_rx_first)); save_item(NAME(m_rx_break)); - save_item(NAME(m_rx_rr0_latch)); - save_item(NAME(m_sh)); - save_item(NAME(m_cts)); - save_item(NAME(m_dcd)); save_item(NAME(m_tx_data)); save_item(NAME(m_tx_clock)); + save_item(NAME(m_tx_count)); + save_item(NAME(m_tx_bits)); + save_item(NAME(m_tx_parity)); + save_item(NAME(m_tx_sr)); + save_item(NAME(m_tx_crc)); + save_item(NAME(m_tx_hist)); + save_item(NAME(m_tx_flags)); + save_item(NAME(m_txd)); save_item(NAME(m_dtr)); save_item(NAME(m_rts)); + save_item(NAME(m_ext_latched)); + save_item(NAME(m_brk_latched)); + save_item(NAME(m_dcd)); save_item(NAME(m_sync)); - save_item(NAME(m_variant)); + save_item(NAME(m_cts)); } @@ -601,145 +1004,217 @@ void z80sio_channel::device_reset() LOG("%s\n", FUNCNAME); // Reset RS232 emulation - receive_register_reset(); - transmit_register_reset(); + m_rx_fifo_depth = 0; + m_rx_data_fifo = m_rx_error_fifo = 0U; + m_rx_bit = 0; + m_tx_count = 0; + m_tx_bits = 0; + m_rr0 &= ~RR0_RX_CHAR_AVAILABLE; + m_rr1 &= ~(RR1_PARITY_ERROR | RR1_RX_OVERRUN_ERROR | RR1_CRC_FRAMING_ERROR); // disable receiver m_wr3 &= ~WR3_RX_ENABLE; // disable transmitter m_wr5 &= ~WR5_TX_ENABLE; - m_rr0 |= RR0_TX_BUFFER_EMPTY; + m_rr0 |= RR0_TX_BUFFER_EMPTY | RR0_TX_UNDERRUN; m_rr1 |= RR1_ALL_SENT; + m_tx_flags = 0U; + + // TODO: what happens to WAIT/READY? // reset external lines - set_rts(1); - set_dtr(1); + out_rts_cb(m_rts = 1); + out_dtr_cb(m_dtr = 1); // reset interrupts + m_uart->clear_interrupt(m_index, INT_TRANSMIT); + m_uart->clear_interrupt(m_index, INT_RECEIVE); + reset_ext_status(); + // FIXME: should this actually reset all the interrtupts, or just the prioritisation (daisy chain) logic? if (m_index == z80sio_device::CHANNEL_A) - { m_uart->reset_interrupts(); - } } + //------------------------------------------------- -// tra_callback - +// transmit_enable - start transmission if +// conditions met //------------------------------------------------- -void z80sio_channel::tra_callback() +void z80sio_channel::transmit_enable() { - if (!(m_wr5 & WR5_TX_ENABLE)) + if (!m_tx_bits && transmit_allowed()) { - LOGBIT("%s() \"%s \"Channel %c transmit mark 1 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); - // transmit mark - if (m_index == z80sio_device::CHANNEL_A) - m_uart->m_out_txda_cb(1); - else - m_uart->m_out_txdb_cb(1); - } - else if (m_wr5 & WR5_SEND_BREAK) - { - LOGBIT("%s() \"%s \"Channel %c send break 1 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); - // transmit break - if (m_index == z80sio_device::CHANNEL_A) - m_uart->m_out_txda_cb(0); - else - m_uart->m_out_txdb_cb(0); + if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC) + { + LOGTX("Channel %c synchronous transmit enabled - load sync pattern\n", 'A' + m_index); + tx_setup_idle(); + if ((m_wr1 & WR1_WRDY_ENABLE) && !(m_wr1 & WR1_WRDY_ON_RX_TX)) + set_ready(true); + } + else if (!(m_rr0 & RR0_TX_BUFFER_EMPTY)) + { + async_tx_setup(); + } } - else if (!is_transmit_register_empty()) - { - int db = transmit_register_get_data_bit(); +} - LOGBIT("%s() \"%s \"Channel %c transmit data bit %d m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, db, m_wr5); - // transmit data - if (m_index == z80sio_device::CHANNEL_A) - m_uart->m_out_txda_cb(db); - else - m_uart->m_out_txdb_cb(db); - } +//------------------------------------------------- +// transmit_complete - transmit shift register +// empty +//------------------------------------------------- +void z80sio_channel::transmit_complete() +{ + LOG("%s %s\n",FUNCNAME, tag()); + + if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC) + sync_tx_sr_empty(); + else if (transmit_allowed() && !(m_rr0 & RR0_TX_BUFFER_EMPTY)) + async_tx_setup(); // async mode, with data available else - { - LOGBIT("%s() \"%s \"Channel %c Failed to transmit m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); - logerror("%s \"%s \"Channel %c Failed to transmit\n", FUNCNAME, owner()->tag(), 'A' + m_index); - } + LOGTX("%s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); } - //------------------------------------------------- -// tra_complete - +// sync_tx_sr_empty - set up next chunk of bits +// to send //------------------------------------------------- -void z80sio_channel::tra_complete() +void z80sio_channel::sync_tx_sr_empty() { - LOG("%s %s\n",FUNCNAME, tag()); - if ((m_wr5 & WR5_TX_ENABLE) && !(m_wr5 & WR5_SEND_BREAK) && !(m_rr0 & RR0_TX_BUFFER_EMPTY)) + if (!transmit_allowed()) { - LOGTX("%s() \"%s \"Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_tx_data, m_wr5); + LOGTX("%s() Channel %c Transmitter Disabled m_wr5:%02x\n", FUNCNAME, 'A' + m_index, m_wr5); - transmit_register_setup(m_tx_data); + // transmit disabled, set flag if nothing pending + m_tx_flags &= ~TX_FLAG_SPECIAL; + if (m_rr0 & RR0_TX_BUFFER_EMPTY) + m_rr1 |= RR1_ALL_SENT; + } + else if (!(m_rr0 & RR0_TX_BUFFER_EMPTY)) + { + LOGTX("%s() Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", FUNCNAME, 'A' + m_index, m_tx_data, m_wr5); + tx_setup(m_tx_data, get_tx_word_length(m_tx_data), (m_wr4 & WR4_PARITY_ENABLE) ? 1 : 0, false, false); // empty transmit buffer m_rr0 |= RR0_TX_BUFFER_EMPTY; - + if ((m_wr1 & WR1_WRDY_ENABLE) && !(m_wr1 & WR1_WRDY_ON_RX_TX)) + set_ready(true); if (m_wr1 & WR1_TX_INT_ENABLE) m_uart->trigger_interrupt(m_index, INT_TRANSMIT); } - else if (m_wr5 & WR5_SEND_BREAK) + else if ((m_rr0 & RR0_TX_UNDERRUN) || ((m_wr4 & WR4_SYNC_MODE_MASK) == WR4_SYNC_MODE_8_BIT)) { - LOGTX("%s() \"%s \"Channel %c Transmit Break 0 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); - // transmit break - if (m_index == z80sio_device::CHANNEL_A) - m_uart->m_out_txda_cb(0); - else - m_uart->m_out_txdb_cb(0); + // uts20 always resets the underrun/end-of-message flag if it sees it set, but wants to see sync (not CRC) on the loopback. + // It seems odd that automatic CRC transmission would be disabled by certain modes, but this at least allows the test to pass. + + LOGTX("%s() Channel %c Underrun - load sync pattern m_wr5:%02x\n", FUNCNAME, 'A' + m_index, m_wr5); + bool const first_idle((m_tx_flags & TX_FLAG_SPECIAL) || !(m_tx_flags & TX_FLAG_FRAMING)); + tx_setup_idle(); + + if ((m_wr1 & WR1_WRDY_ENABLE) && !(m_wr1 & WR1_WRDY_ON_RX_TX)) + set_ready(true); + m_rr1 |= RR1_ALL_SENT; + + // if this is the first sync pattern, generate an interrupt indicating that the next frame can be sent + // FIXME: uts20 definitely doesn't want a Tx interrupt here, but what does SDLC mode want? + // In that case, it would seem that the underrun flag would already be set when the CRC was loaded. + if (!(m_rr0 & RR0_TX_UNDERRUN)) + trigger_ext_int(); + else if (first_idle && (m_wr1 & WR1_TX_INT_ENABLE)) + m_uart->trigger_interrupt(m_index, INT_TRANSMIT); } else { - LOGTX("%s() \"%s \"Channel %c Transmit Mark 1 m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); - // transmit mark - if (m_index == z80sio_device::CHANNEL_A) - m_uart->m_out_txda_cb(1); - else - m_uart->m_out_txdb_cb(1); - } + LOGTX("%s() Channel %c Transmit FCS '%04x' m_wr5:%02x\n", FUNCNAME, 'A' + m_index, m_tx_crc, m_wr5); - // if transmit buffer is empty - if (m_rr0 & RR0_TX_BUFFER_EMPTY) - { - LOGTX("%s() \"%s \"Channel %c Transmit buffer empty m_wr5:%02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_wr5); - // then all characters have been sent - m_rr1 |= RR1_ALL_SENT; + // just for fun, SDLC sends the FCS inverted in reverse bit order + uint16_t const fcs(BITSWAP16(m_tx_crc, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)); + tx_setup(((m_wr4 & WR4_SYNC_MODE_MASK) == WR4_SYNC_MODE_SDLC) ? ~fcs : fcs, 16, 0, false, true); - // when the RTS bit is reset, the _RTS output goes high after the transmitter empties - if (!m_rts) - set_rts(1); + // set the underrun flag so it will send sync next time + m_rr0 |= RR0_TX_UNDERRUN; + trigger_ext_int(); } } //------------------------------------------------- -// rcv_callback - +// async_tx_setup - set up for asynchronous +// transmission //------------------------------------------------- -void z80sio_channel::rcv_callback() +void z80sio_channel::async_tx_setup() { - if (m_wr3 & WR3_RX_ENABLE) - { - LOGBIT("%s() \"%s \"Channel %c Received Data Bit %d\n", FUNCNAME, owner()->tag(), 'A' + m_index, m_rxd); - receive_register_update_bit(m_rxd); - } + LOGTX("%s() Channel %c Transmit Data Byte '%02x' m_wr5:%02x\n", FUNCNAME, 'A' + m_index, m_tx_data, m_wr5); + + tx_setup(uint16_t(m_tx_data) << 1, get_tx_word_length(m_tx_data) + 1, (m_wr4 & WR4_PARITY_ENABLE) ? 2 : 0, false, false); + ++m_tx_bits; // stop bit + + // empty transmit buffer + m_rr0 |= RR0_TX_BUFFER_EMPTY; + if ((m_wr1 & WR1_WRDY_ENABLE) && !(m_wr1 & WR1_WRDY_ON_RX_TX)) + set_ready(true); + if (m_wr1 & WR1_TX_INT_ENABLE) + m_uart->trigger_interrupt(m_index, INT_TRANSMIT); +} + + +//------------------------------------------------- +// reset_ext_status - reset external/status +// condiotions +//------------------------------------------------- +void z80sio_channel::reset_ext_status() +{ + // this will clear latched external pin state + m_ext_latched = 0; + m_brk_latched = 0; + read_ext(); + + // Clear any pending External interrupt + m_uart->clear_interrupt(m_index, INT_EXTERNAL); } //------------------------------------------------- -// rcv_complete - +// read_ext - copy external status to register //------------------------------------------------- -void z80sio_channel::rcv_complete() +void z80sio_channel::read_ext() { - uint8_t data; + // clear to send + if (m_cts) + m_rr0 &= ~RR0_CTS; + else + m_rr0 |= RR0_CTS; + + // data carrier detect + if (m_dcd) + m_rr0 &= ~RR0_DCD; + else + m_rr0 |= RR0_DCD; + + // sync is a general-purpose input in asynchronous mode + if ((m_wr4 & WR4_STOP_BITS_MASK) != WR4_STOP_BITS_SYNC) + { + if (m_sync) + m_rr0 &= ~RR0_SYNC_HUNT; + else + m_rr0 |= RR0_SYNC_HUNT; + } +} - receive_register_extract(); - data = get_received_char(); - LOGRCV("%s() \"%s \"Channel %c Received Data %02x\n", FUNCNAME, owner()->tag(), 'A' + m_index, data); - receive_data(data); +//------------------------------------------------- +// trigger_ext_int - trigger external signal +// interrupt +//------------------------------------------------- +void z80sio_channel::trigger_ext_int() +{ + // update line + if (!m_ext_latched) + read_ext(); + m_ext_latched = 1; + + // trigger interrupt if enabled + if (m_wr1 & WR1_EXT_INT_ENABLE) + m_uart->trigger_interrupt(m_index, INT_EXTERNAL); } @@ -772,49 +1247,24 @@ int z80sio_channel::get_clock_mode() CR5 = m_wr5 and SR1 = m_rr1 */ -void z80sio_channel::set_rts(int state) -{ - LOG("%s(%d) \"%s\" Channel %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index); - if (m_index == z80sio_device::CHANNEL_A) - m_uart->m_out_rtsa_cb(state); - else - m_uart->m_out_rtsb_cb(state); -} - -void z80sio_channel::update_rts() +void z80sio_channel::update_dtr_rts_break() { // LOG("%s(%d) \"%s\" Channel %c \n", FUNCNAME, state, owner()->tag(), 'A' + m_index); LOG("%s() \"%s\" Channel %c \n", FUNCNAME, owner()->tag(), 'A' + m_index); + + // RTS is affected by transmit queue state in asynchronous mode if (m_wr5 & WR5_RTS) - { - // when the RTS bit is set, the _RTS output goes low - set_rts(0); - m_rts = 1; - } + set_rts(0); // when the RTS bit is set, the _RTS output goes low + else if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC) + set_rts(1); // in synchronous mode, there's no automatic RTS else - { - // when the RTS bit is reset, the _RTS output goes high after the transmitter empties - m_rts = 0; - } + set_rts(((m_rr0 & RR0_TX_BUFFER_EMPTY) && !m_tx_count) ? 1 : 0); // TODO: is this affected by transmit enable? - // data terminal ready output follows the state programmed into the DTR bit*/ - set_dtr((m_wr5 & WR5_DTR) ? 0 : 1); -} + // break immediately forces spacing condition on TxD output + out_txd_cb((m_wr5 & WR5_SEND_BREAK) ? 0 : m_txd); -//------------------------------------------------- -// get_stop_bits - get number of stop bits -//------------------------------------------------- -device_serial_interface::stop_bits_t z80sio_channel::get_stop_bits() -{ - LOG("%s %s\n",FUNCNAME, tag()); - switch (m_wr4 & WR4_STOP_BITS_MASK) - { - case WR4_STOP_BITS_1: return STOP_BITS_1; - case WR4_STOP_BITS_1_5: return STOP_BITS_1_5; - case WR4_STOP_BITS_2: return STOP_BITS_2; - } - - return STOP_BITS_0; + // data terminal ready output follows the state programmed into the DTR bit + set_dtr((m_wr5 & WR5_DTR) ? 0 : 1); } @@ -841,19 +1291,32 @@ int z80sio_channel::get_rx_word_length() //------------------------------------------------- // get_tx_word_length - get transmit word length //------------------------------------------------- -int z80sio_channel::get_tx_word_length() +int z80sio_channel::get_tx_word_length() const { - LOG("%s %s\n",FUNCNAME, tag()); - int bits = 5; + LOG("%s\n", FUNCNAME); switch (m_wr5 & WR5_TX_WORD_LENGTH_MASK) { - case WR5_TX_WORD_LENGTH_5: bits = 5; break; - case WR5_TX_WORD_LENGTH_6: bits = 6; break; - case WR5_TX_WORD_LENGTH_7: bits = 7; break; - case WR5_TX_WORD_LENGTH_8: bits = 8; break; + case WR5_TX_WORD_LENGTH_5: return 5; + case WR5_TX_WORD_LENGTH_6: return 6; + case WR5_TX_WORD_LENGTH_7: return 7; + case WR5_TX_WORD_LENGTH_8: return 8; } + return 5; +} + +int z80sio_channel::get_tx_word_length(uint8_t data) const +{ + LOG("%s(%02x)\n", FUNCNAME, data); + + // deal with "five bits or less" mode (the actual chips probably detect a sentinel pattern in the transmit shift register) + int bits = get_tx_word_length(); + if (5 == bits) + { + for (int b = 7; (b >= 4) && BIT(data, b); --b) + --bits; + } return bits; } @@ -863,8 +1326,11 @@ int z80sio_channel::get_tx_word_length() * Break/Abort latch. */ uint8_t z80sio_channel::do_sioreg_rr0() { - LOGR("%s %s\n",FUNCNAME, tag()); - return m_rr0; + LOGR("%s\n", FUNCNAME); + if (m_tx_flags & TX_FLAG_SPECIAL) + return m_rr0 & ~RR0_TX_BUFFER_EMPTY; + else + return m_rr0; } /* @@ -872,10 +1338,7 @@ uint8_t z80sio_channel::do_sioreg_rr0() * codes for the I-Field in the SDLC Receive Mode. */ uint8_t z80sio_channel::do_sioreg_rr1() { - LOGR("%s %s\n",FUNCNAME, tag()); - // channel B only, channel A returns 0 - if (m_index == z80sio_device::CHANNEL_A) return 0; - + LOGR("%s\n", FUNCNAME); return m_rr1; } @@ -902,41 +1365,12 @@ uint8_t z80sio_channel::do_sioreg_rr1() uint8_t z80sio_channel::do_sioreg_rr2() { LOGINT("%s %s Chan:%c\n", tag(), FUNCNAME, 'A' + m_index); - // channel B only, channel A returns 0 - if (m_index == z80sio_device::CHANNEL_A) return 0; - - LOGINT(" - Channel B so we might need to update the vector modification\n"); - // Assume the unmodified vector - m_rr2 = m_uart->m_chanB->m_wr2; - - if((m_variant == z80sio_device::TYPE_I8274) || (m_variant == z80sio_device::TYPE_UPD7201)) - { - int i = 0; - LOGINT(" - 8274 or 7201 requires special care\n"); - // loop over all interrupt sources - for (auto & elem : m_uart->m_int_state) - { - // find the first channel with an interrupt requested - if (elem & Z80_DAISY_INT) - { - LOGINT(" - Checking an INT source %d\n", i); - m_rr2 = m_uart->modify_vector((m_uart->m_int_source[i] >> 8) & 1, m_uart->m_int_source[i] & 3); - LOGINT(" - Found an INT request to ack while reading RR2\n"); - elem = Z80_DAISY_IEO; // Set IUS bit (called IEO in z80 daisy lingo) - m_uart->check_interrupts(); - break; - } - i++; - } - // If no pending interrupt were found set variable bits to ones. - if (i >= 6) - { - m_rr2 |= 0x1F; - m_uart->m_chanA->m_rr0 &= ~z80sio_channel::RR0_INTERRUPT_PENDING; - } - } - return m_rr2; + // channel B only, channel A returns 0 + if (m_index == z80sio_device::CHANNEL_A) + return 0U; + else + return m_uart->read_vector(); } @@ -946,18 +1380,16 @@ uint8_t z80sio_channel::do_sioreg_rr2() uint8_t z80sio_channel::control_read() { uint8_t data = 0; - uint8_t reg = m_wr0 & WR0_REGISTER_MASK; + uint8_t const reg = m_wr0 & WR0_REGISTER_MASK; //LOG("%s %s\n",FUNCNAME, tag()); - if (reg != 0) - { - // mask out register index + // mask out register index + if (!machine().side_effect_disabled()) m_wr0 &= ~WR0_REGISTER_MASK; - } switch (reg) { - case REG_RR0_STATUS: data = do_sioreg_rr0(); break; + case REG_RR0_STATUS: data = do_sioreg_rr0(); break; case REG_RR1_SPEC_RCV_COND: data = do_sioreg_rr1(); break; case REG_RR2_INTERRUPT_VECT: data = do_sioreg_rr2(); break; default: @@ -974,23 +1406,25 @@ uint8_t z80sio_channel::control_read() Handle the WR0 CRC Reset/Init bits separatelly, needed by derived devices separatelly from the commands */ void z80sio_channel::do_sioreg_wr0_resets(uint8_t data) { - LOG("%s %s\n",FUNCNAME, tag()); + LOG("%s\n", FUNCNAME); switch (data & WR0_CRC_RESET_CODE_MASK) { case WR0_CRC_RESET_NULL: - LOG("Z80SIO \"%s\" Channel %c : CRC_RESET_NULL\n", owner()->tag(), 'A' + m_index); + LOGCMD("Z80SIO Channel %c : CRC_RESET_NULL\n", 'A' + m_index); break; case WR0_CRC_RESET_RX: /* In Synchronous mode: all Os (zeros) (CCITT-O CRC-16) */ - LOG("Z80SIO \"%s\" Channel %c : CRC_RESET_RX - not implemented\n", owner()->tag(), 'A' + m_index); + LOGCMD("Z80SIO Channel %c : CRC_RESET_RX - not implemented\n", 'A' + m_index); break; case WR0_CRC_RESET_TX: /* In HDLC mode: all 1s (ones) (CCITT-1) */ - LOG("Z80SIO \"%s\" Channel %c : CRC_RESET_TX - not implemented\n", owner()->tag(), 'A' + m_index); + LOGCMD("Z80SIO Channel %c : CRC_RESET_TX\n", 'A' + m_index); + m_tx_crc = ((m_wr4 & WR4_SYNC_MODE_MASK) == WR4_SYNC_MODE_SDLC) ? ~uint16_t(0U) : uint16_t(0U); break; case WR0_CRC_RESET_TX_UNDERRUN: /* Resets Tx underrun/EOM bit (D6 of the SRO register) */ - LOG("Z80SIO \"%s\" Channel %c : CRC_RESET_TX_UNDERRUN - not implemented\n", owner()->tag(), 'A' + m_index); + LOGCMD("Z80SIO Channel %c : CRC_RESET_TX_UNDERRUN\n", 'A' + m_index); + m_rr0 &= ~RR0_TX_UNDERRUN; break; default: /* Will not happen unless someone messes with the mask */ - logerror("Z80SIO \"%s\" Channel %c : %s Wrong CRC reset/init command:%02x\n", owner()->tag(), 'A' + m_index, FUNCNAME, data & WR0_CRC_RESET_CODE_MASK); + logerror("Z80SIO Channel %c : %s Wrong CRC reset/init command:%02x\n", 'A' + m_index, FUNCNAME, data & WR0_CRC_RESET_CODE_MASK); } } @@ -1003,81 +1437,60 @@ void z80sio_channel::do_sioreg_wr0(uint8_t data) switch (data & WR0_COMMAND_MASK) { case WR0_NULL: - LOGCMD("%s %s Ch:%c : Null command\n", FUNCNAME, tag(), 'A' + m_index); + LOGCMD("%s Ch:%c : Null command\n", FUNCNAME, 'A' + m_index); break; case WR0_SEND_ABORT: - LOGCMD("%s %s Ch:%c : Send abort command - not implemented\n", FUNCNAME, tag(), 'A' + m_index); + LOGCMD("%s Ch:%c : Send abort command\n", FUNCNAME, 'A' + m_index); + // TODO: what actually happens if you try this in a mode other than SDLC? + // FIXME: how does this interact with interrupts? + // For now assume it behaves like automatically sending CRC and generates a transmit interrupt when a new frame can be sent. + tx_setup(0xff, 8, 0, true, true); + m_rr0 |= RR0_TX_BUFFER_EMPTY; + m_rr1 &= ~RR1_ALL_SENT; + if ((m_wr1 & WR1_WRDY_ENABLE) && !(m_wr1 & WR1_WRDY_ON_RX_TX)) + set_ready(false); break; case WR0_RESET_EXT_STATUS: - // reset external/status interrupt - - m_rr0 &= ~(RR0_DCD | RR0_SYNC_HUNT | RR0_CTS | RR0_BREAK_ABORT); - // release the latch - - m_rx_rr0_latch = 0; - // update register to reflect wire values TODO: Check if this will fire new interrupts - if (!m_dcd) m_rr0 |= RR0_DCD; - if (m_sync) m_rr0 |= RR0_SYNC_HUNT; - if (m_cts) m_rr0 |= RR0_CTS; - - // Clear any pending External interrupt - m_uart->m_int_state[m_index == z80sio_device::CHANNEL_A ? 4 : 5] = 0; - - LOGINT("%s %s Ch:%c : Reset External/Status Interrupt\n", FUNCNAME, tag(), 'A' + m_index); + reset_ext_status(); + LOGINT("%s Ch:%c : Reset External/Status Interrupt\n", FUNCNAME, 'A' + m_index); break; case WR0_CHANNEL_RESET: // channel reset - LOGCMD("%s %s Ch:%c : Channel Reset\n", FUNCNAME, tag(), 'A' + m_index); + LOGCMD("%s Ch:%c : Channel Reset\n", FUNCNAME, 'A' + m_index); device_reset(); break; case WR0_ENABLE_INT_NEXT_RX: // enable interrupt on next receive character - LOGINT("%s %s Ch:%c : Enable Interrupt on Next Received Character\n", FUNCNAME, tag(), 'A' + m_index); + LOGINT("%s Ch:%c : Enable Interrupt on Next Received Character\n", FUNCNAME, 'A' + m_index); m_rx_first = 1; break; case WR0_RESET_TX_INT: + LOGCMD("%s Ch:%c : Reset Transmitter Interrupt Pending\n", FUNCNAME, 'A' + m_index); // reset transmitter interrupt pending - { - uint8_t priority = 3; // Assume TxB - // Check if it is TxA - if (m_index == z80sio_device::CHANNEL_A) - { - // Check if priority bit is cleared - priority = (m_uart->m_chanA->m_wr2 & z80sio_channel::WR2_PRIORITY) == 0 ? 1 : 2; - } - m_uart->m_int_state[priority] = 0; - LOGINT("%s %s Ch:%c : Reset TX Interrupt, priority:%d\n", FUNCNAME, tag(), 'A' + m_index, priority); - } - m_uart->check_interrupts(); - LOGCMD("%s %s Ch:%c : Reset Transmitter Interrupt Pending\n", FUNCNAME, tag(), 'A' + m_index); + m_uart->clear_interrupt(m_index, INT_TRANSMIT); break; case WR0_ERROR_RESET: // error reset - LOGCMD("%s %s Ch:%c : Error Reset\n", FUNCNAME, tag(), 'A' + m_index); - m_rr1 &= ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR); - break; - case WR0_RETURN_FROM_INT: - LOGINT("%s %s Ch:%c : Return from interrupt\n", FUNCNAME, tag(), 'A' + m_index); + LOGCMD("%s Ch:%c : Error Reset\n", FUNCNAME, 'A' + m_index); + if ((WR1_RX_INT_FIRST == (m_wr1 & WR1_RX_INT_MODE_MASK)) && (m_rr1 & (RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR))) { - int found = 0; - // loop over all interrupt sources - for (auto & elem : m_uart->m_int_state) - { - // find the first channel with an interrupt requested - if (elem & (Z80_DAISY_IEO)) - { - // clear the IEO state and update the IRQs - elem &= ~(Z80_DAISY_IEO); - m_uart->check_interrupts(); - found = 1; - break; - } - } - LOGINT(" - %s\n", found == 0 ? "failed to find an interrupt to clear IEO on!" : "cleared IEO"); + // clearing framing and overrun errors advances the FIFO + // TODO: Intel 8274 manual doesn't mention this behaviour - is it specific to Z80 SIO? + m_rr1 &= ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR); + advance_rx_fifo(); + } + else + { + m_rr1 &= ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR); } break; + case WR0_RETURN_FROM_INT: + LOGINT("%s Ch:%c : Return from interrupt\n", FUNCNAME, 'A' + m_index); + if (m_index == z80sio_device::CHANNEL_A) + m_uart->return_from_interrupt(); + break; default: - LOG("Z80SIO \"%s\" Channel %c : Unsupported WR0 command %02x mask %02x\n", owner()->tag(), 'A' + m_index, data, WR0_REGISTER_MASK); + LOG("Z80SIO Channel %c : Unsupported WR0 command %02x mask %02x\n", 'A' + m_index, data, WR0_REGISTER_MASK); } do_sioreg_wr0_resets(data); @@ -1112,6 +1525,13 @@ void z80sio_channel::do_sioreg_wr1(uint8_t data) LOG("Z80SIO \"%s\" Channel %c : Receiver Interrupt on All Characters\n", owner()->tag(), 'A' + m_index); break; } + + if (!(data & WR1_WRDY_ENABLE)) + set_ready(false); + else if (data & WR1_WRDY_ON_RX_TX) + set_ready(bool(m_rr0 & RR0_RX_CHAR_AVAILABLE)); + else + set_ready((m_rr0 & RR0_TX_BUFFER_EMPTY) && !(m_tx_flags & TX_FLAG_SPECIAL)); } void z80sio_channel::do_sioreg_wr2(uint8_t data) @@ -1122,10 +1542,35 @@ void z80sio_channel::do_sioreg_wr2(uint8_t data) void z80sio_channel::do_sioreg_wr3(uint8_t data) { + LOGSETUP("Z80SIO Channel %c : Receiver Enable %u\n", 'A' + m_index, (data & WR3_RX_ENABLE) ? 1 : 0); + LOGSETUP("Z80SIO Channel %c : Sync Character Load Inhibit %u\n", 'A' + m_index, (data & WR3_SYNC_CHAR_LOAD_INHIBIT) ? 1 : 0); + LOGSETUP("Z80SIO Channel %c : Receive CRC Enable %u\n", 'A' + m_index, (data & WR3_RX_CRC_ENABLE) ? 1 : 0); + LOGSETUP("Z80SIO Channel %c : Auto Enables %u\n", 'A' + m_index, (data & WR3_AUTO_ENABLES) ? 1 : 0); + LOGSETUP("Z80SIO Channel %c : Receiver Bits/Character %u\n", 'A' + m_index, get_rx_word_length()); + if (data & WR3_ENTER_HUNT_PHASE) + LOGCMD("Z80SIO Channel %c : Enter Hunt Phase\n", 'A' + m_index); + + bool const was_allowed(receive_allowed()); m_wr3 = data; - LOG("Z80SIO \"%s\" Channel %c : Receiver Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR3_RX_ENABLE) ? 1 : 0); - LOG("Z80SIO \"%s\" Channel %c : Auto Enables %u\n", owner()->tag(), 'A' + m_index, (data & WR3_AUTO_ENABLES) ? 1 : 0); - LOG("Z80SIO \"%s\" Channel %c : Receiver Bits/Character %u\n", owner()->tag(), 'A' + m_index, get_rx_word_length()); + + if (!was_allowed && receive_allowed()) + { + receive_enabled(); + } + else if ((data & WR3_ENTER_HUNT_PHASE) && ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC)) + { + // TODO: should this re-initialise hunt logic if already in hunt phase for 8-bit/16-bit/SDLC sync? + if ((m_wr4 & WR4_SYNC_MODE_MASK) == WR4_SYNC_MODE_EXT) + { + m_rx_bit = 0; + } + else if (!(m_rr0 & RR0_SYNC_HUNT)) + { + m_rx_bit = 0; + m_rr0 |= RR0_SYNC_HUNT; + trigger_ext_int(); + } + } } void z80sio_channel::do_sioreg_wr4(uint8_t data) @@ -1133,30 +1578,38 @@ void z80sio_channel::do_sioreg_wr4(uint8_t data) m_wr4 = data; LOG("Z80SIO \"%s\" Channel %c : Parity Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR4_PARITY_ENABLE) ? 1 : 0); LOG("Z80SIO \"%s\" Channel %c : Parity %s\n", owner()->tag(), 'A' + m_index, (data & WR4_PARITY_EVEN) ? "Even" : "Odd"); - LOG("Z80SIO \"%s\" Channel %c : Stop Bits %s\n", owner()->tag(), 'A' + m_index, stop_bits_tostring(get_stop_bits())); + if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC) + LOG("Z80SIO \"%s\" Channel %c : Synchronous Mode\n", owner()->tag(), 'A' + m_index); + else + LOG("Z80SIO \"%s\" Channel %c : Stop Bits %g\n", owner()->tag(), 'A' + m_index, (((m_wr4 & WR4_STOP_BITS_MASK) >> 2) + 1) / 2.); LOG("Z80SIO \"%s\" Channel %c : Clock Mode %uX\n", owner()->tag(), 'A' + m_index, get_clock_mode()); } void z80sio_channel::do_sioreg_wr5(uint8_t data) { m_wr5 = data; - LOG("Z80SIO \"%s\" Channel %c : Transmitter Enable %u\n", owner()->tag(), 'A' + m_index, (data & WR5_TX_ENABLE) ? 1 : 0); - LOG("Z80SIO \"%s\" Channel %c : Transmitter Bits/Character %u\n", owner()->tag(), 'A' + m_index, get_tx_word_length()); - LOG("Z80SIO \"%s\" Channel %c : Send Break %u\n", owner()->tag(), 'A' + m_index, (data & WR5_SEND_BREAK) ? 1 : 0); - LOG("Z80SIO \"%s\" Channel %c : Request to Send %u\n", owner()->tag(), 'A' + m_index, (data & WR5_RTS) ? 1 : 0); - LOG("Z80SIO \"%s\" Channel %c : Data Terminal Ready %u\n", owner()->tag(), 'A' + m_index, (data & WR5_DTR) ? 1 : 0); + LOG("Z80SIO Channel %c : Transmitter Enable %u\n", 'A' + m_index, (data & WR5_TX_ENABLE) ? 1 : 0); + LOG("Z80SIO Channel %c : Transmitter Bits/Character %u\n", 'A' + m_index, get_tx_word_length()); + LOG("Z80SIO Channel %c : Transmit CRC Enable %u\n", 'A' + m_index, (data & WR5_TX_CRC_ENABLE) ? 1 : 0); + LOG("Z80SIO Channel %c : %s Frame Check Polynomial\n", 'A' + m_index, (data & WR5_CRC16) ? "CRC-16" : "SDLC"); + LOG("Z80SIO Channel %c : Send Break %u\n", 'A' + m_index, (data & WR5_SEND_BREAK) ? 1 : 0); + LOG("Z80SIO Channel %c : Request to Send %u\n", 'A' + m_index, (data & WR5_RTS) ? 1 : 0); + LOG("Z80SIO Channel %c : Data Terminal Ready %u\n", 'A' + m_index, (data & WR5_DTR) ? 1 : 0); + + if (~data & WR5_TX_ENABLE) + m_uart->clear_interrupt(m_index, INT_TRANSMIT); } void z80sio_channel::do_sioreg_wr6(uint8_t data) { - LOG("Z80SIO \"%s\" Channel %c : Transmit Sync %02x\n", owner()->tag(), 'A' + m_index, data); - m_sync = (m_sync & 0xff00) | data; + LOG("Z80SIO \"%s\" Channel %c : Transmit Sync/Sync 1/SDLC Address %02x\n", owner()->tag(), 'A' + m_index, data); + m_wr6 = data; } void z80sio_channel::do_sioreg_wr7(uint8_t data) { - LOG("Z80SIO \"%s\" Channel %c : Receive Sync %02x\n", owner()->tag(), 'A' + m_index, data); - m_sync = (data << 8) | (m_sync & 0xff); + LOG("Z80SIO \"%s\" Channel %c : Receive Sync/Sync 2/SDLC Flag %02x\n", owner()->tag(), 'A' + m_index, data); + m_wr7 = data; } //------------------------------------------------- @@ -1174,16 +1627,16 @@ void z80sio_channel::control_write(uint8_t data) m_wr0 &= ~WR0_REGISTER_MASK; } - LOG("\n%s(%02x) reg %02x\n", FUNCNAME, data, reg); + LOG("%s(%02x) reg %02x\n", FUNCNAME, data, reg); switch (reg) { case REG_WR0_COMMAND_REGPT: do_sioreg_wr0(data); break; case REG_WR1_INT_DMA_ENABLE: do_sioreg_wr1(data); m_uart->check_interrupts(); break; case REG_WR2_INT_VECTOR: do_sioreg_wr2(data); break; - case REG_WR3_RX_CONTROL: do_sioreg_wr3(data); update_serial(); break; - case REG_WR4_RX_TX_MODES: do_sioreg_wr4(data); update_serial(); break; - case REG_WR5_TX_CONTROL: do_sioreg_wr5(data); update_serial(); update_rts(); break; + case REG_WR3_RX_CONTROL: do_sioreg_wr3(data); break; + case REG_WR4_RX_TX_MODES: do_sioreg_wr4(data); update_dtr_rts_break(); break; + case REG_WR5_TX_CONTROL: do_sioreg_wr5(data); update_dtr_rts_break(); transmit_enable(); break; case REG_WR6_SYNC_OR_SDLC_A: do_sioreg_wr6(data); break; case REG_WR7_SYNC_OR_SDLC_F: do_sioreg_wr7(data); break; default: @@ -1197,25 +1650,18 @@ void z80sio_channel::control_write(uint8_t data) //------------------------------------------------- uint8_t z80sio_channel::data_read() { - uint8_t data = 0; + uint8_t const data = uint8_t(m_rx_data_fifo & 0x000000ffU); - if (!m_rx_data_fifo.empty()) + if (!machine().side_effect_disabled()) { - // load data from the FIFO - data = m_rx_data_fifo.dequeue(); + // framing and overrun errors need to be cleared to advance the FIFO in interrupt-on-first mode + // TODO: Intel 8274 manual doesn't mention this behaviour - is it specific to Z80 SIO? + if ((WR1_RX_INT_FIRST != (m_wr1 & WR1_RX_INT_MODE_MASK)) || !(m_rr1 & (RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR))) + advance_rx_fifo(); - // load error status from the FIFO - m_rr1 = (m_rr1 & ~(RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR | RR1_PARITY_ERROR)) | m_rx_error_fifo.dequeue(); - - if (m_rx_data_fifo.empty()) - { - // no more characters available in the FIFO - m_rr0 &= ~ RR0_RX_CHAR_AVAILABLE; - } + LOG("Z80SIO \"%s\" Channel %c : Data Register Read '%02x'\n", owner()->tag(), 'A' + m_index, data); } - LOG("Z80SIO \"%s\" Channel %c : Data Register Read '%02x'\n", owner()->tag(), 'A' + m_index, data); - return data; } @@ -1225,85 +1671,218 @@ uint8_t z80sio_channel::data_read() //------------------------------------------------- void z80sio_channel::data_write(uint8_t data) { + if (!(m_rr0 & RR0_TX_BUFFER_EMPTY)) + LOGTX("Z80SIO \"%s\" Channel %c : Dropped Data Byte '%02x'\n", owner()->tag(), 'A' + m_index, m_tx_data); + LOGTX("Z80SIO Channel %c : Queue Data Byte '%02x'\n", 'A' + m_index, data); + + // fill transmit buffer m_tx_data = data; + m_rr0 &= ~RR0_TX_BUFFER_EMPTY; + m_rr1 &= ~RR1_ALL_SENT; + if ((m_wr1 & WR1_WRDY_ENABLE) && !(m_wr1 & WR1_WRDY_ON_RX_TX)) + set_ready(false); + + // handle automatic RTS + bool const async((m_wr4 & WR4_STOP_BITS_MASK) != WR4_STOP_BITS_SYNC); + if (async && !(m_wr5 & WR5_RTS)) + set_rts(0); // TODO: if transmission is disabled when the data buffer is full, is this still asserted? + + // clear transmit interrupt + m_uart->clear_interrupt(m_index, INT_TRANSMIT); + + // may be possible to transmit immediately (synchronous mode will load when sync pattern completes) + if (async && !m_tx_bits && transmit_allowed()) + async_tx_setup(); +} + - if ((m_wr5 & WR5_TX_ENABLE) && is_transmit_register_empty()) +//------------------------------------------------- +// advance_rx_fifo - move to next received byte +//------------------------------------------------- +void z80sio_channel::advance_rx_fifo() +{ + if (m_rx_fifo_depth) { - LOGTX("Z80SIO \"%s\" Channel %c : Transmit Data Byte '%02x'\n", owner()->tag(), 'A' + m_index, m_tx_data); + if (--m_rx_fifo_depth) + { + // shift the FIFO + m_rx_data_fifo >>= 8; + m_rx_error_fifo >>= 8; - transmit_register_setup(m_tx_data); + // load error status from the FIFO + m_rr1 = (m_rr1 & ~m_rr1_auto_reset) | uint8_t(m_rx_error_fifo & 0x000000ffU); - // empty transmit buffer - m_rr0 |= RR0_TX_BUFFER_EMPTY; + // if we're in interrupt-on-first mode, clear interrupt if there's no pending error condition + if ((m_wr1 & WR1_RX_INT_MODE_MASK) == WR1_RX_INT_FIRST) + { + for (int i = 0; m_rx_fifo_depth > i; ++i) + { + if (uint8_t(m_rx_error_fifo >> (i * 8)) & (RR1_CRC_FRAMING_ERROR | RR1_RX_OVERRUN_ERROR)) + return; + } + m_uart->clear_interrupt(m_index, INT_RECEIVE); + } + } + else + { + // no more characters available in the FIFO + m_rr0 &= ~RR0_RX_CHAR_AVAILABLE; + if ((m_wr1 & WR1_WRDY_ENABLE) && (m_wr1 & WR1_WRDY_ON_RX_TX)) + set_ready(false); + m_uart->clear_interrupt(m_index, INT_RECEIVE); + } + } +} - if (m_wr1 & WR1_TX_INT_ENABLE) - m_uart->trigger_interrupt(m_index, INT_TRANSMIT); + +//------------------------------------------------- +// receive_enabled - conditions have changed +// allowing reception to begin +//------------------------------------------------- + +void z80sio_channel::receive_enabled() +{ + bool const sync_mode((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC); + m_rx_count = sync_mode ? 0 : ((get_clock_mode() - 1) / 2); + m_rx_bit = 0; + if (sync_mode && ((m_wr4 & WR4_SYNC_MODE_MASK) != WR4_SYNC_MODE_EXT)) + m_rr0 |= RR0_SYNC_HUNT; +} + + +//------------------------------------------------- +// sync_receive - synchronous reception handler +//------------------------------------------------- + +void z80sio_channel::sync_receive() +{ + // TODO: this is a fundamentally flawed approach - it's just the quickest way to get uts20 to pass some tests + // Sync acquisition works, but sync load suppression doesn't work right. + // Assembled data needs to be separated from the receive shift register for SDLC. + // Supporting receive checksum for modes other than SDLC is going to be very complicated due to all the bit delays involved. + + bool const ext_sync((m_wr4 & WR4_SYNC_MODE_MASK) == WR4_SYNC_MODE_EXT); + bool const hunt_phase(ext_sync ? m_sync : (m_rr0 & RR0_SYNC_HUNT)); + if (hunt_phase) + { + // check for sync detection + bool acquired(false); + int limit(16); + switch (m_wr4 & WR4_SYNC_MODE_MASK) + { + case WR4_SYNC_MODE_8_BIT: + case WR4_SYNC_MODE_SDLC: + acquired = (m_rx_bit >= 8) && ((m_rx_sr & 0xff00U) == (uint16_t(m_wr7) << 8)); + limit = 8; + break; + case WR4_SYNC_MODE_16_BIT: + acquired = (m_rx_bit >= 16) && (m_rx_sr == ((uint16_t(m_wr7) << 8) | uint16_t(m_wr6))); + break; + } + if (acquired) + { + // TODO: make this do something sensible in SDLC mode + // FIXME: set sync output for one receive bit cycle + // FIXME: what if sync load isn't suppressed? + LOGRCV("%s() Channel %c Character Sync Acquired\n", FUNCNAME, 'A' + m_index); + m_rr0 &= ~RR0_SYNC_HUNT; + m_rx_bit = 0; + trigger_ext_int(); + } + else + { + // track number of bits we have + m_rx_bit = (std::min)(m_rx_bit + 1, limit); + } } else { - LOGTX(" Transmitter %s, data byte dropped\n", m_wr5 & WR5_TX_ENABLE ? "not enabled" : "not emptied"); - m_rr0 &= ~RR0_TX_BUFFER_EMPTY; + // FIXME: SDLC needs to monitor for flag/abort + // FIXME: what if sync load is suppressed? + // FIXME: what about receive checksum and the nasty internal shift register delays? + int const word_length(get_rx_word_length() + ((m_wr4 & WR4_PARITY_ENABLE) ? 1 : 0)); + if (++m_rx_bit == word_length) + { + uint16_t const data((m_rx_sr >> (16 - word_length)) | (~uint16_t(0) << word_length)); + m_rx_bit = 0; + LOGRCV("%s() Channel %c Received Data %02x\n", FUNCNAME, 'A' + m_index, data & 0xff); + queue_received(data, 0U); + } } - m_rr1 &= ~RR1_ALL_SENT; + LOGBIT("%s() Channel %c Read Bit %d\n", FUNCNAME, 'A' + m_index, m_rxd); + m_rx_sr = (m_rx_sr >> 1) | (m_rxd ? 0x8000U : 0x0000U); } - //------------------------------------------------- // receive_data - receive data word //------------------------------------------------- -void z80sio_channel::receive_data(uint8_t data) + +void z80sio_channel::receive_data() { - LOGRCV("%s(%02x) %s:%c\n",FUNCNAME, data, tag(), 'A' + m_index); +} + +//------------------------------------------------- +// queue_recevied - queue recevied character +//------------------------------------------------- - if (m_rx_data_fifo.full()) +void z80sio_channel::queue_received(uint16_t data, uint32_t error) +{ + if (m_wr4 & WR4_PARITY_ENABLE) { - LOG(" Overrun detected\n"); - // receive overrun error detected - m_rx_error |= RR1_RX_OVERRUN_ERROR; + int const word_length = get_rx_word_length(); + uint16_t par(data); + for (int i = 1; word_length >= i; ++i) + par ^= BIT(par, i); - switch (m_wr1 & WR1_RX_INT_MODE_MASK) + if (bool(BIT(par, 0)) == bool(m_wr4 & WR4_PARITY_EVEN)) { - case WR1_RX_INT_FIRST: - if (!m_rx_first) - { - m_uart->trigger_interrupt(m_index, INT_SPECIAL); - } - break; - - case WR1_RX_INT_ALL_PARITY: - case WR1_RX_INT_ALL: - m_uart->trigger_interrupt(m_index, INT_SPECIAL); - break; + LOGRCV(" Parity error detected\n"); + error |= RR1_PARITY_ERROR; } } + + if (3 == m_rx_fifo_depth) + { + LOG(" Receive FIFO overrun detected\n"); + // receive overrun error detected + error |= RR1_RX_OVERRUN_ERROR; + + m_rx_data_fifo = (m_rx_data_fifo & 0x0000ffffU) | (uint32_t(data & 0x00ffU) << 16); + m_rx_error_fifo = (m_rx_error_fifo & 0x0000ffffU) | (error << 16); + } else { // store received character and error status into FIFO - m_rx_data_fifo.enqueue(data); - m_rx_error_fifo.enqueue(m_rx_error); + if (!m_rx_fifo_depth) + m_rx_data_fifo = m_rx_error_fifo = 0U; + m_rx_data_fifo |= uint32_t(data & 0x00ffU) << (8 * m_rx_fifo_depth); + m_rx_error_fifo |= error << (8 * m_rx_fifo_depth); + if (!m_rx_fifo_depth) + m_rr1 |= uint8_t(error); + ++m_rx_fifo_depth; } m_rr0 |= RR0_RX_CHAR_AVAILABLE; + if ((m_wr1 & WR1_WRDY_ENABLE) && (m_wr1 & WR1_WRDY_ON_RX_TX)) + set_ready(true); // receive interrupt switch (m_wr1 & WR1_RX_INT_MODE_MASK) { case WR1_RX_INT_FIRST: - if (m_rx_first) - { + if (m_rx_first || (error & (RR1_RX_OVERRUN_ERROR | RR1_CRC_FRAMING_ERROR))) m_uart->trigger_interrupt(m_index, INT_RECEIVE); - m_rx_first = 0; - } + m_rx_first = 0; break; case WR1_RX_INT_ALL_PARITY: case WR1_RX_INT_ALL: m_uart->trigger_interrupt(m_index, INT_RECEIVE); break; - default: - LOG("No interrupt triggered\n"); + default: + LOG("No receive interrupt triggered\n"); } } @@ -1313,35 +1892,16 @@ void z80sio_channel::receive_data(uint8_t data) //------------------------------------------------- WRITE_LINE_MEMBER( z80sio_channel::cts_w ) { - LOG("%s(%02x) %s:%c\n",FUNCNAME, state, tag(), 'A' + m_index); - - if (m_cts != state) + if (bool(m_cts) != bool(state)) { - // enable transmitter if in auto enables mode - if (!state) - if (m_wr3 & WR3_AUTO_ENABLES) - m_wr5 |= WR5_TX_ENABLE; + LOGCTS("Z80SIO Channel %c : CTS %u\n", 'A' + m_index, state); - // set clear to send m_cts = state; + trigger_ext_int(); - if (!m_rx_rr0_latch) - { - if (!m_cts) - m_rr0 |= RR0_CTS; - else - m_rr0 &= ~RR0_CTS; - - // trigger interrupt - if (m_wr1 & WR1_EXT_INT_ENABLE) - { - // trigger interrupt - m_uart->trigger_interrupt(m_index, INT_EXTERNAL); - - // latch read register 0 - m_rx_rr0_latch = 1; - } - } + // this may enable transmission + if (!state) + transmit_enable(); } } @@ -1351,34 +1911,17 @@ WRITE_LINE_MEMBER( z80sio_channel::cts_w ) //------------------------------------------------- WRITE_LINE_MEMBER( z80sio_channel::dcd_w ) { - LOG("Z80SIO \"%s\" Channel %c : DCD %u\n", owner()->tag(), 'A' + m_index, state); - - if (m_dcd != state) + if (bool(m_dcd) != bool(state)) { - // enable receiver if in auto enables mode - if (!state) - if (m_wr3 & WR3_AUTO_ENABLES) - m_wr3 |= WR3_RX_ENABLE; + LOG("Z80SIO Channel %c : DCD %u\n", 'A' + m_index, state); - // set data carrier detect + bool const was_allowed(receive_allowed()); m_dcd = state; + trigger_ext_int(); - if (!m_rx_rr0_latch) - { - if (!m_dcd) - m_rr0 |= RR0_DCD; - else - m_rr0 &= ~RR0_DCD; - - if (m_wr1 & WR1_EXT_INT_ENABLE) - { - // trigger interrupt - m_uart->trigger_interrupt(m_index, INT_EXTERNAL); - - // latch read register 0 - m_rx_rr0_latch = 1; - } - } + // in auto-enable mode, this can start the receiver + if (!was_allowed && receive_allowed()) + receive_enabled(); } } @@ -1388,29 +1931,15 @@ WRITE_LINE_MEMBER( z80sio_channel::dcd_w ) //------------------------------------------------- WRITE_LINE_MEMBER( z80sio_channel::sync_w ) { - LOG("Z80SIO \"%s\" Channel %c : Sync %u\n", owner()->tag(), 'A' + m_index, state); - - if (m_sh != state) + if (bool(m_sync) != bool(state)) { - // set ring indicator state - m_sh = state; + LOG("Z80SIO Channel %c : Sync %u\n", 'A' + m_index, state); - if (!m_rx_rr0_latch) - { - if (m_sh) - m_rr0 |= RR0_SYNC_HUNT; - else - m_rr0 &= ~RR0_SYNC_HUNT; - - if (m_wr1 & WR1_EXT_INT_ENABLE) - { - // trigger interrupt - m_uart->trigger_interrupt(m_index, INT_EXTERNAL); + m_sync = state; - // latch read register 0 - m_rx_rr0_latch = 1; - } - } + // sync is a general-purpose input in asynchronous mode + if ((m_wr4 & WR4_STOP_BITS_MASK) != WR4_STOP_BITS_SYNC) + trigger_ext_int(); } } @@ -1421,18 +1950,100 @@ WRITE_LINE_MEMBER( z80sio_channel::sync_w ) WRITE_LINE_MEMBER( z80sio_channel::rxc_w ) { //LOG("Z80SIO \"%s\" Channel %c : Receiver Clock Pulse\n", owner()->tag(), m_index + 'A'); - int clocks = get_clock_mode(); - if (clocks == 1) - rx_clock_w(state); - else if(state) + if (receive_allowed() && state && !m_rx_clock) { - rx_clock_w(m_rx_clock < clocks/2); + // RxD sampled on rising edge + int const clocks = get_clock_mode() - 1; + + // break termination detection + // TODO: how does this interact with receiver being disable or synchronous modes? + if (m_rxd && !m_brk_latched && (m_rr0 & RR0_BREAK_ABORT)) + { + LOGRCV("Break termination detected\n"); + m_rr0 &= ~RR0_BREAK_ABORT; + m_brk_latched = 1; + trigger_ext_int(); + } + + if ((m_wr4 & WR4_STOP_BITS_MASK) == WR4_STOP_BITS_SYNC) + { + // synchronous receive is a different beast + if (!m_rx_count) + { + sync_receive(); + m_rx_count = clocks; + } + else + { + --m_rx_count; + } + } + else if (!m_rx_bit) + { + // look for start bit + if (m_rxd) + { + // line idle + m_rx_count = (std::max)(m_rx_count, (clocks / 2) + 1) - 1; + } + else if (!m_rx_count) + { + // half a bit period expired, start shifting bits + m_rx_count = clocks; + ++m_rx_bit; + m_rx_sr = ~uint16_t(0U); + } + else + { + // ensure start bit lasts long enough + --m_rx_count; + } + } + else if (!m_rx_count) + { + // sample a data/parity/stop bit + if (!m_rxd) + m_rx_sr &= ~uint16_t(1U << (m_rx_bit - 1)); + int const word_length(get_rx_word_length() + ((m_wr4 & WR4_PARITY_ENABLE) ? 1 : 0)); + bool const stop_reached((word_length + 1) == m_rx_bit); + LOGBIT("%s() Channel %c Received %s Bit %d\n", FUNCNAME, 'A' + m_index, stop_reached ? "Stop" : "Data", m_rxd); + + if (stop_reached) + { + // this is the stop bit - framing error adds a half bit period + m_rx_count = m_rxd ? (clocks / 2) : clocks; + m_rx_bit = 0; - m_rx_clock++; - if (m_rx_clock == clocks) - m_rx_clock = 0; + LOGRCV("%s() Channel %c Received Data %02x\n", FUNCNAME, 'A' + m_index, m_rx_sr & 0xff); + // check framing errors and break condition + uint16_t const stop_bit = uint16_t(1U) << word_length; + bool const brk(!(m_rx_sr & ((stop_bit << 1) - 1))); + queue_received(m_rx_sr | stop_bit, (m_rx_sr & stop_bit) ? 0U : RR1_CRC_FRAMING_ERROR); + + // break interrupt + if (brk && !m_brk_latched && !(m_rr0 & RR0_BREAK_ABORT)) + { + LOGRCV("Break detected\n"); + m_rr0 |= RR0_BREAK_ABORT; + m_brk_latched = 1; + trigger_ext_int(); + } + } + else + { + // wait a whole bit period for the next bit + m_rx_count = clocks; + ++m_rx_bit; + } + } + else + { + // bit period hasn't expired + --m_rx_count; + } } + m_rx_clock = state; } @@ -1442,83 +2053,91 @@ WRITE_LINE_MEMBER( z80sio_channel::rxc_w ) WRITE_LINE_MEMBER( z80sio_channel::txc_w ) { //LOG("Z80SIO \"%s\" Channel %c : Transmitter Clock Pulse\n", owner()->tag(), m_index + 'A'); - int clocks = get_clock_mode(); - if (clocks == 1) - tx_clock_w(state); - else if(state) + if (!state && m_tx_clock) { - tx_clock_w(m_tx_clock < clocks/2); - - m_tx_clock++; - if (m_tx_clock == clocks) - m_tx_clock = 0; - - } -} - - -//------------------------------------------------- -// update_serial - -//------------------------------------------------- -void z80sio_channel::update_serial() -{ - int data_bit_count = get_rx_word_length(); - stop_bits_t stop_bits = get_stop_bits(); - parity_t parity; + // falling edge active + if (m_tx_count) + { + // divide transmit clock + --m_tx_count; + } + else if (!m_tx_bits) + { + // idle marking line + if (!m_txd) + { + m_txd = 1; + if (!(m_wr5 & WR5_SEND_BREAK)) + out_txd_cb(1); + } - LOG("%s\n", FUNCNAME); + if (((m_wr4 & WR4_STOP_BITS_MASK) != WR4_STOP_BITS_SYNC) && (m_rr0 & RR0_TX_BUFFER_EMPTY)) + { + // when the RTS bit is reset in asynchronous mode, the _RTS output goes high after the transmitter empties + if (!(m_wr5 & WR5_RTS) && !m_rts) + set_rts(1); // TODO: if transmission is disabled when the data buffer is full, is this still asserted? - if (m_wr4 & WR4_PARITY_ENABLE) - { - LOG("- Parity enabled\n"); - if (m_wr4 & WR4_PARITY_EVEN) - parity = PARITY_EVEN; + // if transmit buffer is empty in asynchronous mode then all characters have been sent + m_rr1 |= RR1_ALL_SENT; + } + } else - parity = PARITY_ODD; - } - else - parity = PARITY_NONE; - - set_data_frame(1, data_bit_count, parity, stop_bits); + { + bool const sdlc_mode((m_wr4 & (WR4_STOP_BITS_MASK | WR4_SYNC_MODE_MASK)) == (WR4_STOP_BITS_SYNC | WR4_SYNC_MODE_SDLC)); + bool const framing(m_tx_flags & TX_FLAG_FRAMING); + bool const stuff_zero(sdlc_mode && !framing && ((m_tx_hist & 0x1fU) == 0x1fU)); - int clocks = get_clock_mode(); + // have bits, shift out + int const db(stuff_zero ? 0 : BIT(m_tx_sr, 0)); + if (!stuff_zero) + { + LOGBIT("%s() Channel %c transmit %s bit %d m_wr5:%02x\n", FUNCNAME, 'A' + m_index, framing ? "framing" : "data", db, m_wr5); + if (m_tx_parity >= m_tx_bits) + m_tx_parity = 0; + else if (m_tx_parity) + m_tx_sr ^= uint16_t(db) << (m_tx_bits - m_tx_parity); + m_tx_sr >>= 1; + + if (m_tx_flags & TX_FLAG_CRC) + { + uint16_t const poly((m_wr5 & WR5_CRC16) ? 0x8005U : device_sdlc_consumer_interface::POLY_SDLC); + m_tx_crc = device_sdlc_consumer_interface::update_frame_check(poly, m_tx_crc, db); + } + } + else + { + LOGBIT("%s() Channel %c stuff bit %d m_wr5:%02x\n", FUNCNAME, 'A' + m_index, db, m_wr5); + } + m_tx_hist = (m_tx_hist << 1) | db; - if (m_rxc > 0) - { - LOG("- RxC:%d/%d = %d\n", m_rxc, clocks, m_rxc / clocks); - set_rcv_rate(m_rxc / clocks); - } + // update output line state + if (bool(m_txd) != bool(db)) + { + m_txd = db; + if (!(m_wr5 & WR5_SEND_BREAK)) + out_txd_cb(m_txd); + } - if (m_txc > 0) - { - LOG("- TxC:%d/%d = %d\n", m_txc, clocks, m_txc / clocks); - set_tra_rate(m_txc / clocks); + // calculate next bit time + m_tx_count = get_clock_mode(); + if (!stuff_zero && !--m_tx_bits) + { + switch (m_wr4 & WR4_STOP_BITS_MASK) + { + case WR4_STOP_BITS_SYNC: + case WR4_STOP_BITS_1: + break; + case WR4_STOP_BITS_1_5: + m_tx_count = ((m_tx_count * 3) + 1) / 2; // TODO: what does 1.5 stop bits do in TxC/1 mode? the +1 here rounds it up + break; + case WR4_STOP_BITS_2: + m_tx_count *= 2; + break; + } + transmit_complete(); + } + --m_tx_count; + } } - receive_register_reset(); // if stop bits is changed from 0, receive register has to be reset -} - - -//------------------------------------------------- -// set_dtr - -//------------------------------------------------- -void z80sio_channel::set_dtr(int state) -{ - LOG("%s(%d)\n", FUNCNAME, state); - m_dtr = state; - - if (m_index == z80sio_device::CHANNEL_A) - m_uart->m_out_dtra_cb(m_dtr); - else - m_uart->m_out_dtrb_cb(m_dtr); -} - -//------------------------------------------------- -// write_rx - -//------------------------------------------------- -WRITE_LINE_MEMBER(z80sio_channel::write_rx) -{ - m_rxd = state; - //only use rx_w when self-clocked - if(m_rxc) - device_serial_interface::rx_w(state); + m_tx_clock = state; } diff --git a/src/devices/machine/z80sio.h b/src/devices/machine/z80sio.h index 55803b7e427..f4363d23ce6 100644 --- a/src/devices/machine/z80sio.h +++ b/src/devices/machine/z80sio.h @@ -67,9 +67,6 @@ #define SIO_CHANB_TAG "chb" /* Generic macros */ -#define MCFG_Z80SIO_OFFSETS(_rxa, _txa, _rxb, _txb) \ - z80sio_device::configure_channels(*device, _rxa, _txa, _rxb, _txb); - #define MCFG_Z80SIO_OUT_INT_CB(_devcb) \ devcb = &z80sio_device::set_out_int_callback(*device, DEVCB_##_devcb); @@ -78,47 +75,47 @@ // Port A callbacks #define MCFG_Z80SIO_OUT_TXDA_CB(_devcb) \ - devcb = &z80sio_device::set_out_txda_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_txd_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_DTRA_CB(_devcb) \ - devcb = &z80sio_device::set_out_dtra_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_dtr_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_RTSA_CB(_devcb) \ - devcb = &z80sio_device::set_out_rtsa_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_rts_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_WRDYA_CB(_devcb) \ - devcb = &z80sio_device::set_out_wrdya_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_wrdy_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_SYNCA_CB(_devcb) \ - devcb = &z80sio_device::set_out_synca_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_sync_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_RXDRQA_CB(_devcb) \ - devcb = &z80sio_device::set_out_rxdrqa_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_rxdrq_callback<0>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_TXDRQA_CB(_devcb) \ - devcb = &z80sio_device::set_out_txdrqa_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_txdrq_callback<0>(*device, DEVCB_##_devcb); // Port B callbacks #define MCFG_Z80SIO_OUT_TXDB_CB(_devcb) \ - devcb = &z80sio_device::set_out_txdb_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_txd_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_DTRB_CB(_devcb) \ - devcb = &z80sio_device::set_out_dtrb_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_dtr_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_RTSB_CB(_devcb) \ - devcb = &z80sio_device::set_out_rtsb_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_rts_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_WRDYB_CB(_devcb) \ - devcb = &z80sio_device::set_out_wrdyb_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_wrdy_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_SYNCB_CB(_devcb) \ - devcb = &z80sio_device::set_out_syncb_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_sync_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_RXDRQB_CB(_devcb) \ - devcb = &z80sio_device::set_out_rxdrqb_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_rxdrq_callback<1>(*device, DEVCB_##_devcb); #define MCFG_Z80SIO_OUT_TXDRQB_CB(_devcb) \ - devcb = &z80sio_device::set_out_txdrqb_callback(*device, DEVCB_##_devcb); + devcb = &z80sio_device::set_out_txdrq_callback<1>(*device, DEVCB_##_devcb); //************************************************************************** @@ -129,20 +126,15 @@ class z80sio_device; -class z80sio_channel : public device_t, - public device_serial_interface +class z80sio_channel : public device_t { friend class z80sio_device; + friend class i8274_new_device; + friend class upd7201_new_device; public: z80sio_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // device_serial_interface overrides - virtual void tra_callback() override; - virtual void tra_complete() override; - virtual void rcv_callback() override; - virtual void rcv_complete() override; - // read register handlers uint8_t do_sioreg_rr0(); uint8_t do_sioreg_rr1(); @@ -165,23 +157,17 @@ public: uint8_t data_read(); void data_write(uint8_t data); - void receive_data(uint8_t data); - - DECLARE_WRITE_LINE_MEMBER( write_rx ); + DECLARE_WRITE_LINE_MEMBER( write_rx ) { m_rxd = state; } DECLARE_WRITE_LINE_MEMBER( cts_w ); DECLARE_WRITE_LINE_MEMBER( dcd_w ); DECLARE_WRITE_LINE_MEMBER( rxc_w ); DECLARE_WRITE_LINE_MEMBER( txc_w ); DECLARE_WRITE_LINE_MEMBER( sync_w ); - int m_rxc; - int m_txc; - // Register state // read registers enum uint8_t m_rr0; // REG_RR0_STATUS uint8_t m_rr1; // REG_RR1_SPEC_RCV_COND - uint8_t m_rr2; // REG_RR2_INTERRUPT_VECT // write registers enum uint8_t m_wr0; // REG_WR0_COMMAND_REGPT uint8_t m_wr1; // REG_WR1_INT_DMA_ENABLE @@ -192,15 +178,12 @@ public: uint8_t m_wr6; // REG_WR6_SYNC_OR_SDLC_A uint8_t m_wr7; // REG_WR7_SYNC_OR_SDLC_F - int m_variant; // Set in device - protected: enum { INT_TRANSMIT = 0, INT_EXTERNAL, - INT_RECEIVE, - INT_SPECIAL + INT_RECEIVE }; enum @@ -231,179 +214,116 @@ protected: REG_WR7_SYNC_OR_SDLC_F = 7 }; - enum - { - RR0_RX_CHAR_AVAILABLE = 0x01, - RR0_INTERRUPT_PENDING = 0x02, - RR0_TX_BUFFER_EMPTY = 0x04, - RR0_DCD = 0x08, - RR0_SYNC_HUNT = 0x10, - RR0_CTS = 0x20, - RR0_TX_UNDERRUN = 0x40, - RR0_BREAK_ABORT = 0x80 - }; - - enum - { - RR1_ALL_SENT = 0x01, - RR1_RESIDUE_CODE_MASK = 0x0e, - RR1_PARITY_ERROR = 0x10, - RR1_RX_OVERRUN_ERROR = 0x20, - RR1_CRC_FRAMING_ERROR = 0x40, - RR1_END_OF_FRAME = 0x80 - }; - - enum - { - RR2_INT_VECTOR_MASK = 0xff, - RR2_INT_VECTOR_V1 = 0x02, - RR2_INT_VECTOR_V2 = 0x04, - RR2_INT_VECTOR_V3 = 0x08 - }; - - enum - { - WR0_REGISTER_MASK = 0x07, - WR0_COMMAND_MASK = 0x38, - WR0_NULL = 0x00, - WR0_SEND_ABORT = 0x08, - WR0_RESET_EXT_STATUS = 0x10, - WR0_CHANNEL_RESET = 0x18, - WR0_ENABLE_INT_NEXT_RX = 0x20, - WR0_RESET_TX_INT = 0x28, - WR0_ERROR_RESET = 0x30, - WR0_RETURN_FROM_INT = 0x38, - WR0_CRC_RESET_CODE_MASK = 0xc0, - WR0_CRC_RESET_NULL = 0x00, - WR0_CRC_RESET_RX = 0x40, - WR0_CRC_RESET_TX = 0x80, - WR0_CRC_RESET_TX_UNDERRUN = 0xc0 - }; - - enum - { - WR1_EXT_INT_ENABLE = 0x01, - WR1_TX_INT_ENABLE = 0x02, - WR1_STATUS_VECTOR = 0x04, - WR1_RX_INT_MODE_MASK = 0x18, - WR1_RX_INT_DISABLE = 0x00, - WR1_RX_INT_FIRST = 0x08, - WR1_RX_INT_ALL_PARITY = 0x10, // not supported - WR1_RX_INT_ALL = 0x18, - WR1_WRDY_ON_RX_TX = 0x20, // not supported - WR1_WRDY_FUNCTION = 0x40, // not supported - WR1_WRDY_ENABLE = 0x80 // not supported - }; - - enum - { - WR2_DATA_XFER_INT = 0x00, // not supported - WR2_DATA_XFER_DMA_INT = 0x01, // not supported - WR2_DATA_XFER_DMA = 0x02, // not supported - WR2_DATA_XFER_ILLEGAL = 0x03, // not supported - WR2_DATA_XFER_MASK = 0x03, // not supported - WR2_PRIORITY = 0x04, // not supported - WR2_MODE_8085_1 = 0x00, // not supported - WR2_MODE_8085_2 = 0x08, // not supported - WR2_MODE_8086_8088 = 0x10, // not supported - WR2_MODE_ILLEGAL = 0x18, // not supported - WR2_MODE_MASK = 0x18, // not supported - WR2_VECTORED_INT = 0x20, // not supported - WR2_PIN10_SYNDETB_RTSB = 0x80 // not supported - }; - - enum + // used in a flag bitmap variable + enum : uint8_t { - WR3_RX_ENABLE = 0x01, - WR3_SYNC_CHAR_LOAD_INHIBIT= 0x02, // not supported - WR3_ADDRESS_SEARCH_MODE = 0x04, // not supported - WR3_RX_CRC_ENABLE = 0x08, // not supported - WR3_ENTER_HUNT_PHASE = 0x10, // not supported - WR3_AUTO_ENABLES = 0x20, - WR3_RX_WORD_LENGTH_MASK = 0xc0, - WR3_RX_WORD_LENGTH_5 = 0x00, - WR3_RX_WORD_LENGTH_7 = 0x40, - WR3_RX_WORD_LENGTH_6 = 0x80, - WR3_RX_WORD_LENGTH_8 = 0xc0 + TX_FLAG_CRC = 1U << 0, // include in checksum calculation + TX_FLAG_FRAMING = 1U << 1, // tranmitting framing bits + TX_FLAG_SPECIAL = 1U << 2 // transmitting checksum or abort sequence }; - enum - { - WR4_PARITY_ENABLE = 0x01, - WR4_PARITY_EVEN = 0x02, - WR4_STOP_BITS_MASK = 0x0c, - WR4_STOP_BITS_1 = 0x04, - WR4_STOP_BITS_1_5 = 0x08, // not supported - WR4_STOP_BITS_2 = 0x0c, - WR4_SYNC_MODE_MASK = 0x30, // not supported - WR4_SYNC_MODE_8_BIT = 0x00, // not supported - WR4_SYNC_MODE_16_BIT = 0x10, // not supported - WR4_SYNC_MODE_SDLC = 0x20, // not supported - WR4_SYNC_MODE_EXT = 0x30, // not supported - WR4_CLOCK_RATE_MASK = 0xc0, - WR4_CLOCK_RATE_X1 = 0x00, - WR4_CLOCK_RATE_X16 = 0x40, - WR4_CLOCK_RATE_X32 = 0x80, - WR4_CLOCK_RATE_X64 = 0xc0 - }; - - enum - { - WR5_TX_CRC_ENABLE = 0x01, // not supported - WR5_RTS = 0x02, - WR5_CRC16 = 0x04, // not supported - WR5_TX_ENABLE = 0x08, - WR5_SEND_BREAK = 0x10, - WR5_TX_WORD_LENGTH_MASK = 0x60, - WR5_TX_WORD_LENGTH_5 = 0x00, - WR5_TX_WORD_LENGTH_6 = 0x40, - WR5_TX_WORD_LENGTH_7 = 0x20, - WR5_TX_WORD_LENGTH_8 = 0x60, - WR5_DTR = 0x80 - }; + z80sio_channel( + const machine_config &mconfig, + device_type type, + const char *tag, + device_t *owner, + uint32_t clock, + uint8_t rr1_auto_reset); // device-level overrides virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; - void update_serial(); - void update_rts(); + void update_dtr_rts_break(); void set_dtr(int state); void set_rts(int state); int get_clock_mode(); - stop_bits_t get_stop_bits(); int get_rx_word_length(); - int get_tx_word_length(); + int get_tx_word_length() const; + int get_tx_word_length(uint8_t data) const; // receiver state - util::fifo<uint8_t, 3> m_rx_data_fifo; - util::fifo<uint8_t, 3> m_rx_error_fifo; - uint8_t m_rx_error; // current receive error + int m_rx_fifo_depth; + uint32_t m_rx_data_fifo; + uint32_t m_rx_error_fifo; + + int m_rx_clock; // receive clock line state + int m_rx_count; // clocks until next sample + int m_rx_bit; // receive data bit (0 = start bit, 1 = LSB, etc.) + uint16_t m_rx_sr; // receive shift register - int m_rx_clock; // receive clock pulse count int m_rx_first; // first character received int m_rx_break; // receive break condition - uint8_t m_rx_rr0_latch; // read register 0 latched int m_rxd; int m_sh; // sync hunt - int m_cts; // clear to send latch - int m_dcd; // data carrier detect latch // transmitter state - uint8_t m_tx_data; // transmit data register - int m_tx_clock; // transmit clock pulse count - + uint8_t m_tx_data; + + int m_tx_clock; // transmit clock line state + int m_tx_count; // clocks until next bit transition + int m_tx_bits; // remaining bits in shift register + int m_tx_parity; // parity bit position or zero if disabled + uint16_t m_tx_sr; // transmit shift register + uint16_t m_tx_crc; // calculated transmit checksum + uint8_t m_tx_hist; // transmit history (for bitstuffing) + uint8_t m_tx_flags; // internal transmit control flags + + int m_txd; int m_dtr; // data terminal ready int m_rts; // request to send + // external/status monitoring + int m_ext_latched; // changed data lines + int m_brk_latched; // break status latched + int m_cts; // clear to send line state + int m_dcd; // data carrier detect line state + int m_sync; // sync line state + // synchronous state - uint16_t m_sync; // sync character int m_index; z80sio_device *m_uart; + +private: + // helpers + void out_txd_cb(int state); + void out_rts_cb(int state); + void out_dtr_cb(int state); + void set_ready(bool ready); + bool receive_allowed() const; + bool transmit_allowed() const; + + void receive_enabled(); + void sync_receive(); + void receive_data(); + void queue_received(uint16_t data, uint32_t error); + void advance_rx_fifo(); + + void transmit_enable(); + void transmit_complete(); + void async_tx_setup(); + void sync_tx_sr_empty(); + void tx_setup(uint16_t data, int bits, int parity, bool framing, bool special); + void tx_setup_idle(); + + void reset_ext_status(); + void read_ext(); + void trigger_ext_int(); + + uint8_t const m_rr1_auto_reset; +}; + + +// ======================> i8274_channel + +class i8274_channel : public z80sio_channel +{ +public: + i8274_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; @@ -418,21 +338,14 @@ public: // construction/destruction z80sio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template <class Object> static devcb_base &set_out_txda_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_txda_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_dtra_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_dtra_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_rtsa_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_rtsa_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_wrdya_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_wrdya_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_synca_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_synca_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_txdb_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_txdb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_dtrb_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_dtrb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_rtsb_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_rtsb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_wrdyb_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_wrdyb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_syncb_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_syncb_cb.set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_txd_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_txd_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_dtr_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_dtr_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_rts_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_rts_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_wrdy_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_wrdy_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_sync_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_sync_cb[N].set_callback(std::forward<Object>(cb)); } template <class Object> static devcb_base &set_out_int_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_int_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_rxdrqa_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_rxdrqa_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_txdrqa_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_txdrqa_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_rxdrqb_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_rxdrqb_cb.set_callback(std::forward<Object>(cb)); } - template <class Object> static devcb_base &set_out_txdrqb_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_txdrqb_cb.set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_rxdrq_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_rxdrq_cb[N].set_callback(std::forward<Object>(cb)); } + template <unsigned N, class Object> static devcb_base &set_out_txdrq_callback(device_t &device, Object &&cb) { return downcast<z80sio_device &>(device).m_out_txdrq_cb[N].set_callback(std::forward<Object>(cb)); } static void static_set_cputag(device_t &device, const char *tag) { @@ -440,15 +353,6 @@ public: dev.m_cputag = tag; } - static void configure_channels(device_t &device, int rxa, int txa, int rxb, int txb) - { - z80sio_device &dev = downcast<z80sio_device &>(device); - dev.m_rxca = rxa; - dev.m_txca = txa; - dev.m_rxcb = rxb; - dev.m_txcb = txb; - } - DECLARE_READ8_MEMBER( cd_ba_r ); DECLARE_WRITE8_MEMBER( cd_ba_w ); DECLARE_READ8_MEMBER( ba_cd_r ); @@ -465,7 +369,7 @@ public: DECLARE_WRITE8_MEMBER( cb_w ) { m_chanB->control_write(data); } // interrupt acknowledge - int m1_r(); + virtual int m1_r(); DECLARE_WRITE_LINE_MEMBER( rxa_w ) { m_chanA->write_rx(state); } DECLARE_WRITE_LINE_MEMBER( rxb_w ) { m_chanB->write_rx(state); } @@ -482,7 +386,7 @@ public: DECLARE_WRITE_LINE_MEMBER( syncb_w ) { m_chanB->sync_w(state); } protected: - z80sio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t variant); + z80sio_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); // device-level overrides virtual void device_resolve_objects() override; @@ -498,18 +402,13 @@ protected: // internal interrupt management void check_interrupts(); void reset_interrupts(); - int get_interrupt_prio(int index, int type); - uint8_t modify_vector(int index, int type); - void trigger_interrupt(int index, int state); - int get_channel_index(z80sio_channel *ch) { return (ch == m_chanA) ? 0 : 1; } + void trigger_interrupt(int index, int type); + void clear_interrupt(int index, int type); + void return_from_interrupt(); + virtual uint8_t read_vector(); + virtual int const *interrupt_priorities() const; - // CPU types that has slightly different behaviour - enum - { - TYPE_Z80SIO = 0x001, - TYPE_UPD7201 = 0x002, - TYPE_I8274 = 0x004 - }; + int get_channel_index(z80sio_channel const *ch) const { return (ch == m_chanA) ? 0 : 1; } enum { @@ -521,51 +420,51 @@ protected: required_device<z80sio_channel> m_chanB; // internal state - int m_rxca; - int m_txca; - int m_rxcb; - int m_txcb; - - devcb_write_line m_out_txda_cb; - devcb_write_line m_out_dtra_cb; - devcb_write_line m_out_rtsa_cb; - devcb_write_line m_out_wrdya_cb; - devcb_write_line m_out_synca_cb; - - devcb_write_line m_out_txdb_cb; - devcb_write_line m_out_dtrb_cb; - devcb_write_line m_out_rtsb_cb; - devcb_write_line m_out_wrdyb_cb; - devcb_write_line m_out_syncb_cb; + devcb_write_line m_out_txd_cb[2]; + devcb_write_line m_out_dtr_cb[2]; + devcb_write_line m_out_rts_cb[2]; + devcb_write_line m_out_wrdy_cb[2]; + devcb_write_line m_out_sync_cb[2]; devcb_write_line m_out_int_cb; - devcb_write_line m_out_rxdrqa_cb; - devcb_write_line m_out_txdrqa_cb; - devcb_write_line m_out_rxdrqb_cb; - devcb_write_line m_out_txdrqb_cb; + devcb_write_line m_out_rxdrq_cb[2]; + devcb_write_line m_out_txdrq_cb[2]; int m_int_state[8]; // interrupt state int m_int_source[8]; // interrupt source - int m_variant; const char *m_cputag; }; -class upd7201_new_device : public z80sio_device +class i8274_new_device : public z80sio_device { public: - upd7201_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + i8274_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual int m1_r() override; + +protected: + i8274_new_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device_t overrides + virtual void device_add_mconfig(machine_config &config) override; + + // device_z80daisy_interface overrides + virtual int z80daisy_irq_ack() override; + virtual void z80daisy_irq_reti() override; + + virtual uint8_t read_vector() override; + virtual int const *interrupt_priorities() const override; }; -class i8274_new_device : public z80sio_device +class upd7201_new_device : public i8274_new_device { public: - i8274_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + upd7201_new_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); }; -// device type definition +// device type declaration DECLARE_DEVICE_TYPE(Z80SIO, z80sio_device) -DECLARE_DEVICE_TYPE(Z80SIO_CHANNEL, z80sio_channel) -DECLARE_DEVICE_TYPE(UPD7201_NEW, upd7201_new_device) DECLARE_DEVICE_TYPE(I8274_NEW, i8274_new_device) +DECLARE_DEVICE_TYPE(UPD7201_NEW, upd7201_new_device) #endif // MAME_MACHINE_Z80SIO_H diff --git a/src/devices/sound/cdp1869.cpp b/src/devices/sound/cdp1869.cpp index 2a352d01bd8..fa9cdff2d84 100644 --- a/src/devices/sound/cdp1869.cpp +++ b/src/devices/sound/cdp1869.cpp @@ -12,7 +12,6 @@ - white noise - scanline based update - - CMSEL output */ diff --git a/src/devices/sound/fmopl.cpp b/src/devices/sound/fmopl.cpp index a9c15478779..2e1be1b4266 100644 --- a/src/devices/sound/fmopl.cpp +++ b/src/devices/sound/fmopl.cpp @@ -309,11 +309,37 @@ struct OPL_CH SLOT.eg_sel_rr = eg_rate_select[SLOT.rr + SLOT.ksr ]; } } + + /* CSM Key Control */ + void CSMKeyControll() + { + SLOT[SLOT1].KEYON(4); + SLOT[SLOT2].KEYON(4); + + /* The key off should happen exactly one sample later - not implemented correctly yet */ + + SLOT[SLOT1].KEYOFF(~4); + SLOT[SLOT2].KEYOFF(~4); + } }; /* OPL state */ -struct FM_OPL +class FM_OPL { +protected: + FM_OPL() +#if BUILD_Y8950 + : deltat(nullptr, [] (YM_DELTAT *p) { p->~YM_DELTAT(); }) +#endif + { + } + +public: + ~FM_OPL() + { + UnLockTable(); + } + /* FM channel slots */ OPL_CH P_CH[9]; /* OPL/OPL2 chips have 9 channels*/ @@ -349,7 +375,7 @@ struct FM_OPL #if BUILD_Y8950 /* Delta-T ADPCM unit (Y8950) */ - YM_DELTAT *deltat; + std::unique_ptr<YM_DELTAT, void (*)(YM_DELTAT *)> deltat; /* Keyboard and I/O ports interface */ uint8_t portDirection; @@ -908,39 +934,183 @@ struct FM_OPL } - void WriteReg(int r, int v); void ResetChip(); void postload(); + void clock_changed(uint32_t c, uint32_t r) + { + clock = c; + rate = r; - /* lock/unlock for common table */ - static int LockTable(device_t *device) + /* init global tables */ + initialize(); + } + + int Write(int a, int v) { - num_lock++; - if(num_lock>1) return 0; + if( !(a&1) ) + { /* address port */ + address = v & 0xff; + } + else + { /* data port */ + if (UpdateHandler) UpdateHandler(UpdateParam, 0); + WriteReg(address, v); + } + return status>>7; + } - /* first time */ + unsigned char Read(int a) + { + if( !(a&1) ) + { + /* status port */ - /* allocate total level table (128kb space) */ - if( !init_tables() ) + #if BUILD_Y8950 + + if(type&OPL_TYPE_ADPCM) /* Y8950 */ + { + return (status & (statusmask|0x80)) | (deltat->PCM_BSY&1); + } + + #endif + + /* OPL and OPL2 */ + return status & (statusmask|0x80); + } + +#if BUILD_Y8950 + /* data port */ + switch(address) { - num_lock--; - return -1; + case 0x05: /* KeyBoard IN */ + if(type&OPL_TYPE_KEYBOARD) + { + if(keyboardhandler_r) + return keyboardhandler_r(keyboard_param); + else + device->logerror("Y8950: read unmapped KEYBOARD port\n"); + } + return 0; + + case 0x0f: /* ADPCM-DATA */ + if(type&OPL_TYPE_ADPCM) + { + uint8_t val; + + val = deltat->ADPCM_Read(); + /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/ + return val; + } + return 0; + + case 0x19: /* I/O DATA */ + if(type&OPL_TYPE_IO) + { + if(porthandler_r) + return porthandler_r(port_param); + else + device->logerror("Y8950:read unmapped I/O port\n"); + } + return 0; + case 0x1a: /* PCM-DATA */ + if(type&OPL_TYPE_ADPCM) + { + device->logerror("Y8950 A/D conversion is accessed but not implemented !\n"); + return 0x80; /* 2's complement PCM data - result from A/D conversion */ + } + return 0; } +#endif - return 0; + return 0xff; } - static void UnLockTable() + + int TimerOver(int c) { - if(num_lock) num_lock--; - if(num_lock) return; + if( c ) + { /* Timer B */ + STATUS_SET(0x20); + } + else + { /* Timer A */ + STATUS_SET(0x40); + /* CSM mode key,TL controll */ + if( mode & 0x80 ) + { /* CSM mode total level latch and auto key on */ + int ch; + if(UpdateHandler) UpdateHandler(UpdateParam,0); + for(ch=0; ch<9; ch++) + P_CH[ch].CSMKeyControll(); + } + } + /* reload timer */ + if (timer_handler) (timer_handler)(TimerParam,c,TimerBase * T[c]); + return status>>7; + } - /* last time */ - CloseTable(); + + /* Create one of virtual YM3812/YM3526/Y8950 */ + /* 'clock' is chip clock in Hz */ + /* 'rate' is sampling rate */ + static FM_OPL *Create(device_t *device, uint32_t clock, uint32_t rate, int type) + { + if (LockTable(device) == -1) + return nullptr; + + /* calculate OPL state size */ + size_t state_size = sizeof(FM_OPL); +#if BUILD_Y8950 + if (type & OPL_TYPE_ADPCM) + state_size+= sizeof(YM_DELTAT); +#endif + + /* allocate memory block */ + char *ptr = reinterpret_cast<char *>(::operator new(state_size)); + std::fill_n(ptr, state_size, 0); + + FM_OPL *const OPL = new(ptr) FM_OPL; + + ptr += sizeof(FM_OPL); + +#if BUILD_Y8950 + if (type & OPL_TYPE_ADPCM) + { + OPL->deltat.reset(reinterpret_cast<YM_DELTAT *>(ptr)); + ptr += sizeof(YM_DELTAT); + } +#endif + + OPL->device = device; + OPL->type = type; + OPL->clock_changed(clock, rate); + + return OPL; + } + + + /* Optional handlers */ + + void SetTimerHandler(OPL_TIMERHANDLER handler, device_t *device) + { + timer_handler = handler; + TimerParam = device; + } + void SetIRQHandler(OPL_IRQHANDLER handler, device_t *device) + { + IRQHandler = handler; + IRQParam = device; + } + void SetUpdateHandler(OPL_UPDATEHANDLER handler, device_t *device) + { + UpdateHandler = handler; + UpdateParam = device; } private: + void WriteReg(int r, int v); + uint32_t volume_calc(OPL_SLOT const &OP) const { return OP.TLL + uint32_t(OP.volume) + (LFO_AM & OP.AMmask); @@ -961,6 +1131,33 @@ private: } + /* lock/unlock for common table */ + static int LockTable(device_t *device) + { + num_lock++; + if(num_lock>1) return 0; + + /* first time */ + + /* allocate total level table (128kb space) */ + if( !init_tables() ) + { + num_lock--; + return -1; + } + + return 0; + } + + static void UnLockTable() + { + if(num_lock) num_lock--; + if(num_lock) return; + + /* last time */ + CloseTable(); + } + static int init_tables(); static void CloseTable() @@ -1781,13 +1978,11 @@ void FM_OPL::ResetChip() #if BUILD_Y8950 if(type&OPL_TYPE_ADPCM) { - YM_DELTAT *DELTAT = deltat; - - DELTAT->freqbase = freqbase; - DELTAT->output_pointer = &output_deltat[0]; - DELTAT->portshift = 5; - DELTAT->output_range = 1<<23; - DELTAT->ADPCM_Reset(0,YM_DELTAT::EMULATION_MODE_NORMAL,device); + deltat->freqbase = freqbase; + deltat->output_pointer = &output_deltat[0]; + deltat->portshift = 5; + deltat->output_range = 1<<23; + deltat->ADPCM_Reset(0,YM_DELTAT::EMULATION_MODE_NORMAL,device); } #endif } @@ -1936,197 +2131,6 @@ static void OPL_save_state(FM_OPL *OPL, device_t *device) device->machine().save().register_postload(save_prepost_delegate(FUNC(FM_OPL::postload), OPL)); } -static void OPL_clock_changed(FM_OPL *OPL, uint32_t clock, uint32_t rate) -{ - OPL->clock = clock; - OPL->rate = rate; - - /* init global tables */ - OPL->initialize(); -} - - -/* Create one of virtual YM3812/YM3526/Y8950 */ -/* 'clock' is chip clock in Hz */ -/* 'rate' is sampling rate */ -static FM_OPL *OPLCreate(device_t *device, uint32_t clock, uint32_t rate, int type) -{ - char *ptr; - FM_OPL *OPL; - int state_size; - - if (FM_OPL::LockTable(device) == -1) return nullptr; - - /* calculate OPL state size */ - state_size = sizeof(FM_OPL); - -#if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) state_size+= sizeof(YM_DELTAT); -#endif - - /* allocate memory block */ - ptr = (char *)auto_alloc_array_clear(device->machine(), uint8_t, state_size); - - OPL = (FM_OPL *)ptr; - - ptr += sizeof(FM_OPL); - -#if BUILD_Y8950 - if (type&OPL_TYPE_ADPCM) - { - OPL->deltat = (YM_DELTAT *)ptr; - } - ptr += sizeof(YM_DELTAT); -#endif - - OPL->device = device; - OPL->type = type; - OPL_clock_changed(OPL, clock, rate); - - return OPL; -} - -/* Destroy one of virtual YM3812 */ -static void OPLDestroy(FM_OPL *OPL) -{ - FM_OPL::UnLockTable(); - auto_free(OPL->device->machine(), OPL); -} - -/* Optional handlers */ - -static void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER timer_handler,device_t *device) -{ - OPL->timer_handler = timer_handler; - OPL->TimerParam = device; -} -static void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,device_t *device) -{ - OPL->IRQHandler = IRQHandler; - OPL->IRQParam = device; -} -static void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,device_t *device) -{ - OPL->UpdateHandler = UpdateHandler; - OPL->UpdateParam = device; -} - -static int OPLWrite(FM_OPL *OPL,int a,int v) -{ - if( !(a&1) ) - { /* address port */ - OPL->address = v & 0xff; - } - else - { /* data port */ - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - OPL->WriteReg(OPL->address,v); - } - return OPL->status>>7; -} - -static unsigned char OPLRead(FM_OPL *OPL,int a) -{ - if( !(a&1) ) - { - /* status port */ - - #if BUILD_Y8950 - - if(OPL->type&OPL_TYPE_ADPCM) /* Y8950 */ - { - return (OPL->status & (OPL->statusmask|0x80)) | (OPL->deltat->PCM_BSY&1); - } - - #endif - - /* OPL and OPL2 */ - return OPL->status & (OPL->statusmask|0x80); - } - -#if BUILD_Y8950 - /* data port */ - switch(OPL->address) - { - case 0x05: /* KeyBoard IN */ - if(OPL->type&OPL_TYPE_KEYBOARD) - { - if(OPL->keyboardhandler_r) - return OPL->keyboardhandler_r(OPL->keyboard_param); - else - OPL->device->logerror("Y8950: read unmapped KEYBOARD port\n"); - } - return 0; - - case 0x0f: /* ADPCM-DATA */ - if(OPL->type&OPL_TYPE_ADPCM) - { - uint8_t val; - - val = OPL->deltat->ADPCM_Read(); - /*logerror("Y8950: read ADPCM value read=%02x\n",val);*/ - return val; - } - return 0; - - case 0x19: /* I/O DATA */ - if(OPL->type&OPL_TYPE_IO) - { - if(OPL->porthandler_r) - return OPL->porthandler_r(OPL->port_param); - else - OPL->device->logerror("Y8950:read unmapped I/O port\n"); - } - return 0; - case 0x1a: /* PCM-DATA */ - if(OPL->type&OPL_TYPE_ADPCM) - { - OPL->device->logerror("Y8950 A/D conversion is accessed but not implemented !\n"); - return 0x80; /* 2's complement PCM data - result from A/D conversion */ - } - return 0; - } -#endif - - return 0xff; -} - -/* CSM Key Controll */ -static inline void CSMKeyControll(OPL_CH *CH) -{ - CH->SLOT[SLOT1].KEYON(4); - CH->SLOT[SLOT2].KEYON(4); - - /* The key off should happen exactly one sample later - not implemented correctly yet */ - - CH->SLOT[SLOT1].KEYOFF(~4); - CH->SLOT[SLOT2].KEYOFF(~4); -} - - -static int OPLTimerOver(FM_OPL *OPL,int c) -{ - if( c ) - { /* Timer B */ - OPL->STATUS_SET(0x20); - } - else - { /* Timer A */ - OPL->STATUS_SET(0x40); - /* CSM mode key,TL controll */ - if( OPL->mode & 0x80 ) - { /* CSM mode total level latch and auto key on */ - int ch; - if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); - for(ch=0; ch<9; ch++) - CSMKeyControll( &OPL->P_CH[ch] ); - } - } - /* reload timer */ - if (OPL->timer_handler) (OPL->timer_handler)(OPL->TimerParam,c,OPL->TimerBase * OPL->T[c]); - return OPL->status>>7; -} - #define MAX_OPL_CHIPS 2 @@ -2135,13 +2139,13 @@ static int OPLTimerOver(FM_OPL *OPL,int c) void ym3812_clock_changed(void *chip, uint32_t clock, uint32_t rate) { - OPL_clock_changed((FM_OPL *)chip, clock, rate); + reinterpret_cast<FM_OPL *>(chip)->clock_changed(clock, rate); } void * ym3812_init(device_t *device, uint32_t clock, uint32_t rate) { /* emulator create */ - FM_OPL *YM3812 = OPLCreate(device,clock,rate,OPL_TYPE_YM3812); + FM_OPL *YM3812 = FM_OPL::Create(device,clock,rate,OPL_TYPE_YM3812); if (YM3812) { OPL_save_state(YM3812, device); @@ -2155,7 +2159,7 @@ void ym3812_shutdown(void *chip) FM_OPL *YM3812 = (FM_OPL *)chip; /* emulator shutdown */ - OPLDestroy(YM3812); + delete YM3812; } void ym3812_reset_chip(void *chip) { @@ -2166,35 +2170,32 @@ void ym3812_reset_chip(void *chip) int ym3812_write(void *chip, int a, int v) { FM_OPL *YM3812 = (FM_OPL *)chip; - return OPLWrite(YM3812, a, v); + return YM3812->Write(a, v); } unsigned char ym3812_read(void *chip, int a) { FM_OPL *YM3812 = (FM_OPL *)chip; /* YM3812 always returns bit2 and bit1 in HIGH state */ - return OPLRead(YM3812, a) | 0x06 ; + return YM3812->Read(a) | 0x06 ; } int ym3812_timer_over(void *chip, int c) { FM_OPL *YM3812 = (FM_OPL *)chip; - return OPLTimerOver(YM3812, c); + return YM3812->TimerOver(c); } void ym3812_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, device_t *device) { - FM_OPL *YM3812 = (FM_OPL *)chip; - OPLSetTimerHandler(YM3812, timer_handler, device); + reinterpret_cast<FM_OPL *>(chip)->SetTimerHandler(timer_handler, device); } void ym3812_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,device_t *device) { - FM_OPL *YM3812 = (FM_OPL *)chip; - OPLSetIRQHandler(YM3812, IRQHandler, device); + reinterpret_cast<FM_OPL *>(chip)->SetIRQHandler(IRQHandler, device); } void ym3812_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device_t *device) { - FM_OPL *YM3812 = (FM_OPL *)chip; - OPLSetUpdateHandler(YM3812, UpdateHandler, device); + reinterpret_cast<FM_OPL *>(chip)->SetUpdateHandler(UpdateHandler, device); } @@ -2268,13 +2269,13 @@ void ym3812_update_one(void *chip, OPLSAMPLE *buffer, int length) void ym3526_clock_changed(void *chip, uint32_t clock, uint32_t rate) { - OPL_clock_changed((FM_OPL *)chip, clock, rate); + reinterpret_cast<FM_OPL *>(chip)->clock_changed(clock, rate); } void *ym3526_init(device_t *device, uint32_t clock, uint32_t rate) { /* emulator create */ - FM_OPL *YM3526 = OPLCreate(device,clock,rate,OPL_TYPE_YM3526); + FM_OPL *YM3526 = FM_OPL::Create(device,clock,rate,OPL_TYPE_YM3526); if (YM3526) { OPL_save_state(YM3526, device); @@ -2287,7 +2288,7 @@ void ym3526_shutdown(void *chip) { FM_OPL *YM3526 = (FM_OPL *)chip; /* emulator shutdown */ - OPLDestroy(YM3526); + delete YM3526; } void ym3526_reset_chip(void *chip) { @@ -2298,35 +2299,32 @@ void ym3526_reset_chip(void *chip) int ym3526_write(void *chip, int a, int v) { FM_OPL *YM3526 = (FM_OPL *)chip; - return OPLWrite(YM3526, a, v); + return YM3526->Write(a, v); } unsigned char ym3526_read(void *chip, int a) { FM_OPL *YM3526 = (FM_OPL *)chip; /* YM3526 always returns bit2 and bit1 in HIGH state */ - return OPLRead(YM3526, a) | 0x06 ; + return YM3526->Read(a) | 0x06 ; } int ym3526_timer_over(void *chip, int c) { FM_OPL *YM3526 = (FM_OPL *)chip; - return OPLTimerOver(YM3526, c); + return YM3526->TimerOver(c); } void ym3526_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, device_t *device) { - FM_OPL *YM3526 = (FM_OPL *)chip; - OPLSetTimerHandler(YM3526, timer_handler, device); + reinterpret_cast<FM_OPL *>(chip)->SetTimerHandler(timer_handler, device); } void ym3526_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,device_t *device) { - FM_OPL *YM3526 = (FM_OPL *)chip; - OPLSetIRQHandler(YM3526, IRQHandler, device); + reinterpret_cast<FM_OPL *>(chip)->SetIRQHandler(IRQHandler, device); } void ym3526_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device_t *device) { - FM_OPL *YM3526 = (FM_OPL *)chip; - OPLSetUpdateHandler(YM3526, UpdateHandler, device); + reinterpret_cast<FM_OPL *>(chip)->SetUpdateHandler(UpdateHandler, device); } @@ -2413,7 +2411,7 @@ static void Y8950_deltat_status_reset(void *chip, uint8_t changebits) void *y8950_init(device_t *device, uint32_t clock, uint32_t rate) { /* emulator create */ - FM_OPL *Y8950 = OPLCreate(device,clock,rate,OPL_TYPE_Y8950); + FM_OPL *Y8950 = FM_OPL::Create(device,clock,rate,OPL_TYPE_Y8950); if (Y8950) { Y8950->deltat->status_set_handler = Y8950_deltat_status_set; @@ -2436,7 +2434,7 @@ void y8950_shutdown(void *chip) { FM_OPL *Y8950 = (FM_OPL *)chip; /* emulator shutdown */ - OPLDestroy(Y8950); + delete Y8950; } void y8950_reset_chip(void *chip) { @@ -2447,34 +2445,31 @@ void y8950_reset_chip(void *chip) int y8950_write(void *chip, int a, int v) { FM_OPL *Y8950 = (FM_OPL *)chip; - return OPLWrite(Y8950, a, v); + return Y8950->Write(a, v); } unsigned char y8950_read(void *chip, int a) { FM_OPL *Y8950 = (FM_OPL *)chip; - return OPLRead(Y8950, a); + return Y8950->Read(a); } int y8950_timer_over(void *chip, int c) { FM_OPL *Y8950 = (FM_OPL *)chip; - return OPLTimerOver(Y8950, c); + return Y8950->TimerOver(c); } void y8950_set_timer_handler(void *chip, OPL_TIMERHANDLER timer_handler, device_t *device) { - FM_OPL *Y8950 = (FM_OPL *)chip; - OPLSetTimerHandler(Y8950, timer_handler, device); + reinterpret_cast<FM_OPL *>(chip)->SetTimerHandler(timer_handler, device); } void y8950_set_irq_handler(void *chip,OPL_IRQHANDLER IRQHandler,device_t *device) { - FM_OPL *Y8950 = (FM_OPL *)chip; - OPLSetIRQHandler(Y8950, IRQHandler, device); + reinterpret_cast<FM_OPL *>(chip)->SetIRQHandler(IRQHandler, device); } void y8950_set_update_handler(void *chip,OPL_UPDATEHANDLER UpdateHandler,device_t *device) { - FM_OPL *Y8950 = (FM_OPL *)chip; - OPLSetUpdateHandler(Y8950, UpdateHandler, device); + reinterpret_cast<FM_OPL *>(chip)->SetUpdateHandler(UpdateHandler, device); } void y8950_set_delta_t_memory(void *chip, void * deltat_mem_ptr, int deltat_mem_size ) @@ -2496,7 +2491,7 @@ void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length) int i; FM_OPL *OPL = (FM_OPL *)chip; uint8_t rhythm = OPL->rhythm&0x20; - YM_DELTAT *DELTAT = OPL->deltat; + YM_DELTAT &DELTAT = *OPL->deltat; OPLSAMPLE *buf = buffer; for( i=0; i < length ; i++ ) @@ -2509,8 +2504,8 @@ void y8950_update_one(void *chip, OPLSAMPLE *buffer, int length) OPL->advance_lfo(); /* deltaT ADPCM */ - if( DELTAT->portstate&0x80 ) - DELTAT->ADPCM_CALC(); + if( DELTAT.portstate&0x80 ) + DELTAT.ADPCM_CALC(); /* FM part */ OPL->CALC_CH(OPL->P_CH[0]); diff --git a/src/devices/sound/mpeg_audio.cpp b/src/devices/sound/mpeg_audio.cpp index 26433ae73e9..0aa9c3192c6 100644 --- a/src/devices/sound/mpeg_audio.cpp +++ b/src/devices/sound/mpeg_audio.cpp @@ -16,6 +16,11 @@ mpeg_audio::mpeg_audio(const void *_base, unsigned int _accepted, bool lsb_first do_gb = lsb_first ? do_gb_lsb : do_gb_msb; position_align = _position_align ? _position_align - 1 : 0; + for (int i = 0; i < 32; i++) { + for (int j = 0; j < 32; j++) + m_cos_cache[i][j] = cos(i*(2 * j + 1)*M_PI / 64); + } + clear(); } @@ -722,10 +727,10 @@ void mpeg_audio::retrieve_subbuffer(int step) void mpeg_audio::idct32(const double *input, double *output) { // Simplest idct32 ever, non-fast at all - for(int i=0; i<32; i++) { + for (int i = 0; i < 32; i++) { double s = 0; - for(int j=0; j<32; j++) - s += input[j] * cos(i*(2*j+1)*M_PI/64); + for (int j = 0; j < 32; j++) + s += input[j] * m_cos_cache[i][j]; output[i] = s; } } diff --git a/src/devices/sound/mpeg_audio.h b/src/devices/sound/mpeg_audio.h index 4641dd9beb0..53738671c16 100644 --- a/src/devices/sound/mpeg_audio.h +++ b/src/devices/sound/mpeg_audio.h @@ -92,6 +92,7 @@ private: double subbuffer[2][32]; double audio_buffer[2][32*32]; int audio_buffer_pos[2]; + double m_cos_cache[32][32]; int current_pos, current_limit; diff --git a/src/devices/sound/okim6295.cpp b/src/devices/sound/okim6295.cpp index 78bf872af3d..4b089eb00a6 100644 --- a/src/devices/sound/okim6295.cpp +++ b/src/devices/sound/okim6295.cpp @@ -35,6 +35,11 @@ ???? abcd = one bit per voice, set to 0 if nothing is playing, or 1 if it is active + OKI Semiconductor produced this chip in two package variants. The + 44-pin QFP version, MSM6295GS, is the original one and by far the more + common of the two. The 42-pin DIP version, MSM6295VRS, omits A17 and + RD, which limits its ROM addressing to one megabit instead of two. + ***************************************************************************/ #include "emu.h" diff --git a/src/devices/sound/rf5c400.cpp b/src/devices/sound/rf5c400.cpp index 39440c66991..4fc6a364c7a 100644 --- a/src/devices/sound/rf5c400.cpp +++ b/src/devices/sound/rf5c400.cpp @@ -181,7 +181,7 @@ void rf5c400_device::device_start() m_stream = stream_alloc(0, 2, clock() / 384); - m_rommask = m_rom.length() - 1; + m_rommask = (m_rom.length()/2) - 1; } //------------------------------------------------- @@ -258,7 +258,7 @@ void rf5c400_device::sound_stream_update(sound_stream &stream, stream_sample_t * { env_phase = PHASE_DECAY; env_level = 1.0; - if (channel->decay & 0x0080) + if ((channel->decay & 0x0080) || (channel->decay == 0x100)) { env_step = 0.0; } diff --git a/src/devices/sound/wave.cpp b/src/devices/sound/wave.cpp index 7383805d05e..810f537e51d 100644 --- a/src/devices/sound/wave.cpp +++ b/src/devices/sound/wave.cpp @@ -47,13 +47,13 @@ wave_device::wave_device(const machine_config &mconfig, const char *tag, device_ void wave_device::device_start() { - speaker_device_iterator spkiter(machine().root_device()); + speaker_device_iterator spkiter(*owner()); int speakers = spkiter.count(); if (speakers > 1) machine().sound().stream_alloc(*this, 0, 2, machine().sample_rate()); else machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate()); - m_cass = machine().device<cassette_image_device>(m_cassette_tag); + m_cass = owner()->subdevice<cassette_image_device>(m_cassette_tag); } //------------------------------------------------- @@ -69,7 +69,7 @@ void wave_device::sound_stream_update(sound_stream &stream, stream_sample_t **in stream_sample_t *right_buffer = nullptr; int i; - speaker_device_iterator spkiter(m_cass->machine().root_device()); + speaker_device_iterator spkiter(*owner()); int speakers = spkiter.count(); if (speakers>1) right_buffer = outputs[1]; diff --git a/src/devices/sound/ymz770.cpp b/src/devices/sound/ymz770.cpp index 506de02da15..ae7a995ce21 100644 --- a/src/devices/sound/ymz770.cpp +++ b/src/devices/sound/ymz770.cpp @@ -1,21 +1,23 @@ // license:BSD-3-Clause -// copyright-holders:Olivier Galibert, R. Belmont +// copyright-holders:Olivier Galibert, R. Belmont, MetalliC /*************************************************************************** - ymz770.c + Yamaha YMZ770C and YMZ774 - Emulation by R. Belmont + Emulation by R. Belmont and MetalliC AMM decode by Olivier Galibert ----- TODO: -- A lot of unimplemented features, even simple ones like panning, - these should be added once we find out any software that uses it. -- Sequencer is very preliminary -- verify if pan 100% correct - What does channel ATBL mean? -- Is YMZ774(and other variants) the same family as this chip? - What are the differences? + 770: +- verify if pan 100% correct +- sequencer timers and triggers not implemented (seems used in Deathsmiles ending tune) + 774: +- find out how volume/pan delayed transition works (used few times in orleg2 attract mode) +- 4 channel output +- Equalizer +- Sequencer (not used) ***************************************************************************/ @@ -24,20 +26,28 @@ TODO: #include "mpeg_audio.h" // device type definition -DEFINE_DEVICE_TYPE(YMZ770, ymz770_device, "ymz770", "Yamaha YMZ770 AMMS-A") +DEFINE_DEVICE_TYPE(YMZ770, ymz770_device, "ymz770", "Yamaha YMZ770C-F AMMS-A") +DEFINE_DEVICE_TYPE(YMZ774, ymz774_device, "ymz774", "Yamaha YMZ774-S AMMS2") //------------------------------------------------- // ymz770_device - constructor //------------------------------------------------- ymz770_device::ymz770_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, YMZ770, tag, owner, clock) + : ymz770_device(mconfig, YMZ770, tag, owner, clock, 16000) +{ +} + +ymz770_device::ymz770_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t sclock) + : device_t(mconfig, type, tag, owner, clock) , device_sound_interface(mconfig, *this) , m_stream(nullptr) + , m_sclock(sclock) , m_cur_reg(0) , m_mute(0) , m_doen(0) , m_vlma(0) + , m_vlma1(0) , m_bsl(0) , m_cpl(0) , m_rom(*this, DEVICE_SELF) @@ -52,41 +62,54 @@ ymz770_device::ymz770_device(const machine_config &mconfig, const char *tag, dev void ymz770_device::device_start() { // create the stream - m_stream = machine().sound().stream_alloc(*this, 0, 2, 16000); + m_stream = machine().sound().stream_alloc(*this, 0, 2, m_sclock); - for (auto & elem : m_channels) + for (auto & channel : m_channels) { - elem.is_playing = false; - elem.is_seq_playing = false; - elem.decoder = new mpeg_audio(&m_rom[0], mpeg_audio::AMM, false, 0); + channel.is_playing = false; + channel.decoder = new mpeg_audio(&m_rom[0], mpeg_audio::AMM, false, 0); } + for (auto & sequence : m_sequences) + sequence.is_playing = false; // register for save states save_item(NAME(m_cur_reg)); save_item(NAME(m_mute)); save_item(NAME(m_doen)); save_item(NAME(m_vlma)); + save_item(NAME(m_vlma1)); save_item(NAME(m_bsl)); save_item(NAME(m_cpl)); - for (int ch = 0; ch < 8; ch++) + for (int ch = 0; ch < 16; ch++) // TODO array size { save_item(NAME(m_channels[ch].phrase), ch); save_item(NAME(m_channels[ch].pan), ch); + save_item(NAME(m_channels[ch].pan_delay), ch); + save_item(NAME(m_channels[ch].pan1), ch); + save_item(NAME(m_channels[ch].pan1_delay), ch); save_item(NAME(m_channels[ch].volume), ch); - save_item(NAME(m_channels[ch].control), ch); + save_item(NAME(m_channels[ch].volume_delay), ch); + save_item(NAME(m_channels[ch].volume2), ch); + save_item(NAME(m_channels[ch].loop), ch); save_item(NAME(m_channels[ch].is_playing), ch); save_item(NAME(m_channels[ch].last_block), ch); save_item(NAME(m_channels[ch].output_remaining), ch); save_item(NAME(m_channels[ch].output_ptr), ch); save_item(NAME(m_channels[ch].atbl), ch); save_item(NAME(m_channels[ch].pptr), ch); - save_item(NAME(m_channels[ch].sequence), ch); - save_item(NAME(m_channels[ch].seqcontrol), ch); - save_item(NAME(m_channels[ch].seqdelay), ch); - save_item(NAME(m_channels[ch].is_seq_playing), ch); save_item(NAME(m_channels[ch].output_data), ch); } + for (int ch = 0; ch < 8; ch++) + { + save_item(NAME(m_sequences[ch].delay), ch); + save_item(NAME(m_sequences[ch].sequence), ch); + save_item(NAME(m_sequences[ch].timer), ch); + save_item(NAME(m_sequences[ch].stopchan), ch); + save_item(NAME(m_sequences[ch].loop), ch); + save_item(NAME(m_sequences[ch].bank), ch); + save_item(NAME(m_sequences[ch].is_playing), ch); + } } @@ -96,19 +119,30 @@ void ymz770_device::device_start() void ymz770_device::device_reset() { - for (auto & elem : m_channels) + for (auto & channel : m_channels) { - elem.phrase = 0; - elem.pan = 8; - elem.volume = 0; - elem.control = 0; - elem.sequence = 0; - elem.seqcontrol = 0; - elem.seqdelay = 0; - elem.is_playing = false; - elem.is_seq_playing = false; - elem.output_remaining = 0; - elem.decoder->clear(); + channel.phrase = 0; + channel.pan = 64; + channel.pan_delay = 0; + channel.pan1 = 64; + channel.pan1_delay = 0; + channel.volume = 0; + channel.volume_delay = 0; + channel.volume2 = 0; + channel.loop = 0; + channel.is_playing = false; + channel.output_remaining = 0; + channel.decoder->clear(); + } + for (auto & sequence : m_sequences) + { + sequence.delay = 0; + sequence.sequence = 0; + sequence.timer = 0; + sequence.stopchan = 0; + sequence.loop = 0; + sequence.bank = 0; + sequence.is_playing = false; } } @@ -127,107 +161,74 @@ void ymz770_device::sound_stream_update(sound_stream &stream, stream_sample_t ** for (int i = 0; i < samples; i++) { - // run sequencers (should probably be in separate timer callbacks) - for (auto & elem : m_channels) - { - if (elem.is_seq_playing) - { - if (elem.seqdelay > 0) - { - elem.seqdelay--; - } - else - { - int reg = *elem.seqdata++; - uint8_t data = *elem.seqdata++; - switch (reg) - { - case 0x0f: - if (elem.seqcontrol & 1) - { - // loop sequence - uint8_t sqn = elem.sequence; - uint32_t pptr = m_rom[(4*sqn)+1+0x400]<<16 | m_rom[(4*sqn)+2+0x400]<<8 | m_rom[(4*sqn)+3+0x400]; - elem.seqdata = &m_rom[pptr]; - } - else - { - elem.is_seq_playing = false; - } - break; - case 0x0e: - elem.seqdelay = 32 - 1; - break; - default: - internal_reg_write(reg, data); - break; - } - } - } - } + sequencer(); // process channels int32_t mixl = 0; int32_t mixr = 0; - for (auto & elem : m_channels) + for (auto & channel : m_channels) { - if (elem.output_remaining > 0) + if (channel.output_remaining > 0) { // force finish current block - int32_t smpl = elem.output_data[elem.output_ptr++] * elem.volume; // volume is linear, 0 - 128 (100%) - mixr += (smpl * elem.pan) >> 11; // pan seems linear, 0 - 16, where 0 = 100% left, 16 = 100% right, 8 = 50% left 50% right - mixl += (smpl * (16 - elem.pan)) >> 11; - elem.output_remaining--; - - if (elem.output_remaining == 0 && !elem.is_playing) - elem.decoder->clear(); + int32_t smpl = (channel.output_data[channel.output_ptr++] * channel.volume) >> 7; // volume is linear, 0 - 128 (100%) + smpl = (smpl * channel.volume2) >> 7; + mixr += (smpl * channel.pan) >> 7; // pan seems linear, 0 - 128, where 0 = 100% left, 128 = 100% right, 64 = 50% left 50% right + mixl += (smpl * (128 - channel.pan)) >> 7; + channel.output_remaining--; + + if (channel.output_remaining == 0 && !channel.is_playing) + channel.decoder->clear(); } - else if (elem.is_playing) + else if (channel.is_playing) { retry: - if (elem.last_block) + if (channel.last_block) { - if (elem.control & 1) + if (channel.loop) { + if (channel.loop != 255) + --channel.loop; // loop sample - uint8_t phrase = elem.phrase; - elem.atbl = m_rom[(4*phrase)+0] >> 4 & 7; - elem.pptr = 8*(m_rom[(4*phrase)+1]<<16 | m_rom[(4*phrase)+2]<<8 | m_rom[(4*phrase)+3]); + int phrase = channel.phrase; + channel.atbl = m_rom[(4*phrase)+0] >> 4 & 7; + channel.pptr = 8 * get_phrase_offs(phrase); } else { - elem.is_playing = false; - elem.output_remaining = 0; - elem.decoder->clear(); + channel.is_playing = false; + channel.output_remaining = 0; + channel.decoder->clear(); } } - if (elem.is_playing) + if (channel.is_playing) { // next block int sample_rate, channel_count; - if (!elem.decoder->decode_buffer(elem.pptr, m_rom.bytes()*8, elem.output_data, elem.output_remaining, sample_rate, channel_count) || elem.output_remaining == 0) + if (!channel.decoder->decode_buffer(channel.pptr, m_rom.bytes()*8, channel.output_data, channel.output_remaining, sample_rate, channel_count) || channel.output_remaining == 0) { - elem.is_playing = !elem.last_block; // detect infinite retry loop - elem.last_block = true; - elem.output_remaining = 0; + channel.is_playing = !channel.last_block; // detect infinite retry loop + channel.last_block = true; + channel.output_remaining = 0; goto retry; } - elem.last_block = elem.output_remaining < 1152; - elem.output_remaining--; - elem.output_ptr = 1; + channel.last_block = channel.output_remaining < 1152; + channel.output_remaining--; + channel.output_ptr = 1; - int32_t smpl = elem.output_data[0] * elem.volume; - mixr += (smpl * elem.pan) >> 11; - mixl += (smpl * (16 - elem.pan)) >> 11; + int32_t smpl = (channel.output_data[0] * channel.volume) >> 7; + smpl = (smpl * channel.volume2) >> 7; + mixr += (smpl * channel.pan) >> 7; + mixl += (smpl * (128 - channel.pan)) >> 7; } } } - mixr *= m_vlma; // main volume is linear, 0 - 255, where 128 = 100% + mixr *= m_vlma; // main volume is linear, 0 - 255, where 128 = 100% mixl *= m_vlma; mixr >>= 7 - m_bsl; mixl >>= 7 - m_bsl; @@ -256,6 +257,46 @@ retry: } } +void ymz770_device::sequencer() +{ + for (auto & sequence : m_sequences) + { + if (sequence.is_playing) + { + if (sequence.delay > 0) + { + sequence.delay--; + } + else + { + int reg = *sequence.data++; + uint8_t data = *sequence.data++; + switch (reg) + { + case 0x0f: + if (sequence.loop) + { + // loop sequence + uint8_t sqn = sequence.sequence; + uint32_t pptr = get_seq_offs(sqn); + sequence.data = &m_rom[pptr]; + } + else + { + sequence.is_playing = false; + } + break; + case 0x0e: + sequence.delay = 32 - 1; + break; + default: + internal_reg_write(reg, data); + break; + } + } + } + } +} //------------------------------------------------- // write - write to the chip's registers @@ -315,10 +356,11 @@ void ymz770_device::internal_reg_write(uint8_t reg, uint8_t data) case 1: m_channels[ch].volume = data; + m_channels[ch].volume2 = 128; break; case 2: - m_channels[ch].pan = data; + m_channels[ch].pan = data << 3; break; case 3: @@ -326,7 +368,7 @@ void ymz770_device::internal_reg_write(uint8_t reg, uint8_t data) { uint8_t phrase = m_channels[ch].phrase; m_channels[ch].atbl = m_rom[(4*phrase)+0] >> 4 & 7; - m_channels[ch].pptr = 8*(m_rom[(4*phrase)+1]<<16 | m_rom[(4*phrase)+2]<<8 | m_rom[(4*phrase)+3]); + m_channels[ch].pptr = 8 * get_phrase_offs(phrase); m_channels[ch].last_block = false; m_channels[ch].is_playing = true; @@ -336,7 +378,7 @@ void ymz770_device::internal_reg_write(uint8_t reg, uint8_t data) m_channels[ch].is_playing = false; } - m_channels[ch].control = data; + m_channels[ch].loop = (data & 1) ? 255 : 0; break; } } @@ -349,23 +391,23 @@ void ymz770_device::internal_reg_write(uint8_t reg, uint8_t data) switch (reg & 0x0f) { case 0: - m_channels[ch].sequence = data; + m_sequences[ch].sequence = data; break; case 1: if (data & 6) { - uint8_t sqn = m_channels[ch].sequence; - uint32_t pptr = m_rom[(4*sqn)+1+0x400]<<16 | m_rom[(4*sqn)+2+0x400]<<8 | m_rom[(4*sqn)+3+0x400]; - m_channels[ch].seqdata = &m_rom[pptr]; - m_channels[ch].seqdelay = 0; - m_channels[ch].is_seq_playing = true; + uint8_t sqn = m_sequences[ch].sequence; + uint32_t pptr = get_seq_offs(sqn); + m_sequences[ch].data = &m_rom[pptr]; + m_sequences[ch].delay = 0; + m_sequences[ch].is_playing = true; } else { - m_channels[ch].is_seq_playing = false; + m_sequences[ch].is_playing = false; } - m_channels[ch].seqcontrol = data; + m_sequences[ch].loop = data & 1; break; default: @@ -373,3 +415,240 @@ void ymz770_device::internal_reg_write(uint8_t reg, uint8_t data) } } } + +//------------------------------------------------- +// ymz774_device +//------------------------------------------------- + +ymz774_device::ymz774_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : ymz770_device(mconfig, YMZ774, tag, owner, clock, 44100) +{ +} + +READ8_MEMBER(ymz774_device::read) +{ + if (offset & 1) + { + if (m_cur_reg == 0xe3 || m_cur_reg == 0xe4) + { + m_stream->update(); + uint8_t res = 0; + int bank = (m_cur_reg == 0xe3) ? 8 : 0; + for (int i = 0; i < 8; i++) + if (m_channels[i + bank].is_playing) + res |= 1 << i; + return res; + } + } + logerror("unimplemented read %02X\n", m_cur_reg); + return 0; +} + +void ymz774_device::internal_reg_write(uint8_t reg, uint8_t data) +{ + // playback registers + if (reg < 0x10) // phrase num H and L + { + int ch = ((reg >> 1) & 7) + m_bank * 8; + if (reg & 1) + m_channels[ch].phrase = (m_channels[ch].phrase & 0xff00) | data; + else + m_channels[ch].phrase = (m_channels[ch].phrase & 0x00ff) | ((data & 7) << 8); + } + else if (reg < 0x60) + { + int ch = (reg & 7) + m_bank * 8; + switch (reg & 0xf8) + { + case 0x10: // Volume 1 + m_channels[ch].volume = data; + break; + case 0x18: // Volume 1 delayed transition + if (data) logerror("unimplemented write %02X %02X\n", reg, data); + m_channels[ch].volume_delay = data; + break; + case 0x20: // Volume 2 + m_channels[ch].volume2 = data; + break; + case 0x28: // Pan L/R + m_channels[ch].pan = data; + break; + case 0x30: // Pan L/R delayed transition + if (data) logerror("unimplemented write %02X %02X\n", reg, data); + m_channels[ch].pan_delay = data; + break; + case 0x38: // Pan T/B + m_channels[ch].pan1 = data; + break; + case 0x40: // Pan T/B delayed transition + if (data) logerror("unimplemented write %02X %02X\n", reg, data); + m_channels[ch].pan1_delay = data; + break; + case 0x48: // Loop + m_channels[ch].loop = data; + break; + case 0x50: // Start / Stop + if (data) + { + int phrase = m_channels[ch].phrase; + m_channels[ch].atbl = m_rom[(4 * phrase) + 0] >> 4 & 7; + m_channels[ch].pptr = 8 * get_phrase_offs(phrase); + m_channels[ch].last_block = false; + + m_channels[ch].is_playing = true; + } + else + { + m_channels[ch].is_playing = false; + } + break; + case 0x58: // Pause / Resume + if (data) logerror("pause/resume unimplemented %02X %02X\n", reg, data); + break; + } + } + else if (reg < 0xd0) + { + if (m_bank == 0) + { + if (reg < 0xb0) + { + int sq = reg & 7; + switch (reg & 0xf8) + { + case 0x60: // sequence num H and L + case 0x68: + sq = (reg >> 1) & 7; + if (reg & 1) + m_sequences[sq].sequence = (m_sequences[sq].sequence & 0xff00) | data; + else + m_sequences[sq].sequence = (m_sequences[sq].sequence & 0x00ff) | ((data & 0x0f) << 8); // TODO check if total number really upto 0x1000 + break; + case 0x70: // Start / Stop + if (data) + { + uint32_t pptr = get_seq_offs(m_sequences[sq].sequence); + m_sequences[sq].data = &m_rom[pptr]; + m_sequences[sq].delay = 0; + m_sequences[sq].is_playing = true; + } + else + { + m_sequences[sq].is_playing = false; + } + break; + case 0x78: // Pause / Resume + if (data) logerror("SEQ pause/resume unimplemented %02X %02X\n", reg, data); + break; + case 0x80: // Loop count, 0 = off, 255 - infinite + m_sequences[sq].loop = data; + break; + case 0x88: // timer H and L + case 0x90: + sq = (reg >> 1) & 7; + if (reg & 1) + m_sequences[sq].timer = (m_sequences[sq].timer & 0xff00) | data; + else + m_sequences[sq].timer = (m_sequences[sq].timer & 0x00ff) | (data << 8); + break; + case 0x98: // Off trigger, bit4 = on/off, bits0-3 channel (end sequence when channel playback ends) + if (data) logerror("SEQ Off trigger unimplemented %02X %02X\n", reg, data); + break; + case 0xa0: // stop channel mask H and L, what it for ? stop chanels immediatelly or when sequence ends (so far assuming later) ? + case 0xa8: + sq = (reg >> 1) & 7; + if (reg & 1) + m_sequences[sq].stopchan = (m_sequences[sq].stopchan & 0xff00) | data; + else + m_sequences[sq].stopchan = (m_sequences[sq].stopchan & 0x00ff) | (data << 8); + break; + } + } + else + { + if (data) logerror("SQC unimplemented %02X %02X\n", reg, data); + } + } + // else bank1 - Equalizer control + } + // global registers + else + { + switch (reg) { + case 0xd0: + m_vlma = data; + break; + case 0xd1: + m_vlma1 = data; + break; + case 0xd2: + m_cpl = data; + break; + case 0xf0: + m_bank = data & 1; + if (data > 1) logerror("Set bank %02X!\n", data); + break; + } + } +} + +void ymz774_device::sequencer() +{ + for (int i = 0; i < 8; i++) + { + auto & sequence = m_sequences[i]; + if (sequence.is_playing) + { + if (sequence.delay > 0) + { + --sequence.delay; + } + else + { + int reg = *sequence.data++; + uint8_t data = *sequence.data++; + switch (reg) + { + case 0xff: // end + for (int ch = 0; ch < 16; ch++) // check this + if (sequence.stopchan & (1 << ch)) + m_channels[ch].is_playing = false; + if (sequence.loop) + { + if (sequence.loop != 255) + --sequence.loop; + uint32_t pptr = get_seq_offs(sequence.sequence); + sequence.data = &m_rom[pptr]; + } + else + { + sequence.is_playing = false; + } + break; + case 0xfe: // timer delay + sequence.delay = sequence.timer * 32; // possible needed -1 or +(32-1) + break; + case 0xf0: + sequence.bank = data & 1; + break; + default: + { + uint8_t temp = m_bank; + m_bank = sequence.bank; + if (m_bank == 0 && reg >= 0x60 && reg < 0xb0) // if we hit SEQ registers need to add this sequence offset + { + int sqn = i; + if (reg < 0x70 || (reg >= 0x88 && reg < 0x98) || reg >= 0xa0) + sqn = i * 2; + internal_reg_write(reg + sqn, data); + } + else + internal_reg_write(reg, data); + m_bank = temp; + } + break; + } + } + } + } +} diff --git a/src/devices/sound/ymz770.h b/src/devices/sound/ymz770.h index b7f047dc4b4..b640d780ef5 100644 --- a/src/devices/sound/ymz770.h +++ b/src/devices/sound/ymz770.h @@ -12,10 +12,6 @@ #pragma once //************************************************************************** -// CONSTANTS -//************************************************************************** - -//************************************************************************** // INTERFACE CONFIGURATION MACROS //************************************************************************** @@ -25,6 +21,12 @@ #define MCFG_YMZ770_REPLACE(_tag, _clock) \ MCFG_DEVICE_REPLACE(_tag, YMZ770, _clock) +#define MCFG_YMZ774_ADD(_tag, _clock) \ + MCFG_DEVICE_ADD(_tag, YMZ774, _clock) + +#define MCFG_YMZ774_REPLACE(_tag, _clock) \ + MCFG_DEVICE_REPLACE(_tag, YMZ774, _clock) + //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -49,26 +51,37 @@ protected: virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; - void internal_reg_write(uint8_t reg, uint8_t data); + virtual void internal_reg_write(uint8_t reg, uint8_t data); + virtual uint32_t get_phrase_offs(int phrase) { return m_rom[(4 * phrase) + 1] << 16 | m_rom[(4 * phrase) + 2] << 8 | m_rom[(4 * phrase) + 3]; }; + virtual uint32_t get_seq_offs(int sqn) { return m_rom[(4 * sqn) + 1 + 0x400] << 16 | m_rom[(4 * sqn) + 2 + 0x400] << 8 | m_rom[(4 * sqn) + 3 + 0x400]; }; + virtual void sequencer(); + + ymz770_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t sclock); sound_stream *m_stream; + uint32_t m_sclock; // data uint8_t m_cur_reg; uint8_t m_mute; // mute chip uint8_t m_doen; // digital output enable - uint8_t m_vlma; // overall AAM volume + uint8_t m_vlma; // overall volume L0/R0 + uint8_t m_vlma1; // overall volume L1/R1 uint8_t m_bsl; // boost level uint8_t m_cpl; // clip limiter required_region_ptr<uint8_t> m_rom; -private: struct ymz_channel { - uint8_t phrase; + uint16_t phrase; uint8_t pan; + uint8_t pan_delay; + uint8_t pan1; + uint8_t pan1_delay; uint8_t volume; - uint8_t control; + uint8_t volume_delay; + uint8_t volume2; + uint8_t loop; bool is_playing, last_block; @@ -79,19 +92,43 @@ private: int output_ptr; int atbl; int pptr; - - uint8_t sequence; - uint8_t seqcontrol; - uint8_t seqdelay; - uint8_t *seqdata; - bool is_seq_playing; + }; + struct ymz_sequence + { + uint32_t delay; + uint16_t sequence; + uint16_t timer; + uint16_t stopchan; + uint8_t loop; + uint8_t *data; + uint8_t bank; + bool is_playing; }; - ymz_channel m_channels[8]; + ymz_channel m_channels[16]; + ymz_sequence m_sequences[8]; }; +// ======================> ymz774_device + +class ymz774_device : public ymz770_device +{ +public: + // construction/destruction + ymz774_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ8_MEMBER(read); +protected: + virtual void internal_reg_write(uint8_t reg, uint8_t data) override; + virtual uint32_t get_phrase_offs(int phrase) override { int ph = phrase * 4; return ((m_rom[ph] & 0x0f) << 24 | m_rom[ph + 1] << 16 | m_rom[ph + 2] << 8 | m_rom[ph + 3]) * 2; }; + virtual uint32_t get_seq_offs(int sqn) override { int sq = sqn * 4 + 0x2000; return ((m_rom[sq] & 0x0f) << 24 | m_rom[sq + 1] << 16 | m_rom[sq + 2] << 8 | m_rom[sq + 3]) * 2; }; + virtual void sequencer() override; +private: + int m_bank; +}; // device type definition DECLARE_DEVICE_TYPE(YMZ770, ymz770_device) +DECLARE_DEVICE_TYPE(YMZ774, ymz774_device) #endif // MAME_SOUND_YMZ770_H diff --git a/src/devices/video/bt459.cpp b/src/devices/video/bt459.cpp index b9ae57ab813..4bf7d4c5236 100644 --- a/src/devices/video/bt459.cpp +++ b/src/devices/video/bt459.cpp @@ -10,12 +10,8 @@ * Reference: http://www.bitsavers.org/components/brooktree/_dataBooks/1991_Brooktree_Product_Databook.pdf * * TODO - * - blink masking and blinking * - pixel pan and zoom - * - dual cursor logic - * - X Windows modes * - overlay/underlay - * - optimisation */ #include "emu.h" @@ -72,10 +68,13 @@ void bt459_device::device_start() save_item(NAME(m_cursor_ram)); save_item(NAME(m_palette_ram)); + + save_item(NAME(m_blink_start)); } void bt459_device::device_reset() { + m_blink_start = -1; } /* @@ -274,6 +273,9 @@ WRITE8_MEMBER(bt459_device::register_w) (data & CR0302) == CR0302_3232 ? "32 on 32 off" : (data & CR0302) == CR0302_1616 ? "16 on 16 off" : "16 on 48 off", 8 >> (data & CR0100)); + + // reset the blink timer + m_blink_start = -1; break; case REG_COMMAND_1: @@ -489,60 +491,80 @@ WRITE8_MEMBER(bt459_device::palette_w) void bt459_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, u8 *pixel_data) { - // draw pixel data + // initialise the blink timer + if (m_blink_start > screen.frame_number()) + m_blink_start = screen.frame_number(); + + // compute the blink state according to the programmed duty cycle + const bool blink_state = ((screen.frame_number() - m_blink_start) & ( + (m_command_0 & CR0302) == CR0302_1616 ? 0x10 : + (m_command_0 & CR0302) == CR0302_3232 ? 0x20 : + (m_command_0 & CR0302) == CR0302_6464 ? 0x40 : 0x30)) == 0; + + // compute the pixel mask from the pixel read mask and blink mask/state + const u8 pixel_mask = m_pixel_read_mask & (blink_state ? 0xffU : ~m_pixel_blink_mask); + + // draw visible pixel data switch (m_command_0 & CR0100) { case CR0100_1BPP: - for (int y = 0; y < screen.height(); y++) - for (int x = 0; x < screen.width(); x += 8) + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 8) { u8 data = *pixel_data++; - bitmap.pix(y, x + 7) = get_rgb(data & 0x1); data >>= 1; - bitmap.pix(y, x + 6) = get_rgb(data & 0x1); data >>= 1; - bitmap.pix(y, x + 5) = get_rgb(data & 0x1); data >>= 1; - bitmap.pix(y, x + 4) = get_rgb(data & 0x1); data >>= 1; - bitmap.pix(y, x + 3) = get_rgb(data & 0x1); data >>= 1; - bitmap.pix(y, x + 2) = get_rgb(data & 0x1); data >>= 1; - bitmap.pix(y, x + 1) = get_rgb(data & 0x1); data >>= 1; - bitmap.pix(y, x + 0) = get_rgb(data & 0x1); + bitmap.pix(y, x + 7) = get_rgb(data & 0x1, pixel_mask); data >>= 1; + bitmap.pix(y, x + 6) = get_rgb(data & 0x1, pixel_mask); data >>= 1; + bitmap.pix(y, x + 5) = get_rgb(data & 0x1, pixel_mask); data >>= 1; + bitmap.pix(y, x + 4) = get_rgb(data & 0x1, pixel_mask); data >>= 1; + bitmap.pix(y, x + 3) = get_rgb(data & 0x1, pixel_mask); data >>= 1; + bitmap.pix(y, x + 2) = get_rgb(data & 0x1, pixel_mask); data >>= 1; + bitmap.pix(y, x + 1) = get_rgb(data & 0x1, pixel_mask); data >>= 1; + bitmap.pix(y, x + 0) = get_rgb(data & 0x1, pixel_mask); } break; case CR0100_2BPP: - for (int y = 0; y < screen.height(); y++) - for (int x = 0; x < screen.width(); x += 4) + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 4) { u8 data = *pixel_data++; - bitmap.pix(y, x + 3) = get_rgb(data & 0x3); data >>= 2; - bitmap.pix(y, x + 2) = get_rgb(data & 0x3); data >>= 2; - bitmap.pix(y, x + 1) = get_rgb(data & 0x3); data >>= 2; - bitmap.pix(y, x + 0) = get_rgb(data & 0x3); + bitmap.pix(y, x + 3) = get_rgb(data & 0x3, pixel_mask); data >>= 2; + bitmap.pix(y, x + 2) = get_rgb(data & 0x3, pixel_mask); data >>= 2; + bitmap.pix(y, x + 1) = get_rgb(data & 0x3, pixel_mask); data >>= 2; + bitmap.pix(y, x + 0) = get_rgb(data & 0x3, pixel_mask); } break; case CR0100_4BPP: - for (int y = 0; y < screen.height(); y++) - for (int x = 0; x < screen.width(); x += 2) + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x += 2) { u8 data = *pixel_data++; - bitmap.pix(y, x + 1) = get_rgb(data & 0x7); data >>= 4; - bitmap.pix(y, x + 0) = get_rgb(data & 0x7); + bitmap.pix(y, x + 1) = get_rgb(data & 0x7, pixel_mask); data >>= 4; + bitmap.pix(y, x + 0) = get_rgb(data & 0x7, pixel_mask); } break; case CR0100_8BPP: - for (int y = 0; y < screen.height(); y++) - for (int x = 0; x < screen.width(); x++) - bitmap.pix(y, x) = get_rgb(*pixel_data++); + for (int y = screen.visible_area().min_y; y <= screen.visible_area().max_y; y++) + for (int x = screen.visible_area().min_x; x <= screen.visible_area().max_x; x++) + bitmap.pix(y, x) = get_rgb(*pixel_data++, pixel_mask); break; } - // draw cursors - if (m_cursor_command & (CR47 | CR46 | CR45 | CR44)) + // draw cursors when visible and not blinked off + if ((m_cursor_command & (CR47 | CR46 | CR45 | CR44)) && ((m_cursor_command & CR40) == 0 || blink_state)) { + // get 64x64 bitmap and cross hair cursor plane enable + const u8 bm_cursor_enable = (m_cursor_command & (CR47 | CR46)) >> 6; + const u8 ch_cursor_enable = (m_cursor_command & (CR45 | CR44)) >> 4; + + // get cross hair cursor half thickness + const int ch_thickness = (m_cursor_command & CR4241) >> 1; + /* * The cursor (x) value to be written is calculated as follows: * @@ -550,9 +572,10 @@ void bt459_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co * * where * - * P = 37 if 1:1 input multiplexing, 52 if 4:1 input multiplexing, 57 if 5:1 input multiplexing - * H = number of pixels between the first rising edge of LD* following the falling edge of HSYNC* - * to active video + * P = 37 if 1:1 input multiplexing, 52 if 4:1 input multiplexing, + * 57 if 5:1 input multiplexing + * H = number of pixels between the first rising edge of LD* + * following the falling edge of HSYNC* to active video * * The cursor (y) value to be written is calculated as follows: * @@ -560,63 +583,67 @@ void bt459_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co * * where * - * V = number of scan lines from the second sync pulse during vertical blanking to active video + * V = number of scan lines from the second sync pulse during + * vertical blanking to active video * - * Values from $0FC0 (-64) to $0FBF (+4031) may be loaded into the cursor(y) register. The negative values ($0FC0 - * to $0FFF) are used in situations where V < 32, and the cursor must be moved off the top of the screen. + * Values from $0FC0 (-64) to $0FBF (+4031) may be loaded into the + * cursor (y) register. The negative values ($0FC0 to $0FFF) are used + * in situations where V < 32, and the cursor must be moved off the + * top of the screen. */ - const int cursor_x = m_cursor_x - screen.visible_area().min_x + ( + const int cursor_x = m_cursor_x + ( (m_command_0 & CR0706) == CR0706_11MPX ? 37 : (m_command_0 & CR0706) == CR0706_41MPX ? 52 : (m_command_0 & CR0706) == CR0706_51MPX ? 57 : 0); - const int cursor_y = (m_cursor_y < 0xfc0 ? m_cursor_y : m_cursor_y - 0x1000) - screen.visible_area().min_y + 32; + const int cursor_y = (m_cursor_y < 0xfc0 ? m_cursor_y : m_cursor_y - 0x1000) + 32; - // 64x64 cursor - if (m_cursor_command & (CR47 | CR46)) + // 64x64 bitmap cursor + if (bm_cursor_enable) { // compute target 64x64 rectangle rectangle cursor(cursor_x - 31, cursor_x + 32, cursor_y - 31, cursor_y + 32); - // intersect with bitmap + // intersect with screen bitmap cursor &= bitmap.cliprect(); // draw if any portion is visible if (!cursor.empty()) { - const u8 cursor_mask = ((m_cursor_command & CR47) ? 0x2 : 0) | ((m_cursor_command & CR46) ? 0x1 : 0); - int cursor_offset = 0; + for (int y = 0; y < 64; y++) + { + // get screen y pixel coordinate + const int ypos = cursor_y - 31 + y; - for (int y = cursor_y - 31; y <= cursor_y + 32; y++) - for (int x = cursor_x - 31; x <= cursor_x + 32; x += 4) + for (int x = 0; x < 64; x++) { - // fetch 4x2 bits of cursor data - u8 data = m_cursor_ram[cursor_offset++]; - int cursor_color; - - // write cursor pixels which are visible - if ((cursor_color = ((data >>= 0) & cursor_mask)) && cursor.contains(x + 3, y)) - bitmap.pix(y, x + 3) = m_cursor_color[cursor_color - 1]; - - if ((cursor_color = ((data >>= 2) & cursor_mask)) && cursor.contains(x + 2, y)) - bitmap.pix(y, x + 2) = m_cursor_color[cursor_color - 1]; - - if ((cursor_color = ((data >>= 2) & cursor_mask)) && cursor.contains(x + 1, y)) - bitmap.pix(y, x + 1) = m_cursor_color[cursor_color - 1]; - - if ((cursor_color = ((data >>= 2) & cursor_mask)) && cursor.contains(x + 0, y)) - bitmap.pix(y, x + 0) = m_cursor_color[cursor_color - 1]; + // get screen x pixel coordinate + const int xpos = cursor_x - 31 + x; + + // check if pixel is visible + if (cursor.contains(xpos, ypos)) + { + // retrieve 2 bits of 64x64 bitmap cursor data + u8 data = (m_cursor_ram[y * 16 + (x >> 2)] >> ((3 - (x & 3)) << 1)) & bm_cursor_enable; + + // check for dual-cursor mode and combine with cross-hair data + if (ch_cursor_enable) + if (((x >= 31 - ch_thickness) && (x <= 31 + ch_thickness)) || ((y >= 31 - ch_thickness) && (y <= 31 + ch_thickness))) + data = (m_cursor_command & CR43) ? data | ch_cursor_enable : data ^ ch_cursor_enable; + + // write cursor data to screen (normal or X Window mode) + if (data && !((m_command_2 & CR21) && data == 1)) + bitmap.pix(ypos, xpos) = m_cursor_color[data - 1]; + } } + } } } // cross hair cursor - if (m_cursor_command & (CR45 | CR44)) + if (ch_cursor_enable) { // get the cross hair cursor color - const rgb_t cursor_color = m_cursor_color[(((m_cursor_command & CR45) ? 0x2 : 0) | ((m_cursor_command & CR44) ? 0x1 : 0)) - 1]; - - // get half the cross hair line thickness - const int thickness = (m_cursor_command & CR4241) >> 1; + const rgb_t ch_color = m_cursor_color[ch_cursor_enable - 1]; /* * The window (x) value to be written is calculated as follows: @@ -625,9 +652,10 @@ void bt459_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co * * where * - * P = 5 if 1:1 input multiplexing, 20 if 4:1 input multiplexing, 25 if 5:1 input multiplexing - * H = number of pixels between the first rising edge of LD* following the falling edge of HSYNC* - * to active video + * P = 5 if 1:1 input multiplexing, 20 if 4:1 input multiplexing, + * 25 if 5:1 input multiplexing + * H = number of pixels between the first rising edge of LD* + * following the falling edge of HSYNC* to active video * * The window (y) value to be written is calculated as follows: * @@ -635,47 +663,80 @@ void bt459_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, co * * where * - * V = number of scan lines from the second sync pulse during vertical blanking to active video + * V = number of scan lines from the second sync pulse during + * vertical blanking to active video * - * Values from $0000 to $0FFF may be written to the window (x) and (y) registers. A full-screen cross hair - * is implemented by loading the window (x,y) registers with $0000, and the window width and height registers with - * $0FFF. + * Values from $0000 to $0FFF may be written to the window (x) and + * (y) registers. A full-screen cross hair is implemented by + * loading the window (x,y) registers with $0000, and the window + * width and height registers with $0FFF. */ - const int window_x = m_window_x - screen.visible_area().min_x + ( + const bool full_screen = (m_window_x == 0 && m_window_y == 0 && m_window_w == 0x0fff && m_window_h == 0x0fff); + const int window_x = full_screen ? screen.visible_area().min_x : m_window_x + ( (m_command_0 & CR0706) == CR0706_11MPX ? 5 : (m_command_0 & CR0706) == CR0706_41MPX ? 20 : (m_command_0 & CR0706) == CR0706_51MPX ? 25 : 0); - const int window_y = m_window_y - screen.visible_area().min_y; + const int window_y = full_screen ? screen.visible_area().min_y : m_window_y; /* - * The actual window width is 2, 8 or 10 pixels more than the value specified by the window width register, depending - * on whether 1:1, 4:1 or 5:1 input multiplexing is specified. The actual window height is 2 pixels more than the - * value specified by the window height register. Therefore, the minimum window width is 2, 8 or 10 pixels for 1:1, - * 4:1 and 5:1 multiplexing, respectively. The minimum window height is 2 pixels. + * The actual window width is 2, 8 or 10 pixels more than the + * value specified by the window width register, depending on + * whether 1:1, 4:1 or 5:1 input multiplexing is specified. The + * actual window height is 2 pixels more than the value specified + * by the window height register. Therefore, the minimum window + * width is 2, 8 or 10 pixels for 1:1, 4:1 and 5:1 multiplexing, + * respectively. The minimum window height is 2 pixels. + * + * Values from $0000 to $0FFF may be written to the window width + * and height registers. * - * Values from $0000 to $0FFF may be written to the window width and height registers. + * Note: testing indicates the cross-hair cursor should be drawn + * strictly inside the window, although this is not 100% clear from + * the documentation. */ - const int window_w = m_window_w + ( + const int window_w = full_screen ? screen.visible_area().width() : m_window_w + ( (m_command_0 & CR0706) == CR0706_11MPX ? 2 : (m_command_0 & CR0706) == CR0706_41MPX ? 8 : (m_command_0 & CR0706) == CR0706_51MPX ? 10 : 0); - const int window_h = m_window_h + 2; - - // draw the vertical line - rectangle vertical(cursor_x - thickness, cursor_x + thickness, window_y, window_y + window_h); - - vertical &= bitmap.cliprect(); + const int window_h = full_screen ? screen.visible_area().height() : m_window_h + 2; - if (!vertical.empty()) - bitmap.fill(cursor_color, vertical); - - // draw the horizontal line - rectangle horizontal(window_x, window_x + window_w, cursor_y - thickness, cursor_y + thickness); + // check for dual-cursor mode + if (bm_cursor_enable) + { + // draw the cross hair cursor as vertical and horizontal filled rectangles broken by the 64x64 cursor area + rectangle v1(cursor_x - ch_thickness, cursor_x + ch_thickness, window_y + 1, cursor_y - 32); + rectangle v2(cursor_x - ch_thickness, cursor_x + ch_thickness, cursor_y + 33, window_y + window_h); + rectangle h1(window_x + 1, cursor_x - 32, cursor_y - ch_thickness, cursor_y + ch_thickness); + rectangle h2(cursor_x + 33, window_x + window_w, cursor_y - ch_thickness, cursor_y + ch_thickness); + + v1 &= bitmap.cliprect(); + v2 &= bitmap.cliprect(); + h1 &= bitmap.cliprect(); + h2 &= bitmap.cliprect(); + + if (!v1.empty()) + bitmap.fill(ch_color, v1); + if (!v2.empty()) + bitmap.fill(ch_color, v2); + if (!h1.empty()) + bitmap.fill(ch_color, h1); + if (!h2.empty()) + bitmap.fill(ch_color, h2); + } + else + { + // draw the cross hair cursor as unbroken vertical and horizontal filled rectangles + rectangle v(cursor_x - ch_thickness, cursor_x + ch_thickness, window_y + 1, window_y + window_h); + rectangle h(window_x + 1, window_x + window_w, cursor_y - ch_thickness, cursor_y + ch_thickness); - horizontal &= bitmap.cliprect(); + v &= bitmap.cliprect(); + h &= bitmap.cliprect(); - if (!horizontal.empty()) - bitmap.fill(cursor_color, horizontal); + if (!v.empty()) + bitmap.fill(ch_color, v); + if (!h.empty()) + bitmap.fill(ch_color, h); + } } } } diff --git a/src/devices/video/bt459.h b/src/devices/video/bt459.h index cc1e67c3161..78cdc5a2579 100644 --- a/src/devices/video/bt459.h +++ b/src/devices/video/bt459.h @@ -202,7 +202,7 @@ private: // helper functions u8 get_component(rgb_t *arr, int index); void set_component(rgb_t *arr, int index, u8 data); - u32 get_rgb(u8 data) const { return m_palette_ram[data & m_pixel_read_mask]; } + u32 get_rgb(u8 data, u8 mask) const { return m_palette_ram[data & mask]; } // device state in memory map order u16 m_address; @@ -237,6 +237,8 @@ private: u8 m_cursor_ram[1024]; rgb_t m_palette_ram[BT459_PIXEL_COLORS]; + + u64 m_blink_start; }; DECLARE_DEVICE_TYPE(BT459, bt459_device) diff --git a/src/devices/video/crt9007.cpp b/src/devices/video/crt9007.cpp index b68317a7b57..9eba3705e4f 100644 --- a/src/devices/video/crt9007.cpp +++ b/src/devices/video/crt9007.cpp @@ -45,7 +45,7 @@ // DEVICE DEFINITIONS //************************************************************************** -DEFINE_DEVICE_TYPE(CRT9007, crt9007_device, "crt9007", "SMC SRT9007 VPAC") +DEFINE_DEVICE_TYPE(CRT9007, crt9007_device, "crt9007", "SMC CRT9007 VPAC") diff --git a/src/devices/video/hd63484.cpp b/src/devices/video/hd63484.cpp index 854222d1efe..0b383bd927b 100644 --- a/src/devices/video/hd63484.cpp +++ b/src/devices/video/hd63484.cpp @@ -367,7 +367,7 @@ const tiny_rom_entry *hd63484_device::device_rom_region() const inline uint16_t hd63484_device::readword(offs_t address) { - return space().read_word(address << 1); + return space().read_word(address); } @@ -377,7 +377,7 @@ inline uint16_t hd63484_device::readword(offs_t address) inline void hd63484_device::writeword(offs_t address, uint16_t data) { - space().write_word(address << 1, data); + space().write_word(address, data); } diff --git a/src/devices/video/i8275.cpp b/src/devices/video/i8275.cpp index 99081d83d59..ee146c92519 100644 --- a/src/devices/video/i8275.cpp +++ b/src/devices/video/i8275.cpp @@ -584,8 +584,8 @@ WRITE8_MEMBER( i8275_device::dack_w ) } else { - assert(m_buffer_idx >= 0 && m_buffer_idx < ARRAY_LENGTH(m_buffer[m_buffer_dma])); - m_buffer[m_buffer_dma][m_buffer_idx++] = data; + if (m_buffer_idx < ARRAY_LENGTH(m_buffer[m_buffer_dma])) + m_buffer[m_buffer_dma][m_buffer_idx++] = data; if (!VISIBLE_FIELD_ATTRIBUTE && ((data & 0xc0) == 0x80)) { diff --git a/src/devices/video/imagetek_i4100.cpp b/src/devices/video/imagetek_i4100.cpp new file mode 100644 index 00000000000..1897f5951fc --- /dev/null +++ b/src/devices/video/imagetek_i4100.cpp @@ -0,0 +1,1190 @@ +// license:BSD-3-Clause +// copyright-holders:Luca Elia,David Haywood,Angelo Salese +/*************************************************************************** + + Imagetek I4100 / I4220 / I4300 device files + + device emulation by Angelo Salese, based off from original metro.cpp + implementation by Luca Elia & David Haywood + + TODO: + - interrupt enable/acknowledge/vector; + - soundlatch delegate; + - inputs for i4300; + - hyprduel.cpp uses scanline attribute which crawls to unusable state + with current video routines here; + - CRT Controller, also understand why it needs so many writes before actual parameters; + - Wrong color bars in service mode (e.g. balcube, toride2g). They use solid color tiles (80xx), + but the right palette is not at 00-ff. + Related to the unknown table in the RAM mapped just before the palette? + Update: the colors should have a common bank of 0xb (so 0x8bxx), it's unknown why the values + diverges, the blitter is responsible of that upload fwiw; + - Some gfx problems in ladykill, 3kokushi, puzzli, gakusai, seem related to how we handle + windows, wrapping, read-modify-write areas; + - puzzli: emulate hblank irq and fix video routines here (water effect not emulated?); + +============================================================================ + + driver by Luca Elia (l.elia@tin.it) + + [ 3 Scrolling Layers ] + + There is memory for a huge layer, but the actual tilemap + is a smaller window (of fixed size) carved from anywhere + inside that layer. + + Tile Size: 8 x 8 x 4 + (later games can switch to 8 x 8 x 8, 16 x 16 x 4/8 at run time) + + Big Layer Size: 2048 x 2048 (8x8 tiles) or 4096 x 4096 (16x16 tiles) + + Tilemap Window Size: 512 x 256 (8x8 tiles) or 1024 x 512 (16x16 tiles) + + The tile codes in memory do not map directly to tiles. They + are indexes into a table (with 0x200 entries) that defines + a virtual set of tiles for the 3 layers. Each entry in that + table adds 16 tiles to the set of available tiles, and decides + their color code. + + Tile code with their msbit set are different as they mean: + draw a tile filled with a single color (0-fff) + + + [ 512 Zooming Sprites ] + + The sprites are NOT tile based: the "tile" size can vary from + 8 to 64 (independently for width and height) with an 8 pixel + granularity. The "tile" address is a multiple of 8x8 pixels. + + Each sprite can be shrinked to ~1/4 or enlarged to ~32x following + an exponential curve of sizes (with one zoom value for both width + and height) + + +***************************************************************************/ + +#include "emu.h" +#include "imagetek_i4100.h" + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(I4100, imagetek_i4100_device, "i4100", "Imagetek I4100 052 VDP") +DEFINE_DEVICE_TYPE(I4220, imagetek_i4220_device, "i4220", "Imagetek I4220 071 VDP") +DEFINE_DEVICE_TYPE(I4300, imagetek_i4300_device, "i4300", "Imagetek I4300 095 VDP") + +DEVICE_ADDRESS_MAP_START( map, 16, imagetek_i4100_device) + AM_RANGE(0x00000, 0x1ffff) AM_READWRITE(vram_0_r, vram_0_w) AM_SHARE("vram_0") + AM_RANGE(0x20000, 0x3ffff) AM_READWRITE(vram_1_r, vram_1_w) AM_SHARE("vram_1") + AM_RANGE(0x40000, 0x5ffff) AM_READWRITE(vram_2_r, vram_2_w) AM_SHARE("vram_2") + AM_RANGE(0x60000, 0x6ffff) AM_READ(gfxrom_r) + AM_RANGE(0x70000, 0x71fff) AM_READWRITE(scratchram_r, scratchram_w) AM_SHARE("scratchram") // unknown, maybe palette + AM_RANGE(0x72000, 0x73fff) AM_DEVREADWRITE("palette", palette_device, read, write) AM_SHARE("palette") + AM_RANGE(0x74000, 0x74fff) AM_READWRITE(spriteram_r, spriteram_w) AM_SHARE("spriteram") + AM_RANGE(0x75000, 0x75fff) AM_READWRITE(rmw_vram_0_r, rmw_vram_0_w) + AM_RANGE(0x76000, 0x76fff) AM_READWRITE(rmw_vram_1_r, rmw_vram_1_w) + AM_RANGE(0x77000, 0x77fff) AM_READWRITE(rmw_vram_2_r, rmw_vram_2_w) + AM_RANGE(0x78000, 0x787ff) AM_READWRITE(tiletable_r, tiletable_w) AM_SHARE("tiletable") + // video registers + AM_RANGE(0x78800, 0x78801) AM_READWRITE(sprite_count_r, sprite_count_w) + AM_RANGE(0x78802, 0x78803) AM_READWRITE(sprite_priority_r, sprite_priority_w) + AM_RANGE(0x78804, 0x78805) AM_READWRITE(sprite_yoffset_r, sprite_yoffset_w) + AM_RANGE(0x78806, 0x78807) AM_READWRITE(sprite_xoffset_r, sprite_xoffset_w) + AM_RANGE(0x78808, 0x78809) AM_READWRITE(sprite_color_code_r, sprite_color_code_w) + AM_RANGE(0x78810, 0x78811) AM_READWRITE(layer_priority_r, layer_priority_w) + AM_RANGE(0x78812, 0x78813) AM_READWRITE(background_color_r, background_color_w) + + AM_RANGE(0x78840, 0x7884d) AM_WRITE(blitter_w) AM_SHARE("blitter_regs") + AM_RANGE(0x78850, 0x78851) AM_READWRITE(screen_yoffset_r, screen_yoffset_w) + AM_RANGE(0x78852, 0x78853) AM_READWRITE(screen_xoffset_r, screen_xoffset_w) + AM_RANGE(0x78860, 0x7886b) AM_READWRITE(window_r, window_w) AM_SHARE("windowregs") + AM_RANGE(0x78870, 0x7887b) AM_READWRITE(scroll_r, scroll_w) AM_SHARE("scrollregs") + + AM_RANGE(0x78880, 0x78881) AM_WRITE(crtc_vert_w) + AM_RANGE(0x78890, 0x78891) AM_WRITE(crtc_horz_w) + AM_RANGE(0x788a0, 0x788a1) AM_WRITE(crtc_unlock_w) + AM_RANGE(0x788aa, 0x788ab) AM_WRITE(rombank_w) + AM_RANGE(0x788ac, 0x788ad) AM_WRITE(screen_ctrl_w) +ADDRESS_MAP_END + +// same as above but with moved video registers (now at 0x797**) +DEVICE_ADDRESS_MAP_START( v2_map, 16, imagetek_i4220_device) + AM_RANGE(0x00000, 0x1ffff) AM_READWRITE(vram_0_r, vram_0_w) AM_SHARE("vram_0") + AM_RANGE(0x20000, 0x3ffff) AM_READWRITE(vram_1_r, vram_1_w) AM_SHARE("vram_1") + AM_RANGE(0x40000, 0x5ffff) AM_READWRITE(vram_2_r, vram_2_w) AM_SHARE("vram_2") + AM_RANGE(0x60000, 0x6ffff) AM_READ(gfxrom_r) + AM_RANGE(0x70000, 0x71fff) AM_READWRITE(scratchram_r, scratchram_w) AM_SHARE("scratchram") // unknown, maybe palette + AM_RANGE(0x72000, 0x73fff) AM_DEVREADWRITE("palette", palette_device, read, write) AM_SHARE("palette") + AM_RANGE(0x74000, 0x74fff) AM_READWRITE(spriteram_r, spriteram_w) AM_SHARE("spriteram") + AM_RANGE(0x75000, 0x75fff) AM_READWRITE(rmw_vram_0_r, rmw_vram_0_w) + AM_RANGE(0x76000, 0x76fff) AM_READWRITE(rmw_vram_1_r, rmw_vram_1_w) + AM_RANGE(0x77000, 0x77fff) AM_READWRITE(rmw_vram_2_r, rmw_vram_2_w) + AM_RANGE(0x78000, 0x787ff) AM_READWRITE(tiletable_r, tiletable_w) AM_SHARE("tiletable") + + AM_RANGE(0x78840, 0x7884d) AM_WRITE(blitter_w) AM_SHARE("blitter_regs") + AM_RANGE(0x78850, 0x78851) AM_READWRITE(screen_yoffset_r, screen_yoffset_w) + AM_RANGE(0x78852, 0x78853) AM_READWRITE(screen_xoffset_r, screen_xoffset_w) + AM_RANGE(0x78860, 0x7886b) AM_READWRITE(window_r, window_w) AM_SHARE("windowregs") + AM_RANGE(0x78870, 0x7887b) AM_READWRITE(scroll_r, scroll_w) AM_SHARE("scrollregs") + + AM_RANGE(0x78880, 0x78881) AM_WRITE(crtc_vert_w) + AM_RANGE(0x78890, 0x78891) AM_WRITE(crtc_horz_w) + AM_RANGE(0x788a0, 0x788a1) AM_WRITE(crtc_unlock_w) + AM_RANGE(0x788aa, 0x788ab) AM_WRITE(rombank_w) + AM_RANGE(0x788ac, 0x788ad) AM_WRITE(screen_ctrl_w) + + // video registers + AM_RANGE(0x79700, 0x79701) AM_READWRITE(sprite_count_r, sprite_count_w) + AM_RANGE(0x79702, 0x79703) AM_READWRITE(sprite_priority_r, sprite_priority_w) + AM_RANGE(0x79704, 0x79705) AM_READWRITE(sprite_yoffset_r, sprite_yoffset_w) + AM_RANGE(0x79706, 0x79707) AM_READWRITE(sprite_xoffset_r, sprite_xoffset_w) + AM_RANGE(0x79708, 0x79709) AM_READWRITE(sprite_color_code_r, sprite_color_code_w) + AM_RANGE(0x79710, 0x79711) AM_READWRITE(layer_priority_r, layer_priority_w) + AM_RANGE(0x79712, 0x79713) AM_READWRITE(background_color_r, background_color_w) + // repeated here in Puzzlet compatibility mode + AM_RANGE(0x78800, 0x78801) AM_READWRITE(sprite_count_r, sprite_count_w) + // ... this one breaks Blazing Tornado tho +// AM_RANGE(0x78802, 0x78803) AM_READWRITE(sprite_priority_r, sprite_priority_w) + AM_RANGE(0x78804, 0x78805) AM_READWRITE(sprite_yoffset_r, sprite_yoffset_w) + AM_RANGE(0x78806, 0x78807) AM_READWRITE(sprite_xoffset_r, sprite_xoffset_w) + AM_RANGE(0x78808, 0x78809) AM_READWRITE(sprite_color_code_r, sprite_color_code_w) + AM_RANGE(0x78810, 0x78811) AM_READWRITE(layer_priority_r, layer_priority_w) + AM_RANGE(0x78812, 0x78813) AM_READWRITE(background_color_r, background_color_w) +ADDRESS_MAP_END + +// more changes around, namely the screen offsets being reversed here +DEVICE_ADDRESS_MAP_START( v3_map, 16, imagetek_i4300_device) + AM_RANGE(0x00000, 0x1ffff) AM_READWRITE(vram_0_r, vram_0_w) AM_SHARE("vram_0") + AM_RANGE(0x20000, 0x3ffff) AM_READWRITE(vram_1_r, vram_1_w) AM_SHARE("vram_1") + AM_RANGE(0x40000, 0x5ffff) AM_READWRITE(vram_2_r, vram_2_w) AM_SHARE("vram_2") + AM_RANGE(0x60000, 0x6ffff) AM_READ(gfxrom_r) + AM_RANGE(0x70000, 0x71fff) AM_READWRITE(scratchram_r, scratchram_w) AM_SHARE("scratchram") // unknown, maybe palette + AM_RANGE(0x72000, 0x73fff) AM_DEVREADWRITE("palette", palette_device, read, write) AM_SHARE("palette") + AM_RANGE(0x74000, 0x74fff) AM_READWRITE(spriteram_r, spriteram_w) AM_SHARE("spriteram") + AM_RANGE(0x75000, 0x75fff) AM_READWRITE(rmw_vram_0_r, rmw_vram_0_w) + AM_RANGE(0x76000, 0x76fff) AM_READWRITE(rmw_vram_1_r, rmw_vram_1_w) + AM_RANGE(0x77000, 0x77fff) AM_READWRITE(rmw_vram_2_r, rmw_vram_2_w) + AM_RANGE(0x78000, 0x787ff) AM_READWRITE(tiletable_r, tiletable_w) AM_SHARE("tiletable") + AM_RANGE(0x78808, 0x78809) AM_READWRITE(screen_xoffset_r, screen_xoffset_w) + AM_RANGE(0x7880a, 0x7880b) AM_READWRITE(screen_yoffset_r, screen_yoffset_w) + AM_RANGE(0x7880e, 0x7880f) AM_WRITE(screen_ctrl_w) // TODO: can be read back here (gakusai) + + AM_RANGE(0x78800, 0x78801) AM_WRITE(crtc_unlock_w) + AM_RANGE(0x78802, 0x78803) AM_WRITE(crtc_horz_w) + AM_RANGE(0x78804, 0x78805) AM_WRITE(crtc_vert_w) + + AM_RANGE(0x78840, 0x7884d) AM_WRITE(blitter_w) AM_SHARE("blitter_regs") + AM_RANGE(0x78850, 0x7885b) AM_READWRITE(scroll_r, scroll_w) AM_SHARE("scrollregs") + AM_RANGE(0x78860, 0x7886b) AM_READWRITE(window_r, window_w) AM_SHARE("windowregs") + AM_RANGE(0x78870, 0x78871) AM_WRITE(rombank_w) + + // video registers + AM_RANGE(0x79700, 0x79701) AM_READWRITE(sprite_count_r, sprite_count_w) + AM_RANGE(0x79702, 0x79703) AM_READWRITE(sprite_priority_r, sprite_priority_w) + AM_RANGE(0x79704, 0x79705) AM_READWRITE(sprite_yoffset_r, sprite_yoffset_w) + AM_RANGE(0x79706, 0x79707) AM_READWRITE(sprite_xoffset_r, sprite_xoffset_w) + AM_RANGE(0x79708, 0x79709) AM_READWRITE(sprite_color_code_r, sprite_color_code_w) + AM_RANGE(0x79710, 0x79711) AM_READWRITE(layer_priority_r, layer_priority_w) + AM_RANGE(0x79712, 0x79713) AM_READWRITE(background_color_r, background_color_w) +ADDRESS_MAP_END + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// i4100_device - constructor +//------------------------------------------------- + + +imagetek_i4100_device::imagetek_i4100_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool has_ext_tiles) + : device_t(mconfig, type, tag, owner, clock) + , device_video_interface(mconfig, *this) + , m_vram_0(*this, "vram_0") + , m_vram_1(*this, "vram_1") + , m_vram_2(*this, "vram_2") + , m_scratchram(*this, "scratchram") + , m_blitter_regs(*this, "blitter_regs") + , m_spriteram(*this, "spriteram") + , m_tiletable(*this, "tiletable") + , m_window(*this, "windowregs") + , m_scroll(*this, "scrollregs") + , m_palette(*this, "palette") + , m_gfxdecode(*this, finder_base::DUMMY_TAG) + , m_gfxrom(*this, "^gfx1") + , m_blit_irq_cb(*this) + , m_support_8bpp( has_ext_tiles ) + , m_support_16x16( has_ext_tiles ) + , m_tilemap_scrolldx{0, 0, 0} + , m_tilemap_scrolldy{0, 0, 0} +{ +} + +imagetek_i4100_device::imagetek_i4100_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : imagetek_i4100_device(mconfig, I4100, tag, owner, clock, false) +{ +} + + +imagetek_i4220_device::imagetek_i4220_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : imagetek_i4100_device(mconfig, I4220, tag, owner, clock, true) +{ +} + +imagetek_i4300_device::imagetek_i4300_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : imagetek_i4100_device(mconfig, I4300, tag, owner, clock, true) +{ +} + +//------------------------------------------------- +// device_add_mconfig - device-specific machine +// configuration addiitons +//------------------------------------------------- + +MACHINE_CONFIG_MEMBER(imagetek_i4100_device::device_add_mconfig) + MCFG_PALETTE_ADD("palette", 0x1000) + MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) +MACHINE_CONFIG_END + + +//------------------------------------------------- +// static_set_gfxdecode_tag: Set the tag of the +// gfx decoder +//------------------------------------------------- + +void imagetek_i4100_device::static_set_gfxdecode_tag(device_t &device, const char *tag) +{ + downcast<imagetek_i4100_device &>(device).m_gfxdecode.set_tag(tag); +} + + +void imagetek_i4100_device::static_set_tmap_xoffsets(device_t &device, int x1, int x2, int x3) +{ + downcast<imagetek_i4100_device &>(device).m_tilemap_scrolldx[0] = x1; + downcast<imagetek_i4100_device &>(device).m_tilemap_scrolldx[1] = x2; + downcast<imagetek_i4100_device &>(device).m_tilemap_scrolldx[2] = x3; +} + + +void imagetek_i4100_device::static_set_tmap_yoffsets(device_t &device, int y1, int y2, int y3) +{ + downcast<imagetek_i4100_device &>(device).m_tilemap_scrolldy[0] = y1; + downcast<imagetek_i4100_device &>(device).m_tilemap_scrolldy[1] = y2; + downcast<imagetek_i4100_device &>(device).m_tilemap_scrolldy[2] = y3; +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void imagetek_i4100_device::expand_gfx1() +{ + // TODO: remove from device_reset (otherwise you get broken sprites in i4220+ games because gfx rom isn't yet inited!) + if(m_inited_hack == true) + return; + + m_inited_hack = true; + uint32_t length = m_gfxrom_size * 2; + + m_expanded_gfx1 = std::make_unique<uint8_t[]>(length); + + for (int i = 0; i < length; i += 2) + { + uint8_t src = m_gfxrom[i / 2]; + + m_expanded_gfx1[i + 0] = src & 0xf; + m_expanded_gfx1[i + 1] = src >> 4; + } +} + +void imagetek_i4100_device::device_start() +{ + if(!m_gfxdecode->started()) + throw device_missing_dependencies(); + + m_inited_hack = false; + save_item(NAME(m_rombank)); + save_item(NAME(m_crtc_unlock)); + save_item(NAME(m_sprite_count)); + save_item(NAME(m_sprite_priority)); + save_item(NAME(m_sprite_color_code)); + save_item(NAME(m_sprite_xoffset)); + save_item(NAME(m_sprite_yoffset)); + save_item(NAME(m_screen_xoffset)); + save_item(NAME(m_screen_yoffset)); + save_item(NAME(m_layer_priority)); + save_item(NAME(m_background_color)); +// save_item(NAME(m_window)); +// save_item(NAME(m_scroll)); + save_item(NAME(m_screen_blank)); + save_item(NAME(m_screen_flip)); + +// memory_region *devregion = machine().root_device().memregion(":gfx1"); +// m_gfxrom = devregion->base(); + if (m_gfxrom == nullptr) + fatalerror("Imagetek i4100 %s: \"gfx1\" memory base not found",this->tag()); + + m_gfxrom_size = m_gfxrom.bytes(); + + m_blit_irq_cb.resolve_safe(); + m_blit_done_timer = timer_alloc(TIMER_BLIT_END); + +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void imagetek_i4100_device::device_reset() +{ + expand_gfx1(); +} + + +void imagetek_i4100_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (id) + { + case TIMER_BLIT_END: + m_blit_irq_cb(ASSERT_LINE); + break; + } +} + +//************************************************************************** +// READ/WRITE HANDLERS +//************************************************************************** + +READ16_MEMBER(imagetek_i4100_device::vram_0_r){ return m_vram_0[offset]; } +READ16_MEMBER(imagetek_i4100_device::vram_1_r){ return m_vram_1[offset]; } +READ16_MEMBER(imagetek_i4100_device::vram_2_r){ return m_vram_2[offset]; } +WRITE16_MEMBER(imagetek_i4100_device::vram_0_w){ COMBINE_DATA(&m_vram_0[offset]); } +WRITE16_MEMBER(imagetek_i4100_device::vram_1_w){ COMBINE_DATA(&m_vram_1[offset]); } +WRITE16_MEMBER(imagetek_i4100_device::vram_2_w){ COMBINE_DATA(&m_vram_2[offset]); } + +/* This game uses almost only the blitter to write to the tilemaps. + The CPU can only access a "window" of 512x256 pixels in the upper + left corner of the big tilemap */ +// TODO: Puzzlet, Sankokushi & Lady Killer contradicts with aformentioned description (more like RMW?) + +#define RMW_OFFS( _x_ ) ((_x_) & (0x3f)) + (((_x_) & ~(0x3f)) * (0x100 / 0x40)) + +READ16_MEMBER(imagetek_i4100_device::rmw_vram_0_r){ return m_vram_0[RMW_OFFS(offset)]; } +READ16_MEMBER(imagetek_i4100_device::rmw_vram_1_r){ return m_vram_1[RMW_OFFS(offset)]; } +READ16_MEMBER(imagetek_i4100_device::rmw_vram_2_r){ return m_vram_2[RMW_OFFS(offset)]; } +WRITE16_MEMBER(imagetek_i4100_device::rmw_vram_0_w){ COMBINE_DATA(&m_vram_0[RMW_OFFS(offset)]); } +WRITE16_MEMBER(imagetek_i4100_device::rmw_vram_1_w){ COMBINE_DATA(&m_vram_1[RMW_OFFS(offset)]); } +WRITE16_MEMBER(imagetek_i4100_device::rmw_vram_2_w){ COMBINE_DATA(&m_vram_2[RMW_OFFS(offset)]); } + +#undef RMW_OFFS + +READ16_MEMBER(imagetek_i4100_device::scratchram_r ) { return m_scratchram[offset]; } +WRITE16_MEMBER(imagetek_i4100_device::scratchram_w ) { COMBINE_DATA(&m_scratchram[offset]); } +READ16_MEMBER(imagetek_i4100_device::spriteram_r ) { return m_spriteram[offset]; } +WRITE16_MEMBER(imagetek_i4100_device::spriteram_w ) { COMBINE_DATA(&m_spriteram[offset]); } +READ16_MEMBER(imagetek_i4100_device::tiletable_r ) { return m_tiletable[offset]; } +WRITE16_MEMBER(imagetek_i4100_device::tiletable_w ) { COMBINE_DATA(&m_tiletable[offset]); } + +// video registers +/************************************************************* + * + * 0.w ---- ---- ---- ---- Number Of Sprites To Draw + * + ************************************************************/ +READ16_MEMBER(imagetek_i4100_device::sprite_count_r) { return m_sprite_count; } +WRITE16_MEMBER(imagetek_i4100_device::sprite_count_w) { COMBINE_DATA(&m_sprite_count); } + +/************************************************************* + * + * 2.w f--- ---- ---- ---- Disable Sprites Layer Priority + * -edc ---- ---- ---- + * ---- ba-- ---- ---- Sprites Masked Layer + * ---- --98 ---- ---- Sprites Priority + * ---- ---- 765- ---- + * ---- ---- ---4 3210 Sprites Masked Number + * + *************************************************************/ +READ16_MEMBER(imagetek_i4100_device::sprite_priority_r) { return m_sprite_priority; } +WRITE16_MEMBER(imagetek_i4100_device::sprite_priority_w) { COMBINE_DATA(&m_sprite_priority); } + +/************************************************************* + * + * 4.w ---- ---- ---- ---- Sprites Y Offset + * 6.w ---- ---- ---- ---- Sprites X Offset + * + ************************************************************/ +READ16_MEMBER(imagetek_i4100_device::sprite_xoffset_r) { return m_sprite_xoffset; } +WRITE16_MEMBER(imagetek_i4100_device::sprite_xoffset_w) { COMBINE_DATA(&m_sprite_xoffset); } +READ16_MEMBER(imagetek_i4100_device::sprite_yoffset_r) { return m_sprite_yoffset; } +WRITE16_MEMBER(imagetek_i4100_device::sprite_yoffset_w) { COMBINE_DATA(&m_sprite_yoffset); } + +/************************************************************* + * + * 8.w ---- ---- ---- ---- Sprites Color Codes Start + * + ************************************************************/ +READ16_MEMBER(imagetek_i4100_device::sprite_color_code_r) { return m_sprite_color_code; } +WRITE16_MEMBER(imagetek_i4100_device::sprite_color_code_w) { COMBINE_DATA(&m_sprite_color_code); } + +/************************************************************* + * + * 10.w ---- ---- --54 ---- Layer 2 Priority (3 backmost, 0 frontmost) + * ---- ---- ---- 32-- Layer 1 Priority + * ---- ---- ---- --10 Layer 0 Priority + * + ************************************************************/ + +READ16_MEMBER(imagetek_i4100_device::layer_priority_r) +{ + return (m_layer_priority[2]<<4) | (m_layer_priority[1]<<2) | m_layer_priority[0]; +} + +WRITE16_MEMBER(imagetek_i4100_device::layer_priority_w) +{ + m_layer_priority[2] = (data >> 4) & 3; + m_layer_priority[1] = (data >> 2) & 3; + m_layer_priority[0] = (data >> 0) & 3; + if((data >> 6) != 0) + logerror("%s warning: layer_priority_w write with %04x %04x\n",this->tag(),data,mem_mask); +} + +/************************************************************* + * + * 12.w ---- cccc cccc cccc Background Color + * + ************************************************************/ + +READ16_MEMBER(imagetek_i4100_device::background_color_r) +{ + return m_background_color; +} + +WRITE16_MEMBER(imagetek_i4100_device::background_color_w) +{ + COMBINE_DATA(&m_background_color); + + m_background_color &= 0x0fff; + if(data & 0xf000) + logerror("%s warning: background_color_w write with %04x %04x\n",this->tag(),data,mem_mask); +} + +/*************************************************************************** + * + * 0.w Sprite Y center point + * 2.w Sprite X center point + * + * Appears to apply only for sprites, maybe they applies to tilemaps too under + * certain conditions + * + ***************************************************************************/ +READ16_MEMBER(imagetek_i4100_device::screen_xoffset_r) { return m_screen_xoffset; } +WRITE16_MEMBER(imagetek_i4100_device::screen_xoffset_w) { COMBINE_DATA(&m_screen_xoffset); } +READ16_MEMBER(imagetek_i4100_device::screen_yoffset_r) { return m_screen_yoffset; } +WRITE16_MEMBER(imagetek_i4100_device::screen_yoffset_w) { COMBINE_DATA(&m_screen_yoffset); } + +READ16_MEMBER(imagetek_i4100_device::window_r) { return m_window[offset]; } +WRITE16_MEMBER(imagetek_i4100_device::window_w) { COMBINE_DATA(&m_window[offset]); } +READ16_MEMBER(imagetek_i4100_device::scroll_r) { return m_scroll[offset]; } +WRITE16_MEMBER(imagetek_i4100_device::scroll_w) { COMBINE_DATA(&m_scroll[offset]); } + +/**************************************************** + * + * Screen Control Register: + * + * f--- ---- ---- ---- ? + * -edc b--- ---- ---- + * ---- -a98 ---- ---- ? Leds (see gakusai attract) + * ---- ---- 765- ---- 16x16 Tiles (Layer 2-1-0) + * ---- ---- ---4 32-- + * ---- ---- ---- --1- Blank Screen + * ---- ---- ---- ---0 Flip Screen + * + ****************************************************/ +WRITE16_MEMBER(imagetek_i4100_device::screen_ctrl_w) +{ + m_layer_tile_select[2] = BIT(data,7); + m_layer_tile_select[1] = BIT(data,6); + m_layer_tile_select[0] = BIT(data,5); + + // TODO: some of these must be externalized + m_screen_blank = BIT(data,1); + m_screen_flip = BIT(data,0); + + if(data & 0xff1c) + logerror("%s warning: screen_ctrl_w write with %04x %04x\n",this->tag(),data,mem_mask); + +} + + +/* + The main CPU has access to the ROMs that hold the graphics through + a banked window of 64k. Those ROMs also usually store the tables for + the virtual tiles set. The tile codes to be written to the tilemap + memory to render the backgrounds are also stored here, in a format + that the blitter can readily use (which is a form of compression) +*/ + +READ16_MEMBER(imagetek_i4100_device::gfxrom_r) +{ + offset = offset * 2 + 0x10000 * (m_rombank); + + if (offset < m_gfxrom_size) + return ((m_gfxrom[offset + 0] << 8) + m_gfxrom[offset + 1]); + else + return 0xffff; +} + +WRITE16_MEMBER( imagetek_i4100_device::rombank_w ) +{ + COMBINE_DATA(&m_rombank); +} + +WRITE16_MEMBER( imagetek_i4100_device::crtc_horz_w ) +{ + if(m_crtc_unlock == true) + { + //logerror("%s CRTC horizontal %04x %04x\n",this->tag(),data,mem_mask); + } +} + +WRITE16_MEMBER( imagetek_i4100_device::crtc_vert_w ) +{ + if(m_crtc_unlock == true) + { + //logerror("%s CRTC vertical %04x %04x\n",this->tag(),data,mem_mask); + } +} + +WRITE16_MEMBER( imagetek_i4100_device::crtc_unlock_w ) +{ + m_crtc_unlock = BIT(data,0); + if(data & ~1) + logerror("%s warning: unlock register write with %04x %04x\n",this->tag(),data,mem_mask); +} + +/*************************************************************************** + + + Blitter + + [ Registers ] + + Offset: Value: + + 0.l Destination Tilemap (1,2,3) + 4.l Blitter Data Address (byte offset into the gfx ROMs) + 8.l Destination Address << 7 (byte offset into the tilemap) + + The Blitter reads a byte and looks at the most significative + bits for the opcode, while the remaining bits define a value + (usually how many bytes to write). The opcode byte may be + followed by a number of other bytes: + + 76------ Opcode + --543210 N + (at most N+1 bytes follow) + + + The blitter is designed to write every other byte (e.g. it + writes a byte and skips the next). Hence 2 blits are needed + to fill a tilemap (first even, then odd addresses) + + [ Opcodes ] + + 0 Copy the following N+1 bytes. If the whole byte + is $00: stop and generate an IRQ + + 1 Fill N+1 bytes with a sequence, starting with + the value in the following byte + + 2 Fill N+1 bytes with the value in the following + byte + + 3 Skip N+1 bytes. If the whole byte is $C0: + skip to the next row of the tilemap (+0x200 bytes) + but preserve the column passed at the start of the + blit (destination address % 0x200) + + +***************************************************************************/ + +void imagetek_i4100_device::blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask ) +{ + switch(tmap) + { + case 1: vram_0_w(space, offs, data, mask); break; + case 2: vram_1_w(space, offs, data, mask); break; + case 3: vram_2_w(space, offs, data, mask); break; + } +// logerror("%s : Blitter %X] %04X <- %04X & %04X\n", space.machine().describe_context(), tmap, offs, data, mask); +} + +/*************************************************************************** + + + Blitter + + [ Registers ] + + Offset: Value: + + 0.l Destination Tilemap (1,2,3) + 4.l Blitter Data Address (byte offset into the gfx ROMs) + 8.l Destination Address << 7 (byte offset into the tilemap) + + The Blitter reads a byte and looks at the most significative + bits for the opcode, while the remaining bits define a value + (usually how many bytes to write). The opcode byte may be + followed by a number of other bytes: + + 76------ Opcode + --543210 N + (at most N+1 bytes follow) + + + The blitter is designed to write every other byte (e.g. it + writes a byte and skips the next). Hence 2 blits are needed + to fill a tilemap (first even, then odd addresses) + + [ Opcodes ] + + 0 Copy the following N+1 bytes. If the whole byte + is $00: stop and generate an IRQ + + 1 Fill N+1 bytes with a sequence, starting with + the value in the following byte + + 2 Fill N+1 bytes with the value in the following + byte + + 3 Skip N+1 bytes. If the whole byte is $C0: + skip to the next row of the tilemap (+0x200 bytes) + but preserve the column passed at the start of the + blit (destination address % 0x200) + + +***************************************************************************/ + + +// TODO: clean this up +WRITE16_MEMBER( imagetek_i4100_device::blitter_w ) +{ + COMBINE_DATA(&m_blitter_regs[offset]); + + if (offset == 0x0c / 2) + { + //uint8_t *src = memregion("gfx1")->base(); + + uint32_t tmap = (m_blitter_regs[0x00 / 2] << 16) + m_blitter_regs[0x02 / 2]; + uint32_t src_offs = (m_blitter_regs[0x04 / 2] << 16) + m_blitter_regs[0x06 / 2]; + uint32_t dst_offs = (m_blitter_regs[0x08 / 2] << 16) + m_blitter_regs[0x0a / 2]; + + int shift = (dst_offs & 0x80) ? 0 : 8; + uint16_t mask = (dst_offs & 0x80) ? 0x00ff : 0xff00; + +// logerror("CPU #0 PC %06X : Blitter regs %08X, %08X, %08X\n", space.device().safe_pc(), tmap, src_offs, dst_offs); + + dst_offs >>= 7 + 1; + switch (tmap) + { + case 1: + case 2: + case 3: + break; + default: + logerror("CPU #0 PC %06X : Blitter unknown destination: %08X\n", space.device().safe_pc(), tmap); + return; + } + + while (1) + { + uint16_t b1, b2, count; + + src_offs %= m_gfxrom_size; + b1 = m_gfxrom[src_offs]; +// logerror("CPU #0 PC %06X : Blitter opcode %02X at %06X\n", space.device().safe_pc(), b1, src_offs); + src_offs++; + + count = ((~b1) & 0x3f) + 1; + + switch ((b1 & 0xc0) >> 6) + { + case 0: + /* Stop and Generate an IRQ. We can't generate it now + both because it's unlikely that the blitter is so + fast and because some games (e.g. lastfort) need to + complete the blitter irq service routine before doing + another blit. */ + if (b1 == 0) + { + m_blit_done_timer->adjust(attotime::from_usec(500)); + return; + } + + /* Copy */ + while (count--) + { + src_offs %= m_gfxrom_size; + b2 = m_gfxrom[src_offs] << shift; + src_offs++; + + dst_offs &= 0xffff; + blt_write(space, tmap, dst_offs, b2, mask); + dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1))); + } + break; + + case 1: + /* Fill with an increasing value */ + src_offs %= m_gfxrom_size; + b2 = m_gfxrom[src_offs]; + src_offs++; + + while (count--) + { + dst_offs &= 0xffff; + blt_write(space, tmap, dst_offs, b2 << shift, mask); + dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1))); + b2++; + } + break; + + case 2: + /* Fill with a fixed value */ + src_offs %= m_gfxrom_size; + b2 = m_gfxrom[src_offs] << shift; + src_offs++; + + while (count--) + { + dst_offs &= 0xffff; + blt_write(space, tmap, dst_offs, b2, mask); + dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1))); + } + break; + + case 3: + /* Skip to the next line ?? */ + if (b1 == 0xc0) + { + dst_offs += 0x100; + dst_offs &= ~(0x100 - 1); + dst_offs |= (0x100 - 1) & (m_blitter_regs[0x0a / 2] >> (7 + 1)); + } + else + { + dst_offs += count; + } + break; + + default: + //logerror("CPU #0 PC %06X : Blitter unknown opcode %02X at %06X\n",space.device().safe_pc(),b1,src_offs-1); + return; + } + + } + } +} + + + +/*************************************************************************** + * + * Screen Drawing + * + ***************************************************************************/ + + /*************************************************************************** + + + Sprites Drawing + + + Offset: Bits: Value: + + 0.w fedc b--- ---- ---- Priority (0 = Max) + ---- -a98 7654 3210 X + + 2.w fedc ba-- ---- ---- Zoom (Both X & Y) + ---- --98 7654 3210 Y + + 4.w f--- ---- ---- ---- Flip X + -e-- ---- ---- ---- Flip Y + --dc b--- ---- ---- Size X * + ---- -a98 ---- ---- Size Y * + ---- ---- 7654 ---- Color + ---- ---- ---- 3210 Code High Bits ** + + 6.w Code Low Bits ** + +* 8 pixel increments +** 8x8 pixel increments + +***************************************************************************/ + +void imagetek_i4100_device::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) +{ + uint8_t *base_gfx4 = m_expanded_gfx1.get(); + uint8_t *base_gfx8 = m_gfxrom; + uint32_t gfx_size = m_gfxrom_size; + + int max_x = (m_screen_xoffset+1)*2; + int max_y = (m_screen_yoffset+1)*2; + int m_sprite_xoffs = m_sprite_xoffset - (m_screen_xoffset+1); + int m_sprite_yoffs = m_sprite_yoffset - (m_screen_yoffset+1); + + int max_sprites = m_spriteram.bytes() / 8; + int sprites = m_sprite_count % max_sprites; + + int color_start = (m_sprite_color_code & 0x0f) << 4; + + int i, j, pri; + static const int primask[4] = { 0x0000, 0xff00, 0xff00 | 0xf0f0, 0xff00 | 0xf0f0 | 0xcccc }; + + uint16_t *src; + int inc; + + if (sprites == 0) + return; + + for (i = 0; i < 0x20; i++) + { + if (!(m_sprite_priority & 0x8000)) + { + src = m_spriteram + (sprites - 1) * (8 / 2); + inc = -(8 / 2); + } else { + src = m_spriteram; + inc = (8 / 2); + } + + for (j = 0; j < sprites; j++) + { + int x, y, attr, code, color, flipx, flipy, zoom, curr_pri, width, height; + + // Exponential zoom table extracted from daitoride + static const int zoomtable[0x40] = + { 0xAAC,0x800,0x668,0x554,0x494,0x400,0x390,0x334, + 0x2E8,0x2AC,0x278,0x248,0x224,0x200,0x1E0,0x1C8, + 0x1B0,0x198,0x188,0x174,0x164,0x154,0x148,0x13C, + 0x130,0x124,0x11C,0x110,0x108,0x100,0x0F8,0x0F0, + 0x0EC,0x0E4,0x0DC,0x0D8,0x0D4,0x0CC,0x0C8,0x0C4, + 0x0C0,0x0BC,0x0B8,0x0B4,0x0B0,0x0AC,0x0A8,0x0A4, + 0x0A0,0x09C,0x098,0x094,0x090,0x08C,0x088,0x080, + 0x078,0x070,0x068,0x060,0x058,0x050,0x048,0x040 }; + + x = src[0]; + curr_pri = (x & 0xf800) >> 11; + + if ((curr_pri == 0x1f) || (curr_pri != i)) + { + src += inc; + continue; + } + + pri = (m_sprite_priority & 0x0300) >> 8; + + if (!(m_sprite_priority & 0x8000)) + { + if (curr_pri > (m_sprite_priority & 0x1f)) + pri = (m_sprite_priority & 0x0c00) >> 10; + } + + y = src[1]; + attr = src[2]; + code = src[3]; + + flipx = attr & 0x8000; + flipy = attr & 0x4000; + color = (attr & 0xf0) >> 4; + + zoom = zoomtable[(y & 0xfc00) >> 10] << (16 - 8); + + x = (x & 0x07ff) - m_sprite_xoffs; + y = (y & 0x03ff) - m_sprite_yoffs; + + width = (((attr >> 11) & 0x7) + 1) * 8; + height = (((attr >> 8) & 0x7) + 1) * 8; + + uint32_t gfxstart = (8 * 8 * 4 / 8) * (((attr & 0x000f) << 16) + code); + + if (m_screen_flip) + { + flipx = !flipx; x = max_x - x - width; + flipy = !flipy; y = max_y - y - height; + } + + if (m_support_8bpp == true && color == 0xf) /* 8bpp */ + { + /* Bounds checking */ + if ((gfxstart + width * height - 1) >= gfx_size) + continue; + + gfx_element gfx(m_palette, base_gfx8 + gfxstart, width, height, width, m_palette->entries(), 0, 256); + + gfx.prio_zoom_transpen(bitmap,cliprect, + 0, + color_start >> 4, + flipx, flipy, + x, y, + zoom, zoom, + screen.priority(),primask[pri], 255); + } + else + { + /* Bounds checking */ + if ((gfxstart + width / 2 * height - 1) >= gfx_size) + continue; + + gfx_element gfx(m_palette, base_gfx4 + 2 * gfxstart, width, height, width, m_palette->entries(),0, 16); + + gfx.prio_zoom_transpen(bitmap,cliprect, + 0, + color + color_start, + flipx, flipy, + x, y, + zoom, zoom, + screen.priority(),primask[pri], 15); + } + + src += inc; + } + } +} + + + inline uint8_t imagetek_i4100_device::get_tile_pix( uint16_t code, uint8_t x, uint8_t y, bool big, uint16_t *pix ) +{ + int table_index; + uint32_t tile; + + // Use code as an index into the tiles set table + table_index = ((code & 0x1ff0) >> 4) * 2; + tile = (m_tiletable[table_index + 0] << 16) + m_tiletable[table_index + 1]; + + if (code & 0x8000) // Special: draw a tile of a single color (i.e. not from the gfx ROMs) + { + *pix = code & 0x0fff; + + if ((*pix & 0xf) != 0xf) + return 1; + else + return 0; + } + else if (((tile & 0x00f00000) == 0x00f00000) && (m_support_8bpp == true)) /* draw tile as 8bpp (e.g. balcube bg) */ + { + gfx_element *gfx1 = m_gfxdecode->gfx(big?3:1); + uint32_t tile2 = big ? ((tile & 0xfffff) + 8*(code & 0xf)) : + ((tile & 0xfffff) + 2*(code & 0xf)); + const uint8_t* data; + uint8_t flipxy = (code & 0x6000) >> 13; + + if (tile2 < gfx1->elements()) + data = gfx1->get_data(tile2); + else + { + *pix = 0; + return 0; + } + + switch (flipxy) + { + default: + case 0x0: *pix = data[(y * (big?16:8)) + x]; break; + case 0x1: *pix = data[(((big?15:7)-y) * (big?16:8)) + x]; break; + case 0x2: *pix = data[(y * (big?16:8)) + ((big?15:7)-x)]; break; + case 0x3: *pix = data[(((big?15:7)-y) * (big?16:8)) + ((big?15:7)-x)]; break; + } + + *pix |= ((tile & 0x0f000000) >> 24) * 0x100; + + if ((*pix & 0xff) != 0xff) + return 1; + else + return 0; + } + else + { + gfx_element *gfx1 = m_gfxdecode->gfx(big?2:0); + uint32_t tile2 = big ? ((tile & 0xfffff) + 4*(code & 0xf)) : + ((tile & 0xfffff) + (code & 0xf)); + const uint8_t* data; + uint8_t flipxy = (code & 0x6000) >> 13; + + if (tile2 < gfx1->elements()) + data = gfx1->get_data(tile2); + else + { + *pix = 0; + return 0; + } + + switch (flipxy) + { + default: + case 0x0: *pix = data[(y * (big?16:8)) + x]; break; + case 0x1: *pix = data[(((big?15:7)-y) * (big?16:8)) + x]; break; + case 0x2: *pix = data[(y * (big?16:8)) + ((big?15:7)-x)]; break; + case 0x3: *pix = data[(((big?15:7)-y) * (big?16:8)) + ((big?15:7)-x)]; break; + } + + *pix |= (((tile & 0x0ff00000) >> 20)) * 0x10; + + if ((*pix & 0xf) != 0xf) + return 1; + else + return 0; + } +} + +/*************************************************************************** + + Tilemaps: Tiles Set & Window + + Each entry in the Tiles Set RAM uses 2 words to specify a starting + tile code and a color code. This adds 16 consecutive tiles with + that color code to the set of available tiles. + + Offset: Bits: Value: + + 0.w fedc ---- ---- ---- + ---- ba98 7654 ---- Color Code* + ---- ---- ---- 3210 Code High Bits + + 2.w Code Low Bits + +* 00-ff, but on later chips supporting it, xf means 256 color tile and palette x + +***************************************************************************/ + +void imagetek_i4100_device::draw_tilemap( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint32_t flags, uint32_t pcode, + int sx, int sy, int wx, int wy, bool big, uint16_t *tilemapram, int layer ) +{ + int y; + + bitmap_ind8 &priority_bitmap = m_screen->priority(); + + int width = big ? 4096 : 2048; + int height = big ? 4096 : 2048; + + int scrwidth = bitmap.width(); + int scrheight = bitmap.height(); + + int windowwidth = width >> 2; + int windowheight = height >> 3; + + sx += m_tilemap_scrolldx[layer] * (m_screen_flip ? 1 : -1); + sy += m_tilemap_scrolldy[layer] * (m_screen_flip ? 1 : -1); + + for (y = 0; y < scrheight; y++) + { + int scrolly = (sy+y-wy)&(windowheight-1); + int x; + uint16_t *dst; + uint8_t *priority_baseaddr; + int srcline = (wy+scrolly)&(height-1); + int srctilerow = srcline >> (big ? 4 : 3); + + if (!m_screen_flip) + { + dst = &bitmap.pix16(y); + priority_baseaddr = &priority_bitmap.pix8(y); + + for (x = 0; x < scrwidth; x++) + { + int scrollx = (sx+x-wx)&(windowwidth-1); + int srccol = (wx+scrollx)&(width-1); + int srctilecol = srccol >> (big ? 4 : 3); + int tileoffs = srctilecol + srctilerow * BIG_NX; + + uint16_t dat = 0; + + uint16_t tile = tilemapram[tileoffs]; + uint8_t draw = get_tile_pix(tile, big ? (srccol&0xf) : (srccol&0x7), big ? (srcline&0xf) : (srcline&0x7), big, &dat); + + if (draw) + { + dst[x] = dat; + priority_baseaddr[x] = (priority_baseaddr[x] & (pcode >> 8)) | pcode; + } + } + } + else // flipped case + { + dst = &bitmap.pix16(scrheight-y-1); + priority_baseaddr = &priority_bitmap.pix8(scrheight-y-1); + + for (x = 0; x < scrwidth; x++) + { + int scrollx = (sx+x-wx)&(windowwidth-1); + int srccol = (wx+scrollx)&(width-1); + int srctilecol = srccol >> (big ? 4 : 3); + int tileoffs = srctilecol + srctilerow * BIG_NX; + + uint16_t dat = 0; + + uint16_t tile = tilemapram[tileoffs]; + uint8_t draw = get_tile_pix(tile, big ? (srccol&0xf) : (srccol&0x7), big ? (srcline&0xf) : (srcline&0x7), big, &dat); + + if (draw) + { + dst[scrwidth-x-1] = dat; + priority_baseaddr[scrwidth-x-1] = (priority_baseaddr[scrwidth-x-1] & (pcode >> 8)) | pcode; + } + } + } + } +} + + +void imagetek_i4100_device::draw_layers( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri ) +{ + // Draw all the layers with priority == pri + for (int layer = 2; layer >= 0; layer--) + { + if (pri == m_layer_priority[layer]) + { + // Scroll and Window values + uint16_t sy = m_scroll[layer * 2 + 0]; uint16_t sx = m_scroll[layer * 2 + 1]; + uint16_t wy = m_window[layer * 2 + 0]; uint16_t wx = m_window[layer * 2 + 1]; + + uint16_t *tilemapram = nullptr; + + switch (layer) + { + case 0: tilemapram = m_vram_0; break; + case 1: tilemapram = m_vram_1; break; + case 2: tilemapram = m_vram_2; break; + } + + bool big = (m_support_16x16 && m_layer_tile_select[layer]) == 1; + + draw_tilemap(screen, bitmap, cliprect, 0, 1 << (3 - pri), sx, sy, wx, wy, big, tilemapram, layer); + } + } +} + + +uint32_t imagetek_i4100_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + screen.priority().fill(0, cliprect); + + bitmap.fill(m_background_color, cliprect); + + if (m_screen_blank == true) + return 0; + + for (int pri = 3; pri >= 0; pri--) + draw_layers(screen, bitmap, cliprect, pri); + + draw_sprites(screen, bitmap, cliprect); + + return 0; +} diff --git a/src/devices/video/imagetek_i4100.h b/src/devices/video/imagetek_i4100.h new file mode 100644 index 00000000000..4e0d0108920 --- /dev/null +++ b/src/devices/video/imagetek_i4100.h @@ -0,0 +1,225 @@ +// license:BSD-3-Clause +// copyright-holders:Luca Elia,David Haywood,Angelo Salese +/*************************************************************************** + + Imagetek I4100 / I4220 / I4300 device files + +***************************************************************************/ + +#ifndef MAME_VIDEO_I4100_H +#define MAME_VIDEO_I4100_H + +#pragma once + +#include "screen.h" + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_I4100_GFXDECODE(gfxtag) \ + imagetek_i4100_device::static_set_gfxdecode_tag(*device, ("^" gfxtag)); + +#define MCFG_I4100_BLITTER_END_CALLBACK(_devcb) \ + devcb = &imagetek_i4100_device::static_set_blitter_irq_callback(*device, DEVCB_##_devcb); + +#define MCFG_I4100_TILEMAP_XOFFSETS(_a, _b, _c) \ + imagetek_i4100_device::static_set_tmap_xoffsets(*device, _a, _b, _c); + +#define MCFG_I4100_TILEMAP_YOFFSETS(_a, _b, _c) \ + imagetek_i4100_device::static_set_tmap_yoffsets(*device, _a, _b, _c); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> i4100_device + +class imagetek_i4100_device : public device_t, + public device_video_interface +{ +public: + // construction/destruction + imagetek_i4100_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_ADDRESS_MAP(map, 16); + + static void static_set_gfxdecode_tag(device_t &device, const char *tag); + static void static_set_tmap_xoffsets(device_t &device, int x1, int x2, int x3); + static void static_set_tmap_yoffsets(device_t &device, int y1, int y2, int y3); + + template <class Object> static devcb_base &static_set_blitter_irq_callback(device_t &device, Object &&cb) { return downcast<imagetek_i4100_device &>(device).m_blit_irq_cb.set_callback(std::forward<Object>(cb)); } + + + // I/O operations + DECLARE_READ16_MEMBER( vram_0_r ); + DECLARE_READ16_MEMBER( vram_1_r ); + DECLARE_READ16_MEMBER( vram_2_r ); + DECLARE_WRITE16_MEMBER( vram_0_w ); + DECLARE_WRITE16_MEMBER( vram_1_w ); + DECLARE_WRITE16_MEMBER( vram_2_w ); + DECLARE_READ16_MEMBER( rmw_vram_0_r ); + DECLARE_READ16_MEMBER( rmw_vram_1_r ); + DECLARE_READ16_MEMBER( rmw_vram_2_r ); + DECLARE_WRITE16_MEMBER( rmw_vram_0_w ); + DECLARE_WRITE16_MEMBER( rmw_vram_1_w ); + DECLARE_WRITE16_MEMBER( rmw_vram_2_w ); + DECLARE_READ16_MEMBER( scratchram_r ); + DECLARE_WRITE16_MEMBER( scratchram_w ); + DECLARE_READ16_MEMBER( spriteram_r ); + DECLARE_WRITE16_MEMBER( spriteram_w ); + DECLARE_READ16_MEMBER( tiletable_r ); + DECLARE_WRITE16_MEMBER( tiletable_w ); + DECLARE_READ16_MEMBER( sprite_count_r ); + DECLARE_WRITE16_MEMBER( sprite_count_w ); + DECLARE_READ16_MEMBER( sprite_priority_r ); + DECLARE_WRITE16_MEMBER( sprite_priority_w ); + DECLARE_READ16_MEMBER( sprite_xoffset_r ); + DECLARE_WRITE16_MEMBER( sprite_xoffset_w ); + DECLARE_READ16_MEMBER( sprite_yoffset_r ); + DECLARE_WRITE16_MEMBER( sprite_yoffset_w ); + DECLARE_READ16_MEMBER( sprite_color_code_r ); + DECLARE_WRITE16_MEMBER( sprite_color_code_w ); + DECLARE_READ16_MEMBER( layer_priority_r ); + DECLARE_WRITE16_MEMBER( layer_priority_w ); + DECLARE_READ16_MEMBER( background_color_r ); + DECLARE_WRITE16_MEMBER( background_color_w ); + + DECLARE_READ16_MEMBER( screen_xoffset_r ); + DECLARE_WRITE16_MEMBER( screen_xoffset_w ); + DECLARE_READ16_MEMBER( screen_yoffset_r ); + DECLARE_WRITE16_MEMBER( screen_yoffset_w ); + + DECLARE_READ16_MEMBER( window_r ); + DECLARE_WRITE16_MEMBER( window_w ); + DECLARE_READ16_MEMBER( scroll_r ); + DECLARE_WRITE16_MEMBER( scroll_w ); + + + DECLARE_READ16_MEMBER( gfxrom_r ); + DECLARE_WRITE16_MEMBER( crtc_vert_w ); + DECLARE_WRITE16_MEMBER( crtc_horz_w ); + DECLARE_WRITE16_MEMBER( crtc_unlock_w ); + DECLARE_WRITE16_MEMBER( blitter_w ); + DECLARE_WRITE16_MEMBER( screen_ctrl_w ); + DECLARE_WRITE16_MEMBER( rombank_w ); + + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + +protected: + imagetek_i4100_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool has_ext_tiles); + + // device-level overrides + //virtual void device_validity_check(validity_checker &valid) const override; + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + + required_shared_ptr<uint16_t> m_vram_0; + required_shared_ptr<uint16_t> m_vram_1; + required_shared_ptr<uint16_t> m_vram_2; + required_shared_ptr<uint16_t> m_scratchram; + required_shared_ptr<uint16_t> m_blitter_regs; + required_shared_ptr<uint16_t> m_spriteram; + required_shared_ptr<uint16_t> m_tiletable; + required_shared_ptr<uint16_t> m_window; + required_shared_ptr<uint16_t> m_scroll; + + required_device<palette_device> m_palette; + required_device<gfxdecode_device> m_gfxdecode; + required_region_ptr<uint8_t> m_gfxrom; + + std::unique_ptr<uint8_t[]> m_expanded_gfx1; + + devcb_write_line m_blit_irq_cb; + + uint16_t m_rombank; + size_t m_gfxrom_size; + bool m_crtc_unlock; + uint16_t m_sprite_count; + uint16_t m_sprite_priority; + uint16_t m_sprite_xoffset,m_sprite_yoffset; + uint16_t m_sprite_color_code; + uint8_t m_layer_priority[3]; + uint16_t m_background_color; + uint16_t m_screen_xoffset,m_screen_yoffset; + bool m_layer_tile_select[3]; + bool m_screen_blank; + bool m_screen_flip; + const bool m_support_8bpp, m_support_16x16; + int m_tilemap_scrolldx[3]; + int m_tilemap_scrolldy[3]; + + void blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask ); + + enum + { + TIMER_BLIT_END = 1 + }; + + emu_timer *m_blit_done_timer; + + void draw_layers( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri ); + inline uint8_t get_tile_pix( uint16_t code, uint8_t x, uint8_t y, bool big, uint16_t *pix ); + void draw_tilemap( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint32_t flags, uint32_t pcode, + int sx, int sy, int wx, int wy, bool big, uint16_t *tilemapram, int layer ); + void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ); + void expand_gfx1(); + +// A 2048 x 2048 virtual tilemap + static constexpr uint32_t BIG_NX = (0x100); + static constexpr uint32_t BIG_NY = (0x100); + +// A smaller 512 x 256 window defines the actual tilemap + static constexpr uint32_t WIN_NX = (0x40); + static constexpr uint32_t WIN_NY = (0x20); + + bool m_inited_hack; +}; + +class imagetek_i4220_device : public imagetek_i4100_device +{ +public: + // construction/destruction + imagetek_i4220_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_ADDRESS_MAP(v2_map, 16); + + // needed by Blazing Tornado / Grand Striker 2 for mixing with PSAC + // (it's unknown how the chip enables external sync) + uint16_t get_background_pen() { return m_background_color; }; + +protected: + +}; + +class imagetek_i4300_device : public imagetek_i4100_device +{ +public: + // construction/destruction + imagetek_i4300_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_ADDRESS_MAP(v3_map, 16); + + +protected: + +}; + +// device type definition +DECLARE_DEVICE_TYPE(I4100, imagetek_i4100_device) +DECLARE_DEVICE_TYPE(I4220, imagetek_i4220_device) +DECLARE_DEVICE_TYPE(I4300, imagetek_i4300_device) + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + + +#endif // MAME_VIDEO_I4100_H diff --git a/src/devices/video/mc6845.cpp b/src/devices/video/mc6845.cpp index 57ebab801c2..5723de82f57 100644 --- a/src/devices/video/mc6845.cpp +++ b/src/devices/video/mc6845.cpp @@ -155,6 +155,29 @@ READ8_MEMBER( mc6845_device::status_r ) } +void mc6845_device::transparent_update() +{ + if (m_supports_transparent && MODE_TRANSPARENT) + { + if (MODE_TRANSPARENT_PHI2) + { + m_update_addr++; + m_update_addr &= 0x3fff; + call_on_update_address(0); + } + else + { + /* MODE_TRANSPARENT_BLANK */ + if (m_update_ready_bit) + { + m_update_ready_bit = false; + update_upd_adr_timer(); + } + } + } +} + + READ8_MEMBER( mc6845_device::register_r ) { uint8_t ret = 0; @@ -167,26 +190,7 @@ READ8_MEMBER( mc6845_device::register_r ) case 0x0f: ret = (m_cursor_addr >> 0) & 0xff; break; case 0x10: ret = (m_light_pen_addr >> 8) & 0xff; m_light_pen_latched = false; break; case 0x11: ret = (m_light_pen_addr >> 0) & 0xff; m_light_pen_latched = false; break; - case 0x1f: - if (m_supports_transparent && MODE_TRANSPARENT) - { - if(MODE_TRANSPARENT_PHI2) - { - m_update_addr++; - m_update_addr &= 0x3fff; - call_on_update_address(0); - } - else - { - /* MODE_TRANSPARENT_BLANK */ - if(m_update_ready_bit) - { - m_update_ready_bit = false; - update_upd_adr_timer(); - } - } - } - break; + case 0x1f: transparent_update(); break; /* all other registers are write only and return 0 */ default: break; @@ -236,26 +240,7 @@ WRITE8_MEMBER( mc6845_device::register_w ) call_on_update_address(0); } break; - case 0x1f: - if (m_supports_transparent && MODE_TRANSPARENT) - { - if(MODE_TRANSPARENT_PHI2) - { - m_update_addr++; - m_update_addr &= 0x3fff; - call_on_update_address(0); - } - else - { - /* MODE_TRANSPARENT_BLANK */ - if(m_update_ready_bit) - { - m_update_ready_bit = false; - update_upd_adr_timer(); - } - } - } - break; + case 0x1f: transparent_update(); break; default: break; } diff --git a/src/devices/video/mc6845.h b/src/devices/video/mc6845.h index 45c10eb980a..ffb2dc373d7 100644 --- a/src/devices/video/mc6845.h +++ b/src/devices/video/mc6845.h @@ -256,6 +256,7 @@ protected: void update_upd_adr_timer(); void call_on_update_address(int strobe); + void transparent_update(); void recompute_parameters(bool postload); void update_counters(); void set_de(int state); diff --git a/src/devices/video/saa5050.cpp b/src/devices/video/saa5050.cpp index cebcbe7e40e..65825c853a8 100644 --- a/src/devices/video/saa5050.cpp +++ b/src/devices/video/saa5050.cpp @@ -26,14 +26,14 @@ // DEVICE DEFINITIONS //************************************************************************** -DEFINE_DEVICE_TYPE(SAA5050, saa5050_device, "saa5050", "Mullard SA5050") -DEFINE_DEVICE_TYPE(SAA5051, saa5051_device, "saa5051", "Mullard SA5051") -DEFINE_DEVICE_TYPE(SAA5052, saa5052_device, "saa5052", "Mullard SA5052") -DEFINE_DEVICE_TYPE(SAA5053, saa5053_device, "saa5053", "Mullard SA5053") -DEFINE_DEVICE_TYPE(SAA5054, saa5054_device, "saa5054", "Mullard SA5054") -DEFINE_DEVICE_TYPE(SAA5055, saa5055_device, "saa5055", "Mullard SA5055") -DEFINE_DEVICE_TYPE(SAA5056, saa5056_device, "saa5056", "Mullard SA5056") -DEFINE_DEVICE_TYPE(SAA5057, saa5057_device, "saa5057", "Mullard SA5057") +DEFINE_DEVICE_TYPE(SAA5050, saa5050_device, "saa5050", "SAA5050 Teletext Character Generator") +DEFINE_DEVICE_TYPE(SAA5051, saa5051_device, "saa5051", "SAA5051 Teletext Character Generator") +DEFINE_DEVICE_TYPE(SAA5052, saa5052_device, "saa5052", "SAA5052 Teletext Character Generator") +DEFINE_DEVICE_TYPE(SAA5053, saa5053_device, "saa5053", "SAA5053 Teletext Character Generator") +DEFINE_DEVICE_TYPE(SAA5054, saa5054_device, "saa5054", "SAA5054 Teletext Character Generator") +DEFINE_DEVICE_TYPE(SAA5055, saa5055_device, "saa5055", "SAA5055 Teletext Character Generator") +DEFINE_DEVICE_TYPE(SAA5056, saa5056_device, "saa5056", "SAA5056 Teletext Character Generator") +DEFINE_DEVICE_TYPE(SAA5057, saa5057_device, "saa5057", "SAA5057 Teletext Character Generator") //------------------------------------------------- diff --git a/src/devices/video/scn2674.cpp b/src/devices/video/scn2674.cpp index 2af0483b14c..e5f84e4b3a7 100644 --- a/src/devices/video/scn2674.cpp +++ b/src/devices/video/scn2674.cpp @@ -13,7 +13,7 @@ #include "logmacro.h" -DEFINE_DEVICE_TYPE(SCN2674_VIDEO, scn2674_device, "scn2674", "Signetics SCN2674 AVDC") +DEFINE_DEVICE_TYPE(SCN2674, scn2674_device, "scn2674", "Signetics SCN2674 AVDC") // default address map @@ -22,10 +22,10 @@ static ADDRESS_MAP_START( scn2674_vram, 0, 8, scn2674_device ) ADDRESS_MAP_END scn2674_device::scn2674_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, SCN2674_VIDEO, tag, owner, clock) + : device_t(mconfig, SCN2674, tag, owner, clock) , device_video_interface(mconfig, *this) , device_memory_interface(mconfig, *this) - , m_irq_cb(*this) + , m_intr_cb(*this) , m_IR_pointer(0) , m_screen1_l(0), m_screen1_h(0), m_cursor_l(0), m_cursor_h(0), m_screen2_l(0), m_screen2_h(0) , m_irq_register(0), m_status_register(0), m_irq_mask(0) @@ -64,7 +64,7 @@ void scn2674_device::device_start() { // resolve callbacks m_display_cb.bind_relative_to(*owner()); - m_irq_cb.resolve_safe(); + m_intr_cb.resolve_safe(); m_scanline_timer = timer_alloc(TIMER_SCANLINE); m_screen->register_screen_bitmap(m_bitmap); @@ -410,7 +410,7 @@ void scn2674_device::write_command(uint8_t data) m_irq_state = 1; } } - m_irq_cb(m_irq_register ? 1 : 0); + m_intr_cb(m_irq_register ? ASSERT_LINE : CLEAR_LINE); } if ((data&0xe0)==0x80) @@ -685,7 +685,7 @@ void scn2674_device::device_timer(emu_timer &timer, device_timer_id id, int para LOG("vblank irq\n"); m_irq_state = 1; m_irq_register |= 0x10; - m_irq_cb(1); + m_intr_cb(ASSERT_LINE); } } @@ -704,7 +704,7 @@ void scn2674_device::device_timer(emu_timer &timer, device_timer_id id, int para LOG("SCN2674 Line Zero\n"); m_irq_state = 1; m_irq_register |= 0x08; - m_irq_cb(1); + m_intr_cb(ASSERT_LINE); } } @@ -716,7 +716,7 @@ void scn2674_device::device_timer(emu_timer &timer, device_timer_id id, int para LOG("SCN2674 Split Screen 1 irq\n"); m_irq_state = 1; m_irq_register |= 0x04; - m_irq_cb(1); + m_intr_cb(ASSERT_LINE); } if(m_spl1) m_address = (m_screen2_h << 8) | m_screen2_l; @@ -732,7 +732,7 @@ void scn2674_device::device_timer(emu_timer &timer, device_timer_id id, int para LOG("SCN2674 Split Screen 2 irq\n"); m_irq_state = 1; m_irq_register |= 0x01; - m_irq_cb(1); + m_intr_cb(ASSERT_LINE); } if(m_spl2) m_address = (m_screen2_h << 8) | m_screen2_l; diff --git a/src/devices/video/scn2674.h b/src/devices/video/scn2674.h index a79ac7d4738..7e110430671 100644 --- a/src/devices/video/scn2674.h +++ b/src/devices/video/scn2674.h @@ -6,9 +6,8 @@ #pragma once -#define MCFG_SCN2674_VIDEO_ADD(_tag, _clock, _irq) \ - MCFG_DEVICE_ADD(_tag, SCN2674_VIDEO, _clock) \ - devcb = &scn2674_device::set_irq_callback(*device, DEVCB_##_irq); +#define MCFG_SCN2674_INTR_CALLBACK(_intr) \ + devcb = &scn2674_device::set_intr_callback(*device, DEVCB_##_intr); #define MCFG_SCN2674_TEXT_CHARACTER_WIDTH(_value) \ scn2674_device::static_set_character_width(*device, _value); @@ -31,7 +30,7 @@ public: typedef device_delegate<void (bitmap_rgb32 &bitmap, int x, int y, uint8_t linecount, uint8_t charcode, uint16_t address, uint8_t cursor, uint8_t dw, uint8_t lg, uint8_t ul, uint8_t blink)> draw_character_delegate; // static configuration - template <class Object> static devcb_base &set_irq_callback(device_t &device, Object &&cb) { return downcast<scn2674_device &>(device).m_irq_cb.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_intr_callback(device_t &device, Object &&cb) { return downcast<scn2674_device &>(device).m_intr_cb.set_callback(std::forward<Object>(cb)); } static void static_set_character_width(device_t &device, int value) { downcast<scn2674_device &>(device).m_text_hpixels_per_column = value; } static void static_set_gfx_character_width(device_t &device, int value) { downcast<scn2674_device &>(device).m_gfx_hpixels_per_column = value; } static void static_set_display_callback(device_t &device, draw_character_delegate &&cb) { downcast<scn2674_device &>(device).m_display_cb = std::move(cb); } @@ -51,7 +50,7 @@ protected: private: bitmap_rgb32 m_bitmap; - devcb_write_line m_irq_cb; + devcb_write_line m_intr_cb; uint8_t m_IR_pointer; uint8_t m_screen1_l; @@ -129,6 +128,6 @@ private: }; -DECLARE_DEVICE_TYPE(SCN2674_VIDEO, scn2674_device) +DECLARE_DEVICE_TYPE(SCN2674, scn2674_device) #endif // MAME_VIDEO_SCN2674_H diff --git a/src/devices/video/v9938.cpp b/src/devices/video/v9938.cpp index f5925cf1f48..468cc3900db 100644 --- a/src/devices/video/v9938.cpp +++ b/src/devices/video/v9938.cpp @@ -241,22 +241,6 @@ void v99x8_device::configure_pal_ntsc() /* - Not really right... won't work with sprites in graphics 7 - and with palette updated mid-screen -*/ -int v99x8_device::get_transpen() -{ - if (m_mode == V9938_MODE_GRAPHIC7) - { - return m_pal_ind256[0]; - } - else - { - return m_pal_ind16[0]; - } -} - -/* Driver-specific function: update the vdp mouse state */ void v99x8_device::update_mouse_state(int mx_delta, int my_delta, int button_state) @@ -309,11 +293,6 @@ b0 is set if b2 and b1 are set (remember, color bus is 3 bits) void v9938_device::palette_init() { - int i; - - // create the full 512 colour palette - for (i=0;i<512;i++) - set_pen_color(i, pal3bit(i >> 6), pal3bit(i >> 3), pal3bit(i >> 0)); } /* @@ -327,23 +306,15 @@ to emulate this. Also it keeps the palette a reasonable size. :) */ -uint16_t v99x8_device::s_pal_indYJK[0x20000]; +uint32_t v99x8_device::s_pal_indYJK[0x20000]; void v9958_device::palette_init() { - int r,g,b,y,j,k,i,k0,j0,n; - uint8_t pal[19268*3]; - - // init v9938 512-color palette - for (i=0;i<512;i++) - set_pen_color(i, pal3bit(i >> 6), pal3bit(i >> 3), pal3bit(i >> 0)); - - if (entries() != 19780) - fatalerror("V9958: not enough palette, must be 19780"); + int r,g,b,y,j,k,k0,j0; // set up YJK table LOG("Building YJK table for V9958 screens, may take a while ... \n"); - i = 0; + for (y=0;y<32;y++) for (k=0;k<64;k++) for (j=0;j<64;j++) { // calculate the color @@ -356,38 +327,11 @@ void v9958_device::palette_init() if (g < 0) g = 0; else if (g > 31) g = 31; if (b < 0) b = 0; else if (b > 31) b = 31; - //r = (r << 3) | (r >> 2); - //b = (b << 3) | (b >> 2); - //g = (g << 3) | (g >> 2); - // have we seen this one before? - n = 0; - while (n < i) - { - if (pal[n*3+0] == r && pal[n*3+1] == g && pal[n*3+2] == b) - { - v99x8_device::s_pal_indYJK[y | j << 5 | k << (5 + 6)] = n + 512; - break; - } - n++; - } - - if (i == n) - { - // so we haven't; add it - pal[i*3+0] = r; - pal[i*3+1] = g; - pal[i*3+2] = b; - set_pen_color(i+512, rgb_t(pal5bit(r), pal5bit(g), pal5bit(b))); - v99x8_device::s_pal_indYJK[y | j << 5 | k << (5 + 6)] = i + 512; - i++; - } + v99x8_device::s_pal_indYJK[y | j << 5 | k << (5 + 6)] = uint32_t(rgb_t(pal5bit(r), pal5bit(g), pal5bit(b))); } - - if (i != 19268) - LOG("Table creation failed - %d colours out of 19286 created\n", i); } -uint32_t v99x8_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t v99x8_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect); return 0; @@ -530,10 +474,9 @@ void v99x8_device::palette_w(uint8_t data) indexp = m_cont_reg[0x10] & 15; m_pal_reg[indexp*2] = m_pal_write & 0x77; m_pal_reg[indexp*2+1] = data & 0x07; + // update palette - m_pal_ind16[indexp] = (((int)m_pal_write << 2) & 0x01c0) | - (((int)data << 3) & 0x0038) | - ((int)m_pal_write & 0x0007); + set_pen16(indexp, uint32_t(rgb_t(pal3bit((m_pal_write & 0x70) >> 4), pal3bit(data & 0x07), pal3bit(m_pal_write & 0x07)))); m_cont_reg[0x10] = (m_cont_reg[0x10] + 1) & 15; m_pal_write_first = 0; @@ -668,8 +611,6 @@ void v99x8_device::device_start() save_item(NAME(m_mx_delta)); save_item(NAME(m_my_delta)); save_item(NAME(m_button_state)); - save_item(NAME(m_pal_ind16)); - save_item(NAME(m_pal_ind256)); save_item(NAME(m_mmc.SX)); save_item(NAME(m_mmc.SY)); save_item(NAME(m_mmc.DX)); @@ -755,7 +696,7 @@ void v99x8_device::reset_palette() 5, 5, 5, // 14: gray 7, 7, 7 // 15: white }; - int i, red, ind; + int i, red; for (i=0;i<16;i++) { @@ -763,18 +704,15 @@ void v99x8_device::reset_palette() m_pal_reg[i*2+0] = pal16[i*3+1] << 4 | pal16[i*3+2]; m_pal_reg[i*2+1] = pal16[i*3]; // set the reference table - m_pal_ind16[i] = pal16[i*3+1] << 6 | pal16[i*3] << 3 | pal16[i*3+2]; + set_pen16(i, uint32_t(rgb_t(pal3bit(pal16[i*3+1]), pal3bit(pal16[i*3]), pal3bit(pal16[i*3+2])))); } // set internal palette GRAPHIC 7 for (i=0;i<256;i++) { - ind = (i << 4) & 0x01c0; - ind |= (i >> 2) & 0x0038; red = (i << 1) & 6; if (red == 6) red++; - ind |= red; - m_pal_ind256[i] = ind; + set_pen256(i, uint32_t(rgb_t(pal3bit((i & 0x1c) >> 2), pal3bit((i & 0xe0) >> 5), pal3bit(red)))); } } @@ -938,39 +876,39 @@ inline bool v99x8_device::v9938_second_field() } -void v99x8_device::default_border(uint16_t *ln) +void v99x8_device::default_border(uint32_t *ln) { pen_t pen; int i; - pen = this->pen(m_pal_ind16[m_cont_reg[7] & 0x0f]); + pen = pen16(m_cont_reg[7] & 0x0f); i = LONG_WIDTH; while (i--) *ln++ = pen; } -void v99x8_device::graphic7_border(uint16_t *ln) +void v99x8_device::graphic7_border(uint32_t *ln) { pen_t pen; int i; - pen = this->pen(m_pal_ind256[m_cont_reg[7]]); + pen = pen256(m_cont_reg[7]); i = LONG_WIDTH; while (i--) *ln++ = pen; } -void v99x8_device::graphic5_border(uint16_t *ln) +void v99x8_device::graphic5_border(uint32_t *ln) { int i; pen_t pen0; pen_t pen1; - pen1 = pen(m_pal_ind16[m_cont_reg[7] & 0x03]); - pen0 = pen(m_pal_ind16[(m_cont_reg[7] >> 2) & 0x03]); + pen1 = pen16(m_cont_reg[7] & 0x03); + pen0 = pen16((m_cont_reg[7] >> 2) & 0x03); i = LONG_WIDTH / 2; while (i--) { *ln++ = pen0; *ln++ = pen1; } } -void v99x8_device::mode_text1(uint16_t *ln, int line) +void v99x8_device::mode_text1(uint32_t *ln, int line) { int pattern, x, xx, name, xxx; pen_t fg, bg, pen; @@ -979,12 +917,12 @@ void v99x8_device::mode_text1(uint16_t *ln, int line) patterntbl_addr = m_cont_reg[4] << 11; nametbl_addr = m_cont_reg[2] << 10; - fg = this->pen(m_pal_ind16[m_cont_reg[7] >> 4]); - bg = this->pen(m_pal_ind16[m_cont_reg[7] & 15]); + fg = pen16(m_cont_reg[7] >> 4); + bg = pen16(m_cont_reg[7] & 15); name = (line/8)*40; - pen = this->pen(m_pal_ind16[m_cont_reg[7] & 0x0f]); + pen = pen16(m_cont_reg[7] & 0x0f); xxx = (m_offset_x + 8) * 2; while (xxx--) *ln++ = pen; @@ -1007,7 +945,7 @@ void v99x8_device::mode_text1(uint16_t *ln, int line) while (xxx--) *ln++ = pen; } -void v99x8_device::mode_text2(uint16_t *ln, int line) +void v99x8_device::mode_text2(uint32_t *ln, int line) { int pattern, x, charcode, name, xxx, patternmask, colourmask; pen_t fg, bg, fg0, bg0, pen; @@ -1023,15 +961,15 @@ void v99x8_device::mode_text2(uint16_t *ln, int line) nametbl_addr = ((m_cont_reg[2] & 0xfc) << 10); patternmask = ((m_cont_reg[2] & 3) << 10) | 0x3ff; /* seems correct */ - fg = this->pen(m_pal_ind16[m_cont_reg[7] >> 4]); - bg = this->pen(m_pal_ind16[m_cont_reg[7] & 15]); - fg0 = this->pen(m_pal_ind16[m_cont_reg[12] >> 4]); - bg0 = this->pen(m_pal_ind16[m_cont_reg[12] & 15]); + fg = pen16(m_cont_reg[7] >> 4); + bg = pen16(m_cont_reg[7] & 15); + fg0 = pen16(m_cont_reg[12] >> 4); + bg0 = pen16(m_cont_reg[12] & 15); name = (line/8)*80; xxx = (m_offset_x + 8) * 2; - pen = this->pen(m_pal_ind16[m_cont_reg[7] & 0x0f]); + pen = pen16(m_cont_reg[7] & 0x0f); while (xxx--) *ln++ = pen; for (x=0;x<80;x++) @@ -1074,7 +1012,7 @@ void v99x8_device::mode_text2(uint16_t *ln, int line) while (xxx--) *ln++ = pen; } -void v99x8_device::mode_multi(uint16_t *ln, int line) +void v99x8_device::mode_multi(uint32_t *ln, int line) { int nametbl_addr, patterntbl_addr, colour; int name, line2, x, xx; @@ -1086,14 +1024,14 @@ void v99x8_device::mode_multi(uint16_t *ln, int line) line2 = (line - m_cont_reg[23]) & 255; name = (line2/8)*32; - pen_bg = this->pen(m_pal_ind16[m_cont_reg[7] & 0x0f]); + pen_bg = pen16(m_cont_reg[7] & 0x0f); xx = m_offset_x * 2; while (xx--) *ln++ = pen_bg; for (x=0;x<32;x++) { colour = m_vram_space->read_byte(patterntbl_addr + (m_vram_space->read_byte(nametbl_addr + name) * 8) + ((line2/4)&7)); - pen = this->pen(m_pal_ind16[colour >> 4]); + pen = pen16(colour >> 4); /* eight pixels */ *ln++ = pen; *ln++ = pen; @@ -1103,7 +1041,7 @@ void v99x8_device::mode_multi(uint16_t *ln, int line) *ln++ = pen; *ln++ = pen; *ln++ = pen; - pen = this->pen(m_pal_ind16[colour & 15]); + pen = pen16(colour & 15); /* eight pixels */ *ln++ = pen; *ln++ = pen; @@ -1120,7 +1058,7 @@ void v99x8_device::mode_multi(uint16_t *ln, int line) while (xx--) *ln++ = pen_bg; } -void v99x8_device::mode_graphic1(uint16_t *ln, int line) +void v99x8_device::mode_graphic1(uint32_t *ln, int line) { pen_t fg, bg, pen; int nametbl_addr, patterntbl_addr, colourtbl_addr; @@ -1134,7 +1072,7 @@ void v99x8_device::mode_graphic1(uint16_t *ln, int line) name = (line2/8)*32; - pen = this->pen(m_pal_ind16[m_cont_reg[7] & 0x0f]); + pen = pen16(m_cont_reg[7] & 0x0f); xxx = m_offset_x * 2; while (xxx--) *ln++ = pen; @@ -1142,8 +1080,8 @@ void v99x8_device::mode_graphic1(uint16_t *ln, int line) { charcode = m_vram_space->read_byte(nametbl_addr + name); colour = m_vram_space->read_byte(colourtbl_addr + charcode/8); - fg = this->pen(m_pal_ind16[colour >> 4]); - bg = this->pen(m_pal_ind16[colour & 15]); + fg = pen16(colour >> 4); + bg = pen16(colour & 15); pattern = m_vram_space->read_byte(patterntbl_addr + (charcode * 8 + (line2 & 7))); for (xx=0;xx<8;xx++) @@ -1159,7 +1097,7 @@ void v99x8_device::mode_graphic1(uint16_t *ln, int line) while (xx--) *ln++ = pen; } -void v99x8_device::mode_graphic23(uint16_t *ln, int line) +void v99x8_device::mode_graphic23(uint32_t *ln, int line) { pen_t fg, bg, pen; int nametbl_addr, patterntbl_addr, colourtbl_addr; @@ -1176,7 +1114,7 @@ void v99x8_device::mode_graphic23(uint16_t *ln, int line) line2 = (line + m_cont_reg[23]) & 255; name = (line2/8)*32; - pen = this->pen(m_pal_ind16[m_cont_reg[7] & 0x0f]); + pen = pen16(m_cont_reg[7] & 0x0f); xxx = m_offset_x * 2; while (xxx--) *ln++ = pen; @@ -1185,8 +1123,8 @@ void v99x8_device::mode_graphic23(uint16_t *ln, int line) charcode = m_vram_space->read_byte(nametbl_addr + name) + (line2&0xc0)*4; colour = m_vram_space->read_byte(colourtbl_addr + ((charcode&colourmask)*8+(line2&7))); pattern = m_vram_space->read_byte(patterntbl_addr + ((charcode&patternmask)*8+(line2&7))); - fg = this->pen(m_pal_ind16[colour >> 4]); - bg = this->pen(m_pal_ind16[colour & 15]); + fg = pen16(colour >> 4); + bg = pen16(colour & 15); for (xx=0;xx<8;xx++) { *ln++ = (pattern & 0x80) ? fg : bg; @@ -1200,7 +1138,7 @@ void v99x8_device::mode_graphic23(uint16_t *ln, int line) while (xx--) *ln++ = pen; } -void v99x8_device::mode_graphic4(uint16_t *ln, int line) +void v99x8_device::mode_graphic4(uint32_t *ln, int line) { int nametbl_addr, colour; int line2, linemask, x, xx; @@ -1214,17 +1152,17 @@ void v99x8_device::mode_graphic4(uint16_t *ln, int line) if ( (m_cont_reg[2] & 0x20) && v9938_second_field() ) nametbl_addr += 0x8000; - pen_bg = this->pen(m_pal_ind16[m_cont_reg[7] & 0x0f]); + pen_bg = pen16(m_cont_reg[7] & 0x0f); xx = m_offset_x * 2; while (xx--) *ln++ = pen_bg; for (x=0;x<128;x++) { colour = m_vram_space->read_byte(nametbl_addr++); - pen = this->pen(m_pal_ind16[colour >> 4]); + pen = pen16(colour >> 4); *ln++ = pen; *ln++ = pen; - pen = this->pen(m_pal_ind16[colour & 15]); + pen = pen16(colour & 15); *ln++ = pen; *ln++ = pen; } @@ -1233,7 +1171,7 @@ void v99x8_device::mode_graphic4(uint16_t *ln, int line) while (xx--) *ln++ = pen_bg; } -void v99x8_device::mode_graphic5(uint16_t *ln, int line) +void v99x8_device::mode_graphic5(uint32_t *ln, int line) { int nametbl_addr, colour; int line2, linemask, x, xx; @@ -1248,8 +1186,8 @@ void v99x8_device::mode_graphic5(uint16_t *ln, int line) if ( (m_cont_reg[2] & 0x20) && v9938_second_field() ) nametbl_addr += 0x8000; - pen_bg1[0] = this->pen(m_pal_ind16[m_cont_reg[7] & 0x03]); - pen_bg0[0] = this->pen(m_pal_ind16[(m_cont_reg[7] >> 2) & 0x03]); + pen_bg1[0] = pen16(m_cont_reg[7] & 0x03); + pen_bg0[0] = pen16((m_cont_reg[7] >> 2) & 0x03); xx = m_offset_x; while (xx--) { *ln++ = pen_bg0[0]; *ln++ = pen_bg1[0]; } @@ -1258,8 +1196,8 @@ void v99x8_device::mode_graphic5(uint16_t *ln, int line) for (;x<4;x++) { - pen_bg0[x] = this->pen(m_pal_ind16[x]); - pen_bg1[x] = this->pen(m_pal_ind16[x]); + pen_bg0[x] = pen16(x); + pen_bg1[x] = pen16(x); } for (x=0;x<128;x++) @@ -1272,13 +1210,13 @@ void v99x8_device::mode_graphic5(uint16_t *ln, int line) *ln++ = pen_bg1[(colour&3)]; } - pen_bg1[0] = this->pen(m_pal_ind16[m_cont_reg[7] & 0x03]); - pen_bg0[0] = this->pen(m_pal_ind16[(m_cont_reg[7] >> 2) & 0x03]); + pen_bg1[0] = pen16(m_cont_reg[7] & 0x03); + pen_bg0[0] = pen16((m_cont_reg[7] >> 2) & 0x03); xx = 16 - m_offset_x; while (xx--) { *ln++ = pen_bg0[0]; *ln++ = pen_bg1[0]; } } -void v99x8_device::mode_graphic6(uint16_t *ln, int line) +void v99x8_device::mode_graphic6(uint32_t *ln, int line) { uint8_t colour; int line2, linemask, x, xx, nametbl_addr; @@ -1293,7 +1231,7 @@ void v99x8_device::mode_graphic6(uint16_t *ln, int line) if ( (m_cont_reg[2] & 0x20) && v9938_second_field() ) nametbl_addr += 0x10000; - pen_bg = pen(m_pal_ind16[m_cont_reg[7] & 0x0f]); + pen_bg = pen16(m_cont_reg[7] & 0x0f); xx = m_offset_x * 2; while (xx--) *ln++ = pen_bg; @@ -1303,8 +1241,8 @@ void v99x8_device::mode_graphic6(uint16_t *ln, int line) { nametbl_addr++; colour = m_vram_space->read_byte(((nametbl_addr&1) << 16) | (nametbl_addr>>1)); - fg0 = pen(m_pal_ind16[colour >> 4]); - fg1 = pen(m_pal_ind16[colour & 15]); + fg0 = pen16(colour >> 4); + fg1 = pen16(colour & 15); *ln++ = fg0; *ln++ = fg1; *ln++ = fg0; *ln++ = fg1; *ln++ = fg0; *ln++ = fg1; *ln++ = fg0; *ln++ = fg1; *ln++ = fg0; *ln++ = fg1; *ln++ = fg0; *ln++ = fg1; @@ -1317,8 +1255,8 @@ void v99x8_device::mode_graphic6(uint16_t *ln, int line) for (x=0;x<256;x++) { colour = m_vram_space->read_byte(((nametbl_addr&1) << 16) | (nametbl_addr>>1)); - *ln++ = pen(m_pal_ind16[colour >> 4]); - *ln++ = pen(m_pal_ind16[colour & 15]); + *ln++ = pen16(colour >> 4); + *ln++ = pen16(colour & 15); nametbl_addr++; } } @@ -1327,7 +1265,7 @@ void v99x8_device::mode_graphic6(uint16_t *ln, int line) while (xx--) *ln++ = pen_bg; } -void v99x8_device::mode_graphic7(uint16_t *ln, int line) +void v99x8_device::mode_graphic7(uint32_t *ln, int line) { uint8_t colour; int line2, linemask, x, xx, nametbl_addr; @@ -1341,7 +1279,7 @@ void v99x8_device::mode_graphic7(uint16_t *ln, int line) if ( (m_cont_reg[2] & 0x20) && v9938_second_field() ) nametbl_addr += 0x10000; - pen_bg = this->pen(m_pal_ind256[m_cont_reg[7]]); + pen_bg = pen256(m_cont_reg[7]); xx = m_offset_x * 2; while (xx--) *ln++ = pen_bg; @@ -1396,17 +1334,17 @@ void v99x8_device::mode_graphic7(uint16_t *ln, int line) ind = (colour[0] & 7) << 11 | (colour[1] & 7) << 14 | (colour[2] & 7) << 5 | (colour[3] & 7) << 8; - *ln++ = colour[0] & 8 ? m_pal_ind16[colour[0] >> 4] : s_pal_indYJK[ind | ((colour[0] >> 3) & 30)]; - *ln++ = colour[0] & 8 ? m_pal_ind16[colour[0] >> 4] : s_pal_indYJK[ind | ((colour[0] >> 3) & 30)]; + *ln++ = colour[0] & 8 ? pen16(colour[0] >> 4) : s_pal_indYJK[ind | ((colour[0] >> 3) & 30)]; + *ln++ = colour[0] & 8 ? pen16(colour[0] >> 4) : s_pal_indYJK[ind | ((colour[0] >> 3) & 30)]; - *ln++ = colour[1] & 8 ? m_pal_ind16[colour[1] >> 4] : s_pal_indYJK[ind | ((colour[1] >> 3) & 30)]; - *ln++ = colour[1] & 8 ? m_pal_ind16[colour[1] >> 4] : s_pal_indYJK[ind | ((colour[1] >> 3) & 30)]; + *ln++ = colour[1] & 8 ? pen16(colour[1] >> 4) : s_pal_indYJK[ind | ((colour[1] >> 3) & 30)]; + *ln++ = colour[1] & 8 ? pen16(colour[1] >> 4) : s_pal_indYJK[ind | ((colour[1] >> 3) & 30)]; - *ln++ = colour[2] & 8 ? m_pal_ind16[colour[2] >> 4] : s_pal_indYJK[ind | ((colour[2] >> 3) & 30)]; - *ln++ = colour[2] & 8 ? m_pal_ind16[colour[2] >> 4] : s_pal_indYJK[ind | ((colour[2] >> 3) & 30)]; + *ln++ = colour[2] & 8 ? pen16(colour[2] >> 4) : s_pal_indYJK[ind | ((colour[2] >> 3) & 30)]; + *ln++ = colour[2] & 8 ? pen16(colour[2] >> 4) : s_pal_indYJK[ind | ((colour[2] >> 3) & 30)]; - *ln++ = colour[3] & 8 ? m_pal_ind16[colour[3] >> 4] : s_pal_indYJK[ind | ((colour[3] >> 3) & 30)]; - *ln++ = colour[3] & 8 ? m_pal_ind16[colour[3] >> 4] : s_pal_indYJK[ind | ((colour[3] >> 3) & 30)]; + *ln++ = colour[3] & 8 ? pen16(colour[3] >> 4) : s_pal_indYJK[ind | ((colour[3] >> 3) & 30)]; + *ln++ = colour[3] & 8 ? pen16(colour[3] >> 4) : s_pal_indYJK[ind | ((colour[3] >> 3) & 30)]; nametbl_addr++; } @@ -1417,7 +1355,7 @@ void v99x8_device::mode_graphic7(uint16_t *ln, int line) { nametbl_addr++; colour = m_vram_space->read_byte(((nametbl_addr&1) << 16) | (nametbl_addr>>1)); - pen = this->pen(m_pal_ind256[colour]); + pen = pen256(colour); *ln++ = pen; *ln++ = pen; *ln++ = pen; *ln++ = pen; *ln++ = pen; *ln++ = pen; @@ -1434,7 +1372,7 @@ void v99x8_device::mode_graphic7(uint16_t *ln, int line) for (x=0;x<256;x++) { colour = m_vram_space->read_byte(((nametbl_addr&1) << 16) | (nametbl_addr>>1)); - pen = this->pen(m_pal_ind256[colour]); + pen = pen256(colour); *ln++ = pen; *ln++ = pen; nametbl_addr++; @@ -1445,13 +1383,13 @@ void v99x8_device::mode_graphic7(uint16_t *ln, int line) while (xx--) *ln++ = pen_bg; } -void v99x8_device::mode_unknown(uint16_t *ln, int line) +void v99x8_device::mode_unknown(uint32_t *ln, int line) { pen_t fg, bg; int x; - fg = pen(m_pal_ind16[m_cont_reg[7] >> 4]); - bg = pen(m_pal_ind16[m_cont_reg[7] & 15]); + fg = pen16(m_cont_reg[7] >> 4); + bg = pen16(m_cont_reg[7] & 15); x = m_offset_x * 2; while (x--) *ln++ = bg; @@ -1463,7 +1401,7 @@ void v99x8_device::mode_unknown(uint16_t *ln, int line) while (x--) *ln++ = bg; } -void v99x8_device::default_draw_sprite(uint16_t *ln, uint8_t *col) +void v99x8_device::default_draw_sprite(uint32_t *ln, uint8_t *col) { int i; ln += m_offset_x * 2; @@ -1472,8 +1410,8 @@ void v99x8_device::default_draw_sprite(uint16_t *ln, uint8_t *col) { if (col[i] & 0x80) { - *ln++ = pen(m_pal_ind16[col[i] & 0x0f]); - *ln++ = pen(m_pal_ind16[col[i] & 0x0f]); + *ln++ = pen16(col[i] & 0x0f); + *ln++ = pen16(col[i] & 0x0f); } else { @@ -1482,7 +1420,7 @@ void v99x8_device::default_draw_sprite(uint16_t *ln, uint8_t *col) } } -void v99x8_device::graphic5_draw_sprite(uint16_t *ln, uint8_t *col) +void v99x8_device::graphic5_draw_sprite(uint32_t *ln, uint8_t *col) { int i; ln += m_offset_x * 2; @@ -1491,8 +1429,8 @@ void v99x8_device::graphic5_draw_sprite(uint16_t *ln, uint8_t *col) { if (col[i] & 0x80) { - *ln++ = pen(m_pal_ind16[(col[i] >> 2) & 0x03]); - *ln++ = pen(m_pal_ind16[col[i] & 0x03]); + *ln++ = pen16((col[i] >> 2) & 0x03); + *ln++ = pen16(col[i] & 0x03); } else { @@ -1502,7 +1440,7 @@ void v99x8_device::graphic5_draw_sprite(uint16_t *ln, uint8_t *col) } -void v99x8_device::graphic7_draw_sprite(uint16_t *ln, uint8_t *col) +void v99x8_device::graphic7_draw_sprite(uint32_t *ln, uint8_t *col) { static const uint16_t g7_ind16[16] = { 0, 2, 192, 194, 48, 50, 240, 242, @@ -1515,8 +1453,9 @@ void v99x8_device::graphic7_draw_sprite(uint16_t *ln, uint8_t *col) { if (col[i] & 0x80) { - *ln++ = pen(g7_ind16[col[i] & 0x0f]); - *ln++ = pen(g7_ind16[col[i] & 0x0f]); + rgb_t color = rgb_t(pal3bit(g7_ind16[col[i] & 0x0f] >> 6), pal3bit(g7_ind16[col[i] & 0x0f] >> 3), pal3bit(g7_ind16[col[i] & 0x0f])); + *ln++ = uint32_t(color); + *ln++ = uint32_t(color); } else { @@ -1858,60 +1797,60 @@ void v99x8_device::set_mode() m_mode = i; } -void v99x8_device::refresh_16(int line) +void v99x8_device::refresh_32(int line) { bool double_lines = false; uint8_t col[256]; - uint16_t *ln, *ln2 = nullptr; + uint32_t *ln, *ln2 = nullptr; if (m_cont_reg[9] & 0x08) { - ln = &m_bitmap.pix16(m_scanline*2+((m_stat_reg[2]>>1)&1)); + ln = &m_bitmap.pix32(m_scanline*2+((m_stat_reg[2]>>1)&1)); } else { - ln = &m_bitmap.pix16(m_scanline*2); - ln2 = &m_bitmap.pix16(m_scanline*2+1); + ln = &m_bitmap.pix32(m_scanline*2); + ln2 = &m_bitmap.pix32(m_scanline*2+1); double_lines = true; } if ( !(m_cont_reg[1] & 0x40) || (m_stat_reg[2] & 0x40) ) { - (this->*s_modes[m_mode].border_16)(ln); + (this->*s_modes[m_mode].border_32)(ln); } else { - (this->*s_modes[m_mode].visible_16)(ln, line); + (this->*s_modes[m_mode].visible_32)(ln, line); if (s_modes[m_mode].sprites) { (this->*s_modes[m_mode].sprites)(line, col); - (this->*s_modes[m_mode].draw_sprite_16)(ln, col); + (this->*s_modes[m_mode].draw_sprite_32)(ln, col); } } if (double_lines) - memcpy(ln2, ln, (512 + 32) * 2); + memcpy(ln2, ln, (512 + 32) * sizeof(*ln)); } void v99x8_device::refresh_line(int line) { - int ind16, ind256; + pen_t ind16, ind256; - ind16 = m_pal_ind16[0]; - ind256 = m_pal_ind256[0]; + ind16 = pen16(0); + ind256 = pen256(0); if ( !(m_cont_reg[8] & 0x20) && (m_mode != V9938_MODE_GRAPHIC5) ) { - m_pal_ind16[0] = m_pal_ind16[(m_cont_reg[7] & 0x0f)]; - m_pal_ind256[0] = m_pal_ind256[m_cont_reg[7]]; + set_pen16(0, pen16(m_cont_reg[7] & 0x0f)); + set_pen256(0, pen256(m_cont_reg[7])); } - refresh_16 (line); + refresh_32(line); if ( !(m_cont_reg[8] & 0x20) && (m_mode != V9938_MODE_GRAPHIC5) ) { - m_pal_ind16[0] = ind16; - m_pal_ind256[0] = ind256; + set_pen16(0, ind16); + set_pen256(0, ind256); } } diff --git a/src/devices/video/v9938.h b/src/devices/video/v9938.h index a177e7daa6e..7644cd724b0 100644 --- a/src/devices/video/v9938.h +++ b/src/devices/video/v9938.h @@ -36,8 +36,7 @@ v99x8_device::VTOTAL_NTSC * 2, \ v99x8_device::VERTICAL_ADJUST * 2, \ v99x8_device::VVISIBLE_NTSC * 2 - 1 - v99x8_device::VERTICAL_ADJUST * 2) \ - MCFG_SCREEN_UPDATE_DEVICE(_v9938_tag, v9938_device, screen_update) \ - MCFG_SCREEN_PALETTE(_v9938_tag) + MCFG_SCREEN_UPDATE_DEVICE(_v9938_tag, v9938_device, screen_update) #define MCFG_V99X8_SCREEN_ADD_PAL(_screen_tag, _v9938_tag, _clock) \ MCFG_SCREEN_ADD(_screen_tag, RASTER) \ @@ -48,8 +47,7 @@ v99x8_device::VTOTAL_PAL * 2, \ v99x8_device::VERTICAL_ADJUST * 2, \ v99x8_device::VVISIBLE_PAL * 2 - 1 - v99x8_device::VERTICAL_ADJUST * 2) \ - MCFG_SCREEN_UPDATE_DEVICE(_v9938_tag, v9938_device, screen_update) \ - MCFG_SCREEN_PALETTE(_v9938_tag) + MCFG_SCREEN_UPDATE_DEVICE(_v9938_tag, v9938_device, screen_update) #define MCFG_V99X8_INTERRUPT_CALLBACK(_irq) \ devcb = &downcast<v99x8_device *>(device)->set_interrupt_callback(DEVCB_##_irq); @@ -78,11 +76,10 @@ class v99x8_device : public device_t, { public: template <class Object> devcb_base &set_interrupt_callback(Object &&irq) { return m_int_callback.set_callback(std::forward<Object>(irq)); } - int get_transpen(); - bitmap_ind16 &get_bitmap() { return m_bitmap; } + bitmap_rgb32 &get_bitmap() { return m_bitmap; } void update_mouse_state(int mx_delta, int my_delta, int button_state); - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); DECLARE_READ8_MEMBER( read ); DECLARE_WRITE8_MEMBER( write ); @@ -132,12 +129,18 @@ protected: virtual space_config_vector memory_space_config() const override; virtual void palette_init() = 0; + virtual u32 palette_entries() const override { return 16 + 256; } void configure_pal_ntsc(); void set_screen_parameters(); private: // internal helpers + pen_t pen16(int index) const { return uint32_t(pen_color(index)); } + pen_t pen256(int index) const { return uint32_t(pen_color(index + 16)); } + void set_pen16(int index, pen_t pen) { set_pen_color(index, rgb_t(pen).set_a(index != 0 ? 0xff : 0x00)); } + void set_pen256(int index, pen_t pen) { set_pen_color(index + 16, rgb_t(pen).set_a(index != 0 ? 0xff : 0x00)); } + inline int position_offset(uint8_t value) { value &= 0x0f; return (value < 8) ? -value : 16 - value; } void reset_palette(); void vram_write(int offset, int data); @@ -145,29 +148,29 @@ private: void check_int(); void register_write(int reg, int data); - void default_border(uint16_t *ln); - void graphic7_border(uint16_t *ln); - void graphic5_border(uint16_t *ln); - void mode_text1(uint16_t *ln, int line); - void mode_text2(uint16_t *ln, int line); - void mode_multi(uint16_t *ln, int line); - void mode_graphic1(uint16_t *ln, int line); - void mode_graphic23(uint16_t *ln, int line); - void mode_graphic4(uint16_t *ln, int line); - void mode_graphic5(uint16_t *ln, int line); - void mode_graphic6(uint16_t *ln, int line); - void mode_graphic7(uint16_t *ln, int line); + void default_border(uint32_t *ln); + void graphic7_border(uint32_t *ln); + void graphic5_border(uint32_t *ln); + void mode_text1(uint32_t *ln, int line); + void mode_text2(uint32_t *ln, int line); + void mode_multi(uint32_t *ln, int line); + void mode_graphic1(uint32_t *ln, int line); + void mode_graphic23(uint32_t *ln, int line); + void mode_graphic4(uint32_t *ln, int line); + void mode_graphic5(uint32_t *ln, int line); + void mode_graphic6(uint32_t *ln, int line); + void mode_graphic7(uint32_t *ln, int line); // template<typename _PixelType, int _Width> void mode_yae(_PixelType *ln, int line); // template<typename _PixelType, int _Width> void mode_yjk(_PixelType *ln, int line); - void mode_unknown(uint16_t *ln, int line); - void default_draw_sprite(uint16_t *ln, uint8_t *col); - void graphic5_draw_sprite(uint16_t *ln, uint8_t *col); - void graphic7_draw_sprite(uint16_t *ln, uint8_t *col); + void mode_unknown(uint32_t *ln, int line); + void default_draw_sprite(uint32_t *ln, uint8_t *col); + void graphic5_draw_sprite(uint32_t *ln, uint8_t *col); + void graphic7_draw_sprite(uint32_t *ln, uint8_t *col); void sprite_mode1(int line, uint8_t *col); void sprite_mode2(int line, uint8_t *col); void set_mode(); - void refresh_16(int line); + void refresh_32(int line); void refresh_line(int line); void interrupt_start_vblank(); @@ -233,11 +236,8 @@ private: uint8_t m_mx_delta, m_my_delta; // mouse & lightpen uint8_t m_button_state; - // palette - uint16_t m_pal_ind16[16]; - uint16_t m_pal_ind256[256]; // render bitmap - bitmap_ind16 m_bitmap; + bitmap_rgb32 m_bitmap; // Command unit struct { int SX,SY; @@ -257,10 +257,10 @@ private: struct v99x8_mode { uint8_t m; - void (v99x8_device::*visible_16)(uint16_t*, int); - void (v99x8_device::*border_16)(uint16_t*); + void (v99x8_device::*visible_32)(uint32_t*, int); + void (v99x8_device::*border_32)(uint32_t*); void (v99x8_device::*sprites)(int, uint8_t*); - void (v99x8_device::*draw_sprite_16)(uint16_t*, uint8_t*); + void (v99x8_device::*draw_sprite_32)(uint32_t*, uint8_t*); } ; static const v99x8_mode s_modes[]; emu_timer *m_line_timer; @@ -270,7 +270,7 @@ private: int m_scanline_max; int m_height; protected: - static uint16_t s_pal_indYJK[0x20000]; + static uint32_t s_pal_indYJK[0x20000]; }; @@ -281,7 +281,6 @@ public: protected: virtual void palette_init() override; - virtual u32 palette_entries() const override { return 512; } }; class v9958_device : public v99x8_device @@ -291,7 +290,6 @@ public: protected: virtual void palette_init() override; - virtual u32 palette_entries() const override { return 19780; } }; diff --git a/src/devices/video/vooddefs.h b/src/devices/video/vooddefs.h index 55c22903799..cad79c3d7f2 100644 --- a/src/devices/video/vooddefs.h +++ b/src/devices/video/vooddefs.h @@ -2641,9 +2641,9 @@ void voodoo_device::raster_##name(void *destbase, int32_t y, const poly_extent * int32_t stopx = extent->stopx; \ rgbaint_t iterargb, iterargbDelta; \ int32_t iterz; \ - int64_t iterw, iterw0 = 0, iterw1 = 0; \ - int64_t iters0 = 0, iters1 = 0; \ - int64_t itert0 = 0, itert1 = 0; \ + int64_t iterw; \ + tmu_state::stw_t iterstw0, iterstw1; \ + tmu_state::stw_t deltastw0, deltastw1; \ uint16_t *depth; \ uint16_t *dest; \ int32_t dx, dy; \ @@ -2713,15 +2713,19 @@ void voodoo_device::raster_##name(void *destbase, int32_t y, const poly_extent * iterw = extra->startw + dy * extra->dwdy + dx * extra->dwdx; \ if (TMUS >= 1) \ { \ - iterw0 = extra->startw0 + dy * extra->dw0dy + dx * extra->dw0dx; \ - iters0 = extra->starts0 + dy * extra->ds0dy + dx * extra->ds0dx; \ - itert0 = extra->startt0 + dy * extra->dt0dy + dx * extra->dt0dx; \ + iterstw0.set( \ + extra->starts0 + dy * extra->ds0dy + dx * extra->ds0dx, \ + extra->startt0 + dy * extra->dt0dy + dx * extra->dt0dx, \ + extra->startw0 + dy * extra->dw0dy + dx * extra->dw0dx); \ + deltastw0.set(extra->ds0dx, extra->dt0dx, extra->dw0dx); \ } \ if (TMUS >= 2) \ { \ - iterw1 = extra->startw1 + dy * extra->dw1dy + dx * extra->dw1dx; \ - iters1 = extra->starts1 + dy * extra->ds1dy + dx * extra->ds1dx; \ - itert1 = extra->startt1 + dy * extra->dt1dy + dx * extra->dt1dx; \ + iterstw1.set( \ + extra->starts1 + dy * extra->ds1dy + dx * extra->ds1dx, \ + extra->startt1 + dy * extra->dt1dy + dx * extra->dt1dx, \ + extra->startw1 + dy * extra->dw1dy + dx * extra->dw1dx); \ + deltastw1.set(extra->ds1dx, extra->dt1dx, extra->dw1dx); \ } \ extra->info->hits++; \ /* loop in X */ \ @@ -2743,7 +2747,7 @@ void voodoo_device::raster_##name(void *destbase, int32_t y, const poly_extent * int32_t tmp; \ const rgbaint_t texelZero(0); \ texel = vd->tmu[1].genTexture(x, dither4, TEXMODE1, vd->tmu[1].lookup, extra->lodbase1, \ - iters1, itert1, iterw1, tmp); \ + iterstw1, tmp); \ texel = vd->tmu[1].combineTexture(TEXMODE1, texel, texelZero, tmp); \ } \ /* run the texture pipeline on TMU0 to produce a final */ \ @@ -2756,7 +2760,7 @@ void voodoo_device::raster_##name(void *destbase, int32_t y, const poly_extent * int32_t lod0; \ rgbaint_t texelT0; \ texelT0 = vd->tmu[0].genTexture(x, dither4, TEXMODE0, vd->tmu[0].lookup, extra->lodbase0, \ - iters0, itert0, iterw0, lod0); \ + iterstw0, lod0); \ texel = vd->tmu[0].combineTexture(TEXMODE0, texelT0, texel, lod0); \ } \ else \ @@ -2792,15 +2796,11 @@ void voodoo_device::raster_##name(void *destbase, int32_t y, const poly_extent * iterw += extra->dwdx; \ if (TMUS >= 1) \ { \ - iterw0 += extra->dw0dx; \ - iters0 += extra->ds0dx; \ - itert0 += extra->dt0dx; \ + iterstw0.add(deltastw0); \ } \ if (TMUS >= 2) \ { \ - iterw1 += extra->dw1dx; \ - iters1 += extra->ds1dx; \ - itert1 += extra->dt1dx; \ + iterstw1.add(deltastw1); \ } \ } \ } @@ -2812,38 +2812,23 @@ void voodoo_device::raster_##name(void *destbase, int32_t y, const poly_extent * // The maximum error using a 4 bit lookup from the mantissa is 0.0875, which is less than 1/2 lsb (0.125) for 2 bits of fraction. // An offset of +(56 << 8) is added for alignment in multi_reciplog // ****************************************************************************************************************************** -static inline int32_t ATTR_FORCE_INLINE new_log2(double &value) +inline int32_t ATTR_FORCE_INLINE voodoo_device::tmu_state::new_log2(double &value, const int &offset) { - static const int32_t new_log2_table[16] = {0 + (56 << 8), 22 + (56 << 8), 44 + (56 << 8), 63 + (56 << 8), 82 + (56 << 8), - 100 + (56 << 8), 118 + (56 << 8), 134 + (56 << 8), 150 + (56 << 8), 165 + (56 << 8), 179 + (56 << 8), 193 + (56 << 8), - 207 + (56 << 8), 220 + (56 << 8), 232 + (56 << 8), 244 + (56 << 8)}; + static const int32_t new_log2_table[16] = {0, 22, 44, 63, 82, 100, 118, 134, 150, 165, 179, 193, 207, 220, 232, 244}; uint64_t ival = *((uint64_t *)&value); // Return 0 if negative if (ival & ((uint64_t)1 << 63)) return 0; // We zero the result if negative so don't worry about the sign bit int32_t exp = (ival>>52); - exp -= 1023+32; + exp -= 1023+32-offset; exp <<= 8; uint32_t addr = (uint64_t)(ival>>48) & 0xf; exp += new_log2_table[addr]; return exp; } -// Computes A/C and B/C and returns log2 of 1/C -// A, B and C are 16.32 values. The results are 24.8. -static inline void ATTR_FORCE_INLINE multi_reciplog(int64_t valueA, int64_t valueB, int64_t valueC, int32_t &log, int32_t &resA, int32_t &resB) -{ - double recip = double(1ULL<<(47-39))/valueC; - double resAD = valueA * recip; - double resBD = valueB * recip; - log = new_log2(recip); - resA = resAD; - resB = resBD; -} - - -inline rgbaint_t ATTR_FORCE_INLINE voodoo_device::tmu_state::genTexture(int32_t x, const uint8_t *dither4, const uint32_t TEXMODE, rgb_t *LOOKUP, int32_t LODBASE, int64_t ITERS, int64_t ITERT, int64_t ITERW, int32_t &lod) +inline rgbaint_t ATTR_FORCE_INLINE voodoo_device::tmu_state::genTexture(int32_t x, const uint8_t *dither4, const uint32_t TEXMODE, rgb_t *LOOKUP, int32_t LODBASE, const stw_t &iterstw, int32_t &lod) { rgbaint_t result; int32_t s, t, ilod; @@ -2853,23 +2838,16 @@ inline rgbaint_t ATTR_FORCE_INLINE voodoo_device::tmu_state::genTexture(int32_t if (TEXMODE_ENABLE_PERSPECTIVE(TEXMODE)) { int32_t wLog; - if (USE_FAST_RECIP) { - const int32_t oow = fast_reciplog((ITERW), &wLog); - s = ((int64_t)oow * (ITERS)) >> (29+10); - t = ((int64_t)oow * (ITERT)) >> (29+10); - } else { - multi_reciplog(ITERS, ITERT, ITERW, wLog, s, t); - } + iterstw.calc_stow(s, t, wLog); lod += wLog; } else { - s = (ITERS) >> (14+10); - t = (ITERT) >> (14+10); + iterstw.get_st_shiftr(s, t, (14 + 10)); } /* clamp W */ - if (TEXMODE_CLAMP_NEG_W(TEXMODE) && (ITERW) < 0) + if (TEXMODE_CLAMP_NEG_W(TEXMODE) && iterstw.is_w_neg()) { s = t = 0; } diff --git a/src/devices/video/voodoo.cpp b/src/devices/video/voodoo.cpp index a5ac18a7262..259e24899e5 100644 --- a/src/devices/video/voodoo.cpp +++ b/src/devices/video/voodoo.cpp @@ -1431,8 +1431,8 @@ inline int32_t voodoo_device::tmu_state::prepare() return (-lodbase + (12 << 8)) / 2; #else double tmpTex = texdx; - lodbase = new_log2(tmpTex); - return (lodbase + (12 << 8) - (56 << 8)) / 2; + lodbase = new_log2(tmpTex, 0); + return (lodbase + (12 << 8)) / 2; #endif } @@ -2588,8 +2588,8 @@ int32_t voodoo_device::register_w(voodoo_device *vd, offs_t offset, uint32_t dat visarea.set(hbp, hbp + hvis - 1, vbp, vbp + vvis - 1); /* keep within bounds */ - visarea.max_x = std::min(visarea.max_x, htotal - 1); - visarea.max_y = std::min(visarea.max_y, vtotal - 1); + visarea.max_x = (std::min)(visarea.max_x, htotal - 1); + visarea.max_y = (std::min)(visarea.max_y, vtotal - 1); /* compute the new period for standard res, medium res, and VGA res */ stdperiod = HZ_TO_ATTOSECONDS(15750) * vtotal; @@ -5258,7 +5258,7 @@ int32_t voodoo_device::fastfill(voodoo_device *vd) for (y = sy; y < ey; y += ARRAY_LENGTH(extents)) { poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(vd->poly); - int count = std::min(ey - y, int(ARRAY_LENGTH(extents))); + int count = (std::min)(ey - y, int(ARRAY_LENGTH(extents))); extra->device = vd; memcpy(extra->dither, dithermatrix, sizeof(extra->dither)); diff --git a/src/devices/video/voodoo.h b/src/devices/video/voodoo.h index af3bd9a17d3..fd3fc7b8a78 100644 --- a/src/devices/video/voodoo.h +++ b/src/devices/video/voodoo.h @@ -1593,10 +1593,12 @@ protected: struct tmu_state { + class stw_t; void recompute_texture_params(); void init(uint8_t vdt, tmu_shared_state &share, voodoo_reg *r, void *memory, int tmem); int32_t prepare(); - rgbaint_t genTexture(int32_t x, const uint8_t *dither4, const uint32_t TEXMODE, rgb_t *LOOKUP, int32_t LODBASE, int64_t ITERS, int64_t ITERT, int64_t ITERW, int32_t &lod); + static int32_t new_log2(double &value, const int &offset); + rgbaint_t genTexture(int32_t x, const uint8_t *dither4, const uint32_t TEXMODE, rgb_t *LOOKUP, int32_t LODBASE, const stw_t &iterstw, int32_t &lod); rgbaint_t combineTexture(const uint32_t TEXMODE, const rgbaint_t& c_local, const rgbaint_t& c_other, int32_t lod); struct ncc_table @@ -1958,4 +1960,86 @@ DECLARE_DEVICE_TYPE(VOODOO_2, voodoo_2_device) DECLARE_DEVICE_TYPE(VOODOO_BANSHEE, voodoo_banshee_device) DECLARE_DEVICE_TYPE(VOODOO_3, voodoo_3_device) +// use SSE on 64-bit implementations, where it can be assumed +#if 1 && ((!defined(MAME_DEBUG) || defined(__OPTIMIZE__)) && (defined(__SSE2__) || defined(_MSC_VER)) && defined(PTR64)) +#include <emmintrin.h> +#ifdef __SSE4_1__ +#include <smmintrin.h> +#endif +class voodoo_device::tmu_state::stw_t +{ +public: + stw_t() {} + stw_t(const stw_t& other) = default; + stw_t &operator=(const stw_t& other) = default; + + inline void set(s64 s, s64 t, s64 w) { m_st = _mm_set_pd(s, t); m_w = _mm_set1_pd(w); } + inline int is_w_neg() const { return _mm_comilt_sd(m_w, _mm_set1_pd(0.0)); } + inline void get_st_shiftr(s32 &s, s32 &t, const s32 &shift) const { + s64 tmpS = _mm_cvtsd_si64(_mm_shuffle_pd(m_st, _mm_setzero_pd(), 1)); + s = tmpS >> shift; + s64 tmpT = _mm_cvtsd_si64(m_st); + t = tmpT >> shift; + } + inline void add(const stw_t& other) + { + m_st = _mm_add_pd(m_st, other.m_st); + m_w = _mm_add_pd(m_w, other.m_w); + } + inline void calc_stow(s32 &sow, s32 &tow, int32_t &oowlog) const + { + __m128d tmp = _mm_div_pd(m_st, m_w); + // Allow for 8 bits of decimal in integer + tmp = _mm_mul_pd(tmp, _mm_set1_pd(256.0)); + __m128i tmp2 = _mm_cvttpd_epi32(tmp); +#ifdef __SSE4_1__ + sow = _mm_extract_epi32(tmp2, 1); + tow = _mm_extract_epi32(tmp2, 0); +#else + sow = _mm_cvtsi128_si32(_mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 0, 1))); + tow = _mm_cvtsi128_si32(tmp2); +#endif + double dW = _mm_cvtsd_f64(m_w); + oowlog = -new_log2(dW, 0); + } +private: + __m128d m_st; + __m128d m_w; +}; +#else +class voodoo_device::tmu_state::stw_t +{ +public: + stw_t() {} + stw_t(const stw_t& other) = default; + stw_t &operator=(const stw_t& other) = default; + + inline void set(s64 s, s64 t, s64 w) { m_s = s; m_t = t; m_w = w; } + inline int is_w_neg() const { return (m_w < 0) ? 1 : 0; } + inline void get_st_shiftr(s32 &s, s32 &t, const s32 &shift) const { + s = m_s >> shift; + t = m_t >> shift; + } + inline void add(const stw_t& other) + { + m_s += other.m_s; + m_t += other.m_t; + m_w += other.m_w; + } + // Computes s/w and t/w and returns log2 of 1/w + // s, t and c are 16.32 values. The results are 24.8. + inline void calc_stow(s32 &sow, s32 &tow, int32_t &oowlog) const + { + double recip = double(1ULL << (47 - 39)) / m_w; + double resAD = m_s * recip; + double resBD = m_t * recip; + oowlog = new_log2(recip, 56); + sow = resAD; + tow = resBD; + } +private: + s64 m_s, m_t, m_w; +}; +#endif + #endif // MAME_VIDEO_VOODOO_H diff --git a/src/emu/addrmap.cpp b/src/emu/addrmap.cpp index 0d8d7bc4eef..5f717f3f79a 100644 --- a/src/emu/addrmap.cpp +++ b/src/emu/addrmap.cpp @@ -41,11 +41,7 @@ address_map_entry::address_map_entry(device_t &device, address_map &map, offs_t m_region(nullptr), m_rgnoffs(0), m_submap_bits(0), - m_memory(nullptr), - m_bytestart(0), - m_byteend(0), - m_bytemirror(0), - m_bytemask(0) + m_memory(nullptr) { } @@ -404,7 +400,7 @@ address_map::address_map(const address_space &space, offs_t start, offs_t end, i m_device(&device), m_databits(space.data_width()), m_unmapval(space.unmap()), - m_globalmask(space.bytemask()) + m_globalmask(space.addrmask()) { range(start, end).set_submap(DEVICE_SELF, submap_delegate, bits, unitmask); } @@ -609,8 +605,8 @@ void address_map::map_validity_check(validity_checker &valid, int spacenum) cons { // it's safe to assume here that the device has a memory interface and a config for this space const address_space_config &spaceconfig = *m_device->memory().space_config(spacenum); - int datawidth = spaceconfig.m_databus_width; - int alignunit = datawidth / 8; + int datawidth = spaceconfig.m_data_width; + int alignunit = spaceconfig.alignment(); bool detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true; @@ -624,16 +620,13 @@ void address_map::map_validity_check(validity_checker &valid, int spacenum) cons if (m_databits != datawidth) osd_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig.m_name, datawidth, m_databits); - offs_t globalmask = 0xffffffffUL >> (32 - spaceconfig.m_addrbus_width); + offs_t globalmask = 0xffffffffUL >> (32 - spaceconfig.m_addr_width); if (m_globalmask != 0) globalmask = m_globalmask; // loop over entries and look for errors for (address_map_entry &entry : m_entrylist) { - u32 bytestart = spaceconfig.addr2byte(entry.m_addrstart); - u32 byteend = spaceconfig.addr2byte_end(entry.m_addrend); - // look for overlapping entries if (!detected_overlap) { @@ -653,7 +646,7 @@ void address_map::map_validity_check(validity_checker &valid, int spacenum) cons } // look for inverted start/end pairs - if (byteend < bytestart) + if (entry.m_addrend < entry.m_addrstart) osd_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend); // look for ranges outside the global mask @@ -663,7 +656,7 @@ void address_map::map_validity_check(validity_checker &valid, int spacenum) cons osd_printf_error("In %s memory range %x-%x, end address is outside of the global address mask %x\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, globalmask); // look for misaligned entries - if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1)) + if ((entry.m_addrstart & (alignunit - 1)) != 0 || (entry.m_addrend & (alignunit - 1)) != (alignunit - 1)) osd_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, alignunit); // verify mask/mirror/select @@ -715,7 +708,7 @@ void address_map::map_validity_check(validity_checker &valid, int spacenum) cons { // verify the address range is within the region's bounds offs_t const length = region.get_length(); - if (entry.m_rgnoffs + (byteend - bytestart + 1) > length) + if (entry.m_rgnoffs + spaceconfig.addr2byte(entry.m_addrend - entry.m_addrstart + 1) > length) osd_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig.m_name, entry.m_addrstart, entry.m_addrend, entry.m_region, length); found = true; } diff --git a/src/emu/addrmap.h b/src/emu/addrmap.h index c56c9257d47..587f9a16e33 100644 --- a/src/emu/addrmap.h +++ b/src/emu/addrmap.h @@ -154,10 +154,6 @@ public: // information used during processing void * m_memory; // pointer to memory backing this entry - offs_t m_bytestart; // byte-adjusted start address - offs_t m_byteend; // byte-adjusted end address - offs_t m_bytemirror; // byte-adjusted mirror bits - offs_t m_bytemask; // byte-adjusted mask bits // handler setters for 8-bit functions address_map_entry &set_handler(read8_delegate func, u64 mask = 0); diff --git a/src/emu/debug/debugbuf.cpp b/src/emu/debug/debugbuf.cpp new file mode 100644 index 00000000000..bd24f475340 --- /dev/null +++ b/src/emu/debug/debugbuf.cpp @@ -0,0 +1,1379 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Buffering interface for the disassembly windows + +#include "emu.h" +#include "debugbuf.h" + +debug_disasm_buffer::debug_data_buffer::debug_data_buffer(util::disasm_interface *intf) : m_intf(intf) +{ + m_space = nullptr; + m_back = nullptr; + m_opcode = true; + m_lstart = m_lend = 0; + m_wrapped = false; +} + +bool debug_disasm_buffer::debug_data_buffer::active() const +{ + return m_space || m_back; +} + +void debug_disasm_buffer::debug_data_buffer::set_source(address_space &space) +{ + m_space = &space; + setup_methods(); +} + +void debug_disasm_buffer::debug_data_buffer::set_source(debug_data_buffer &back, bool opcode) +{ + m_back = &back; + m_opcode = opcode; + setup_methods(); +} + +u8 debug_disasm_buffer::debug_data_buffer::r8 (offs_t pc) const +{ + return m_do_r8(pc & m_pc_mask); +} + +u16 debug_disasm_buffer::debug_data_buffer::r16(offs_t pc) const +{ + return m_do_r16(pc & m_pc_mask); +} + +u32 debug_disasm_buffer::debug_data_buffer::r32(offs_t pc) const +{ + return m_do_r32(pc & m_pc_mask); +} + +u64 debug_disasm_buffer::debug_data_buffer::r64(offs_t pc) const +{ + return m_do_r64(pc & m_pc_mask); +} + +address_space *debug_disasm_buffer::debug_data_buffer::get_underlying_space() const +{ + return m_space; +} + +void debug_disasm_buffer::debug_data_buffer::fill(offs_t lstart, offs_t size) const +{ + offs_t lend = (lstart + size) & m_pc_mask; + if(m_page_mask) { + if((lstart ^ lend) & ~m_page_mask) { + lstart = lstart & ~m_page_mask; + lend = (((lend - 1) | m_page_mask) + 1) & m_pc_mask; + } + } + + if(!m_buffer.empty()) { + if(m_lstart == m_lend) + return; + if(m_wrapped) { + if(lstart >= m_lstart && (lend > m_lstart || lend <= m_lend)) + return; + if(lstart < m_lend && lend <= m_lend) + return; + } else { + if(lstart < lend && lstart >= m_lstart && lend <= m_lend) + return; + } + } + + if(m_buffer.empty()) { + m_lstart = lstart; + m_lend = lend; + m_wrapped = lend < lstart; + offs_t size = m_pc_delta_to_bytes((lend - lstart) & m_pc_mask); + m_buffer.resize(size); + m_do_fill(lstart, lend); + + } else { + offs_t n_lstart, n_lend; + if(lstart > lend) { + if(m_wrapped) { + // Old is wrapped, new is wrapped, just extend + n_lstart = std::min(m_lstart, lstart); + n_lend = std::max(m_lend, lend); + } else { + // Old is unwrapped, new is wrapped. Reduce the amount of "useless" data. + offs_t gap_post = m_lend >= lstart ? 0 : lstart - m_lend; + offs_t gap_pre = m_lstart <= lend ? 0 : m_lstart - lend; + if(gap_post < gap_pre) { + // extend the old one end until it reaches the new one + n_lstart = std::min(m_lstart, lstart); + n_lend = lend; + } else { + // extend the old one start until it reaches the new one + n_lstart = lstart; + n_lend = std::max(m_lend, lend); + } + m_wrapped = true; + } + } else if(m_wrapped) { + // Old is wrapped, new is unwrapped. Reduce the amount of "useless" data. + offs_t gap_post = m_lend >= lstart ? 0 : lstart - m_lend; + offs_t gap_pre = m_lstart <= lend ? 0 : m_lstart - lend; + if(gap_post < gap_pre) { + // extend the old one end until it reaches the new one + n_lstart = m_lstart; + n_lend = lend; + } else { + // extend the old one start until it reaches the new one + n_lstart = lstart; + n_lend = m_lend; + } + } else { + // Both are unwrapped, decide whether to wrap. + // If there's overlap, don't wrap, just extend + if(lend >= m_lstart && lstart < m_lend) { + n_lstart = std::min(m_lstart, lstart); + n_lend = std::max(m_lend, lend); + } else { + // If there's no overlap, compute the gap with wrapping or without + offs_t gap_unwrapped = lstart > m_lstart ? lstart - m_lend : m_lstart - lend; + offs_t gap_wrapped = lstart > m_lstart ? (m_lstart - lend) & m_pc_mask : (lstart - m_lend) & m_pc_mask; + if(gap_unwrapped < gap_wrapped) { + n_lstart = std::min(m_lstart, lstart); + n_lend = std::max(m_lend, lend); + } else { + n_lstart = std::max(m_lstart, lstart); + n_lend = std::min(m_lend, lend); + m_wrapped = true; + } + } + } + + if(n_lstart != m_lstart) { + offs_t size = m_pc_delta_to_bytes((m_lstart - n_lstart) & m_pc_mask); + m_buffer.insert(m_buffer.begin(), size, 0); + offs_t old_lstart = m_lstart; + m_lstart = n_lstart; + m_do_fill(m_lstart, old_lstart); + } + if(n_lend != m_lend) { + offs_t size = m_pc_delta_to_bytes((n_lend - m_lstart) & m_pc_mask); + m_buffer.resize(size); + offs_t old_lend = m_lend; + m_lend = n_lend; + m_do_fill(old_lend, m_lend); + } + } +} + +std::string debug_disasm_buffer::debug_data_buffer::data_to_string(offs_t pc, offs_t size) const +{ + return m_data_to_string(pc, size); +} + +void debug_disasm_buffer::debug_data_buffer::data_get(offs_t pc, offs_t size, std::vector<u8> &data) const +{ + return m_data_get(pc, size, data); +} + +void debug_disasm_buffer::debug_data_buffer::setup_methods() +{ + address_space *space = m_space ? m_space : m_back->get_underlying_space(); + int shift = space->addr_shift(); + int alignment = m_intf->opcode_alignment(); + endianness_t endian = space->endianness(); + + m_pc_mask = space->logaddrmask(); + + if(m_intf->interface_flags() & util::disasm_interface::PAGED) + m_page_mask = (1 << m_intf->page_address_bits()) - 1; + else + m_page_mask = 0; + + // Define the byte counter + switch(shift) { + case -3: m_pc_delta_to_bytes = [](offs_t delta) { return delta << 3; }; break; + case -2: m_pc_delta_to_bytes = [](offs_t delta) { return delta << 2; }; break; + case -1: m_pc_delta_to_bytes = [](offs_t delta) { return delta << 1; }; break; + case 0: m_pc_delta_to_bytes = [](offs_t delta) { return delta; }; break; + case 3: m_pc_delta_to_bytes = [](offs_t delta) { return delta >> 3; }; break; + default: throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer::setup_methods: Abnormal address buf shift\n"); + } + + // Define the filler + if(m_space) { + // get the data from given space + if(m_intf->interface_flags() & util::disasm_interface::NONLINEAR_PC) { + switch(shift) { + case -1: + m_do_fill = [this](offs_t lstart, offs_t lend) { + auto dis = m_space->machine().disable_side_effect(); + u16 *dest = get_ptr<u16>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { + offs_t tpc = m_intf->pc_linear_to_real(lpc); + if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) + *dest++ = m_space->read_word(tpc); + else + *dest++ = 0; + } + }; + break; + case 0: + m_do_fill = [this](offs_t lstart, offs_t lend) { + auto dis = m_space->machine().disable_side_effect(); + u8 *dest = get_ptr<u8>(lstart); + u32 steps = 0; + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { + offs_t tpc = m_intf->pc_linear_to_real(lpc); + if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) + *dest++ = m_space->read_byte(tpc); + else + *dest++ = 0; + steps++; + } + }; + break; + } + + } else { + switch(shift) { + case -3: // bus granularity 64 + m_do_fill = [this](offs_t lstart, offs_t lend) { + auto dis = m_space->machine().disable_side_effect(); + u64 *dest = get_ptr<u64>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { + offs_t tpc = lpc; + if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) + *dest++ = m_space->read_qword(tpc); + else + *dest++ = 0; + } + }; + break; + + case -2: // bus granularity 32 + m_do_fill = [this](offs_t lstart, offs_t lend) { + auto dis = m_space->machine().disable_side_effect(); + u32 *dest = get_ptr<u32>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { + offs_t tpc = lpc; + if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) + *dest++ = m_space->read_dword(tpc); + else + *dest++ = 0; + } + }; + break; + + case -1: // bus granularity 16 + m_do_fill = [this](offs_t lstart, offs_t lend) { + auto dis = m_space->machine().disable_side_effect(); + u16 *dest = get_ptr<u16>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { + offs_t tpc = lpc; + if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) + *dest++ = m_space->read_word(tpc); + else + *dest++ = 0; + } + }; + break; + + case 0: // bus granularity 8 + m_do_fill = [this](offs_t lstart, offs_t lend) { + auto dis = m_space->machine().disable_side_effect(); + u8 *dest = get_ptr<u8>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) { + offs_t tpc = lpc; + if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) + *dest++ = m_space->read_byte(tpc); + else + *dest++ = 0; + } + }; + break; + + case 3: // bus granularity 1, stored as u16 + m_do_fill = [this](offs_t lstart, offs_t lend) { + auto dis = m_space->machine().disable_side_effect(); + u16 *dest = reinterpret_cast<u16 *>(&m_buffer[0]) + ((lstart - m_lstart) >> 4); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 0x10) & m_pc_mask) { + offs_t tpc = lpc; + if (m_space->device().memory().translate(m_space->spacenum(), TRANSLATE_FETCH_DEBUG, tpc)) + *dest++ = m_space->read_word(tpc); + else + *dest++ = 0; + } + }; + break; + } + } + } else { + // get the data from a back buffer and decrypt it through the device + // size chosen is alignment * granularity + assert(!(m_intf->interface_flags() & util::disasm_interface::NONLINEAR_PC)); + + switch(shift) { + case -3: // bus granularity 64, endianness irrelevant + m_do_fill = [this](offs_t lstart, offs_t lend) { + u64 *dest = get_ptr<u64>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) + *dest++ = m_intf->decrypt64(m_back->r64(lpc), lpc, m_opcode); + }; + break; + + case -2: // bus granularity 32 + switch(alignment) { + case 1: // bus granularity 32, alignment 32, endianness irrelevant + m_do_fill = [this](offs_t lstart, offs_t lend) { + u32 *dest = get_ptr<u32>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) + *dest++ = m_intf->decrypt32(m_back->r32(lpc), lpc, m_opcode); + }; + break; + + case 2: // bus granularity 32, alignment 64 + switch(endian) { + case ENDIANNESS_LITTLE: // bus granularity 32, alignment 64, little endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u32 *dest = get_ptr<u32>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 2) & m_pc_mask) { + u64 val = m_intf->decrypt64(m_back->r64(lpc), lpc, m_opcode); + *dest++ = val; + *dest++ = val >> 32; + } + }; + break; + + case ENDIANNESS_BIG: // bus granularity 32, bus width 64, big endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u32 *dest = get_ptr<u32>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 2) & m_pc_mask) { + u64 val = m_intf->decrypt64(m_back->r64(lpc), lpc, m_opcode); + *dest++ = val >> 32; + *dest++ = val; + } + }; + break; + } + break; + } + break; + + case -1: // bus granularity 16 + switch(alignment) { + case 1: // bus granularity 16, alignment 16, endianness irrelevant + m_do_fill = [this](offs_t lstart, offs_t lend) { + u16 *dest = get_ptr<u16>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) + *dest++ = m_intf->decrypt16(m_back->r16(lpc), lpc, m_opcode); + }; + break; + + case 2: // bus granularity 16, alignment 32 + switch(endian) { + case ENDIANNESS_LITTLE: // bus granularity 16, alignment 32, little endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u16 *dest = get_ptr<u16>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 2) & m_pc_mask) { + u32 val = m_intf->decrypt32(m_back->r32(lpc), lpc, m_opcode); + *dest++ = val; + *dest++ = val >> 16; + } + }; + break; + + case ENDIANNESS_BIG: // bus granularity 16, alignment 32, big endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u16 *dest = get_ptr<u16>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 2) & m_pc_mask) { + u32 val = m_intf->decrypt32(m_back->r32(lpc), lpc, m_opcode); + *dest++ = val >> 16; + *dest++ = val; + } + }; + break; + } + break; + + case 4: // bus granularity 16, alignment 64 + switch(endian) { + case ENDIANNESS_LITTLE: // bus granularity 16, alignment 64, little endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u16 *dest = get_ptr<u16>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 4) & m_pc_mask) { + u64 val = m_intf->decrypt64(m_back->r64(lpc), lpc, m_opcode); + *dest++ = val; + *dest++ = val >> 16; + *dest++ = val >> 32; + *dest++ = val >> 48; + } + }; + break; + + case ENDIANNESS_BIG: // bus granularity 16, alignment 64, big endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u16 *dest = get_ptr<u16>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 4) & m_pc_mask) { + u64 val = m_intf->decrypt64(m_back->r64(lpc), lpc, m_opcode); + *dest++ = val >> 48; + *dest++ = val >> 32; + *dest++ = val >> 16; + *dest++ = val; + } + }; + break; + } + break; + } + break; + + case 0: // bus granularity 8 + switch(alignment) { + case 1: // bus granularity 8, alignment 8, endianness irrelevant + m_do_fill = [this](offs_t lstart, offs_t lend) { + u8 *dest = get_ptr<u8>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 1) & m_pc_mask) + *dest++ = m_intf->decrypt8(m_back->r8(lpc), lpc, m_opcode); + }; + break; + + case 2: // bus granularity 8, alignment 16 + switch(endian) { + case ENDIANNESS_LITTLE: // bus granularity 8, alignment 16, little endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u8 *dest = get_ptr<u8>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 2) & m_pc_mask) { + u16 val = m_intf->decrypt16(m_back->r16(lpc), lpc, m_opcode); + *dest++ = val; + *dest++ = val >> 8; + } + }; + break; + + case ENDIANNESS_BIG: // bus granularity 16, alignment 16, big endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u8 *dest = get_ptr<u8>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 2) & m_pc_mask) { + u16 val = m_intf->decrypt16(m_back->r16(lpc), lpc, m_opcode); + *dest++ = val >> 8; + *dest++ = val; + } + }; + break; + } + break; + + case 4: // bus granularity 8, alignment 32 + switch(endian) { + case ENDIANNESS_LITTLE: // bus granularity 8, alignment 16, little endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u8 *dest = get_ptr<u8>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 4) & m_pc_mask) { + u32 val = m_intf->decrypt32(m_back->r32(lpc), lpc, m_opcode); + *dest++ = val; + *dest++ = val >> 8; + *dest++ = val >> 16; + *dest++ = val >> 24; + } + }; + break; + + case ENDIANNESS_BIG: // bus granularity 16, alignment 32, big endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u8 *dest = get_ptr<u8>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 4) & m_pc_mask) { + u32 val = m_intf->decrypt32(m_back->r32(lpc), lpc, m_opcode); + *dest++ = val >> 24; + *dest++ = val >> 16; + *dest++ = val >> 8; + *dest++ = val; + } + }; + break; + } + break; + + + case 8: // bus granularity 8, alignment 64 + switch(endian) { + case ENDIANNESS_LITTLE: // bus granularity 8, alignment 64, little endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u8 *dest = get_ptr<u8>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 8) & m_pc_mask) { + u64 val = m_intf->decrypt64(m_back->r64(lpc), lpc, m_opcode); + *dest++ = val; + *dest++ = val >> 8; + *dest++ = val >> 16; + *dest++ = val >> 24; + *dest++ = val >> 32; + *dest++ = val >> 40; + *dest++ = val >> 48; + *dest++ = val >> 56; + } + }; + break; + + case ENDIANNESS_BIG: // bus granularity 8, alignment 64, big endian + m_do_fill = [this](offs_t lstart, offs_t lend) { + u8 *dest = get_ptr<u8>(lstart); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 2) & m_pc_mask) { + u64 val = m_intf->decrypt64(m_back->r64(lpc), lpc, m_opcode); + *dest++ = val >> 56; + *dest++ = val >> 48; + *dest++ = val >> 40; + *dest++ = val >> 32; + *dest++ = val >> 24; + *dest++ = val >> 16; + *dest++ = val >> 8; + *dest++ = val; + } + }; + break; + } + break; + } + break; + + case 3: // bus granularity 1, alignment 16, little endian (bit addressing, stored as u16, tms3401x) + assert(alignment == 16); + assert(endian == ENDIANNESS_LITTLE); + m_do_fill = [this](offs_t lstart, offs_t lend) { + u16 *dest = reinterpret_cast<u16 *>(&m_buffer[0]) + ((lstart - m_lstart) >> 4); + for(offs_t lpc = lstart; lpc != lend; lpc = (lpc + 0x10) & m_pc_mask) + *dest++ = m_intf->decrypt16(m_back->r16(lpc), lpc, m_opcode); + }; + break; + } + } + + // Define the accessors + if(m_intf->interface_flags() & util::disasm_interface::NONLINEAR_PC) { + switch(shift) { + case -1: + m_do_r8 = [](offs_t pc) -> u8 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r8 access on 16-bits granularity bus\n"); }; + m_do_r16 = [this](offs_t pc) -> u16 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 1); + const u16 *src = get_ptr<u16>(lpc); + return src[0]; + }; + + switch(endian) { + case ENDIANNESS_LITTLE: + m_do_r32 = [this](offs_t pc) -> u32 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 2); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u16>(lpc) << (j*16); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 4); + u64 r = 0; + for(int j=0; j != 4; j++) { + r |= u64(get<u16>(lpc)) << (j*16); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + break; + + case ENDIANNESS_BIG: + m_do_r32 = [this](offs_t pc) -> u32 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 2); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u16>(lpc) << ((1-j)*16); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 4); + u64 r = 0; + for(int j=0; j != 4; j++) { + r |= u64(get<u16>(lpc)) << ((3-j)*16); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + break; + } + break; + + case 0: + m_do_r8 = [this](offs_t pc) -> u8 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 1); + const u8 *src = get_ptr<u8>(lpc); + return src[0]; + }; + + switch(endian) { + case ENDIANNESS_LITTLE: + m_do_r16 = [this](offs_t pc) -> u16 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 2); + u16 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(lpc) << (j*8); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + m_do_r32 = [this](offs_t pc) -> u32 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 4); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(lpc) << (j*8); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 8); + u64 r = 0; + for(int j=0; j != 8; j++) { + r |= u64(get<u8>(lpc)) << (j*8); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + break; + + case ENDIANNESS_BIG: + m_do_r16 = [this](offs_t pc) -> u16 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 2); + u16 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(lpc) << ((1-j)*8); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + m_do_r32 = [this](offs_t pc) -> u32 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 4); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(lpc) << ((3-j)*8); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + offs_t lpc = m_intf->pc_real_to_linear(pc); + fill(lpc, 8); + u64 r = 0; + for(int j=0; j != 8; j++) { + r |= u64(get<u8>(lpc)) << ((7-j)*8); + lpc = (lpc & ~m_page_mask) | ((lpc + 1) & m_page_mask); + } + return r; + }; + break; + } + break; + } + } else { + switch(shift) { + case -3: // bus granularity 64 + m_do_r8 = [](offs_t pc) -> u8 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r8 access on 64-bits granularity bus\n"); }; + m_do_r16 = [](offs_t pc) -> u16 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r16 access on 64-bits granularity bus\n"); }; + m_do_r32 = [](offs_t pc) -> u32 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r32 access on 64-bits granularity bus\n"); }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 1); + const u64 *src = get_ptr<u64>(pc); + return src[0]; + }; + break; + + case -2: // bus granularity 32 + m_do_r8 = [](offs_t pc) -> u8 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r8 access on 32-bits granularity bus\n"); }; + m_do_r16 = [](offs_t pc) -> u16 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r16 access on 32-bits granularity bus\n"); }; + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 1); + const u32 *src = get_ptr<u32>(pc); + return src[0]; + }; + switch(endian) { + case ENDIANNESS_LITTLE: + if(m_page_mask) { + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 2); + u64 r = 0; + for(int j=0; j != 2; j++) { + r |= u64(get<u32>(pc)) << (j*32); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + } else { + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 2); + const u32 *src = get_ptr<u32>(pc); + return src[0] | (u64(src[1]) << 32); + }; + } + break; + case ENDIANNESS_BIG: + if(m_page_mask) { + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 2); + u64 r = 0; + for(int j=0; j != 2; j++) { + r |= u64(get<u32>(pc)) << ((1-j)*32); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + } else { + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 2); + const u32 *src = get_ptr<u32>(pc); + return (u64(src[0]) << 32) | u64(src[1]); + }; + } + break; + } + break; + + case -1: // bus granularity 16 + m_do_r8 = [](offs_t pc) -> u8 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r8 access on 16-bits granularity bus\n"); }; + m_do_r16 = [this](offs_t pc) -> u16 { + fill(pc, 1); + const u16 *src = get_ptr<u16>(pc); + return src[0]; + }; + switch(endian) { + case ENDIANNESS_LITTLE: + if(m_page_mask) { + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 2); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u16>(pc) << (j*16); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 4); + u64 r = 0; + for(int j=0; j != 4; j++) { + r |= u64(get<u16>(pc)) << (j*16); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + } else { + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 2); + const u16 *src = get_ptr<u16>(pc); + return src[0] | (src[1] << 16); + }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 4); + const u16 *src = get_ptr<u16>(pc); + return src[0] | (src[1] << 16) | (u64(src[2]) << 32) | (u64(src[3]) << 48); + }; + } + break; + case ENDIANNESS_BIG: + if(m_page_mask) { + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 2); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u16>(pc) << ((1-j)*16); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 4); + u64 r = 0; + for(int j=0; j != 4; j++) { + r |= u64(get<u16>(pc)) << ((3-j)*16); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + } else { + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 2); + const u16 *src = get_ptr<u16>(pc); + return (src[0] << 16) | src[1]; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 4); + const u16 *src = get_ptr<u16>(pc); + return (u64(src[0]) << 48) | (u64(src[1]) << 32) | u32(src[2] << 16) | src[3]; + }; + } + break; + } + break; + + case 0: // bus granularity 8 + m_do_r8 = [this](offs_t pc) -> u8 { + fill(pc, 1); + const u8 *src = get_ptr<u8>(pc); + return src[0]; + }; + switch(endian) { + case ENDIANNESS_LITTLE: + if(m_page_mask) { + m_do_r16 = [this](offs_t pc) -> u16 { + fill(pc, 2); + u16 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(pc) << (j*8); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 4); + u32 r = 0; + for(int j=0; j != 4; j++) { + r |= get<u8>(pc) << (j*8); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 8); + u64 r = 0; + for(int j=0; j != 8; j++) { + r |= u64(get<u8>(pc)) << (j*8); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + } else { + m_do_r16 = [this](offs_t pc) -> u16 { + fill(pc, 2); + const u8 *src = get_ptr<u8>(pc); + return src[0] | (src[1] << 8); + }; + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 4); + const u8 *src = get_ptr<u8>(pc); + return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 8); + const u8 *src = get_ptr<u8>(pc); + return src[0] | (src[1] << 8) | (src[2] << 16) | u32(src[3] << 24) | + (u64(src[4]) << 32) | (u64(src[5]) << 40) | (u64(src[6]) << 48) | (u64(src[7]) << 56); + }; + } + break; + case ENDIANNESS_BIG: + if(m_page_mask) { + m_do_r16 = [this](offs_t pc) -> u16 { + fill(pc, 2); + u16 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(pc) << ((1-j)*8); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 4); + u32 r = 0; + for(int j=0; j != 4; j++) { + r |= get<u8>(pc) << ((3-j)*8); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 8); + u64 r = 0; + for(int j=0; j != 8; j++) { + r |= u64(get<u8>(pc)) << ((7-j)*8); + pc = (pc & ~m_page_mask) | ((pc + 1) & m_page_mask); + } + return r; + }; + } else { + m_do_r16 = [this](offs_t pc) -> u16 { + fill(pc, 2); + const u8 *src = get_ptr<u8>(pc); + return (src[0] << 8) | src[1]; + }; + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 4); + const u8 *src = get_ptr<u8>(pc); + return (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | src[3]; + }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 8); + const u8 *src = get_ptr<u8>(pc); + return (u64(src[0]) << 56) | (u64(src[1]) << 32) | (u64(src[2]) << 40) | (u64(src[3]) << 32) | + (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7]; + }; + } + break; + } + break; + + case 3: // bus granularity 1, u16 storage, no paging + assert(endian == ENDIANNESS_LITTLE); + assert(!m_page_mask); + m_do_r8 = [](offs_t pc) -> u8 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r8 access on 1-bit/16 wide granularity bus\n"); }; + m_do_r16 = [this](offs_t pc) -> u16 { + fill(pc, 16); + const u16 *src = reinterpret_cast<u16 *>(&m_buffer[0]) + ((pc - m_lstart) >> 4); + return src[0]; + }; + m_do_r32 = [this](offs_t pc) -> u32 { + fill(pc, 32); + const u16 *src = reinterpret_cast<u16 *>(&m_buffer[0]) + ((pc - m_lstart) >> 4); + return src[0] | (src[1] << 16); + }; + m_do_r64 = [this](offs_t pc) -> u64 { + fill(pc, 64); + const u16 *src = reinterpret_cast<u16 *>(&m_buffer[0]) + ((pc - m_lstart) >> 4); + return src[0] | (src[1] << 16) | (u64(src[2]) << 32) | (u64(src[3]) << 48); + }; + break; + } + } + + // Define the data -> string conversion + switch(shift) { + case -3: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i++) { + if(i) + out << ' '; + util::stream_format(out, "%016x", r64(pc)); + pc = m_next_pc_wrap(pc, 1); + } + return out.str(); + }; + break; + + case -2: + switch(alignment) { + case 1: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i++) { + if(i) + out << ' '; + util::stream_format(out, "%08x", r32(pc)); + pc = m_next_pc_wrap(pc, 1); + } + return out.str(); + }; + break; + + case 2: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i += 2) { + if(i) + out << ' '; + util::stream_format(out, "%016x", r64(pc)); + pc = m_next_pc_wrap(pc, 2); + } + return out.str(); + }; + break; + } + break; + + case -1: + switch(alignment) { + case 1: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i++) { + if(i) + out << ' '; + util::stream_format(out, "%04x", r16(pc)); + pc = m_next_pc_wrap(pc, 1); + } + return out.str(); + }; + break; + + case 2: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i += 2) { + if(i) + out << ' '; + util::stream_format(out, "%08x", r32(pc)); + pc = m_next_pc_wrap(pc, 2); + } + return out.str(); + }; + break; + + case 4: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i += 4) { + if(i) + out << ' '; + util::stream_format(out, "%016x", r64(pc)); + pc = m_next_pc_wrap(pc, 4); + } + return out.str(); + }; + break; + } + break; + + case 0: + switch(alignment) { + case 1: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i++) { + if(i) + out << ' '; + util::stream_format(out, "%02x", r8(pc)); + pc = m_next_pc_wrap(pc, 1); + } + return out.str(); + }; + break; + + case 2: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i += 2) { + if(i) + out << ' '; + util::stream_format(out, "%04x", r16(pc)); + pc = m_next_pc_wrap(pc, 2); + } + return out.str(); + }; + break; + + case 4: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i += 4) { + if(i) + out << ' '; + util::stream_format(out, "%08x", r32(pc)); + pc = m_next_pc_wrap(pc, 4); + } + return out.str(); + }; + break; + + case 8: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i += 8) { + if(i) + out << ' '; + util::stream_format(out, "%016x", r64(pc)); + pc = m_next_pc_wrap(pc, 8); + } + return out.str(); + }; + break; + } + break; + + case 3: + m_data_to_string = [this](offs_t pc, offs_t size) { + std::ostringstream out; + for(offs_t i=0; i != size; i += 16) { + if(i) + out << ' '; + util::stream_format(out, "%04x", r16(pc)); + pc = m_next_pc_wrap(pc, 16); + } + return out.str(); + }; + break; + } + + // Define the data extraction + switch(shift) { + case -3: + m_data_get = [this](offs_t pc, offs_t size, std::vector<u8> &data) { + for(offs_t i=0; i != size; i++) { + u64 r = r64(pc); + for(int j=0; j != 8; j++) + data.push_back(r >> (8*j)); + pc = m_next_pc_wrap(pc, 1); + } + }; + break; + + case -2: + m_data_get = [this](offs_t pc, offs_t size, std::vector<u8> &data) { + for(offs_t i=0; i != size; i++) { + u32 r = r32(pc); + for(int j=0; j != 4; j++) + data.push_back(r >> (8*j)); + pc = m_next_pc_wrap(pc, 1); + } + }; + break; + + case -1: + m_data_get = [this](offs_t pc, offs_t size, std::vector<u8> &data) { + for(offs_t i=0; i != size; i++) { + u16 r = r16(pc); + for(int j=0; j != 2; j++) + data.push_back(r >> (8*j)); + pc = m_next_pc_wrap(pc, 1); + } + }; + break; + + case 0: + m_data_get = [this](offs_t pc, offs_t size, std::vector<u8> &data) { + for(offs_t i=0; i != size; i++) { + data.push_back(r8(pc)); + pc = m_next_pc_wrap(pc, 1); + } + }; + break; + + case 3: + m_data_get = [this](offs_t pc, offs_t size, std::vector<u8> &data) { + for(offs_t i=0; i != size >> 4; i++) { + u16 r = r16(pc); + for(int j=0; j != 2; j++) + data.push_back(r >> (8*j)); + pc = m_next_pc_wrap(pc, 16); + } + }; + break; + } + + // Wrapped next pc computation + if(m_intf->interface_flags() & util::disasm_interface::NONLINEAR_PC) { + // lfsr pc is always paged + m_next_pc_wrap = [this](offs_t pc, offs_t size) { + offs_t lpc = m_intf->pc_real_to_linear(pc); + offs_t lpce = (lpc & ~m_page_mask) | ((lpc + size) & m_page_mask); + return m_intf->pc_linear_to_real(lpce); + }; + } else if(m_intf->interface_flags() & util::disasm_interface::PAGED) { + m_next_pc_wrap = [this](offs_t pc, offs_t size) { + offs_t pce = (pc & ~m_page_mask) | ((pc + size) & m_page_mask); + return pce; + }; + } else { + m_next_pc_wrap = [this](offs_t pc, offs_t size) { + return (pc + size) & m_pc_mask; + }; + } +} + +debug_disasm_buffer::debug_disasm_buffer(device_t &device) : + m_buf_raw(dynamic_cast<device_disasm_interface &>(device).get_disassembler()), + m_buf_opcodes(dynamic_cast<device_disasm_interface &>(device).get_disassembler()), + m_buf_params(dynamic_cast<device_disasm_interface &>(device).get_disassembler()) +{ + m_dintf = dynamic_cast<device_disasm_interface *>(&device)->get_disassembler(); + m_mintf = dynamic_cast<device_memory_interface *>(&device); + + m_flags = m_dintf->interface_flags(); + + if(m_flags & util::disasm_interface::INTERNAL_DECRYPTION) { + m_buf_raw.set_source(m_mintf->space(AS_PROGRAM)); + m_buf_opcodes.set_source(m_buf_raw, true); + if((m_flags & util::disasm_interface::SPLIT_DECRYPTION) == util::disasm_interface::SPLIT_DECRYPTION) + m_buf_params.set_source(m_buf_raw, false); + } else { + if(m_mintf->has_space(AS_OPCODES)) { + m_buf_opcodes.set_source(m_mintf->space(AS_OPCODES)); + m_buf_params.set_source(m_mintf->space(AS_PROGRAM)); + } else + m_buf_opcodes.set_source(m_mintf->space(AS_PROGRAM)); + } + + m_pc_mask = m_mintf->space(AS_PROGRAM).logaddrmask(); + + if(m_flags & util::disasm_interface::PAGED) + m_page_mask = (1 << m_dintf->page_address_bits()) - 1; + else + m_page_mask = 0; + + // Next pc computation + if(m_flags & util::disasm_interface::NONLINEAR_PC) { + // lfsr pc is always paged + m_next_pc = [this](offs_t pc, offs_t size) { + offs_t lpc = m_dintf->pc_real_to_linear(pc); + offs_t lpce = lpc + size; + if((lpc ^ lpce) & ~m_page_mask) + lpce = (lpc | m_page_mask) + 1; + lpce &= m_pc_mask; + return m_dintf->pc_linear_to_real(lpce); + }; + m_next_pc_wrap = [this](offs_t pc, offs_t size) { + offs_t lpc = m_dintf->pc_real_to_linear(pc); + offs_t lpce = (lpc & ~m_page_mask) | ((lpc + size) & m_page_mask); + return m_dintf->pc_linear_to_real(lpce); + }; + + } else if(m_flags & util::disasm_interface::PAGED) { + m_next_pc = [this](offs_t pc, offs_t size) { + offs_t pce = pc + size; + if((pc ^ pce) & ~m_page_mask) + pce = (pc | m_page_mask) + 1; + pce &= m_pc_mask; + return pce; + }; + m_next_pc_wrap = [this](offs_t pc, offs_t size) { + offs_t pce = (pc & ~m_page_mask) | ((pc + size) & m_page_mask); + return pce; + }; + + } else { + m_next_pc = [this](offs_t pc, offs_t size) { + return (pc + size) & m_pc_mask; + }; + m_next_pc_wrap = [this](offs_t pc, offs_t size) { + return (pc + size) & m_pc_mask; + }; + } + + // pc to string conversion + int aw = m_mintf->space(AS_PROGRAM).addr_width(); + bool is_octal = m_mintf->space(AS_PROGRAM).is_octal(); + if((m_flags & util::disasm_interface::PAGED2LEVEL) == util::disasm_interface::PAGED2LEVEL) { + int bits1 = m_dintf->page_address_bits(); + int bits2 = m_dintf->page2_address_bits(); + int bits3 = aw - bits1 - bits2; + offs_t sm1 = (1 << bits1) - 1; + int sh2 = bits1; + offs_t sm2 = (1 << bits2) - 1; + int sh3 = bits1+bits2; + + if(is_octal) { + int nc1 = (bits1+2)/3; + int nc2 = (bits2+2)/3; + int nc3 = (bits3+2)/3; + m_pc_to_string = [nc1, nc2, nc3, sm1, sm2, sh2, sh3](offs_t pc) -> std::string { + return util::string_format("%0*o:%0*o:%0*o", + nc3, pc >> sh3, + nc2, (pc >> sh2) & sm2, + nc1, pc & sm1); + }; + } else { + int nc1 = (bits1+3)/4; + int nc2 = (bits2+3)/4; + int nc3 = (bits3+3)/4; + m_pc_to_string = [nc1, nc2, nc3, sm1, sm2, sh2, sh3](offs_t pc) -> std::string { + return util::string_format("%0*x:%0*x:%0*x", + nc3, pc >> sh3, + nc2, (pc >> sh2) & sm2, + nc1, pc & sm1); + }; + } + + } else if(m_flags & util::disasm_interface::PAGED) { + int bits1 = m_dintf->page_address_bits(); + int bits2 = aw - bits1; + offs_t sm1 = (1 << bits1) - 1; + int sh2 = bits1; + + if(is_octal) { + int nc1 = (bits1+2)/3; + int nc2 = (bits2+2)/3; + m_pc_to_string = [nc1, nc2, sm1, sh2](offs_t pc) -> std::string { + return util::string_format("%0*o:%0*o", + nc2, pc >> sh2, + nc1, pc & sm1); + }; + } else { + int nc1 = (bits1+3)/4; + int nc2 = (bits2+3)/4; + m_pc_to_string = [nc1, nc2, sm1, sh2](offs_t pc) -> std::string { + return util::string_format("%0*x:%0*x", + nc2, pc >> sh2, + nc1, pc & sm1); + }; + } + + } else { + int bits1 = aw; + + if(is_octal) { + int nc1 = (bits1+2)/3; + m_pc_to_string = [nc1](offs_t pc) -> std::string { + return util::string_format("%0*o", + nc1, pc); + }; + } else { + int nc1 = (bits1+3)/4; + m_pc_to_string = [nc1](offs_t pc) -> std::string { + return util::string_format("%0*x", + nc1, pc); + }; + } + } +} + +void debug_disasm_buffer::disassemble(offs_t pc, std::string &instruction, offs_t &next_pc, offs_t &size, u32 &info) const +{ + std::ostringstream out; + u32 result = m_dintf->disassemble(out, pc, m_buf_opcodes, m_buf_params.active() ? m_buf_params : m_buf_opcodes); + instruction = out.str(); + size = result & util::disasm_interface::LENGTHMASK; + next_pc = m_next_pc(pc, size); + info = result; +} + + +u32 debug_disasm_buffer::disassemble_info(offs_t pc) const +{ + std::ostringstream out; + return m_dintf->disassemble(out, pc, m_buf_opcodes, m_buf_params.active() ? m_buf_params : m_buf_opcodes); +} + +std::string debug_disasm_buffer::pc_to_string(offs_t pc) const +{ + return m_pc_to_string(pc); +} + +std::string debug_disasm_buffer::data_to_string(offs_t pc, offs_t size, bool opcode) const +{ + if(!opcode && !m_buf_params.active()) + return std::string(); + return (opcode ? m_buf_opcodes : m_buf_params).data_to_string(pc, size); +} + +void debug_disasm_buffer::data_get(offs_t pc, offs_t size, bool opcode, std::vector<u8> &data) const +{ + data.clear(); + if(!opcode && !m_buf_params.active()) + return; + (opcode ? m_buf_opcodes : m_buf_params).data_get(pc, size, data); +} + +offs_t debug_disasm_buffer::next_pc(offs_t pc, offs_t step) const +{ + return m_next_pc(pc, step); +} + +offs_t debug_disasm_buffer::next_pc_wrap(offs_t pc, offs_t step) const +{ + return m_next_pc_wrap(pc, step); +} diff --git a/src/emu/debug/debugbuf.h b/src/emu/debug/debugbuf.h new file mode 100644 index 00000000000..46ec8286417 --- /dev/null +++ b/src/emu/debug/debugbuf.h @@ -0,0 +1,93 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Buffering interface for the disassembly windows + +#ifndef MAME_EMU_DEBUG_DEBUGBUF_H +#define MAME_EMU_DEBUG_DEBUGBUF_H + +#pragma once + +class debug_disasm_buffer +{ +public: + debug_disasm_buffer(device_t &device); + + void disassemble(offs_t pc, std::string &instruction, offs_t &next_pc, offs_t &size, u32 &info) const; + u32 disassemble_info(offs_t pc) const; + std::string pc_to_string(offs_t pc) const; + std::string data_to_string(offs_t pc, offs_t size, bool opcode) const; + void data_get(offs_t pc, offs_t size, bool opcode, std::vector<u8> &data) const; + + offs_t next_pc(offs_t pc, offs_t step) const; + offs_t next_pc_wrap(offs_t pc, offs_t step) const; + +private: + class debug_data_buffer : public util::disasm_interface::data_buffer + { + public: + debug_data_buffer(util::disasm_interface *intf); + ~debug_data_buffer() = default; + + virtual u8 r8 (offs_t pc) const override; + virtual u16 r16(offs_t pc) const override; + virtual u32 r32(offs_t pc) const override; + virtual u64 r64(offs_t pc) const override; + + void set_source(address_space &space); + void set_source(debug_data_buffer &back, bool opcode); + + bool active() const; + + address_space *get_underlying_space() const; + std::string data_to_string(offs_t pc, offs_t size) const; + void data_get(offs_t pc, offs_t size, std::vector<u8> &data) const; + + private: + util::disasm_interface *m_intf; + + std::function<offs_t (offs_t)> m_pc_delta_to_bytes; + std::function<void (offs_t, offs_t)> m_do_fill; + std::function<u8 (offs_t)> m_do_r8; + std::function<u16 (offs_t)> m_do_r16; + std::function<u32 (offs_t)> m_do_r32; + std::function<u64 (offs_t)> m_do_r64; + std::function<std::string (offs_t, offs_t)> m_data_to_string; + std::function<void (offs_t, offs_t, std::vector<u8> &)> m_data_get; + std::function<offs_t (offs_t, offs_t)> m_next_pc_wrap; + + address_space *m_space; + debug_data_buffer *m_back; + bool m_opcode; + offs_t m_page_mask, m_pc_mask; + mutable offs_t m_lstart, m_lend; + mutable bool m_wrapped; + mutable std::vector<u8> m_buffer; + + template<typename T> T *get_ptr(offs_t lpc) { + return reinterpret_cast<T *>(&m_buffer[0]) + ((lpc - m_lstart) & m_pc_mask); + } + + template<typename T> T get(offs_t lpc) const { + return reinterpret_cast<const T *>(&m_buffer[0])[(lpc - m_lstart) & m_pc_mask]; + } + + void setup_methods(); + void fill(offs_t lstart, offs_t size) const; + + }; + + util::disasm_interface *m_dintf; + device_memory_interface *m_mintf; + + std::function<offs_t (offs_t, offs_t)> m_next_pc; + std::function<offs_t (offs_t, offs_t)> m_next_pc_wrap; + std::function<std::string (offs_t)> m_pc_to_string; + + debug_data_buffer m_buf_raw, m_buf_opcodes, m_buf_params; + u32 m_flags; + offs_t m_page_mask, m_pc_mask; +}; + +#endif + diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index c1e96054164..38bff17b8c4 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -14,6 +14,7 @@ #include "debugcmd.h" #include "debugcon.h" #include "debugcpu.h" +#include "debugbuf.h" #include "express.h" #include "debughlp.h" #include "debugvw.h" @@ -99,15 +100,15 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu , m_cpu(cpu) , m_console(console) { - m_global_array = auto_alloc_array_clear(m_machine, global_entry, MAX_GLOBALS); + m_global_array = std::make_unique<global_entry []>(MAX_GLOBALS); symbol_table *symtable = m_cpu.get_global_symtable(); /* add a few simple global functions */ using namespace std::placeholders; - symtable->add("min", nullptr, 2, 2, std::bind(&debugger_commands::execute_min, this, _1, _2, _3, _4)); - symtable->add("max", nullptr, 2, 2, std::bind(&debugger_commands::execute_max, this, _1, _2, _3, _4)); - symtable->add("if", nullptr, 3, 3, std::bind(&debugger_commands::execute_if, this, _1, _2, _3, _4)); + symtable->add("min", 2, 2, std::bind(&debugger_commands::execute_min, this, _1, _2, _3)); + symtable->add("max", 2, 2, std::bind(&debugger_commands::execute_max, this, _1, _2, _3)); + symtable->add("if", 3, 3, std::bind(&debugger_commands::execute_if, this, _1, _2, _3)); /* add all single-entry save state globals */ for (int itemnum = 0; itemnum < MAX_GLOBALS; itemnum++) @@ -127,7 +128,10 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu sprintf(symname, ".%s", strrchr(name, '/') + 1); m_global_array[itemnum].base = base; m_global_array[itemnum].size = valsize; - symtable->add(symname, &m_global_array, std::bind(&debugger_commands::global_get, this, _1, _2), std::bind(&debugger_commands::global_set, this, _1, _2, _3)); + symtable->add( + symname, + std::bind(&debugger_commands::global_get, this, _1, &m_global_array[itemnum]), + std::bind(&debugger_commands::global_set, this, _1, &m_global_array[itemnum], _2)); } } @@ -292,7 +296,7 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu execute_min - return the minimum of two values -------------------------------------------------*/ -u64 debugger_commands::execute_min(symbol_table &table, void *ref, int params, const u64 *param) +u64 debugger_commands::execute_min(symbol_table &table, int params, const u64 *param) { return (param[0] < param[1]) ? param[0] : param[1]; } @@ -302,7 +306,7 @@ u64 debugger_commands::execute_min(symbol_table &table, void *ref, int params, c execute_max - return the maximum of two values -------------------------------------------------*/ -u64 debugger_commands::execute_max(symbol_table &table, void *ref, int params, const u64 *param) +u64 debugger_commands::execute_max(symbol_table &table, int params, const u64 *param) { return (param[0] > param[1]) ? param[0] : param[1]; } @@ -312,7 +316,7 @@ u64 debugger_commands::execute_max(symbol_table &table, void *ref, int params, c execute_if - if (a) return b; else return c; -------------------------------------------------*/ -u64 debugger_commands::execute_if(symbol_table &table, void *ref, int params, const u64 *param) +u64 debugger_commands::execute_if(symbol_table &table, int params, const u64 *param) { return param[0] ? param[1] : param[2]; } @@ -327,9 +331,8 @@ u64 debugger_commands::execute_if(symbol_table &table, void *ref, int params, co global_get - symbol table getter for globals -------------------------------------------------*/ -u64 debugger_commands::global_get(symbol_table &table, void *ref) +u64 debugger_commands::global_get(symbol_table &table, global_entry *global) { - global_entry *global = (global_entry *)ref; switch (global->size) { case 1: return *(u8 *)global->base; @@ -345,9 +348,8 @@ u64 debugger_commands::global_get(symbol_table &table, void *ref) global_set - symbol table setter for globals -------------------------------------------------*/ -void debugger_commands::global_set(symbol_table &table, void *ref, u64 value) +void debugger_commands::global_set(symbol_table &table, global_entry *global, u64 value) { - global_entry *global = (global_entry *)ref; switch (global->size) { case 1: *(u8 *)global->base = value; break; @@ -760,7 +762,7 @@ void debugger_commands::execute_tracesym(int ref, const std::vector<std::string> void debugger_commands::execute_quit(int ref, const std::vector<std::string> ¶ms) { - osd_printf_error("Exited via the debugger\n"); + osd_printf_warning("Exited via the debugger\n"); m_machine.schedule_exit(); } @@ -1644,7 +1646,6 @@ void debugger_commands::execute_save(int ref, const std::vector<std::string> &pa u64 offset, endoffset, length; address_space *space; FILE *f; - u64 i; /* validate parameters */ if (!validate_number_parameter(params[1], offset)) @@ -1655,8 +1656,9 @@ void debugger_commands::execute_save(int ref, const std::vector<std::string> &pa return; /* determine the addresses to write */ - endoffset = space->address_to_byte(offset + length - 1) & space->bytemask(); - offset = space->address_to_byte(offset) & space->bytemask(); + endoffset = (offset + length - 1) & space->addrmask(); + offset = offset & space->addrmask(); + endoffset ++; /* open the file */ f = fopen(params[0].c_str(), "wb"); @@ -1667,10 +1669,46 @@ void debugger_commands::execute_save(int ref, const std::vector<std::string> &pa } /* now write the data out */ - for (i = offset; i <= endoffset; i++) + auto dis = space->machine().disable_side_effect(); + switch (space->addr_shift()) { - u8 byte = m_cpu.read_byte(*space, i, true); - fwrite(&byte, 1, 1, f); + case -3: + for (offs_t i = offset; i != endoffset; i++) + { + u64 data = space->read_qword(i); + fwrite(&data, 8, 1, f); + } + break; + case -2: + for (offs_t i = offset; i != endoffset; i++) + { + u32 data = space->read_dword(i); + fwrite(&data, 4, 1, f); + } + break; + case -1: + for (offs_t i = offset; i != endoffset; i++) + { + u16 byte = space->read_word(i); + fwrite(&byte, 2, 1, f); + } + break; + case 0: + for (offs_t i = offset; i != endoffset; i++) + { + u8 byte = space->read_byte(i); + fwrite(&byte, 1, 1, f); + } + break; + case 3: + offset &= ~15; + endoffset &= ~15; + for (offs_t i = offset; i != endoffset; i+=16) + { + u16 byte = space->read_word(i >> 4); + fwrite(&byte, 2, 1, f); + } + break; } /* close the file */ @@ -1687,7 +1725,6 @@ void debugger_commands::execute_load(int ref, const std::vector<std::string> &pa { u64 offset, endoffset, length = 0; address_space *space; - u64 i; // validate parameters if (!validate_number_parameter(params[1], offset)) @@ -1712,19 +1749,66 @@ void debugger_commands::execute_load(int ref, const std::vector<std::string> &pa f.seekg(0, std::ios::end); length = f.tellg(); f.seekg(0); + if (space->addr_shift() < 0) + length >>= -space->addr_shift(); + else if (space->addr_shift() > 0) + length <<= space->addr_shift(); } // determine the addresses to read - endoffset = space->address_to_byte(offset + length - 1) & space->bytemask(); - offset = space->address_to_byte(offset) & space->bytemask(); - + endoffset = (offset + length - 1) & space->addrmask(); + offset = offset & space->addrmask(); + offs_t i = 0; // now read the data in, ignore endoffset and load entire file if length has been set to zero (offset-1) - for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++) + switch (space->addr_shift()) { - char byte; - f.read(&byte, 1); - if (f) - m_cpu.write_byte(*space, i, byte, true); + case -3: + for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++) + { + u64 data; + f.read((char *)&data, 8); + if (f) + space->write_qword(i, data); + } + break; + case -2: + for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++) + { + u32 data; + f.read((char *)&data, 4); + if (f) + space->write_dword(i, data); + } + break; + case -1: + for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++) + { + u16 data; + f.read((char *)&data, 2); + if (f) + space->write_word(i, data); + } + break; + case 0: + for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 1); i++) + { + u8 data; + f.read((char *)&data, 1); + if (f) + space->write_byte(i, data); + } + break; + case 3: + offset &= ~15; + endoffset &= ~15; + for (i = offset; f.good() && (i <= endoffset || endoffset == offset - 16); i+=16) + { + u16 data; + f.read((char *)&data, 2); + if (f) + space->write_word(i >> 4, data); + } + break; } if (!f.good()) @@ -1767,6 +1851,9 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa if (!validate_cpu_space_parameter((params.size() > 6) ? params[6].c_str() : nullptr, ref, space)) return; + int shift = space->addr_shift(); + u64 granularity = shift > 0 ? 2 : 1 << -shift; + /* further validation */ if (width == 0) width = space->data_width() / 8; @@ -1777,14 +1864,19 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa m_console.printf("Invalid width! (must be 1,2,4 or 8)\n"); return; } + if (width < granularity) + { + m_console.printf("Invalid width! (must be at least %d)\n", granularity); + return; + } if (rowsize == 0 || (rowsize % width) != 0) { m_console.printf("Invalid row size! (must be a positive multiple of %d)\n", width); return; } - u64 endoffset = space->address_to_byte(offset + length - 1) & space->bytemask(); - offset = space->address_to_byte(offset) & space->bytemask(); + u64 endoffset = (offset + length - 1) & space->addrmask(); + offset = offset & space->addrmask(); /* open the file */ FILE* f = fopen(params[0].c_str(), "w"); @@ -1797,13 +1889,22 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa /* now write the data out */ util::ovectorstream output; output.reserve(200); - for (u64 i = offset; i <= endoffset; i += rowsize) + + if (shift > 0) + width <<= shift; + else if(shift < 0) + width >>= -shift; + + auto dis = space->machine().disable_side_effect(); + bool be = space->endianness() == ENDIANNESS_BIG; + + for (offs_t i = offset; i <= endoffset; i += rowsize) { output.clear(); output.rdbuf()->clear(); /* print the address */ - util::stream_format(output, "%0*X: ", space->logaddrchars(), u32(space->byte_to_address(i))); + util::stream_format(output, "%0*X: ", space->logaddrchars(), i); /* print the bytes */ for (u64 j = 0; j < rowsize; j += width) @@ -1813,8 +1914,21 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa offs_t curaddr = i + j; if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) { - u64 value = m_cpu.read_memory(*space, i + j, width, true); - util::stream_format(output, " %0*X", width * 2, value); + switch (width) + { + case 8: + util::stream_format(output, " %016X", space->read_qword(i+j)); + break; + case 4: + util::stream_format(output, " %08X", space->read_dword(i+j)); + break; + case 2: + util::stream_format(output, " %04X", space->read_word(i+j)); + break; + case 1: + util::stream_format(output, " %02X", space->read_byte(i+j)); + break; + } } else { @@ -1834,8 +1948,26 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa offs_t curaddr = i + j; if (space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, curaddr)) { - u8 byte = m_cpu.read_byte(*space, i + j, true); - util::stream_format(output, "%c", (byte >= 32 && byte < 127) ? byte : '.'); + u64 data = 0; + switch (width) + { + case 8: + data = space->read_qword(i+j); + break; + case 4: + data = space->read_dword(i+j); + break; + case 2: + data = space->read_word(i+j); + break; + case 1: + data = space->read_byte(i+j); + break; + } + for (unsigned int b = 0; b != width; b++) { + u8 byte = data >> (8 * (be ? (width-i-b) : b)); + util::stream_format(output, "%c", (byte >= 32 && byte < 127) ? byte : '.'); + } } else { @@ -1920,8 +2052,8 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string { for (address_map_entry &entry : space->map()->m_entrylist) { - cheat_region[region_count].offset = space->address_to_byte(entry.m_addrstart) & space->bytemask(); - cheat_region[region_count].endoffset = space->address_to_byte(entry.m_addrend) & space->bytemask(); + cheat_region[region_count].offset = entry.m_addrstart & space->addrmask(); + cheat_region[region_count].endoffset = entry.m_addrend & space->addrmask(); cheat_region[region_count].share = entry.m_share; cheat_region[region_count].disabled = (entry.m_write.m_type == AMH_RAM) ? false : true; @@ -1944,8 +2076,8 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string return; /* force region to the specified range */ - cheat_region[region_count].offset = space->address_to_byte(offset) & space->bytemask(); - cheat_region[region_count].endoffset = space->address_to_byte(offset + length - 1) & space->bytemask(); + cheat_region[region_count].offset = offset & space->addrmask(); + cheat_region[region_count].endoffset = (offset + length - 1) & space->addrmask(); cheat_region[region_count].share = nullptr; cheat_region[region_count].disabled = false; region_count++; @@ -2320,9 +2452,9 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa return; /* further validation */ - endoffset = space->address_to_byte(offset + length - 1) & space->bytemask(); - offset = space->address_to_byte(offset) & space->bytemask(); - cur_data_size = space->address_to_byte(1); + endoffset = (offset + length - 1) & space->addrmask(); + offset = offset & space->addrmask(); + cur_data_size = space->addr_shift() > 0 ? 2 : 1 << -space->addr_shift(); if (cur_data_size == 0) cur_data_size = 1; @@ -2403,10 +2535,7 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa void debugger_commands::execute_dasm(int ref, const std::vector<std::string> ¶ms) { u64 offset, length, bytes = 1; - int minbytes, maxbytes, byteswidth; - address_space *space, *decrypted_space; - FILE *f; - int j; + address_space *space; /* validate parameters */ if (!validate_number_parameter(params[1], offset)) @@ -2417,10 +2546,6 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa return; if (!validate_cpu_space_parameter(params.size() > 4 ? params[4].c_str() : nullptr, AS_PROGRAM, space)) return; - if (space->device().memory().has_space(AS_OPCODES)) - decrypted_space = &space->device().memory().space(AS_OPCODES); - else - decrypted_space = space; /* determine the width of the bytes */ device_disasm_interface *dasmintf; @@ -2429,104 +2554,72 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa m_console.printf("No disassembler available for %s\n", space->device().name()); return; } - minbytes = dasmintf->min_opcode_bytes(); - maxbytes = dasmintf->max_opcode_bytes(); - byteswidth = 0; - if (bytes) - { - byteswidth = (maxbytes + (minbytes - 1)) / minbytes; - byteswidth *= (2 * minbytes) + 1; - } - /* open the file */ - f = fopen(params[0].c_str(), "w"); - if (!f) - { - m_console.printf("Error opening file '%s'\n", params[0].c_str()); - return; - } + /* build the data, check the maximum size of the opcodes and disasm */ + std::vector<offs_t> pcs; + std::vector<std::string> instructions; + std::vector<std::string> tpc; + std::vector<std::string> topcodes; + int max_opcodes_size = 0; + int max_disasm_size = 0; + + debug_disasm_buffer buffer(space->device()); - /* now write the data out */ - util::ovectorstream output; - util::ovectorstream disasm; - output.reserve(512); for (u64 i = 0; i < length; ) { - int pcbyte = space->address_to_byte(offset + i) & space->bytemask(); - const char *comment; - offs_t tempaddr; - int numbytes = 0; - output.clear(); - output.rdbuf()->clear(); - disasm.clear(); - disasm.seekp(0); + std::string instruction; + offs_t next_offset; + offs_t size; + u32 info; + buffer.disassemble(offset, instruction, next_offset, size, info); + pcs.push_back(offset); + instructions.emplace_back(instruction); + tpc.emplace_back(buffer.pc_to_string(offset)); + topcodes.emplace_back(buffer.data_to_string(offset, size, true)); - /* print the address */ - stream_format(output, "%0*X: ", space->logaddrchars(), u32(space->byte_to_address(pcbyte))); + int osize = topcodes.back().size(); + if(osize > max_opcodes_size) + max_opcodes_size = osize; - /* make sure we can translate the address */ - tempaddr = pcbyte; - if (space->device().memory().translate(space->spacenum(), TRANSLATE_FETCH_DEBUG, tempaddr)) - { - { - u8 opbuf[64], argbuf[64]; + int dsize = instructions.back().size(); + if(dsize > max_disasm_size) + max_disasm_size = dsize; - /* fetch the bytes up to the maximum */ - for (numbytes = 0; numbytes < maxbytes; numbytes++) - { - opbuf[numbytes] = m_cpu.read_opcode(*decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = m_cpu.read_opcode(*space, pcbyte + numbytes, 1); - } + i += size; + offset = next_offset; + } - /* disassemble the result */ - i += numbytes = dasmintf->disassemble(disasm, offset + i, opbuf, argbuf) & DASMFLAG_LENGTHMASK; - } + /* write the data */ + std::ofstream f(params[0]); + if (!f.good()) + { + m_console.printf("Error opening file '%s'\n", params[0]); + return; + } - /* print the bytes */ - if (bytes) - { - auto const startdex = output.tellp(); - numbytes = space->address_to_byte(numbytes); - for (j = 0; j < numbytes; j += minbytes) - stream_format(output, "%0*X ", minbytes * 2, m_cpu.read_opcode(*decrypted_space, pcbyte + j, minbytes)); - if ((output.tellp() - startdex) < byteswidth) - stream_format(output, "%*s", byteswidth - (output.tellp() - startdex), ""); - stream_format(output, " "); - } - } - else + if (bytes) + { + for(unsigned int i=0; i != pcs.size(); i++) { - disasm << "<unmapped>"; - i += minbytes; + const char *comment = space->device().debug()->comment_text(pcs[i]); + if (comment) + util::stream_format(f, "%s: %-*s %-*s // %s\n", tpc[i], max_opcodes_size, topcodes[i], max_disasm_size, instructions[i], comment); + else + util::stream_format(f, "%s: %-*s %s\n", tpc[i], max_opcodes_size, topcodes[i], instructions[i]); } - - /* add the disassembly */ - disasm.put('\0'); - stream_format(output, "%s", &disasm.vec()[0]); - - /* attempt to add the comment */ - comment = space->device().debug()->comment_text(tempaddr); - if (comment != nullptr) + } + else + { + for(unsigned int i=0; i != pcs.size(); i++) { - /* somewhat arbitrary guess as to how long most disassembly lines will be [column 60] */ - if (output.tellp() < 60) - { - /* pad the comment space out to 60 characters and null-terminate */ - while (output.tellp() < 60) output.put(' '); - - stream_format(output, "// %s", comment); - } + const char *comment = space->device().debug()->comment_text(pcs[i]); + if (comment) + util::stream_format(f, "%s: %-*s // %s\n", tpc[i], max_disasm_size, instructions[i], comment); else - stream_format(output, "\t// %s", comment); + util::stream_format(f, "%s: %s\n", tpc[i], instructions[i]); } - - /* output the result */ - auto const &text(output.vec()); - fprintf(f, "%.*s\n", int(unsigned(text.size())), &text[0]); } - /* close the file */ - fclose(f); m_console.printf("Data dumped successfully\n"); } @@ -2640,13 +2733,9 @@ void debugger_commands::execute_traceflush(int ref, const std::vector<std::strin void debugger_commands::execute_history(int ref, const std::vector<std::string> ¶ms) { /* validate parameters */ - address_space *space, *decrypted_space; + address_space *space; if (!validate_cpu_space_parameter(!params.empty() ? params[0].c_str() : nullptr, AS_PROGRAM, space)) return; - if (space->device().memory().has_space(AS_OPCODES)) - decrypted_space = &space->device().memory().space(AS_OPCODES); - else - decrypted_space = space; u64 count = device_debug::HISTORY_SIZE; if (params.size() > 1 && !validate_number_parameter(params[1], count)) @@ -2665,25 +2754,19 @@ void debugger_commands::execute_history(int ref, const std::vector<std::string> m_console.printf("No disassembler available for %s\n", space->device().name()); return; } - int maxbytes = dasmintf->max_opcode_bytes(); + + debug_disasm_buffer buffer(space->device()); + for (int index = 0; index < (int) count; index++) { offs_t pc = debug->history_pc(-index); + std::string instruction; + offs_t next_offset; + offs_t size; + u32 info; + buffer.disassemble(pc, instruction, next_offset, size, info); - /* fetch the bytes up to the maximum */ - offs_t pcbyte = space->address_to_byte(pc) & space->bytemask(); - u8 opbuf[64], argbuf[64]; - for (int numbytes = 0; numbytes < maxbytes; numbytes++) - { - opbuf[numbytes] = m_cpu.read_opcode(*decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = m_cpu.read_opcode(*space, pcbyte + numbytes, 1); - } - - util::ovectorstream buffer; - dasmintf->disassemble(buffer, pc, opbuf, argbuf); - buffer.put('\0'); - - m_console.printf("%0*X: %s\n", space->logaddrchars(), pc, &buffer.vec()[0]); + m_console.printf("%s: %s\n", buffer.pc_to_string(pc), instruction); } } @@ -2882,7 +2965,7 @@ void debugger_commands::execute_map(int ref, const std::vector<std::string> &par for (intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++) { static const char *const intnames[] = { "Read", "Write", "Fetch" }; - taddress = space->address_to_byte(address) & space->bytemask(); + taddress = address & space->addrmask(); if (space->device().memory().translate(space->spacenum(), intention, taddress)) { const char *mapname = space->get_handler_string((intention == TRANSLATE_WRITE_DEBUG) ? read_or_write::WRITE : read_or_write::READ, taddress); @@ -2890,7 +2973,7 @@ void debugger_commands::execute_map(int ref, const std::vector<std::string> &par "%7s: %0*X logical == %0*X physical -> %s\n", intnames[intention & 3], space->logaddrchars(), address, - space->addrchars(), space->byte_to_address(taddress), + space->addrchars(), taddress, mapname); } else diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h index 7eca669908e..98b6d8ae03d 100644 --- a/src/emu/debug/debugcmd.h +++ b/src/emu/debug/debugcmd.h @@ -37,8 +37,10 @@ public: private: struct global_entry { - void * base; - u32 size; + global_entry() { } + + void * base = nullptr; + u32 size = 0; }; @@ -79,12 +81,12 @@ private: u64 cheat_byte_swap(const cheat_system *cheatsys, u64 value); u64 cheat_read_extended(const cheat_system *cheatsys, address_space &space, offs_t address); - u64 execute_min(symbol_table &table, void *ref, int params, const u64 *param); - u64 execute_max(symbol_table &table, void *ref, int params, const u64 *param); - u64 execute_if(symbol_table &table, void *ref, int params, const u64 *param); + u64 execute_min(symbol_table &table, int params, const u64 *param); + u64 execute_max(symbol_table &table, int params, const u64 *param); + u64 execute_if(symbol_table &table, int params, const u64 *param); - u64 global_get(symbol_table &table, void *ref); - void global_set(symbol_table &table, void *ref, u64 value); + u64 global_get(symbol_table &table, global_entry *global); + void global_set(symbol_table &table, global_entry *global, u64 value); int mini_printf(char *buffer, const char *format, int params, u64 *param); @@ -162,7 +164,7 @@ private: debugger_cpu& m_cpu; debugger_console& m_console; - global_entry *m_global_array; + std::unique_ptr<global_entry []> m_global_array; cheat_system m_cheat; static const size_t MAX_GLOBALS; diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp index 0289ef7f664..eab6f7771e7 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "debugcpu.h" +#include "debugbuf.h" #include "express.h" #include "debugcon.h" @@ -48,6 +49,7 @@ debugger_cpu::debugger_cpu(running_machine &machine) , m_breakcpu(nullptr) , m_symtable(nullptr) , m_execution_state(EXECUTION_STATE_STOPPED) + , m_stop_when_not_device(nullptr) , m_bpindex(1) , m_wpindex(1) , m_rpindex(1) @@ -71,10 +73,10 @@ debugger_cpu::debugger_cpu(running_machine &machine) m_symtable->add("wpdata", symbol_table::READ_ONLY, &m_wpdata); using namespace std::placeholders; - m_symtable->add("cpunum", nullptr, std::bind(&debugger_cpu::get_cpunum, this, _1, _2)); - m_symtable->add("beamx", (void *)first_screen, std::bind(&debugger_cpu::get_beamx, this, _1, _2)); - m_symtable->add("beamy", (void *)first_screen, std::bind(&debugger_cpu::get_beamy, this, _1, _2)); - m_symtable->add("frame", (void *)first_screen, std::bind(&debugger_cpu::get_frame, this, _1, _2)); + m_symtable->add("cpunum", std::bind(&debugger_cpu::get_cpunum, this, _1)); + m_symtable->add("beamx", std::bind(&debugger_cpu::get_beamx, this, _1, first_screen)); + m_symtable->add("beamy", std::bind(&debugger_cpu::get_beamy, this, _1, first_screen)); + m_symtable->add("frame", std::bind(&debugger_cpu::get_frame, this, _1, first_screen)); /* add the temporary variables to the global symbol table */ for (int regnum = 0; regnum < NUM_TEMP_VARIABLES; regnum++) @@ -363,7 +365,7 @@ u8 debugger_cpu::read_byte(address_space &space, offs_t address, bool apply_tran device_memory_interface &memory = space.device().memory(); /* mask against the logical byte mask */ - address &= space.logbytemask(); + address &= space.logaddrmask(); /* translate if necessary; if not mapped, return 0xff */ u8 result; @@ -388,7 +390,7 @@ u8 debugger_cpu::read_byte(address_space &space, offs_t address, bool apply_tran u16 debugger_cpu::read_word(address_space &space, offs_t address, bool apply_translation) { /* mask against the logical byte mask */ - address &= space.logbytemask(); + address &= space.logaddrmask(); u16 result; if (!WORD_ALIGNED(address)) @@ -429,7 +431,7 @@ u16 debugger_cpu::read_word(address_space &space, offs_t address, bool apply_tra u32 debugger_cpu::read_dword(address_space &space, offs_t address, bool apply_translation) { /* mask against the logical byte mask */ - address &= space.logbytemask(); + address &= space.logaddrmask(); u32 result; if (!DWORD_ALIGNED(address)) @@ -469,7 +471,7 @@ u32 debugger_cpu::read_dword(address_space &space, offs_t address, bool apply_tr u64 debugger_cpu::read_qword(address_space &space, offs_t address, bool apply_translation) { /* mask against the logical byte mask */ - address &= space.logbytemask(); + address &= space.logaddrmask(); u64 result; if (!QWORD_ALIGNED(address)) @@ -531,7 +533,7 @@ void debugger_cpu::write_byte(address_space &space, offs_t address, u8 data, boo device_memory_interface &memory = space.device().memory(); /* mask against the logical byte mask */ - address &= space.logbytemask(); + address &= space.logaddrmask(); /* translate if necessary; if not mapped, we're done */ if (apply_translation && !memory.translate(space.spacenum(), TRANSLATE_WRITE_DEBUG, address)) @@ -553,7 +555,7 @@ void debugger_cpu::write_byte(address_space &space, offs_t address, u8 data, boo void debugger_cpu::write_word(address_space &space, offs_t address, u16 data, bool apply_translation) { /* mask against the logical byte mask */ - address &= space.logbytemask(); + address &= space.logaddrmask(); /* if this is a misaligned write, or if there are no word writers, just read two bytes */ if (!WORD_ALIGNED(address)) @@ -596,7 +598,7 @@ void debugger_cpu::write_word(address_space &space, offs_t address, u16 data, bo void debugger_cpu::write_dword(address_space &space, offs_t address, u32 data, bool apply_translation) { /* mask against the logical byte mask */ - address &= space.logbytemask(); + address &= space.logaddrmask(); /* if this is a misaligned write, or if there are no dword writers, just read two words */ if (!DWORD_ALIGNED(address)) @@ -639,7 +641,7 @@ void debugger_cpu::write_dword(address_space &space, offs_t address, u32 data, b void debugger_cpu::write_qword(address_space &space, offs_t address, u64 data, bool apply_translation) { /* mask against the logical byte mask */ - address &= space.logbytemask(); + address &= space.logaddrmask(); /* if this is a misaligned write, or if there are no qword writers, just read two dwords */ if (!QWORD_ALIGNED(address)) @@ -703,7 +705,7 @@ u64 debugger_cpu::read_opcode(address_space &space, offs_t address, int size) u64 result = ~u64(0) & (~u64(0) >> (64 - 8*size)); /* keep in logical range */ - address &= space.logbytemask(); + address &= space.logaddrmask(); /* if we're bigger than the address bus, break into smaller pieces */ if (size > space.data_width() / 8) @@ -723,7 +725,7 @@ u64 debugger_cpu::read_opcode(address_space &space, offs_t address, int size) return result; /* keep in physical range */ - address &= space.bytemask(); + address &= space.addrmask(); /* switch off the size and handle unaligned accesses */ switch (size) @@ -1340,9 +1342,8 @@ expression_error::error_code debugger_cpu::expression_validate(void *param, cons get_beamx - get beam horizontal position -------------------------------------------------*/ -u64 debugger_cpu::get_beamx(symbol_table &table, void *ref) +u64 debugger_cpu::get_beamx(symbol_table &table, screen_device *screen) { - screen_device *screen = reinterpret_cast<screen_device *>(ref); return (screen != nullptr) ? screen->hpos() : 0; } @@ -1351,9 +1352,8 @@ u64 debugger_cpu::get_beamx(symbol_table &table, void *ref) get_beamy - get beam vertical position -------------------------------------------------*/ -u64 debugger_cpu::get_beamy(symbol_table &table, void *ref) +u64 debugger_cpu::get_beamy(symbol_table &table, screen_device *screen) { - screen_device *screen = reinterpret_cast<screen_device *>(ref); return (screen != nullptr) ? screen->vpos() : 0; } @@ -1362,9 +1362,8 @@ u64 debugger_cpu::get_beamy(symbol_table &table, void *ref) get_frame - get current frame number -------------------------------------------------*/ -u64 debugger_cpu::get_frame(symbol_table &table, void *ref) +u64 debugger_cpu::get_frame(symbol_table &table, screen_device *screen) { - screen_device *screen = reinterpret_cast<screen_device *>(ref); return (screen != nullptr) ? screen->frame_number() : 0; } @@ -1374,7 +1373,7 @@ u64 debugger_cpu::get_frame(symbol_table &table, void *ref) 'cpunum' symbol -------------------------------------------------*/ -u64 debugger_cpu::get_cpunum(symbol_table &table, void *ref) +u64 debugger_cpu::get_cpunum(symbol_table &table) { execute_interface_iterator iter(m_machine.root_device()); return iter.indexof(m_visiblecpu->execute()); @@ -1537,22 +1536,34 @@ device_debug::device_debug(device_t &device) // add global symbol for cycles and totalcycles if (m_exec != nullptr) { - m_symtable.add("cycles", nullptr, get_cycles); - m_symtable.add("totalcycles", nullptr, get_totalcycles); - m_symtable.add("lastinstructioncycles", nullptr, get_lastinstructioncycles); + m_symtable.add("cycles", get_cycles); + m_symtable.add("totalcycles", get_totalcycles); + m_symtable.add("lastinstructioncycles", get_lastinstructioncycles); } // add entries to enable/disable unmap reporting for each space if (m_memory != nullptr) { if (m_memory->has_space(AS_PROGRAM)) - m_symtable.add("logunmap", (void *)&m_memory->space(AS_PROGRAM), get_logunmap, set_logunmap); + m_symtable.add( + "logunmap", + [&space = m_memory->space(AS_PROGRAM)] (symbol_table &table) { return space.log_unmap(); }, + [&space = m_memory->space(AS_PROGRAM)] (symbol_table &table, u64 value) { return space.set_log_unmap(bool(value)); }); if (m_memory->has_space(AS_DATA)) - m_symtable.add("logunmapd", (void *)&m_memory->space(AS_DATA), get_logunmap, set_logunmap); + m_symtable.add( + "logunmap", + [&space = m_memory->space(AS_DATA)] (symbol_table &table) { return space.log_unmap(); }, + [&space = m_memory->space(AS_DATA)] (symbol_table &table, u64 value) { return space.set_log_unmap(bool(value)); }); if (m_memory->has_space(AS_IO)) - m_symtable.add("logunmapi", (void *)&m_memory->space(AS_IO), get_logunmap, set_logunmap); + m_symtable.add( + "logunmap", + [&space = m_memory->space(AS_IO)] (symbol_table &table) { return space.log_unmap(); }, + [&space = m_memory->space(AS_IO)] (symbol_table &table, u64 value) { return space.set_log_unmap(bool(value)); }); if (m_memory->has_space(AS_OPCODES)) - m_symtable.add("logunmapo", (void *)&m_memory->space(AS_OPCODES), get_logunmap, set_logunmap); + m_symtable.add( + "logunmap", + [&space = m_memory->space(AS_OPCODES)] (symbol_table &table) { return space.log_unmap(); }, + [&space = m_memory->space(AS_OPCODES)] (symbol_table &table, u64 value) { return space.set_log_unmap(bool(value)); }); } // add all registers into it @@ -1562,8 +1573,13 @@ device_debug::device_debug(device_t &device) // TODO: floating point registers if (!entry->is_float()) { + using namespace std::placeholders; strmakelower(tempstr.assign(entry->symbol())); - m_symtable.add(tempstr.c_str(), (void *)(uintptr_t)entry->index(), get_state, entry->writeable() ? set_state : nullptr, entry->format_string()); + m_symtable.add( + tempstr.c_str(), + std::bind(&device_debug::get_state, _1, entry->index()), + entry->writeable() ? std::bind(&device_debug::set_state, _1, entry->index(), _2) : symbol_table::setter_func(nullptr), + entry->format_string()); } } } @@ -1574,8 +1590,8 @@ device_debug::device_debug(device_t &device) m_flags = DEBUG_FLAG_OBSERVING | DEBUG_FLAG_HISTORY; // if no curpc, add one - if (m_state != nullptr && m_symtable.find("curpc") == nullptr) - m_symtable.add("curpc", nullptr, get_current_pc); + if (m_state && !m_symtable.find("curpc")) + m_symtable.add("curpc", get_current_pc); } // set up trace @@ -2487,33 +2503,15 @@ bool device_debug::comment_import(util::xml::data_node const &cpunode, bool is_i u32 device_debug::compute_opcode_crc32(offs_t pc) const { - // Basically the same thing as dasm_wrapped, but with some tiny savings - assert(m_memory != nullptr); + std::vector<u8> opbuf; + debug_disasm_buffer buffer(device()); - // determine the adjusted PC - address_space &decrypted_space = m_memory->has_space(AS_OPCODES) ? m_memory->space(AS_OPCODES) : m_memory->space(AS_PROGRAM); - address_space &space = m_memory->space(AS_PROGRAM); - offs_t pcbyte = space.address_to_byte(pc) & space.bytemask(); - - // fetch the bytes up to the maximum - u8 opbuf[64], argbuf[64]; - int maxbytes = (m_disasm != nullptr) ? m_disasm->max_opcode_bytes() : 1; - for (int numbytes = 0; numbytes < maxbytes; numbytes++) - { - opbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(space, pcbyte + numbytes, 1); - } - - u32 numbytes = maxbytes; - if (m_disasm != nullptr) - { - // disassemble to our buffer - std::ostringstream diasmbuf; - numbytes = m_disasm->disassemble(diasmbuf, pc, opbuf, argbuf) & DASMFLAG_LENGTHMASK; - } + // disassemble the current instruction and get the flags + u32 dasmresult = buffer.disassemble_info(pc); + buffer.data_get(pc, dasmresult & util::disasm_interface::LENGTHMASK, true, opbuf); // return a CRC of the exact count of opcode bytes - return core_crc32(0, opbuf, numbytes); + return core_crc32(0, &opbuf[0], opbuf.size()); } @@ -2593,26 +2591,29 @@ void device_debug::compute_debug_flags() void device_debug::prepare_for_step_overout(offs_t pc) { + debug_disasm_buffer buffer(device()); + // disassemble the current instruction and get the flags - std::string dasmbuffer; - offs_t dasmresult = dasm_wrapped(dasmbuffer, pc); + u32 dasmresult = buffer.disassemble_info(pc); // if flags are supported and it's a call-style opcode, set a temp breakpoint after that instruction - if ((dasmresult & DASMFLAG_SUPPORTED) != 0 && (dasmresult & DASMFLAG_STEP_OVER) != 0) + if ((dasmresult & util::disasm_interface::SUPPORTED) != 0 && (dasmresult & util::disasm_interface::STEP_OVER) != 0) { - int extraskip = (dasmresult & DASMFLAG_OVERINSTMASK) >> DASMFLAG_OVERINSTSHIFT; - pc += dasmresult & DASMFLAG_LENGTHMASK; + int extraskip = (dasmresult & util::disasm_interface::OVERINSTMASK) >> util::disasm_interface::OVERINSTSHIFT; + pc = buffer.next_pc_wrap(pc, dasmresult & util::disasm_interface::LENGTHMASK); // if we need to skip additional instructions, advance as requested - while (extraskip-- > 0) - pc += dasm_wrapped(dasmbuffer, pc) & DASMFLAG_LENGTHMASK; + while (extraskip-- > 0) { + u32 result = buffer.disassemble_info(pc); + pc += buffer.next_pc_wrap(pc, result & util::disasm_interface::LENGTHMASK); + } m_stepaddr = pc; } // if we're stepping out and this isn't a step out instruction, reset the steps until stop to a high number if ((m_flags & DEBUG_FLAG_STEPPING_OUT) != 0) { - if ((dasmresult & DASMFLAG_SUPPORTED) != 0 && (dasmresult & DASMFLAG_STEP_OUT) == 0) + if ((dasmresult & util::disasm_interface::SUPPORTED) != 0 && (dasmresult & util::disasm_interface::STEP_OUT) == 0) m_stepsleft = 100; else m_stepsleft = 1; @@ -2885,43 +2886,11 @@ void device_debug::hotspot_check(address_space &space, offs_t address) //------------------------------------------------- -// dasm_wrapped - wraps calls to the disassembler -// by fetching the opcode bytes to a temporary -// buffer and then disassembling them -//------------------------------------------------- - -u32 device_debug::dasm_wrapped(std::string &buffer, offs_t pc) -{ - assert(m_memory != nullptr && m_disasm != nullptr); - - // determine the adjusted PC - address_space &decrypted_space = m_memory->has_space(AS_OPCODES) ? m_memory->space(AS_OPCODES) : m_memory->space(AS_PROGRAM); - address_space &space = m_memory->space(AS_PROGRAM); - offs_t pcbyte = space.address_to_byte(pc) & space.bytemask(); - - // fetch the bytes up to the maximum - u8 opbuf[64], argbuf[64]; - int maxbytes = m_disasm->max_opcode_bytes(); - for (int numbytes = 0; numbytes < maxbytes; numbytes++) - { - opbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = m_device.machine().debugger().cpu().read_opcode(space, pcbyte + numbytes, 1); - } - - // disassemble to our buffer - std::ostringstream stream; - uint32_t result = m_disasm->disassemble(stream, pc, opbuf, argbuf); - buffer = stream.str(); - return result; -} - - -//------------------------------------------------- // get_current_pc - getter callback for a device's // current instruction pointer //------------------------------------------------- -u64 device_debug::get_current_pc(symbol_table &table, void *ref) +u64 device_debug::get_current_pc(symbol_table &table) { device_t *device = reinterpret_cast<device_t *>(table.globalref()); return device->safe_pcbase(); @@ -2933,7 +2902,7 @@ u64 device_debug::get_current_pc(symbol_table &table, void *ref) // 'cycles' symbol //------------------------------------------------- -u64 device_debug::get_cycles(symbol_table &table, void *ref) +u64 device_debug::get_cycles(symbol_table &table) { device_t *device = reinterpret_cast<device_t *>(table.globalref()); return device->debug()->m_exec->cycles_remaining(); @@ -2945,7 +2914,7 @@ u64 device_debug::get_cycles(symbol_table &table, void *ref) // 'totalcycles' symbol //------------------------------------------------- -u64 device_debug::get_totalcycles(symbol_table &table, void *ref) +u64 device_debug::get_totalcycles(symbol_table &table) { device_t *device = reinterpret_cast<device_t *>(table.globalref()); return device->debug()->m_total_cycles; @@ -2957,7 +2926,7 @@ u64 device_debug::get_totalcycles(symbol_table &table, void *ref) // 'lastinstructioncycles' symbol //------------------------------------------------- -u64 device_debug::get_lastinstructioncycles(symbol_table &table, void *ref) +u64 device_debug::get_lastinstructioncycles(symbol_table &table) { device_t *device = reinterpret_cast<device_t *>(table.globalref()); device_debug *debug = device->debug(); @@ -2966,38 +2935,14 @@ u64 device_debug::get_lastinstructioncycles(symbol_table &table, void *ref) //------------------------------------------------- -// get_logunmap - getter callback for the logumap -// symbols -//------------------------------------------------- - -u64 device_debug::get_logunmap(symbol_table &table, void *ref) -{ - address_space &space = *reinterpret_cast<address_space *>(table.globalref()); - return space.log_unmap(); -} - - -//------------------------------------------------- -// set_logunmap - setter callback for the logumap -// symbols -//------------------------------------------------- - -void device_debug::set_logunmap(symbol_table &table, void *ref, u64 value) -{ - address_space &space = *reinterpret_cast<address_space *>(table.globalref()); - space.set_log_unmap(value ? true : false); -} - - -//------------------------------------------------- // get_state - getter callback for a device's // state symbols //------------------------------------------------- -u64 device_debug::get_state(symbol_table &table, void *ref) +u64 device_debug::get_state(symbol_table &table, int index) { device_t *device = reinterpret_cast<device_t *>(table.globalref()); - return device->debug()->m_state->state_int(reinterpret_cast<uintptr_t>(ref)); + return device->debug()->m_state->state_int(index); } @@ -3006,10 +2951,10 @@ u64 device_debug::get_state(symbol_table &table, void *ref) // state symbols //------------------------------------------------- -void device_debug::set_state(symbol_table &table, void *ref, u64 value) +void device_debug::set_state(symbol_table &table, int index, u64 value) { device_t *device = reinterpret_cast<device_t *>(table.globalref()); - device->debug()->m_state->set_state_int(reinterpret_cast<uintptr_t>(ref), value); + device->debug()->m_state->set_state_int(index, value); } @@ -3094,8 +3039,8 @@ device_debug::watchpoint::watchpoint(device_debug* debugInterface, m_index(index), m_enabled(true), m_type(type), - m_address(space.address_to_byte(address) & space.bytemask()), - m_length(space.address_to_byte(length)), + m_address(address & space.addrmask()), + m_length(length), m_condition(&symbols, (condition != nullptr) ? condition : "1"), m_action((action != nullptr) ? action : "") { @@ -3257,35 +3202,24 @@ void device_debug::tracer::update(offs_t pc) if (!m_action.empty()) m_debug.m_device.machine().debugger().console().execute_command(m_action, false); - // print the address - std::string buffer; - int logaddrchars = m_debug.logaddrchars(); - if (m_debug.is_octal()) - { - buffer = string_format("%0*o: ", logaddrchars*3/2, pc); - } - else - { - buffer = string_format("%0*X: ", logaddrchars, pc); - } - - // print the disassembly - std::string dasm; - offs_t dasmresult = m_debug.dasm_wrapped(dasm, pc); - buffer.append(dasm); + debug_disasm_buffer buffer(m_debug.device()); + std::string instruction; + offs_t next_pc, size; + u32 dasmresult; + buffer.disassemble(pc, instruction, next_pc, size, dasmresult); // output the result - fprintf(&m_file, "%s\n", buffer.c_str()); + fprintf(&m_file, "%s: %s\n", buffer.pc_to_string(pc).c_str(), instruction.c_str()); // do we need to step the trace over this instruction? - if (m_trace_over && (dasmresult & DASMFLAG_SUPPORTED) != 0 && (dasmresult & DASMFLAG_STEP_OVER) != 0) + if (m_trace_over && (dasmresult & util::disasm_interface::SUPPORTED) != 0 && (dasmresult & util::disasm_interface::STEP_OVER) != 0) { - int extraskip = (dasmresult & DASMFLAG_OVERINSTMASK) >> DASMFLAG_OVERINSTSHIFT; - offs_t trace_over_target = pc + (dasmresult & DASMFLAG_LENGTHMASK); + int extraskip = (dasmresult & util::disasm_interface::OVERINSTMASK) >> util::disasm_interface::OVERINSTSHIFT; + offs_t trace_over_target = buffer.next_pc_wrap(pc, dasmresult & util::disasm_interface::LENGTHMASK); // if we need to skip additional instructions, advance as requested while (extraskip-- > 0) - trace_over_target += m_debug.dasm_wrapped(dasm, trace_over_target) & DASMFLAG_LENGTHMASK; + trace_over_target = buffer.next_pc_wrap(trace_over_target, buffer.disassemble_info(trace_over_target) & util::disasm_interface::LENGTHMASK); m_trace_over_target = trace_over_target; } diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h index 2ea78c3fe20..388e497cb0a 100644 --- a/src/emu/debug/debugcpu.h +++ b/src/emu/debug/debugcpu.h @@ -278,7 +278,6 @@ private: // internal helpers void prepare_for_step_overout(offs_t pc); - u32 dasm_wrapped(std::string &buffer, offs_t pc); void errorlog_write_line(const char *line); // breakpoint and watchpoint helpers @@ -289,14 +288,12 @@ private: void hotspot_check(address_space &space, offs_t address); // symbol get/set callbacks - static u64 get_current_pc(symbol_table &table, void *ref); - static u64 get_cycles(symbol_table &table, void *ref); - static u64 get_totalcycles(symbol_table &table, void *ref); - static u64 get_lastinstructioncycles(symbol_table &table, void *ref); - static u64 get_logunmap(symbol_table &table, void *ref); - static void set_logunmap(symbol_table &table, void *ref, u64 value); - static u64 get_state(symbol_table &table, void *ref); - static void set_state(symbol_table &table, void *ref, u64 value); + static u64 get_current_pc(symbol_table &table); + static u64 get_cycles(symbol_table &table); + static u64 get_totalcycles(symbol_table &table); + static u64 get_lastinstructioncycles(symbol_table &table); + static u64 get_state(symbol_table &table, int index); + static void set_state(symbol_table &table, int index, u64 value); // basic device information device_t & m_device; // device we are attached to @@ -586,10 +583,10 @@ private: device_t* expression_get_device(const char *tag); /* variable getters/setters */ - u64 get_cpunum(symbol_table &table, void *ref); - u64 get_beamx(symbol_table &table, void *ref); - u64 get_beamy(symbol_table &table, void *ref); - u64 get_frame(symbol_table &table, void *ref); + u64 get_cpunum(symbol_table &table); + u64 get_beamx(symbol_table &table, screen_device *screen); + u64 get_beamy(symbol_table &table, screen_device *screen); + u64 get_frame(symbol_table &table, screen_device *screen); /* internal helpers */ void on_vblank(screen_device &device, bool vblank_state); diff --git a/src/emu/debug/debugvw.h b/src/emu/debug/debugvw.h index d456eacdbeb..374af7f384e 100644 --- a/src/emu/debug/debugvw.h +++ b/src/emu/debug/debugvw.h @@ -158,7 +158,7 @@ public: void set_visible_position(debug_view_xy pos); void set_cursor_position(debug_view_xy pos); void set_cursor_visible(bool visible = true); - void set_source(const debug_view_source &source); + virtual void set_source(const debug_view_source &source); // helpers void process_char(int character) { view_char(character); } diff --git a/src/emu/debug/dvdisasm.cpp b/src/emu/debug/dvdisasm.cpp index 1051365c561..2292e766132 100644 --- a/src/emu/debug/dvdisasm.cpp +++ b/src/emu/debug/dvdisasm.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Aaron Giles +// copyright-holders:Aaron Giles, Olivier Galibert /********************************************************************* dvdisasm.c @@ -14,7 +14,6 @@ #include "debugcpu.h" #include "debugger.h" - //************************************************************************** // DEBUG VIEW DISASM SOURCE //************************************************************************** @@ -25,7 +24,6 @@ debug_view_disasm_source::debug_view_disasm_source(const char *name, device_t &device) : debug_view_source(name, &device), - m_disasmintf(dynamic_cast<device_disasm_interface *>(&device)), m_space(device.memory().space(AS_PROGRAM)), m_decrypted_space(device.memory().has_space(AS_OPCODES) ? device.memory().space(AS_OPCODES) : device.memory().space(AS_PROGRAM)) { @@ -49,23 +47,17 @@ debug_view_disasm::debug_view_disasm(running_machine &machine, debug_view_osd_up m_right_column(DASM_RIGHTCOL_RAW), m_backwards_steps(3), m_dasm_width(DEFAULT_DASM_WIDTH), - m_last_direct_raw(nullptr), - m_last_direct_decrypted(nullptr), - m_last_change_count(0), - m_last_pcbyte(0), - m_divider1(0), - m_divider2(0), - m_divider3(0), + m_previous_pc(1), m_expression(machine) { // fail if no available sources enumerate_sources(); - if (m_source_list.count() == 0) + if(m_source_list.count() == 0) throw std::bad_alloc(); // count the number of comments int total_comments = 0; - for (const debug_view_source &source : m_source_list) + for(const debug_view_source &source : m_source_list) { const debug_view_disasm_source &dasmsource = downcast<const debug_view_disasm_source &>(source); total_comments += dasmsource.device()->debug()->comment_count(); @@ -98,10 +90,10 @@ void debug_view_disasm::enumerate_sources() // iterate over devices with disassembly interfaces std::string name; - for (device_disasm_interface &dasm : disasm_interface_iterator(machine().root_device())) + for(device_disasm_interface &dasm : disasm_interface_iterator(machine().root_device())) { name = string_format("%s '%s'", dasm.device().name(), dasm.device().tag()); - if (dasm.device().memory().space_config(AS_PROGRAM)!=nullptr) + if(dasm.device().memory().space_config(AS_PROGRAM)!=nullptr) m_source_list.append(*global_alloc(debug_view_disasm_source(name.c_str(), dasm.device()))); } @@ -117,10 +109,10 @@ void debug_view_disasm::enumerate_sources() void debug_view_disasm::view_notify(debug_view_notification type) { - if (type == VIEW_NOTIFY_CURSOR_CHANGED) + if(type == VIEW_NOTIFY_CURSOR_CHANGED) adjust_visible_y_for_cursor(); - else if (type == VIEW_NOTIFY_SOURCE_CHANGED) + else if(type == VIEW_NOTIFY_SOURCE_CHANGED) m_expression.set_context(&downcast<const debug_view_disasm_source *>(m_source)->device()->debug()->symtable()); } @@ -136,29 +128,29 @@ void debug_view_disasm::view_char(int chval) u8 end_buffer = 3; s32 temp; - switch (chval) + switch(chval) { case DCH_UP: - if (m_cursor.y > 0) + if(m_cursor.y > 0) m_cursor.y--; break; case DCH_DOWN: - if (m_cursor.y < m_total.y - 1) + if(m_cursor.y < m_total.y - 1) m_cursor.y++; break; case DCH_PUP: - temp = m_cursor.y - (m_visible.y - end_buffer); - if (temp < 0) + temp = m_cursor.y -(m_visible.y - end_buffer); + if(temp < 0) m_cursor.y = 0; else m_cursor.y = temp; break; case DCH_PDOWN: - temp = m_cursor.y + (m_visible.y - end_buffer); - if (temp > m_total.y - 1) + temp = m_cursor.y +(m_visible.y - end_buffer); + if(temp > m_total.y - 1) m_cursor.y = m_total.y - 1; else m_cursor.y = temp; @@ -167,11 +159,11 @@ void debug_view_disasm::view_char(int chval) case DCH_HOME: // set the active column to the PC { const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); - offs_t pc = source.m_space.address_to_byte(source.device()->safe_pcbase()) & source.m_space.logbytemask(); + offs_t pc = source.device()->safe_pcbase() & source.m_space.logaddrmask(); // figure out which row the pc is on - for (unsigned int curline = 0; curline < m_dasm.size(); curline++) - if (m_dasm[curline].m_byteaddress == pc) + for(unsigned int curline = 0; curline < m_dasm.size(); curline++) + if(m_dasm[curline].m_address == pc) m_cursor.y = curline; break; } @@ -186,7 +178,7 @@ void debug_view_disasm::view_char(int chval) } /* send a cursor changed notification */ - if (m_cursor.y != origcursor.y) + if(m_cursor.y != origcursor.y) { begin_update(); view_notify(VIEW_NOTIFY_CURSOR_CHANGED); @@ -208,7 +200,7 @@ void debug_view_disasm::view_click(const int button, const debug_view_xy& pos) /* cursor popup|toggle */ bool cursorVisible = true; - if (m_cursor.y == origcursor.y) + if(m_cursor.y == origcursor.y) { cursorVisible = !m_cursor_visible; } @@ -221,218 +213,174 @@ void debug_view_disasm::view_click(const int button, const debug_view_xy& pos) end_update(); } +void debug_view_disasm::generate_from_address(debug_disasm_buffer &buffer, offs_t address) +{ + m_dasm.clear(); + for(int i=0; i != m_total.y; i++) { + std::string dasm; + offs_t size; + offs_t next_address; + u32 info; + buffer.disassemble(address, dasm, next_address, size, info); + m_dasm.emplace_back(address, size, dasm); + address = next_address; + } +} -//------------------------------------------------- -// find_pc_backwards - back up the specified -// number of instructions from the given PC -//------------------------------------------------- - -offs_t debug_view_disasm::find_pc_backwards(offs_t targetpc, int numinstrs) +bool debug_view_disasm::generate_with_pc(debug_disasm_buffer &buffer, offs_t pc) { - auto dis = machine().disable_side_effect(); + // Consider that instructions are 64 bytes max const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); + int shift = source.m_space.addr_shift(); - // compute the increment - int minlen = source.m_space.byte_to_address(source.m_disasmintf->min_opcode_bytes()); - if (minlen == 0) minlen = 1; - int maxlen = source.m_space.byte_to_address(source.m_disasmintf->max_opcode_bytes()); - if (maxlen == 0) maxlen = 1; - - // start off numinstrs back - offs_t curpc = targetpc - minlen * numinstrs; - if (curpc > targetpc) - curpc = 0; - - /* loop until we find what we are looking for */ - offs_t targetpcbyte = source.m_space.address_to_byte(targetpc) & source.m_space.logbytemask(); - offs_t fillpcbyte = targetpcbyte; - offs_t lastgoodpc = targetpc; - while (1) - { - // fill the buffer up to the target - offs_t curpcbyte = source.m_space.address_to_byte(curpc) & source.m_space.logbytemask(); - u8 opbuf[1024], argbuf[1024]; - while (curpcbyte < fillpcbyte) - { - fillpcbyte--; - opbuf[1000 + fillpcbyte - targetpcbyte] = machine().debugger().cpu().read_opcode(source.m_decrypted_space, fillpcbyte, 1); - argbuf[1000 + fillpcbyte - targetpcbyte] = machine().debugger().cpu().read_opcode(source.m_space, fillpcbyte, 1); + offs_t backwards_offset; + if(shift < 0) + backwards_offset = 64 >> -shift; + else if(shift == 0) + backwards_offset = 64; + else + backwards_offset = 64 << shift; + + m_dasm.clear(); + offs_t address = (pc - m_backwards_steps*backwards_offset) & source.m_space.logaddrmask(); + // Handle wrap at 0 + if(address > pc) + address = 0; + + util::disasm_interface *intf = dynamic_cast<device_disasm_interface &>(*source.device()).get_disassembler(); + if(intf->interface_flags() & util::disasm_interface::NONLINEAR_PC) { + offs_t lpc = intf->pc_real_to_linear(pc); + while(intf->pc_real_to_linear(address) < lpc) { + std::string dasm; + offs_t size; + offs_t next_address; + u32 info; + buffer.disassemble(address, dasm, next_address, size, info); + m_dasm.emplace_back(address, size, dasm); + if(intf->pc_real_to_linear(address) > intf->pc_real_to_linear(next_address)) + return false; + address = next_address; } - // loop until we get past the target instruction - int instcount = 0; - int instlen; - offs_t scanpc; - for (scanpc = curpc; scanpc < targetpc; scanpc += instlen) - { - offs_t scanpcbyte = source.m_space.address_to_byte(scanpc) & source.m_space.logbytemask(); - offs_t physpcbyte = scanpcbyte; - - // get the disassembly, but only if mapped - instlen = 1; - if (source.m_space.device().memory().translate(source.m_space.spacenum(), TRANSLATE_FETCH, physpcbyte)) - { - std::ostringstream dasmbuffer; - instlen = source.m_disasmintf->disassemble(dasmbuffer, scanpc, &opbuf[1000 + scanpcbyte - targetpcbyte], &argbuf[1000 + scanpcbyte - targetpcbyte]) & DASMFLAG_LENGTHMASK; - } - - // count this one - instcount++; + } else { + while(address < pc) { + std::string dasm; + offs_t size; + offs_t next_address; + u32 info; + buffer.disassemble(address, dasm, next_address, size, info); + m_dasm.emplace_back(address, size, dasm); + if(address > next_address) + return false; + address = next_address; } + } - // if we ended up right on targetpc, this is a good candidate - if (scanpc == targetpc && instcount <= numinstrs) - lastgoodpc = curpc; - - // we're also done if we go back too far - if (targetpc - curpc >= numinstrs * maxlen) - break; + if(address != pc) + return false; - // and if we hit 0, we're done - if (curpc == 0) - break; + if(m_dasm.size() > m_backwards_steps) + m_dasm.erase(m_dasm.begin(), m_dasm.begin() + (m_dasm.size() - m_backwards_steps)); - // back up one more and try again - curpc -= minlen; - if (curpc > targetpc) - curpc = 0; + while(m_dasm.size() < m_total.y) { + std::string dasm; + offs_t size; + offs_t next_address; + u32 info; + buffer.disassemble(address, dasm, next_address, size, info); + m_dasm.emplace_back(address, size, dasm); + address = next_address; } - - return lastgoodpc; + return true; } - -//------------------------------------------------- -// generate_bytes - generate the opcode byte -// values -//------------------------------------------------- - -std::string debug_view_disasm::generate_bytes(offs_t pcbyte, int numbytes, int granularity, bool encrypted) +int debug_view_disasm::address_position(offs_t pc) const { - const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); - const int char_num = source.m_space.is_octal() ? 3 : 2; - std::ostringstream ostr; - - for (int byte = 0; byte < numbytes; byte += granularity) { - if (byte) - ostr << ' '; - util::stream_format(ostr, source.m_space.is_octal() ? "%0*o" : "%0*X", granularity * char_num, machine().debugger().cpu().read_opcode(encrypted ? source.m_space : source.m_decrypted_space, pcbyte + byte, granularity)); - } - - return ostr.str(); + for(int i=0; i != int(m_dasm.size()); i++) + if(m_dasm[i].m_address == pc) + return i; + return -1; } - -//------------------------------------------------- -// recompute - recompute selected info for the -// disassembly view -//------------------------------------------------- - -bool debug_view_disasm::recompute(offs_t pc, int startline, int lines) +void debug_view_disasm::generate_dasm(debug_disasm_buffer &buffer, offs_t pc) { - auto dis = machine().disable_side_effect(); - - bool changed = false; - const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); - const int char_num = source.m_space.is_octal() ? 3 : 2; - - // determine how many characters we need for an address and set the divider - m_divider1 = 1 + (source.m_space.logaddrchars()/2*char_num) + 1; + bool pc_changed = pc != m_previous_pc; + m_previous_pc = pc; + if(strcmp(m_expression.string(), "curpc")) { + if(m_expression.dirty()) { + m_topleft.x = 0; + m_topleft.y = 0; + } + generate_from_address(buffer, m_expression.value()); + return; + } - // assume a fixed number of characters for the disassembly - m_divider2 = m_divider1 + 1 + m_dasm_width + 1; + if(address_position(pc) != -1) { + generate_from_address(buffer, m_dasm[0].m_address); + int pos = address_position(pc); + if(pos != -1) { + if(!pc_changed) + return; + if(pos >= m_topleft.y && pos < m_topleft.y + m_visible.y) + return; + if(pos < m_total.y - m_visible.y) { + m_topleft.x = 0; + m_topleft.y = pos - m_backwards_steps; + return; + } + } + } - // determine how many bytes we might need to display - const int minbytes = source.m_disasmintf->min_opcode_bytes(); - const int maxbytes = source.m_disasmintf->max_opcode_bytes(); + m_topleft.x = 0; + m_topleft.y = 0; - // ensure that the PC is aligned to the minimum opcode size - pc &= ~source.m_space.byte_to_address_end(minbytes - 1); + if(generate_with_pc(buffer, pc)) + return; - // set the width of the third column according to display mode - if (m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED) - { - int const maxbytes_clamped = (std::min)(maxbytes, DASM_MAX_BYTES); - m_total.x = m_divider2 + 1 + char_num * maxbytes_clamped + (maxbytes_clamped / minbytes - 1) + 1; - } - else if (m_right_column == DASM_RIGHTCOL_COMMENTS) - m_total.x = m_divider2 + 1 + 50; // DEBUG_COMMENT_MAX_LINE_LENGTH - else - m_total.x = m_divider2 + 1; + generate_from_address(buffer, pc); +} - // allocate dasm array - m_dasm.resize(m_total.y); +void debug_view_disasm::complete_information(const debug_view_disasm_source &source, debug_disasm_buffer &buffer, offs_t pc) +{ + for(auto &dasm : m_dasm) { + offs_t adr = dasm.m_address; - // comparison buffer to detect whether data changed when doing only one line - dasm_line comparison_buffer; + dasm.m_tadr = buffer.pc_to_string(adr); + dasm.m_topcodes = buffer.data_to_string(adr, dasm.m_size, true); + dasm.m_tparams = buffer.data_to_string(adr, dasm.m_size, false); - // iterate over lines - for (int line = 0; line < lines; line++) - { - // convert PC to a byte offset - const offs_t pcbyte = source.m_space.address_to_byte(pc) & source.m_space.logbytemask(); - - // save a copy of the previous line as a backup if we're only doing one line - const auto instr = startline + line; - if (lines == 1) - comparison_buffer = m_dasm[instr]; - - // convert back and set the address of this instruction - std::ostringstream oadr; - m_dasm[instr].m_byteaddress = pcbyte; - util::stream_format(oadr, - source.m_space.is_octal() ? " %0*o " : " %0*X ", - source.m_space.logaddrchars()/2*char_num, source.m_space.byte_to_address(pcbyte)); - m_dasm[instr].m_adr = oadr.str(); - - // make sure we can translate the address, and then disassemble the result - std::ostringstream dasm; - int numbytes = 0; - offs_t physpcbyte = pcbyte; - if (source.m_space.device().memory().translate(source.m_space.spacenum(), TRANSLATE_FETCH_DEBUG, physpcbyte)) - { - u8 opbuf[64], argbuf[64]; + dasm.m_is_pc = adr == pc; - // fetch the bytes up to the maximum - for (numbytes = 0; numbytes < maxbytes; numbytes++) - { - opbuf[numbytes] = machine().debugger().cpu().read_opcode(source.m_decrypted_space, pcbyte + numbytes, 1); - argbuf[numbytes] = machine().debugger().cpu().read_opcode(source.m_space, pcbyte + numbytes, 1); + dasm.m_is_bp = false; + for(device_debug::breakpoint *bp = source.device()->debug()->breakpoint_first(); bp != nullptr; bp = bp->next()) + if(adr ==(bp->address() & source.m_space.logaddrmask())) { + dasm.m_is_bp = true; + break; } - // disassemble the result - pc += numbytes = source.m_disasmintf->disassemble(dasm, pc & source.m_space.logaddrmask(), opbuf, argbuf) & DASMFLAG_LENGTHMASK; - } - else - dasm << "<unmapped>"; - - m_dasm[instr].m_dasm = dasm.str(); + dasm.m_is_visited = source.device()->debug()->track_pc_visited(adr); - // generate the byte views - std::ostringstream bytes_raw; - numbytes = source.m_space.address_to_byte(numbytes) & source.m_space.logbytemask(); - m_dasm[instr].m_rawdata = generate_bytes(pcbyte, numbytes, minbytes, false); - m_dasm[instr].m_encdata = generate_bytes(pcbyte, numbytes, minbytes, true); + const char *comment = source.device()->debug()->comment_text(adr); + if(comment) + dasm.m_comment = comment; + } +} - // get and add the comment, if present - const offs_t comment_address = source.m_space.byte_to_address(m_dasm[instr].m_byteaddress); - const char *const text = source.device()->debug()->comment_text(comment_address); - if (text != nullptr) - m_dasm[instr].m_comment = text; +//------------------------------------------------- +// view_update - update the contents of the +// disassembly view +//------------------------------------------------- - // see if the line changed at all - if (lines == 1 && m_dasm[instr] != comparison_buffer) - changed = true; - } +void debug_view_disasm::view_update() +{ + const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); + debug_disasm_buffer buffer(*source.device()); + offs_t pc = source.device()->safe_pcbase() & source.m_space.logaddrmask(); - // update opcode base information - m_last_direct_decrypted = source.m_decrypted_space.direct().ptr(); - m_last_direct_raw = source.m_space.direct().ptr(); - m_last_change_count = source.device()->debug()->comment_change_count(); + generate_dasm(buffer, pc); - // no longer need to recompute - m_recompute = false; - return changed; + complete_information(source, buffer, pc); + redraw(); } @@ -443,11 +391,11 @@ bool debug_view_disasm::recompute(offs_t pc, int startline, int lines) void debug_view_disasm::print(int row, std::string text, int start, int end, u8 attrib) { int view_end = end - m_topleft.x; - if (view_end < 0) + if(view_end < 0) return; int string_0 = start - m_topleft.x; - if (string_0 >= m_visible.x) + if(string_0 >= m_visible.x) return; int view_start = string_0 > 0 ? string_0 : 0; @@ -458,152 +406,63 @@ void debug_view_disasm::print(int row, std::string text, int start, int end, u8 for(int pos = view_start; pos < view_end; pos++) { int spos = pos - string_0; - if (spos >= int(text.size())) + if(spos >= int(text.size())) *dest++ = { ' ', attrib }; else *dest++ = { u8(text[spos]), attrib }; - } + } } + //------------------------------------------------- -// view_update - update the contents of the -// disassembly view +// redraw - update the view from the data //------------------------------------------------- -void debug_view_disasm::view_update() +void debug_view_disasm::redraw() { - const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); - - offs_t pc = source.device()->safe_pcbase(); - offs_t pcbyte = source.m_space.address_to_byte(pc) & source.m_space.logbytemask(); - - // update our context; if the expression is dirty, recompute - if (m_expression.dirty()) - m_recompute = true; - - // if we're tracking a value, make sure it is visible - u64 previous = m_expression.last_value(); - u64 result = m_expression.value(); - if (result != previous) - { - offs_t resultbyte = source.m_space.address_to_byte(result) & source.m_space.logbytemask(); - - // see if the new result is an address we already have - u32 row; - for (row = 0; row < m_dasm.size(); row++) - if (m_dasm[row].m_byteaddress == resultbyte) - break; - - // if we didn't find it, or if it's really close to the bottom, recompute - if (row == m_dasm.size() || row >= m_total.y - m_visible.y) - m_recompute = true; - - // otherwise, if it's not visible, adjust the view so it is - else if (row < m_topleft.y || row >= m_topleft.y + m_visible.y - 2) - m_topleft.y = (row > 3) ? row - 3 : 0; - } - - // if the opcode base has changed, rework things - if (source.m_decrypted_space.direct().ptr() != m_last_direct_decrypted || source.m_space.direct().ptr() != m_last_direct_raw) - m_recompute = true; - - // if the comments have changed, redo it - if (m_last_change_count != source.device()->debug()->comment_change_count()) - m_recompute = true; - - // if we need to recompute, do it - bool recomputed_this_time = false; -recompute: - if (m_recompute) - { - // recompute the view - if (!m_dasm.empty() && m_last_change_count != source.device()->debug()->comment_change_count()) - { - // smoosh us against the left column, but not the top row - m_topleft.x = 0; - - // recompute from where we last recomputed! - recompute(source.m_space.byte_to_address(m_dasm[0].m_byteaddress), 0, m_total.y); - } - else - { - // determine the addresses of what we will display - offs_t backpc = find_pc_backwards(u32(m_expression.value()), m_backwards_steps); - - // put ourselves back in the top left - m_topleft.y = 0; - m_topleft.x = 0; + // determine how many characters we need for an address and set the divider + int m_divider1 = 1 + m_dasm[0].m_tadr.size() + 1; - recompute(backpc, 0, m_total.y); - } - recomputed_this_time = true; - } + // assume a fixed number of characters for the disassembly + int m_divider2 = m_divider1 + 1 + m_dasm_width + 1; - // figure out the row where the PC is and recompute the disassembly - if (pcbyte != m_last_pcbyte) - { - // find the row with the PC on it - for (u32 row = 0; row < m_visible.y; row++) - { - u32 effrow = m_topleft.y + row; - if (effrow >= m_dasm.size()) - break; - if (pcbyte == m_dasm[effrow].m_byteaddress) - { - // see if we changed - bool changed = recompute(pc, effrow, 1); - if (changed && !recomputed_this_time) - { - m_recompute = true; - goto recompute; - } - - // set the effective row and PC - m_cursor.y = effrow; - view_notify(VIEW_NOTIFY_CURSOR_CHANGED); - } - } - m_last_pcbyte = pcbyte; - } + // set the width of the third column to max comment length + m_total.x = m_divider2 + 1 + 50; // DEBUG_COMMENT_MAX_LINE_LENGTH // loop over visible rows - for (u32 row = 0; row < m_visible.y; row++) + for(u32 row = 0; row < m_visible.y; row++) { u32 effrow = m_topleft.y + row; // if this visible row is valid, add it to the buffer u8 attrib = DCA_NORMAL; - if (effrow < m_dasm.size()) + if(effrow < m_dasm.size()) { - // if we're on the line with the PC, recompute and hilight it - if (pcbyte == m_dasm[effrow].m_byteaddress) + // if we're on the line with the PC, hilight it + if(m_dasm[effrow].m_is_pc) attrib = DCA_CURRENT; // if we're on a line with a breakpoint, tag it changed - else - { - for (device_debug::breakpoint *bp = source.device()->debug()->breakpoint_first(); bp != nullptr; bp = bp->next()) - if (m_dasm[effrow].m_byteaddress == (source.m_space.address_to_byte(bp->address()) & source.m_space.logbytemask())) - attrib = DCA_CHANGED; - } + else if(m_dasm[effrow].m_is_bp) + attrib = DCA_CHANGED; // if we're on the active column and everything is couth, highlight it - if (m_cursor_visible && effrow == m_cursor.y) + if(m_cursor_visible && effrow == m_cursor.y) attrib |= DCA_SELECTED; // if we've visited this pc, mark it as such - if (source.device()->debug()->track_pc_visited(m_dasm[effrow].m_byteaddress)) + if(m_dasm[effrow].m_is_visited) attrib |= DCA_VISITED; - print(row, m_dasm[effrow].m_adr, 0, m_divider1, attrib | DCA_ANCILLARY); + print(row, ' ' + m_dasm[effrow].m_tadr, 0, m_divider1, attrib | DCA_ANCILLARY); print(row, ' ' + m_dasm[effrow].m_dasm, m_divider1, m_divider2, attrib); - if (m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED) { - std::string text = ' ' + (m_right_column == DASM_RIGHTCOL_RAW ? m_dasm[effrow].m_rawdata : m_dasm[effrow].m_encdata); + if(m_right_column == DASM_RIGHTCOL_RAW || m_right_column == DASM_RIGHTCOL_ENCRYPTED) { + std::string text = ' ' +(m_right_column == DASM_RIGHTCOL_RAW ? m_dasm[effrow].m_topcodes : m_dasm[effrow].m_tparams); print(row, text, m_divider2, m_visible.x, attrib | DCA_ANCILLARY); if(int(text.size()) > m_visible.x - m_divider2) { int base = m_total.x - 3; - if (base < m_divider2) + if(base < m_divider2) base = m_divider2; print(row, "...", base, m_visible.x, attrib | DCA_ANCILLARY); } @@ -624,7 +483,7 @@ recompute: offs_t debug_view_disasm::selected_address() { flush_updates(); - return downcast<const debug_view_disasm_source &>(*m_source).m_space.byte_to_address(m_dasm[m_cursor.y].m_byteaddress); + return m_dasm[m_cursor.y].m_address; } @@ -679,7 +538,7 @@ void debug_view_disasm::set_disasm_width(u32 width) { begin_update(); m_dasm_width = width; - m_recompute = m_update_pending = true; + m_update_pending = true; end_update(); } @@ -692,12 +551,21 @@ void debug_view_disasm::set_disasm_width(u32 width) void debug_view_disasm::set_selected_address(offs_t address) { const debug_view_disasm_source &source = downcast<const debug_view_disasm_source &>(*m_source); - offs_t byteaddress = source.m_space.address_to_byte(address) & source.m_space.logbytemask(); - for (int line = 0; line < m_total.y; line++) - if (m_dasm[line].m_byteaddress == byteaddress) - { + address = address & source.m_space.logaddrmask(); + for(int line = 0; line < m_total.y; line++) + if(m_dasm[line].m_address == address) { m_cursor.y = line; set_cursor_position(m_cursor); break; } } + +//------------------------------------------------- +// set_source - set the current subview +//------------------------------------------------- + +void debug_view_disasm::set_source(const debug_view_source &source) +{ + debug_view::set_source(source); + m_dasm.clear(); +} diff --git a/src/emu/debug/dvdisasm.h b/src/emu/debug/dvdisasm.h index 85ebd7cfef2..ef9e4209f1b 100644 --- a/src/emu/debug/dvdisasm.h +++ b/src/emu/debug/dvdisasm.h @@ -14,6 +14,7 @@ #pragma once #include "debugvw.h" +#include "debugbuf.h" #include "vecstream.h" @@ -51,7 +52,6 @@ public: private: // internal state - device_disasm_interface *m_disasmintf; // disassembly interface address_space & m_space; // address space to display address_space & m_decrypted_space; // address space to display for decrypted opcodes }; @@ -80,6 +80,7 @@ public: void set_backward_steps(u32 steps); void set_disasm_width(u32 width); void set_selected_address(offs_t address); + virtual void set_source(const debug_view_source &source) override; protected: // view overrides @@ -90,49 +91,42 @@ protected: private: // The information of one disassembly line. May become the actual - // external interface at one point + // external interface at one point. struct dasm_line { - offs_t m_byteaddress; // address of the first byte of the instruction - std::string m_adr; // instruction address as a string + offs_t m_address; // address of the instruction + offs_t m_size; // size of the instruction + + std::string m_tadr; // instruction address as a string std::string m_dasm; // disassembly - std::string m_rawdata; // textual representation of the instruction values - std::string m_encdata; // textual representation of encrypted instruction values + std::string m_topcodes; // textual representation of opcode/default values + std::string m_tparams; // textual representation of parameter values std::string m_comment; // comment, when present - bool operator == (const dasm_line &right) const { - return - m_byteaddress == right.m_byteaddress && - m_adr == right.m_adr && - m_dasm == right.m_dasm && - m_rawdata == right.m_rawdata && - m_encdata == right.m_encdata && - m_comment == right.m_comment; - } - - bool operator != (const dasm_line &right) const { - return !(*this == right); - } + bool m_is_pc; // this line's address is PC + bool m_is_bp; // this line's address is a breakpoint + bool m_is_visited; // this line has been visited + + dasm_line(offs_t address, offs_t size, std::string dasm) : m_address(address), m_size(size), m_dasm(dasm), m_is_pc(false), m_is_bp(false), m_is_visited(false) {} }; // internal helpers + void generate_from_address(debug_disasm_buffer &buffer, offs_t address); + bool generate_with_pc(debug_disasm_buffer &buffer, offs_t pc); + int address_position(offs_t pc) const; + void generate_dasm(debug_disasm_buffer &buffer, offs_t pc); + void complete_information(const debug_view_disasm_source &source, debug_disasm_buffer &buffer, offs_t pc); + void enumerate_sources(); - offs_t find_pc_backwards(offs_t targetpc, int numinstrs); - std::string generate_bytes(offs_t pcbyte, int numbytes, int granularity, bool encrypted); - bool recompute(offs_t pc, int startline, int lines); void print(int row, std::string text, int start, int end, u8 attrib); + void redraw(); // internal state - disasm_right_column m_right_column; // right column contents - u32 m_backwards_steps; // number of backwards steps - u32 m_dasm_width; // width of the disassembly area - u8 * m_last_direct_raw; // last direct raw value - u8 * m_last_direct_decrypted;// last direct decrypted value - u32 m_last_change_count; // last comment change count - offs_t m_last_pcbyte; // last PC byte value - int m_divider1, m_divider2; // left and right divider columns - int m_divider3; // comment divider column - debug_view_expression m_expression; // expression-related information - std::vector<dasm_line> m_dasm; // disassembled instructions + disasm_right_column m_right_column; // right column contents + u32 m_backwards_steps; // number of backwards steps + u32 m_dasm_width; // width of the disassembly area + offs_t m_previous_pc; // previous pc, to detect whether it changed + debug_view_expression m_expression; // expression-related information + std::vector<dasm_line> m_dasm; // disassembled instructions // constants static constexpr int DEFAULT_DASM_LINES = 1000; diff --git a/src/emu/debug/dvmemory.cpp b/src/emu/debug/dvmemory.cpp index a5de89adb30..e32d576fa65 100644 --- a/src/emu/debug/dvmemory.cpp +++ b/src/emu/debug/dvmemory.cpp @@ -531,7 +531,7 @@ void debug_view_memory::recompute() int addrchars; if (source.m_space != nullptr) { - m_maxaddr = m_no_translation ? source.m_space->bytemask() : source.m_space->logbytemask(); + m_maxaddr = m_no_translation ? source.m_space->addrmask() : source.m_space->logaddrmask(); addrchars = m_no_translation ? source.m_space->addrchars() : source.m_space->logaddrchars(); } else @@ -547,6 +547,8 @@ void debug_view_memory::recompute() m_addrformat = string_format("%%0%dX%*s", addrchars, 8 - addrchars, ""); // if we are viewing a space with a minimum chunk size, clamp the bytes per chunk + // BAD +#if 0 if (source.m_space != nullptr && source.m_space->byte_to_address(1) > 1) { u32 min_bytes_per_chunk = source.m_space->byte_to_address(1); @@ -557,6 +559,7 @@ void debug_view_memory::recompute() } m_chunks_per_row = std::max(1U, m_chunks_per_row); } +#endif // recompute the byte offset based on the most recent expression result m_bytes_per_row = m_bytes_per_chunk * m_chunks_per_row; @@ -617,7 +620,7 @@ bool debug_view_memory::needs_recompute() const debug_view_memory_source &source = downcast<const debug_view_memory_source &>(*m_source); offs_t resultbyte; if (source.m_space != nullptr) - resultbyte = source.m_space->address_to_byte(m_expression.value()) & source.m_space->logbytemask(); + resultbyte = m_expression.value() & source.m_space->logaddrmask(); else resultbyte = m_expression.value(); diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp index 9661d80a35a..06e12e09800 100644 --- a/src/emu/debug/express.cpp +++ b/src/emu/debug/express.cpp @@ -114,7 +114,7 @@ public: // construction/destruction integer_symbol_entry(symbol_table &table, const char *name, symbol_table::read_write rw, u64 *ptr = nullptr); integer_symbol_entry(symbol_table &table, const char *name, u64 constval); - integer_symbol_entry(symbol_table &table, const char *name, void *ref, symbol_table::getter_func getter, symbol_table::setter_func setter, const std::string &format); + integer_symbol_entry(symbol_table &table, const char *name, symbol_table::getter_func getter, symbol_table::setter_func setter, const std::string &format); // symbol access virtual bool is_lval() const override; @@ -122,10 +122,6 @@ public: virtual void set_value(u64 newvalue) override; private: - // internal helpers - static u64 internal_getter(symbol_table &table, void *symref); - static void internal_setter(symbol_table &table, void *symref, u64 value); - // internal state symbol_table::getter_func m_getter; symbol_table::setter_func m_setter; @@ -138,7 +134,7 @@ class function_symbol_entry : public symbol_entry { public: // construction/destruction - function_symbol_entry(symbol_table &table, const char *name, void *ref, int minparams, int maxparams, symbol_table::execute_func execute); + function_symbol_entry(symbol_table &table, const char *name, int minparams, int maxparams, symbol_table::execute_func execute); // symbol access virtual bool is_lval() const override; @@ -203,13 +199,12 @@ const char *expression_error::code_string() const // symbol_entry - constructor //------------------------------------------------- -symbol_entry::symbol_entry(symbol_table &table, symbol_type type, const char *name, const std::string &format, void *ref) +symbol_entry::symbol_entry(symbol_table &table, symbol_type type, const char *name, const std::string &format) : m_next(nullptr), m_table(table), m_type(type), m_name(name), - m_format(format), - m_ref(ref) + m_format(format) { } @@ -233,25 +228,31 @@ symbol_entry::~symbol_entry() //------------------------------------------------- integer_symbol_entry::integer_symbol_entry(symbol_table &table, const char *name, symbol_table::read_write rw, u64 *ptr) - : symbol_entry(table, SMT_INTEGER, name, "", (ptr == nullptr) ? &m_value : ptr), - m_getter(internal_getter), - m_setter((rw == symbol_table::READ_ONLY) ? nullptr : internal_setter), + : symbol_entry(table, SMT_INTEGER, name, ""), + m_getter(ptr + ? symbol_table::getter_func([ptr] (symbol_table &table) { return *ptr; }) + : symbol_table::getter_func([this] (symbol_table &table) { return m_value; })), + m_setter((rw == symbol_table::READ_ONLY) + ? symbol_table::setter_func(nullptr) + : ptr + ? symbol_table::setter_func([ptr] (symbol_table &table, u64 value) { *ptr = value; }) + : symbol_table::setter_func([this] (symbol_table &table, u64 value) { m_value = value; })), m_value(0) { } integer_symbol_entry::integer_symbol_entry(symbol_table &table, const char *name, u64 constval) - : symbol_entry(table, SMT_INTEGER, name, "", &m_value), - m_getter(internal_getter), + : symbol_entry(table, SMT_INTEGER, name, ""), + m_getter([this] (symbol_table &table) { return m_value; }), m_setter(nullptr), m_value(constval) { } -integer_symbol_entry::integer_symbol_entry(symbol_table &table, const char *name, void *ref, symbol_table::getter_func getter, symbol_table::setter_func setter, const std::string &format) - : symbol_entry(table, SMT_INTEGER, name, format, ref), +integer_symbol_entry::integer_symbol_entry(symbol_table &table, const char *name, symbol_table::getter_func getter, symbol_table::setter_func setter, const std::string &format) + : symbol_entry(table, SMT_INTEGER, name, format), m_getter(getter), m_setter(setter), m_value(0) @@ -275,7 +276,7 @@ bool integer_symbol_entry::is_lval() const u64 integer_symbol_entry::value() const { - return m_getter(m_table, m_ref); + return m_getter(m_table); } @@ -286,34 +287,12 @@ u64 integer_symbol_entry::value() const void integer_symbol_entry::set_value(u64 newvalue) { if (m_setter != nullptr) - m_setter(m_table, m_ref, newvalue); + m_setter(m_table, newvalue); else throw emu_fatalerror("Symbol '%s' is read-only", m_name.c_str()); } -//------------------------------------------------- -// internal_getter - internal helper for -// returning the value of a variable -//------------------------------------------------- - -u64 integer_symbol_entry::internal_getter(symbol_table &table, void *symref) -{ - return *(u64 *)symref; -} - - -//------------------------------------------------- -// internal_setter - internal helper for setting -// the value of a variable -//------------------------------------------------- - -void integer_symbol_entry::internal_setter(symbol_table &table, void *symref, u64 value) -{ - *(u64 *)symref = value; -} - - //************************************************************************** // FUNCTION SYMBOL ENTRY @@ -323,8 +302,8 @@ void integer_symbol_entry::internal_setter(symbol_table &table, void *symref, u6 // function_symbol_entry - constructor //------------------------------------------------- -function_symbol_entry::function_symbol_entry(symbol_table &table, const char *name, void *ref, int minparams, int maxparams, symbol_table::execute_func execute) - : symbol_entry(table, SMT_FUNCTION, name, "", ref), +function_symbol_entry::function_symbol_entry(symbol_table &table, const char *name, int minparams, int maxparams, symbol_table::execute_func execute) + : symbol_entry(table, SMT_FUNCTION, name, ""), m_minparams(minparams), m_maxparams(maxparams), m_execute(execute) @@ -372,7 +351,7 @@ u64 function_symbol_entry::execute(int numparams, const u64 *paramlist) throw emu_fatalerror("Function '%s' requires at least %d parameters", m_name.c_str(), m_minparams); if (numparams > m_maxparams) throw emu_fatalerror("Function '%s' accepts no more than %d parameters", m_name.c_str(), m_maxparams); - return m_execute(m_table, m_ref, numparams, paramlist); + return m_execute(m_table, numparams, paramlist); } @@ -435,10 +414,10 @@ void symbol_table::add(const char *name, u64 value) // add - add a new register symbol //------------------------------------------------- -void symbol_table::add(const char *name, void *ref, getter_func getter, setter_func setter, const std::string &format_string) +void symbol_table::add(const char *name, getter_func getter, setter_func setter, const std::string &format_string) { m_symlist.erase(name); - m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, ref, getter, setter, format_string)); + m_symlist.emplace(name, std::make_unique<integer_symbol_entry>(*this, name, getter, setter, format_string)); } @@ -446,10 +425,10 @@ void symbol_table::add(const char *name, void *ref, getter_func getter, setter_f // add - add a new function symbol //------------------------------------------------- -void symbol_table::add(const char *name, void *ref, int minparams, int maxparams, execute_func execute) +void symbol_table::add(const char *name, int minparams, int maxparams, execute_func execute) { m_symlist.erase(name); - m_symlist.emplace(name, std::make_unique<function_symbol_entry>(*this, name, ref, minparams, maxparams, execute)); + m_symlist.emplace(name, std::make_unique<function_symbol_entry>(*this, name, minparams, maxparams, execute)); } diff --git a/src/emu/debug/express.h b/src/emu/debug/express.h index 19381786d1b..8084cf84e8f 100644 --- a/src/emu/debug/express.h +++ b/src/emu/debug/express.h @@ -114,7 +114,7 @@ protected: }; // construction/destruction - symbol_entry(symbol_table &table, symbol_type type, const char *name, const std::string &format, void *ref); + symbol_entry(symbol_table &table, symbol_type type, const char *name, const std::string &format); public: virtual ~symbol_entry(); @@ -138,7 +138,6 @@ protected: symbol_type m_type; // type of symbol std::string m_name; // name of the symbol std::string m_format; // format of symbol (or empty if unspecified) - void * m_ref; // internal reference }; @@ -150,11 +149,11 @@ class symbol_table { public: // callback functions for getting/setting a symbol value - typedef std::function<u64(symbol_table &table, void *symref)> getter_func; - typedef std::function<void(symbol_table &table, void *symref, u64 value)> setter_func; + typedef std::function<u64(symbol_table &table)> getter_func; + typedef std::function<void(symbol_table &table, u64 value)> setter_func; // callback functions for function execution - typedef std::function<u64(symbol_table &table, void *symref, int numparams, const u64 *paramlist)> execute_func; + typedef std::function<u64(symbol_table &table, int numparams, const u64 *paramlist)> execute_func; // callback functions for memory reads/writes typedef std::function<expression_error::error_code(void *cbparam, const char *name, expression_space space)> valid_func; @@ -181,8 +180,8 @@ public: // symbol access void add(const char *name, read_write rw, u64 *ptr = nullptr); void add(const char *name, u64 constvalue); - void add(const char *name, void *ref, getter_func getter, setter_func setter = nullptr, const std::string &format_string = ""); - void add(const char *name, void *ref, int minparams, int maxparams, execute_func execute); + void add(const char *name, getter_func getter, setter_func setter = nullptr, const std::string &format_string = ""); + void add(const char *name, int minparams, int maxparams, execute_func execute); symbol_entry *find(const char *name) const { if (name) { auto search = m_symlist.find(name); if (search != m_symlist.end()) return search->second.get(); else return nullptr; } else return nullptr; } symbol_entry *find_deep(const char *name); diff --git a/src/emu/devcpu.h b/src/emu/devcpu.h index 1c4bce13506..35c8c3b2a9e 100644 --- a/src/emu/devcpu.h +++ b/src/emu/devcpu.h @@ -50,15 +50,6 @@ //************************************************************************** -// MACROS -//************************************************************************** - -#define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name -#define CPU_DISASSEMBLE(name) offs_t CPU_DISASSEMBLE_NAME(name)(cpu_device *device, std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, int options) -#define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(device, stream, pc, oprom, opram, options) - - -//************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -86,7 +77,4 @@ private: }; -typedef offs_t (*cpu_disassemble_func)(cpu_device *device, std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, int options); - - #endif /* MAME_EMU_DEVCPU_H */ diff --git a/src/emu/didisasm.cpp b/src/emu/didisasm.cpp index 95353889a65..51a96915a04 100644 --- a/src/emu/didisasm.cpp +++ b/src/emu/didisasm.cpp @@ -11,82 +11,93 @@ #include "emu.h" -//************************************************************************** -// DEVICE DISASM INTERFACE -//************************************************************************** - -//------------------------------------------------- -// device_disasm_interface - constructor -//------------------------------------------------- - device_disasm_interface::device_disasm_interface(const machine_config &mconfig, device_t &device) : device_interface(device, "disasm") { } +util::disasm_interface *device_disasm_interface::get_disassembler() +{ + if(!m_disasm) { + if(m_dasm_override.isnull()) + m_disasm.reset(create_disassembler()); + else + m_disasm = std::make_unique<device_disasm_indirect>(create_disassembler(), m_dasm_override); + } + return m_disasm.get(); +} -//------------------------------------------------- -// ~device_disasm_interface - destructor -//------------------------------------------------- +void device_disasm_interface::interface_pre_start() +{ + m_dasm_override.bind_relative_to(*device().owner()); +} -device_disasm_interface::~device_disasm_interface() +void device_disasm_interface::set_dasm_override(dasm_override_delegate dasm_override) { + m_dasm_override = dasm_override; } +device_disasm_indirect::device_disasm_indirect(util::disasm_interface *upper, dasm_override_delegate &dasm_override) : m_dasm_override(dasm_override) +{ + m_disasm.reset(upper); +} -//------------------------------------------------- -// interface_pre_start - work to be done prior to -// actually starting a device -//------------------------------------------------- +u32 device_disasm_indirect::interface_flags() const +{ + return m_disasm->interface_flags(); +} -void device_disasm_interface::interface_pre_start() +u32 device_disasm_indirect::page_address_bits() const { - // bind delegate - m_dasm_override.bind_relative_to(*device().owner()); + return m_disasm->page_address_bits(); } +u32 device_disasm_indirect::page2_address_bits() const +{ + return m_disasm->page2_address_bits(); +} -//------------------------------------------------- -// static_set_dasm_override - configuration -// helper to override disassemble function -//------------------------------------------------- +offs_t device_disasm_indirect::pc_linear_to_real(offs_t pc) const +{ + return m_disasm->pc_linear_to_real(pc); +} -void device_disasm_interface::static_set_dasm_override(device_t &device, dasm_override_delegate dasm_override) +offs_t device_disasm_indirect::pc_real_to_linear(offs_t pc) const { - device_disasm_interface *dasm; - if (!device.interface(dasm)) - throw emu_fatalerror("MCFG_DEVICE_DISASSEMBLE_OVERRIDE called on device '%s' with no disasm interface", device.tag()); - dasm->m_dasm_override = dasm_override; + return m_disasm->pc_real_to_linear(pc); } +u8 device_disasm_indirect::decrypt8 (u8 value, offs_t pc, bool opcode) const +{ + return m_disasm->decrypt8(value, pc, opcode); +} -//------------------------------------------------- -// disassemble - interface for disassembly -//------------------------------------------------- +u16 device_disasm_indirect::decrypt16(u16 value, offs_t pc, bool opcode) const +{ + return m_disasm->decrypt16(value, pc, opcode); +} -offs_t device_disasm_interface::disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) +u32 device_disasm_indirect::decrypt32(u32 value, offs_t pc, bool opcode) const { - offs_t result = 0; + return m_disasm->decrypt32(value, pc, opcode); +} - // check for disassembler override - if (!m_dasm_override.isnull()) - result = m_dasm_override(device(), stream, pc, oprom, opram, options); - if (result == 0) - result = disasm_disassemble(stream, pc, oprom, opram, options); +u64 device_disasm_indirect::decrypt64(u64 value, offs_t pc, bool opcode) const +{ + return m_disasm->decrypt64(value, pc, opcode); +} - // make sure we get good results - assert((result & DASMFLAG_LENGTHMASK) != 0); -#ifdef MAME_DEBUG - device_memory_interface *memory; - if (device().interface(memory)) - { - address_space &space = memory->space(AS_PROGRAM); - int bytes = space.address_to_byte(result & DASMFLAG_LENGTHMASK); - assert(bytes >= min_opcode_bytes()); - assert(bytes <= max_opcode_bytes()); - (void) bytes; // appease compiler - } -#endif +u32 device_disasm_indirect::opcode_alignment() const +{ + return m_disasm->opcode_alignment(); +} +offs_t device_disasm_indirect::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) +{ + offs_t result = m_dasm_override(stream, pc, opcodes, params); + if(!result) + result = m_disasm->disassemble(stream, pc, opcodes, params); return result; } + + diff --git a/src/emu/didisasm.h b/src/emu/didisasm.h index edd56b3352f..9636b67a6db 100644 --- a/src/emu/didisasm.h +++ b/src/emu/didisasm.h @@ -17,79 +17,70 @@ #ifndef MAME_EMU_DIDISASM_H #define MAME_EMU_DIDISASM_H - -//************************************************************************** -// CONSTANTS -//************************************************************************** - -// Disassembler constants -constexpr u32 DASMFLAG_SUPPORTED = 0x80000000; // are disassembly flags supported? -constexpr u32 DASMFLAG_STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence -constexpr u32 DASMFLAG_STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards -constexpr u32 DASMFLAG_OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over -constexpr u32 DASMFLAG_OVERINSTSHIFT = 27; // bits to shift after masking to get the value -constexpr u32 DASMFLAG_LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length - - - -//************************************************************************** -// MACROS -//************************************************************************** - -#define DASMFLAG_STEP_OVER_EXTRA(x) ((x) << DASMFLAG_OVERINSTSHIFT) - - - -//************************************************************************** -// INTERFACE CONFIGURATION MACROS -//************************************************************************** +#include "disasmintf.h" #define MCFG_DEVICE_DISASSEMBLE_OVERRIDE(_class, _func) \ - device_disasm_interface::static_set_dasm_override(*device, dasm_override_delegate(&_class::_func, #_class "::" #_func, nullptr, (_class *)nullptr)); - - + dynamic_cast<device_disasm_interface *>(device)->set_dasm_override(dasm_override_delegate(&_class::_func, #_class "::" #_func, nullptr, (_class *)nullptr)); //************************************************************************** // TYPE DEFINITIONS //************************************************************************** -typedef device_delegate<offs_t (device_t &device, std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, int options)> dasm_override_delegate; +typedef device_delegate<offs_t (std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms)> dasm_override_delegate; // ======================> device_disasm_interface - + // class representing interface-specific live disasm class device_disasm_interface : public device_interface { public: // construction/destruction device_disasm_interface(const machine_config &mconfig, device_t &device); - virtual ~device_disasm_interface(); + virtual ~device_disasm_interface() = default; - // configuration access - u32 min_opcode_bytes() const { return disasm_min_opcode_bytes(); } - u32 max_opcode_bytes() const { return disasm_max_opcode_bytes(); } + // Override + void set_dasm_override(dasm_override_delegate dasm_override); - // static inline configuration helpers - static void static_set_dasm_override(device_t &device, dasm_override_delegate dasm_override); - - // interface for disassembly - offs_t disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options = 0); + // disassembler request + util::disasm_interface *get_disassembler(); protected: - // required operation overrides - virtual u32 disasm_min_opcode_bytes() const = 0; - virtual u32 disasm_max_opcode_bytes() const = 0; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) = 0; + // disassembler creation + virtual util::disasm_interface *create_disassembler() = 0; - // interface-level overrides + // delegate resolving virtual void interface_pre_start() override; private: - dasm_override_delegate m_dasm_override; // provided override function + std::unique_ptr<util::disasm_interface> m_disasm; + dasm_override_delegate m_dasm_override; }; // iterator typedef device_interface_iterator<device_disasm_interface> disasm_interface_iterator; +class device_disasm_indirect : public util::disasm_interface +{ +public: + device_disasm_indirect(util::disasm_interface *upper, dasm_override_delegate &dasm_override); + virtual ~device_disasm_indirect() = default; + + virtual u32 interface_flags() const override; + virtual u32 page_address_bits() const override; + virtual u32 page2_address_bits() const override; + virtual offs_t pc_linear_to_real(offs_t pc) const override; + virtual offs_t pc_real_to_linear(offs_t pc) const override; + virtual u8 decrypt8 (u8 value, offs_t pc, bool opcode) const override; + virtual u16 decrypt16(u16 value, offs_t pc, bool opcode) const override; + virtual u32 decrypt32(u32 value, offs_t pc, bool opcode) const override; + virtual u64 decrypt64(u64 value, offs_t pc, bool opcode) const override; + + virtual u32 opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; + +private: + std::unique_ptr<util::disasm_interface> m_disasm; + dasm_override_delegate &m_dasm_override; +}; #endif /* MAME_EMU_DIDISASM_H */ diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp index e43613b0302..0958108fe42 100644 --- a/src/emu/diexec.cpp +++ b/src/emu/diexec.cpp @@ -695,6 +695,48 @@ TIMER_CALLBACK_MEMBER(device_execute_interface::trigger_periodic_interrupt) } +//------------------------------------------------- +// irq_pulse_clear - clear a "pulsed" input line +//------------------------------------------------- + +TIMER_CALLBACK_MEMBER(device_execute_interface::irq_pulse_clear) +{ + int irqline = param; + set_input_line(irqline, CLEAR_LINE); +} + + +//------------------------------------------------- +// pulse_input_line - "pulse" an input line by +// asserting it and then clearing it later +//------------------------------------------------- + +void device_execute_interface::pulse_input_line(int irqline, const attotime &duration) +{ + assert(duration > attotime::zero); + set_input_line(irqline, ASSERT_LINE); + + attotime target_time = local_time() + duration; + m_scheduler->timer_set(target_time - m_scheduler->time(), timer_expired_delegate(FUNC(device_execute_interface::irq_pulse_clear), this), irqline); +} + + +//------------------------------------------------- +// pulse_input_line_and_vector - "pulse" an +// input line by asserting it and then clearing it +// later, specifying a vector +//------------------------------------------------- + +void device_execute_interface::pulse_input_line_and_vector(int irqline, int vector, const attotime &duration) +{ + assert(duration > attotime::zero); + set_input_line_and_vector(irqline, ASSERT_LINE, vector); + + attotime target_time = local_time() + duration; + m_scheduler->timer_set(target_time - m_scheduler->time(), timer_expired_delegate(FUNC(device_execute_interface::irq_pulse_clear), this), irqline); +} + + //************************************************************************** // DEVICE INPUT diff --git a/src/emu/diexec.h b/src/emu/diexec.h index 8e4c4ce9cc5..c307400dd69 100644 --- a/src/emu/diexec.h +++ b/src/emu/diexec.h @@ -162,6 +162,8 @@ public: void set_input_line_vector(int linenum, int vector) { m_input[linenum].set_vector(vector); } void set_input_line_and_vector(int linenum, int state, int vector) { m_input[linenum].set_state_synced(state, vector); } int input_state(int linenum) const { return m_input[linenum].m_curstate; } + void pulse_input_line(int irqline, const attotime &duration); + void pulse_input_line_and_vector(int irqline, int vector, const attotime &duration); // suspend/resume void suspend(u32 reason, bool eatcycles); @@ -292,9 +294,13 @@ private: void on_vblank(screen_device &screen, bool vblank_state); TIMER_CALLBACK_MEMBER(trigger_periodic_interrupt); + TIMER_CALLBACK_MEMBER(irq_pulse_clear); void suspend_resume_changed(); attoseconds_t minimum_quantum() const; + +public: + attotime minimum_quantum_time() const { return attotime(0, minimum_quantum()); } }; // iterator diff --git a/src/emu/dimemory.cpp b/src/emu/dimemory.cpp index 43f05f6019c..9a78f88d6c4 100644 --- a/src/emu/dimemory.cpp +++ b/src/emu/dimemory.cpp @@ -30,9 +30,9 @@ address_space_config::address_space_config() : m_name("unknown"), m_endianness(ENDIANNESS_NATIVE), - m_databus_width(0), - m_addrbus_width(0), - m_addrbus_shift(0), + m_data_width(0), + m_addr_width(0), + m_addr_shift(0), m_logaddr_width(0), m_page_shift(0), m_is_octal(false), @@ -53,9 +53,9 @@ address_space_config::address_space_config() address_space_config::address_space_config(const char *name, endianness_t endian, u8 datawidth, u8 addrwidth, s8 addrshift, address_map_constructor internal, address_map_constructor defmap) : m_name(name), m_endianness(endian), - m_databus_width(datawidth), - m_addrbus_width(addrwidth), - m_addrbus_shift(addrshift), + m_data_width(datawidth), + m_addr_width(addrwidth), + m_addr_shift(addrshift), m_logaddr_width(addrwidth), m_page_shift(0), m_is_octal(false), @@ -67,9 +67,9 @@ address_space_config::address_space_config(const char *name, endianness_t endian address_space_config::address_space_config(const char *name, endianness_t endian, u8 datawidth, u8 addrwidth, s8 addrshift, u8 logwidth, u8 pageshift, address_map_constructor internal, address_map_constructor defmap) : m_name(name), m_endianness(endian), - m_databus_width(datawidth), - m_addrbus_width(addrwidth), - m_addrbus_shift(addrshift), + m_data_width(datawidth), + m_addr_width(addrwidth), + m_addr_shift(addrshift), m_logaddr_width(logwidth), m_page_shift(pageshift), m_is_octal(false), @@ -81,9 +81,9 @@ address_space_config::address_space_config(const char *name, endianness_t endian address_space_config::address_space_config(const char *name, endianness_t endian, u8 datawidth, u8 addrwidth, s8 addrshift, address_map_delegate internal, address_map_delegate defmap) : m_name(name), m_endianness(endian), - m_databus_width(datawidth), - m_addrbus_width(addrwidth), - m_addrbus_shift(addrshift), + m_data_width(datawidth), + m_addr_width(addrwidth), + m_addr_shift(addrshift), m_logaddr_width(addrwidth), m_page_shift(0), m_is_octal(false), @@ -97,9 +97,9 @@ address_space_config::address_space_config(const char *name, endianness_t endian address_space_config::address_space_config(const char *name, endianness_t endian, u8 datawidth, u8 addrwidth, s8 addrshift, u8 logwidth, u8 pageshift, address_map_delegate internal, address_map_delegate defmap) : m_name(name), m_endianness(endian), - m_databus_width(datawidth), - m_addrbus_width(addrwidth), - m_addrbus_shift(addrshift), + m_data_width(datawidth), + m_addr_width(addrwidth), + m_addr_shift(addrshift), m_logaddr_width(logwidth), m_page_shift(pageshift), m_is_octal(false), diff --git a/src/emu/dipalette.cpp b/src/emu/dipalette.cpp index d996ccafe4d..f7d4a6974d4 100644 --- a/src/emu/dipalette.cpp +++ b/src/emu/dipalette.cpp @@ -26,7 +26,7 @@ device_palette_interface::device_palette_interface(const machine_config &mconfig : device_interface(device, "palette"), m_palette(nullptr), m_pens(nullptr), - m_format(), + m_format(BITMAP_FORMAT_RGB32), m_shadow_table(nullptr), m_shadow_group(0), m_hilight_group(0), @@ -57,10 +57,6 @@ void device_palette_interface::interface_validity_check(validity_checker &valid) void device_palette_interface::interface_pre_start() { - // reset all our data - screen_device *screen = device().machine().first_screen(); - m_format = (screen != nullptr) ? screen->format() : BITMAP_FORMAT_INVALID; - // allocate the palette u32 numentries = palette_entries(); allocate_palette(numentries); diff --git a/src/emu/dipalette.h b/src/emu/dipalette.h index eb2979f6118..358d5071b58 100644 --- a/src/emu/dipalette.h +++ b/src/emu/dipalette.h @@ -37,6 +37,8 @@ typedef u16 indirect_pen_t; class device_palette_interface : public device_interface { + friend class screen_device; + static constexpr int MAX_SHADOW_PRESETS = 4; public: diff --git a/src/emu/dirom.cpp b/src/emu/dirom.cpp index 161b7770c75..3a0ed23692f 100644 --- a/src/emu/dirom.cpp +++ b/src/emu/dirom.cpp @@ -85,7 +85,7 @@ void device_rom_interface::set_rom(const void *base, u32 size) void device_rom_interface::interface_pre_start() { - m_rom_direct = &space().direct(); + m_rom_direct = space().direct<0>(); m_bank = nullptr; m_cur_bank = -1; device().save_item(NAME(m_cur_bank)); diff --git a/src/emu/dirom.h b/src/emu/dirom.h index 1e9efcca037..2ea7edca810 100644 --- a/src/emu/dirom.h +++ b/src/emu/dirom.h @@ -42,7 +42,7 @@ protected: private: const char *m_rom_tag; const address_space_config m_rom_config; - direct_read_data *m_rom_direct; + direct_read_data<0> *m_rom_direct; memory_bank *m_bank; int m_cur_bank, m_bank_count; diff --git a/src/emu/diserial.cpp b/src/emu/diserial.cpp index b0a8e40ab6a..db8f726d8c7 100644 --- a/src/emu/diserial.cpp +++ b/src/emu/diserial.cpp @@ -213,6 +213,7 @@ WRITE_LINE_MEMBER(device_serial_interface::rx_w) receive_register_update_bit(state); if(m_rcv_flags & RECEIVE_REGISTER_SYNCHRONISED) { + //device().logerror("Receiver is synchronized\n"); if(m_rcv_clock && !(m_rcv_rate.is_never())) // make start delay just a bit longer to make sure we are called after the sender m_rcv_clock->adjust(((m_rcv_rate*3)/2), 0, m_rcv_rate); @@ -266,6 +267,7 @@ void device_serial_interface::receive_register_update_bit(int bit) else if (m_rcv_flags & RECEIVE_REGISTER_SYNCHRONISED) { + //device().logerror("Received bit %d\n", m_rcv_bit_count_received); m_rcv_bit_count_received++; if (!bit && (m_rcv_bit_count_received > (m_rcv_bit_count - m_df_stop_bit_count))) @@ -279,7 +281,7 @@ void device_serial_interface::receive_register_update_bit(int bit) m_rcv_bit_count_received = 0; m_rcv_flags &=~RECEIVE_REGISTER_SYNCHRONISED; m_rcv_flags |= RECEIVE_REGISTER_WAITING_FOR_START_BIT; - //logerror("receive register full\n"); + //device().logerror("Receive register full\n"); m_rcv_flags |= RECEIVE_REGISTER_FULL; } } diff --git a/src/emu/divideo.cpp b/src/emu/divideo.cpp index 4abe607dab3..7007487ef32 100644 --- a/src/emu/divideo.cpp +++ b/src/emu/divideo.cpp @@ -134,11 +134,8 @@ void device_video_interface::interface_pre_start() throw device_missing_dependencies(); else { - // resolve the palette for the sake of register_screen_bitmap - m_screen->resolve_palette(); - - // no other palette may be specified (FIXME: breaks meritm.cpp) - if (0 && m_screen->has_palette() && palintf != &m_screen->palette()) + // no other palette may be specified + if (m_screen->has_palette() && palintf != &m_screen->palette()) throw emu_fatalerror("Device '%s' cannot control screen '%s' with palette '%s'", device().tag(), m_screen_tag, m_screen->palette().device().tag()); } } diff --git a/src/emu/drawgfx.cpp b/src/emu/drawgfx.cpp index edbfa1ec306..eff4e46f2cf 100644 --- a/src/emu/drawgfx.cpp +++ b/src/emu/drawgfx.cpp @@ -1919,6 +1919,18 @@ void copybitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, in } +/*------------------------------------------------- + copybitmap_transalphpa - copy from one bitmap + to another, copying all unclipped pixels except + those with an alpha value of zero +-------------------------------------------------*/ + +void copybitmap_transalpha(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect) +{ + DECLARE_NO_PRIORITY; + COPYBITMAP_CORE(u32, PIXEL_OP_COPY_TRANSALPHA, NO_PRIORITY); +} + /*************************************************************************** COPYSCROLLBITMAP IMPLEMENTATIONS diff --git a/src/emu/drawgfx.h b/src/emu/drawgfx.h index fe5cb7679df..e9833de4a30 100644 --- a/src/emu/drawgfx.h +++ b/src/emu/drawgfx.h @@ -352,6 +352,8 @@ void copybitmap(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flip void copybitmap_trans(bitmap_ind16 &dest, const bitmap_ind16 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, u32 transpen); void copybitmap_trans(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect, u32 transpen); +void copybitmap_transalpha(bitmap_rgb32 &dest, const bitmap_rgb32 &src, int flipx, int flipy, s32 destx, s32 desty, const rectangle &cliprect); + /* Copy a bitmap onto another with scroll and wraparound. These functions support multiple independently scrolling rows/columns. @@ -429,7 +431,7 @@ constexpr u32 alpha_blend_r16(u32 d, u32 s, u8 level) //------------------------------------------------- -// alpha_blend_r16 - alpha blend two 32-bit +// alpha_blend_r32 - alpha blend two 32-bit // 8-8-8 RGB pixels //------------------------------------------------- diff --git a/src/emu/drawgfxm.h b/src/emu/drawgfxm.h index 325ce0e974c..1bef8e15237 100644 --- a/src/emu/drawgfxm.h +++ b/src/emu/drawgfxm.h @@ -95,6 +95,21 @@ do while (0) /*------------------------------------------------- + PIXEL_OP_COPY_TRANSALPHA - render all pixels + except those with an alpha of zero, copying + directly +-------------------------------------------------*/ + +#define PIXEL_OP_COPY_TRANSALPHA(DEST, PRIORITY, SOURCE) \ +do \ +{ \ + u32 srcdata = (SOURCE); \ + if ((srcdata & 0xff000000) != 0) \ + (DEST) = SOURCE; \ +} \ +while (0) + +/*------------------------------------------------- PIXEL_OP_REMAP_OPAQUE - render all pixels regardless of pen, mapping the pen via the 'paldata' array diff --git a/src/emu/driver.cpp b/src/emu/driver.cpp index 7f8d48a9257..75e01880fe2 100644 --- a/src/emu/driver.cpp +++ b/src/emu/driver.cpp @@ -260,55 +260,6 @@ void driver_device::device_reset_after_children() //************************************************************************** -// INTERRUPT ENABLE AND VECTOR HELPERS -//************************************************************************** - -//------------------------------------------------- -// irq_pulse_clear - clear a "pulsed" IRQ line -//------------------------------------------------- - -void driver_device::irq_pulse_clear(void *ptr, s32 param) -{ - device_execute_interface *exec = reinterpret_cast<device_execute_interface *>(ptr); - int irqline = param; - exec->set_input_line(irqline, CLEAR_LINE); -} - - -//------------------------------------------------- -// generic_pulse_irq_line - "pulse" an IRQ line by -// asserting it and then clearing it x cycle(s) -// later -//------------------------------------------------- - -void driver_device::generic_pulse_irq_line(device_execute_interface &exec, int irqline, int cycles) -{ - assert(irqline != INPUT_LINE_NMI && irqline != INPUT_LINE_RESET && cycles > 0); - exec.set_input_line(irqline, ASSERT_LINE); - - attotime target_time = exec.local_time() + exec.cycles_to_attotime(cycles * exec.min_cycles()); - machine().scheduler().timer_set(target_time - machine().time(), timer_expired_delegate(FUNC(driver_device::irq_pulse_clear), this), irqline, (void *)&exec); -} - - -//------------------------------------------------- -// generic_pulse_irq_line_and_vector - "pulse" an -// IRQ line by asserting it and then clearing it -// x cycle(s) later, specifying a vector -//------------------------------------------------- - -void driver_device::generic_pulse_irq_line_and_vector(device_execute_interface &exec, int irqline, int vector, int cycles) -{ - assert(irqline != INPUT_LINE_NMI && irqline != INPUT_LINE_RESET && cycles > 0); - exec.set_input_line_and_vector(irqline, ASSERT_LINE, vector); - - attotime target_time = exec.local_time() + exec.cycles_to_attotime(cycles * exec.min_cycles()); - machine().scheduler().timer_set(target_time - machine().time(), timer_expired_delegate(FUNC(driver_device::irq_pulse_clear), this), irqline, (void *)&exec); -} - - - -//************************************************************************** // INTERRUPT GENERATION CALLBACK HELPERS //************************************************************************** diff --git a/src/emu/driver.h b/src/emu/driver.h index 467a261cedf..2b4d3088a1f 100644 --- a/src/emu/driver.h +++ b/src/emu/driver.h @@ -130,10 +130,6 @@ public: // output heler output_manager &output() const { return machine().output(); } - // generic interrupt generators - void generic_pulse_irq_line(device_execute_interface &exec, int irqline, int cycles); - void generic_pulse_irq_line_and_vector(device_execute_interface &exec, int irqline, int vector, int cycles); - INTERRUPT_GEN_MEMBER( nmi_line_pulse ); INTERRUPT_GEN_MEMBER( nmi_line_assert ); @@ -196,7 +192,6 @@ protected: private: // helpers - void irq_pulse_clear(void *ptr, s32 param); void updateflip(); // internal state diff --git a/src/emu/drivers/xtal.h b/src/emu/drivers/xtal.h index 8729e8e7ec3..8c9fb948510 100644 --- a/src/emu/drivers/xtal.h +++ b/src/emu/drivers/xtal.h @@ -35,6 +35,11 @@ XTAL_3_579545MHz should actually be 3579545.454545...Hz (39375000/11). This is no problem though: see above note about tolerance. + In the "Examples" column, please don't add 1000 examples, this is just + for interest, so two or three examples is enough. + The actual reference where the xtals are used can be found in the + driver files by searching for the frequency (e.g. "XTAL_4_9152MHz") + (Thanks to Guru for starting this documentation.) **************************************************************************/ @@ -53,6 +58,7 @@ enum XTAL_1MHz = 1000000, /* Used to drive OKI M6295 chips */ XTAL_1_2944MHz = 1294400, /* BBN BitGraph PSG */ XTAL_1_75MHz = 1750000, /* RCA CDP1861 */ + XTAL_1_7971MHz = 1797100, /* SWTPC 6800 (with MIKBUG) */ XTAL_1_8432MHz = 1843200, /* Bondwell 12/14 */ XTAL_1_9968MHz = 1996800, /* NEC PC-98xx */ XTAL_2MHz = 2000000, @@ -92,7 +98,7 @@ enum XTAL_5_911MHz = 5911000, /* Philips Videopac Plus G7400 */ XTAL_5_9904MHz = 5990400, /* Luxor ABC 800 keyboard (Keytronic custom part #48-300-008 is equivalent) */ XTAL_6MHz = 6000000, /* American Poker II, Taito SJ System */ - XTAL_6_144MHz = 6144000, /* Used on Alpha Denshi early 80's games sound board, Casio FP-200 and Namco System 16 */ + XTAL_6_144MHz = 6144000, /* Used on Alpha Denshi early 80's games sound board, Casio FP-200 and Namco Universal System 16 */ XTAL_6_5MHz = 6500000, /* Jupiter Ace */ XTAL_6_9MHz = 6900000, /* BBN BitGraph CPU */ XTAL_7MHz = 7000000, /* Jaleco Mega System PCBs */ @@ -124,6 +130,7 @@ enum XTAL_10_733MHz = 10733000, /* The Fairyland Story */ XTAL_10_738635MHz = 10738635, /* TMS9918 family (3x NTSC subcarrier) */ XTAL_10_816MHz = 10816000, /* Universal 1979-1980 (Cosmic Alien, etc) */ + XTAL_10_920MHz = 10920000, /* ADDS Viewpoint 60, Viewpoint A2 */ XTAL_11MHz = 11000000, /* Mario I8039 sound */ XTAL_11_0592MHz = 11059200, /* Used with MCS-51 to generate common baud rates */ XTAL_11_2MHz = 11200000, /* New York, New York */ @@ -151,12 +158,16 @@ enum XTAL_13_5168MHz = 13516800, /* Kontron KDT6 */ XTAL_14MHz = 14000000, XTAL_14_112MHz = 14112000, /* Timex/Sinclair TS2068 */ + XTAL_14_192640MHz = 14192640, /* Reported by Central Data 2650 document, true xtal unchecked on PCB */ + XTAL_14_218MHz = 14218000, /* Dragon */ XTAL_14_3MHz = 14300000, /* Agat-7 */ XTAL_14_314MHz = 14314000, /* Taito TTL Board */ XTAL_14_31818MHz = 14318181, /* Extremely common, used on 100's of PCBs (4x NTSC subcarrier) */ XTAL_14_705882MHz = 14705882, /* Aleck64 */ XTAL_14_7456MHz = 14745600, /* Namco System 12 & System Super 22/23 for JVS */ + XTAL_14_916MHz = 14916000, /* ADDS Viewpoint 122 */ XTAL_15MHz = 15000000, /* Sinclair QL, Amusco Poker */ + XTAL_15_30072MHz = 15300720, /* Microterm 420 */ XTAL_15_36MHz = 15360000, /* Visual 1050 */ XTAL_15_4MHz = 15400000, /* DVK KSM */ XTAL_15_468MHz = 15468480, /* Bank Panic h/w, Sega G80 */ @@ -167,6 +178,7 @@ enum XTAL_16_384MHz = 16384000, XTAL_16_4MHz = 16400000, /* MS 6102 */ XTAL_16_5888MHz = 16588800, /* SM 7238 */ + XTAL_16_6698MHz = 16669800, /* Qume QVT-102 */ XTAL_16_67MHz = 16670000, XTAL_16_777216MHz = 16777216, /* Nintendo Game Boy Advance */ XTAL_16_9344MHz = 16934400, /* Usually used to drive 90's Yamaha OPL/FM chips (44100 * 384) */ @@ -177,8 +189,10 @@ enum XTAL_17_9712MHz = 17971200, XTAL_18MHz = 18000000, /* S.A.R, Ikari Warriors 3 */ XTAL_18_432MHz = 18432000, /* Extremely common, used on 100's of PCBs (48000 * 384) */ + XTAL_18_575MHz = 18575000, /* Visual 102 */ XTAL_18_720MHz = 18720000, /* Nokia MikroMikko 1 */ XTAL_18_8696MHz = 18869600, /* Memorex 2178 */ + XTAL_19_3396MHz = 19339600, /* TeleVideo TVI-955 80-column display clock */ XTAL_19_6MHz = 19600000, /* Universal Mr. Do - Model 8021 PCB */ XTAL_19_6608MHz = 19660800, /* Euro League (bootleg), labeled as "UKI 19.6608 20PF" */ XTAL_19_923MHz = 19923000, /* Cinematronics vectors */ @@ -191,9 +205,11 @@ enum XTAL_21_3MHz = 21300000, XTAL_21_4772MHz = 21477272, /* BMC bowling, some Data East 90's games, Vtech Socrates; (6x NTSC subcarrier) */ XTAL_22MHz = 22000000, + XTAL_22_096MHz = 22096000, /* ADDS Viewpoint 122 */ XTAL_22_1184MHz = 22118400, /* Amusco Poker */ XTAL_22_3210MHz = 22321000, /* Apple LaserWriter II NT */ XTAL_22_656MHz = 22656000, /* Super Pinball Action (~1440x NTSC line rate) */ + XTAL_23_814MHz = 23814000, /* TeleVideo TVI-912C & 950 */ XTAL_23_9616MHz = 23961600, /* Osborne 4 (Vixen) */ XTAL_24MHz = 24000000, /* Mario, 80's Data East games, 80's Konami games */ XTAL_24_0734MHz = 24073400, /* DEC Rainbow 100 */ @@ -205,10 +221,14 @@ enum XTAL_25_447MHz = 25447000, /* Namco EVA3A (Funcube2) */ XTAL_25_590906MHz = 25590906, /* Atari Jaguar NTSC */ XTAL_25_593900MHz = 25593900, /* Atari Jaguar PAL */ + XTAL_25_7715MHz = 25771500, /* HP-2622A */ + XTAL_25_92MHz = 25920000, /* ADDS Viewpoint 60 */ XTAL_26MHz = 26000000, /* Gaelco PCBs */ XTAL_26_601712MHz = 26601712, /* Astro Corp.'s Show Hand, PAL Vtech/Yeno Socrates (6x PAL subcarrier) */ + XTAL_26_666MHz = 26666000, /* Imagetek I4100/I4220/I4300 */ XTAL_26_66666MHz = 26666666, /* Irem M92 but most use 27MHz */ XTAL_26_686MHz = 26686000, /* Typically used on 90's Taito PCBs to drive the custom chips */ + XTAL_26_9892MHz = 26989200, /* TeleVideo 965 */ XTAL_27MHz = 27000000, /* Some Banpresto games macrossp, Irem M92 and 90's Toaplan games */ XTAL_27_164MHz = 27164000, /* Typically used on 90's Taito PCBs to drive the custom chips */ XTAL_27_2109MHz = 27210900, /* LA Girl */ @@ -220,9 +240,11 @@ enum XTAL_28_64MHz = 28640000, /* Fukki FG-1c AI AM-2 PCB */ XTAL_28_7MHz = 28700000, XTAL_29_4912MHz = 29491200, /* Xerox Alto-II system clock (tagged 29.4MHz in the schematics) */ + XTAL_29_876MHz = 29876000, /* Qume QVT-103 */ XTAL_30MHz = 30000000, /* Impera Magic Card */ XTAL_30_4761MHz = 30476100, /* Taito JC */ XTAL_30_8MHz = 30800000, /* 15IE-00-013 */ + XTAL_31_684MHz = 31684000, /* TeleVideo TVI-955 132-column display clock */ XTAL_32MHz = 32000000, XTAL_32_22MHz = 32220000, /* Typically used on 90's Data East PCBs (close to 9x NTSC subcarrier which is 32.215905Mhz*/ XTAL_32_5304MHz = 32530400, /* Seta 2 */ @@ -238,12 +260,18 @@ enum XTAL_40MHz = 40000000, XTAL_42MHz = 42000000, /* BMC A-00211 - Popo Bear */ XTAL_42_9545MHz = 42954545, /* CPS3 (12x NTSC subcarrier)*/ + XTAL_43_320MHz = 43320000, /* DEC VT420 */ XTAL_44_1MHz = 44100000, /* Subsino's Bishou Jan */ + XTAL_44_4528MHz = 44452800, /* TeleVideo 965 */ XTAL_45MHz = 45000000, /* Eolith with Hyperstone CPUs */ XTAL_45_158MHz = 45158000, /* Sega Model 2A video board, Model 3 CPU board */ - XTAL_45_6192Mhz = 45619200, /* DEC VK100 */ + XTAL_45_582MHz = 45582000, /* Zentec Zephyr */ + XTAL_45_6192MHz = 45619200, /* DEC VK100 */ + XTAL_45_8304MHz = 45830400, /* Microterm 5510 */ + XTAL_47_736MHz = 47736000, /* Visual 100 */ XTAL_48MHz = 48000000, /* Williams/Midway Y/Z-unit system / SSV board */ XTAL_48_384MHz = 48384000, /* Namco NB-1 */ + XTAL_48_654MHz = 48654000, /* Qume QVT-201 */ XTAL_48_66MHz = 48660000, /* Zaxxon */ XTAL_49_152MHz = 49152000, /* Used on some Namco PCBs, Baraduke h/w, System 21, Super System 22 */ XTAL_50MHz = 50000000, /* Williams/Midway T/W/V-unit system */ @@ -257,6 +285,7 @@ enum XTAL_55MHz = 55000000, /* Eolith Vega */ XTAL_57_2727MHz = 57272727, /* Psikyo SH2 with /2 divider (16x NTSC subcarrier)*/ XTAL_58MHz = 58000000, /* Magic Reel (Play System) */ + XTAL_59_2920MHz = 59292000, /* Data General D461 */ XTAL_60MHz = 60000000, XTAL_61_44MHz = 61440000, /* dkong */ XTAL_64MHz = 64000000, /* BattleToads */ @@ -265,6 +294,7 @@ enum XTAL_72MHz = 72000000, /* Aristocrat MKV */ XTAL_72_576MHz = 72576000, /* Centipede, Millipede, Missile Command, Let's Go Bowling "Multipede" */ XTAL_73_728MHz = 73728000, /* Ms. Pac-Man/Galaga 20th Anniversary */ + XTAL_87_18336MHz = 87183360, /* AT&T 630 MTG */ XTAL_100MHz = 100000000, /* PSX-based Namco System 12, Vegas, Sony ZN1-2-based */ XTAL_101_4912MHz = 101491200, /* PSX-based Namco System 10 */ XTAL_200MHz = 200000000, /* Base SH4 CPU (Naomi, Hikaru etc.) */ diff --git a/src/emu/emucore.h b/src/emu/emucore.h index 1461dcbb272..1782ac8726d 100644 --- a/src/emu/emucore.h +++ b/src/emu/emucore.h @@ -431,4 +431,12 @@ inline u64 d2u(double d) return u.vv; } + +// constexpr absolute value of an integer +template <typename T> +constexpr std::enable_if_t<std::is_signed<T>::value, T> iabs(T v) +{ + return (v < T(0)) ? -v : v; +} + #endif /* MAME_EMU_EMUCORE_H */ diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h index cd7de9fecb9..0ab280adbf4 100644 --- a/src/emu/emufwd.h +++ b/src/emu/emufwd.h @@ -130,7 +130,7 @@ class driver_device; // declared in emumem.h class address_space; -class direct_read_data; +template<int addr_shift> class direct_read_data; class memory_bank; class memory_block; class memory_manager; diff --git a/src/emu/emumem.cpp b/src/emu/emumem.cpp index c6ad1349d23..2b63aa4952b 100644 --- a/src/emu/emumem.cpp +++ b/src/emu/emumem.cpp @@ -269,8 +269,9 @@ protected: public: // getters bool populated() const { return m_populated; } - offs_t bytestart() const { return m_bytestart; } - offs_t byteend() const { return m_byteend; } + offs_t addrstart() const { return m_addrstart; } + offs_t addrend() const { return m_addrend; } + offs_t addrmask() const { return m_addrmask; } offs_t bytemask() const { return m_bytemask; } virtual const char *name() const = 0; virtual const char *subunit_name(int entry) const = 0; @@ -279,44 +280,45 @@ public: virtual void copy(handler_entry *entry); // return offset within the range referenced by this handler - offs_t byteoffset(offs_t byteaddress) const { return (byteaddress - m_bytestart) & m_bytemask; } + offs_t offset(offs_t address) const { return (address - m_addrstart) & m_addrmask; } // return a pointer to the backing RAM at the given offset u8 *ramptr(offs_t offset = 0) const { return *m_rambaseptr + offset; } // see if we are an exact match to the given parameters - bool matches_exactly(offs_t bytestart, offs_t byteend, offs_t bytemask) const + bool matches_exactly(offs_t addrstart, offs_t addrend, offs_t addrmask) const { - return (m_populated && m_bytestart == bytestart && m_byteend == byteend && m_bytemask == bytemask); + return (m_populated && m_addrstart == addrstart && m_addrend == addrend && m_addrmask == addrmask); } // get the start/end address with the given mirror - void mirrored_start_end(offs_t byteaddress, offs_t &start, offs_t &end) const + void mirrored_start_end(offs_t address, offs_t &start, offs_t &end) const { - offs_t mirrorbits = (byteaddress - m_bytestart) & ~m_bytemask; - start = m_bytestart | mirrorbits; - end = m_byteend | mirrorbits; + offs_t mirrorbits = (address - m_addrstart) & ~m_addrmask; + start = m_addrstart | mirrorbits; + end = m_addrend | mirrorbits; } // configure the handler addresses, and mark as populated - void configure(offs_t bytestart, offs_t byteend, offs_t bytemask) + void configure(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t bytemask) { if (m_populated && m_subunits) - reconfigure_subunits(bytestart); + reconfigure_subunits(addrstart); m_populated = true; - m_bytestart = bytestart; - m_byteend = byteend; + m_addrstart = addrstart; + m_addrend = addrend; + m_addrmask = addrmask; m_bytemask = bytemask; } - // Re-expand the bytemask after subunit fun + // Re-expand the addrmask after subunit fun void expand_bytemask(offs_t previous_mask) { m_bytemask |= previous_mask; } // reconfigure the subunits on a base address change - void reconfigure_subunits(offs_t bytestart); + void reconfigure_subunits(offs_t addrstart); // depopulate an handler void deconfigure() @@ -326,7 +328,7 @@ public: } // apply a global mask - void apply_mask(offs_t bytemask) { m_bytemask &= bytemask; } + void apply_mask(offs_t addrmask) { m_addrmask &= addrmask; } void clear_conflicting_subunits(u64 handlermask); bool overriden_by_mask(u64 handlermask); @@ -335,7 +337,7 @@ protected: // Subunit description information struct subunit_info { - offs_t m_bytemask; // bytemask for this subunit + offs_t m_addrmask; // addrmask for this subunit u32 m_mask; // mask (ff, ffff or ffffffff) s32 m_offset; // offset to add to the address u32 m_multiplier; // multiplier to the pre-split address @@ -351,9 +353,10 @@ protected: bool m_populated; // populated? u8 m_datawidth; endianness_t m_endianness; - offs_t m_bytestart; // byte-adjusted start address for handler - offs_t m_byteend; // byte-adjusted end address for handler - offs_t m_bytemask; // byte-adjusted mask against the final address + offs_t m_addrstart; // start address for handler + offs_t m_addrend; // end address for handler + offs_t m_addrmask; // mask against the final address + offs_t m_bytemask; // mask against the final address, byte resolution u8 ** m_rambaseptr; // pointer to the bank base u8 m_subunits; // for width stubs, the number of subunits subunit_info m_subunit_infos[8]; // for width stubs, the associated subunit info @@ -411,8 +414,8 @@ private: u64 read_stub_64(address_space &space, offs_t offset, u64 mask); // stubs for reading I/O ports - template<typename _UintType> - _UintType read_stub_ioport(address_space &space, offs_t offset, _UintType mask) { return m_ioport->read(); } + template<typename UintType> + UintType read_stub_ioport(address_space &space, offs_t offset, UintType mask) { return m_ioport->read(); } // internal helper virtual void remove_subunit(int entry) override; @@ -474,8 +477,8 @@ private: void write_stub_64(address_space &space, offs_t offset, u64 data, u64 mask); // stubs for writing I/O ports - template<typename _UintType> - void write_stub_ioport(address_space &space, offs_t offset, _UintType data, _UintType mask) { m_ioport->write(data, mask); } + template<typename UintType> + void write_stub_ioport(address_space &space, offs_t offset, UintType data, UintType mask) { m_ioport->write(data, mask); } // internal helper virtual void remove_subunit(int entry) override; @@ -518,15 +521,15 @@ private: // A proxy class that contains an handler_entry_read or _write and forwards the setter calls -template<typename _HandlerEntry> +template<typename HandlerEntry> class handler_entry_proxy { public: - handler_entry_proxy(std::list<_HandlerEntry *> _handlers, u64 _mask) : handlers(std::move(_handlers)), mask(_mask) {} - handler_entry_proxy(const handler_entry_proxy<_HandlerEntry> &hep) : handlers(hep.handlers), mask(hep.mask) {} + handler_entry_proxy(std::list<HandlerEntry *> _handlers, u64 _mask) : handlers(std::move(_handlers)), mask(_mask) {} + handler_entry_proxy(const handler_entry_proxy<HandlerEntry> &hep) : handlers(hep.handlers), mask(hep.mask) {} // forward delegate callbacks configuration - template<typename _delegate> void set_delegate(_delegate delegate) const { + template<typename Delegate> void set_delegate(Delegate delegate) const { for (const auto & elem : handlers) (elem)->set_delegate(delegate, mask); } @@ -538,7 +541,7 @@ public: } private: - std::list<_HandlerEntry *> handlers; + std::list<HandlerEntry *> handlers; u64 mask; }; @@ -568,33 +571,33 @@ public: bool watchpoints_enabled() const { return (m_live_lookup == s_watchpoint_table); } // address lookups - u32 lookup_live(offs_t byteaddress) const { return m_large ? lookup_live_large(byteaddress) : lookup_live_small(byteaddress); } - u32 lookup_live_small(offs_t byteaddress) const { return m_live_lookup[byteaddress]; } + u32 lookup_live(offs_t address) const { return m_large ? lookup_live_large(address) : lookup_live_small(address); } + u32 lookup_live_small(offs_t address) const { return m_live_lookup[address]; } - u32 lookup_live_large(offs_t byteaddress) const + u32 lookup_live_large(offs_t address) const { - u32 entry = m_live_lookup[level1_index_large(byteaddress)]; + u32 entry = m_live_lookup[level1_index_large(address)]; if (entry >= SUBTABLE_BASE) - entry = m_live_lookup[level2_index_large(entry, byteaddress)]; + entry = m_live_lookup[level2_index_large(entry, address)]; return entry; } - u32 lookup_live_nowp(offs_t byteaddress) const { return m_large ? lookup_live_large_nowp(byteaddress) : lookup_live_small_nowp(byteaddress); } - u32 lookup_live_small_nowp(offs_t byteaddress) const { return m_table[byteaddress]; } + u32 lookup_live_nowp(offs_t address) const { return m_large ? lookup_live_large_nowp(address) : lookup_live_small_nowp(address); } + u32 lookup_live_small_nowp(offs_t address) const { return m_table[address]; } - u32 lookup_live_large_nowp(offs_t byteaddress) const + u32 lookup_live_large_nowp(offs_t address) const { - u32 entry = m_table[level1_index_large(byteaddress)]; + u32 entry = m_table[level1_index_large(address)]; if (entry >= SUBTABLE_BASE) - entry = m_table[level2_index_large(entry, byteaddress)]; + entry = m_table[level2_index_large(entry, address)]; return entry; } - u32 lookup(offs_t byteaddress) const + u32 lookup(offs_t address) const { - u32 entry = m_live_lookup[level1_index(byteaddress)]; + u32 entry = m_live_lookup[level1_index(address)]; if (entry >= SUBTABLE_BASE) - entry = m_live_lookup[level2_index(entry, byteaddress)]; + entry = m_live_lookup[level2_index(entry, address)]; return entry; } @@ -602,9 +605,9 @@ public: void enable_watchpoints(bool enable = true) { m_live_lookup = enable ? s_watchpoint_table : &m_table[0]; } // table mapping helpers - void map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, u16 staticentry); - void setup_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, u64 mask, std::list<u32> &entries); - u16 derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const; + void map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, u16 staticentry); + void setup_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, u64 mask, std::list<u32> &entries); + u16 derive_range(offs_t address, offs_t &addrstart, offs_t &addrend) const; // misc helpers void mask_all_handlers(offs_t mask); @@ -618,8 +621,8 @@ protected: u32 level2_index(u16 l1entry, offs_t address) const { return m_large ? level2_index_large(l1entry, address) : 0; } // table population/depopulation - void populate_range_mirrored(offs_t bytestart, offs_t byteend, offs_t bytemirror, u16 handler); - void populate_range(offs_t bytestart, offs_t byteend, u16 handler); + void populate_range_mirrored(offs_t addrstart, offs_t addrend, offs_t addrmirror, u16 handler); + void populate_range(offs_t addrstart, offs_t addrend, u16 handler); // subtable management u16 subtable_alloc(); @@ -700,9 +703,9 @@ public: handler_entry_read &handler_read(u32 index) const { assert(index < ARRAY_LENGTH(m_handlers)); return *m_handlers[index]; } // range getter - handler_entry_proxy<handler_entry_read> handler_map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, u64 mask = 0) { + handler_entry_proxy<handler_entry_read> handler_map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, u64 mask = 0) { std::list<u32> entries; - setup_range(bytestart, byteend, bytemask, bytemirror, mask, entries); + setup_range(addrstart, addrend, addrmask, addrmirror, mask, entries); std::list<handler_entry_read *> handlers; for (std::list<u32>::const_iterator i = entries.begin(); i != entries.end(); ++i) handlers.push_back(&handler_read(*i)); @@ -711,8 +714,8 @@ public: private: // internal unmapped handler - template<typename _UintType> - _UintType unmap_r(address_space &space, offs_t offset, _UintType mask) + template<typename UintType> + UintType unmap_r(address_space &space, offs_t offset, UintType mask) { if (m_space.log_unmap() && !m_space.machine().side_effect_disabled()) { @@ -721,32 +724,32 @@ private: ? "%s: unmapped %s memory read from %0*o & %0*o\n" : "%s: unmapped %s memory read from %0*X & %0*X\n", m_space.machine().describe_context(), m_space.name(), - m_space.addrchars(), m_space.byte_to_address(offset * sizeof(_UintType)), - 2 * sizeof(_UintType), mask); + m_space.addrchars(), m_space.byte_to_address(offset * sizeof(UintType)), + 2 * sizeof(UintType), mask); } return m_space.unmap(); } // internal no-op handler - template<typename _UintType> - _UintType nop_r(address_space &space, offs_t offset, _UintType mask) + template<typename UintType> + UintType nop_r(address_space &space, offs_t offset, UintType mask) { return m_space.unmap(); } // internal watchpoint handler - template<typename _UintType> - _UintType watchpoint_r(address_space &space, offs_t offset, _UintType mask) + template<typename UintType> + UintType watchpoint_r(address_space &space, offs_t offset, UintType mask) { - m_space.device().debug()->memory_read_hook(m_space, offset * sizeof(_UintType), mask); + m_space.device().debug()->memory_read_hook(m_space, offset * sizeof(UintType), mask); u16 *oldtable = m_live_lookup; m_live_lookup = &m_table[0]; - _UintType result; - if (sizeof(_UintType) == 1) result = m_space.read_byte(offset); - if (sizeof(_UintType) == 2) result = m_space.read_word(offset << 1, mask); - if (sizeof(_UintType) == 4) result = m_space.read_dword(offset << 2, mask); - if (sizeof(_UintType) == 8) result = m_space.read_qword(offset << 3, mask); + UintType result; + if (sizeof(UintType) == 1) result = m_space.read_byte(offset); + if (sizeof(UintType) == 2) result = m_space.read_word(offset << 1, mask); + if (sizeof(UintType) == 4) result = m_space.read_dword(offset << 2, mask); + if (sizeof(UintType) == 8) result = m_space.read_qword(offset << 3, mask); m_live_lookup = oldtable; return result; } @@ -771,9 +774,9 @@ public: handler_entry_write &handler_write(u32 index) const { assert(index < ARRAY_LENGTH(m_handlers)); return *m_handlers[index]; } // range getter - handler_entry_proxy<handler_entry_write> handler_map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, u64 mask = 0) { + handler_entry_proxy<handler_entry_write> handler_map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, u64 mask = 0) { std::list<u32> entries; - setup_range(bytestart, byteend, bytemask, bytemirror, mask, entries); + setup_range(addrstart, addrend, addrmask, addrmirror, mask, entries); std::list<handler_entry_write *> handlers; for (std::list<u32>::const_iterator i = entries.begin(); i != entries.end(); ++i) handlers.push_back(&handler_write(*i)); @@ -782,8 +785,8 @@ public: private: // internal handlers - template<typename _UintType> - void unmap_w(address_space &space, offs_t offset, _UintType data, _UintType mask) + template<typename UintType> + void unmap_w(address_space &space, offs_t offset, UintType data, UintType mask) { if (m_space.log_unmap() && !m_space.machine().side_effect_disabled()) { @@ -792,28 +795,28 @@ private: ? "%s: unmapped %s memory write to %0*o = %0*o & %0*o\n" : "%s: unmapped %s memory write to %0*X = %0*X & %0*X\n", m_space.machine().describe_context(), m_space.name(), - m_space.addrchars(), m_space.byte_to_address(offset * sizeof(_UintType)), - 2 * sizeof(_UintType), data, - 2 * sizeof(_UintType), mask); + m_space.addrchars(), m_space.byte_to_address(offset * sizeof(UintType)), + 2 * sizeof(UintType), data, + 2 * sizeof(UintType), mask); } } - template<typename _UintType> - void nop_w(address_space &space, offs_t offset, _UintType data, _UintType mask) + template<typename UintType> + void nop_w(address_space &space, offs_t offset, UintType data, UintType mask) { } - template<typename _UintType> - void watchpoint_w(address_space &space, offs_t offset, _UintType data, _UintType mask) + template<typename UintType> + void watchpoint_w(address_space &space, offs_t offset, UintType data, UintType mask) { - m_space.device().debug()->memory_write_hook(m_space, offset * sizeof(_UintType), data, mask); + m_space.device().debug()->memory_write_hook(m_space, offset * sizeof(UintType), data, mask); u16 *oldtable = m_live_lookup; m_live_lookup = &m_table[0]; - if (sizeof(_UintType) == 1) m_space.write_byte(offset, data); - if (sizeof(_UintType) == 2) m_space.write_word(offset << 1, data, mask); - if (sizeof(_UintType) == 4) m_space.write_dword(offset << 2, data, mask); - if (sizeof(_UintType) == 8) m_space.write_qword(offset << 3, data, mask); + if (sizeof(UintType) == 1) m_space.write_byte(offset, data); + if (sizeof(UintType) == 2) m_space.write_word(offset << 1, data, mask); + if (sizeof(UintType) == 4) m_space.write_dword(offset << 2, data, mask); + if (sizeof(UintType) == 8) m_space.write_qword(offset << 3, data, mask); m_live_lookup = oldtable; } @@ -836,7 +839,7 @@ public: // Watchpoints and unmap states do not make sense for setoffset m_handlers[STATIC_NOP]->set_delegate(setoffset_delegate(FUNC(address_table_setoffset::nop_so), this)); - m_handlers[STATIC_NOP]->configure(0, space.bytemask(), ~0); + m_handlers[STATIC_NOP]->configure(0, space.addrmask(), ~0, ~0); } ~address_table_setoffset() @@ -847,9 +850,9 @@ public: handler_entry_setoffset &handler_setoffset(u32 index) const { assert(index < ARRAY_LENGTH(m_handlers)); return *m_handlers[index]; } // range getter - handler_entry_proxy<handler_entry_setoffset> handler_map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, u64 mask = 0) { + handler_entry_proxy<handler_entry_setoffset> handler_map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, u64 mask = 0) { std::list<u32> entries; - setup_range(bytestart, byteend, bytemask, bytemirror, mask, entries); + setup_range(addrstart, addrend, addrmask, addrmirror, mask, entries); std::list<handler_entry_setoffset *> handlers; for (std::list<u32>::const_iterator i = entries.begin(); i != entries.end(); ++i) handlers.push_back(&handler_setoffset(*i)); @@ -875,28 +878,31 @@ private: // ======================> address_space_specific // this is a derived class of address_space with specific width, endianness, and table size -template<typename _NativeType, endianness_t _Endian, bool _Large> +template<typename NativeType, endianness_t Endian, int AddrShift, bool Large> class address_space_specific : public address_space { - typedef address_space_specific<_NativeType, _Endian, _Large> this_type; + typedef address_space_specific<NativeType, Endian, AddrShift, Large> this_type; // constants describing the native size - static const u32 NATIVE_BYTES = sizeof(_NativeType); - static const u32 NATIVE_MASK = NATIVE_BYTES - 1; - static const u32 NATIVE_BITS = 8 * NATIVE_BYTES; + static constexpr u32 NATIVE_BYTES = sizeof(NativeType); + static constexpr u32 NATIVE_STEP = AddrShift >= 0 ? NATIVE_BYTES << iabs(AddrShift) : NATIVE_BYTES >> iabs(AddrShift); + static constexpr u32 NATIVE_MASK = NATIVE_STEP - 1; + static constexpr u32 NATIVE_BITS = 8 * NATIVE_BYTES; // helpers to simplify core code - u32 read_lookup(offs_t byteaddress) const { return _Large ? m_read.lookup_live_large(byteaddress) : m_read.lookup_live_small(byteaddress); } - u32 write_lookup(offs_t byteaddress) const { return _Large ? m_write.lookup_live_large(byteaddress) : m_write.lookup_live_small(byteaddress); } - u32 setoffset_lookup(offs_t byteaddress) const { return _Large ? m_setoffset.lookup_live_large(byteaddress) : m_setoffset.lookup_live_small(byteaddress); } + u32 read_lookup(offs_t address) const { return Large ? m_read.lookup_live_large(address) : m_read.lookup_live_small(address); } + u32 write_lookup(offs_t address) const { return Large ? m_write.lookup_live_large(address) : m_write.lookup_live_small(address); } + u32 setoffset_lookup(offs_t address) const { return Large ? m_setoffset.lookup_live_large(address) : m_setoffset.lookup_live_small(address); } + + static constexpr offs_t offset_to_byte(offs_t offset) { return AddrShift < 0 ? offset << iabs(AddrShift) : offset >> iabs(AddrShift); } public: // construction/destruction address_space_specific(memory_manager &manager, device_memory_interface &memory, int spacenum) - : address_space(manager, memory, spacenum, _Large), - m_read(*this, _Large), - m_write(*this, _Large), - m_setoffset(*this, _Large) + : address_space(manager, memory, spacenum, Large), + m_read(*this, Large), + m_write(*this, Large), + m_setoffset(*this, Large) { #if (TEST_HANDLER) // test code to verify the read/write handlers are touching the correct bits @@ -905,25 +911,25 @@ public: // install some dummy RAM for the first 16 bytes with well-known values u8 buffer[16]; for (int index = 0; index < 16; index++) - buffer[index ^ ((_Endian == ENDIANNESS_NATIVE) ? 0 : (data_width()/8 - 1))] = index * 0x11; + buffer[index ^ ((Endian == ENDIANNESS_NATIVE) ? 0 : (data_width()/8 - 1))] = index * 0x11; install_ram_generic(0x00, 0x0f, 0x0f, 0, read_or_write::READWRITE, buffer); - printf("\n\naddress_space(%d, %s, %s)\n", NATIVE_BITS, (_Endian == ENDIANNESS_LITTLE) ? "little" : "big", _Large ? "large" : "small"); + printf("\n\naddress_space(%d, %s, %s)\n", NATIVE_BITS, (Endian == ENDIANNESS_LITTLE) ? "little" : "big", Large ? "large" : "small"); // walk through the first 8 addresses for (int address = 0; address < 8; address++) { // determine expected values - u64 expected64 = (u64((address + ((_Endian == ENDIANNESS_LITTLE) ? 7 : 0)) * 0x11) << 56) | - (u64((address + ((_Endian == ENDIANNESS_LITTLE) ? 6 : 1)) * 0x11) << 48) | - (u64((address + ((_Endian == ENDIANNESS_LITTLE) ? 5 : 2)) * 0x11) << 40) | - (u64((address + ((_Endian == ENDIANNESS_LITTLE) ? 4 : 3)) * 0x11) << 32) | - (u64((address + ((_Endian == ENDIANNESS_LITTLE) ? 3 : 4)) * 0x11) << 24) | - (u64((address + ((_Endian == ENDIANNESS_LITTLE) ? 2 : 5)) * 0x11) << 16) | - (u64((address + ((_Endian == ENDIANNESS_LITTLE) ? 1 : 6)) * 0x11) << 8) | - (u64((address + ((_Endian == ENDIANNESS_LITTLE) ? 0 : 7)) * 0x11) << 0); - u32 expected32 = (_Endian == ENDIANNESS_LITTLE) ? expected64 : (expected64 >> 32); - u16 expected16 = (_Endian == ENDIANNESS_LITTLE) ? expected32 : (expected32 >> 16); - u8 expected8 = (_Endian == ENDIANNESS_LITTLE) ? expected16 : (expected16 >> 8); + u64 expected64 = (u64((address + ((Endian == ENDIANNESS_LITTLE) ? 7 : 0)) * 0x11) << 56) | + (u64((address + ((Endian == ENDIANNESS_LITTLE) ? 6 : 1)) * 0x11) << 48) | + (u64((address + ((Endian == ENDIANNESS_LITTLE) ? 5 : 2)) * 0x11) << 40) | + (u64((address + ((Endian == ENDIANNESS_LITTLE) ? 4 : 3)) * 0x11) << 32) | + (u64((address + ((Endian == ENDIANNESS_LITTLE) ? 3 : 4)) * 0x11) << 24) | + (u64((address + ((Endian == ENDIANNESS_LITTLE) ? 2 : 5)) * 0x11) << 16) | + (u64((address + ((Endian == ENDIANNESS_LITTLE) ? 1 : 6)) * 0x11) << 8) | + (u64((address + ((Endian == ENDIANNESS_LITTLE) ? 0 : 7)) * 0x11) << 0); + u32 expected32 = (Endian == ENDIANNESS_LITTLE) ? expected64 : (expected64 >> 32); + u16 expected16 = (Endian == ENDIANNESS_LITTLE) ? expected32 : (expected32 >> 16); + u8 expected8 = (Endian == ENDIANNESS_LITTLE) ? expected16 : (expected16 >> 8); u64 result64; u32 result32; @@ -1064,170 +1070,170 @@ public: } // return a pointer to the read bank, or nullptr if none - virtual void *get_read_ptr(offs_t byteaddress) override + virtual void *get_read_ptr(offs_t address) override { // perform the lookup - byteaddress &= m_bytemask; - u32 entry = read_lookup(byteaddress); + address &= m_addrmask; + u32 entry = read_lookup(address); const handler_entry_read &handler = m_read.handler_read(entry); // 8-bit case: RAM/ROM if (entry > STATIC_BANKMAX) return nullptr; - return handler.ramptr(handler.byteoffset(byteaddress)); + return handler.ramptr(handler.offset(address)); } // return a pointer to the write bank, or nullptr if none - virtual void *get_write_ptr(offs_t byteaddress) override + virtual void *get_write_ptr(offs_t address) override { // perform the lookup - byteaddress &= m_bytemask; - u32 entry = write_lookup(byteaddress); + address &= m_addrmask; + u32 entry = write_lookup(address); const handler_entry_write &handler = m_write.handler_write(entry); // 8-bit case: RAM/ROM if (entry > STATIC_BANKMAX) return nullptr; - return handler.ramptr(handler.byteoffset(byteaddress)); + return handler.ramptr(handler.offset(address)); } // native read - _NativeType read_native(offs_t offset, _NativeType mask) + NativeType read_native(offs_t offset, NativeType mask) { g_profiler.start(PROFILER_MEMREAD); - if (TEST_HANDLER) printf("[r%X,%s]", offset, core_i64_hex_format(mask, sizeof(_NativeType) * 2)); + if (TEST_HANDLER) printf("[r%X,%s]", offset, core_i64_hex_format(mask, sizeof(NativeType) * 2)); // look up the handler - offs_t byteaddress = offset & m_bytemask; - u32 entry = read_lookup(byteaddress); + offs_t address = offset & m_addrmask; + u32 entry = read_lookup(address); const handler_entry_read &handler = m_read.handler_read(entry); // either read directly from RAM, or call the delegate - offset = handler.byteoffset(byteaddress); - _NativeType result; - if (entry <= STATIC_BANKMAX) result = *reinterpret_cast<_NativeType *>(handler.ramptr(offset)); - else if (sizeof(_NativeType) == 1) result = handler.read8(*this, offset, mask); - else if (sizeof(_NativeType) == 2) result = handler.read16(*this, offset >> 1, mask); - else if (sizeof(_NativeType) == 4) result = handler.read32(*this, offset >> 2, mask); - else if (sizeof(_NativeType) == 8) result = handler.read64(*this, offset >> 3, mask); + offset = offset_to_byte(handler.offset(address)); + NativeType result; + if (entry <= STATIC_BANKMAX) result = *reinterpret_cast<NativeType *>(handler.ramptr(offset)); + else if (sizeof(NativeType) == 1) result = handler.read8(*this, offset, mask); + else if (sizeof(NativeType) == 2) result = handler.read16(*this, offset >> 1, mask); + else if (sizeof(NativeType) == 4) result = handler.read32(*this, offset >> 2, mask); + else if (sizeof(NativeType) == 8) result = handler.read64(*this, offset >> 3, mask); g_profiler.stop(); return result; } // mask-less native read - _NativeType read_native(offs_t offset) + NativeType read_native(offs_t offset) { g_profiler.start(PROFILER_MEMREAD); if (TEST_HANDLER) printf("[r%X]", offset); // look up the handler - offs_t byteaddress = offset & m_bytemask; - u32 entry = read_lookup(byteaddress); + offs_t address = offset & m_addrmask; + u32 entry = read_lookup(address); const handler_entry_read &handler = m_read.handler_read(entry); // either read directly from RAM, or call the delegate - offset = handler.byteoffset(byteaddress); - _NativeType result; - if (entry <= STATIC_BANKMAX) result = *reinterpret_cast<_NativeType *>(handler.ramptr(offset)); - else if (sizeof(_NativeType) == 1) result = handler.read8(*this, offset, 0xff); - else if (sizeof(_NativeType) == 2) result = handler.read16(*this, offset >> 1, 0xffff); - else if (sizeof(_NativeType) == 4) result = handler.read32(*this, offset >> 2, 0xffffffff); - else if (sizeof(_NativeType) == 8) result = handler.read64(*this, offset >> 3, 0xffffffffffffffffU); + offset = offset_to_byte(handler.offset(address)); + NativeType result; + if (entry <= STATIC_BANKMAX) result = *reinterpret_cast<NativeType *>(handler.ramptr(offset)); + else if (sizeof(NativeType) == 1) result = handler.read8(*this, offset, 0xff); + else if (sizeof(NativeType) == 2) result = handler.read16(*this, offset >> 1, 0xffff); + else if (sizeof(NativeType) == 4) result = handler.read32(*this, offset >> 2, 0xffffffff); + else if (sizeof(NativeType) == 8) result = handler.read64(*this, offset >> 3, 0xffffffffffffffffU); g_profiler.stop(); return result; } // native write - void write_native(offs_t offset, _NativeType data, _NativeType mask) + void write_native(offs_t offset, NativeType data, NativeType mask) { g_profiler.start(PROFILER_MEMWRITE); // look up the handler - offs_t byteaddress = offset & m_bytemask; - u32 entry = write_lookup(byteaddress); + offs_t address = offset & m_addrmask; + u32 entry = write_lookup(address); const handler_entry_write &handler = m_write.handler_write(entry); // either write directly to RAM, or call the delegate - offset = handler.byteoffset(byteaddress); + offset = offset_to_byte(handler.offset(address)); if (entry <= STATIC_BANKMAX) { - _NativeType *dest = reinterpret_cast<_NativeType *>(handler.ramptr(offset)); + NativeType *dest = reinterpret_cast<NativeType *>(handler.ramptr(offset)); *dest = (*dest & ~mask) | (data & mask); } - else if (sizeof(_NativeType) == 1) handler.write8(*this, offset, data, mask); - else if (sizeof(_NativeType) == 2) handler.write16(*this, offset >> 1, data, mask); - else if (sizeof(_NativeType) == 4) handler.write32(*this, offset >> 2, data, mask); - else if (sizeof(_NativeType) == 8) handler.write64(*this, offset >> 3, data, mask); + else if (sizeof(NativeType) == 1) handler.write8(*this, offset, data, mask); + else if (sizeof(NativeType) == 2) handler.write16(*this, offset >> 1, data, mask); + else if (sizeof(NativeType) == 4) handler.write32(*this, offset >> 2, data, mask); + else if (sizeof(NativeType) == 8) handler.write64(*this, offset >> 3, data, mask); g_profiler.stop(); } // mask-less native write - void write_native(offs_t offset, _NativeType data) + void write_native(offs_t offset, NativeType data) { g_profiler.start(PROFILER_MEMWRITE); // look up the handler - offs_t byteaddress = offset & m_bytemask; - u32 entry = write_lookup(byteaddress); + offs_t address = offset & m_addrmask; + u32 entry = write_lookup(address); const handler_entry_write &handler = m_write.handler_write(entry); // either write directly to RAM, or call the delegate - offset = handler.byteoffset(byteaddress); - if (entry <= STATIC_BANKMAX) *reinterpret_cast<_NativeType *>(handler.ramptr(offset)) = data; - else if (sizeof(_NativeType) == 1) handler.write8(*this, offset, data, 0xff); - else if (sizeof(_NativeType) == 2) handler.write16(*this, offset >> 1, data, 0xffff); - else if (sizeof(_NativeType) == 4) handler.write32(*this, offset >> 2, data, 0xffffffff); - else if (sizeof(_NativeType) == 8) handler.write64(*this, offset >> 3, data, 0xffffffffffffffffU); + offset = offset_to_byte(handler.offset(address)); + if (entry <= STATIC_BANKMAX) *reinterpret_cast<NativeType *>(handler.ramptr(offset)) = data; + else if (sizeof(NativeType) == 1) handler.write8(*this, offset, data, 0xff); + else if (sizeof(NativeType) == 2) handler.write16(*this, offset >> 1, data, 0xffff); + else if (sizeof(NativeType) == 4) handler.write32(*this, offset >> 2, data, 0xffffffff); + else if (sizeof(NativeType) == 8) handler.write64(*this, offset >> 3, data, 0xffffffffffffffffU); g_profiler.stop(); } // generic direct read - template<typename _TargetType, bool _Aligned> - _TargetType read_direct(offs_t address, _TargetType mask) + template<typename TargetType, bool Aligned> + TargetType read_direct(offs_t address, TargetType mask) { - const u32 TARGET_BYTES = sizeof(_TargetType); + const u32 TARGET_BYTES = sizeof(TargetType); const u32 TARGET_BITS = 8 * TARGET_BYTES; // equal to native size and aligned; simple pass-through to the native reader - if (NATIVE_BYTES == TARGET_BYTES && (_Aligned || (address & NATIVE_MASK) == 0)) + if (NATIVE_BYTES == TARGET_BYTES && (Aligned || (address & NATIVE_MASK) == 0)) return read_native(address & ~NATIVE_MASK, mask); // if native size is larger, see if we can do a single masked read (guaranteed if we're aligned) if (NATIVE_BYTES > TARGET_BYTES) { - u32 offsbits = 8 * (address & (NATIVE_BYTES - (_Aligned ? TARGET_BYTES : 1))); - if (_Aligned || (offsbits + TARGET_BITS <= NATIVE_BITS)) + u32 offsbits = 8 * (offset_to_byte(address) & (NATIVE_BYTES - (Aligned ? TARGET_BYTES : 1))); + if (Aligned || (offsbits + TARGET_BITS <= NATIVE_BITS)) { - if (_Endian != ENDIANNESS_LITTLE) offsbits = NATIVE_BITS - TARGET_BITS - offsbits; - return read_native(address & ~NATIVE_MASK, (_NativeType)mask << offsbits) >> offsbits; + if (Endian != ENDIANNESS_LITTLE) offsbits = NATIVE_BITS - TARGET_BITS - offsbits; + return read_native(address & ~NATIVE_MASK, (NativeType)mask << offsbits) >> offsbits; } } // determine our alignment against the native boundaries, and mask the address - u32 offsbits = 8 * (address & (NATIVE_BYTES - 1)); + u32 offsbits = 8 * (offset_to_byte(address) & (NATIVE_BYTES - 1)); address &= ~NATIVE_MASK; // if we're here, and native size is larger or equal to the target, we need exactly 2 reads if (NATIVE_BYTES >= TARGET_BYTES) { // little-endian case - if (_Endian == ENDIANNESS_LITTLE) + if (Endian == ENDIANNESS_LITTLE) { // read lower bits from lower address - _TargetType result = 0; - _NativeType curmask = (_NativeType)mask << offsbits; + TargetType result = 0; + NativeType curmask = (NativeType)mask << offsbits; if (curmask != 0) result = read_native(address, curmask) >> offsbits; // read upper bits from upper address offsbits = NATIVE_BITS - offsbits; curmask = mask >> offsbits; - if (curmask != 0) result |= read_native(address + NATIVE_BYTES, curmask) << offsbits; + if (curmask != 0) result |= read_native(address + NATIVE_STEP, curmask) << offsbits; return result; } @@ -1236,9 +1242,9 @@ public: { // left-justify the mask to the target type const u32 LEFT_JUSTIFY_TARGET_TO_NATIVE_SHIFT = ((NATIVE_BITS >= TARGET_BITS) ? (NATIVE_BITS - TARGET_BITS) : 0); - _NativeType result = 0; - _NativeType ljmask = (_NativeType)mask << LEFT_JUSTIFY_TARGET_TO_NATIVE_SHIFT; - _NativeType curmask = ljmask >> offsbits; + NativeType result = 0; + NativeType ljmask = (NativeType)mask << LEFT_JUSTIFY_TARGET_TO_NATIVE_SHIFT; + NativeType curmask = ljmask >> offsbits; // read upper bits from lower address if (curmask != 0) result = read_native(address, curmask) << offsbits; @@ -1246,7 +1252,7 @@ public: // read lower bits from upper address curmask = ljmask << offsbits; - if (curmask != 0) result |= read_native(address + NATIVE_BYTES, curmask) >> offsbits; + if (curmask != 0) result |= read_native(address + NATIVE_STEP, curmask) >> offsbits; // return the un-justified result return result >> LEFT_JUSTIFY_TARGET_TO_NATIVE_SHIFT; @@ -1259,30 +1265,30 @@ public: // compute the maximum number of loops; we do it this way so that there are // a fixed number of loops for the compiler to unroll if it desires const u32 MAX_SPLITS_MINUS_ONE = TARGET_BYTES / NATIVE_BYTES - 1; - _TargetType result = 0; + TargetType result = 0; // little-endian case - if (_Endian == ENDIANNESS_LITTLE) + if (Endian == ENDIANNESS_LITTLE) { // read lowest bits from first address - _NativeType curmask = mask << offsbits; + NativeType curmask = mask << offsbits; if (curmask != 0) result = read_native(address, curmask) >> offsbits; // read middle bits from subsequent addresses offsbits = NATIVE_BITS - offsbits; for (u32 index = 0; index < MAX_SPLITS_MINUS_ONE; index++) { - address += NATIVE_BYTES; + address += NATIVE_STEP; curmask = mask >> offsbits; - if (curmask != 0) result |= (_TargetType)read_native(address, curmask) << offsbits; + if (curmask != 0) result |= (TargetType)read_native(address, curmask) << offsbits; offsbits += NATIVE_BITS; } // if we're not aligned and we still have bits left, read uppermost bits from last address - if (!_Aligned && offsbits < TARGET_BITS) + if (!Aligned && offsbits < TARGET_BITS) { curmask = mask >> offsbits; - if (curmask != 0) result |= (_TargetType)read_native(address + NATIVE_BYTES, curmask) << offsbits; + if (curmask != 0) result |= (TargetType)read_native(address + NATIVE_STEP, curmask) << offsbits; } } @@ -1291,24 +1297,24 @@ public: { // read highest bits from first address offsbits = TARGET_BITS - (NATIVE_BITS - offsbits); - _NativeType curmask = mask >> offsbits; - if (curmask != 0) result = (_TargetType)read_native(address, curmask) << offsbits; + NativeType curmask = mask >> offsbits; + if (curmask != 0) result = (TargetType)read_native(address, curmask) << offsbits; // read middle bits from subsequent addresses for (u32 index = 0; index < MAX_SPLITS_MINUS_ONE; index++) { offsbits -= NATIVE_BITS; - address += NATIVE_BYTES; + address += NATIVE_STEP; curmask = mask >> offsbits; - if (curmask != 0) result |= (_TargetType)read_native(address, curmask) << offsbits; + if (curmask != 0) result |= (TargetType)read_native(address, curmask) << offsbits; } // if we're not aligned and we still have bits left, read lowermost bits from the last address - if (!_Aligned && offsbits != 0) + if (!Aligned && offsbits != 0) { offsbits = NATIVE_BITS - offsbits; curmask = mask << offsbits; - if (curmask != 0) result |= read_native(address + NATIVE_BYTES, curmask) >> offsbits; + if (curmask != 0) result |= read_native(address + NATIVE_STEP, curmask) >> offsbits; } } return result; @@ -1316,45 +1322,45 @@ public: } // generic direct write - template<typename _TargetType, bool _Aligned> - void write_direct(offs_t address, _TargetType data, _TargetType mask) + template<typename TargetType, bool Aligned> + void write_direct(offs_t address, TargetType data, TargetType mask) { - const u32 TARGET_BYTES = sizeof(_TargetType); + const u32 TARGET_BYTES = sizeof(TargetType); const u32 TARGET_BITS = 8 * TARGET_BYTES; // equal to native size and aligned; simple pass-through to the native writer - if (NATIVE_BYTES == TARGET_BYTES && (_Aligned || (address & NATIVE_MASK) == 0)) + if (NATIVE_BYTES == TARGET_BYTES && (Aligned || (address & NATIVE_MASK) == 0)) return write_native(address & ~NATIVE_MASK, data, mask); // if native size is larger, see if we can do a single masked write (guaranteed if we're aligned) if (NATIVE_BYTES > TARGET_BYTES) { - u32 offsbits = 8 * (address & (NATIVE_BYTES - (_Aligned ? TARGET_BYTES : 1))); - if (_Aligned || (offsbits + TARGET_BITS <= NATIVE_BITS)) + u32 offsbits = 8 * (offset_to_byte(address) & (NATIVE_BYTES - (Aligned ? TARGET_BYTES : 1))); + if (Aligned || (offsbits + TARGET_BITS <= NATIVE_BITS)) { - if (_Endian != ENDIANNESS_LITTLE) offsbits = NATIVE_BITS - TARGET_BITS - offsbits; - return write_native(address & ~NATIVE_MASK, (_NativeType)data << offsbits, (_NativeType)mask << offsbits); + if (Endian != ENDIANNESS_LITTLE) offsbits = NATIVE_BITS - TARGET_BITS - offsbits; + return write_native(address & ~NATIVE_MASK, (NativeType)data << offsbits, (NativeType)mask << offsbits); } } // determine our alignment against the native boundaries, and mask the address - u32 offsbits = 8 * (address & (NATIVE_BYTES - 1)); + u32 offsbits = 8 * (offset_to_byte(address) & (NATIVE_BYTES - 1)); address &= ~NATIVE_MASK; // if we're here, and native size is larger or equal to the target, we need exactly 2 writes if (NATIVE_BYTES >= TARGET_BYTES) { // little-endian case - if (_Endian == ENDIANNESS_LITTLE) + if (Endian == ENDIANNESS_LITTLE) { // write lower bits to lower address - _NativeType curmask = (_NativeType)mask << offsbits; - if (curmask != 0) write_native(address, (_NativeType)data << offsbits, curmask); + NativeType curmask = (NativeType)mask << offsbits; + if (curmask != 0) write_native(address, (NativeType)data << offsbits, curmask); // write upper bits to upper address offsbits = NATIVE_BITS - offsbits; curmask = mask >> offsbits; - if (curmask != 0) write_native(address + NATIVE_BYTES, data >> offsbits, curmask); + if (curmask != 0) write_native(address + NATIVE_STEP, data >> offsbits, curmask); } // big-endian case @@ -1362,17 +1368,17 @@ public: { // left-justify the mask and data to the target type const u32 LEFT_JUSTIFY_TARGET_TO_NATIVE_SHIFT = ((NATIVE_BITS >= TARGET_BITS) ? (NATIVE_BITS - TARGET_BITS) : 0); - _NativeType ljdata = (_NativeType)data << LEFT_JUSTIFY_TARGET_TO_NATIVE_SHIFT; - _NativeType ljmask = (_NativeType)mask << LEFT_JUSTIFY_TARGET_TO_NATIVE_SHIFT; + NativeType ljdata = (NativeType)data << LEFT_JUSTIFY_TARGET_TO_NATIVE_SHIFT; + NativeType ljmask = (NativeType)mask << LEFT_JUSTIFY_TARGET_TO_NATIVE_SHIFT; // write upper bits to lower address - _NativeType curmask = ljmask >> offsbits; + NativeType curmask = ljmask >> offsbits; if (curmask != 0) write_native(address, ljdata >> offsbits, curmask); // write lower bits to upper address offsbits = NATIVE_BITS - offsbits; curmask = ljmask << offsbits; - if (curmask != 0) write_native(address + NATIVE_BYTES, ljdata << offsbits, curmask); + if (curmask != 0) write_native(address + NATIVE_STEP, ljdata << offsbits, curmask); } } @@ -1384,27 +1390,27 @@ public: const u32 MAX_SPLITS_MINUS_ONE = TARGET_BYTES / NATIVE_BYTES - 1; // little-endian case - if (_Endian == ENDIANNESS_LITTLE) + if (Endian == ENDIANNESS_LITTLE) { // write lowest bits to first address - _NativeType curmask = mask << offsbits; + NativeType curmask = mask << offsbits; if (curmask != 0) write_native(address, data << offsbits, curmask); // write middle bits to subsequent addresses offsbits = NATIVE_BITS - offsbits; for (u32 index = 0; index < MAX_SPLITS_MINUS_ONE; index++) { - address += NATIVE_BYTES; + address += NATIVE_STEP; curmask = mask >> offsbits; if (curmask != 0) write_native(address, data >> offsbits, curmask); offsbits += NATIVE_BITS; } // if we're not aligned and we still have bits left, write uppermost bits to last address - if (!_Aligned && offsbits < TARGET_BITS) + if (!Aligned && offsbits < TARGET_BITS) { curmask = mask >> offsbits; - if (curmask != 0) write_native(address + NATIVE_BYTES, data >> offsbits, curmask); + if (curmask != 0) write_native(address + NATIVE_STEP, data >> offsbits, curmask); } } @@ -1413,24 +1419,24 @@ public: { // write highest bits to first address offsbits = TARGET_BITS - (NATIVE_BITS - offsbits); - _NativeType curmask = mask >> offsbits; + NativeType curmask = mask >> offsbits; if (curmask != 0) write_native(address, data >> offsbits, curmask); // write middle bits to subsequent addresses for (u32 index = 0; index < MAX_SPLITS_MINUS_ONE; index++) { offsbits -= NATIVE_BITS; - address += NATIVE_BYTES; + address += NATIVE_STEP; curmask = mask >> offsbits; if (curmask != 0) write_native(address, data >> offsbits, curmask); } // if we're not aligned and we still have bits left, write lowermost bits to the last address - if (!_Aligned && offsbits != 0) + if (!Aligned && offsbits != 0) { offsbits = NATIVE_BITS - offsbits; curmask = mask << offsbits; - if (curmask != 0) write_native(address + NATIVE_BYTES, data << offsbits, curmask); + if (curmask != 0) write_native(address + NATIVE_STEP, data << offsbits, curmask); } } } @@ -1441,12 +1447,12 @@ public: // to some particular set_offset operation for an entry in the address map. void set_address(offs_t address) override { - offs_t byteaddress = address & m_bytemask; - u32 entry = setoffset_lookup(byteaddress); + address &= m_addrmask; + u32 entry = setoffset_lookup(address); const handler_entry_setoffset &handler = m_setoffset.handler_setoffset(entry); - offs_t offset = handler.byteoffset(byteaddress); - handler.setoffset(*this, offset / sizeof(_NativeType)); + offs_t offset = handler.offset(address); + handler.setoffset(*this, offset / sizeof(NativeType)); } // virtual access to these functions @@ -1499,23 +1505,52 @@ public: address_table_setoffset m_setoffset; // memory setoffset lookup table }; -typedef address_space_specific<u8, ENDIANNESS_LITTLE, false> address_space_8le_small; -typedef address_space_specific<u8, ENDIANNESS_BIG, false> address_space_8be_small; -typedef address_space_specific<u16, ENDIANNESS_LITTLE, false> address_space_16le_small; -typedef address_space_specific<u16, ENDIANNESS_BIG, false> address_space_16be_small; -typedef address_space_specific<u32, ENDIANNESS_LITTLE, false> address_space_32le_small; -typedef address_space_specific<u32, ENDIANNESS_BIG, false> address_space_32be_small; -typedef address_space_specific<u64, ENDIANNESS_LITTLE, false> address_space_64le_small; -typedef address_space_specific<u64, ENDIANNESS_BIG, false> address_space_64be_small; +typedef address_space_specific<u8, ENDIANNESS_LITTLE, 0, false> address_space_8_8le_small; +typedef address_space_specific<u8, ENDIANNESS_BIG, 0, false> address_space_8_8be_small; +typedef address_space_specific<u16, ENDIANNESS_LITTLE, 3, false> address_space_16_1le_small; +typedef address_space_specific<u16, ENDIANNESS_BIG, 3, false> address_space_16_1be_small; +typedef address_space_specific<u16, ENDIANNESS_LITTLE, 0, false> address_space_16_8le_small; +typedef address_space_specific<u16, ENDIANNESS_BIG, 0, false> address_space_16_8be_small; +typedef address_space_specific<u16, ENDIANNESS_LITTLE, -1, false> address_space_16_16le_small; +typedef address_space_specific<u16, ENDIANNESS_BIG, -1, false> address_space_16_16be_small; +typedef address_space_specific<u32, ENDIANNESS_LITTLE, 0, false> address_space_32_8le_small; +typedef address_space_specific<u32, ENDIANNESS_BIG, 0, false> address_space_32_8be_small; +typedef address_space_specific<u32, ENDIANNESS_LITTLE, -1, false> address_space_32_16le_small; +typedef address_space_specific<u32, ENDIANNESS_BIG, -1, false> address_space_32_16be_small; +typedef address_space_specific<u32, ENDIANNESS_LITTLE, -2, false> address_space_32_32le_small; +typedef address_space_specific<u32, ENDIANNESS_BIG, -2, false> address_space_32_32be_small; +typedef address_space_specific<u64, ENDIANNESS_LITTLE, 0, false> address_space_64_8le_small; +typedef address_space_specific<u64, ENDIANNESS_BIG, 0, false> address_space_64_8be_small; +typedef address_space_specific<u64, ENDIANNESS_LITTLE, -1, false> address_space_64_16le_small; +typedef address_space_specific<u64, ENDIANNESS_BIG, -1, false> address_space_64_16be_small; +typedef address_space_specific<u64, ENDIANNESS_LITTLE, -2, false> address_space_64_32le_small; +typedef address_space_specific<u64, ENDIANNESS_BIG, -2, false> address_space_64_32be_small; +typedef address_space_specific<u64, ENDIANNESS_LITTLE, -3, false> address_space_64_64le_small; +typedef address_space_specific<u64, ENDIANNESS_BIG, -3, false> address_space_64_64be_small; + +typedef address_space_specific<u8, ENDIANNESS_LITTLE, 0, true> address_space_8_8le_large; +typedef address_space_specific<u8, ENDIANNESS_BIG, 0, true> address_space_8_8be_large; +typedef address_space_specific<u16, ENDIANNESS_LITTLE, 3, true> address_space_16_1le_large; +typedef address_space_specific<u16, ENDIANNESS_BIG, 3, true> address_space_16_1be_large; +typedef address_space_specific<u16, ENDIANNESS_LITTLE, 0, true> address_space_16_8le_large; +typedef address_space_specific<u16, ENDIANNESS_BIG, 0, true> address_space_16_8be_large; +typedef address_space_specific<u16, ENDIANNESS_LITTLE, -1, true> address_space_16_16le_large; +typedef address_space_specific<u16, ENDIANNESS_BIG, -1, true> address_space_16_16be_large; +typedef address_space_specific<u32, ENDIANNESS_LITTLE, 0, true> address_space_32_8le_large; +typedef address_space_specific<u32, ENDIANNESS_BIG, 0, true> address_space_32_8be_large; +typedef address_space_specific<u32, ENDIANNESS_LITTLE, -1, true> address_space_32_16le_large; +typedef address_space_specific<u32, ENDIANNESS_BIG, -1, true> address_space_32_16be_large; +typedef address_space_specific<u32, ENDIANNESS_LITTLE, -2, true> address_space_32_32le_large; +typedef address_space_specific<u32, ENDIANNESS_BIG, -2, true> address_space_32_32be_large; +typedef address_space_specific<u64, ENDIANNESS_LITTLE, 0, true> address_space_64_8le_large; +typedef address_space_specific<u64, ENDIANNESS_BIG, 0, true> address_space_64_8be_large; +typedef address_space_specific<u64, ENDIANNESS_LITTLE, -1, true> address_space_64_16le_large; +typedef address_space_specific<u64, ENDIANNESS_BIG, -1, true> address_space_64_16be_large; +typedef address_space_specific<u64, ENDIANNESS_LITTLE, -2, true> address_space_64_32le_large; +typedef address_space_specific<u64, ENDIANNESS_BIG, -2, true> address_space_64_32be_large; +typedef address_space_specific<u64, ENDIANNESS_LITTLE, -3, true> address_space_64_64le_large; +typedef address_space_specific<u64, ENDIANNESS_BIG, -3, true> address_space_64_64be_large; -typedef address_space_specific<u8, ENDIANNESS_LITTLE, true> address_space_8le_large; -typedef address_space_specific<u8, ENDIANNESS_BIG, true> address_space_8be_large; -typedef address_space_specific<u16, ENDIANNESS_LITTLE, true> address_space_16le_large; -typedef address_space_specific<u16, ENDIANNESS_BIG, true> address_space_16be_large; -typedef address_space_specific<u32, ENDIANNESS_LITTLE, true> address_space_32le_large; -typedef address_space_specific<u32, ENDIANNESS_BIG, true> address_space_32be_large; -typedef address_space_specific<u64, ENDIANNESS_LITTLE, true> address_space_64le_large; -typedef address_space_specific<u64, ENDIANNESS_BIG, true> address_space_64be_large; @@ -1566,7 +1601,7 @@ void memory_manager::allocate(device_memory_interface &memory) if (spaceconfig) { // allocate one of the appropriate type - bool const large(spaceconfig->addr2byte_end(0xffffffffUL >> (32 - spaceconfig->m_addrbus_width)) >= (1 << 18)); + bool const large(spaceconfig->addr2byte_end(0xffffffffUL >> (32 - spaceconfig->m_addr_width)) >= (1 << 18)); switch (spaceconfig->data_width()) { @@ -1574,72 +1609,206 @@ void memory_manager::allocate(device_memory_interface &memory) if (spaceconfig->endianness() == ENDIANNESS_LITTLE) { if (large) - memory.allocate<address_space_8le_large>(*this, spacenum); + memory.allocate<address_space_8_8le_large>(*this, spacenum); else - memory.allocate<address_space_8le_small>(*this, spacenum); + memory.allocate<address_space_8_8le_small>(*this, spacenum); } else { if (large) - memory.allocate<address_space_8be_large>(*this, spacenum); + memory.allocate<address_space_8_8be_large>(*this, spacenum); else - memory.allocate<address_space_8be_small>(*this, spacenum); + memory.allocate<address_space_8_8be_small>(*this, spacenum); } break; - + case 16: - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + switch (spaceconfig->addr_shift()) { - if (large) - memory.allocate<address_space_16le_large>(*this, spacenum); + case 3: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_16_1le_large>(*this, spacenum); + else + memory.allocate<address_space_16_1le_small>(*this, spacenum); + } else - memory.allocate<address_space_16le_small>(*this, spacenum); - } - else - { - if (large) - memory.allocate<address_space_16be_large>(*this, spacenum); + { + if (large) + memory.allocate<address_space_16_1be_large>(*this, spacenum); + else + memory.allocate<address_space_16_1be_small>(*this, spacenum); + } + break; + + case 0: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_16_8le_large>(*this, spacenum); + else + memory.allocate<address_space_16_8le_small>(*this, spacenum); + } else - memory.allocate<address_space_16be_small>(*this, spacenum); + { + if (large) + memory.allocate<address_space_16_8be_large>(*this, spacenum); + else + memory.allocate<address_space_16_8be_small>(*this, spacenum); + } + break; + + case -1: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_16_16le_large>(*this, spacenum); + else + memory.allocate<address_space_16_16le_small>(*this, spacenum); + } + else + { + if (large) + memory.allocate<address_space_16_16be_large>(*this, spacenum); + else + memory.allocate<address_space_16_16be_small>(*this, spacenum); + } + break; } break; - + case 32: - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + switch (spaceconfig->addr_shift()) { - if (large) - memory.allocate<address_space_32le_large>(*this, spacenum); + case 0: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_32_8le_large>(*this, spacenum); + else + memory.allocate<address_space_32_8le_small>(*this, spacenum); + } else - memory.allocate<address_space_32le_small>(*this, spacenum); - } - else - { - if (large) - memory.allocate<address_space_32be_large>(*this, spacenum); + { + if (large) + memory.allocate<address_space_32_8be_large>(*this, spacenum); + else + memory.allocate<address_space_32_8be_small>(*this, spacenum); + } + break; + + case -1: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_32_16le_large>(*this, spacenum); + else + memory.allocate<address_space_32_16le_small>(*this, spacenum); + } else - memory.allocate<address_space_32be_small>(*this, spacenum); + { + if (large) + memory.allocate<address_space_32_16be_large>(*this, spacenum); + else + memory.allocate<address_space_32_16be_small>(*this, spacenum); + } + break; + + case -2: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_32_32le_large>(*this, spacenum); + else + memory.allocate<address_space_32_32le_small>(*this, spacenum); + } + else + { + if (large) + memory.allocate<address_space_32_32be_large>(*this, spacenum); + else + memory.allocate<address_space_32_32be_small>(*this, spacenum); + } + break; } break; - + case 64: - if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + switch (spaceconfig->addr_shift()) { - if (large) - memory.allocate<address_space_64le_large>(*this, spacenum); + case 0: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_64_8le_large>(*this, spacenum); + else + memory.allocate<address_space_64_8le_small>(*this, spacenum); + } else - memory.allocate<address_space_64le_small>(*this, spacenum); - } - else - { - if (large) - memory.allocate<address_space_64be_large>(*this, spacenum); + { + if (large) + memory.allocate<address_space_64_8be_large>(*this, spacenum); + else + memory.allocate<address_space_64_8be_small>(*this, spacenum); + } + break; + + case -1: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_64_16le_large>(*this, spacenum); + else + memory.allocate<address_space_64_16le_small>(*this, spacenum); + } + else + { + if (large) + memory.allocate<address_space_64_16be_large>(*this, spacenum); + else + memory.allocate<address_space_64_16be_small>(*this, spacenum); + } + break; + + case -2: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_64_32le_large>(*this, spacenum); + else + memory.allocate<address_space_64_32le_small>(*this, spacenum); + } + else + { + if (large) + memory.allocate<address_space_64_32be_large>(*this, spacenum); + else + memory.allocate<address_space_64_32be_small>(*this, spacenum); + } + break; + + case -3: + if (spaceconfig->endianness() == ENDIANNESS_LITTLE) + { + if (large) + memory.allocate<address_space_64_64le_large>(*this, spacenum); + else + memory.allocate<address_space_64_64le_small>(*this, spacenum); + } else - memory.allocate<address_space_64be_small>(*this, spacenum); + { + if (large) + memory.allocate<address_space_64_64be_large>(*this, spacenum); + else + memory.allocate<address_space_64_64be_small>(*this, spacenum); + } + break; } break; - + default: - throw emu_fatalerror("Invalid width %d specified for memory_manager::allocate", spaceconfig->data_width()); + throw emu_fatalerror("Invalid width %d specified for address_space::allocate", spaceconfig->data_width()); } } } @@ -1785,20 +1954,25 @@ void memory_manager::bank_reattach() address_space::address_space(memory_manager &manager, device_memory_interface &memory, int spacenum, bool large) : m_config(*memory.space_config(spacenum)), m_device(memory.device()), - m_addrmask(0xffffffffUL >> (32 - m_config.m_addrbus_width)), - m_bytemask(address_to_byte_end(m_addrmask)), + m_addrmask(0xffffffffUL >> (32 - m_config.m_addr_width)), m_logaddrmask(0xffffffffUL >> (32 - m_config.m_logaddr_width)), - m_logbytemask(address_to_byte_end(m_logaddrmask)), m_unmap(0), m_spacenum(spacenum), m_log_unmap(true), - m_direct(std::make_unique<direct_read_data>(*this)), m_name(memory.space_config(spacenum)->name()), - m_addrchars((m_config.m_addrbus_width + 3) / 4), + m_addrchars((m_config.m_addr_width + 3) / 4), m_logaddrchars((m_config.m_logaddr_width + 3) / 4), m_manager(manager), m_machine(memory.device().machine()) { + switch(m_config.addr_shift()) { + case 3: m_direct = static_cast<void *>(new direct_read_data< 3>(*this)); break; + case 0: m_direct = static_cast<void *>(new direct_read_data< 0>(*this)); break; + case -1: m_direct = static_cast<void *>(new direct_read_data<-1>(*this)); break; + case -2: m_direct = static_cast<void *>(new direct_read_data<-2>(*this)); break; + case -3: m_direct = static_cast<void *>(new direct_read_data<-3>(*this)); break; + default: fatalerror("Unsupported address shift %d\n", m_config.addr_shift()); + } } @@ -1808,6 +1982,13 @@ address_space::address_space(memory_manager &manager, device_memory_interface &m address_space::~address_space() { + switch(m_config.addr_shift()) { + case 3: delete static_cast<direct_read_data< 3> *>(m_direct); break; + case 0: delete static_cast<direct_read_data< 0> *>(m_direct); break; + case -1: delete static_cast<direct_read_data<-1> *>(m_direct); break; + case -2: delete static_cast<direct_read_data<-2> *>(m_direct); break; + case -3: delete static_cast<direct_read_data<-3> *>(m_direct); break; + } } @@ -1822,12 +2003,6 @@ inline void address_space::adjust_addresses(offs_t &start, offs_t &end, offs_t & mask &= m_addrmask; start &= ~mirror & m_addrmask; end &= ~mirror & m_addrmask; - - // adjust to byte values - start = address_to_byte(start); - end = address_to_byte_end(end); - mask = address_to_byte_end(mask); - mirror = address_to_byte(mirror); } void address_space::check_optimize_all(const char *function, offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, offs_t addrselect, offs_t &nstart, offs_t &nend, offs_t &nmask, offs_t &nmirror) @@ -1839,7 +2014,7 @@ void address_space::check_optimize_all(const char *function, offs_t addrstart, o if (addrend & ~m_addrmask) fatalerror("%s: In range %x-%x mask %x mirror %x select %x, end address is outside of the global address mask %x, did you mean %x ?\n", function, addrstart, addrend, addrmask, addrmirror, addrselect, m_addrmask, addrend & m_addrmask); - offs_t lowbits_mask = (m_config.data_width() >> (3 - m_config.m_addrbus_shift)) - 1; + offs_t lowbits_mask = (m_config.data_width() >> (3 - m_config.m_addr_shift)) - 1; if (addrstart & lowbits_mask) fatalerror("%s: In range %x-%x mask %x mirror %x select %x, start address has low bits set, did you mean %x ?\n", function, addrstart, addrend, addrmask, addrmirror, addrselect, addrstart & ~lowbits_mask); if ((~addrend) & lowbits_mask) @@ -1900,7 +2075,7 @@ void address_space::check_optimize_mirror(const char *function, offs_t addrstart if (addrend & ~m_addrmask) fatalerror("%s: In range %x-%x mirror %x, end address is outside of the global address mask %x, did you mean %x ?\n", function, addrstart, addrend, addrmirror, m_addrmask, addrend & m_addrmask); - offs_t lowbits_mask = (m_config.data_width() >> (3 - m_config.m_addrbus_shift)) - 1; + offs_t lowbits_mask = (m_config.data_width() >> (3 - m_config.m_addr_shift)) - 1; if (addrstart & lowbits_mask) fatalerror("%s: In range %x-%x mirror %x, start address has low bits set, did you mean %x ?\n", function, addrstart, addrend, addrmirror, addrstart & ~lowbits_mask); if ((~addrend) & lowbits_mask) @@ -1950,7 +2125,7 @@ void address_space::check_address(const char *function, offs_t addrstart, offs_t if (addrend & ~m_addrmask) fatalerror("%s: In range %x-%x, end address is outside of the global address mask %x, did you mean %x ?\n", function, addrstart, addrend, m_addrmask, addrend & m_addrmask); - offs_t lowbits_mask = (m_config.data_width() >> (3 - m_config.m_addrbus_shift)) - 1; + offs_t lowbits_mask = (m_config.data_width() >> (3 - m_config.m_addr_shift)) - 1; if (addrstart & lowbits_mask) fatalerror("%s: In range %x-%x, start address has low bits set, did you mean %x ?\n", function, addrstart, addrend, addrstart & ~lowbits_mask); if ((~addrend) & lowbits_mask) @@ -1978,20 +2153,13 @@ void address_space::prepare_map() // extract global parameters specified by the map m_unmap = (m_map->m_unmapval == 0) ? 0 : ~0; if (m_map->m_globalmask != 0) - { m_addrmask = m_map->m_globalmask; - m_bytemask = address_to_byte_end(m_addrmask); - } // make a pass over the address map, adjusting for the device and getting memory pointers for (address_map_entry &entry : m_map->m_entrylist) { // computed adjusted addresses first - entry.m_bytestart = entry.m_addrstart; - entry.m_byteend = entry.m_addrend; - entry.m_bytemirror = entry.m_addrmirror; - entry.m_bytemask = entry.m_addrmask ? entry.m_addrmask : ~entry.m_addrmirror; - adjust_addresses(entry.m_bytestart, entry.m_byteend, entry.m_bytemask, entry.m_bytemirror); + adjust_addresses(entry.m_addrstart, entry.m_addrend, entry.m_addrmask, entry.m_addrmirror); // if we have a share entry, add it to our map if (entry.m_share != nullptr) @@ -2000,8 +2168,8 @@ void address_space::prepare_map() std::string fulltag = entry.m_devbase.subtag(entry.m_share); if (manager().m_sharelist.find(fulltag.c_str()) == manager().m_sharelist.end()) { - VPRINTF(("Creating share '%s' of length 0x%X\n", fulltag.c_str(), entry.m_byteend + 1 - entry.m_bytestart)); - manager().m_sharelist.emplace(fulltag.c_str(), std::make_unique<memory_share>(m_map->m_databits, entry.m_byteend + 1 - entry.m_bytestart, endianness())); + VPRINTF(("Creating share '%s' of length 0x%X\n", fulltag.c_str(), entry.m_addrend + 1 - entry.m_addrstart)); + manager().m_sharelist.emplace(fulltag.c_str(), std::make_unique<memory_share>(m_map->m_databits, address_to_byte(entry.m_addrend + 1 - entry.m_addrstart), endianness())); } } @@ -2009,10 +2177,10 @@ void address_space::prepare_map() if (m_spacenum == 0 && entry.m_read.m_type == AMH_ROM && entry.m_region == nullptr) { // make sure it fits within the memory region before doing so, however - if (entry.m_byteend < devregionsize) + if (entry.m_addrend < devregionsize) { entry.m_region = m_device.tag(); - entry.m_rgnoffs = entry.m_bytestart; + entry.m_rgnoffs = address_to_byte(entry.m_addrstart); } } @@ -2028,7 +2196,7 @@ void address_space::prepare_map() fatalerror("device '%s' %s space memory map entry %X-%X references non-existant region \"%s\"\n", m_device.tag(), m_name, entry.m_addrstart, entry.m_addrend, entry.m_region); // validate the region - if (entry.m_rgnoffs + (entry.m_byteend - entry.m_bytestart + 1) > region->bytes()) + if (entry.m_rgnoffs + m_config.addr2byte(entry.m_addrend - entry.m_addrstart + 1) > region->bytes()) fatalerror("device '%s' %s space memory map entry %X-%X extends beyond region \"%s\" size (%X)\n", m_device.tag(), m_name, entry.m_addrstart, entry.m_addrend, entry.m_region, region->bytes()); } @@ -2044,8 +2212,8 @@ void address_space::prepare_map() } // now loop over all the handlers and enforce the address mask - read().mask_all_handlers(m_bytemask); - write().mask_all_handlers(m_bytemask); + read().mask_all_handlers(m_addrmask); + write().mask_all_handlers(m_addrmask); } @@ -2176,13 +2344,13 @@ void address_space::allocate_memory() int tail = blocklist.size(); for (address_map_entry &entry : m_map->m_entrylist) if (entry.m_memory != nullptr) - blocklist.push_back(std::make_unique<memory_block>(*this, entry.m_bytestart, entry.m_byteend, entry.m_memory)); + blocklist.push_back(std::make_unique<memory_block>(*this, entry.m_addrstart, entry.m_addrend, entry.m_memory)); // loop over all blocks just allocated and assign pointers from them address_map_entry *unassigned = nullptr; for (auto memblock = blocklist.begin() + tail; memblock != blocklist.end(); ++memblock) - unassigned = block_assign_intersecting(memblock->get()->bytestart(), memblock->get()->byteend(), memblock->get()->data()); + unassigned = block_assign_intersecting(memblock->get()->addrstart(), memblock->get()->addrend(), memblock->get()->data()); // if we don't have an unassigned pointer yet, try to find one if (unassigned == nullptr) @@ -2192,8 +2360,8 @@ void address_space::allocate_memory() while (unassigned != nullptr) { // work in MEMORY_BLOCK_CHUNK-sized chunks - offs_t curblockstart = unassigned->m_bytestart / MEMORY_BLOCK_CHUNK; - offs_t curblockend = unassigned->m_byteend / MEMORY_BLOCK_CHUNK; + offs_t curblockstart = unassigned->m_addrstart / MEMORY_BLOCK_CHUNK; + offs_t curblockend = unassigned->m_addrend / MEMORY_BLOCK_CHUNK; // loop while we keep finding unassigned blocks in neighboring MEMORY_BLOCK_CHUNK chunks bool changed; @@ -2206,8 +2374,8 @@ void address_space::allocate_memory() if (entry.m_memory == nullptr && &entry != unassigned && needs_backing_store(entry)) { // get block start/end blocks for this block - offs_t blockstart = entry.m_bytestart / MEMORY_BLOCK_CHUNK; - offs_t blockend = entry.m_byteend / MEMORY_BLOCK_CHUNK; + offs_t blockstart = entry.m_addrstart / MEMORY_BLOCK_CHUNK; + offs_t blockend = entry.m_addrend / MEMORY_BLOCK_CHUNK; // if we intersect or are adjacent, adjust the start/end if (blockstart <= curblockend + 1 && blockend >= curblockstart - 1) @@ -2221,12 +2389,12 @@ void address_space::allocate_memory() } while (changed); // we now have a block to allocate; do it - offs_t curbytestart = curblockstart * MEMORY_BLOCK_CHUNK; - offs_t curbyteend = curblockend * MEMORY_BLOCK_CHUNK + (MEMORY_BLOCK_CHUNK - 1); - auto block = std::make_unique<memory_block>(*this, curbytestart, curbyteend); + offs_t curaddrstart = curblockstart * MEMORY_BLOCK_CHUNK; + offs_t curaddrend = curblockend * MEMORY_BLOCK_CHUNK + (MEMORY_BLOCK_CHUNK - 1); + auto block = std::make_unique<memory_block>(*this, curaddrstart, curaddrend); // assign memory that intersected the new block - unassigned = block_assign_intersecting(curbytestart, curbyteend, block.get()->data()); + unassigned = block_assign_intersecting(curaddrstart, curaddrend, block.get()->data()); blocklist.push_back(std::move(block)); } } @@ -2245,7 +2413,7 @@ void address_space::locate_memory() { // set the initial bank pointer for (address_map_entry &entry : m_map->m_entrylist) - if (entry.m_bytestart == bank.second->bytestart() && entry.m_memory != nullptr) + if (entry.m_addrstart == bank.second->addrstart() && entry.m_memory != nullptr) { bank.second->set_base(entry.m_memory); VPRINTF(("assigned bank '%s' pointer to memory from range %08X-%08X [%p]\n", bank.second->tag(), entry.m_addrstart, entry.m_addrend, entry.m_memory)); @@ -2266,7 +2434,7 @@ void address_space::locate_memory() // intersecting blocks and assign their pointers //------------------------------------------------- -address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, offs_t byteend, u8 *base) +address_map_entry *address_space::block_assign_intersecting(offs_t addrstart, offs_t addrend, u8 *base) { address_map_entry *unassigned = nullptr; @@ -2290,10 +2458,10 @@ address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, of } // otherwise, look for a match in this block - if (entry.m_memory == nullptr && entry.m_bytestart >= bytestart && entry.m_byteend <= byteend) + if (entry.m_memory == nullptr && entry.m_addrstart >= addrstart && entry.m_addrend <= addrend) { - entry.m_memory = base + (entry.m_bytestart - bytestart); - VPRINTF(("memory range %08X-%08X -> found in block from %08X-%08X [%p]\n", entry.m_addrstart, entry.m_addrend, bytestart, byteend, entry.m_memory)); + entry.m_memory = base + m_config.addr2byte(entry.m_addrstart - addrstart); + VPRINTF(("memory range %08X-%08X -> found in block from %08X-%08X [%p]\n", entry.m_addrstart, entry.m_addrend, addrstart, addrend, entry.m_memory)); } // if we're the first match on a shared pointer, assign it now @@ -2322,12 +2490,12 @@ address_map_entry *address_space::block_assign_intersecting(offs_t bytestart, of // describing the handler at a particular offset //------------------------------------------------- -const char *address_space::get_handler_string(read_or_write readorwrite, offs_t byteaddress) +const char *address_space::get_handler_string(read_or_write readorwrite, offs_t address) { if (readorwrite == read_or_write::READ) - return read().handler_name(read().lookup(byteaddress)); + return read().handler_name(read().lookup(address)); else - return write().handler_name(write().lookup(byteaddress)); + return write().handler_name(write().lookup(address)); } @@ -2341,19 +2509,19 @@ void address_space::dump_map(FILE *file, read_or_write readorwrite) const address_table &table = (readorwrite == read_or_write::READ) ? static_cast<address_table &>(read()) : static_cast<address_table &>(write()); // dump generic information - fprintf(file, " Address bits = %d\n", m_config.m_addrbus_width); - fprintf(file, " Data bits = %d\n", m_config.m_databus_width); - fprintf(file, " Address mask = %X\n", m_bytemask); + fprintf(file, " Address bits = %d\n", m_config.m_addr_width); + fprintf(file, " Data bits = %d\n", m_config.m_data_width); + fprintf(file, " Address mask = %X\n", m_addrmask); fprintf(file, "\n"); // iterate over addresses - offs_t bytestart, byteend; - for (offs_t byteaddress = 0; byteaddress <= m_bytemask; byteaddress = byteend) + offs_t addrstart, addrend; + for (offs_t address = 0; address <= m_addrmask; address = addrend) { - u16 entry = table.derive_range(byteaddress, bytestart, byteend); + u16 entry = table.derive_range(address, addrstart, addrend); fprintf(file, "%08X-%08X = %02X: %s [offset=%08X]\n", - bytestart, byteend, entry, table.handler_name(entry), table.handler(entry).bytestart()); - if (++byteend == 0) + addrstart, addrend, entry, table.handler_name(entry), table.handler(entry).addrstart()); + if (++addrend == 0) break; } } @@ -2549,7 +2717,7 @@ void address_space::install_ram_generic(offs_t addrstart, offs_t addrend, offs_t { if (machine().phase() >= machine_phase::RESET) fatalerror("Attempted to call install_ram_generic() after initialization time without a baseptr!\n"); - auto block = std::make_unique<memory_block>(*this, address_to_byte(addrstart), address_to_byte_end(addrend)); + auto block = std::make_unique<memory_block>(*this, addrstart, addrend); bank.set_base(block.get()->data()); manager().m_blocklist.push_back(std::move(block)); } @@ -2739,10 +2907,7 @@ void address_space::install_setoffset_handler(offs_t addrstart, offs_t addrend, void *address_space::find_backing_memory(offs_t addrstart, offs_t addrend) { - offs_t bytestart = address_to_byte(addrstart); - offs_t byteend = address_to_byte_end(addrend); - - VPRINTF(("address_space::find_backing_memory('%s',%s,%08X-%08X) -> ", m_device.tag(), m_name, bytestart, byteend)); + VPRINTF(("address_space::find_backing_memory('%s',%s,%08X-%08X) -> ", m_device.tag(), m_name, addrstart, addrend)); if (m_map == nullptr) return nullptr; @@ -2750,21 +2915,19 @@ void *address_space::find_backing_memory(offs_t addrstart, offs_t addrend) // look in the address map first for (address_map_entry &entry : m_map->m_entrylist) { - offs_t maskstart = bytestart & entry.m_bytemask; - offs_t maskend = byteend & entry.m_bytemask; - if (entry.m_memory != nullptr && maskstart >= entry.m_bytestart && maskend <= entry.m_byteend) + if (entry.m_memory != nullptr && addrstart >= entry.m_addrstart && addrend <= entry.m_addrend) { - VPRINTF(("found in entry %08X-%08X [%p]\n", entry.m_addrstart, entry.m_addrend, (u8 *)entry.m_memory + (maskstart - entry.m_bytestart))); - return (u8 *)entry.m_memory + (maskstart - entry.m_bytestart); + VPRINTF(("found in entry %08X-%08X [%p]\n", entry.m_addrstart, entry.m_addrend, (u8 *)entry.m_memory + address_to_byte(addrstart - entry.m_addrstart))); + return (u8 *)entry.m_memory + address_to_byte(addrstart - entry.m_addrstart); } } // if not found there, look in the allocated blocks for (auto &block : manager().m_blocklist) - if (block->contains(*this, bytestart, byteend)) + if (block->contains(*this, addrstart, addrend)) { - VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block->bytestart(), block->byteend(), block->data() + (bytestart - block->bytestart()))); - return block->data() + bytestart - block->bytestart(); + VPRINTF(("found in allocated memory block %08X-%08X [%p]\n", block->addrstart(), block->addrend(), block->data() + address_to_byte(addrstart - block->addrstart()))); + return block->data() + address_to_byte(addrstart - block->addrstart()); } VPRINTF(("did not find\n")); @@ -2818,11 +2981,8 @@ bool address_space::needs_backing_store(const address_map_entry &entry) memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrstart, offs_t addrend, offs_t addrmirror, read_or_write readorwrite) { // adjust the addresses, handling mirrors and such - offs_t bytemirror = addrmirror; - offs_t bytestart = addrstart; - offs_t bytemask = ~addrmirror; - offs_t byteend = addrend; - adjust_addresses(bytestart, byteend, bytemask, bytemirror); + offs_t addrmask = ~addrmirror; + adjust_addresses(addrstart, addrend, addrmask, addrmirror); // look up the bank by name, or else by byte range memory_bank *membank = nullptr; @@ -2832,7 +2992,7 @@ memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrst membank = bank->second.get(); } else { - membank = bank_find_anonymous(bytestart, byteend); + membank = bank_find_anonymous(addrstart, addrend); } // if we don't have a bank yet, find a free one @@ -2845,11 +3005,11 @@ memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrst if (tag != nullptr) throw emu_fatalerror("Unable to allocate new bank '%s'", tag); else - throw emu_fatalerror("Unable to allocate bank for RAM/ROM area %X-%X\n", bytestart, byteend); + throw emu_fatalerror("Unable to allocate bank for RAM/ROM area %X-%X\n", addrstart, addrend); } // if no tag, create a unique one - auto bank = std::make_unique<memory_bank>(*this, banknum, bytestart, byteend, tag); + auto bank = std::make_unique<memory_bank>(*this, banknum, addrstart, addrend, tag); std::string temptag; if (tag == nullptr) { temptag = string_format("anon_%p", bank.get()); @@ -2869,17 +3029,56 @@ memory_bank &address_space::bank_find_or_allocate(const char *tag, offs_t addrst // bank_find_anonymous - try to find an anonymous // bank matching the given byte range //------------------------------------------------- -memory_bank *address_space::bank_find_anonymous(offs_t bytestart, offs_t byteend) const +memory_bank *address_space::bank_find_anonymous(offs_t addrstart, offs_t addrend) const { // try to find an exact match for (auto &bank : manager().banks()) - if (bank.second->anonymous() && bank.second->references_space(*this, read_or_write::READWRITE) && bank.second->matches_exactly(bytestart, byteend)) + if (bank.second->anonymous() && bank.second->references_space(*this, read_or_write::READWRITE) && bank.second->matches_exactly(addrstart, addrend)) return bank.second.get(); // not found return nullptr; } +//------------------------------------------------- +// address_space::invalidate_read_caches -- clear +// the read cache (direct) for a specific entry +// or all of them +//------------------------------------------------- + +void address_space::invalidate_read_caches() +{ + switch(m_config.addr_shift()) { + case 3: static_cast<direct_read_data< 3> *>(m_direct)->force_update(); break; + case 0: static_cast<direct_read_data< 0> *>(m_direct)->force_update(); break; + case -1: static_cast<direct_read_data<-1> *>(m_direct)->force_update(); break; + case -2: static_cast<direct_read_data<-2> *>(m_direct)->force_update(); break; + case -3: static_cast<direct_read_data<-3> *>(m_direct)->force_update(); break; + } +} + +void address_space::invalidate_read_caches(u16 entry) +{ + switch(m_config.addr_shift()) { + case 3: static_cast<direct_read_data< 3> *>(m_direct)->force_update(entry); break; + case 0: static_cast<direct_read_data< 0> *>(m_direct)->force_update(entry); break; + case -1: static_cast<direct_read_data<-1> *>(m_direct)->force_update(entry); break; + case -2: static_cast<direct_read_data<-2> *>(m_direct)->force_update(entry); break; + case -3: static_cast<direct_read_data<-3> *>(m_direct)->force_update(entry); break; + } +} + +void address_space::invalidate_read_caches(offs_t start, offs_t end) +{ + switch(m_config.addr_shift()) { + case 3: static_cast<direct_read_data< 3> *>(m_direct)->remove_intersecting_ranges(start, end); break; + case 0: static_cast<direct_read_data< 0> *>(m_direct)->remove_intersecting_ranges(start, end); break; + case -1: static_cast<direct_read_data<-1> *>(m_direct)->remove_intersecting_ranges(start, end); break; + case -2: static_cast<direct_read_data<-2> *>(m_direct)->remove_intersecting_ranges(start, end); break; + case -3: static_cast<direct_read_data<-3> *>(m_direct)->remove_intersecting_ranges(start, end); break; + } +} + //************************************************************************** // TABLE MANAGEMENT @@ -2935,27 +3134,23 @@ address_table::~address_table() void address_table::map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, u16 entry) { // convert addresses to bytes - offs_t bytestart = addrstart; - offs_t byteend = addrend; - offs_t bytemask = addrmask; - offs_t bytemirror = addrmirror; - m_space.adjust_addresses(bytestart, byteend, bytemask, bytemirror); + m_space.adjust_addresses(addrstart, addrend, addrmask, addrmirror); // validity checks assert_always(addrstart <= addrend, "address_table::map_range called with start greater than end"); - assert_always((bytestart & (m_space.data_width() / 8 - 1)) == 0, "address_table::map_range called with misaligned start address"); - assert_always((byteend & (m_space.data_width() / 8 - 1)) == (m_space.data_width() / 8 - 1), "address_table::map_range called with misaligned end address"); + assert_always((addrstart & (m_space.alignment() - 1)) == 0, "address_table::map_range called with misaligned start address"); + assert_always((addrend & (m_space.alignment() - 1)) == (m_space.alignment() - 1), "address_table::map_range called with misaligned end address"); // configure the entry to our parameters (but not for static non-banked cases) handler_entry &curentry = handler(entry); if (entry <= STATIC_BANKMAX || entry >= STATIC_COUNT) - curentry.configure(bytestart, byteend, bytemask); + curentry.configure(addrstart, addrend, addrmask, m_space.address_to_byte_end(addrmask)); // populate it - populate_range_mirrored(bytestart, byteend, bytemirror, entry); + populate_range_mirrored(addrstart, addrend, addrmirror, entry); // recompute any direct access on this space if it is a read modification - m_space.m_direct->force_update(entry); + m_space.invalidate_read_caches(entry); // verify_reference_counts(); } @@ -3022,16 +3217,14 @@ namespace { void address_table::setup_range_masked(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, u64 mask, std::list<u32> &entries) { // convert addresses to bytes - offs_t bytestart = addrstart; - offs_t byteend = addrend; - offs_t bytemask = addrmask; - offs_t bytemirror = addrmirror; - m_space.adjust_addresses(bytestart, byteend, bytemask, bytemirror); + m_space.adjust_addresses(addrstart, addrend, addrmask, addrmirror); // Validity checks assert_always(addrstart <= addrend, "address_table::setup_range called with start greater than end"); - assert_always((bytestart & (m_space.data_width() / 8 - 1)) == 0, "address_table::setup_range called with misaligned start address"); - assert_always((byteend & (m_space.data_width() / 8 - 1)) == (m_space.data_width() / 8 - 1), "address_table::setup_range called with misaligned end address"); + assert_always((addrstart & (m_space.alignment() - 1)) == 0, "address_table::setup_range called with misaligned start address"); + assert_always((addrend & (m_space.alignment() - 1)) == (m_space.alignment() - 1), "address_table::setup_range called with misaligned end address"); + + offs_t bytemask = m_space.address_to_byte_end(addrmask); // Scan the memory to see what has to be done std::list<subrange> range_override; @@ -3040,8 +3233,8 @@ void address_table::setup_range_masked(offs_t addrstart, offs_t addrend, offs_t offs_t base_mirror = 0; do { - offs_t base_address = base_mirror | bytestart; - offs_t end_address = base_mirror | byteend; + offs_t base_address = base_mirror | addrstart; + offs_t end_address = base_mirror | addrend; do { @@ -3059,7 +3252,7 @@ void address_table::setup_range_masked(offs_t addrstart, offs_t addrend, offs_t while (base_address != end_address + 1); // Efficient method to go to the next range start given a mirroring mask - base_mirror = (base_mirror + 1 + ~bytemirror) & bytemirror; + base_mirror = (base_mirror + 1 + ~addrmirror) & addrmirror; } while (base_mirror); @@ -3071,7 +3264,7 @@ void address_table::setup_range_masked(offs_t addrstart, offs_t addrend, offs_t // configure the entry to our parameters handler_entry &curentry = handler(entry); - curentry.configure(bytestart, byteend, bytemask); + curentry.configure(addrstart, addrend, addrmask, bytemask); // Populate it wherever needed for (std::list<subrange>::const_iterator i = range_override.begin(); i != range_override.end(); ++i) @@ -3081,7 +3274,7 @@ void address_table::setup_range_masked(offs_t addrstart, offs_t addrend, offs_t entries.push_back(entry); // recompute any direct access on this space if it is a read modification - m_space.m_direct->force_update(entry); + m_space.invalidate_read_caches(entry); } // Ranges in range_partial must be duplicated then partially changed @@ -3111,7 +3304,7 @@ void address_table::setup_range_masked(offs_t addrstart, offs_t addrend, offs_t curentry.clear_conflicting_subunits(mask); // Reconfigure the base addresses - curentry.configure(bytestart, byteend, bytemask); + curentry.configure(addrstart, addrend, addrmask, bytemask); // Populate it wherever needed for (const auto & elem : i->second) @@ -3123,7 +3316,7 @@ void address_table::setup_range_masked(offs_t addrstart, offs_t addrend, offs_t entries.push_back(entry); // recompute any direct access on this space if it is a read modification - m_space.m_direct->force_update(entry); + m_space.invalidate_read_caches(entry); } } @@ -3182,16 +3375,16 @@ void address_table::verify_reference_counts() // range of addresses //------------------------------------------------- -void address_table::populate_range(offs_t bytestart, offs_t byteend, u16 handlerindex) +void address_table::populate_range(offs_t addrstart, offs_t addrend, u16 handlerindex) { offs_t l2mask = (1 << level2_bits()) - 1; - offs_t l1start = bytestart >> level2_bits(); - offs_t l2start = bytestart & l2mask; - offs_t l1stop = byteend >> level2_bits(); - offs_t l2stop = byteend & l2mask; + offs_t l1start = addrstart >> level2_bits(); + offs_t l2start = addrstart & l2mask; + offs_t l1stop = addrend >> level2_bits(); + offs_t l2stop = addrend & l2mask; // sanity check - if (bytestart > byteend) + if (addrstart > addrend) return; // handle the starting edge if it's not on a block boundary @@ -3267,19 +3460,19 @@ void address_table::populate_range(offs_t bytestart, offs_t byteend, u16 handler // mirrors //------------------------------------------------- -void address_table::populate_range_mirrored(offs_t bytestart, offs_t byteend, offs_t bytemirror, u16 handlerindex) +void address_table::populate_range_mirrored(offs_t addrstart, offs_t addrend, offs_t addrmirror, u16 handlerindex) { // determine the mirror bits offs_t lmirrorbits = 0; offs_t lmirrorbit[32]; for (int bit = 0; bit < level2_bits(); bit++) - if (bytemirror & (1 << bit)) + if (addrmirror & (1 << bit)) lmirrorbit[lmirrorbits++] = 1 << bit; offs_t hmirrorbits = 0; offs_t hmirrorbit[32]; for (int bit = level2_bits(); bit < 32; bit++) - if (bytemirror & (1 << bit)) + if (addrmirror & (1 << bit)) hmirrorbit[hmirrorbits++] = 1 << bit; // loop over mirrors in the level 2 table @@ -3301,14 +3494,14 @@ void address_table::populate_range_mirrored(offs_t bytestart, offs_t byteend, of for (int bit = 0; bit < lmirrorbits; bit++) if (lmirrorcount & (1 << bit)) lmirrorbase |= lmirrorbit[bit]; - m_space.m_direct->remove_intersecting_ranges(bytestart + lmirrorbase, byteend + lmirrorbase); + m_space.invalidate_read_caches(addrstart + lmirrorbase, addrend + lmirrorbase); } // if this is not our first time through, and the level 2 entry matches the previous // level 2 entry, just do a quick map and get out; note that this only works for entries // which don't span multiple level 1 table entries - int cur_index = level1_index(bytestart + hmirrorbase); - if (cur_index == level1_index(byteend + hmirrorbase)) + int cur_index = level1_index(addrstart + hmirrorbase); + if (cur_index == level1_index(addrend + hmirrorbase)) { if (hmirrorcount != 0 && prev_entry == m_table[cur_index]) { @@ -3344,7 +3537,7 @@ void address_table::populate_range_mirrored(offs_t bytestart, offs_t byteend, of lmirrorbase |= lmirrorbit[bit]; // populate the tables - populate_range(bytestart + lmirrorbase, byteend + lmirrorbase, handlerindex); + populate_range(addrstart + lmirrorbase, addrend + lmirrorbase, handlerindex); } } } @@ -3356,22 +3549,22 @@ void address_table::populate_range_mirrored(offs_t bytestart, offs_t byteend, of // range based on the lookup tables //------------------------------------------------- -u16 address_table::derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const +u16 address_table::derive_range(offs_t address, offs_t &addrstart, offs_t &addrend) const { // look up the initial address to get the entry we care about u16 l1entry; - u16 entry = l1entry = m_table[level1_index(byteaddress)]; + u16 entry = l1entry = m_table[level1_index(address)]; if (l1entry >= SUBTABLE_BASE) - entry = m_table[level2_index(l1entry, byteaddress)]; + entry = m_table[level2_index(l1entry, address)]; - // use the bytemask of the entry to set minimum and maximum bounds + // use the addrmask of the entry to set minimum and maximum bounds offs_t minscan, maxscan; - handler(entry).mirrored_start_end(byteaddress, minscan, maxscan); + handler(entry).mirrored_start_end(address, minscan, maxscan); // first scan backwards to find the start address u16 curl1entry = l1entry; u16 curentry = entry; - bytestart = byteaddress; + addrstart = address; while (1) { // if we need to scan the subtable, do it @@ -3381,7 +3574,7 @@ u16 address_table::derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &b u32 index; // scan backwards from the current address, until the previous entry doesn't match - for (index = level2_index(curl1entry, bytestart); index > minindex; index--, bytestart -= 1) + for (index = level2_index(curl1entry, addrstart); index > minindex; index--, addrstart -= 1) if (m_table[index - 1] != entry) break; @@ -3391,25 +3584,25 @@ u16 address_table::derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &b } // move to the beginning of this L1 entry; stop at the minimum address - bytestart &= ~((1 << level2_bits()) - 1); - if (bytestart <= minscan) + addrstart &= ~((1 << level2_bits()) - 1); + if (addrstart <= minscan) break; // look up the entry of the byte at the end of the previous L1 entry; if it doesn't match, stop - curentry = curl1entry = m_table[level1_index(bytestart - 1)]; + curentry = curl1entry = m_table[level1_index(addrstart - 1)]; if (curl1entry >= SUBTABLE_BASE) - curentry = m_table[level2_index(curl1entry, bytestart - 1)]; + curentry = m_table[level2_index(curl1entry, addrstart - 1)]; if (curentry != entry) break; // move into the previous entry and resume searching - bytestart -= 1; + addrstart -= 1; } // then scan forwards to find the end address curl1entry = l1entry; curentry = entry; - byteend = byteaddress; + addrend = address; while (1) { // if we need to scan the subtable, do it @@ -3419,7 +3612,7 @@ u16 address_table::derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &b u32 index; // scan forwards from the current address, until the next entry doesn't match - for (index = level2_index(curl1entry, byteend); index < maxindex; index++, byteend += 1) + for (index = level2_index(curl1entry, addrend); index < maxindex; index++, addrend += 1) if (m_table[index + 1] != entry) break; @@ -3429,19 +3622,19 @@ u16 address_table::derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &b } // move to the end of this L1 entry; stop at the maximum address - byteend |= (1 << level2_bits()) - 1; - if (byteend >= maxscan) + addrend |= (1 << level2_bits()) - 1; + if (addrend >= maxscan) break; // look up the entry of the byte at the start of the next L1 entry; if it doesn't match, stop - curentry = curl1entry = m_table[level1_index(byteend + 1)]; + curentry = curl1entry = m_table[level1_index(addrend + 1)]; if (curl1entry >= SUBTABLE_BASE) - curentry = m_table[level2_index(curl1entry, byteend + 1)]; + curentry = m_table[level2_index(curl1entry, addrend + 1)]; if (curentry != entry) break; // move into the next entry and resume searching - byteend += 1; + addrend += 1; } return entry; @@ -3746,9 +3939,9 @@ address_table_read::address_table_read(address_space &space, bool large) } // reset the byte masks on the special handlers to open up the full address space for proper reporting - m_handlers[STATIC_UNMAP]->configure(0, space.bytemask(), ~0); - m_handlers[STATIC_NOP]->configure(0, space.bytemask(), ~0); - m_handlers[STATIC_WATCHPOINT]->configure(0, space.bytemask(), ~0); + m_handlers[STATIC_UNMAP]->configure(0, space.addrmask(), ~0, ~0); + m_handlers[STATIC_NOP]->configure(0, space.addrmask(), ~0, ~0); + m_handlers[STATIC_WATCHPOINT]->configure(0, space.addrmask(), ~0, ~0); } @@ -3820,9 +4013,9 @@ address_table_write::address_table_write(address_space &space, bool large) } // reset the byte masks on the special handlers to open up the full address space for proper reporting - m_handlers[STATIC_UNMAP]->configure(0, space.bytemask(), ~0); - m_handlers[STATIC_NOP]->configure(0, space.bytemask(), ~0); - m_handlers[STATIC_WATCHPOINT]->configure(0, space.bytemask(), ~0); + m_handlers[STATIC_UNMAP]->configure(0, space.addrmask(), ~0, ~0); + m_handlers[STATIC_NOP]->configure(0, space.addrmask(), ~0, ~0); + m_handlers[STATIC_WATCHPOINT]->configure(0, space.addrmask(), ~0, ~0); } @@ -3856,12 +4049,12 @@ handler_entry &address_table_write::handler(u32 index) const // direct_read_data - constructor //------------------------------------------------- -direct_read_data::direct_read_data(address_space &space) +template<int AddrShift> direct_read_data<AddrShift>::direct_read_data(address_space &space) : m_space(space), m_ptr(nullptr), - m_bytemask(space.bytemask()), - m_bytestart(1), - m_byteend(0), + m_addrmask(space.addrmask()), + m_addrstart(1), + m_addrend(0), m_entry(STATIC_UNMAP) { } @@ -3871,7 +4064,7 @@ direct_read_data::direct_read_data(address_space &space) // ~direct_read_data - destructor //------------------------------------------------- -direct_read_data::~direct_read_data() +template<int AddrShift> direct_read_data<AddrShift>::~direct_read_data() { } @@ -3881,29 +4074,35 @@ direct_read_data::~direct_read_data() // update the opcode base for the given address //------------------------------------------------- -bool direct_read_data::set_direct_region(offs_t byteaddress) +template<int AddrShift> bool direct_read_data<AddrShift>::set_direct_region(offs_t address) { // find or allocate a matching range - direct_range *range = find_range(byteaddress, m_entry); + direct_range *range = find_range(address, m_entry); // if we don't map to a bank, return false if (m_entry < STATIC_BANK1 || m_entry > STATIC_BANKMAX) { // ensure future updates to land here as well until we get back into a bank - m_byteend = 0; - m_bytestart = 1; + m_addrend = 0; + m_addrstart = 1; return false; } u8 *base = *m_space.manager().bank_pointer_addr(m_entry); // compute the adjusted base - offs_t maskedbits = byteaddress & ~m_space.bytemask(); + offs_t maskedbits = address & ~m_space.addrmask(); const handler_entry_read &handler = m_space.read().handler_read(m_entry); - m_bytemask = handler.bytemask(); - m_ptr = base - (handler.bytestart() & m_bytemask); - m_bytestart = maskedbits | range->m_bytestart; - m_byteend = maskedbits | range->m_byteend; + m_addrmask = handler.addrmask(); + u32 delta = handler.addrstart() & m_addrmask; + if(AddrShift < 0) + delta = delta << iabs(AddrShift); + else if(AddrShift > 0) + delta = delta >> iabs(AddrShift); + + m_ptr = base - delta; + m_addrstart = maskedbits | range->m_addrstart; + m_addrend = maskedbits | range->m_addrend; return true; } @@ -3912,20 +4111,20 @@ bool direct_read_data::set_direct_region(offs_t byteaddress) // find_range - find a byte address in a range //------------------------------------------------- -direct_read_data::direct_range *direct_read_data::find_range(offs_t byteaddress, u16 &entry) +template<int AddrShift> typename direct_read_data<AddrShift>::direct_range *direct_read_data<AddrShift>::find_range(offs_t address, u16 &entry) { // determine which entry - byteaddress &= m_space.m_bytemask; - entry = m_space.read().lookup_live_nowp(byteaddress); + address &= m_space.m_addrmask; + entry = m_space.read().lookup_live_nowp(address); // scan our table for (auto &range : m_rangelist[entry]) - if (byteaddress >= range.m_bytestart && byteaddress <= range.m_byteend) + if (address >= range.m_addrstart && address <= range.m_addrend) return ⦥ // didn't find out; create a new one direct_range range; - m_space.read().derive_range(byteaddress, range.m_bytestart, range.m_byteend); + m_space.read().derive_range(address, range.m_addrstart, range.m_addrend); m_rangelist[entry].push_front(range); return &m_rangelist[entry].front(); @@ -3937,7 +4136,7 @@ direct_read_data::direct_range *direct_read_data::find_range(offs_t byteaddress, // ranges that intersect the given address range //------------------------------------------------- -void direct_read_data::remove_intersecting_ranges(offs_t bytestart, offs_t byteend) +template<int AddrShift> void direct_read_data<AddrShift>::remove_intersecting_ranges(offs_t addrstart, offs_t addrend) { // loop over all entries for (auto & elem : m_rangelist) @@ -3946,7 +4145,7 @@ void direct_read_data::remove_intersecting_ranges(offs_t bytestart, offs_t bytee for (auto range = elem.begin(); range!=elem.end();) { // if we intersect, remove - if (bytestart <= range->m_byteend && byteend >= range->m_bytestart) + if (addrstart <= range->m_addrend && addrend >= range->m_addrstart) range = elem.erase(range); else range ++; @@ -3954,6 +4153,12 @@ void direct_read_data::remove_intersecting_ranges(offs_t bytestart, offs_t bytee } } +template class direct_read_data<3>; +template class direct_read_data<0>; +template class direct_read_data<-1>; +template class direct_read_data<-2>; +template class direct_read_data<-3>; + //************************************************************************** // MEMORY BLOCK @@ -3963,15 +4168,15 @@ void direct_read_data::remove_intersecting_ranges(offs_t bytestart, offs_t bytee // memory_block - constructor //------------------------------------------------- -memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteend, void *memory) +memory_block::memory_block(address_space &space, offs_t addrstart, offs_t addrend, void *memory) : m_machine(space.machine()), m_space(space), - m_bytestart(bytestart), - m_byteend(byteend), + m_addrstart(addrstart), + m_addrend(addrend), m_data(reinterpret_cast<u8 *>(memory)) { - offs_t const length = byteend + 1 - bytestart; - VPRINTF(("block_allocate('%s',%s,%08X,%08X,%p)\n", space.device().tag(), space.name(), bytestart, byteend, memory)); + offs_t const length = space.address_to_byte(addrend + 1 - addrstart); + VPRINTF(("block_allocate('%s',%s,%08X,%08X,%p)\n", space.device().tag(), space.name(), addrstart, addrend, memory)); // allocate a block if needed if (m_data == nullptr) @@ -3996,8 +4201,8 @@ memory_block::memory_block(address_space &space, offs_t bytestart, offs_t byteen else { int bytes_per_element = space.data_width() / 8; - std::string name = string_format("%08x-%08x", bytestart, byteend); - space.machine().save().save_memory(nullptr, "memory", space.device().tag(), space.spacenum(), name.c_str(), m_data, bytes_per_element, (u32)length / bytes_per_element); + std::string name = string_format("%08x-%08x", addrstart, addrend); + space.machine().save().save_memory(&space.device(), "memory", space.device().tag(), space.spacenum(), name.c_str(), m_data, bytes_per_element, (u32)length / bytes_per_element); } } @@ -4020,13 +4225,13 @@ memory_block::~memory_block() // memory_bank - constructor //------------------------------------------------- -memory_bank::memory_bank(address_space &space, int index, offs_t bytestart, offs_t byteend, const char *tag) +memory_bank::memory_bank(address_space &space, int index, offs_t addrstart, offs_t addrend, const char *tag) : m_machine(space.machine()), m_baseptr(space.manager().bank_pointer_addr(index)), m_index(index), m_anonymous(tag == nullptr), - m_bytestart(bytestart), - m_byteend(byteend), + m_addrstart(addrstart), + m_addrend(addrend), m_curentry(BANK_ENTRY_UNSPECIFIED) { // generate an internal tag if we don't have one @@ -4042,7 +4247,7 @@ memory_bank::memory_bank(address_space &space, int index, offs_t bytestart, offs } if (!m_anonymous && space.machine().save().registration_allowed()) - space.machine().save().save_item(nullptr, "memory", m_tag.c_str(), 0, NAME(m_curentry)); + space.machine().save().save_item(&space.device(), "memory", m_tag.c_str(), 0, NAME(m_curentry)); } @@ -4093,7 +4298,7 @@ void memory_bank::invalidate_references() { // invalidate all the direct references to any referenced address spaces for (auto &ref : m_reflist) - ref->space().direct().force_update(); + ref->space().invalidate_read_caches(); } @@ -4218,8 +4423,9 @@ handler_entry::handler_entry(u8 width, endianness_t endianness, u8 **rambaseptr) : m_populated(false), m_datawidth(width), m_endianness(endianness), - m_bytestart(0), - m_byteend(0), + m_addrstart(0), + m_addrend(0), + m_addrmask(~0), m_bytemask(~0), m_rambaseptr(rambaseptr), m_subunits(0), @@ -4253,8 +4459,9 @@ void handler_entry::copy(handler_entry *entry) m_populated = true; m_datawidth = entry->m_datawidth; m_endianness = entry->m_endianness; - m_bytestart = entry->m_bytestart; - m_byteend = entry->m_byteend; + m_addrstart = entry->m_addrstart; + m_addrend = entry->m_addrend; + m_addrmask = entry->m_addrmask; m_bytemask = entry->m_bytemask; m_rambaseptr = nullptr; m_subunits = entry->m_subunits; @@ -4267,9 +4474,9 @@ void handler_entry::copy(handler_entry *entry) // reconfigure_subunits - reconfigure the subunits // to handle a new base address //------------------------------------------------- -void handler_entry::reconfigure_subunits(offs_t bytestart) +void handler_entry::reconfigure_subunits(offs_t addrstart) { - s32 delta = bytestart - m_bytestart; + s32 delta = addrstart - m_addrstart; for (int i=0; i != m_subunits; i++) m_subunit_infos[i].m_offset += delta / (m_subunit_infos[i].m_size / 8); } @@ -4319,7 +4526,7 @@ void handler_entry::configure_subunits(u64 handlermask, int handlerbits, int &st u32 shift = (unitnum^shift_xor_mask) * handlerbits; if (((handlermask >> shift) & unitmask) != 0) { - m_subunit_infos[m_subunits].m_bytemask = m_bytemask / (maxunits / multiplier); + m_subunit_infos[m_subunits].m_addrmask = m_bytemask / (maxunits / multiplier); m_subunit_infos[m_subunits].m_mask = unitmask; m_subunit_infos[m_subunits].m_offset = cur_offset++; m_subunit_infos[m_subunits].m_size = handlerbits; @@ -4413,7 +4620,7 @@ void handler_entry::description(char *buffer) const m_subunit_infos[i].m_shift, m_subunit_infos[i].m_offset, m_subunit_infos[i].m_multiplier, - m_subunit_infos[i].m_bytemask, + m_subunit_infos[i].m_addrmask, subunit_name(i)); } } @@ -4660,7 +4867,7 @@ u16 handler_entry_read::read_stub_16(address_space &space, offs_t offset, u16 ma { offs_t aoffset = offset * si.m_multiplier + si.m_offset; u8 val; - val = m_subread[index].r8(space, aoffset & si.m_bytemask, submask); + val = m_subread[index].r8(space, aoffset & si.m_addrmask, submask); result |= val << si.m_shift; } } @@ -4687,10 +4894,10 @@ u32 handler_entry_read::read_stub_32(address_space &space, offs_t offset, u32 ma switch (si.m_size) { case 8: - val = m_subread[index].r8(space, aoffset & si.m_bytemask, submask); + val = m_subread[index].r8(space, aoffset & si.m_addrmask, submask); break; case 16: - val = m_subread[index].r16(space, aoffset & si.m_bytemask, submask); + val = m_subread[index].r16(space, aoffset & si.m_addrmask, submask); break; } result |= val << si.m_shift; @@ -4719,13 +4926,13 @@ u64 handler_entry_read::read_stub_64(address_space &space, offs_t offset, u64 ma switch (si.m_size) { case 8: - val = m_subread[index].r8(space, aoffset & si.m_bytemask, submask); + val = m_subread[index].r8(space, aoffset & si.m_addrmask, submask); break; case 16: - val = m_subread[index].r16(space, aoffset & si.m_bytemask, submask); + val = m_subread[index].r16(space, aoffset & si.m_addrmask, submask); break; case 32: - val = m_subread[index].r32(space, aoffset & si.m_bytemask, submask); + val = m_subread[index].r32(space, aoffset & si.m_addrmask, submask); break; } result |= u64(val) << si.m_shift; @@ -4953,7 +5160,7 @@ void handler_entry_write::write_stub_16(address_space &space, offs_t offset, u16 { offs_t aoffset = offset * si.m_multiplier + si.m_offset; u8 adata = data >> si.m_shift; - m_subwrite[index].w8(space, aoffset & si.m_bytemask, adata, submask); + m_subwrite[index].w8(space, aoffset & si.m_addrmask, adata, submask); } } } @@ -4977,10 +5184,10 @@ void handler_entry_write::write_stub_32(address_space &space, offs_t offset, u32 switch (si.m_size) { case 8: - m_subwrite[index].w8(space, aoffset & si.m_bytemask, adata, submask); + m_subwrite[index].w8(space, aoffset & si.m_addrmask, adata, submask); break; case 16: - m_subwrite[index].w16(space, aoffset & si.m_bytemask, adata, submask); + m_subwrite[index].w16(space, aoffset & si.m_addrmask, adata, submask); break; } } @@ -5006,13 +5213,13 @@ void handler_entry_write::write_stub_64(address_space &space, offs_t offset, u64 switch (si.m_size) { case 8: - m_subwrite[index].w8(space, aoffset & si.m_bytemask, adata, submask); + m_subwrite[index].w8(space, aoffset & si.m_addrmask, adata, submask); break; case 16: - m_subwrite[index].w16(space, aoffset & si.m_bytemask, adata, submask); + m_subwrite[index].w16(space, aoffset & si.m_addrmask, adata, submask); break; case 32: - m_subwrite[index].w32(space, aoffset & si.m_bytemask, adata, submask); + m_subwrite[index].w32(space, aoffset & si.m_addrmask, adata, submask); break; } } diff --git a/src/emu/emumem.h b/src/emu/emumem.h index 19edc918aaa..70f44385d58 100644 --- a/src/emu/emumem.h +++ b/src/emu/emumem.h @@ -17,6 +17,14 @@ #ifndef MAME_EMU_EMUMEM_H #define MAME_EMU_EMUMEM_H +using s8 = std::int8_t; +using u8 = std::uint8_t; +using s16 = std::int16_t; +using u16 = std::uint16_t; +using s32 = std::int32_t; +using u32 = std::uint32_t; +using s64 = std::int64_t; +using u64 = std::uint64_t; //************************************************************************** @@ -63,21 +71,21 @@ typedef named_delegate<void (address_map &)> address_map_delegate; // struct with function pointers for accessors; use is generally discouraged unless necessary struct data_accessors { - u8 (*read_byte)(address_space &space, offs_t byteaddress); - u16 (*read_word)(address_space &space, offs_t byteaddress); - u16 (*read_word_masked)(address_space &space, offs_t byteaddress, u16 mask); - u32 (*read_dword)(address_space &space, offs_t byteaddress); - u32 (*read_dword_masked)(address_space &space, offs_t byteaddress, u32 mask); - u64 (*read_qword)(address_space &space, offs_t byteaddress); - u64 (*read_qword_masked)(address_space &space, offs_t byteaddress, u64 mask); - - void (*write_byte)(address_space &space, offs_t byteaddress, u8 data); - void (*write_word)(address_space &space, offs_t byteaddress, u16 data); - void (*write_word_masked)(address_space &space, offs_t byteaddress, u16 data, u16 mask); - void (*write_dword)(address_space &space, offs_t byteaddress, u32 data); - void (*write_dword_masked)(address_space &space, offs_t byteaddress, u32 data, u32 mask); - void (*write_qword)(address_space &space, offs_t byteaddress, u64 data); - void (*write_qword_masked)(address_space &space, offs_t byteaddress, u64 data, u64 mask); + u8 (*read_byte)(address_space &space, offs_t address); + u16 (*read_word)(address_space &space, offs_t address); + u16 (*read_word_masked)(address_space &space, offs_t address, u16 mask); + u32 (*read_dword)(address_space &space, offs_t address); + u32 (*read_dword_masked)(address_space &space, offs_t address, u32 mask); + u64 (*read_qword)(address_space &space, offs_t address); + u64 (*read_qword_masked)(address_space &space, offs_t address, u64 mask); + + void (*write_byte)(address_space &space, offs_t address, u8 data); + void (*write_word)(address_space &space, offs_t address, u16 data); + void (*write_word_masked)(address_space &space, offs_t address, u16 data, u16 mask); + void (*write_dword)(address_space &space, offs_t address, u32 data); + void (*write_dword_masked)(address_space &space, offs_t address, u32 data, u32 mask); + void (*write_qword)(address_space &space, offs_t address, u64 data); + void (*write_qword_masked)(address_space &space, offs_t address, u64 data, u64 mask); }; @@ -106,26 +114,28 @@ typedef device_delegate<void (address_space &, offs_t)> setoffset_delegate; // ======================> direct_read_data // direct_read_data contains state data for direct read access -class direct_read_data +template<int AddrShift> class direct_read_data { friend class address_table; public: + using direct_update_delegate = delegate<offs_t (direct_read_data<AddrShift> &, offs_t)>; + // direct_range is an internal class that is part of a list of start/end ranges class direct_range { public: // construction - direct_range(): m_bytestart(0),m_byteend(~0) { } + direct_range(): m_addrstart(0),m_addrend(~0) { } inline bool operator==(direct_range val) noexcept { // return true if _Left and _Right identify the same thread - return (m_bytestart == val.m_bytestart) && (m_byteend == val.m_byteend); + return (m_addrstart == val.m_addrstart) && (m_addrend == val.m_addrend); } // internal state - offs_t m_bytestart; // starting byte offset of the range - offs_t m_byteend; // ending byte offset of the range + offs_t m_addrstart; // starting offset of the range + offs_t m_addrend; // ending offset of the range }; // construction/destruction @@ -137,31 +147,34 @@ public: u8 *ptr() const { return m_ptr; } // see if an address is within bounds, or attempt to update it if not - bool address_is_valid(offs_t byteaddress) { return EXPECTED(byteaddress >= m_bytestart && byteaddress <= m_byteend) || set_direct_region(byteaddress); } + bool address_is_valid(offs_t address) { return EXPECTED(address >= m_addrstart && address <= m_addrend) || set_direct_region(address); } // force a recomputation on the next read - void force_update() { m_byteend = 0; m_bytestart = 1; } + void force_update() { m_addrend = 0; m_addrstart = 1; } void force_update(u16 if_match) { if (m_entry == if_match) force_update(); } // accessor methods - void *read_ptr(offs_t byteaddress, offs_t directxor = 0); - u8 read_byte(offs_t byteaddress, offs_t directxor = 0); - u16 read_word(offs_t byteaddress, offs_t directxor = 0); - u32 read_dword(offs_t byteaddress, offs_t directxor = 0); - u64 read_qword(offs_t byteaddress, offs_t directxor = 0); + void *read_ptr(offs_t address, offs_t directxor = 0); + u8 read_byte(offs_t address, offs_t directxor = 0); + u16 read_word(offs_t address, offs_t directxor = 0); + u32 read_dword(offs_t address, offs_t directxor = 0); + u64 read_qword(offs_t address, offs_t directxor = 0); + + void remove_intersecting_ranges(offs_t start, offs_t end); + + static constexpr offs_t offset_to_byte(offs_t offset) { return AddrShift < 0 ? offset << iabs(AddrShift) : offset >> iabs(AddrShift); } private: // internal helpers - bool set_direct_region(offs_t byteaddress); - direct_range *find_range(offs_t byteaddress, u16 &entry); - void remove_intersecting_ranges(offs_t bytestart, offs_t byteend); + bool set_direct_region(offs_t address); + direct_range *find_range(offs_t address, u16 &entry); // internal state address_space & m_space; u8 * m_ptr; // direct access data pointer - offs_t m_bytemask; // byte address mask - offs_t m_bytestart; // minimum valid byte address - offs_t m_byteend; // maximum valid byte address + offs_t m_addrmask; // address mask + offs_t m_addrstart; // minimum valid address + offs_t m_addrend; // maximum valid address u16 m_entry; // live entry std::list<direct_range> m_rangelist[TOTAL_MEMORY_BANKS]; // list of ranges for each entry }; @@ -183,21 +196,27 @@ public: // getters const char *name() const { return m_name; } endianness_t endianness() const { return m_endianness; } - int data_width() const { return m_databus_width; } - int addr_width() const { return m_addrbus_width; } + int data_width() const { return m_data_width; } + int addr_width() const { return m_addr_width; } + int addr_shift() const { return m_addr_shift; } + + // Actual alignment of the bus addresses + int alignment() const { int bytes = m_data_width / 8; return m_addr_shift < 0 ? bytes >> -m_addr_shift : bytes << m_addr_shift; } + + // Address delta to byte delta helpers + inline offs_t addr2byte(offs_t address) const { return (m_addr_shift < 0) ? (address << -m_addr_shift) : (address >> m_addr_shift); } + inline offs_t byte2addr(offs_t address) const { return (m_addr_shift > 0) ? (address << m_addr_shift) : (address >> -m_addr_shift); } // address-to-byte conversion helpers - inline offs_t addr2byte(offs_t address) const { return (m_addrbus_shift < 0) ? (address << -m_addrbus_shift) : (address >> m_addrbus_shift); } - inline offs_t addr2byte_end(offs_t address) const { return (m_addrbus_shift < 0) ? ((address << -m_addrbus_shift) | ((1 << -m_addrbus_shift) - 1)) : (address >> m_addrbus_shift); } - inline offs_t byte2addr(offs_t address) const { return (m_addrbus_shift > 0) ? (address << m_addrbus_shift) : (address >> -m_addrbus_shift); } - inline offs_t byte2addr_end(offs_t address) const { return (m_addrbus_shift > 0) ? ((address << m_addrbus_shift) | ((1 << m_addrbus_shift) - 1)) : (address >> -m_addrbus_shift); } + inline offs_t addr2byte_end(offs_t address) const { return (m_addr_shift < 0) ? ((address << -m_addr_shift) | ((1 << -m_addr_shift) - 1)) : (address >> m_addr_shift); } + inline offs_t byte2addr_end(offs_t address) const { return (m_addr_shift > 0) ? ((address << m_addr_shift) | ((1 << m_addr_shift) - 1)) : (address >> -m_addr_shift); } // state const char * m_name; endianness_t m_endianness; - u8 m_databus_width; - u8 m_addrbus_width; - s8 m_addrbus_shift; + u8 m_data_width; + u8 m_addr_width; + s8 m_addr_shift; u8 m_logaddr_width; u8 m_page_shift; bool m_is_octal; // to determine if messages/debugger will show octal or hex @@ -218,7 +237,11 @@ class address_space friend class address_table_read; friend class address_table_write; friend class address_table_setoffset; - friend class direct_read_data; + friend class direct_read_data<3>; + friend class direct_read_data<0>; + friend class direct_read_data<-1>; + friend class direct_read_data<-2>; + friend class direct_read_data<-3>; protected: // construction/destruction @@ -235,19 +258,24 @@ public: int spacenum() const { return m_spacenum; } address_map *map() const { return m_map.get(); } - direct_read_data &direct() const { return *m_direct; } + template<int AddrShift> direct_read_data<AddrShift> *direct() const { + static_assert(AddrShift == 3 || AddrShift == 0 || AddrShift == -1 || AddrShift == -2 || AddrShift == -3, "Unsupported AddrShift in direct()"); + if(AddrShift != m_config.addr_shift()) + fatalerror("Requesing direct() with address shift %d while the config says %d\n", AddrShift, m_config.addr_shift()); + return static_cast<direct_read_data<AddrShift> *>(m_direct); + } int data_width() const { return m_config.data_width(); } int addr_width() const { return m_config.addr_width(); } + int alignment() const { return m_config.alignment(); } endianness_t endianness() const { return m_config.endianness(); } + int addr_shift() const { return m_config.addr_shift(); } u64 unmap() const { return m_unmap; } bool is_octal() const { return m_config.m_is_octal; } offs_t addrmask() const { return m_addrmask; } - offs_t bytemask() const { return m_bytemask; } u8 addrchars() const { return m_addrchars; } offs_t logaddrmask() const { return m_logaddrmask; } - offs_t logbytemask() const { return m_logbytemask; } u8 logaddrchars() const { return m_logaddrchars; } // debug helpers @@ -262,41 +290,41 @@ public: // general accessors virtual void accessors(data_accessors &accessors) const = 0; - virtual void *get_read_ptr(offs_t byteaddress) = 0; - virtual void *get_write_ptr(offs_t byteaddress) = 0; + virtual void *get_read_ptr(offs_t address) = 0; + virtual void *get_write_ptr(offs_t address) = 0; // read accessors - virtual u8 read_byte(offs_t byteaddress) = 0; - virtual u16 read_word(offs_t byteaddress) = 0; - virtual u16 read_word(offs_t byteaddress, u16 mask) = 0; - virtual u16 read_word_unaligned(offs_t byteaddress) = 0; - virtual u16 read_word_unaligned(offs_t byteaddress, u16 mask) = 0; - virtual u32 read_dword(offs_t byteaddress) = 0; - virtual u32 read_dword(offs_t byteaddress, u32 mask) = 0; - virtual u32 read_dword_unaligned(offs_t byteaddress) = 0; - virtual u32 read_dword_unaligned(offs_t byteaddress, u32 mask) = 0; - virtual u64 read_qword(offs_t byteaddress) = 0; - virtual u64 read_qword(offs_t byteaddress, u64 mask) = 0; - virtual u64 read_qword_unaligned(offs_t byteaddress) = 0; - virtual u64 read_qword_unaligned(offs_t byteaddress, u64 mask) = 0; + virtual u8 read_byte(offs_t address) = 0; + virtual u16 read_word(offs_t address) = 0; + virtual u16 read_word(offs_t address, u16 mask) = 0; + virtual u16 read_word_unaligned(offs_t address) = 0; + virtual u16 read_word_unaligned(offs_t address, u16 mask) = 0; + virtual u32 read_dword(offs_t address) = 0; + virtual u32 read_dword(offs_t address, u32 mask) = 0; + virtual u32 read_dword_unaligned(offs_t address) = 0; + virtual u32 read_dword_unaligned(offs_t address, u32 mask) = 0; + virtual u64 read_qword(offs_t address) = 0; + virtual u64 read_qword(offs_t address, u64 mask) = 0; + virtual u64 read_qword_unaligned(offs_t address) = 0; + virtual u64 read_qword_unaligned(offs_t address, u64 mask) = 0; // write accessors - virtual void write_byte(offs_t byteaddress, u8 data) = 0; - virtual void write_word(offs_t byteaddress, u16 data) = 0; - virtual void write_word(offs_t byteaddress, u16 data, u16 mask) = 0; - virtual void write_word_unaligned(offs_t byteaddress, u16 data) = 0; - virtual void write_word_unaligned(offs_t byteaddress, u16 data, u16 mask) = 0; - virtual void write_dword(offs_t byteaddress, u32 data) = 0; - virtual void write_dword(offs_t byteaddress, u32 data, u32 mask) = 0; - virtual void write_dword_unaligned(offs_t byteaddress, u32 data) = 0; - virtual void write_dword_unaligned(offs_t byteaddress, u32 data, u32 mask) = 0; - virtual void write_qword(offs_t byteaddress, u64 data) = 0; - virtual void write_qword(offs_t byteaddress, u64 data, u64 mask) = 0; - virtual void write_qword_unaligned(offs_t byteaddress, u64 data) = 0; - virtual void write_qword_unaligned(offs_t byteaddress, u64 data, u64 mask) = 0; + virtual void write_byte(offs_t address, u8 data) = 0; + virtual void write_word(offs_t address, u16 data) = 0; + virtual void write_word(offs_t address, u16 data, u16 mask) = 0; + virtual void write_word_unaligned(offs_t address, u16 data) = 0; + virtual void write_word_unaligned(offs_t address, u16 data, u16 mask) = 0; + virtual void write_dword(offs_t address, u32 data) = 0; + virtual void write_dword(offs_t address, u32 data, u32 mask) = 0; + virtual void write_dword_unaligned(offs_t address, u32 data) = 0; + virtual void write_dword_unaligned(offs_t address, u32 data, u32 mask) = 0; + virtual void write_qword(offs_t address, u64 data) = 0; + virtual void write_qword(offs_t address, u64 data, u64 mask) = 0; + virtual void write_qword_unaligned(offs_t address, u64 data) = 0; + virtual void write_qword_unaligned(offs_t address, u64 data, u64 mask) = 0; // Set address. This will invoke setoffset handlers for the respective entries. - virtual void set_address(offs_t byteaddress) = 0; + virtual void set_address(offs_t address) = 0; // address-to-byte conversion helpers offs_t address_to_byte(offs_t address) const { return m_config.addr2byte(address); } @@ -386,6 +414,10 @@ public: void allocate_memory(); void locate_memory(); + void invalidate_read_caches(); + void invalidate_read_caches(u16 entry); + void invalidate_read_caches(offs_t start, offs_t end); + private: // internal helpers virtual address_table_read &read() = 0; @@ -412,15 +444,13 @@ protected: // private state const address_space_config &m_config; // configuration of this space device_t & m_device; // reference to the owning device - std::unique_ptr<address_map> m_map; // original memory map + std::unique_ptr<address_map> m_map; // original memory map offs_t m_addrmask; // physical address mask - offs_t m_bytemask; // byte-converted physical address mask offs_t m_logaddrmask; // logical address mask - offs_t m_logbytemask; // byte-converted logical address mask u64 m_unmap; // unmapped value int m_spacenum; // address space index bool m_log_unmap; // log unmapped accesses in this space? - std::unique_ptr<direct_read_data> m_direct; // fast direct-access read info + void * m_direct; // fast direct-access read info const char * m_name; // friendly name of the address space u8 m_addrchars; // number of characters to use for physical addresses u8 m_logaddrchars; // number of characters to use for logical addresses @@ -440,26 +470,26 @@ class memory_block public: // construction/destruction - memory_block(address_space &space, offs_t bytestart, offs_t byteend, void *memory = nullptr); + memory_block(address_space &space, offs_t start, offs_t end, void *memory = nullptr); ~memory_block(); // getters running_machine &machine() const { return m_machine; } - offs_t bytestart() const { return m_bytestart; } - offs_t byteend() const { return m_byteend; } + offs_t addrstart() const { return m_addrstart; } + offs_t addrend() const { return m_addrend; } u8 *data() const { return m_data; } // is the given range contained by this memory block? - bool contains(address_space &space, offs_t bytestart, offs_t byteend) const + bool contains(address_space &space, offs_t addrstart, offs_t addrend) const { - return (&space == &m_space && m_bytestart <= bytestart && m_byteend >= byteend); + return (&space == &m_space && m_addrstart <= addrstart && m_addrend >= addrend); } private: // internal state running_machine & m_machine; // need the machine to free our memory address_space & m_space; // which address space are we associated with? - offs_t m_bytestart, m_byteend; // byte-normalized start/end for verifying a match + offs_t m_addrstart, m_addrend; // start/end for verifying a match u8 * m_data; // pointer to the data for this block std::vector<u8> m_allocated; // pointer to the actually allocated block }; @@ -502,7 +532,7 @@ class memory_bank public: // construction/destruction - memory_bank(address_space &space, int index, offs_t bytestart, offs_t byteend, const char *tag = nullptr); + memory_bank(address_space &space, int index, offs_t start, offs_t end, const char *tag = nullptr); ~memory_bank(); // getters @@ -510,16 +540,16 @@ public: int index() const { return m_index; } int entry() const { return m_curentry; } bool anonymous() const { return m_anonymous; } - offs_t bytestart() const { return m_bytestart; } + offs_t addrstart() const { return m_addrstart; } void *base() const { return *m_baseptr; } const char *tag() const { return m_tag.c_str(); } const char *name() const { return m_name.c_str(); } // compare a range against our range - bool matches_exactly(offs_t bytestart, offs_t byteend) const { return (m_bytestart == bytestart && m_byteend == byteend); } - bool fully_covers(offs_t bytestart, offs_t byteend) const { return (m_bytestart <= bytestart && m_byteend >= byteend); } - bool is_covered_by(offs_t bytestart, offs_t byteend) const { return (m_bytestart >= bytestart && m_byteend <= byteend); } - bool straddles(offs_t bytestart, offs_t byteend) const { return (m_bytestart < byteend && m_byteend > bytestart); } + bool matches_exactly(offs_t addrstart, offs_t addrend) const { return (m_addrstart == addrstart && m_addrend == addrend); } + bool fully_covers(offs_t addrstart, offs_t addrend) const { return (m_addrstart <= addrstart && m_addrend >= addrend); } + bool is_covered_by(offs_t addrstart, offs_t addrend) const { return (m_addrstart >= addrstart && m_addrend <= addrend); } + bool straddles(offs_t addrstart, offs_t addrend) const { return (m_addrstart < addrend && m_addrend > addrstart); } // track and verify address space references to this bank bool references_space(const address_space &space, read_or_write readorwrite) const; @@ -543,8 +573,8 @@ private: u8 ** m_baseptr; // pointer to our base pointer in the global array u16 m_index; // array index for this handler bool m_anonymous; // are we anonymous or explicit? - offs_t m_bytestart; // byte-adjusted start offset - offs_t m_byteend; // byte-adjusted end offset + offs_t m_addrstart; // start offset + offs_t m_addrend; // end offset int m_curentry; // current entry std::vector<bank_entry> m_entry; // array of entries (dynamically allocated) std::string m_name; // friendly name for this bank @@ -791,10 +821,10 @@ private: // backing that address //------------------------------------------------- -inline void *direct_read_data::read_ptr(offs_t byteaddress, offs_t directxor) +template<int AddrShift> inline void *direct_read_data<AddrShift>::read_ptr(offs_t address, offs_t directxor) { - if (address_is_valid(byteaddress)) - return &m_ptr[(byteaddress ^ directxor) & m_bytemask]; + if (address_is_valid(address)) + return &m_ptr[offset_to_byte(((address ^ directxor) & m_addrmask))]; return nullptr; } @@ -804,11 +834,13 @@ inline void *direct_read_data::read_ptr(offs_t byteaddress, offs_t directxor) // direct_read_data class //------------------------------------------------- -inline u8 direct_read_data::read_byte(offs_t byteaddress, offs_t directxor) +template<int AddrShift> inline u8 direct_read_data<AddrShift>::read_byte(offs_t address, offs_t directxor) { - if (address_is_valid(byteaddress)) - return m_ptr[(byteaddress ^ directxor) & m_bytemask]; - return m_space.read_byte(byteaddress); + if(AddrShift <= -1) + fatalerror("Can't direct_read_data::read_byte on a memory space with address shift %d", AddrShift); + if (address_is_valid(address)) + return m_ptr[offset_to_byte((address ^ directxor) & m_addrmask)]; + return m_space.read_byte(address); } @@ -817,11 +849,13 @@ inline u8 direct_read_data::read_byte(offs_t byteaddress, offs_t directxor) // direct_read_data class //------------------------------------------------- -inline u16 direct_read_data::read_word(offs_t byteaddress, offs_t directxor) +template<int AddrShift> inline u16 direct_read_data<AddrShift>::read_word(offs_t address, offs_t directxor) { - if (address_is_valid(byteaddress)) - return *reinterpret_cast<u16 *>(&m_ptr[(byteaddress ^ directxor) & m_bytemask]); - return m_space.read_word(byteaddress); + if(AddrShift <= -2) + fatalerror("Can't direct_read_data::read_word on a memory space with address shift %d", AddrShift); + if (address_is_valid(address)) + return *reinterpret_cast<u16 *>(&m_ptr[offset_to_byte((address ^ directxor) & m_addrmask)]); + return m_space.read_word(address); } @@ -830,11 +864,13 @@ inline u16 direct_read_data::read_word(offs_t byteaddress, offs_t directxor) // direct_read_data class //------------------------------------------------- -inline u32 direct_read_data::read_dword(offs_t byteaddress, offs_t directxor) +template<int AddrShift> inline u32 direct_read_data<AddrShift>::read_dword(offs_t address, offs_t directxor) { - if (address_is_valid(byteaddress)) - return *reinterpret_cast<u32 *>(&m_ptr[(byteaddress ^ directxor) & m_bytemask]); - return m_space.read_dword(byteaddress); + if(AddrShift <= -3) + fatalerror("Can't direct_read_data::read_dword on a memory space with address shift %d", AddrShift); + if (address_is_valid(address)) + return *reinterpret_cast<u32 *>(&m_ptr[offset_to_byte((address ^ directxor) & m_addrmask)]); + return m_space.read_dword(address); } @@ -843,11 +879,11 @@ inline u32 direct_read_data::read_dword(offs_t byteaddress, offs_t directxor) // direct_read_data class //------------------------------------------------- -inline u64 direct_read_data::read_qword(offs_t byteaddress, offs_t directxor) +template<int AddrShift> inline u64 direct_read_data<AddrShift>::read_qword(offs_t address, offs_t directxor) { - if (address_is_valid(byteaddress)) - return *reinterpret_cast<u64 *>(&m_ptr[(byteaddress ^ directxor) & m_bytemask]); - return m_space.read_qword(byteaddress); + if (address_is_valid(address)) + return *reinterpret_cast<u64 *>(&m_ptr[offset_to_byte((address ^ directxor) & m_addrmask)]); + return m_space.read_qword(address); } #endif /* MAME_EMU_EMUMEM_H */ diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index 82f4c4d8030..d76804a9573 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -153,7 +153,7 @@ inline s64 recip_scale(s64 scale) inline s32 apply_scale(s32 value, s64 scale) { - return (s64(value) * scale) >> 24; + return (s64(value) * scale) / (1 << 24); } @@ -3346,10 +3346,6 @@ analog_field::analog_field(ioport_field &field) // single axis that increases from default m_scalepos = compute_scale(m_adjmax - m_adjmin, INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN); - // move from default - if (m_adjdefvalue == m_adjmax) - m_scalepos = -m_scalepos; - // make the scaling the same for easier coding when we need to scale m_scaleneg = m_scalepos; @@ -3416,25 +3412,11 @@ inline s32 analog_field::apply_min_max(s32 value) const s32 adjmin = apply_inverse_sensitivity(m_minimum); s32 adjmax = apply_inverse_sensitivity(m_maximum); - // for absolute devices, clamp to the bounds absolutely - if (!m_wraps) - { - if (value > adjmax) - value = adjmax; - else if (value < adjmin) - value = adjmin; - } - - // for relative devices, wrap around when we go past the edge - else - { - s32 range = adjmax - adjmin; - // rolls to other end when 1 position past end. - value = (value - adjmin) % range; - if (value < 0) - value += range; - value += adjmin; - } + // clamp to the bounds absolutely + if (value > adjmax) + value = adjmax; + else if (value < adjmin) + value = adjmin; return value; } @@ -3447,7 +3429,7 @@ inline s32 analog_field::apply_min_max(s32 value) const inline s32 analog_field::apply_sensitivity(s32 value) const { - return s32((s64(value) * m_sensitivity) / 100.0 + 0.5); + return lround((s64(value) * m_sensitivity) / 100.0); } @@ -3470,7 +3452,8 @@ inline s32 analog_field::apply_inverse_sensitivity(s32 value) const s32 analog_field::apply_settings(s32 value) const { // apply the min/max and then the sensitivity - value = apply_min_max(value); + if (!m_wraps) + value = apply_min_max(value); value = apply_sensitivity(value); // apply reversal if needed @@ -3488,6 +3471,18 @@ s32 analog_field::apply_settings(s32 value) const value = apply_scale(value, m_scaleneg); value += m_adjdefvalue; + // for relative devices, wrap around when we go past the edge + // (this is done last to prevent rounding errors) + if (m_wraps) + { + s32 range = m_adjmax - m_adjmin; + // rolls to other end when 1 position past end. + value = (value - m_adjmin) % range; + if (value < 0) + value += range; + value += m_adjmin; + } + return value; } @@ -3499,8 +3494,12 @@ s32 analog_field::apply_settings(s32 value) const void analog_field::frame_update(running_machine &machine) { - // clamp the previous value to the min/max range and remember it - m_previous = m_accum = apply_min_max(m_accum); + // clamp the previous value to the min/max range + if (!m_wraps) + m_accum = apply_min_max(m_accum); + + // remember the previous value in case we need to interpolate + m_previous = m_accum; // get the new raw analog value and its type input_item_class itemclass; diff --git a/src/emu/layout/README.md b/src/emu/layout/README.md index ce23c18751a..76dd0e3435e 100644 --- a/src/emu/layout/README.md +++ b/src/emu/layout/README.md @@ -1,6 +1,6 @@ # **Layout** # -Layouts files are definiton files to describe look and fell of emulated machines, and are product -of many different contributors. +Layout files are definition files to describe the look and feel of emulated machines, and are +the product of many different contributors. Licensed under [CC0 1.0 Universal (CC0 1.0)](https://creativecommons.org/publicdomain/zero/1.0/) diff --git a/src/emu/romload.cpp b/src/emu/romload.cpp index 659e6b6c210..6d2dcfec2e9 100644 --- a/src/emu/romload.cpp +++ b/src/emu/romload.cpp @@ -1275,7 +1275,7 @@ void rom_load_manager::normalize_flags_for_device(running_machine &machine, cons endian = ENDIANNESS_BIG; /* set the width */ - buswidth = spaceconfig->m_databus_width; + buswidth = spaceconfig->m_data_width; if (buswidth <= 8) width = 1; else if (buswidth <= 16) diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp index 2d5c177f9b9..52e5cefe37c 100644 --- a/src/emu/screen.cpp +++ b/src/emu/screen.cpp @@ -804,6 +804,39 @@ void screen_device::device_validity_check(validity_checker &valid) const //------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void screen_device::device_resolve_objects() +{ + // bind our handlers + m_screen_update_ind16.bind_relative_to(*owner()); + m_screen_update_rgb32.bind_relative_to(*owner()); + m_screen_vblank.resolve_safe(); + + // find the specified palette + if (m_palette_tag != nullptr && m_palette == nullptr) + { + // find our palette as a sibling device + device_t *palette = owner()->subdevice(m_palette_tag); + if (palette == nullptr) + fatalerror("Screen '%s' specifies nonexistent device '%s' as palette\n", + tag(), + m_palette_tag); + if (!palette->interface(m_palette)) + fatalerror("Screen '%s' specifies device '%s' as palette, but it has no palette interface\n", + tag(), + m_palette_tag); + + // assign our format to the palette before it starts + m_palette->m_format = format(); + } +} + + +//------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- @@ -826,13 +859,7 @@ void screen_device::device_start() } } - // bind our handlers - m_screen_update_ind16.bind_relative_to(*owner()); - m_screen_update_rgb32.bind_relative_to(*owner()); - m_screen_vblank.resolve_safe(); - // if we have a palette and it's not started, wait for it - resolve_palette(); if (m_palette != nullptr && !m_palette->device().started()) throw device_missing_dependencies(); @@ -1482,28 +1509,6 @@ void screen_device::register_screen_bitmap(bitmap_t &bitmap) //------------------------------------------------- -// resolve_palette - find the specified palette -//------------------------------------------------- - -void screen_device::resolve_palette() -{ - if (m_palette_tag != nullptr && m_palette == nullptr) - { - // find our palette as a sibling device - device_t *palette = owner()->subdevice(m_palette_tag); - if (palette == nullptr) - fatalerror("Screen '%s' specifies nonexistent device '%s' as palette\n", - tag(), - m_palette_tag); - if (!palette->interface(m_palette)) - fatalerror("Screen '%s' specifies device '%s' as palette, but it has no palette interface\n", - tag(), - m_palette_tag); - } -} - - -//------------------------------------------------- // vblank_begin - call any external callbacks to // signal the VBLANK period has begun //------------------------------------------------- diff --git a/src/emu/screen.h b/src/emu/screen.h index 3da146bac1d..c022c573316 100644 --- a/src/emu/screen.h +++ b/src/emu/screen.h @@ -239,7 +239,6 @@ public: // additional helpers void register_vblank_callback(vblank_state_delegate vblank_callback); void register_screen_bitmap(bitmap_t &bitmap); - void resolve_palette(); // internal to the video system bool update_quads(); @@ -263,6 +262,7 @@ private: // device-level overrides virtual void device_validity_check(validity_checker &valid) const override; + virtual void device_resolve_objects() override; virtual void device_start() override; virtual void device_reset() override; virtual void device_stop() override; diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp index dd70af41506..ff29b1b7442 100644 --- a/src/emu/validity.cpp +++ b/src/emu/validity.cpp @@ -514,9 +514,13 @@ void validity_checker::validate_inlines() testi32a = (testi32a & 0x0000ffff) | 0x400000; if (count_leading_zeros(testi32a) != 9) osd_printf_error("Error testing count_leading_zeros\n"); + if (count_leading_zeros(0) != 32) + osd_printf_error("Error testing count_leading_zeros\n"); testi32a = (testi32a | 0xffff0000) & ~0x400000; if (count_leading_ones(testi32a) != 9) osd_printf_error("Error testing count_leading_ones\n"); + if (count_leading_ones(0xffffffff) != 32) + osd_printf_error("Error testing count_leading_ones\n"); } @@ -1921,7 +1925,8 @@ void validity_checker::validate_devices() validate_tag(device.basetag()); // look for duplicates - if (!device_map.insert(device.tag()).second) + bool duplicate = !device_map.insert(device.tag()).second; + if (duplicate) osd_printf_error("Multiple devices with the same tag defined\n"); // check for device-specific validity check @@ -1932,7 +1937,7 @@ void validity_checker::validate_devices() // if it's a slot, iterate over possible cards (don't recurse, or you'll stack infinite tee connectors) device_slot_interface *const slot = dynamic_cast<device_slot_interface *>(&device); - if (slot != nullptr && !slot->fixed()) + if (slot != nullptr && !slot->fixed() && !duplicate) { for (auto &option : slot->option_list()) { diff --git a/src/frontend/mame/cheat.cpp b/src/frontend/mame/cheat.cpp index 06d87596e68..1ac5039fa7f 100644 --- a/src/frontend/mame/cheat.cpp +++ b/src/frontend/mame/cheat.cpp @@ -1069,8 +1069,8 @@ cheat_manager::cheat_manager(running_machine &machine) // create a global symbol table m_symtable.add("frame", symbol_table::READ_ONLY, &m_framecount); - m_symtable.add("frombcd", nullptr, 1, 1, execute_frombcd); - m_symtable.add("tobcd", nullptr, 1, 1, execute_tobcd); + m_symtable.add("frombcd", 1, 1, execute_frombcd); + m_symtable.add("tobcd", 1, 1, execute_tobcd); // we rely on the debugger expression callbacks; if the debugger isn't // enabled, we must jumpstart them manually @@ -1320,7 +1320,7 @@ std::string cheat_manager::quote_expression(const parsed_expression &expression) // execute_frombcd - convert a value from BCD //------------------------------------------------- -uint64_t cheat_manager::execute_frombcd(symbol_table &table, void *ref, int params, const uint64_t *param) +uint64_t cheat_manager::execute_frombcd(symbol_table &table, int params, const uint64_t *param) { uint64_t value(param[0]); uint64_t multiplier(1); @@ -1340,7 +1340,7 @@ uint64_t cheat_manager::execute_frombcd(symbol_table &table, void *ref, int para // execute_tobcd - convert a value to BCD //------------------------------------------------- -uint64_t cheat_manager::execute_tobcd(symbol_table &table, void *ref, int params, const uint64_t *param) +uint64_t cheat_manager::execute_tobcd(symbol_table &table, int params, const uint64_t *param) { uint64_t value(param[0]); uint64_t result(0); diff --git a/src/frontend/mame/cheat.h b/src/frontend/mame/cheat.h index b685dba2c33..d05890c7152 100644 --- a/src/frontend/mame/cheat.h +++ b/src/frontend/mame/cheat.h @@ -327,8 +327,8 @@ public: // global helpers static std::string quote_expression(parsed_expression const &expression); - static uint64_t execute_frombcd(symbol_table &table, void *ref, int params, uint64_t const *param); - static uint64_t execute_tobcd(symbol_table &table, void *ref, int params, uint64_t const *param); + static uint64_t execute_frombcd(symbol_table &table, int params, uint64_t const *param); + static uint64_t execute_tobcd(symbol_table &table, int params, uint64_t const *param); private: // internal helpers diff --git a/src/frontend/mame/clifront.cpp b/src/frontend/mame/clifront.cpp index 91a4df81b3c..a219ec614c7 100644 --- a/src/frontend/mame/clifront.cpp +++ b/src/frontend/mame/clifront.cpp @@ -719,7 +719,15 @@ void cli_frontend::listdevices(const std::vector<std::string> &args) // sort them by tag std::sort(device_list.begin(), device_list.end(), [](device_t *dev1, device_t *dev2) { - return strcmp(dev1->tag(), dev2->tag()) < 0; + // end of string < ':' < '0' + const char *tag1 = dev1->tag(); + const char *tag2 = dev2->tag(); + while (*tag1 == *tag2 && *tag1 != '\0' && *tag2 != '\0') + { + tag1++; + tag2++; + } + return (*tag1 == ':' ? ' ' : *tag1) < (*tag2 == ':' ? ' ' : *tag2); }); // dump the results diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp index 610b1947210..2c81f5f9a4b 100644 --- a/src/frontend/mame/luaengine.cpp +++ b/src/frontend/mame/luaengine.cpp @@ -828,7 +828,7 @@ void lua_engine::initialize() [](emu_file &file, const char *path, u32 flags) { new (&file) emu_file(path, flags); }, [](emu_file &file, const char *mode) { int flags = 0; - for(int i = 0; i < 2; i++) // limit to three chars + for(int i = 0; i < 3 && mode[i]; i++) // limit to three chars { switch(mode[i]) { @@ -847,7 +847,7 @@ void lua_engine::initialize() }, [](emu_file &file, const char *path, const char* mode) { int flags = 0; - for(int i = 0; i < 2; i++) // limit to three chars + for(int i = 0; i < 3 && mode[i]; i++) // limit to three chars { switch(mode[i]) { @@ -1454,8 +1454,8 @@ void lua_engine::initialize() for (address_map_entry &entry : space.map()->m_entrylist) { sol::table mapentry = sol().create_table(); - mapentry["offset"] = space.address_to_byte(entry.m_addrstart) & space.bytemask(); - mapentry["endoff"] = space.address_to_byte(entry.m_addrend) & space.bytemask(); + mapentry["offset"] = space.address_to_byte(entry.m_addrstart) & space.addrmask(); + mapentry["endoff"] = space.address_to_byte(entry.m_addrend) & space.addrmask(); mapentry["readtype"] = entry.m_read.m_type; mapentry["writetype"] = entry.m_write.m_type; map.add(mapentry); @@ -1587,8 +1587,8 @@ void lua_engine::initialize() * input:code_name(code) - get code friendly name * input:seq_from_tokens(tokens) - get input_seq for multiple space separated KEYCODE_* string tokens * input:seq_pressed(seq) - get pressed state for input_seq - * input:seq_to_token(seq) - get KEYCODE_* string tokens for seq - * input:seq_to_name(seq) - get seq friendly name + * input:seq_to_tokens(seq) - get KEYCODE_* string tokens for seq + * input:seq_name(seq) - get seq friendly name */ sol().registry().new_usertype<input_manager>("input", "new", sol::no_constructor, diff --git a/src/frontend/mame/ui/filemngr.cpp b/src/frontend/mame/ui/filemngr.cpp index 8b4c758c69d..07842f423aa 100644 --- a/src/frontend/mame/ui/filemngr.cpp +++ b/src/frontend/mame/ui/filemngr.cpp @@ -154,7 +154,9 @@ void menu_file_manager::populate(float &customtop, float &custombottom) } } item_append(menu_item_type::SEPARATOR); - item_append("Reset", "", 0, (void *)1); + + if (m_warnings.empty() || m_curr_selected) + item_append("Reset", "", 0, (void *)1); custombottom = ui().get_line_height() + 3.0f * UI_BOX_TB_BORDER; } @@ -172,8 +174,7 @@ void menu_file_manager::handle() { if ((uintptr_t)event->itemref == 1) { - if (m_curr_selected) - machine().schedule_hard_reset(); + machine().schedule_hard_reset(); } else { diff --git a/src/frontend/mame/ui/viewgfx.cpp b/src/frontend/mame/ui/viewgfx.cpp index d1734b172af..560dc30d0f9 100644 --- a/src/frontend/mame/ui/viewgfx.cpp +++ b/src/frontend/mame/ui/viewgfx.cpp @@ -1300,7 +1300,7 @@ static void tilemap_update_bitmap(running_machine &machine, ui_gfx_state &state, std::swap(width, height); // realloc the bitmap if it is too small - if (state.bitmap_dirty || state.bitmap == nullptr || state.texture == nullptr || state.bitmap->width() != width || state.bitmap->height() != height) + if (state.bitmap == nullptr || state.texture == nullptr || state.bitmap->width() != width || state.bitmap->height() != height) { // free the old stuff machine.render().texture_free(state.texture); @@ -1318,6 +1318,7 @@ static void tilemap_update_bitmap(running_machine &machine, ui_gfx_state &state, // handle the redraw if (state.bitmap_dirty) { + state.bitmap->fill(0); tilemap_t *tilemap = machine.tilemap().find(state.tilemap.which); tilemap->draw_debug(*machine.first_screen(), *state.bitmap, state.tilemap.xoffs, state.tilemap.yoffs, state.tilemap.flags); diff --git a/src/lib/formats/jvc_dsk.cpp b/src/lib/formats/jvc_dsk.cpp index 3c230eed3cd..d2e7e503d3b 100644 --- a/src/lib/formats/jvc_dsk.cpp +++ b/src/lib/formats/jvc_dsk.cpp @@ -84,16 +84,20 @@ bool jvc_format::parse_header(io_generic *io, int &header_size, int &tracks, int int os9_total_sectors = pick_integer_be(os9_header, 0x00, 3); int os9_heads = BIT(os9_header[0x10], 0) ? 2 : 1; int os9_sectors = pick_integer_be(os9_header, 0x11, 2); - int os9_tracks = os9_total_sectors / os9_sectors / os9_heads; - // now let's see if we have valid info - if ((os9_tracks * os9_heads * os9_sectors * 256) == size) + if (os9_total_sectors > 0 && os9_heads > 0 && os9_sectors > 0) { - tracks = os9_tracks; - heads = os9_heads; - sectors = os9_sectors; + int os9_tracks = os9_total_sectors / os9_sectors / os9_heads; - osd_printf_verbose("OS-9 format disk image detected.\n"); + // now let's see if we have valid info + if ((os9_tracks * os9_heads * os9_sectors * 256) == size) + { + tracks = os9_tracks; + heads = os9_heads; + sectors = os9_sectors; + + osd_printf_verbose("OS-9 format disk image detected.\n"); + } } } diff --git a/src/lib/formats/pc_dsk.cpp b/src/lib/formats/pc_dsk.cpp index fa8f72f67d2..e4d7e02f47d 100644 --- a/src/lib/formats/pc_dsk.cpp +++ b/src/lib/formats/pc_dsk.cpp @@ -193,6 +193,10 @@ const pc_format::format pc_format::formats[] = { floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM, 2000, 9, 40, 2, 512, {}, 1, {}, 80, 50, 22, 80 }, + { /* 360K 5 1/4 inch double density, 41 tracks */ + floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM, + 2000, 9, 41, 2, 512, {}, 1, {}, 80, 50, 22, 80 + }, { /* 360K 5 1/4 inch double density, 42 tracks */ floppy_image::FF_525, floppy_image::DSDD, floppy_image::MFM, 2000, 9, 42, 2, 512, {}, 1, {}, 80, 50, 22, 80 diff --git a/src/lib/util/disasmintf.cpp b/src/lib/util/disasmintf.cpp new file mode 100644 index 00000000000..9699f68e823 --- /dev/null +++ b/src/lib/util/disasmintf.cpp @@ -0,0 +1,47 @@ +#include "disasmintf.h" + +util::u32 util::disasm_interface::interface_flags() const +{ + return 0; +} + +util::u32 util::disasm_interface::page_address_bits() const +{ + throw ("unimplemented page_address_bits called"); +} + +util::u32 util::disasm_interface::page2_address_bits() const +{ + throw ("unimplemented page2_address_bits called"); +} + +util::disasm_interface::offs_t util::disasm_interface::pc_linear_to_real(offs_t pc) const +{ + throw ("unimplemented pc_linear_to_real called"); +} + +util::disasm_interface::offs_t util::disasm_interface::pc_real_to_linear(offs_t pc) const +{ + throw ("unimplemented pc_real_to_linear called"); +} + +util::u8 util::disasm_interface::decrypt8(u8 value, offs_t pc, bool opcode) const +{ + throw ("unimplemented decrypt8 called"); +} + +util::u16 util::disasm_interface::decrypt16(u16 value, offs_t pc, bool opcode) const +{ + throw ("unimplemented decrypt16 called"); +} + +util::u32 util::disasm_interface::decrypt32(u32 value, offs_t pc, bool opcode) const +{ + throw ("unimplemented decrypt32 called"); +} + +util::u64 util::disasm_interface::decrypt64(u64 value, offs_t pc, bool opcode) const +{ + throw ("unimplemented decrypt64 called"); +} + diff --git a/src/lib/util/disasmintf.h b/src/lib/util/disasmintf.h new file mode 100644 index 00000000000..908bd762bdb --- /dev/null +++ b/src/lib/util/disasmintf.h @@ -0,0 +1,69 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert +/*************************************************************************** + + disasmintf.h + + Generic disassembler interface. + +***************************************************************************/ + +#pragma once + +#ifndef MAME_UTIL_DISASMINTF_H +#define MAME_UTIL_DISASMINTF_H + +#include "coretmpl.h" + +namespace util { +// class implementing a disassembler +class disasm_interface +{ +public: + using offs_t = u32; + + // Disassembler constants for the return value + static constexpr u32 SUPPORTED = 0x80000000; // are disassembly flags supported? + static constexpr u32 STEP_OUT = 0x40000000; // this instruction should be the end of a step out sequence + static constexpr u32 STEP_OVER = 0x20000000; // this instruction should be stepped over by setting a breakpoint afterwards + static constexpr u32 OVERINSTMASK = 0x18000000; // number of extra instructions to skip when stepping over + static constexpr u32 OVERINSTSHIFT = 27; // bits to shift after masking to get the value + static constexpr u32 LENGTHMASK = 0x0000ffff; // the low 16-bits contain the actual length + + static inline u32 step_over_extra(u32 x) { + return x << OVERINSTSHIFT; + } + + class data_buffer { + public: + virtual ~data_buffer() = default; + virtual u8 r8 (offs_t pc) const = 0; + virtual u16 r16(offs_t pc) const = 0; + virtual u32 r32(offs_t pc) const = 0; + virtual u64 r64(offs_t pc) const = 0; + }; + + enum { + NONLINEAR_PC = 0x00000001, + PAGED = 0x00000002, + PAGED2LEVEL = 0x00000006, + INTERNAL_DECRYPTION = 0x00000008, + SPLIT_DECRYPTION = 0x00000018 + }; + + virtual u32 interface_flags() const; + virtual u32 page_address_bits() const; + virtual u32 page2_address_bits() const; + virtual offs_t pc_linear_to_real(offs_t pc) const; + virtual offs_t pc_real_to_linear(offs_t pc) const; + virtual u8 decrypt8 (u8 value, offs_t pc, bool opcode) const; + virtual u16 decrypt16(u16 value, offs_t pc, bool opcode) const; + virtual u32 decrypt32(u32 value, offs_t pc, bool opcode) const; + virtual u64 decrypt64(u64 value, offs_t pc, bool opcode) const; + + virtual u32 opcode_alignment() const = 0; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) = 0; +}; +} + +#endif diff --git a/src/mame/audio/arcadia.cpp b/src/mame/audio/arcadia.cpp index 796d8e816e5..b1c41fff35d 100644 --- a/src/mame/audio/arcadia.cpp +++ b/src/mame/audio/arcadia.cpp @@ -42,7 +42,7 @@ // device type definition -DEFINE_DEVICE_TYPE(ARCADIA_SOUND, arcadia_sound_device, "arcadia_sound", "Arcadia Audio Custom") +DEFINE_DEVICE_TYPE(ARCADIA_SOUND, arcadia_sound_device, "arcadia_sound", "Arcadia Custom Sound") //------------------------------------------------- // arcadia_sound_device - constructor diff --git a/src/mame/audio/cage.cpp b/src/mame/audio/cage.cpp index 55bcbde77bb..aa41bd9840e 100644 --- a/src/mame/audio/cage.cpp +++ b/src/mame/audio/cage.cpp @@ -237,7 +237,7 @@ void atari_cage_device::update_dma_state(address_space &space) inc = (tms32031_io_regs[DMA_GLOBAL_CTL] >> 4) & 1; for (i = 0; i < tms32031_io_regs[DMA_TRANSFER_COUNT]; i++) { - sound_data[i % STACK_SOUND_BUFSIZE] = space.read_dword(addr * 4); + sound_data[i % STACK_SOUND_BUFSIZE] = space.read_dword(addr); addr += inc; if (i % STACK_SOUND_BUFSIZE == STACK_SOUND_BUFSIZE - 1) dmadac_transfer(&m_dmadac[0], DAC_BUFFER_CHANNELS, 1, DAC_BUFFER_CHANNELS, STACK_SOUND_BUFSIZE / DAC_BUFFER_CHANNELS, sound_data); diff --git a/src/mame/audio/cps3.cpp b/src/mame/audio/cps3.cpp index 0c5c3c764dd..950c30e4fc2 100644 --- a/src/mame/audio/cps3.cpp +++ b/src/mame/audio/cps3.cpp @@ -11,7 +11,7 @@ // device type definition -DEFINE_DEVICE_TYPE(CPS3, cps3_sound_device, "cps3_custom", "CPS3 Audio Custom") +DEFINE_DEVICE_TYPE(CPS3, cps3_sound_device, "cps3_custom", "CPS3 Custom Sound") //************************************************************************** diff --git a/src/mame/audio/dai_snd.cpp b/src/mame/audio/dai_snd.cpp index 3e59797b817..ccfd41cf33a 100644 --- a/src/mame/audio/dai_snd.cpp +++ b/src/mame/audio/dai_snd.cpp @@ -14,7 +14,7 @@ #include "dai_snd.h" // device type definition -DEFINE_DEVICE_TYPE(DAI_SOUND, dai_sound_device, "dai_sound", "DAI Audio Custom") +DEFINE_DEVICE_TYPE(DAI_SOUND, dai_sound_device, "dai_sound", "DAI Custom Sound") //------------------------------------------------- diff --git a/src/mame/audio/dcs.cpp b/src/mame/audio/dcs.cpp index f90d5a83c62..030d1c15f9f 100644 --- a/src/mame/audio/dcs.cpp +++ b/src/mame/audio/dcs.cpp @@ -1736,19 +1736,19 @@ void dcs_audio_device::reset_timer() { /* Road Burners: @ 28: JMP $0032 18032F, same code at $32 */ - if (m_program->read_dword(0x18*4) == 0x0c0030 && /* ENA SEC_REG */ - m_program->read_dword(0x19*4) == 0x804828 && /* SI = DM($0482) */ - m_program->read_dword(0x1a*4) == 0x904828 && /* DM($0482) = SI */ - m_program->read_dword(0x1b*4) == 0x0C0020 && /* DIS SEC_REG */ - m_program->read_dword(0x1c*4) == 0x0A001F) /* RTI */ + if (m_program->read_dword(0x18) == 0x0c0030 && /* ENA SEC_REG */ + m_program->read_dword(0x19) == 0x804828 && /* SI = DM($0482) */ + m_program->read_dword(0x1a) == 0x904828 && /* DM($0482) = SI */ + m_program->read_dword(0x1b) == 0x0C0020 && /* DIS SEC_REG */ + m_program->read_dword(0x1c) == 0x0A001F) /* RTI */ { m_timer_ignore = true; } else if ( // ADSP 2181 (DSIO and DENVER) - m_program->read_dword(0x28*4) == 0x18032F && /* JUMP $0032 */ - m_program->read_dword(0x32*4) == 0x0c0030 && /* ENA SEC_REG */ - m_program->read_dword(0x33*4) == 0x014828 && /* SI = IO($482) */ - m_program->read_dword(0x34*4) == 0x01C828) /* IO($482) = SI */ + m_program->read_dword(0x28) == 0x18032F && /* JUMP $0032 */ + m_program->read_dword(0x32) == 0x0c0030 && /* ENA SEC_REG */ + m_program->read_dword(0x33) == 0x014828 && /* SI = IO($482) */ + m_program->read_dword(0x34) == 0x01C828) /* IO($482) = SI */ { m_timer_ignore = true; } @@ -1944,7 +1944,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::dcs_irq ) for (i = 0; i < count; i++) { - buffer[i] = m_data->read_word(reg * 2); + buffer[i] = m_data->read_word(reg); reg += m_incs; } @@ -1962,7 +1962,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( dcs_audio_device::dcs_irq ) /* generate the (internal, thats why the pulse) irq */ if (LOG_DCS_IO) logerror("dcs_irq: Genrating interrupt\n"); - m_cpu->machine().driver_data()->generic_pulse_irq_line(*m_cpu, ADSP2105_IRQ1, 1); + m_cpu->pulse_input_line(ADSP2105_IRQ1, m_cpu->minimum_quantum_time()); } /* store it */ @@ -2280,10 +2280,10 @@ int dcs_audio_device::preprocess_stage_1(uint16_t data) if (transfer.writes_left & 1) transfer.temp = data; else - m_program->write_dword(transfer.start++ * 4, (transfer.temp << 8) | (data & 0xff)); + m_program->write_dword(transfer.start++, (transfer.temp << 8) | (data & 0xff)); } else - m_data->write_word(transfer.start++ * 2, data); + m_data->write_word(transfer.start++, data); /* if we're done, start a timer to send the response words */ if (transfer.state == 0) @@ -2628,8 +2628,8 @@ MACHINE_CONFIG_MEMBER( dcs2_audio_dsio_device::device_add_mconfig ) MCFG_DEVICE_ADD("data_map_bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(dsio_rambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(14) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_TIMER_DEVICE_ADD("dcs_reg_timer", DEVICE_SELF, dcs_audio_device, dcs_irq) @@ -2669,8 +2669,8 @@ MACHINE_CONFIG_MEMBER( dcs2_audio_denver_device::device_add_mconfig ) MCFG_DEVICE_ADD("data_map_bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(denver_rambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(14) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_TIMER_DEVICE_ADD("dcs_reg_timer", DEVICE_SELF, dcs_audio_device, dcs_irq) diff --git a/src/mame/audio/depthch.cpp b/src/mame/audio/depthch.cpp index 18a23c25b58..22b59fe0aea 100644 --- a/src/mame/audio/depthch.cpp +++ b/src/mame/audio/depthch.cpp @@ -25,6 +25,7 @@ static const char *const depthch_sample_names[] = "longex", "shortex", "spray", + "bonus", "sonar", nullptr }; @@ -36,6 +37,7 @@ enum SND_LONGEXPL = 0, SND_SHRTEXPL, SND_SPRAY, + SND_BONUS, SND_SONAR }; @@ -74,6 +76,9 @@ WRITE8_MEMBER( vicdual_state::depthch_audio_w ) if ( bitsGoneLow & OUT_PORT_1_SONAR ) { STOP( m_samples, SND_SONAR ); + + // bonus sound on same line as sonar + PLAY( m_samples, SND_BONUS, 0 ); } } @@ -82,7 +87,7 @@ MACHINE_CONFIG_START( depthch_audio ) /* samples */ MCFG_SOUND_ADD("samples", SAMPLES, 0) - MCFG_SAMPLES_CHANNELS(4) + MCFG_SAMPLES_CHANNELS(5) MCFG_SAMPLES_NAMES(depthch_sample_names) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) MACHINE_CONFIG_END diff --git a/src/mame/audio/dsbz80.cpp b/src/mame/audio/dsbz80.cpp index 34d3cc33938..245d5d52032 100644 --- a/src/mame/audio/dsbz80.cpp +++ b/src/mame/audio/dsbz80.cpp @@ -54,6 +54,7 @@ MACHINE_CONFIG_MEMBER( dsbz80_device::device_add_mconfig ) MCFG_CLOCK_ADD("uart_clock", 500000) // 16 times 31.25MHz (standard Sega/MIDI sound data rate) MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("uart", i8251_device, write_rxc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart", i8251_device, write_txc)) MACHINE_CONFIG_END //************************************************************************** diff --git a/src/mame/audio/flower.cpp b/src/mame/audio/flower.cpp new file mode 100644 index 00000000000..24c1db54ed5 --- /dev/null +++ b/src/mame/audio/flower.cpp @@ -0,0 +1,273 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese +/*************************************************************************** + + Flower custom sound chip + + Similar to Wiping and Namco 15xx designs + + TODO: + - several unknown registers (effects and unknown register tied to repeat port); + - repeat certainly needs a cutoff, which is unknown about how it works; + +***************************************************************************/ + +#include "emu.h" +#include "flower.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(FLOWER_CUSTOM, flower_sound_device, "flower_sound", "Flower Custom Sound") + +// TODO: AM_SELECT unsupported by DEVICE_ADDRESS_MAP, so we need a trampoline here +static ADDRESS_MAP_START( regs_map, AS_IO, 8, flower_sound_device ) + AM_RANGE(0x00, 0x03) AM_SELECT(0x38) AM_WRITE(frequency_w) + AM_RANGE(0x04, 0x04) AM_SELECT(0x38) AM_WRITE(repeat_w) + AM_RANGE(0x05, 0x05) AM_SELECT(0x38) AM_WRITE(unk_w) + AM_RANGE(0x07, 0x07) AM_SELECT(0x38) AM_WRITE(volume_w) + AM_RANGE(0x40, 0x45) AM_SELECT(0x38) AM_WRITE(start_address_w) + AM_RANGE(0x47, 0x47) AM_SELECT(0x38) AM_WRITE(sample_trigger_w) +ADDRESS_MAP_END + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// flower_sound_device - constructor +//------------------------------------------------- + +flower_sound_device::flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, FLOWER_CUSTOM, tag, owner, clock), + device_sound_interface(mconfig, *this), + device_memory_interface(mconfig, *this), + m_io_space_config("io", ENDIANNESS_LITTLE, 8, 7, 0, *ADDRESS_MAP_NAME(regs_map)), + m_stream(nullptr), + m_mixer_table(nullptr), + m_mixer_lookup(nullptr), + m_mixer_buffer(nullptr), + m_last_channel(nullptr) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void flower_sound_device::device_start() +{ + m_iospace = &space(AS_IO); + m_stream = machine().sound().stream_alloc(*this, 0, 1, clock()/2); + + m_mixer_buffer = make_unique_clear<short[]>(clock()/2); + make_mixer_table(MAX_VOICES, defgain); + + m_last_channel = m_channel_list + MAX_VOICES; + + m_sample_rom = machine().root_device().memregion("samples")->base(); + m_volume_rom = machine().root_device().memregion("soundvol")->base(); + + for (int i = 0; i < MAX_VOICES; i++) + { + save_item(NAME(m_channel_list[i].start_address), i); + save_item(NAME(m_channel_list[i].position), i); + save_item(NAME(m_channel_list[i].frequency), i); + save_item(NAME(m_channel_list[i].volume), i); + save_item(NAME(m_channel_list[i].volume_bank), i); + save_item(NAME(m_channel_list[i].effect), i); + save_item(NAME(m_channel_list[i].enable), i); + save_item(NAME(m_channel_list[i].repeat), i); + + // assign a channel number (debugger aid) + m_channel_list[i].channel_number = i; + } +} + + +/* build a table to divide by the number of voices; gain is specified as gain*16 */ +void flower_sound_device::make_mixer_table(int voices, int gain) +{ + /* allocate memory */ + m_mixer_table = make_unique_clear<int16_t[]>(256 * voices); + + /* find the middle of the table */ + m_mixer_lookup = m_mixer_table.get() + (128 * voices); + + /* fill in the table - 16 bit case */ + for (int i = 0; i < voices * 128; i++) + { + int val = i * gain * 16 / voices; + if (val > 32767) val = 32767; + m_mixer_lookup[ i] = val; + m_mixer_lookup[-i] = -val; + } +} + + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void flower_sound_device::device_reset() +{ + for (fl_sound_channel *voice = m_channel_list; voice < m_last_channel; voice++) + { + voice->start_address = 0; + voice->position = 0; + voice->volume = 0; + voice->enable = false; + voice->repeat = false; + } +} + +void flower_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + stream_sample_t *buffer = outputs[0]; + short *mix; + uint8_t raw_sample; + + memset(m_mixer_buffer.get(), 0, samples * sizeof(short)); + + for (fl_sound_channel *voice = m_channel_list; voice < m_last_channel; voice++) + { + int ch_volume = voice->volume; + int ch_frequency = voice->frequency; + + if (voice->enable == false) + continue; + + mix = m_mixer_buffer.get(); + + for (int i = 0; i < samples; i++) + { + if (voice->repeat == true) + { + raw_sample = m_sample_rom[((voice->start_address >> 7) & 0x7e00) | ((voice->position >> 7) & 0x1ff)]; + // guess: cut off after a number of repetitions + if ((voice->position >> 7) & 0x20000) + { + voice->enable = false; + break; + } + } + else + { + raw_sample = m_sample_rom[((voice->start_address + voice->position) >> 7) & 0x7fff]; + if (raw_sample == 0xff) + { + voice->enable = false; + break; + } + } + ch_volume |= voice->volume_bank; + + *mix++ += m_volume_rom[(ch_volume << 8 | raw_sample) & 0x3fff] - 0x80; + voice->position += ch_frequency; + } + } + + /* mix it down */ + mix = m_mixer_buffer.get(); + for (int i = 0; i < samples; i++) + *buffer++ = m_mixer_lookup[*mix++]; +} + +//------------------------------------------------- +// memory_space_config - return a description of +// any address spaces owned by this device +//------------------------------------------------- + +device_memory_interface::space_config_vector flower_sound_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_IO, &m_io_space_config) + }; +} + +//************************************************************************** +// READ/WRITE HANDLERS +//************************************************************************** + +WRITE8_MEMBER( flower_sound_device::lower_write ) +{ + m_stream->update(); + m_iospace->write_byte(offset,data); +} + +WRITE8_MEMBER( flower_sound_device::upper_write ) +{ + m_stream->update(); + m_iospace->write_byte(offset|0x40,data); +} + +WRITE8_MEMBER( flower_sound_device::frequency_w ) +{ + uint8_t ch = (offset >> 3) & 0x7; + fl_sound_channel *voice; + + voice = &m_channel_list[ch]; + + voice->raw_frequency[offset & 3] = data & 0xf; + + voice->frequency = voice->raw_frequency[2] << 12; + voice->frequency|= voice->raw_frequency[3] << 8; + voice->frequency|= voice->raw_frequency[0] << 4; + voice->frequency|= voice->raw_frequency[1] << 0; +} + +WRITE8_MEMBER( flower_sound_device::repeat_w ) +{ + uint8_t ch = (offset >> 3) & 0x7; + fl_sound_channel *voice; + + voice = &m_channel_list[ch]; + voice->repeat = BIT(data,4); +} + +WRITE8_MEMBER( flower_sound_device::unk_w ) +{ + // same as above? +} + +WRITE8_MEMBER( flower_sound_device::volume_w ) +{ + uint8_t ch = (offset >> 3) & 0x7; + fl_sound_channel *voice; + + voice = &m_channel_list[ch]; + voice->volume = data >> 4; +} + +WRITE8_MEMBER( flower_sound_device::start_address_w ) +{ + uint8_t ch = (offset >> 3) & 0x7; + fl_sound_channel *voice; + + voice = &m_channel_list[ch]; + voice->start_nibbles[offset & 7] = data & 0xf; + if ((offset & 7) == 4) + voice->effect = data >> 4; +} + +WRITE8_MEMBER( flower_sound_device::sample_trigger_w ) +{ + uint8_t ch = (offset >> 3) & 0x7; + fl_sound_channel *voice; + + voice = &m_channel_list[ch]; + + voice->enable = true; + voice->volume_bank = (data & 3) << 4; + voice->start_address = 0; + voice->position = 0; + for (int i = 5; i >= 0; i--) + { + voice->start_address = (voice->start_address << 4) | voice->start_nibbles[i]; + } +} diff --git a/src/mame/audio/flower.h b/src/mame/audio/flower.h new file mode 100644 index 00000000000..7c3f02da773 --- /dev/null +++ b/src/mame/audio/flower.h @@ -0,0 +1,92 @@ +// license:BSD-3-Clause +// copyright-holders:Angelo Salese +/*************************************************************************** + + Flower custom sound chip + +***************************************************************************/ + +#ifndef MAME_AUDIO_FLOWER_H +#define MAME_AUDIO_FLOWER_H + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> flower_sound_device + +class flower_sound_device : public device_t, + public device_sound_interface, + public device_memory_interface +{ +public: + // construction/destruction + flower_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // I/O operations + DECLARE_WRITE8_MEMBER( lower_write ); + DECLARE_WRITE8_MEMBER( upper_write ); +// virtual DECLARE_ADDRESS_MAP(lower_map, 8); +// virtual DECLARE_ADDRESS_MAP(upper_map, 8); + DECLARE_WRITE8_MEMBER( frequency_w ); + DECLARE_WRITE8_MEMBER( repeat_w ); + DECLARE_WRITE8_MEMBER( unk_w ); + DECLARE_WRITE8_MEMBER( volume_w ); + DECLARE_WRITE8_MEMBER( start_address_w ); + DECLARE_WRITE8_MEMBER( sample_trigger_w ); + +protected: + // device-level overrides + //virtual void device_validity_check(validity_checker &valid) const override; + //virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + virtual space_config_vector memory_space_config() const override; + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + + address_space *m_iospace; +private: + + const address_space_config m_io_space_config; + sound_stream *m_stream; + + static constexpr unsigned MAX_VOICES = 8; + static constexpr int defgain = 48; + + std::unique_ptr<int16_t[]> m_mixer_table; + int16_t *m_mixer_lookup; + std::unique_ptr<short[]> m_mixer_buffer; + + struct fl_sound_channel + { + uint8_t start_nibbles[6]; + uint8_t raw_frequency[4]; + uint32_t start_address; + uint32_t position; + uint16_t frequency; + uint8_t volume; + uint8_t volume_bank; + uint8_t effect; + bool enable; + bool repeat; + int channel_number; + }; + + /* data about the sound system */ + fl_sound_channel m_channel_list[MAX_VOICES]; + fl_sound_channel *m_last_channel; + + void make_mixer_table(int voices, int gain); + + const uint8_t *m_sample_rom; + const uint8_t *m_volume_rom; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(FLOWER_CUSTOM, flower_sound_device) + + +#endif // MAME_AUDIO_FLOWER_H diff --git a/src/mame/audio/galaxian.cpp b/src/mame/audio/galaxian.cpp index 35d0bf0d736..9efa49df63a 100644 --- a/src/mame/audio/galaxian.cpp +++ b/src/mame/audio/galaxian.cpp @@ -386,7 +386,7 @@ static DISCRETE_SOUND_START(mooncrst) DISCRETE_MIXER7(NODE_280, 1, NODE_133_00, NODE_133_02, NODE_133_02,NODE_133_03, NODE_120, NODE_157, NODE_182, &mooncrst_mixer_desc) DISCRETE_SOUND_END -DEFINE_DEVICE_TYPE(GALAXIAN, galaxian_sound_device, "galaxian_sound", "Galaxian Audio Custom") +DEFINE_DEVICE_TYPE(GALAXIAN, galaxian_sound_device, "galaxian_sound", "Galaxian Custom Sound") galaxian_sound_device::galaxian_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, GALAXIAN, tag, owner, clock) diff --git a/src/mame/audio/geebee.cpp b/src/mame/audio/geebee.cpp index 8400b80ea04..c4088b88736 100644 --- a/src/mame/audio/geebee.cpp +++ b/src/mame/audio/geebee.cpp @@ -13,7 +13,7 @@ #include "audio/geebee.h" -DEFINE_DEVICE_TYPE(GEEBEE, geebee_sound_device, "geebee_sound", "Gee Bee Audio Custom") +DEFINE_DEVICE_TYPE(GEEBEE, geebee_sound_device, "geebee_sound", "Gee Bee Custom Sound") geebee_sound_device::geebee_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, GEEBEE, tag, owner, clock), diff --git a/src/mame/audio/gomoku.cpp b/src/mame/audio/gomoku.cpp index 46b81b532d2..0f9c804c216 100644 --- a/src/mame/audio/gomoku.cpp +++ b/src/mame/audio/gomoku.cpp @@ -16,7 +16,7 @@ static constexpr int defgain = 48; // device type definition -DEFINE_DEVICE_TYPE(GOMOKU, gomoku_sound_device, "gomoku_sound", "Gomoku Narabe Renju Audio Custom") +DEFINE_DEVICE_TYPE(GOMOKU, gomoku_sound_device, "gomoku_sound", "Gomoku Narabe Renju Custom Sound") //************************************************************************** diff --git a/src/mame/audio/gridlee.cpp b/src/mame/audio/gridlee.cpp index 78280b7511e..1e98d311e3f 100644 --- a/src/mame/audio/gridlee.cpp +++ b/src/mame/audio/gridlee.cpp @@ -11,7 +11,7 @@ // device type definition -DEFINE_DEVICE_TYPE(GRIDLEE, gridlee_sound_device, "gridlee_sound", "Gridlee Audio Custom") +DEFINE_DEVICE_TYPE(GRIDLEE, gridlee_sound_device, "gridlee_sound", "Gridlee Custom Sound") //************************************************************************** diff --git a/src/mame/audio/micro3d.cpp b/src/mame/audio/micro3d.cpp index 8e117894a9a..6b775406a75 100644 --- a/src/mame/audio/micro3d.cpp +++ b/src/mame/audio/micro3d.cpp @@ -160,7 +160,7 @@ void micro3d_sound_device::noise_sh_w(u8 data) *************************************/ -DEFINE_DEVICE_TYPE(MICRO3D, micro3d_sound_device, "micro3d_sound", "Microprose Audio Custom") +DEFINE_DEVICE_TYPE(MICRO3D, micro3d_sound_device, "micro3d_sound", "Microprose Custom Sound") micro3d_sound_device::micro3d_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MICRO3D, tag, owner, clock), diff --git a/src/mame/audio/n8080.cpp b/src/mame/audio/n8080.cpp index d566198c3e6..f3a27c3869c 100644 --- a/src/mame/audio/n8080.cpp +++ b/src/mame/audio/n8080.cpp @@ -129,10 +129,9 @@ void n8080_state::spacefev_sound_pins_changed() { start_mono_flop(2, attotime::from_usec(550 * 22 * 33)); } - if (changes & ((1 << 0x2) | (1 << 0x3) | (1 << 0x5))) - { - generic_pulse_irq_line(*m_audiocpu, 0, 2); - } + + bool irq_active = (~m_curr_sound_pins & ((1 << 0x2) | (1 << 0x3) | (1 << 0x5))) != 0; + m_audiocpu->set_input_line(INPUT_LINE_IRQ0, irq_active ? ASSERT_LINE : CLEAR_LINE); } @@ -152,25 +151,22 @@ void n8080_state::sheriff_sound_pins_changed() { start_mono_flop(1, attotime::from_usec(550 * 33 * 33)); } - if (changes & ((1 << 0x2) | (1 << 0x3) | (1 << 0x5))) - { - generic_pulse_irq_line(*m_audiocpu, 0, 2); - } + + bool irq_active = (~m_curr_sound_pins & ((1 << 0x2) | (1 << 0x3) | (1 << 0x5))) != 0; + m_audiocpu->set_input_line(INPUT_LINE_IRQ0, irq_active ? ASSERT_LINE : CLEAR_LINE); } void n8080_state::helifire_sound_pins_changed() { - uint16_t changes = ~m_curr_sound_pins & m_prev_sound_pins; + //uint16_t changes = ~m_curr_sound_pins & m_prev_sound_pins; /* ((m_curr_sound_pins >> 0xa) & 1) not emulated */ /* ((m_curr_sound_pins >> 0xb) & 1) not emulated */ /* ((m_curr_sound_pins >> 0xc) & 1) not emulated */ - if (changes & (1 << 6)) - { - generic_pulse_irq_line(*m_audiocpu, 0, 2); - } + bool irq_active = (~m_curr_sound_pins & (1 << 6)) != 0; + m_audiocpu->set_input_line(INPUT_LINE_IRQ0, irq_active ? ASSERT_LINE : CLEAR_LINE); } diff --git a/src/mame/audio/phoenix.cpp b/src/mame/audio/phoenix.cpp index 92e0eb7dcb4..00fba614a46 100644 --- a/src/mame/audio/phoenix.cpp +++ b/src/mame/audio/phoenix.cpp @@ -48,7 +48,7 @@ -DEFINE_DEVICE_TYPE(PHOENIX, phoenix_sound_device, "phoenix_sound", "Phoenix Audio Custom") +DEFINE_DEVICE_TYPE(PHOENIX, phoenix_sound_device, "phoenix_sound", "Phoenix Custom Sound") phoenix_sound_device::phoenix_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, PHOENIX, tag, owner, clock) diff --git a/src/mame/audio/pleiads.cpp b/src/mame/audio/pleiads.cpp index 68d79f79e25..e74c4670b8e 100644 --- a/src/mame/audio/pleiads.cpp +++ b/src/mame/audio/pleiads.cpp @@ -18,7 +18,7 @@ #define TONE1_CLOCK 8000 -DEFINE_DEVICE_TYPE(PLEIADS, pleiads_sound_device, "pleiads_sound", "Pleiads Audio Custom") +DEFINE_DEVICE_TYPE(PLEIADS, pleiads_sound_device, "pleiads_sound", "Pleiads Custom Sound") pleiads_sound_device::pleiads_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pleiads_sound_device(mconfig, PLEIADS, tag, owner, clock) @@ -106,7 +106,7 @@ void pleiads_sound_device::device_start() common_start(); } -DEFINE_DEVICE_TYPE(NAUGHTYB, naughtyb_sound_device, "naughtyb_sound", "Naughty Boy Audio Custom") +DEFINE_DEVICE_TYPE(NAUGHTYB, naughtyb_sound_device, "naughtyb_sound", "Naughty Boy Custom Sound") naughtyb_sound_device::naughtyb_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pleiads_sound_device(mconfig, NAUGHTYB, tag, owner, clock) @@ -174,7 +174,7 @@ void naughtyb_sound_device::device_start() common_start(); } -DEFINE_DEVICE_TYPE(POPFLAME, popflame_sound_device, "popflame_sound", "Pop Flamer Audio Custom") +DEFINE_DEVICE_TYPE(POPFLAME, popflame_sound_device, "popflame_sound", "Pop Flamer Custom Sound") popflame_sound_device::popflame_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : pleiads_sound_device(mconfig, POPFLAME, tag, owner, clock) diff --git a/src/mame/audio/polepos.cpp b/src/mame/audio/polepos.cpp index 9f23e69ccaa..ef575abc899 100644 --- a/src/mame/audio/polepos.cpp +++ b/src/mame/audio/polepos.cpp @@ -216,7 +216,7 @@ static void filter_opamp_m_bandpass_setup(device_t *device, double r1, double r2 // device type definition -DEFINE_DEVICE_TYPE(POLEPOS, polepos_sound_device, "polepos_sound", "Pole Position Audio Custom") +DEFINE_DEVICE_TYPE(POLEPOS, polepos_sound_device, "polepos_sound", "Pole Position Custom Sound") //************************************************************************** diff --git a/src/mame/audio/rax.cpp b/src/mame/audio/rax.cpp index 587b7c85d9c..617eae79a79 100644 --- a/src/mame/audio/rax.cpp +++ b/src/mame/audio/rax.cpp @@ -227,7 +227,7 @@ TIMER_DEVICE_CALLBACK_MEMBER( acclaim_rax_device::dma_timer_callback ) if (m_control_regs[BDMA_CONTROL_REG] & 8) m_cpu->set_input_line(INPUT_LINE_RESET, PULSE_LINE); else - m_cpu->machine().driver_data()->generic_pulse_irq_line(*m_cpu, ADSP2181_BDMA, 1); + m_cpu->pulse_input_line(ADSP2181_BDMA, m_cpu->minimum_quantum_time()); timer.adjust(attotime::never); } diff --git a/src/mame/audio/redbaron.cpp b/src/mame/audio/redbaron.cpp index 15f1cc8f537..edf8a8c901c 100644 --- a/src/mame/audio/redbaron.cpp +++ b/src/mame/audio/redbaron.cpp @@ -27,7 +27,7 @@ // device type definition -DEFINE_DEVICE_TYPE(REDBARON, redbaron_sound_device, "redbaron_custom", "Red Baron Audio Custom") +DEFINE_DEVICE_TYPE(REDBARON, redbaron_sound_device, "redbaron_custom", "Red Baron Custom Sound") //************************************************************************** diff --git a/src/mame/audio/segag80r.cpp b/src/mame/audio/segag80r.cpp index 36bd88f0459..adc354b9d7b 100644 --- a/src/mame/audio/segag80r.cpp +++ b/src/mame/audio/segag80r.cpp @@ -30,7 +30,7 @@ #define SEGA005_555_TIMER_FREQ (1.44 / ((15000 + 2 * 4700) * 1.5e-6)) #define SEGA005_COUNTER_FREQ (100000) /* unknown, just a guess */ -DEFINE_DEVICE_TYPE(SEGA005, sega005_sound_device, "sega005_sound", "Sega 005 Audio Custom") +DEFINE_DEVICE_TYPE(SEGA005, sega005_sound_device, "sega005_sound", "Sega 005 Custom Sound") sega005_sound_device::sega005_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SEGA005, tag, owner, clock) diff --git a/src/mame/audio/snk6502.cpp b/src/mame/audio/snk6502.cpp index 3fc0b7a632b..62c644f6e6e 100644 --- a/src/mame/audio/snk6502.cpp +++ b/src/mame/audio/snk6502.cpp @@ -128,7 +128,7 @@ DISCRETE_SOUND_START( fantasy ) DISCRETE_SOUND_END -DEFINE_DEVICE_TYPE(SNK6502, snk6502_sound_device, "snk6502_sound", "SNK6502 Audio Custom") +DEFINE_DEVICE_TYPE(SNK6502, snk6502_sound_device, "snk6502_sound", "SNK6502 Custom Sound") snk6502_sound_device::snk6502_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, SNK6502, tag, owner, clock), diff --git a/src/mame/audio/spacefb.cpp b/src/mame/audio/spacefb.cpp index 0d6456bd040..00607b17649 100644 --- a/src/mame/audio/spacefb.cpp +++ b/src/mame/audio/spacefb.cpp @@ -24,7 +24,7 @@ READ8_MEMBER(spacefb_state::audio_p2_r) READ_LINE_MEMBER(spacefb_state::audio_t0_r) { - return BIT(m_sound_latch, 6); + return BIT(m_sound_latch, 5); } diff --git a/src/mame/audio/special.cpp b/src/mame/audio/special.cpp index 6edc3cebcdf..e48d8a37c4a 100644 --- a/src/mame/audio/special.cpp +++ b/src/mame/audio/special.cpp @@ -14,7 +14,7 @@ // device type definition -DEFINE_DEVICE_TYPE(SPECIMX_SND, specimx_sound_device, "specimx_sound", "Specialist MX Audio Custom") +DEFINE_DEVICE_TYPE(SPECIMX_SND, specimx_sound_device, "specimx_sound", "Specialist MX Custom Sound") //************************************************************************** diff --git a/src/mame/audio/svis_snd.cpp b/src/mame/audio/svis_snd.cpp index 55b1921e713..8d1f30aa204 100644 --- a/src/mame/audio/svis_snd.cpp +++ b/src/mame/audio/svis_snd.cpp @@ -11,7 +11,7 @@ // device type definition -DEFINE_DEVICE_TYPE(SVISION_SND, svision_sound_device, "svision_sound", "Super Vision Audio Custom") +DEFINE_DEVICE_TYPE(SVISION_SND, svision_sound_device, "svision_sound", "Super Vision Custom Sound") //************************************************************************** diff --git a/src/mame/audio/taito_en.cpp b/src/mame/audio/taito_en.cpp index 2cc1ac987e2..88a776e7f22 100644 --- a/src/mame/audio/taito_en.cpp +++ b/src/mame/audio/taito_en.cpp @@ -276,7 +276,7 @@ MACHINE_CONFIG_MEMBER( taito_en_device::device_add_mconfig ) MCFG_CPU_ADD("audiocpu", M68000, XTAL_30_4761MHz / 2) MCFG_CPU_PROGRAM_MAP(en_sound_map) - MCFG_MC68681_ADD("duart68681", XTAL_16MHz / 4) + MCFG_DEVICE_ADD("duart68681", MC68681, XTAL_16MHz / 4) MCFG_MC68681_SET_EXTERNAL_CLOCKS(XTAL_16MHz/2/8, XTAL_16MHz/2/16, XTAL_16MHz/2/16, XTAL_16MHz/2/8) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(taito_en_device, duart_irq_handler)) diff --git a/src/mame/audio/tiamc1.cpp b/src/mame/audio/tiamc1.cpp index 09ac9e8aa4a..344ed501dc0 100644 --- a/src/mame/audio/tiamc1.cpp +++ b/src/mame/audio/tiamc1.cpp @@ -46,7 +46,7 @@ // device type definition -DEFINE_DEVICE_TYPE(TIAMC1, tiamc1_sound_device, "tiamc1_sound", "TIA-MC1 Audio Custom") +DEFINE_DEVICE_TYPE(TIAMC1, tiamc1_sound_device, "tiamc1_sound", "TIA-MC1 Custom Sound") //************************************************************************** diff --git a/src/mame/audio/tranqgun.cpp b/src/mame/audio/tranqgun.cpp new file mode 100644 index 00000000000..c3583407049 --- /dev/null +++ b/src/mame/audio/tranqgun.cpp @@ -0,0 +1,150 @@ +// license:BSD-3-Clause +// copyright-holders:Zsolt Vasvari, Jim Hernandez +/* + * Tranquillizer Gun audio routines + */ + +#include "emu.h" +#include "includes/vicdual.h" + +/* output port 0x01 definitions - sound effect drive outputs */ +#define OUT_PORT_1_ANIMAL 0x01 +#define OUT_PORT_1_CRY 0x02 +#define OUT_PORT_1_WALK 0x04 +#define OUT_PORT_1_EMAR 0x08 +#define OUT_PORT_1_ANIMALHIT 0x10 +#define OUT_PORT_1_POINT 0x20 +#define OUT_PORT_1_JEEP 0x40 +#define OUT_PORT_1_GUN 0x80 + + +#define PLAY(samp,id,loop) samp->start( id, id, loop ) +#define STOP(samp,id) samp->stop( id ) + + +/* sample file names */ +static const char *const tranqgun_sample_names[] = +{ + "*tranqgun", + "cry", + "walk", + "emar", + "animalhit", + "point", + "jeep", + "gun", + "animal", + nullptr +}; + + +/* sample IDs - must match sample file name table above */ +enum +{ + SND_CRY = 0, + SND_WALK, + SND_EMAR, + SND_ANIMALHIT, + SND_POINT, + SND_JEEP, + SND_GUN, + SND_ANIMAL, +}; + + +WRITE8_MEMBER( vicdual_state::tranqgun_audio_w ) +{ + int bitsChanged; + int bitsGoneHigh; + int bitsGoneLow; + + bitsChanged = m_port1State ^ data; + bitsGoneHigh = bitsChanged & data; + bitsGoneLow = bitsChanged & ~data; + + m_port1State = data; + + if ( bitsGoneHigh & OUT_PORT_1_ANIMAL ) + { + PLAY( m_samples, SND_ANIMAL, 0 ); + } + if ( bitsGoneLow & OUT_PORT_1_ANIMAL ) + { + STOP( m_samples, SND_ANIMAL ); + } + + if ( bitsGoneHigh & OUT_PORT_1_CRY ) + { + PLAY( m_samples, SND_CRY, 0 ); + } + if ( bitsGoneLow & OUT_PORT_1_CRY ) + { + STOP( m_samples, SND_CRY ); + } + + if ( bitsGoneHigh & OUT_PORT_1_WALK ) + { + PLAY( m_samples, SND_WALK, 0 ); + } + if ( bitsGoneLow & OUT_PORT_1_WALK ) + { + STOP( m_samples, SND_WALK ); + } + + if ( bitsGoneLow & OUT_PORT_1_ANIMAL ) + { + PLAY( m_samples, SND_ANIMAL,0 ); + } + + if ( bitsGoneHigh & OUT_PORT_1_ANIMALHIT ) + { + PLAY( m_samples, SND_ANIMALHIT, 0 ); + } + if ( bitsGoneLow & OUT_PORT_1_ANIMALHIT ) + { + STOP( m_samples, SND_ANIMALHIT ); + } + + if ( bitsGoneHigh & OUT_PORT_1_POINT ) + { + PLAY( m_samples, SND_POINT, 0 ); + } + if ( bitsGoneLow & OUT_PORT_1_POINT ) + { + STOP( m_samples, SND_POINT ); + } + + if ( bitsGoneLow & OUT_PORT_1_JEEP ) + { + PLAY( m_samples, SND_JEEP, 1 ); + + } + if ( bitsGoneHigh & OUT_PORT_1_JEEP ) + { + STOP( m_samples, SND_JEEP ); + } + + if ( bitsGoneLow & OUT_PORT_1_EMAR ) + { + PLAY( m_samples, SND_EMAR, 0 ); + } + + if ( bitsGoneHigh & OUT_PORT_1_GUN ) + { + PLAY( m_samples, SND_GUN, 0 ); + } + if ( bitsGoneLow & OUT_PORT_1_GUN ) + { + STOP( m_samples, SND_GUN ); + } +} + + +MACHINE_CONFIG_START( tranqgun_audio ) + + /* samples */ + MCFG_SOUND_ADD("samples", SAMPLES, 0) + MCFG_SAMPLES_CHANNELS(8) + MCFG_SAMPLES_NAMES(tranqgun_sample_names) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) +MACHINE_CONFIG_END diff --git a/src/mame/audio/tranqgun.h b/src/mame/audio/tranqgun.h new file mode 100644 index 00000000000..d5228077554 --- /dev/null +++ b/src/mame/audio/tranqgun.h @@ -0,0 +1,4 @@ +// license:BSD-3-Clause +// copyright-holders:Zsolt Vasvari + +MACHINE_CONFIG_EXTERN( tranqgun_audio ); diff --git a/src/mame/audio/turrett.cpp b/src/mame/audio/turrett.cpp index f875bfe3cf1..760e98259a4 100644 --- a/src/mame/audio/turrett.cpp +++ b/src/mame/audio/turrett.cpp @@ -44,7 +44,7 @@ device_memory_interface::space_config_vector turrett_device::memory_space_config void turrett_device::device_start() { // Find our direct access - m_direct = &space().direct(); + m_direct = space().direct<0>(); // Create the sound stream m_stream = machine().sound().stream_alloc(*this, 0, 2, 44100); diff --git a/src/mame/audio/tvc.cpp b/src/mame/audio/tvc.cpp index 0c4a70d22b6..bd7da39a759 100644 --- a/src/mame/audio/tvc.cpp +++ b/src/mame/audio/tvc.cpp @@ -10,7 +10,7 @@ #include "tvc.h" // device type definition -DEFINE_DEVICE_TYPE(TVC_SOUND, tvc_sound_device, "tvc_sound", "TVC 64 Audio Custom") +DEFINE_DEVICE_TYPE(TVC_SOUND, tvc_sound_device, "tvc_sound", "TVC 64 Custom Sound") //------------------------------------------------- // tvc_sound_device - constructor diff --git a/src/mame/audio/tx1.cpp b/src/mame/audio/tx1.cpp index f462fb20b31..486da6330e6 100644 --- a/src/mame/audio/tx1.cpp +++ b/src/mame/audio/tx1.cpp @@ -52,7 +52,7 @@ static const double tx1_engine_gains[16] = }; -DEFINE_DEVICE_TYPE(TX1, tx1_sound_device, "tx1_sound", "TX-1 Audio Custom") +DEFINE_DEVICE_TYPE(TX1, tx1_sound_device, "tx1_sound", "TX-1 Custom Sound") tx1_sound_device::tx1_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : tx1_sound_device(mconfig, TX1, tag, owner, clock) @@ -335,7 +335,7 @@ static const double bb_engine_gains[16] = -1.0/(1.0/(BUGGYBOY_R1S + BUGGYBOY_R2S + BUGGYBOY_R3S + BUGGYBOY_R4S) + 1.0/100e3)/100e3, }; -DEFINE_DEVICE_TYPE(BUGGYBOY, buggyboy_sound_device, "buggyboy_sound", "Buggy Boy Audio Custom") +DEFINE_DEVICE_TYPE(BUGGYBOY, buggyboy_sound_device, "buggyboy_sound", "Buggy Boy Custom Sound") buggyboy_sound_device::buggyboy_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : tx1_sound_device(mconfig, BUGGYBOY, tag, owner, clock) diff --git a/src/mame/audio/vc4000.cpp b/src/mame/audio/vc4000.cpp index 3d0b921fd32..df4a308f619 100644 --- a/src/mame/audio/vc4000.cpp +++ b/src/mame/audio/vc4000.cpp @@ -11,7 +11,7 @@ #include "vc4000.h" -DEFINE_DEVICE_TYPE(VC4000_SND, vc4000_sound_device, "vc4000_sound", "Interton Electronic VC 4000 Audio Custom") +DEFINE_DEVICE_TYPE(VC4000_SND, vc4000_sound_device, "vc4000_sound", "Interton Electronic VC 4000 Custom Sound") vc4000_sound_device::vc4000_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, VC4000_SND, tag, owner, clock) diff --git a/src/mame/audio/warpwarp.cpp b/src/mame/audio/warpwarp.cpp index bd8490e49b7..98a74f24e21 100644 --- a/src/mame/audio/warpwarp.cpp +++ b/src/mame/audio/warpwarp.cpp @@ -16,7 +16,7 @@ #define CLOCK_1V (18432000/3/2/384) -DEFINE_DEVICE_TYPE(WARPWARP, warpwarp_sound_device, "warpwarp_sound", "Warp Warp Audio Custom") +DEFINE_DEVICE_TYPE(WARPWARP, warpwarp_sound_device, "warpwarp_sound", "Warp Warp Custom Sound") warpwarp_sound_device::warpwarp_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, WARPWARP, tag, owner, clock), diff --git a/src/mame/audio/williams.cpp b/src/mame/audio/williams.cpp index f9174d44105..a61e4c28696 100644 --- a/src/mame/audio/williams.cpp +++ b/src/mame/audio/williams.cpp @@ -753,7 +753,7 @@ MACHINE_CONFIG_MEMBER( williams_adpcm_sound_device::device_add_mconfig ) MCFG_YM2151_IRQ_HANDLER(INPUTLINE("cpu", M6809_FIRQ_LINE)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, DEVICE_SELF_OWNER, 0.10) - MCFG_SOUND_ADD("dac", AD7524, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, DEVICE_SELF_OWNER, 0.5) + MCFG_SOUND_ADD("dac", AD7524, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, DEVICE_SELF_OWNER, 0.10) MCFG_DEVICE_ADD("vref", VOLTAGE_REGULATOR, 0) MCFG_VOLTAGE_REGULATOR_OUTPUT(5.0) MCFG_SOUND_ROUTE_EX(0, "dac", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE_EX(0, "dac", -1.0, DAC_VREF_NEG_INPUT) diff --git a/src/mame/audio/wiping.cpp b/src/mame/audio/wiping.cpp index 7618ce74ce9..4a2b1236662 100644 --- a/src/mame/audio/wiping.cpp +++ b/src/mame/audio/wiping.cpp @@ -4,20 +4,19 @@ Wiping sound driver (quick hack of the Namco sound driver) - used by wiping.c and clshroad.c + used by wiping.cpp and clshroad.cpp ***************************************************************************/ #include "emu.h" #include "audio/wiping.h" -static constexpr int samplerate = 48000; static constexpr int defgain = 48; -DEFINE_DEVICE_TYPE(WIPING, wiping_sound_device, "wiping_sound", "Wiping Audio Custom") +DEFINE_DEVICE_TYPE(WIPING_CUSTOM, wiping_sound_device, "wiping_sound", "Wiping Custom Sound") wiping_sound_device::wiping_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, WIPING, tag, owner, clock), + : device_t(mconfig, WIPING_CUSTOM, tag, owner, clock), device_sound_interface(mconfig, *this), m_last_channel(nullptr), m_sound_prom(nullptr), @@ -27,8 +26,7 @@ wiping_sound_device::wiping_sound_device(const machine_config &mconfig, const ch m_stream(nullptr), m_mixer_table(nullptr), m_mixer_lookup(nullptr), - m_mixer_buffer(nullptr), - m_mixer_buffer_2(nullptr) + m_mixer_buffer(nullptr) { memset(m_channel_list, 0, sizeof(wp_sound_channel)*MAX_VOICES); memset(m_soundregs, 0, sizeof(uint8_t)*0x4000); @@ -44,11 +42,10 @@ void wiping_sound_device::device_start() wp_sound_channel *voice; /* get stream channels */ - m_stream = machine().sound().stream_alloc(*this, 0, 1, samplerate); + m_stream = machine().sound().stream_alloc(*this, 0, 1, clock()/2); - /* allocate a pair of buffers to mix into - 1 second's worth should be more than enough */ - m_mixer_buffer = make_unique_clear<short[]>(samplerate); - m_mixer_buffer_2 = make_unique_clear<short[]>(samplerate); + /* allocate a buffer to mix into - 1 second's worth should be more than enough */ + m_mixer_buffer = make_unique_clear<short[]>(clock()/2); /* build the mixer table */ make_mixer_table(8, defgain); @@ -87,9 +84,6 @@ void wiping_sound_device::device_start() /* build a table to divide by the number of voices; gain is specified as gain*16 */ void wiping_sound_device::make_mixer_table(int voices, int gain) { - int count = voices * 128; - int i; - /* allocate memory */ m_mixer_table = make_unique_clear<int16_t[]>(256 * voices); @@ -97,7 +91,7 @@ void wiping_sound_device::make_mixer_table(int voices, int gain) m_mixer_lookup = m_mixer_table.get() + (128 * voices); /* fill in the table - 16 bit case */ - for (i = 0; i < count; i++) + for (int i = 0; i < voices * 128; i++) { int val = i * gain * 16 / voices; if (val > 32767) val = 32767; diff --git a/src/mame/audio/wiping.h b/src/mame/audio/wiping.h index 11924852bd9..367ff408044 100644 --- a/src/mame/audio/wiping.h +++ b/src/mame/audio/wiping.h @@ -58,6 +58,6 @@ private: void make_mixer_table(int voices, int gain); }; -DECLARE_DEVICE_TYPE(WIPING, wiping_sound_device) +DECLARE_DEVICE_TYPE(WIPING_CUSTOM, wiping_sound_device) #endif // MAME_AUDIO_WIPING_H diff --git a/src/mame/audio/wswan.cpp b/src/mame/audio/wswan.cpp index acd698eea1c..37f7c6288ab 100644 --- a/src/mame/audio/wswan.cpp +++ b/src/mame/audio/wswan.cpp @@ -18,7 +18,7 @@ The noise taps and behavior are the same as the Virtual Boy. // device type definition -DEFINE_DEVICE_TYPE(WSWAN_SND, wswan_sound_device, "wswan_sound", "WonderSwan Audio Custom") +DEFINE_DEVICE_TYPE(WSWAN_SND, wswan_sound_device, "wswan_sound", "WonderSwan Custom Sound") //************************************************************************** diff --git a/src/mame/drivers/68ksbc.cpp b/src/mame/drivers/68ksbc.cpp index baaf6a043b7..4e6fcc23221 100644 --- a/src/mame/drivers/68ksbc.cpp +++ b/src/mame/drivers/68ksbc.cpp @@ -49,8 +49,7 @@ static ADDRESS_MAP_START(c68ksbc_mem, AS_PROGRAM, 16, c68ksbc_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x000000, 0x002fff) AM_ROM AM_RANGE(0x003000, 0x5fffff) AM_RAM - AM_RANGE(0x600000, 0x600001) AM_DEVREADWRITE8("acia", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0x600002, 0x600003) AM_DEVREADWRITE8("acia", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0x600000, 0x600003) AM_DEVREADWRITE8("acia", acia6850_device, read, write, 0x00ff) ADDRESS_MAP_END diff --git a/src/mame/drivers/a7150.cpp b/src/mame/drivers/a7150.cpp index 0b87eaeee8f..4c7440c7e84 100644 --- a/src/mame/drivers/a7150.cpp +++ b/src/mame/drivers/a7150.cpp @@ -471,8 +471,8 @@ static MACHINE_CONFIG_START( a7150 ) MCFG_DEVICE_ADD("video_bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(k7070_cpu_banked) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_DEVICE_ADD(Z80CTC_TAG, Z80CTC, XTAL_16MHz/3) diff --git a/src/mame/drivers/accomm.cpp b/src/mame/drivers/accomm.cpp index 63729222f20..4012236b50e 100644 --- a/src/mame/drivers/accomm.cpp +++ b/src/mame/drivers/accomm.cpp @@ -15,6 +15,10 @@ #include "emu.h" #include "cpu/g65816/g65816.h" #include "machine/6522via.h" +#include "machine/6850acia.h" +#include "machine/clock.h" +#include "machine/mc6854.h" +#include "machine/ram.h" #include "machine/nvram.h" #include "machine/bankdev.h" #include "sound/beep.h" @@ -70,12 +74,16 @@ public: accomm_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), - m_bank0dev(*this, "bank0dev"), m_beeper(*this, "beeper"), + m_ram(*this, RAM_TAG), m_via(*this, "via6522"), + m_acia(*this, "acia"), + m_acia_clock(*this, "acia_clock"), + m_adlc(*this, "mc6854"), m_vram(*this, "vram"), m_keybd1(*this, "LINE1.%u", 0), - m_keybd2(*this, "LINE2.%u", 0) + m_keybd2(*this, "LINE2.%u", 0), + m_ch00rom_enabled(true) { } virtual void machine_reset() override; @@ -83,11 +91,15 @@ public: uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - DECLARE_WRITE8_MEMBER(b0_rom_disable_w); + DECLARE_WRITE8_MEMBER(ch00switch_w); DECLARE_READ8_MEMBER(read_keyboard1); DECLARE_READ8_MEMBER(read_keyboard2); + DECLARE_READ8_MEMBER(ram_r); + DECLARE_WRITE8_MEMBER(ram_w); DECLARE_READ8_MEMBER(sheila_r); DECLARE_WRITE8_MEMBER(sheila_w); + DECLARE_WRITE_LINE_MEMBER(write_acia_clock); + DECLARE_WRITE_LINE_MEMBER(econet_clk_w); DECLARE_PALETTE_INIT(accomm); INTERRUPT_GEN_MEMBER(vbl_int); @@ -95,9 +107,12 @@ public: protected: // devices required_device<g65816_device> m_maincpu; - required_device<address_map_bank_device> m_bank0dev; required_device<beep_device> m_beeper; + required_device<ram_device> m_ram; required_device<via6522_device> m_via; + required_device<acia6850_device> m_acia; + required_device<clock_device> m_acia_clock; + required_device<mc6854_device> m_adlc; required_shared_ptr<uint8_t> m_vram; required_ioport_array<14> m_keybd1, m_keybd2; @@ -109,6 +124,7 @@ protected: inline void plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color); private: + bool m_ch00rom_enabled; ULA m_ula; int m_map4[256]; int m_map16[256]; @@ -178,6 +194,8 @@ void accomm_state::machine_reset() m_ula.interrupt_status = 0x82; m_ula.interrupt_control = 0; m_ula.vram = (uint8_t *)m_vram.target() + m_ula.screen_base; + + m_ch00rom_enabled = true; } void accomm_state::machine_start() @@ -195,9 +213,10 @@ void accomm_state::video_start() } } -WRITE8_MEMBER(accomm_state::b0_rom_disable_w) +WRITE8_MEMBER(accomm_state::ch00switch_w) { - m_bank0dev->set_bank(1); + if (!machine().side_effect_disabled()) + m_ch00rom_enabled = false; } inline uint8_t accomm_state::read_vram(uint16_t addr) @@ -411,6 +430,45 @@ uint32_t accomm_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap } +READ8_MEMBER(accomm_state::ram_r) +{ + uint8_t data = 0xff; + + if (m_ch00rom_enabled && (offset < 0x10000)) + { + data = memregion("maincpu")->base()[0x30000 + offset]; + } + else + { + switch (m_ram->size()) + { + case 512 * 1024: + data = m_ram->pointer()[offset & 0x7ffff]; + break; + + case 1024 * 1024: + data = m_ram->pointer()[offset & 0xfffff]; + break; + } + } + return data; +} + +WRITE8_MEMBER(accomm_state::ram_w) +{ + switch (m_ram->size()) + { + case 512 * 1024: + m_ram->pointer()[offset & 0x7ffff] = data; + break; + + case 1024 * 1024: + m_ram->pointer()[offset & 0xfffff] = data; + break; + } +} + + READ8_MEMBER(accomm_state::sheila_r) { uint8_t data = 0; @@ -560,23 +618,41 @@ void accomm_state::interrupt_handler(int mode, int interrupt) } } -static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, accomm_state ) - AM_RANGE(0x000000, 0x007fff) AM_RAM - AM_RANGE(0x008000, 0x00ffff) AM_DEVICE("bank0dev", address_map_bank_device, amap8) - AM_RANGE(0x010000, 0x08ffff) AM_RAM // "576K RAM" - AM_RANGE(0x420000, 0x42000f) AM_DEVREADWRITE("via6522", via6522_device, read, write) - AM_RANGE(0x440000, 0x440000) AM_WRITE(b0_rom_disable_w) - AM_RANGE(0x450000, 0x457fff) AM_RAM AM_SHARE("vram") - AM_RANGE(0x458000, 0x459fff) AM_READ(read_keyboard1) - AM_RANGE(0x45a000, 0x45bfff) AM_READ(read_keyboard2) - AM_RANGE(0x45fe00, 0x45feff) AM_READWRITE(sheila_r, sheila_w) - AM_RANGE(0x460000, 0x467fff) AM_RAM // nvram? - AM_RANGE(0xfc0000, 0xffffff) AM_ROM AM_REGION("maincpu", 0) -ADDRESS_MAP_END +WRITE_LINE_MEMBER(accomm_state::write_acia_clock) +{ + m_acia->write_txc(state); + m_acia->write_rxc(state); +} + +WRITE_LINE_MEMBER(accomm_state::econet_clk_w) +{ + m_adlc->rxc_w(state); + m_adlc->txc_w(state); +} -static ADDRESS_MAP_START( b0dev_map, AS_PROGRAM, 8, accomm_state ) - AM_RANGE(0x0000, 0x7fff) AM_ROM AM_REGION("maincpu", 0x38000) - AM_RANGE(0x8000, 0xffff) AM_RAM +static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, accomm_state ) + AM_RANGE(0x000000, 0x1fffff) AM_READWRITE(ram_r, ram_w) /* System RAM */ + AM_RANGE(0x200000, 0x3fffff) AM_NOP /* External expansion RAM */ + AM_RANGE(0x400000, 0x400000) AM_NOP /* MODEM */ + AM_RANGE(0x410000, 0x410000) AM_RAM /* Econet ID */ + AM_RANGE(0x420000, 0x42000f) AM_DEVREADWRITE("via6522", via6522_device, read, write) /* 6522 VIA (printer etc) */ + AM_RANGE(0x430000, 0x430001) AM_DEVREADWRITE("acia", acia6850_device, read, write) /* 2641 ACIA (RS423) */ + AM_RANGE(0x440000, 0x440000) AM_WRITE(ch00switch_w) /* CH00SWITCH */ + AM_RANGE(0x450000, 0x457fff) AM_RAM AM_SHARE("vram") /* Video RAM */ + AM_RANGE(0x458000, 0x459fff) AM_READ(read_keyboard1) /* Video ULA */ + AM_RANGE(0x45a000, 0x45bfff) AM_READ(read_keyboard2) /* Video ULA */ + AM_RANGE(0x45fe00, 0x45feff) AM_READWRITE(sheila_r, sheila_w) /* Video ULA */ + AM_RANGE(0x460000, 0x467fff) AM_RAM AM_SHARE("nvram") /* CMOS RAM */ + AM_RANGE(0x470000, 0x47001f) AM_DEVREADWRITE("mc6854", mc6854_device, read, write) /* 68B54 (Econet) */ + AM_RANGE(0x480000, 0x7fffff) AM_NOP /* Reserved */ + AM_RANGE(0x800000, 0xbfffff) AM_NOP /* External expansion IO */ + AM_RANGE(0xc00000, 0xf7ffff) AM_NOP /* External expansion ROM */ + AM_RANGE(0xf80000, 0xf9ffff) AM_NOP /* Empty */ + AM_RANGE(0xfa0000, 0xfbffff) AM_NOP /* ROM bank 4 */ + AM_RANGE(0xfc0000, 0xfcffff) AM_ROM AM_REGION("maincpu", 0x000000) /* ROM bank 3 */ + AM_RANGE(0xfd0000, 0xfdffff) AM_ROM AM_REGION("maincpu", 0x010000) /* ROM bank 2 */ + AM_RANGE(0xfe0000, 0xfeffff) AM_ROM AM_REGION("maincpu", 0x020000) /* ROM bank 0 */ + AM_RANGE(0xff0000, 0xffffff) AM_ROM AM_REGION("maincpu", 0x030000) /* ROM bank 1 */ ADDRESS_MAP_END static INPUT_PORTS_START( accomm ) @@ -767,23 +843,51 @@ static MACHINE_CONFIG_START( accomm ) MCFG_DEFAULT_LAYOUT(layout_accomm) - MCFG_DEVICE_ADD("bank0dev", ADDRESS_MAP_BANK, 0) - MCFG_DEVICE_PROGRAM_MAP(b0dev_map) - MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) + /* internal ram */ + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("512K") + MCFG_RAM_EXTRA_OPTIONS("1M") - MCFG_DEVICE_ADD("via6522", VIA6522, XTAL_16MHz / 16) - MCFG_VIA6522_WRITEPA_HANDLER(DEVWRITE8("cent_data_out", output_latch_device, write)) - MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE("centronics", centronics_device, write_strobe)) + MCFG_NVRAM_ADD_0FILL("nvram") + /* sound */ MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("beeper", BEEP, 300) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + /* rtc pcf8573 */ + + /* via */ + MCFG_DEVICE_ADD("via6522", VIA6522, XTAL_16MHz / 16) + MCFG_VIA6522_WRITEPA_HANDLER(DEVWRITE8("cent_data_out", output_latch_device, write)) + MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE("centronics", centronics_device, write_strobe)) + + /* acia */ + MCFG_DEVICE_ADD("acia", ACIA6850, 0) + MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("serial", rs232_port_device, write_txd)) + MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("serial", rs232_port_device, write_rts)) + MCFG_ACIA6850_IRQ_HANDLER(INPUTLINE("maincpu", G65816_LINE_IRQ)) + + MCFG_RS232_PORT_ADD("serial", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_dcd)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts)) + + MCFG_DEVICE_ADD("acia_clock", CLOCK, XTAL_16MHz / 13) + MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(accomm_state, write_acia_clock)) + + /* econet */ + MCFG_DEVICE_ADD("mc6854", MC6854, 0) + MCFG_MC6854_OUT_TXD_CB(DEVWRITELINE(ECONET_TAG, econet_device, data_w)) + MCFG_MC6854_OUT_IRQ_CB(INPUTLINE("maincpu", G65816_LINE_NMI)) + MCFG_ECONET_ADD() + MCFG_ECONET_CLK_CALLBACK(WRITELINE(accomm_state, econet_clk_w)) + MCFG_ECONET_DATA_CALLBACK(DEVWRITELINE("mc6854", mc6854_device, set_rx)) + MCFG_ECONET_SLOT_ADD("econet254", 254, econet_devices, nullptr) + /* printer */ MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") - MCFG_CENTRONICS_ACK_HANDLER(DEVWRITELINE("via6522", via6522_device, write_ca1)) MCFG_DEVCB_INVERT /* ack seems to be inverted? */ + MCFG_CENTRONICS_ACK_HANDLER(DEVWRITELINE("via6522", via6522_device, write_ca1)) MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics") MACHINE_CONFIG_END diff --git a/src/mame/drivers/acd.cpp b/src/mame/drivers/acd.cpp index ecdc10e6c3a..3bb574397e8 100644 --- a/src/mame/drivers/acd.cpp +++ b/src/mame/drivers/acd.cpp @@ -9,26 +9,25 @@ Advanced Computer Design computer. CPU is WD9000. Some details at bitsavers. ************************************************************************************************************************************/ #include "emu.h" -//#include "cpu/mcs51/mcs51.h" class acd_state : public driver_device { public: acd_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) -// , maincpu(*this, "maincpu") +// , m_maincpu(*this, "maincpu") { } -protected: -// required_device<i80c52_device> maincpu; +private: +// required_device<cpu_device> m_maincpu; }; +//static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, acd_state ) +//ADDRESS_MAP_END + static INPUT_PORTS_START( acd ) INPUT_PORTS_END -//static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, acd_state ) -//ADDRESS_MAP_END - static MACHINE_CONFIG_START( acd ) MACHINE_CONFIG_END @@ -45,4 +44,4 @@ ROM_START( acd ) ROM_LOAD( "d9_cpu_b14_rev_1.2.bin", 0x000000, 0x000200, CRC(5572ff8b) SHA1(9e8158c338b2798f7fb1d9c4fa6dd99592d2fae3) ) ROM_END -COMP( 198?, acd, 0, 0, acd, acd, acd_state, 0, "Advanced Computer Design", "Unknown computer", MACHINE_IS_SKELETON ) +COMP( 198?, acd, 0, 0, acd, acd, acd_state, 0, "Advanced Computer Design", "unknown ACD computer", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/adp.cpp b/src/mame/drivers/adp.cpp index 682938053f4..1a2de92f5ab 100644 --- a/src/mame/drivers/adp.cpp +++ b/src/mame/drivers/adp.cpp @@ -542,7 +542,7 @@ static MACHINE_CONFIG_START( quickjac ) MCFG_MACHINE_START_OVERRIDE(adp_state,skattv) MCFG_MACHINE_RESET_OVERRIDE(adp_state,skattv) - MCFG_MC68681_ADD( "duart68681", XTAL_8_664MHz / 2 ) + MCFG_DEVICE_ADD( "duart68681", MC68681, XTAL_8_664MHz / 2 ) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(adp_state, duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("microtouch", microtouch_device, rx)) MCFG_MC68681_INPORT_CALLBACK(IOPORT("DSW1")) diff --git a/src/mame/drivers/agat.cpp b/src/mame/drivers/agat.cpp index 546122ead74..62f111e7255 100644 --- a/src/mame/drivers/agat.cpp +++ b/src/mame/drivers/agat.cpp @@ -1026,7 +1026,7 @@ static MACHINE_CONFIG_START( agat7 ) MCFG_DEVICE_ADD(A7_UPPERBANK_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(inhbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) /* keyboard controller -- XXX must be replaced */ diff --git a/src/mame/drivers/alg.cpp b/src/mame/drivers/alg.cpp index 38ce8fedeb1..6e86fc37fe4 100644 --- a/src/mame/drivers/alg.cpp +++ b/src/mame/drivers/alg.cpp @@ -298,8 +298,8 @@ static MACHINE_CONFIG_START( alg_r1 ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_512kb_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_NVRAM_ADD_0FILL("nvram") diff --git a/src/mame/drivers/aliens.cpp b/src/mame/drivers/aliens.cpp index 692eb06e770..3eef3edda85 100644 --- a/src/mame/drivers/aliens.cpp +++ b/src/mame/drivers/aliens.cpp @@ -204,8 +204,8 @@ static MACHINE_CONFIG_START( aliens ) MCFG_DEVICE_ADD("bank0000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank0000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(11) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(11) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) MCFG_WATCHDOG_ADD("watchdog") diff --git a/src/mame/drivers/alphatpx.cpp b/src/mame/drivers/alphatpx.cpp index 5c31f58cae0..fcb3d9de838 100644 --- a/src/mame/drivers/alphatpx.cpp +++ b/src/mame/drivers/alphatpx.cpp @@ -1,11 +1,54 @@ // license: GPL-2.0+ // copyright-holders: Dirk Best +// test / modify oct-2017 begin: rfka01 + helwie44 /*************************************************************************** Triumph-Adler Alphatronic Px series TODO: Doesn't do much more than showing the initial boot message - + + The Px series was designed by SKS, like the ITT3030 and the SKS Nano, + the boards are closely related. + + Keyboard and floppy stuff was copypasted from ITT3030 and adapted to the best of knowledge. + +P1, P2 and P2S: no paging +Lower 16K for P1, P2 and P2 S + +0x0000 - 0x17ff ROM monitor (MOS) +0x1800 - 0x1bff 1K RAM +0x1c00 - 0x1fff reserved +0x2000 - 0x2fff reserved, belonging to the video card's memory space (video ROM?) +0x3000 - 0x3fff actual video memory + +P1 +Upper 32K +0x4000 - 0x400a reserved +0x4010 - 0xc000 32K RAM + +P2, P2S +Upper 48K +0x4000 - 0x400a reserved +0x4010 - 0xfff 48K RAM + +P2 U, paging via +An adapter with RAM at 0x0000 and 0x3fff and the banking logic (see above) is added to the the standard 48K memory card. +16K memory card + +P3, P4 +0x0000 - 0x0fff ROM monitor (MOS) +0x1000 - 0x17ff free +0x1800 - 0x1bff monitor stack (RAM) +0x1c00 - 0x2fff free +0x3000 - 0x3fff video memory +0x4000 - 0xffff RAM + + +P2 U and P3 support regular CP/M use with a full 64K RAM complement. +Still, the video RAM is at 0x3000 and 0x3ffff even for these machines, and from what I've read they also use the routine present in the ROM monitor, the MOS. +That means, that in order to update the video RAM and probably other I/O the lower 16K (page 0) are constantly paged in and paged out. + +This is accomplished by writing 2FH to port 0x78 in order to switch in the ROM (and assorted, see below) area and by writing 63H to port 0x78 in order to swap the full 64K RAM back in. ***************************************************************************/ #include "emu.h" @@ -28,25 +71,60 @@ class alphatpx_state : public driver_device { public: alphatpx_state(const machine_config &mconfig, device_type type, const char *tag) : - driver_device(mconfig, type, tag), - m_bankdev(*this, "bankdev"), - m_palette(*this, "palette"), - m_vram(*this, "vram"), - m_gfx(*this, "gfx") + driver_device(mconfig, type, tag), + m_bankdev(*this, "bankdev"), + m_kbdmcu(*this, "kbdmcu"), + m_crtc(*this, "crtc"), + m_fdc (*this, "fdc"), + m_floppy0(*this, "fdc:0"), + m_floppy1(*this, "fdc:1"), + m_keycols(*this, "COL.%u", 0), + m_palette(*this, "palette"), + m_vram(*this, "vram"), + m_gfx(*this, "gfx"), + m_ram(*this, "ram") + { } - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); +public: + DECLARE_READ_LINE_MEMBER(kbd_matrix_r); + DECLARE_WRITE8_MEMBER(kbd_matrix_w); + DECLARE_READ8_MEMBER(kbd_port2_r); + DECLARE_WRITE8_MEMBER(kbd_port2_w); + + DECLARE_READ8_MEMBER(fdc_r); + DECLARE_WRITE8_MEMBER(fdc_w); + DECLARE_READ8_MEMBER(fdc_stat_r); + DECLARE_WRITE8_MEMBER(fdc_cmd_w); + + DECLARE_WRITE_LINE_MEMBER(fdcirq_w); + DECLARE_WRITE_LINE_MEMBER(fdcdrq_w); + DECLARE_WRITE_LINE_MEMBER(fdchld_w); + DECLARE_WRITE8_MEMBER(bank_w); protected: virtual void machine_start() override; + virtual void machine_reset() override; + required_device<address_map_bank_device> m_bankdev; + required_device<i8041_device> m_kbdmcu; + required_device<crt5037_device> m_crtc; + required_device<fd1791_device> m_fdc; + required_device<floppy_connector> m_floppy0; + required_device<floppy_connector> m_floppy1; + required_ioport_array<16> m_keycols; private: - required_device<address_map_bank_device> m_bankdev; + + uint8_t m_kbdclk, m_kbdread, m_kbdport2; required_device<palette_device> m_palette; - required_shared_ptr<uint8_t> m_vram; + required_shared_ptr<u8> m_vram; required_region_ptr<u8> m_gfx; - - std::unique_ptr<uint8_t[]> m_ram; + required_shared_ptr<u8> m_ram; + floppy_image_device *m_curfloppy; + bool m_fdc_irq, m_fdc_drq, m_fdc_hld; + floppy_connector *m_con1, *m_con2; + }; @@ -59,26 +137,185 @@ static ADDRESS_MAP_START( alphatp3_mem, AS_PROGRAM, 8, alphatpx_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( alphatp3_map, AS_PROGRAM, 8, alphatpx_state ) - AM_RANGE(0x00000, 0x00fff) AM_READ_BANK("rom") AM_WRITE_BANK("ram_0000") - AM_RANGE(0x01000, 0x02fff) AM_RAMBANK("ram_1000") - AM_RANGE(0x03000, 0x037ef) AM_MIRROR(0x800) AM_RAM AM_SHARE("vram") - AM_RANGE(0x037f0, 0x037ff) AM_MIRROR(0x800) AM_DEVREADWRITE("crtc", crt5037_device, read, write) - AM_RANGE(0x04000, 0x0ffff) AM_RAMBANK("ram_4000") - AM_RANGE(0x10000, 0x1ffff) AM_RAMBANK("ram") + AM_RANGE(0x00000, 0x017ff) AM_ROM AM_REGION("boot", 0) // P2 0x0000 , 0x17ff -hw 6kB, P3 only 4 kB + AM_RANGE(0x01800, 0x01c00) AM_RAM // boot rom variables + AM_RANGE(0x03000, 0x03bff) AM_WRITEONLY AM_SHARE("vram") // test 2017 hw, MOS directly writes to display RAM + AM_RANGE(0x03FF0, 0x03fff) AM_DEVWRITE("crtc", crt5037_device, write) //test hw, mem-mapped registers, cursor position can be determined through this range + AM_RANGE(0x00000, 0x0ffff) AM_RAMBANK("ram_0000") + + AM_RANGE(0x10000, 0x1ffff) AM_RAM AM_SHARE("ram") ADDRESS_MAP_END static ADDRESS_MAP_START( alphatp3_io, AS_IO, 8, alphatpx_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x04, 0x04) AM_DEVREADWRITE("uart", i8251_device, data_r, data_w) AM_RANGE(0x05, 0x05) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w) + AM_RANGE(0x10, 0x11) AM_DEVREADWRITE("kbdmcu", i8041_device, upi41_master_r, upi41_master_w) + AM_RANGE(0x50, 0x53) AM_READWRITE(fdc_r, fdc_w) + AM_RANGE(0x54, 0x54) AM_READWRITE(fdc_stat_r, fdc_cmd_w) + AM_RANGE(0x78, 0x78) AM_WRITE(bank_w) ADDRESS_MAP_END +WRITE8_MEMBER(alphatpx_state::bank_w) +{ + m_bankdev->set_bank(BIT(data, 6)); +} //************************************************************************** // INPUTS //************************************************************************** -INPUT_PORTS_START( alphatp3 ) +READ_LINE_MEMBER(alphatpx_state::kbd_matrix_r) +{ + return m_kbdread; +} + +WRITE8_MEMBER(alphatpx_state::kbd_matrix_w) +{ + int rd_masks[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 }; + int tmp_read; + + if ((data & 0x80) && (!m_kbdclk)) + { + tmp_read = m_keycols[(data >> 3) & 0xf]->read() & rd_masks[data & 0x7]; + m_kbdread = (tmp_read != 0) ? 1 : 0; + } + + m_kbdclk = (data & 0x80) ? 1 : 0; + +} + +// bit 2 is UPI-41 host IRQ to Z80 +WRITE8_MEMBER(alphatpx_state::kbd_port2_w) +{ + m_kbdport2 = data; + +} + +READ8_MEMBER(alphatpx_state::kbd_port2_r) +{ + return m_kbdport2; +} + +// translation table at offset 0xdc0 in the main rom +static INPUT_PORTS_START( alphatp3 ) + PORT_START("COL.0") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + + PORT_START("COL.1") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x8a + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') + + PORT_START("COL.2") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x82 + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x8c + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('@') + + PORT_START("COL.3") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x8b + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + + PORT_START("COL.4") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0xc0 + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + + PORT_START("COL.5") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x89 + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + + PORT_START("COL.6") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('k') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR(';') + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR('<') PORT_CHAR('>') + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('/') + + PORT_START("COL.7") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR(':') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x8f + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + + PORT_START("COL.8") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x84 + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + + PORT_START("COL.9") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_MAMEKEY(RSHIFT)) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('=') + + PORT_START("COL.10") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('+') PORT_CHAR('*') + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('#') PORT_CHAR('^') + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x7f + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) PORT_CHAR(UCHAR_MAMEKEY(DEL_PAD)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('~') PORT_CHAR('?') + + PORT_START("COL.11") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_MAMEKEY(TAB)) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD)) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR(UCHAR_MAMEKEY(1_PAD)) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('`') + + PORT_START("COL.12") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_CHAR(UCHAR_MAMEKEY(2_PAD)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x93 + + PORT_START("COL.13") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_CHAR(UCHAR_MAMEKEY(4_PAD)) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) + PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0xc2 + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x92 + + PORT_START("COL.14") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_CHAR(UCHAR_MAMEKEY(6_PAD)) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x91 + + PORT_START("COL.15") + PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) + PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_CHAR(UCHAR_MAMEKEY(5_PAD)) + PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR(UCHAR_MAMEKEY(3_PAD)) + PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0x90 + PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_UNKNOWN) // 0xff + INPUT_PORTS_END @@ -113,18 +350,17 @@ GFXDECODE_END uint32_t alphatpx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { const pen_t *pen = m_palette->pens(); - + int start = m_crtc->upscroll_offset(); for (int y = 0; y < 24; y++) { + int vramy = (start + y) % 24; for (int x = 0; x < 80; x++) { - uint8_t code = m_vram[(y * 24) + x] & 0x7f; - + uint8_t code = m_vram[(vramy * 128) + x]; // helwie44 must be 128d is 080h physical display-ram step line // draw 12 lines of the character for (int line = 0; line < 12; line++) { - uint8_t data = m_gfx[(code * 16) + line]; - + uint8_t data = m_gfx[((code & 0x7f) * 16) + line]; bitmap.pix32(y * 12 + line, x * 8 + 0) = pen[BIT(data, 0) ^ BIT(code, 7)]; bitmap.pix32(y * 12 + line, x * 8 + 1) = pen[BIT(data, 1) ^ BIT(code, 7)]; bitmap.pix32(y * 12 + line, x * 8 + 2) = pen[BIT(data, 2) ^ BIT(code, 7)]; @@ -147,6 +383,103 @@ uint32_t alphatpx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitm // Beeper +// FLOPPY +WRITE_LINE_MEMBER(alphatpx_state::fdcirq_w) +{ + m_fdc_irq = state; +} + +#include "debugger.h" + +WRITE_LINE_MEMBER(alphatpx_state::fdcdrq_w) +{ + m_fdc_drq = state; +} + +WRITE_LINE_MEMBER(alphatpx_state::fdchld_w) +{ + m_fdc_hld = state; +} + +/* + 7 Data Request (DRQ - inverted 1791-Signal) + 6 Interrupt Request (INTRQ - 1791-Signal) + 5 Head Load (HLD - inverted 1791-Signal) + 4 Ready 3 (Drive 3 ready) + 3 Ready 2 (Drive 2 ready) + 2 Ready l (Drive 1 ready) + 1 Write protect (the disk in the selected drive is write protected) + 0 HLT (Halt signal during head load and track change) +*/ +READ8_MEMBER(alphatpx_state::fdc_stat_r) +{ + uint8_t res = 0; + floppy_image_device *floppy1 = m_con1 ? m_con1->get_device() : nullptr; + floppy_image_device *floppy2 = m_con2 ? m_con2->get_device() : nullptr; + + res = m_fdc_drq ? 0x80 : 0x00; + res |= m_fdc_irq ? 0x40 : 0x00; + res |= m_fdc_hld ? 0x00 : 0x20; + if (floppy2) res |= floppy2->ready_r() ? 0x08 : 0; + if (floppy1) res |= floppy1->ready_r() ? 0x04 : 0; + if (m_curfloppy) res |= m_curfloppy->wpt_r() ? 0x02 : 0; + + return res; +} + +/* As far as we can tell, the mess of ttl de-inverts the bus */ +READ8_MEMBER(alphatpx_state::fdc_r) +{ + return m_fdc->gen_r(offset) ^ 0xff; +} + +WRITE8_MEMBER(alphatpx_state::fdc_w) +{ + m_fdc->gen_w(offset, data ^ 0xff); +} + +/* + 7 SEL1 - Select drive 1 + 6 SEL2 - Select drive 2 + 5 SEL3 - Select drive 3 + 4 MOTOR - Motor on + 3 DOOR - Drive door lock drives 1 + 2 (not possible with all drives) + 2 SIDESEL - Select disk side + 1 KOMP - write comp on/off + 0 RG J - Change separator stage to read +*/ +WRITE8_MEMBER(alphatpx_state::fdc_cmd_w) +{ + floppy_image_device *floppy = nullptr; + + logerror("%02x to fdc_cmd_w: motor %d side %d\n", data, (data & 0x10)>>4, (data & 4)>>2); + + // select drive + if (!(data & 0x80)) + { + floppy = m_con1 ? m_con1->get_device() : nullptr; + } + else if (!(data & 0x40)) + { + floppy = m_con2 ? m_con2->get_device() : nullptr; + } + + // selecting a new drive? + if (floppy != m_curfloppy) + { + m_fdc->set_floppy(floppy); + m_curfloppy = floppy; + } + + if (floppy != nullptr) + { + // side select + floppy->ss_w((data & 4) ? 0 : 1); + + // motor control (active low) + floppy->mon_w((data & 0x10) ? 1 : 0); + } +} //************************************************************************** // MACHINE @@ -154,20 +487,23 @@ uint32_t alphatpx_state::screen_update(screen_device &screen, bitmap_rgb32 &bitm void alphatpx_state::machine_start() { - // allocate memory - m_ram = std::make_unique<uint8_t[]>(0x10000); - // setup banking - membank("rom")->set_base(memregion("boot")->base()); - membank("ram_0000")->set_base(m_ram.get() + 0x0000); - membank("ram_1000")->set_base(m_ram.get() + 0x1000); - membank("ram_4000")->set_base(m_ram.get() + 0x4000); - membank("ram")->set_base(m_ram.get()); - - // register for save states - save_pointer(NAME(m_ram.get()), 0x10000); + membank("ram_0000")->set_base(m_ram.target()); + + + m_kbdclk = 0; // must be initialized here b/c mcs48_reset() causes write of 0xff to all ports } +void alphatpx_state::machine_reset() +{ + m_kbdread = 1; + m_kbdclk = 1; m_fdc_irq = m_fdc_drq = m_fdc_hld = 0; + m_curfloppy = nullptr; + + // look up floppies in advance + m_con1 = machine().device<floppy_connector>("fdc:0"); + m_con2 = machine().device<floppy_connector>("fdc:1"); +} //************************************************************************** // MACHINE DEFINITIONS @@ -178,14 +514,17 @@ static MACHINE_CONFIG_START( alphatp3 ) MCFG_CPU_PROGRAM_MAP(alphatp3_mem) MCFG_CPU_IO_MAP(alphatp3_io) - MCFG_CPU_ADD("mcu", I8041, XTAL_6MHz) - MCFG_DEVICE_DISABLE() + MCFG_CPU_ADD("kbdmcu", I8041, XTAL_12_8544MHz/2) + MCFG_MCS48_PORT_T0_IN_CB(READLINE(alphatpx_state, kbd_matrix_r)) + MCFG_MCS48_PORT_P1_OUT_CB(WRITE8(alphatpx_state, kbd_matrix_w)) + MCFG_MCS48_PORT_P2_IN_CB(READ8(alphatpx_state, kbd_port2_r)) + MCFG_MCS48_PORT_P2_OUT_CB(WRITE8(alphatpx_state, kbd_port2_w)) MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(alphatp3_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(17) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) // video hardware @@ -197,6 +536,7 @@ static MACHINE_CONFIG_START( alphatp3 ) MCFG_DEVICE_ADD("crtc", CRT5037, XTAL_12_8544MHz) MCFG_TMS9927_CHAR_WIDTH(8) + MCFG_TMS9927_VSYN_CALLBACK(INPUTLINE("maincpu", I8085_RST65_LINE)) MCFG_DEVCB_XOR(1) MCFG_VIDEO_SET_SCREEN("screen") @@ -210,7 +550,10 @@ static MACHINE_CONFIG_START( alphatp3 ) MCFG_DEVICE_ADD("uart", I8251, 0) // XTAL_4_9152MHz serial clock - MCFG_FD1791_ADD("fdc", XTAL_4MHz / 2) + MCFG_FD1791_ADD("fdc", XTAL_4MHz / 4) + MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(alphatpx_state, fdcirq_w)) + MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(alphatpx_state, fdcdrq_w)) + MCFG_WD_FDC_HLD_CALLBACK(WRITELINE(alphatpx_state, fdchld_w)) MCFG_FLOPPY_DRIVE_ADD("fdc:0", alphatp3_floppies, "525qd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_ADD("fdc:1", alphatp3_floppies, "525qd", floppy_image_device::default_floppy_formats) MACHINE_CONFIG_END @@ -220,21 +563,59 @@ MACHINE_CONFIG_END // ROM DEFINITIONS //************************************************************************** +// Alphatronic P2 +ROM_START( alphatp2 ) // P2 ROM space 0x1800 + ROM_REGION(0x1800, "boot", 0) + ROM_SYSTEM_BIOS(0, "p2_es", "p2_es") + ROMX_LOAD("caap_p2_es.bin", 0x0000, 0x1800, CRC(FBA85CD3) SHA1(E82482AF6D39F892B88868677572898945E02581), ROM_BIOS(1) ) // P2 SPANIEN + ROM_SYSTEM_BIOS(1, "p2_sks", "p2_sks") + ROMX_LOAD("mos3-p2_sks.bin", 0x0000, 0x1800, CRC(C045AADB) SHA1(1478530894E1DA53CC96DDB765DD1E03FF3ADEF1), ROM_BIOS(2) ) // P2 sks + ROM_SYSTEM_BIOS(2, "p2_ta", "p2_ta") + ROMX_LOAD("prom2p00.bin", 0x0000, 0x0800, CRC(c98d2982) SHA1(11e98ae441b7a9c8dfd22795f8208667959f1d1c), ROM_BIOS(3) ) // P2 TA + ROMX_LOAD("prom2p01.bin", 0x0800, 0x0800, CRC(14f19693) SHA1(7ecb66818a3e352fede1857a18cd12bf742603a9), ROM_BIOS(3) ) + ROMX_LOAD("prom2p02.bin", 0x1000, 0x0800, CRC(f304c3aa) SHA1(92213e77e4e6de12a4eaee25a9c1ec0ab54e93d4), ROM_BIOS(3) ) + + ROM_REGION(0x400, "kbdmcu", 0) + ROM_LOAD("p3_keyboard_8278.bin", 0x000, 0x400, CRC(5DB00D85) SHA1(0DC8E274A5AECE261EF60494901601C0D8B1EB51)) // borrowed from rfka01 machine #2 until we have a proper dump from a P2 + + ROM_REGION(0x800, "gfx", 0) + ROM_LOAD("cajp08_01_15.bin", 0x000, 0x800, CRC(4ed11dac) SHA1(9db9b8e0edf471faaddbb5521d6223121146bab8)) // borrowed from rfka01 machine #1 until we have a proper dump from a P2 +ROM_END + +// Alphatronic P3 ROM_START( alphatp3 ) - ROM_REGION(0x1000, "boot", 0) - ROM_LOAD("caap36_02_19.bin", 0x0000, 0x1000, CRC(23df6666) SHA1(5ea04cd299dec9951425eb91ecceb4818c4c6378)) + ROM_REGION(0x1800, "boot", 0) // P3 ROM space 0x1000 + ROM_LOAD("caap36_02_19.bin", 0x0000, 0x1000, CRC(23df6666) SHA1(5ea04cd299dec9951425eb91ecceb4818c4c6378)) // identical between rfka01 #1 and #2 - ROM_REGION(0x400, "mcu", 0) - ROM_LOAD("p3_8041.bin", 0x000, 0x400, NO_DUMP) + ROM_REGION(0x400, "kbdmcu", 0) +// ROM_LOAD("p3_keyboard_mab8041a.bin", 0x000, 0x400, CRC(4fd60dc1) SHA1(165f0c5afdef37385d06cf5caeae8422536de7fc)) // rfka01 machine #1 + ROM_LOAD("p3_keyboard_8278.bin", 0x000, 0x400, CRC(5DB00D85) SHA1(0DC8E274A5AECE261EF60494901601C0D8B1EB51)) // rfka01 machine #2 ROM_REGION(0x800, "gfx", 0) - ROM_LOAD("cajp08_01_15.bin", 0x000, 0x800, CRC(4ed11dac) SHA1(9db9b8e0edf471faaddbb5521d6223121146bab8)) + // ROM_LOAD("cajp08_00_15.bin", 0x000, 0x800, CRC(d6248209) SHA1(21689703de7183ecffb410eb8a6d516efe27da9d)) // rfka01 machine #2 + ROM_LOAD("cajp08_01_15.bin", 0x000, 0x800, CRC(4ed11dac) SHA1(9db9b8e0edf471faaddbb5521d6223121146bab8)) // rfka01 machine #1 ROM_END +// Alphatronic P30 +ROM_START( alphatp30 ) // P30 add-on card with 8088 needs to be emulated to boot DOS + ROM_REGION(0x1800, "boot", 0) + ROM_LOAD("hasl17.07.84.bin", 0x0000, 0x1000, CRC(6A91701B) SHA1(8A4F925D0FABAB37852A54D04E06DEB2AEAA349C)) // netmercer EPRom P30 ...wait for INT6.5 or INT5.5 with RIM to write char in hsync or hsync GAP-time !! + + ROM_REGION(0x400, "kbdmcu", 0) + ROM_LOAD("p3_keyboard_8278.bin", 0x000, 0x400, CRC(5DB00D85) SHA1(0DC8E274A5AECE261EF60494901601C0D8B1EB51)) // borrowed from rfka01 machine #2 + + ROM_REGION(0x800, "gfx", 0) + ROM_LOAD("cajp08_01_15.bin", 0x000, 0x800, CRC(4ed11dac) SHA1(9db9b8e0edf471faaddbb5521d6223121146bab8)) // borrowed from rfka01 machine #1 + +// ROM_LOAD("p30_8088.bin", 0x000, 0x4000, CRC(e6bf6dd5) SHA1(dc87210bbcd96f3c1370565174a45199e3c1bc70)) // P30 ROM from 8088 card +ROM_END + //************************************************************************** // SYSTEM DRIVERS //************************************************************************** -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1982, alphatp3, 0, 0, alphatp3, alphatp3, alphatpx_state, 0, "Triumph-Adler", "alphatronic P3", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 198?, alphatp2, alphatp3, 0, alphatp3, alphatp3, alphatpx_state, 0, "Triumph-Adler", "alphatronic P2", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1982, alphatp3, 0, 0, alphatp3, alphatp3, alphatpx_state, 0, "Triumph-Adler", "alphatronic P3", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 198?, alphatp30, alphatp3, 0, alphatp3, alphatp3, alphatpx_state, 0, "Triumph-Adler", "alphatronic P30",MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/alphatro.cpp b/src/mame/drivers/alphatro.cpp index a95673dba51..aeb128f7bc4 100644 --- a/src/mame/drivers/alphatro.cpp +++ b/src/mame/drivers/alphatro.cpp @@ -759,21 +759,21 @@ static MACHINE_CONFIG_START( alphatro ) MCFG_DEVICE_ADD("lowbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(rombank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x6000) /* A000 banking */ MCFG_DEVICE_ADD("cartbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(cartbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) /* F000 banking */ MCFG_DEVICE_ADD("monbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(monbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MACHINE_CONFIG_END diff --git a/src/mame/drivers/altair.cpp b/src/mame/drivers/altair.cpp index a1cb7132f21..0eb95a0bc28 100644 --- a/src/mame/drivers/altair.cpp +++ b/src/mame/drivers/altair.cpp @@ -25,6 +25,7 @@ #include "emu.h" #include "bus/rs232/rs232.h" +//#include "bus/s100/s100.h" #include "cpu/i8085/i8085.h" #include "machine/6850acia.h" #include "machine/clock.h" @@ -50,19 +51,18 @@ private: -static ADDRESS_MAP_START(altair_mem, AS_PROGRAM, 8, altair_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, altair_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0xfcff ) AM_RAM AM_SHARE("ram") AM_RANGE( 0xfd00, 0xfdff ) AM_ROM AM_RANGE( 0xff00, 0xffff ) AM_ROM ADDRESS_MAP_END -static ADDRESS_MAP_START(altair_io, AS_IO, 8, altair_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, altair_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) // TODO: Remove AM_MIRROR() and use SIO address S0-S7 - AM_RANGE( 0x00, 0x00 ) AM_MIRROR(0x10) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE( 0x01, 0x01 ) AM_MIRROR(0x10) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0x00, 0x01) AM_MIRROR(0x10) AM_DEVREADWRITE("acia", acia6850_device, read, write) ADDRESS_MAP_END /* Input ports */ @@ -93,8 +93,8 @@ void altair_state::machine_reset() static MACHINE_CONFIG_START( altair ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", I8080, XTAL_2MHz) - MCFG_CPU_PROGRAM_MAP(altair_mem) - MCFG_CPU_IO_MAP(altair_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_DEVICE_ADD("acia", ACIA6850, 0) diff --git a/src/mame/drivers/alto1.cpp b/src/mame/drivers/alto1.cpp new file mode 100644 index 00000000000..d939f8f4711 --- /dev/null +++ b/src/mame/drivers/alto1.cpp @@ -0,0 +1,78 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-05 Skeleton + +Xerox Alto I + +Similar in architecture to the Alto II and the Lilith, with 74181 ALUs and unique CPU, this was the first computer with a GUI. + + +************************************************************************************************************************************/ + +#include "emu.h" + +class alto1_state : public driver_device +{ +public: + alto1_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) +// , m_maincpu(*this, "maincpu") + { } + +private: +// required_device<cpu_device> m_maincpu; +}; + + +static INPUT_PORTS_START( alto1 ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( alto1 ) +MACHINE_CONFIG_END + +ROM_START( alto1 ) + ROM_REGION( 0x4000, "roms", 0 ) + ROM_LOAD( "00_23.bin", 0x0000, 0x0100, CRC(56cc822f) SHA1(b337ff7abf5da92008c72cf9585faadf552ede32) ) + ROM_LOAD( "01_23.bin", 0x0100, 0x0100, CRC(37ea8320) SHA1(85a60869f49b73cbf80392566253aa86a3b5767c) ) + ROM_LOAD( "02_23.bin", 0x0200, 0x0100, CRC(c8e5966d) SHA1(d519d9b3e08f5b0032a1b3487a4ee389764895b5) ) + ROM_LOAD( "03_23.bin", 0x0300, 0x0100, CRC(1d894299) SHA1(a7cd3071caa22d5efbd9b3a2368e1d131b66481b) ) + ROM_LOAD( "04_23.bin", 0x0400, 0x0100, CRC(e0870437) SHA1(075129edaa4992bd61b530cdc0b8ce8b363e5144) ) + ROM_LOAD( "05_23.bin", 0x0500, 0x0100, CRC(734f2bfc) SHA1(31a05a01ba635f2c58ae88acf54efc86f78fc621) ) + ROM_LOAD( "06_23.bin", 0x0600, 0x0100, CRC(2ee8f9ee) SHA1(5a5c0d464a268954ad458b905c0170ca95a2c2ac) ) + ROM_LOAD( "07_23.bin", 0x0700, 0x0100, CRC(c4f64e7a) SHA1(837333b8b2d9c8ce24571914f5e38c2b3491e7ce) ) + ROM_LOAD( "10_23.bin", 0x0800, 0x0100, CRC(ddc71e20) SHA1(813d503627e4d65b44af2f6038db30a81ff2d99f) ) + ROM_LOAD( "11_23.bin", 0x0900, 0x0100, CRC(cc5cca76) SHA1(6beac0676d11411325bb61d0be2e842a3b4d8dd0) ) + ROM_LOAD( "12_23.bin", 0x0a00, 0x0100, CRC(8d4fa6c0) SHA1(9c1d5f661c34678e65e09a2b1961818a98098c47) ) + ROM_LOAD( "13_23.bin", 0x0b00, 0x0100, CRC(f73d5e3b) SHA1(e4b2a33e6b8a54133d298e3d8e4856f85c84764c) ) + ROM_LOAD( "14_23.bin", 0x0c00, 0x0100, CRC(8eee7d4a) SHA1(c7917f096b8e56a5393c1901ecb0d5248e5592e1) ) + ROM_LOAD( "15_23.bin", 0x0d00, 0x0100, CRC(b648751c) SHA1(bb192751521e2d9948501cc3a68d92a15cf5eae8) ) + ROM_LOAD( "16_23.bin", 0x0e00, 0x0100, CRC(011a309e) SHA1(2914519695fc65a09f797203881c42d2e5abc782) ) + ROM_LOAD( "17_23.bin", 0x0f00, 0x0100, CRC(6ccb4acb) SHA1(c307ee5bb5c72a37bab389eb7668f9367811ec2d) ) + ROM_LOAD( "20_23.bin", 0x1000, 0x0100, CRC(00846711) SHA1(330a4cfd1d15b31cf361db72fc44172887af7db5) ) + ROM_LOAD( "21_23.bin", 0x1100, 0x0100, CRC(f08f993b) SHA1(803a872c192a081423f2a65364afd8d0531dfa64) ) + ROM_LOAD( "22_23.bin", 0x1200, 0x0100, CRC(0a15cca5) SHA1(c1ee6f77dfe830cb470a6929ab74d1dce52f4129) ) + ROM_LOAD( "23_23.bin", 0x1300, 0x0100, CRC(197adfe9) SHA1(18b37eb95d7300399adb01f003cbea611a4b48ad) ) + ROM_LOAD( "24_23.bin", 0x1400, 0x0100, CRC(4fe970f0) SHA1(d9791fc60a11d00989cf3b167530593461edb659) ) + ROM_LOAD( "25_23.bin", 0x1500, 0x0100, CRC(b2638af5) SHA1(7b789731af5b390ff51de113149f1af47ed1f4a2) ) + ROM_LOAD( "26_23.bin", 0x1600, 0x0100, CRC(3920d097) SHA1(3a2717368f1a0afb021789165c5c032dce2369dc) ) + ROM_LOAD( "27_23.bin", 0x1700, 0x0100, CRC(cb425e98) SHA1(69573461633a702c284df7a2e931588c289c8529) ) + ROM_LOAD( "30_23.bin", 0x1800, 0x0100, CRC(95a4763a) SHA1(1a28b04d51b9125f92f40f914bf43957383a1edc) ) + ROM_LOAD( "31_23.bin", 0x1900, 0x0100, CRC(0cb672a1) SHA1(20a1cf8295fbe7884fbb1dd26c61f122a43e030f) ) + ROM_LOAD( "32_23.bin", 0x1a00, 0x0100, CRC(46f51eb0) SHA1(5b4a0f94a9c133da0f734ae44b09e0f8bab86058) ) + ROM_LOAD( "33_23.bin", 0x1b00, 0x0100, CRC(491db151) SHA1(1c1a816609abcafe00c80731148140ff68ecac58) ) + ROM_LOAD( "34_23.bin", 0x1c00, 0x0100, CRC(ce6f062f) SHA1(fe8751aa3884c8d2cefc28fb116336912264b962) ) + ROM_LOAD( "35_23.bin", 0x1d00, 0x0100, CRC(d7f5eb01) SHA1(300f42e251eaa2a4ad37e17376c46bd272018d92) ) + ROM_LOAD( "36_23.bin", 0x1e00, 0x0100, CRC(d4b335f5) SHA1(ed4ed14ab8e8f50cc07ef8d394490ce168bd47be) ) + ROM_LOAD( "37_23.bin", 0x1f00, 0x0100, CRC(320eaae9) SHA1(44bd5bd1e4de054c6feb52dbc0dc4e848bab085e) ) + ROM_LOAD( "c0_23.bin", 0x2000, 0x0100, CRC(ef5634be) SHA1(912dc906069dfbed1c1a846bbe50ef1ed6dfe081) ) + ROM_LOAD( "c1_23.bin", 0x2100, 0x0100, CRC(b698f779) SHA1(ef33c9aefbf3e650bea33d42179a9c9743dfbe4d) ) + ROM_LOAD( "c2_23.bin", 0x2200, 0x0100, CRC(4dfc72e8) SHA1(56ac873d13cc1f351537145a586609a34f79d6af) ) + ROM_LOAD( "c3_23.bin", 0x2300, 0x0100, CRC(cd0e855b) SHA1(75d1bad4c5bded95703be358834a969aa2a56942) ) + ROM_LOAD( "ctr.bin", 0x2400, 0x0020, CRC(fc51b1d1) SHA1(e36c2a12a5da377394264899b5ae504e2ffda46e) ) + ROM_LOAD( "dp14.bin", 0x2500, 0x0100, CRC(8f54203b) SHA1(158d6c8b54d5cc0de7a902001a9ee207ed3358a0) ) + ROM_LOAD( "pram.bin", 0x2600, 0x0100, CRC(8087140e) SHA1(e17d9756150d41d6ff614afa86808a9c77516749) ) +ROM_END + +COMP( 1973, alto1, 0, 0, alto1, alto1, alto1_state, 0, "Xerox", "Alto I", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/altos2.cpp b/src/mame/drivers/altos2.cpp new file mode 100644 index 00000000000..081872f02cd --- /dev/null +++ b/src/mame/drivers/altos2.cpp @@ -0,0 +1,102 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-03 Skeleton + +Altos II terminal. Green screen. + +Chips: Z80A, 2x Z80DART, Z80CTC, X2210D, 2x CRT9006, CRT9007, CRT9021A, 8x 6116 + +Other: Beeper. Crystals: 4.9152, 8.000, 40.000 + +Keyboard: P8035L CPU, undumped 2716 labelled "358_2758" + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "cpu/z80/z80daisy.h" +#include "machine/z80ctc.h" +#include "machine/z80dart.h" +#include "machine/clock.h" +//#include "screen.h" + +class altos2_state : public driver_device +{ +public: + altos2_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_p_chargen(*this, "chargen") + , m_p_videoram(*this, "videoram") + { } + +private: + required_device<cpu_device> m_maincpu; + required_region_ptr<u8> m_p_chargen; + required_shared_ptr<u8> m_p_videoram; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, altos2_state ) + AM_RANGE(0x0000, 0x3fff) AM_ROM AM_REGION("roms", 0) + AM_RANGE(0xc000, 0xffff) AM_RAM AM_SHARE("videoram") +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_IO, 8, altos2_state) + ADDRESS_MAP_GLOBAL_MASK(0xff) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("uart1", z80dart_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("uart2", z80dart_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) +ADDRESS_MAP_END + +static INPUT_PORTS_START( altos2 ) +INPUT_PORTS_END + +static const z80_daisy_config daisy_chain[] = +{ + { "uart1" }, + { "uart2" }, + { "ctc" }, + { nullptr } +}; + +static MACHINE_CONFIG_START( altos2 ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) // unknown clock + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + MCFG_Z80_DAISY_CHAIN(daisy_chain) + + MCFG_DEVICE_ADD("ctc_clock", CLOCK, 4915200) // ctc & dart connections are guesswork + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc", z80ctc_device, trg0)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc", z80ctc_device, trg1)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc", z80ctc_device, trg2)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc", z80ctc_device, trg3)) + + MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_4MHz) + MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80CTC_ZC0_CB(DEVWRITELINE("uart1", z80dart_device, txca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", z80dart_device, rxca_w)) + MCFG_Z80CTC_ZC1_CB(DEVWRITELINE("uart1", z80dart_device, rxtxcb_w)) + MCFG_Z80CTC_ZC2_CB(DEVWRITELINE("uart2", z80dart_device, rxtxcb_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart2", z80dart_device, rxca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart2", z80dart_device, txca_w)) + + MCFG_DEVICE_ADD("uart1", Z80DART, XTAL_4MHz) + MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("uart2", Z80DART, XTAL_4MHz) + MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) +MACHINE_CONFIG_END + +ROM_START( altos2 ) + ROM_REGION( 0x4000, "roms", 0 ) + ROM_LOAD( "us_v1.2_15732.u32", 0x0000, 0x2000, CRC(a85f7be0) SHA1(3cfa954c916258d86f7f745d10ec2ff5e33261b3) ) + ROM_LOAD( "us_v1.2_15733.u19", 0x2000, 0x2000, CRC(45ebe88a) SHA1(33f16b382a2b365122ebf5e5f7312f8afa45ad15) ) + + ROM_REGION( 0x2000, "chargen", 0 ) + ROM_LOAD( "us_v1.1_14410.u34", 0x0000, 0x2000, CRC(0ebb78bf) SHA1(96a1f7d34ff35037cbbc93049c0e2b9c9f11f1db) ) +ROM_END + +COMP( 1983, altos2, 0, 0, altos2, altos2, altos2_state, 0, "Altos", "Altos II Terminal", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/altos5.cpp b/src/mame/drivers/altos5.cpp index b682b2fb20c..df6ccb18d75 100644 --- a/src/mame/drivers/altos5.cpp +++ b/src/mame/drivers/altos5.cpp @@ -15,6 +15,7 @@ #include "cpu/z80/z80daisy.h" #include "machine/z80ctc.h" #include "machine/z80pio.h" +#include "machine/z80sio.h" #include "machine/z80dart.h" #include "machine/z80dma.h" #include "machine/wd_fdc.h" @@ -65,7 +66,7 @@ private: required_device<floppy_connector> m_floppy1; }; -static ADDRESS_MAP_START(altos5_mem, AS_PROGRAM, 8, altos5_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, altos5_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0x0fff ) AM_READ_BANK("bankr0") AM_WRITE_BANK("bankw0") AM_RANGE( 0x1000, 0x1fff ) AM_READ_BANK("bankr1") AM_WRITE_BANK("bankw1") @@ -85,7 +86,7 @@ static ADDRESS_MAP_START(altos5_mem, AS_PROGRAM, 8, altos5_state) AM_RANGE( 0xf000, 0xffff ) AM_READ_BANK("bankrf") AM_WRITE_BANK("bankwf") ADDRESS_MAP_END -static ADDRESS_MAP_START(altos5_io, AS_IO, 8, altos5_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, altos5_state) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("dma", z80dma_device, read, write) AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("fdc", fd1797_device, read, write) @@ -95,7 +96,7 @@ static ADDRESS_MAP_START(altos5_io, AS_IO, 8, altos5_state) AM_RANGE(0x14, 0x17) AM_WRITE(port14_w) AM_RANGE(0x1c, 0x1f) AM_DEVREADWRITE("dart", z80dart_device, ba_cd_r, ba_cd_w) //AM_RANGE(0x20, 0x23) // Hard drive - AM_RANGE(0x2c, 0x2f) AM_DEVREADWRITE("sio", z80sio0_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x2c, 0x2f) AM_DEVREADWRITE("sio", z80sio_device, ba_cd_r, ba_cd_w) ADDRESS_MAP_END /* Input ports */ @@ -346,8 +347,8 @@ DRIVER_INIT_MEMBER( altos5_state, altos5 ) static MACHINE_CONFIG_START( altos5 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, XTAL_8MHz / 2) - MCFG_CPU_PROGRAM_MAP(altos5_mem) - MCFG_CPU_IO_MAP(altos5_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_Z80_DAISY_CHAIN(daisy_chain_intf) MCFG_DEVICE_ADD("ctc_clock", CLOCK, XTAL_8MHz / 4) // 2MHz @@ -380,29 +381,28 @@ static MACHINE_CONFIG_START( altos5 ) // Channel B - printer MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio", Z80SIO0, XTAL_8MHz / 2) + MCFG_DEVICE_ADD("sio", Z80SIO, XTAL_8MHz / 2) // Channel A - console #2 // WRDY connects to (altos5_state, fdc_intrq_w) // Channel B - console #1 - MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) - MCFG_Z80DART_OUT_DTRB_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) - MCFG_Z80DART_OUT_RTSB_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_8MHz / 2) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_Z80CTC_ZC0_CB(DEVWRITELINE("sio", z80dart_device, rxtxcb_w)) // SIO Ch B + MCFG_Z80CTC_ZC0_CB(DEVWRITELINE("sio", z80sio_device, rxtxcb_w)) // SIO Ch B MCFG_Z80CTC_ZC1_CB(DEVWRITELINE("dart", z80dart_device, txca_w)) // Z80DART Ch A, SIO Ch A MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("dart" ,z80dart_device, rxca_w)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio" ,z80sio0_device, txca_w)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio" ,z80sio0_device, rxca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio" ,z80sio_device, txca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio" ,z80sio_device, rxca_w)) MCFG_Z80CTC_ZC2_CB(DEVWRITELINE("dart", z80dart_device, rxtxcb_w)) // Z80DART Ch B MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio0_device, rxb_w)) - MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio", z80sio0_device, dcdb_w)) - MCFG_RS232_RI_HANDLER(DEVWRITELINE("sio", z80sio0_device, rib_w)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio0_device, ctsb_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio_device, rxb_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio", z80sio_device, dcdb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio_device, ctsb_w)) MCFG_FD1797_ADD("fdc", XTAL_8MHz / 8) MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(altos5_state, fdc_intrq_w)) diff --git a/src/mame/drivers/altos8600.cpp b/src/mame/drivers/altos8600.cpp index aafb96fdab6..af9ddbb1615 100644 --- a/src/mame/drivers/altos8600.cpp +++ b/src/mame/drivers/altos8600.cpp @@ -691,7 +691,7 @@ static MACHINE_CONFIG_START(altos8600) MCFG_CPU_ADD("dmac", I8089, XTAL_5MHz) MCFG_CPU_PROGRAM_MAP(dmac_mem) MCFG_CPU_IO_MAP(dmac_io) - MCFG_I8089_DATABUS_WIDTH(16) + MCFG_I8089_DATA_WIDTH(16) MCFG_I8089_SINTR1(WRITELINE(altos8600_state, sintr1_w)) MCFG_I8089_SINTR2(DEVWRITELINE("pic8259_2", pic8259_device, ir4_w)) diff --git a/src/mame/drivers/amiga.cpp b/src/mame/drivers/amiga.cpp index 1e528d1a402..19851c14393 100644 --- a/src/mame/drivers/amiga.cpp +++ b/src/mame/drivers/amiga.cpp @@ -1393,15 +1393,15 @@ static MACHINE_CONFIG_DERIVED( a1000, amiga_base ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(a1000_overlay_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_DEVICE_ADD("bootrom", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(a1000_bootrom_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(19) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(19) MCFG_ADDRESS_MAP_BANK_STRIDE(0x40000) MCFG_SOFTWARE_LIST_ADD("a1000_list", "amiga_a1000") @@ -1430,8 +1430,8 @@ static MACHINE_CONFIG_DERIVED( a2000, amiga_base ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_512kb_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) // real-time clock @@ -1475,8 +1475,8 @@ static MACHINE_CONFIG_DERIVED( a500, amiga_base ) //MCFG_DEVICE_PROGRAM_MAP(overlay_512kb_map) MCFG_DEVICE_PROGRAM_MAP(overlay_1mb_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) // cpu slot @@ -1519,8 +1519,8 @@ static MACHINE_CONFIG_DERIVED( cdtv, amiga_base ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_1mb_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) // standard sram @@ -1582,8 +1582,8 @@ static MACHINE_CONFIG_DERIVED( a3000, amiga_base ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_1mb_map32) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) // real-time clock @@ -1615,8 +1615,8 @@ static MACHINE_CONFIG_DERIVED( a500p, amiga_base ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_1mb_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) // real-time clock @@ -1652,8 +1652,8 @@ static MACHINE_CONFIG_DERIVED( a600, amiga_base ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_2mb_map16) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_GAYLE_ADD("gayle", amiga_state::CLK_28M_PAL / 2, a600_state::GAYLE_ID) @@ -1697,8 +1697,8 @@ static MACHINE_CONFIG_DERIVED( a1200, amiga_base ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_2mb_map32) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_DEVICE_MODIFY("screen") @@ -1760,8 +1760,8 @@ static MACHINE_CONFIG_DERIVED( a4000, amiga_base ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_2mb_map32) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_DEVICE_MODIFY("screen") @@ -1835,8 +1835,8 @@ static MACHINE_CONFIG_DERIVED( cd32, amiga_base ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_2mb_map32) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_I2CMEM_ADD("i2cmem") diff --git a/src/mame/drivers/ampex.cpp b/src/mame/drivers/ampex.cpp new file mode 100644 index 00000000000..de32ba7e4b2 --- /dev/null +++ b/src/mame/drivers/ampex.cpp @@ -0,0 +1,63 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-05 Skeleton + +Ampex Dialogue 80 terminal + +Chips: CRT-5037, COM8017, SMC5016-5, MK3880N (Z80) +Crystals: 4.9152, 23.814 +Other: Beeper, 5x 10sw-dips. + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" + +class ampex_state : public driver_device +{ +public: + ampex_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_p_chargen(*this, "chargen") + { } + +private: + required_device<cpu_device> m_maincpu; + required_region_ptr<u8> m_p_chargen; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, ampex_state ) + AM_RANGE(0x0000, 0x2fff) AM_ROM AM_REGION("roms", 0) + AM_RANGE(0x4000, 0x43ff) AM_RAM // main RAM + AM_RANGE(0x4400, 0x57ff) AM_RAM // expansion RAM + AM_RANGE(0x5841, 0x5841) AM_WRITENOP // ??? + AM_RANGE(0x5842, 0x5842) AM_READNOP // ??? + AM_RANGE(0x8000, 0x9fff) AM_RAM + AM_RANGE(0xc000, 0xcfff) AM_RAM // video RAM +ADDRESS_MAP_END + +static INPUT_PORTS_START( ampex ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( ampex ) + MCFG_CPU_ADD("maincpu", Z80, 2'000'000) // no idea of clock. + MCFG_CPU_PROGRAM_MAP(mem_map) +MACHINE_CONFIG_END + +ROM_START( dialog80 ) + ROM_REGION( 0x3000, "roms", 0 ) + ROM_LOAD( "3505240-01.u102", 0x0000, 0x0800, CRC(c5315780) SHA1(f2a8924f277d04bf4407f9b71b8d2788df0b1dc2) ) + ROM_LOAD( "3505240-02.u104", 0x0800, 0x0800, CRC(3fefa114) SHA1(d83c00605ae6c02d3aac7b572eb2bf615f0d4f3a) ) + ROM_LOAD( "3505240-03.u103", 0x1000, 0x0800, CRC(03abbcb2) SHA1(e5d382eefc3baff8f3e4d6b13219cb5eb1ca32f2) ) + ROM_LOAD( "3505240-04.u105", 0x1800, 0x0800, CRC(c051e15f) SHA1(16a066c39743ddf9a7da54bb8c03e2090d461862) ) + ROM_LOAD( "3505240-05.u100", 0x2000, 0x0800, CRC(6db6365b) SHA1(a68c83e554c2493645287e369749a07474723452) ) + ROM_LOAD( "3505240-06.u101", 0x2800, 0x0800, CRC(8f9a4969) SHA1(f9cd434f8d287c584cda429b45ca2537fdfb436b) ) + + ROM_REGION( 0x0800, "chargen", 0 ) + ROM_LOAD( "3505240-07.u69", 0x0000, 0x0800, CRC(838a16cb) SHA1(4301324b9fe9453c2d277972f9464c4214c6793d) ) +ROM_END + +COMP( 1980, dialog80, 0, 0, ampex, ampex, ampex_state, 0, "Ampex", "Dialogue 80", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/ampscarp.cpp b/src/mame/drivers/ampscarp.cpp index 9c6e78bee44..77a28708bea 100644 --- a/src/mame/drivers/ampscarp.cpp +++ b/src/mame/drivers/ampscarp.cpp @@ -9,31 +9,30 @@ Motorola AMPS Car Phone. ************************************************************************************************************************************/ #include "emu.h" -//#include "cpu/mcs51/mcs51.h" class ampscarp_state : public driver_device { public: ampscarp_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) -// , maincpu(*this, "maincpu") +// , m_maincpu(*this, "maincpu") { } -protected: -// required_device<i80c52_device> maincpu; +private: +// required_device<cpu_device> m_maincpu; }; +//static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, ampscarp_state ) +//ADDRESS_MAP_END + static INPUT_PORTS_START( ampscarp ) INPUT_PORTS_END -//static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, ampscarp_state ) -//ADDRESS_MAP_END - static MACHINE_CONFIG_START( ampscarp ) MACHINE_CONFIG_END ROM_START( ampscarp ) - ROM_REGION( 0x20000, "maincpu", 0 ) + ROM_REGION( 0x20000, "maincpu", 0 ) // unknown cpu ROM_LOAD( "motorola_amps_car_phone_dump.bin", 0x0000, 0x20000, CRC(677ec85e) SHA1(219611b6c4b16461705e2df61d79a0f7ac8f529f) ) ROM_END diff --git a/src/mame/drivers/amusco.cpp b/src/mame/drivers/amusco.cpp index f55d49fda8d..af39e4757e3 100644 --- a/src/mame/drivers/amusco.cpp +++ b/src/mame/drivers/amusco.cpp @@ -103,7 +103,6 @@ class amusco_state : public driver_device public: amusco_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_videoram(*this, "videoram"), m_maincpu(*this, "maincpu"), m_gfxdecode(*this, "gfxdecode"), m_pit(*this, "pit8253"), @@ -114,11 +113,7 @@ public: m_hopper(*this, "hopper") { } - required_shared_ptr<uint8_t> m_videoram; - tilemap_t *m_bg_tilemap; TILE_GET_INFO_MEMBER(get_bg_tile_info); - virtual void video_start() override; - virtual void machine_start() override; DECLARE_WRITE_LINE_MEMBER(coin_irq); DECLARE_READ8_MEMBER(mc6845_r); DECLARE_WRITE8_MEMBER(mc6845_w); @@ -131,6 +126,13 @@ public: DECLARE_WRITE8_MEMBER(rtc_control_w); MC6845_ON_UPDATE_ADDR_CHANGED(crtc_addr); MC6845_UPDATE_ROW(update_row); + DECLARE_PALETTE_INIT(amusco); +protected: + virtual void video_start() override; + virtual void machine_start() override; +private: + std::unique_ptr<uint8_t []> m_videoram; + tilemap_t *m_bg_tilemap; required_device<cpu_device> m_maincpu; required_device<gfxdecode_device> m_gfxdecode; @@ -143,6 +145,7 @@ public: uint8_t m_mc6845_address; uint16_t m_video_update_address; bool m_blink_state; + static constexpr uint32_t videoram_size = 0x10000; }; @@ -176,6 +179,11 @@ void amusco_state::video_start() { m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(amusco_state::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 8, 10, 74, 24); m_blink_state = false; + + m_videoram = std::make_unique<uint8_t []>(videoram_size); + std::fill_n(m_videoram.get(), videoram_size, 0); + + save_pointer(NAME(m_videoram.get()), videoram_size); } void amusco_state::machine_start() @@ -189,7 +197,6 @@ void amusco_state::machine_start() static ADDRESS_MAP_START( amusco_mem_map, AS_PROGRAM, 8, amusco_state ) AM_RANGE(0x00000, 0x0ffff) AM_RAM - AM_RANGE(0xec000, 0xecfff) AM_RAM AM_SHARE("videoram") // placeholder AM_RANGE(0xf8000, 0xfffff) AM_ROM ADDRESS_MAP_END @@ -439,7 +446,7 @@ static const gfx_layout charlayout = ******************************/ static GFXDECODE_START( amusco ) - GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, /*8*/ 1 ) // current palette has only 8 colors... + GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 8 ) // current palette has only 8 colors... GFXDECODE_END @@ -465,6 +472,50 @@ MC6845_UPDATE_ROW(amusco_state::update_row) m_bg_tilemap->draw(*m_screen, bitmap, rowrect, 0, 0); } +PALETTE_INIT_MEMBER(amusco_state,amusco) +{ + // add some templates first + for (int i = 0; i < 8; i++) + { + for(int j=0;j<8;j++) + palette.set_pen_color(i*8+j, pal1bit(i >> 2), pal1bit(i >> 1), pal1bit(i >> 0)); + } + + // override colors +/**/palette.set_pen_color(0, pal1bit(0), pal1bit(0), pal1bit(0)); +/**/palette.set_pen_color(1, pal1bit(1), pal1bit(1), pal1bit(1)); + +/**/palette.set_pen_color(1*8+0, pal1bit(0), pal1bit(0), pal1bit(0)); +/**/palette.set_pen_color(1*8+1, pal1bit(1), pal1bit(0), pal1bit(0)); + +/**/palette.set_pen_color(2*8+0, pal1bit(0), pal1bit(0), pal1bit(0)); +/**/palette.set_pen_color(2*8+1, pal1bit(0), pal1bit(0), pal1bit(1)); + +/**/palette.set_pen_color(3*8+0, pal1bit(0), pal1bit(0), pal1bit(0)); +/**/palette.set_pen_color(3*8+1, pal1bit(0), pal1bit(1), pal1bit(0)); + + + palette.set_pen_color(5*8+0, pal1bit(0), pal1bit(0), pal1bit(0)); +/**/palette.set_pen_color(5*8+1, pal2bit(0), pal2bit(0), pal2bit(1)); +/**/palette.set_pen_color(5*8+2, pal1bit(1), pal1bit(1), pal1bit(0)); + palette.set_pen_color(5*8+3, pal1bit(0), pal1bit(0), pal1bit(0)); + palette.set_pen_color(5*8+4, pal1bit(1), pal1bit(1), pal1bit(1)); + palette.set_pen_color(5*8+5, pal2bit(2), pal2bit(1), pal2bit(0)); +/**/palette.set_pen_color(5*8+6, pal1bit(0), pal1bit(0), pal1bit(1)); +/**/palette.set_pen_color(5*8+7, pal1bit(1), pal1bit(1), pal1bit(1)); + + palette.set_pen_color(6*8+0, pal1bit(0), pal1bit(0), pal1bit(0)); +/**/palette.set_pen_color(6*8+1, pal2bit(1), pal2bit(0), pal2bit(0)); +/**/palette.set_pen_color(6*8+2, pal1bit(1), pal1bit(1), pal1bit(0)); + palette.set_pen_color(6*8+3, pal1bit(0), pal1bit(0), pal1bit(0)); + palette.set_pen_color(6*8+4, pal1bit(1), pal1bit(1), pal1bit(1)); + palette.set_pen_color(6*8+5, pal2bit(2), pal2bit(1), pal2bit(0)); +/**/palette.set_pen_color(6*8+6, pal1bit(0), pal1bit(0), pal1bit(1)); +/**/palette.set_pen_color(6*8+7, pal1bit(1), pal1bit(1), pal1bit(1)); + + +} + /************************* * Machine Drivers * *************************/ @@ -520,7 +571,8 @@ static MACHINE_CONFIG_START( amusco ) MCFG_GFXDECODE_ADD("gfxdecode", "palette", amusco) - MCFG_PALETTE_ADD_3BIT_GBR("palette") + MCFG_PALETTE_ADD("palette",8*8) + MCFG_PALETTE_INIT_OWNER(amusco_state, amusco) MCFG_MC6845_ADD("crtc", R6545_1, "screen", CRTC_CLOCK) /* guess */ MCFG_MC6845_SHOW_BORDER_AREA(false) diff --git a/src/mame/drivers/amust.cpp b/src/mame/drivers/amust.cpp index 356d465ccb3..6a7b8db8d4b 100644 --- a/src/mame/drivers/amust.cpp +++ b/src/mame/drivers/amust.cpp @@ -84,8 +84,9 @@ ToDo: #include "cpu/z80/z80.h" #include "machine/i8251.h" #include "machine/i8255.h" -#include "machine/keyboard.h" #include "machine/pit8253.h" +#include "machine/clock.h" +#include "bus/rs232/rs232.h" #include "machine/upd765.h" #include "sound/beep.h" #include "video/mc6845.h" @@ -115,8 +116,6 @@ public: DECLARE_DRIVER_INIT(amust); DECLARE_MACHINE_RESET(amust); - DECLARE_READ8_MEMBER(port00_r); - DECLARE_READ8_MEMBER(port01_r); DECLARE_READ8_MEMBER(port04_r); DECLARE_WRITE8_MEMBER(port04_w); DECLARE_READ8_MEMBER(port05_r); @@ -172,19 +171,17 @@ void amust_state::device_timer(emu_timer &timer, device_timer_id id, int param, // floppy->ss_w(BIT(data, 4)); //} -static ADDRESS_MAP_START(amust_mem, AS_PROGRAM, 8, amust_state) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, amust_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0xf7ff) AM_RAM AM_RANGE(0xf800, 0xffff) AM_READ_BANK("bankr0") AM_WRITE_BANK("bankw0") ADDRESS_MAP_END -static ADDRESS_MAP_START(amust_io, AS_IO, 8, amust_state) +static ADDRESS_MAP_START( io_map, AS_IO, 8, amust_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) - //AM_RANGE(0x00, 0x00) AM_DEVREADWRITE("uart1", i8251_device, data_r, data_w) - //AM_RANGE(0x01, 0x01) AM_DEVREADWRITE("uart1", i8251_device, status_r, control_w) - AM_RANGE(0x00, 0x00) AM_READ(port00_r) - AM_RANGE(0x01, 0x01) AM_READ(port01_r) + AM_RANGE(0x00, 0x00) AM_DEVREADWRITE("uart1", i8251_device, data_r, data_w) + AM_RANGE(0x01, 0x01) AM_DEVREADWRITE("uart1", i8251_device, status_r, control_w) AM_RANGE(0x02, 0x02) AM_DEVREADWRITE("uart2", i8251_device, data_r, data_w) AM_RANGE(0x03, 0x03) AM_DEVREADWRITE("uart2", i8251_device, status_r, control_w) AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("ppi1", i8255_device, read, write) @@ -215,18 +212,6 @@ static INPUT_PORTS_START( amust ) PORT_DIPSETTING( 0x08, "4" ) INPUT_PORTS_END -READ8_MEMBER( amust_state::port00_r ) -{ - u8 ret = m_term_data; - m_term_data = 0; - return ret; -} - -READ8_MEMBER( amust_state::port01_r ) -{ - return 0xff; -} - // bodgy INTERRUPT_GEN_MEMBER( amust_state::irq_vs ) { @@ -315,11 +300,6 @@ WRITE8_MEMBER( amust_state::port0d_w ) m_p_videoram[video_address] = data; } -void amust_state::kbd_put(u8 data) -{ - m_term_data = data; -} - /* F4 Character Displayer */ static const gfx_layout amust_charlayout = { @@ -393,8 +373,8 @@ DRIVER_INIT_MEMBER( amust_state, amust ) static MACHINE_CONFIG_START( amust ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",Z80, XTAL_16MHz / 4) - MCFG_CPU_PROGRAM_MAP(amust_mem) - MCFG_CPU_IO_MAP(amust_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_CPU_VBLANK_INT_DRIVER("screen", amust_state, irq_vs) MCFG_MACHINE_RESET_OVERRIDE(amust_state, amust) @@ -419,29 +399,31 @@ static MACHINE_CONFIG_START( amust ) MCFG_MC6845_CHAR_WIDTH(8) MCFG_MC6845_UPDATE_ROW_CB(amust_state, crtc_update_row) - MCFG_DEVICE_ADD("keybd", GENERIC_KEYBOARD, 0) - MCFG_GENERIC_KEYBOARD_CB(PUT(amust_state, kbd_put)) MCFG_UPD765A_ADD("fdc", false, true) MCFG_FLOPPY_DRIVE_ADD("fdc:0", amust_floppies, "525qd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_SOUND(true) MCFG_FLOPPY_DRIVE_ADD("fdc:1", amust_floppies, "525qd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_SOUND(true) - //MCFG_DEVICE_ADD("uart1", I8251, 0) - //MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) - //MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) - //MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_DEVICE_ADD("uart_clock", CLOCK, 153600) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("uart1", i8251_device, write_txc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", i8251_device, write_rxc)) + + MCFG_DEVICE_ADD("uart1", I8251, 0) + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "keyboard") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart1", i8251_device, write_rxd)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart1", i8251_device, write_cts)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart1", i8251_device, write_dsr)) MCFG_DEVICE_ADD("uart2", I8251, 0) //MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) //MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) //MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) - //MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") - //MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart8251", i8251_device, write_rxd)) - //MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart8251", i8251_device, write_cts)) - //MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart8251", i8251_device, write_dsr)) - MCFG_DEVICE_ADD("pit", PIT8253, 0) MCFG_DEVICE_ADD("ppi1", I8255A, 0) diff --git a/src/mame/drivers/apple2.cpp b/src/mame/drivers/apple2.cpp index 9581987ca54..0527d461daf 100644 --- a/src/mame/drivers/apple2.cpp +++ b/src/mame/drivers/apple2.cpp @@ -78,6 +78,7 @@ II Plus: RAM options reduced to 16/32/48 KB. #include "bus/a2bus/ramcard16k.h" #include "bus/a2bus/timemasterho.h" #include "bus/a2bus/ssprite.h" +#include "bus/a2bus/ssbapple.h" #include "screen.h" #include "softlist.h" @@ -146,8 +147,19 @@ public: DECLARE_READ8_MEMBER(ram_r); DECLARE_WRITE8_MEMBER(ram_w); - DECLARE_READ8_MEMBER(c000_r); - DECLARE_WRITE8_MEMBER(c000_w); + DECLARE_READ8_MEMBER(keyb_data_r); + DECLARE_READ8_MEMBER(keyb_strobe_r); + DECLARE_WRITE8_MEMBER(keyb_strobe_w); + DECLARE_READ8_MEMBER(cassette_toggle_r); + DECLARE_WRITE8_MEMBER(cassette_toggle_w); + DECLARE_READ8_MEMBER(speaker_toggle_r); + DECLARE_WRITE8_MEMBER(speaker_toggle_w); + DECLARE_READ8_MEMBER(utility_strobe_r); + DECLARE_WRITE8_MEMBER(utility_strobe_w); + DECLARE_READ8_MEMBER(switches_r); + DECLARE_READ8_MEMBER(flags_r); + DECLARE_READ8_MEMBER(controller_strobe_r); + DECLARE_WRITE8_MEMBER(controller_strobe_w); DECLARE_WRITE_LINE_MEMBER(txt_w); DECLARE_WRITE_LINE_MEMBER(mix_w); DECLARE_WRITE_LINE_MEMBER(scr_w); @@ -200,7 +212,6 @@ private: device_a2bus_card_interface *m_slotdevice[8]; - void do_io(address_space &space, int offset); uint8_t read_floatingbus(); }; @@ -482,43 +493,6 @@ uint32_t napple2_state::screen_update_jp(screen_device &screen, bitmap_ind16 &bi /*************************************************************************** I/O ***************************************************************************/ -// most softswitches don't care about read vs write, so handle them here -void napple2_state::do_io(address_space &space, int offset) -{ - if(machine().side_effect_disabled()) - { - return; - } - - switch (offset) - { - case 0x20: - m_cassette_state ^= 1; - m_cassette->output(m_cassette_state ? 1.0f : -1.0f); - break; - - case 0x30: - m_speaker_state ^= 1; - m_speaker->level_w(m_speaker_state); - break; - - case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: - case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: - m_softlatch->write_bit((offset & 0x0e) >> 1, offset & 0x01); - break; - - case 0x68: // IIgs STATE register, which ProDOS touches - break; - - case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: - case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: - m_joystick_x1_time = machine().time().as_double() + m_x_calibration * m_joy1x->read(); - m_joystick_y1_time = machine().time().as_double() + m_y_calibration * m_joy1y->read(); - m_joystick_x2_time = machine().time().as_double() + m_x_calibration * m_joy2x->read(); - m_joystick_y2_time = machine().time().as_double() + m_y_calibration * m_joy2y->read(); - break; - } -} WRITE_LINE_MEMBER(napple2_state::txt_w) { @@ -573,77 +547,124 @@ WRITE_LINE_MEMBER(napple2_state::an3_w) m_an3 = state; } -READ8_MEMBER(napple2_state::c000_r) +READ8_MEMBER(napple2_state::keyb_data_r) { - switch (offset) - { - case 0x00: // keyboard latch - return m_transchar | m_strobe; - - case 0x10: // reads any key down, clears strobe - { - uint8_t rv = m_transchar | (m_anykeydown ? 0x80 : 0x00); - m_strobe = 0; - return rv; - } - - case 0x60: // cassette in - case 0x68: - return m_cassette->input() > 0.0 ? 0x80 : 0; + // keyboard latch + return m_transchar | m_strobe; +} - case 0x61: // button 0 - case 0x69: - return (m_joybuttons->read() & 0x10) ? 0x80 : 0; +READ8_MEMBER(napple2_state::keyb_strobe_r) +{ + // reads any key down, clears strobe + uint8_t rv = m_transchar | (m_anykeydown ? 0x80 : 0x00); + if (!machine().side_effect_disabled()) + m_strobe = 0; + return rv; +} - case 0x62: // button 1 - case 0x6a: - return (m_joybuttons->read() & 0x20) ? 0x80 : 0; +WRITE8_MEMBER(napple2_state::keyb_strobe_w) +{ + // clear keyboard latch + m_strobe = 0; +} - case 0x63: // button 2 - case 0x6b: - // check if SHIFT key mod configured - if (m_sysconfig->read() & 0x04) - { - return ((m_joybuttons->read() & 0x40) || (m_kbspecial->read() & 0x06)) ? 0x80 : 0; - } - return (m_joybuttons->read() & 0x40) ? 0x80 : 0; +READ8_MEMBER(napple2_state::cassette_toggle_r) +{ + if (!machine().side_effect_disabled()) + cassette_toggle_w(space, offset, 0); + return read_floatingbus(); +} - case 0x64: // joy 1 X axis - case 0x6c: - return (space.machine().time().as_double() < m_joystick_x1_time) ? 0x80 : 0; +WRITE8_MEMBER(napple2_state::cassette_toggle_w) +{ + m_cassette_state ^= 1; + m_cassette->output(m_cassette_state ? 1.0f : -1.0f); +} - case 0x65: // joy 1 Y axis - case 0x6d: - return (space.machine().time().as_double() < m_joystick_y1_time) ? 0x80 : 0; +READ8_MEMBER(napple2_state::speaker_toggle_r) +{ + if (!machine().side_effect_disabled()) + speaker_toggle_w(space, offset, 0); + return read_floatingbus(); +} - case 0x66: // joy 2 X axis - case 0x6e: - return (space.machine().time().as_double() < m_joystick_x2_time) ? 0x80 : 0; +WRITE8_MEMBER(napple2_state::speaker_toggle_w) +{ + m_speaker_state ^= 1; + m_speaker->level_w(m_speaker_state); +} - case 0x67: // joy 2 Y axis - case 0x6f: - return (space.machine().time().as_double() < m_joystick_y2_time) ? 0x80 : 0; +READ8_MEMBER(napple2_state::utility_strobe_r) +{ + if (!machine().side_effect_disabled()) + utility_strobe_w(space, offset, 0); + return read_floatingbus(); +} - default: - do_io(space, offset); - break; - } +WRITE8_MEMBER(napple2_state::utility_strobe_w) +{ + // pulses pin 5 of game I/O connector +} +READ8_MEMBER(napple2_state::switches_r) +{ + if (!machine().side_effect_disabled()) + m_softlatch->write_bit((offset & 0x0e) >> 1, offset & 0x01); return read_floatingbus(); } -WRITE8_MEMBER(napple2_state::c000_w) +READ8_MEMBER(napple2_state::flags_r) { + // Y output of 74LS251 at H14 read as D7 switch (offset) { - case 0x10: // clear keyboard latch - m_strobe = 0; - break; + case 0: // cassette in + return m_cassette->input() > 0.0 ? 0x80 : 0; + + case 1: // button 0 + return (m_joybuttons->read() & 0x10) ? 0x80 : 0; + + case 2: // button 1 + return (m_joybuttons->read() & 0x20) ? 0x80 : 0; + + case 3: // button 2 + // check if SHIFT key mod configured + if (m_sysconfig->read() & 0x04) + { + return ((m_joybuttons->read() & 0x40) || (m_kbspecial->read() & 0x06)) ? 0x80 : 0; + } + return (m_joybuttons->read() & 0x40) ? 0x80 : 0; + + case 4: // joy 1 X axis + return (space.machine().time().as_double() < m_joystick_x1_time) ? 0x80 : 0; + + case 5: // joy 1 Y axis + return (space.machine().time().as_double() < m_joystick_y1_time) ? 0x80 : 0; - default: - do_io(space, offset); - break; + case 6: // joy 2 X axis + return (space.machine().time().as_double() < m_joystick_x2_time) ? 0x80 : 0; + + case 7: // joy 2 Y axis + return (space.machine().time().as_double() < m_joystick_y2_time) ? 0x80 : 0; } + + // this is never reached + return 0; +} + +READ8_MEMBER(napple2_state::controller_strobe_r) +{ + if (!machine().side_effect_disabled()) + controller_strobe_w(space, offset, 0); + return read_floatingbus(); +} + +WRITE8_MEMBER(napple2_state::controller_strobe_w) +{ + m_joystick_x1_time = machine().time().as_double() + m_x_calibration * m_joy1x->read(); + m_joystick_y1_time = machine().time().as_double() + m_y_calibration * m_joy1y->read(); + m_joystick_x2_time = machine().time().as_double() + m_x_calibration * m_joy2x->read(); + m_joystick_y2_time = machine().time().as_double() + m_y_calibration * m_joy2y->read(); } READ8_MEMBER(napple2_state::c080_r) @@ -924,7 +945,14 @@ WRITE8_MEMBER(napple2_state::ram_w) static ADDRESS_MAP_START( apple2_map, AS_PROGRAM, 8, napple2_state ) AM_RANGE(0x0000, 0xbfff) AM_READWRITE(ram_r, ram_w) - AM_RANGE(0xc000, 0xc07f) AM_READWRITE(c000_r, c000_w) + AM_RANGE(0xc000, 0xc000) AM_MIRROR(0xf) AM_READ(keyb_data_r) AM_WRITENOP + AM_RANGE(0xc010, 0xc010) AM_MIRROR(0xf) AM_READWRITE(keyb_strobe_r, keyb_strobe_w) + AM_RANGE(0xc020, 0xc020) AM_MIRROR(0xf) AM_READWRITE(cassette_toggle_r, cassette_toggle_w) + AM_RANGE(0xc030, 0xc030) AM_MIRROR(0xf) AM_READWRITE(speaker_toggle_r, speaker_toggle_w) + AM_RANGE(0xc040, 0xc040) AM_MIRROR(0xf) AM_READWRITE(utility_strobe_r, utility_strobe_w) + AM_RANGE(0xc050, 0xc05f) AM_READ(switches_r) AM_DEVWRITE("softlatch", addressable_latch_device, write_a0) + AM_RANGE(0xc060, 0xc067) AM_MIRROR(0x8) AM_READ(flags_r) AM_WRITENOP // includes IIgs STATE register, which ProDOS touches + AM_RANGE(0xc070, 0xc070) AM_MIRROR(0xf) AM_READWRITE(controller_strobe_r, controller_strobe_w) AM_RANGE(0xc080, 0xc0ff) AM_READWRITE(c080_r, c080_w) AM_RANGE(0xc100, 0xc7ff) AM_READWRITE(c100_r, c100_w) AM_RANGE(0xc800, 0xcfff) AM_READWRITE(c800_r, c800_w) @@ -1321,6 +1349,7 @@ static SLOT_INTERFACE_START(apple2_cards) SLOT_INTERFACE("ezcgi9938", A2BUS_EZCGI_9938) /* E-Z Color Graphics Interface (TMS9938) */ SLOT_INTERFACE("ezcgi9958", A2BUS_EZCGI_9958) /* E-Z Color Graphics Interface (TMS9958) */ SLOT_INTERFACE("ssprite", A2BUS_SSPRITE) /* Synetix SuperSprite Board */ + SLOT_INTERFACE("ssbapple", A2BUS_SSBAPPLE) /* SSB Apple speech board */ // SLOT_INTERFACE("magicmusician", A2BUS_MAGICMUSICIAN) /* Magic Musician Card */ SLOT_INTERFACE_END @@ -1350,7 +1379,7 @@ static MACHINE_CONFIG_START( apple2_common ) MCFG_DEVICE_ADD(A2_UPPERBANK_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(inhbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) /* soft switches */ diff --git a/src/mame/drivers/apple2e.cpp b/src/mame/drivers/apple2e.cpp index d1ef8abbecd..dcfde97b251 100644 --- a/src/mame/drivers/apple2e.cpp +++ b/src/mame/drivers/apple2e.cpp @@ -80,10 +80,11 @@ Like IIc with memory expansion, but with licensed built-in Zip Chip which runs the 65C02 at 4 MHz turbo speed with a small cache RAM. - The machine has an internal "Apple 3.5" drive plus a custom gate array - which emulates the functionality of the UniDisk 3.5's on-board 65C02. - This gets around the fact that 1 MHz isn't sufficient to handle direct - Woz-style control of a double-density 3.5" drive. + The machine has an internal "Apple 3.5" drive plus a custom chip + named "MIG" (Multidrive Interface Glue) which helps with the control + of the drive. This gets around the fact that 1 MHz isn't + sufficient to handle direct Woz-style control of a double-density + 3.5" drive. External drive port allows IIgs-style daisy-chaining. @@ -112,6 +113,7 @@ Address bus A0-A11 is Y0-Y11 #include "machine/ram.h" #include "machine/sonydriv.h" #include "machine/timer.h" +#include "machine/ds1315.h" #include "bus/a2bus/a2bus.h" #include "bus/a2bus/a2diskii.h" @@ -148,6 +150,8 @@ Address bus A0-A11 is Y0-Y11 #include "bus/a2bus/a2eext80col.h" #include "bus/a2bus/a2eramworks3.h" #include "bus/a2bus/ssprite.h" +#include "bus/a2bus/ssbapple.h" +#include "bus/a2bus/transwarp.h" #include "bus/rs232/rs232.h" @@ -238,7 +242,8 @@ public: m_acia1(*this, IIC_ACIA1_TAG), m_acia2(*this, IIC_ACIA2_TAG), m_laserudc(*this, LASER128_UDC_TAG), - m_iicpiwm(*this, IICP_IWM_TAG) + m_iicpiwm(*this, IICP_IWM_TAG), + m_ds1315(*this, "nsc") { } required_device<cpu_device> m_maincpu; @@ -271,6 +276,7 @@ public: optional_device<mos6551_device> m_acia1, m_acia2; optional_device<applefdc_base_device> m_laserudc; optional_device<iwm_device> m_iicpiwm; + required_device<ds1315_device> m_ds1315; TIMER_DEVICE_CALLBACK_MEMBER(apple2_interrupt); TIMER_DEVICE_CALLBACK_MEMBER(ay3600_repeat); @@ -342,6 +348,8 @@ public: DECLARE_WRITE8_MEMBER(inh_w); DECLARE_READ8_MEMBER(lc_r); DECLARE_WRITE8_MEMBER(lc_w); + DECLARE_READ8_MEMBER(lc_romswitch_r); + DECLARE_WRITE8_MEMBER(lc_romswitch_w); DECLARE_WRITE_LINE_MEMBER(a2bus_irq_w); DECLARE_WRITE_LINE_MEMBER(a2bus_nmi_w); DECLARE_WRITE_LINE_MEMBER(a2bus_inh_w); @@ -351,6 +359,7 @@ public: DECLARE_WRITE_LINE_MEMBER(ay3600_ako_w); DECLARE_READ8_MEMBER(memexp_r); DECLARE_WRITE8_MEMBER(memexp_w); + DECLARE_READ8_MEMBER(nsc_backing_r); private: int m_speaker_state; @@ -391,7 +400,8 @@ private: bool m_intc8rom; bool m_isiic, m_isiicplus, m_iscec; - uint8_t m_iicplus_ce00[0x200]; + uint8_t m_migram[0x800]; + uint16_t m_migpage; uint8_t *m_ram_ptr, *m_rom_ptr, *m_cec_ptr; int m_ram_size; @@ -429,6 +439,9 @@ private: void update_iic_mouse(); uint8_t m_cec_remap[0x40000]; + + uint8_t mig_r(uint16_t offset); + void mig_w(uint16_t offset, uint8_t data); }; /*************************************************************************** @@ -439,6 +452,53 @@ private: #define JOYSTICK_SENSITIVITY 50 #define JOYSTICK_AUTOCENTER 80 +uint8_t apple2e_state::mig_r(uint16_t offset) +{ + // MIG RAM window + if (offset < 0x20) + { + return m_migram[m_migpage + offset]; + } + + // increment MIG RAM window + if (offset == 0x20) + { + m_migpage += 0x20; + m_migpage &= 0x7ff; // make sure we wrap + } + + // reset MIG RAM window + if (offset == 0xa0) + { + m_migpage = 0; + } + + return read_floatingbus(); +} + +void apple2e_state::mig_w(uint16_t offset, uint8_t data) +{ + // MIG RAM window + if (offset < 0x20) + { + m_migram[m_migpage + offset] = data; + return; + } + + // increment MIG RAM window + if (offset == 0x20) + { + m_migpage += 0x20; + m_migpage &= 0x7ff; // make sure we wrap + } + + // reset MIG RAM window + if (offset == 0xa0) + { + m_migpage = 0; + } +} + WRITE_LINE_MEMBER(apple2e_state::a2bus_irq_w) { if (state == ASSERT_LINE) @@ -511,7 +571,7 @@ READ8_MEMBER(apple2e_state::memexp_r) if (!m_exp_ram) { - return 0xff; + return read_floatingbus(); } if (offset == 3) @@ -614,6 +674,9 @@ void apple2e_state::machine_start() m_4000bank->set_bank(0); m_inh_bank = 0; + m_migpage = 0; + memset(m_migram, 0, 0x200); + // expansion RAM size if (m_ram_size > (128*1024)) { @@ -744,7 +807,8 @@ void apple2e_state::machine_start() save_item(NAME(m_y1)); save_item(NAME(m_xirq)); save_item(NAME(m_yirq)); - save_item(NAME(m_iicplus_ce00)); + save_item(NAME(m_migram)); + save_item(NAME(m_migpage)); save_item(NAME(m_exp_regs)); save_item(NAME(m_exp_wptr)); save_item(NAME(m_exp_liveptr)); @@ -2111,17 +2175,12 @@ void apple2e_state::write_slot_rom(address_space &space, int slotbias, int offse uint8_t apple2e_state::read_int_rom(address_space &space, int slotbias, int offset) { -#if 0 - if ((m_cnxx_slot == CNXX_UNCLAIMED) && (!machine().side_effect_disabled())) - { - m_cnxx_slot = CNXX_INTROM; - update_slotrom_banks(); - } -#endif - - return m_rom_ptr[slotbias + offset]; + //return m_rom_ptr[slotbias + offset]; + return m_ds1315->read(space, slotbias + offset); } +READ8_MEMBER(apple2e_state::nsc_backing_r) { return m_rom_ptr[offset]; } + READ8_MEMBER(apple2e_state::c100_r) { return read_slot_rom(space, 1, offset); } READ8_MEMBER(apple2e_state::c100_int_r) { return read_int_rom(space, 0x100, offset); } READ8_MEMBER(apple2e_state::c100_int_bank_r) { return read_int_rom(space, 0x4100, offset); } @@ -2200,9 +2259,9 @@ READ8_MEMBER(apple2e_state::c400_cec_bank_r) { return m_rom_ptr[0x4400 + offset READ8_MEMBER(apple2e_state::c800_r) { - if ((m_isiicplus) && (offset >= 0x600)) + if ((m_isiicplus) && (m_romswitch) && (offset >= 0x600) && (offset < 0x700)) { - return m_iicplus_ce00[offset-0x600]; + return mig_r(offset-0x600); } if (offset == 0x7ff) @@ -2226,9 +2285,9 @@ READ8_MEMBER(apple2e_state::c800_r) READ8_MEMBER(apple2e_state::c800_int_r) { - if ((m_isiicplus) && (offset >= 0x600)) + if ((m_isiicplus) && (m_romswitch) && (offset >= 0x600) && (offset < 0x700)) { - return m_iicplus_ce00[offset-0x600]; + return mig_r(offset-0x600); } if ((offset == 0x7ff) && !machine().side_effect_disabled()) @@ -2248,9 +2307,9 @@ READ8_MEMBER(apple2e_state::c800_int_r) READ8_MEMBER(apple2e_state::c800_b2_int_r) { - if ((m_isiicplus) && (offset >= 0x600)) + if ((m_isiicplus) && (m_romswitch) && (offset >= 0x600) && (offset < 0x700)) { - return m_iicplus_ce00[offset-0x600]; + return mig_r(offset-0x600); } if ((offset == 0x7ff) && !machine().side_effect_disabled()) @@ -2265,9 +2324,9 @@ READ8_MEMBER(apple2e_state::c800_b2_int_r) WRITE8_MEMBER(apple2e_state::c800_w) { - if ((m_isiicplus) && (offset >= 0x600)) + if ((m_isiicplus) && (m_romswitch) && (offset >= 0x600) && (offset < 0x700)) { - m_iicplus_ce00[offset-0x600] = data; + mig_w(offset-0x600, data); return; } @@ -2311,6 +2370,27 @@ WRITE8_MEMBER(apple2e_state::inh_w) } } +READ8_MEMBER(apple2e_state::lc_romswitch_r) +{ + if ((offset >= 0xc00) && (offset < 0xd00)) + { + return mig_r(offset-0xc00); + } + + return m_rom_ptr[0x5000 + offset]; +} + +WRITE8_MEMBER(apple2e_state::lc_romswitch_w) +{ + if ((offset >= 0xc00) && (offset < 0xd00)) + { + mig_w(offset-0xc00, data); + return; + } + + lc_w(space, offset, data); +} + READ8_MEMBER(apple2e_state::lc_r) { if ((m_altzp) && (!m_iscec)) @@ -2735,7 +2815,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( lcbank_map, AS_PROGRAM, 8, apple2e_state ) AM_RANGE(0x00000, 0x02fff) AM_ROM AM_REGION("maincpu", 0x1000) AM_WRITE(lc_w) AM_RANGE(0x03000, 0x05fff) AM_READWRITE(lc_r, lc_w) - AM_RANGE(0x06000, 0x08fff) AM_ROM AM_REGION("maincpu", 0x5000) AM_WRITE(lc_w) + AM_RANGE(0x06000, 0x08fff) AM_READWRITE(lc_romswitch_r, lc_romswitch_w) AM_RANGE(0x09000, 0x0bfff) AM_ROM AM_REGION("maincpu", 0x5000) AM_WRITE(lc_w) AM_RANGE(0x0c000, 0x0efff) AM_READWRITE(lc_r, lc_w) AM_RANGE(0x0f000, 0x11fff) AM_ROM AM_REGION("maincpu", 0xd000) AM_WRITE(lc_w) @@ -3743,6 +3823,8 @@ static SLOT_INTERFACE_START(apple2_cards) // SLOT_INTERFACE("magicmusician", A2BUS_MAGICMUSICIAN) /* Magic Musician Card */ SLOT_INTERFACE("pcxport", A2BUS_PCXPORTER) /* Applied Engineering PC Transporter */ SLOT_INTERFACE("ssprite", A2BUS_SSPRITE) /* Synetix SuperSprite Board */ + SLOT_INTERFACE("ssbapple", A2BUS_SSBAPPLE) /* SSB Apple speech board */ + SLOT_INTERFACE("twarp", A2BUS_TRANSWARP) /* AE TransWarp accelerator */ SLOT_INTERFACE_END static SLOT_INTERFACE_START(apple2eaux_cards) @@ -3773,6 +3855,10 @@ static MACHINE_CONFIG_START( apple2e ) MCFG_SOUND_ADD(A2_SPEAKER_TAG, SPEAKER_SOUND, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + /* DS1315 for no-slot clock */ + MCFG_DS1315_ADD("nsc") + MCFG_DS1315_BACKING_HANDLER(READ8(apple2e_state, nsc_backing_r)) + /* RAM */ MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("64K") @@ -3782,84 +3868,84 @@ static MACHINE_CONFIG_START( apple2e ) MCFG_DEVICE_ADD(A2_0000_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(r0000bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200) /* 0200 banking */ MCFG_DEVICE_ADD(A2_0200_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(r0200bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200) /* 0400 banking */ MCFG_DEVICE_ADD(A2_0400_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(r0400bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) /* 0800 banking */ MCFG_DEVICE_ADD(A2_0800_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(r0800bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) /* 2000 banking */ MCFG_DEVICE_ADD(A2_2000_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(r2000bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) /* 4000 banking */ MCFG_DEVICE_ADD(A2_4000_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(r4000bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) /* C100 banking */ MCFG_DEVICE_ADD(A2_C100_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(c100bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200) /* C300 banking */ MCFG_DEVICE_ADD(A2_C300_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(c300bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x100) /* C400 banking */ MCFG_DEVICE_ADD(A2_C400_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(c400bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) /* C800 banking */ MCFG_DEVICE_ADD(A2_C800_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(c800bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x800) /* built-in language card emulation */ MCFG_DEVICE_ADD(A2_LCBANK_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(lcbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) /* /INH banking */ MCFG_DEVICE_ADD(A2_UPPERBANK_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(inhbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x3000) /* keyboard controller */ diff --git a/src/mame/drivers/apricot.cpp b/src/mame/drivers/apricot.cpp index 964b2484555..d183210e690 100644 --- a/src/mame/drivers/apricot.cpp +++ b/src/mame/drivers/apricot.cpp @@ -20,6 +20,7 @@ #include "cpu/i8089/i8089.h" #include "formats/apridisk.h" #include "imagedev/flopdrv.h" +#include "machine/clock.h" #include "machine/ram.h" #include "machine/74153.h" #include "machine/i8255.h" @@ -359,7 +360,7 @@ static MACHINE_CONFIG_START( apricot ) MCFG_CPU_ADD("ic71", I8089, XTAL_15MHz / 3) MCFG_CPU_PROGRAM_MAP(apricot_mem) MCFG_CPU_IO_MAP(apricot_io) - MCFG_I8089_DATABUS_WIDTH(16) + MCFG_I8089_DATA_WIDTH(16) MCFG_I8089_SINTR1(DEVWRITELINE("ic31", pic8259_device, ir0_w)) MCFG_I8089_SINTR2(DEVWRITELINE("ic31", pic8259_device, ir1_w)) @@ -412,8 +413,10 @@ static MACHINE_CONFIG_START( apricot ) MCFG_TTL153_ZA_CB(DEVWRITELINE("ic15", z80sio_device, rxca_w)) MCFG_TTL153_ZB_CB(DEVWRITELINE("ic15", z80sio_device, txca_w)) + MCFG_CLOCK_ADD("ic15_rxtxcb", XTAL_4MHz / 16) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ic15", z80sio_device, rxtxcb_w)) + MCFG_DEVICE_ADD("ic15", Z80SIO, XTAL_15MHz / 6) - MCFG_Z80SIO_OFFSETS(0, 0, XTAL_4MHz / 16, XTAL_4MHz / 16) MCFG_Z80SIO_CPU("ic91") MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) MCFG_Z80SIO_OUT_DTRA_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) diff --git a/src/mame/drivers/apricotf.cpp b/src/mame/drivers/apricotf.cpp index 28aa129fed1..ce541dd27a8 100644 --- a/src/mame/drivers/apricotf.cpp +++ b/src/mame/drivers/apricotf.cpp @@ -35,7 +35,7 @@ #include "machine/input_merger.h" #include "machine/wd_fdc.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "screen.h" @@ -82,7 +82,7 @@ public: required_device<cpu_device> m_maincpu; required_device<z80ctc_device> m_ctc; - required_device<z80sio2_device> m_sio; + required_device<z80sio_device> m_sio; required_device<wd2797_device> m_fdc; required_device<floppy_connector> m_floppy0; required_device<floppy_connector> m_floppy1; @@ -266,7 +266,7 @@ static ADDRESS_MAP_START( act_f1_io, AS_IO, 16, f1_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x000f) AM_WRITE8(system_w, 0xffff) AM_RANGE(0x0010, 0x0017) AM_DEVREADWRITE8(Z80CTC_TAG, z80ctc_device, read, write, 0x00ff) - AM_RANGE(0x0020, 0x0027) AM_DEVREADWRITE8(Z80SIO2_TAG, z80sio2_device, ba_cd_r, ba_cd_w, 0x00ff) + AM_RANGE(0x0020, 0x0027) AM_DEVREADWRITE8(Z80SIO2_TAG, z80sio_device, ba_cd_r, ba_cd_w, 0x00ff) // AM_RANGE(0x0030, 0x0031) AM_WRITE8(ctc_ack_w, 0x00ff) AM_RANGE(0x0040, 0x0047) AM_DEVREADWRITE8(WD2797_TAG, wd2797_device, read, write, 0x00ff) // AM_RANGE(0x01e0, 0x01ff) winchester @@ -353,8 +353,8 @@ static MACHINE_CONFIG_START( act_f1 ) /* Devices */ MCFG_DEVICE_ADD(APRICOT_KEYBOARD_TAG, APRICOT_KEYBOARD, 0) - MCFG_DEVICE_ADD(Z80SIO2_TAG, Z80SIO2, 2500000) - MCFG_Z80DART_OUT_INT_CB(DEVWRITELINE("irqs", input_merger_device, in_w<0>)) + MCFG_DEVICE_ADD(Z80SIO2_TAG, Z80SIO, 2500000) + MCFG_Z80SIO_OUT_INT_CB(DEVWRITELINE("irqs", input_merger_device, in_w<0>)) MCFG_DEVICE_ADD(Z80CTC_TAG, Z80CTC, 2500000) MCFG_Z80CTC_INTR_CB(DEVWRITELINE("irqs", input_merger_device, in_w<1>)) @@ -362,7 +362,7 @@ static MACHINE_CONFIG_START( act_f1 ) MCFG_Z80CTC_ZC2_CB(WRITELINE(f1_state, ctc_z2_w)) MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") - MCFG_CENTRONICS_BUSY_HANDLER(DEVWRITELINE(Z80SIO2_TAG, z80dart_device, ctsa_w)) + MCFG_CENTRONICS_BUSY_HANDLER(DEVWRITELINE(Z80SIO2_TAG, z80sio_device, ctsa_w)) MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", CENTRONICS_TAG) diff --git a/src/mame/drivers/apricotp.cpp b/src/mame/drivers/apricotp.cpp index 324e77c5dda..e75c8a19a35 100644 --- a/src/mame/drivers/apricotp.cpp +++ b/src/mame/drivers/apricotp.cpp @@ -35,7 +35,7 @@ #include "machine/pit8253.h" #include "machine/ram.h" #include "machine/wd_fdc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "sound/sn76496.h" #include "video/mc6845.h" #include "screen.h" @@ -111,7 +111,7 @@ public: required_device<am9517a_device> m_dmac; required_device<pic8259_device> m_pic; required_device<pit8253_device> m_pit; - required_device<z80dart_device> m_sio; + required_device<z80sio_device> m_sio; required_device<wd2797_device> m_fdc; required_device<mc6845_device> m_crtc; required_device<ram_device> m_ram; @@ -435,7 +435,7 @@ static ADDRESS_MAP_START( fp_io, AS_IO, 16, fp_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x000, 0x007) AM_DEVREADWRITE8(WD2797_TAG, wd2797_device, read, write, 0x00ff) AM_RANGE(0x008, 0x00f) AM_DEVREADWRITE8(I8253A5_TAG, pit8253_device, read, write, 0x00ff) - AM_RANGE(0x018, 0x01f) AM_DEVREADWRITE8(Z80SIO0_TAG, z80sio0_device, ba_cd_r, ba_cd_w, 0x00ff) + AM_RANGE(0x018, 0x01f) AM_DEVREADWRITE8(Z80SIO0_TAG, z80sio_device, ba_cd_r, ba_cd_w, 0x00ff) AM_RANGE(0x020, 0x021) AM_DEVWRITE8("cent_data_out", output_latch_device, write, 0x00ff) AM_RANGE(0x022, 0x023) AM_WRITE8(pint_clr_w, 0x00ff) AM_RANGE(0x024, 0x025) AM_READ8(prtr_snd_r, 0x00ff) @@ -634,8 +634,8 @@ static MACHINE_CONFIG_START( fp ) MCFG_PIT8253_CLK1(2000000) MCFG_PIT8253_CLK2(2000000) - MCFG_DEVICE_ADD(Z80SIO0_TAG, Z80SIO0, 2500000) - MCFG_Z80DART_OUT_INT_CB(DEVWRITELINE(I8259A_TAG, pic8259_device, ir4_w)) + MCFG_DEVICE_ADD(Z80SIO0_TAG, Z80SIO, 2500000) + MCFG_Z80SIO_OUT_INT_CB(DEVWRITELINE(I8259A_TAG, pic8259_device, ir4_w)) MCFG_WD2797_ADD(WD2797_TAG, 2000000) MCFG_WD_FDC_INTRQ_CALLBACK(DEVWRITELINE(I8259A_TAG, pic8259_device, ir1_w)) diff --git a/src/mame/drivers/argo.cpp b/src/mame/drivers/argo.cpp index 8288c247d1c..11fbeda0fcd 100644 --- a/src/mame/drivers/argo.cpp +++ b/src/mame/drivers/argo.cpp @@ -2,24 +2,24 @@ // copyright-holders:Robbbert /*************************************************************************** - Argo +Argo - 16/03/2011 Skeleton driver. +2011-03-16 Skeleton driver. - Some info obtained from EMU-80. - There are no manuals, diagrams, or anything else available afaik. - The entire driver is guesswork. +Some info obtained from EMU-80. +There are no manuals, diagrams, or anything else available afaik. +The entire driver is guesswork. - The monitor will only allow certain characters to be typed, thus the - modifier keys appear to do nothing. There is no need to use the enter - key; using spacebar and the correct parameters is enough. +The monitor will only allow certain characters to be typed, thus the +modifier keys appear to do nothing. There is no need to use the enter +key; using spacebar and the correct parameters is enough. - Commands: same as UNIOR +Commands: same as UNIOR - ToDo: - - Add devices - - There is no obvious evidence of sound. - - Cassette UART on ports C1 and C3. +ToDo: +- Add devices +- There is no obvious evidence of sound. +- Cassette UART on ports C1 and C3. ****************************************************************************/ @@ -141,7 +141,7 @@ WRITE8_MEMBER(argo_state::argo_io_w) -static ADDRESS_MAP_START(argo_mem, AS_PROGRAM, 8, argo_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, argo_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x07ff) AM_RAMBANK("boot") AM_RANGE(0x0800, 0xf7af) AM_RAM @@ -149,7 +149,7 @@ static ADDRESS_MAP_START(argo_mem, AS_PROGRAM, 8, argo_state) AM_RANGE(0xf800, 0xffff) AM_ROM AM_WRITE(argo_videoram_w) ADDRESS_MAP_END -static ADDRESS_MAP_START(argo_io, AS_IO, 8, argo_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, argo_state) AM_RANGE(0x0000, 0xFFFF) AM_READWRITE(argo_io_r,argo_io_w) ADDRESS_MAP_END @@ -345,8 +345,8 @@ uint32_t argo_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, static MACHINE_CONFIG_START( argo ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, 3500000) - MCFG_CPU_PROGRAM_MAP(argo_mem) - MCFG_CPU_IO_MAP(argo_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) diff --git a/src/mame/drivers/aristmk5.cpp b/src/mame/drivers/aristmk5.cpp index c86052b691d..5b9a27577de 100644 --- a/src/mame/drivers/aristmk5.cpp +++ b/src/mame/drivers/aristmk5.cpp @@ -983,11 +983,12 @@ INPUT_CHANGED_MEMBER(aristmk5_state::coin_start) static INPUT_PORTS_START( aristmk5_usa ) /* This simulates the ROM swap */ PORT_START("ROM_LOAD") - PORT_CONFNAME( 0x03, 0x03, "System Mode" ) + PORT_CONFNAME( 0x07, 0x04, "System Mode" ) PORT_CONFSETTING( 0x00, "USA Set Chip v4.04.09 Mode" ) - PORT_CONFSETTING( 0x01, "USA Set Chip v4.04.00 Mode" ) - PORT_CONFSETTING( 0x02, "USA Set Chip v4.02.04 Mode" ) - PORT_CONFSETTING( 0x03, "Game Mode" ) + PORT_CONFSETTING( 0x01, "USA Set Chip v4.04.08 Mode" ) + PORT_CONFSETTING( 0x02, "USA Set Chip v4.04.00 Mode" ) + PORT_CONFSETTING( 0x03, "USA Set Chip v4.02.04 Mode" ) + PORT_CONFSETTING( 0x04, "Game Mode" ) PORT_START("DSW1") PORT_DIPUNKNOWN_DIPLOC(0x01, 0x01, "DSW1:1") @@ -1056,11 +1057,12 @@ INPUT_PORTS_END static INPUT_PORTS_START( aristmk5 ) /* This simulates the ROM swap */ PORT_START("ROM_LOAD") - PORT_CONFNAME( 0x03, 0x03, "System Mode" ) + PORT_CONFNAME( 0x07, 0x04, "System Mode" ) PORT_CONFSETTING( 0x00, "USA Set Chip v4.04.09 Mode" ) - PORT_CONFSETTING( 0x01, "USA Set Chip v4.04.00 Mode" ) - PORT_CONFSETTING( 0x02, "USA Set Chip v4.02.04 Mode" ) - PORT_CONFSETTING( 0x03, "Game Mode" ) + PORT_CONFSETTING( 0x01, "USA Set Chip v4.04.08 Mode" ) + PORT_CONFSETTING( 0x02, "USA Set Chip v4.04.00 Mode" ) + PORT_CONFSETTING( 0x03, "USA Set Chip v4.02.04 Mode" ) + PORT_CONFSETTING( 0x04, "Game Mode" ) PORT_START("P1") PORT_BIT(0x00000001, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_J) PORT_NAME("Gamble") @@ -1881,11 +1883,11 @@ void aristmk5_state::machine_reset() uint8_t *PRG;// = memregion("prg_code")->base(); int i; uint8_t op_mode; - static const char *const rom_region[] = { "set_4.04.09", "set_4.04.00", "set_4.02.04", "game_prg" }; + static const char *const rom_region[] = { "set_4.04.09", "set_4.04.08", "set_4.04.00", "set_4.02.04", "game_prg" }; op_mode = ioport("ROM_LOAD")->read(); - PRG = memregion(rom_region[op_mode & 3])->base(); + PRG = memregion(rom_region[op_mode & 7])->base(); if(PRG!=nullptr) @@ -2004,6 +2006,9 @@ MACHINE_CONFIG_END ROM_REGION( 0x400000, "set_4.04.09", ROMREGION_ERASEFF ) /* setchip v4.04.09 4meg */ \ ROM_LOAD32_WORD( "setchip v4.04.09.u7", 0x000000, 0x80000, CRC(e8e8dc75) SHA1(201fe95256459ce34fdb6f7498135ab5016d07f3) ) \ ROM_LOAD32_WORD( "setchip v4.04.09.u11", 0x000002, 0x80000, CRC(ff7a9035) SHA1(4352c4336e61947c555fdc80c61f944076f64b64) ) \ + ROM_REGION( 0x400000, "set_4.04.08", ROMREGION_ERASEFF ) /* setchip v4.04.08 4meg */ \ + ROM_LOAD32_WORD( "setchip v4.04.08.u7", 0x000000, 0x80000, CRC(7c4b7fe4) SHA1(39dd39c794c0cb6abc1b7503650643a8131468d1) ) \ + ROM_LOAD32_WORD( "setchip v4.04.08.u11", 0x000002, 0x80000, CRC(d3234a28) SHA1(8ff112ee4aadf1d359ca8ffe0cfa9c7400aa0595) ) \ ROM_REGION( 0x400000, "set_4.04.00", ROMREGION_ERASEFF ) /* setchip v4.04.00 4meg 42pin */ \ ROM_LOAD32_WORD( "setchip v4.04.00.u7", 0x000000, 0x80000, CRC(2453137e) SHA1(b59998e75ae3924da16faf47b9cfe9afd60d810c) ) \ ROM_LOAD32_WORD( "setchip v4.04.00.u11", 0x000002, 0x80000, CRC(82dfa12a) SHA1(86fd0f0ad8d5d1bc503392a40bbcdadb055b2765) ) \ @@ -2022,6 +2027,9 @@ MACHINE_CONFIG_END ROM_REGION( 0x400000, "set_4.04.09", ROMREGION_ERASEFF ) /* setchip v4.04.09 4meg */ \ ROM_LOAD32_WORD( "setchip v4.04.09.u7", 0x000000, 0x80000, CRC(e8e8dc75) SHA1(201fe95256459ce34fdb6f7498135ab5016d07f3) ) \ ROM_LOAD32_WORD( "setchip v4.04.09.u11", 0x000002, 0x80000, CRC(ff7a9035) SHA1(4352c4336e61947c555fdc80c61f944076f64b64) ) \ + ROM_REGION( 0x400000, "set_4.04.08", ROMREGION_ERASEFF ) /* setchip v4.04.08 4meg */ \ + ROM_LOAD32_WORD( "setchip v4.04.08.u7", 0x000000, 0x80000, CRC(7c4b7fe4) SHA1(39dd39c794c0cb6abc1b7503650643a8131468d1) ) \ + ROM_LOAD32_WORD( "setchip v4.04.08.u11", 0x000002, 0x80000, CRC(d3234a28) SHA1(8ff112ee4aadf1d359ca8ffe0cfa9c7400aa0595) ) \ ROM_REGION( 0x400000, "set_4.04.00", ROMREGION_ERASEFF ) /* setchip v4.04.00 4meg 42pin */ \ ROM_LOAD32_WORD( "setchip v4.04.00.u7", 0x000000, 0x80000, CRC(2453137e) SHA1(b59998e75ae3924da16faf47b9cfe9afd60d810c) ) \ ROM_LOAD32_WORD( "setchip v4.04.00.u11", 0x000002, 0x80000, CRC(82dfa12a) SHA1(86fd0f0ad8d5d1bc503392a40bbcdadb055b2765) ) \ @@ -2104,16 +2112,15 @@ ROM_START( adonisu ) Checksum code found at 0x000d18 0x000000-0x0e8a7b is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0xe6715f98 - Calculated Checksum 0xc80cd95e (BAD) + Calculated Checksum 0xe6715f98 (OK) 0x0e8a7c-0x1c5f47 is the non-Checksummed range still containing data but NOT covered by Checksum 0x0e8a7c-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "bhg1508.u7", 0x000000, 0x80000, BAD_DUMP CRC(ed6254d7) SHA1(d2b790fdd7f5fc7b78fcfc4c96d0fc272ccf8da6) ) - ROM_LOAD32_WORD( "bhg1508.u11", 0x000002, 0x80000, BAD_DUMP CRC(1f629286) SHA1(bce380a6a76c77bc790436bd6f94474a1db0c231) ) - ROM_LOAD32_WORD( "bhg1508.u8", 0x100000, 0x80000, BAD_DUMP CRC(b756c96d) SHA1(494df20090d415e83d599023203c13273e7925ad) ) - ROM_LOAD32_WORD( "bhg1508.u12", 0x100002, 0x80000, BAD_DUMP CRC(1d3b6b8f) SHA1(1ddcfd7323cc7e79d3e39d913fdb5cf5cd53d56d) ) + ROM_LOAD32_WORD( "bhg1508.u7", 0x000000, 0x80000, CRC(09107577) SHA1(6cb525a96cdcb414ae7a45b5a5853d94059bc333) ) + ROM_LOAD32_WORD( "bhg1508.u11", 0x000002, 0x80000, CRC(45630329) SHA1(a2c8e3ae786948135797a80ae12bf3ba2e6192a8) ) + ROM_LOAD32_WORD( "bhg1508.u8", 0x100000, 0x80000, CRC(c572e39b) SHA1(e6ca864b620a17f8b963d4917cbdc894b9b275dc) ) + ROM_LOAD32_WORD( "bhg1508.u12", 0x100002, 0x80000, CRC(b8995b25) SHA1(ad39ad11dc02dbbe8be99d81c96e9fc3191726ad) ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -2264,20 +2271,19 @@ ROM_START( bootsctnu ) Checksum code found at 0x000d08 0x000000-0x0941ab is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0xdf68cecf - Calculated Checksum 0xed145d01 (BAD) + Calculated Checksum 0xdf68cecf (OK) 0x0941ac-0x328187 is the non-Checksummed range (suspicious endpoint) */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "ghg101202.u7", 0x000000, 0x80000, BAD_DUMP CRC(ca26f31e) SHA1(e8da31cc8d12bf8a28f1ca4d796259ae9010f8af) ) // 92.767% - ROM_LOAD32_WORD( "ghg101202.u11", 0x000002, 0x80000, BAD_DUMP CRC(61da1767) SHA1(83d4df1060975f03f291b9119c0d2b8debb0fb60) ) // 92.767% - ROM_LOAD32_WORD( "ghg101202.u8", 0x100000, 0x80000, BAD_DUMP CRC(9ae4d616) SHA1(60d4d36f75685dfe21f914fa4682cd6a64fcfa58) ) // base - ROM_LOAD32_WORD( "ghg101202.u12", 0x100002, 0x80000, BAD_DUMP CRC(2c50c083) SHA1(ae3b01200d152df9b2966b5308c71e9d1ad43d78) ) // base - ROM_LOAD32_WORD( "ghg101202.u9", 0x200000, 0x80000, BAD_DUMP CRC(c0a4920d) SHA1(d2c6d259d2e067b6e5ad72a6ef164aac7d72bc5a) ) // base - ROM_LOAD32_WORD( "ghg101202.u13", 0x200002, 0x80000, BAD_DUMP CRC(55716d82) SHA1(5b9982a49201842e9551a9c763a6babbb47a863e) ) // base - ROM_LOAD32_WORD( "ghg101202.u10", 0x300000, 0x80000, BAD_DUMP CRC(3ecdf7ee) SHA1(9d658a22da737daafdf6cb0d49009796036d04b1) ) // base - ROM_LOAD32_WORD( "ghg101202.u14", 0x300002, 0x80000, BAD_DUMP CRC(18934c51) SHA1(f7c9c95c687dbfe89747e7877157fde37bc1119e) ) // base + ROM_LOAD32_WORD( "ghg101202.u7", 0x000000, 0x80000, CRC(ea389201) SHA1(a838a9115ca3101cb06ec86e955294d51f8d65e4) ) // 92.767% + ROM_LOAD32_WORD( "ghg101202.u11", 0x000002, 0x80000, CRC(af6f2142) SHA1(200be993ad21643c46995d68a119fd8c1d2fedbe) ) // 92.767% + ROM_LOAD32_WORD( "ghg101202.u8", 0x100000, 0x80000, CRC(7b9c153e) SHA1(2144a208d2fd2f993e113d809045e864d89df7ec) ) // base + ROM_LOAD32_WORD( "ghg101202.u12", 0x100002, 0x80000, CRC(565ce1ca) SHA1(a9a64027d78f9ca7036b5b299040e1a7c776b617) ) // base + ROM_LOAD32_WORD( "ghg101202.u9", 0x200000, 0x80000, CRC(b60ea737) SHA1(847cdb4a6bf887a08dd525320aeffc74fcc10643) ) // base + ROM_LOAD32_WORD( "ghg101202.u13", 0x200002, 0x80000, CRC(55ddba7b) SHA1(3a43e577e8bc72aa1c09b131ec8b2a87eaeccf9f) ) // base + ROM_LOAD32_WORD( "ghg101202.u10", 0x300000, 0x80000, CRC(230725bc) SHA1(85320b1b72c7f83f57bc8cc861e5a6323750ff4f) ) // base + ROM_LOAD32_WORD( "ghg101202.u14", 0x300002, 0x80000, CRC(18934c51) SHA1(f7c9c95c687dbfe89747e7877157fde37bc1119e) ) // base ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -2316,6 +2322,7 @@ ROM_END // Bachelorette Party / Export / B - 25/08/2000 // ROM says "9 Line Multiline" but this is a 20 line game, it cannot be set to 9 lines at all // Touchscreen game +// Game requires set chip version: 4.01.xx ROM_START( bparty ) ARISTOCRAT_MK5_BIOS /* @@ -2418,16 +2425,15 @@ ROM_START( bumblbugu ) Checksum code found at 0x000d08 0x000000-0x0b1f47 is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0x9f3936f9 - Calculated Checksum 0x16f5c058 (BAD) + Calculated Checksum 0x9f3936f9 (OK) 0x0b1f48-0x183c1f is the non-Checksummed range still containing data but NOT covered by Checksum 0x0b1f48-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "chg047903.u7", 0x000000, 0x80000, BAD_DUMP CRC(ec605a36) SHA1(114e0840cfbd0c64645a5a33065db85462a0ba2d) ) // 92.691% - ROM_LOAD32_WORD( "chg047903.u11", 0x000002, 0x80000, BAD_DUMP CRC(17b154bd) SHA1(efdf307670a3d74f7980fec2d2197d837d4c26e2) ) // 92.691% - ROM_LOAD32_WORD( "chg047903.u8", 0x100000, 0x80000, BAD_DUMP CRC(e0c01d01) SHA1(9153129fd348a97da7cccf002e5d03e4b4db9264) ) // base - ROM_LOAD32_WORD( "chg047903.u12", 0x100002, 0x80000, BAD_DUMP CRC(28700d5d) SHA1(87a583cd487da6cb4c2da5f62297f0e577269fae) ) // base + ROM_LOAD32_WORD( "chg047903.u7", 0x000000, 0x80000, CRC(ae49d394) SHA1(fae7db8193915a3307e89a4623289fcbf9486283) ) // 92.691% + ROM_LOAD32_WORD( "chg047903.u11", 0x000002, 0x80000, CRC(6da81e81) SHA1(a9e7aff23b24213ce2c68f672a9e22088cf53f3f) ) // 92.691% + ROM_LOAD32_WORD( "chg047903.u8", 0x100000, 0x80000, CRC(e0c01d01) SHA1(9153129fd348a97da7cccf002e5d03e4b4db9264) ) // base + ROM_LOAD32_WORD( "chg047903.u12", 0x100002, 0x80000, CRC(7dbb634b) SHA1(f7a752240989032af142f4cd6e4260a12a5b4c0a) ) // base ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -2622,16 +2628,15 @@ ROM_START( cashchamu ) Checksum code found at 0x000d08 0x000000-0x09b413 is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0x741cd9a0 - Calculated Checksum 0x740e5ad7 (BAD) + Calculated Checksum 0x741cd9a0 (OK) 0x09b414-0x1b550b is the non-Checksummed range still containing data but NOT covered by Checksum 0x09b414-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "dhg407899.u7", 0x000000, 0x80000, BAD_DUMP CRC(cb407a19) SHA1(d98421d6548e48b413f6dfcab4e240e98fcc9a69) ) - ROM_LOAD32_WORD( "dhg407899.u11", 0x000002, 0x80000, BAD_DUMP CRC(94d73843) SHA1(ab236750c67e7fff3af831f1d03f45c45f280fd1) ) - ROM_LOAD32_WORD( "dhg407899.u8", 0x100000, 0x80000, BAD_DUMP CRC(4cae8a5d) SHA1(3232461afd75ce71f8a2cb4ac7e9a3caeb8aabcd) ) - ROM_LOAD32_WORD( "dhg407899.u12", 0x100002, 0x80000, BAD_DUMP CRC(39e17f0b) SHA1(25a0364fa45e4e78d6c365b0739606e71597bd71) ) + ROM_LOAD32_WORD( "dhg407899.u7", 0x000000, 0x80000, CRC(9944fe04) SHA1(5f68b08e3480c0c8c1a29fe40e0221e9aeb969b7) ) + ROM_LOAD32_WORD( "dhg407899.u11", 0x000002, 0x80000, CRC(1f7fa88a) SHA1(6ca40c5edba758084fd4d4cc0899584fd2d72ad3) ) + ROM_LOAD32_WORD( "dhg407899.u8", 0x100000, 0x80000, CRC(6630b35b) SHA1(0126be7a73460fc70c7f1527a3eb0c9a0c58618e) ) + ROM_LOAD32_WORD( "dhg407899.u12", 0x100002, 0x80000, CRC(2fd087f8) SHA1(f16414abf58e1a7a8ca08380993bdeca6f9c7317) ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -3417,11 +3422,10 @@ ROM_START( eforsta5u ) 0x0a5234-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // if you enable the additional debug output you get 'Error in graphics EPROMs' so these ROMs are also bad even if the above passes - ROM_LOAD32_WORD( "jhg041503.u7", 0x000000, 0x80000, BAD_DUMP CRC(cae1fb55) SHA1(386913ddf9be406f46aab06cf3e27c3c38a4d52d) ) // 94.97% - ROM_LOAD32_WORD( "jhg041503.u11", 0x000002, 0x80000, BAD_DUMP CRC(a71b7b3c) SHA1(26c3438398b6a3cc9946a1cd1c92d317a8e2738e) ) // 94.97% - ROM_LOAD32_WORD( "jhg041503.u8", 0x100000, 0x80000, BAD_DUMP CRC(002dec6c) SHA1(fb3f4ce9cd8cd9e0e3133376ed014db83db041c5) ) // base - ROM_LOAD32_WORD( "jhg041503.u12", 0x100002, 0x80000, BAD_DUMP CRC(c968471f) SHA1(9d54a5c396e6f83690db2fcb7ddcc8a47a7dd777) ) // base + ROM_LOAD32_WORD( "jhg041503.u7", 0x000000, 0x80000, CRC(48a87915) SHA1(103f79f482b4e1ba3653280cdcf1ac6718981faf) ) // 94.97% + ROM_LOAD32_WORD( "jhg041503.u11", 0x000002, 0x80000, CRC(beb31b6d) SHA1(454fe5b04789e6f45d82d92f808fde5770435a80) ) // 94.97% + ROM_LOAD32_WORD( "jhg041503.u8", 0x100000, 0x80000, CRC(002dec6c) SHA1(fb3f4ce9cd8cd9e0e3133376ed014db83db041c5) ) // base + ROM_LOAD32_WORD( "jhg041503.u12", 0x100002, 0x80000, CRC(c968471f) SHA1(9d54a5c396e6f83690db2fcb7ddcc8a47a7dd777) ) // base ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -3517,11 +3521,10 @@ ROM_START( gambler ) 0x08f46c-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // if you enable the additional debug output you get 'Error2 in graphics EPROMs' so these ROMs are also bad even if the above passes - ROM_LOAD32_WORD( "ehg091602.u7", 0x000000, 0x80000, BAD_DUMP CRC(7524c954) SHA1(0a895d1e2d09a2c873bbbbeb37bc59c25f3c577c) ) // 92.268% - ROM_LOAD32_WORD( "ehg091602.u11", 0x000002, 0x80000, BAD_DUMP CRC(f29a6932) SHA1(17761218a04d36a599c987b4e13c0e3f46b7793f) ) // 92.268% - ROM_LOAD32_WORD( "ehg091602.u8", 0x100000, 0x80000, BAD_DUMP CRC(e2221fdf) SHA1(8a7b2d5de68ae66fe1915a6faac6277249e3fb53) ) // base - ROM_LOAD32_WORD( "ehg091602.u12", 0x100002, 0x80000, BAD_DUMP CRC(ebe957f9) SHA1(539945ec9beafe2c83051208370588fce2334f16) ) // base + ROM_LOAD32_WORD( "ehg091602.u7", 0x000000, 0x80000, CRC(084167e3) SHA1(ec10a3f1a52ec4a2e2b4e1f303c1cbc048d1331b) ) // 92.268% + ROM_LOAD32_WORD( "ehg091602.u11", 0x000002, 0x80000, CRC(049b027c) SHA1(8212708c63003e6fd95ce2ee32d46dc4a26ab3c3) ) // 92.268% + ROM_LOAD32_WORD( "ehg091602.u8", 0x100000, 0x80000, CRC(e2221fdf) SHA1(8a7b2d5de68ae66fe1915a6faac6277249e3fb53) ) // base + ROM_LOAD32_WORD( "ehg091602.u12", 0x100002, 0x80000, CRC(ebe957f9) SHA1(539945ec9beafe2c83051208370588fce2334f16) ) // base ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -3631,16 +3634,15 @@ ROM_START( goldpyra ) Checksum code found at 0x000d08 0x000000-0x08ef13 is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0xd3126f08 - Calculated Checksum 0x26ee6f08 (BAD) + Calculated Checksum 0xd3126f08 (OK) 0x08ef14-0x1aca3b is the non-Checksummed range still containing data but NOT covered by Checksum 0x08ef14-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "ahg120699.u7", 0x000000, 0x80000, BAD_DUMP CRC(e6c80f67) SHA1(901cf8f8fd46c1c4a70e1954d2d2d88e7acd07a8) ) - ROM_LOAD32_WORD( "ahg120699.u11", 0x000002, 0x80000, BAD_DUMP CRC(3cc221ea) SHA1(a71d16b818110f5b632e996e9f2fcb8be17b2aee) ) - ROM_LOAD32_WORD( "ahg120699.u8", 0x100000, 0x80000, BAD_DUMP CRC(df1ffb31) SHA1(1cf9d008b1f8fdb06ba050c97dae79f272c8063c) ) - ROM_LOAD32_WORD( "ahg120699.u12", 0x100002, 0x80000, BAD_DUMP CRC(d2c8f786) SHA1(a9efa35c8f2833a2b77f092398ca959d5fe6194e) ) + ROM_LOAD32_WORD( "ahg120699.u7", 0x000000, 0x80000, CRC(19d21119) SHA1(de809e098a676f3d5f2c2750c5f7c97ee4c836a7) ) + ROM_LOAD32_WORD( "ahg120699.u11", 0x000002, 0x80000, CRC(0f585009) SHA1(2e93caba45d5a79db2d7fd3a15da432afe05e59c) ) + ROM_LOAD32_WORD( "ahg120699.u8", 0x100000, 0x80000, CRC(df1ffb31) SHA1(1cf9d008b1f8fdb06ba050c97dae79f272c8063c) ) + ROM_LOAD32_WORD( "ahg120699.u12", 0x100002, 0x80000, CRC(13021157) SHA1(6beb8dea66659b5ec9cbb8dcd921c30a621049a9) ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -3838,14 +3840,19 @@ ROM_END // Same strings as incasunu but different version ROM_START( incasunua ) ARISTOCRAT_MK5_BIOS - // checksum code not found due to ROMs being corrupted, all files are missing bytes consisting of 0x0D + /* + Checksum code found at 0x000d18 + Checksum is stored in 0x000020-0x000027 + Expected Checksum 0x24e1ed00 + Calculated Checksum 0x24e1ed00 (OK) + */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - ROM_LOAD32_WORD( "dhg1577.u7", 0x000000, 0x7f079, BAD_DUMP CRC(ebbd4d54) SHA1(7e5c0da2bc62338dd2148af7fa87745d622b85b9) ) - ROM_LOAD32_WORD( "dhg1577.u11", 0x000002, 0x7ff6c, BAD_DUMP CRC(fb86c7b2) SHA1(62b1897907ceebcd0c2c0a4da002a783174321e7) ) - ROM_LOAD32_WORD( "dhg1577.u8", 0x100000, 0x7fcb7, BAD_DUMP CRC(809c5277) SHA1(2efde9a7887d3ca5cb7fa5aebb0b6fcc9aeb880a) ) - ROM_LOAD32_WORD( "dhg1577.u12", 0x100002, 0x7fc89, BAD_DUMP CRC(dbf26048) SHA1(2fcf1f7d5a0402798b4fe25afd178d8c1db89e3b) ) - ROM_LOAD32_WORD( "dhg1577.u9", 0x200000, 0x7fd47, BAD_DUMP CRC(046e019e) SHA1(4c6e17562cb337c3d79efc095960c4d1f9d87f39) ) - ROM_LOAD32_WORD( "dhg1577.u13", 0x200002, 0x7fd62, BAD_DUMP CRC(7299484f) SHA1(f6b75e5be6ef724504a543702692e455437d7046) ) + ROM_LOAD32_WORD( "dhg1577.u7", 0x000000, 0x80000, CRC(e31e3c81) SHA1(56b00aae1b9385686530e089cad05308e0c0751d) ) + ROM_LOAD32_WORD( "dhg1577.u11", 0x000002, 0x80000, CRC(68d58ad3) SHA1(c521da10b719250e3f115357c6e4ff51377d4335) ) + ROM_LOAD32_WORD( "dhg1577.u8", 0x100000, 0x80000, CRC(475db842) SHA1(3c49fbf45a256222e6a5a0343a7dc96386bb8897) ) + ROM_LOAD32_WORD( "dhg1577.u12", 0x100002, 0x80000, CRC(f1be432e) SHA1(ed4a064e4e8200126bda3f1c25ac5075014c9f94) ) + ROM_LOAD32_WORD( "dhg1577.u9", 0x200000, 0x80000, CRC(a8956bf5) SHA1(d444a3a64968a6275b38babf23089c7d186f30e6) ) + ROM_LOAD32_WORD( "dhg1577.u13", 0x200002, 0x80000, CRC(f7c30ef9) SHA1(44d7213e1220d6b89715408d009ef1484de2696f) ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -4130,12 +4137,17 @@ ROM_END // Loco Loot / Export / A - 30/07/01 ROM_START( locolootu ) ARISTOCRAT_MK5_BIOS - // checksum code not found due to ROMs being corrupted, all files are missing bytes consisting of 0x0D +/* + Checksum code found at 0x000d18 + Checksum is stored at 0x000020-0x000027 + Expected Checksum 0xbd28f614 + Calculated Checksum 0xbd28f614 (OK) +*/ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - ROM_LOAD32_WORD( "ahg1513.u7", 0x000000, 0x7f06f, BAD_DUMP CRC(c0e769a1) SHA1(df0dedf6dc9412efccd26ad16ab0d316863f9488) ) - ROM_LOAD32_WORD( "ahg1513.u11", 0x000002, 0x7ff6c, BAD_DUMP CRC(f60c2e0b) SHA1(d3ba83eb458ab99d28a910688e63c9dd5ae6570b) ) - ROM_LOAD32_WORD( "ahg1513.u8", 0x100000, 0x7fede, BAD_DUMP CRC(c24cfe7b) SHA1(7f1f02a4e77ad178c7e08362feb1ec4b064e539c) ) - ROM_LOAD32_WORD( "ahg1513.u12", 0x100002, 0x7ff14, BAD_DUMP CRC(73e30f47) SHA1(eb12716f3c384901cd80b2f43760b522150c64b0) ) + ROM_LOAD32_WORD( "ahg1513.u7", 0x000000, 0x80000, CRC(16854250) SHA1(a3b6e112dcce38310ca13eb9e9851901ee213fcf) ) + ROM_LOAD32_WORD( "ahg1513.u11", 0x000002, 0x80000, CRC(0abe509a) SHA1(a5d0b870390e7f4b38d7685c09c079acb198dd42) ) + ROM_LOAD32_WORD( "ahg1513.u8", 0x100000, 0x80000, CRC(bd9d2ad7) SHA1(5e5eaf2521473246fb54175f88521b43b9b86f9f) ) + ROM_LOAD32_WORD( "ahg1513.u12", 0x100002, 0x80000, CRC(5bf7b4b1) SHA1(2282ec8d0ddd1aea715005fba2171468831513f4) ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -4188,22 +4200,22 @@ ROM_END // MV4033 / 10 Credit Multiplier / 9 Line Multiline // Magic Garden / Export / B - 10/02/97 // Marked as AHG1211 and 88.26% +// (Same game as Enchanted Forest?) ROM_START( mgarden ) ARISTOCRAT_MK5_BIOS /* Checksum code found at 0x000d08 0x000000-0x0a522b is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0x8b0f5dae - Calculated Checksum 0x8afcb91f (BAD) + Calculated Checksum 0x8b0f5dae (OK) 0x0a522c-0x15dbd7 is the non-Checksummed range still containing data but NOT covered by Checksum 0x0a522c-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "ahg121199.u7", 0x000000, 0x80000, BAD_DUMP CRC(4fe50505) SHA1(6cde87a8a6748af792a1fb101829491367bd4487) ) - ROM_LOAD32_WORD( "ahg121199.u11", 0x000002, 0x80000, BAD_DUMP CRC(723ffeee) SHA1(9eab33c9dbf656489914e539a28da5ae289e8df7) ) - ROM_LOAD32_WORD( "ahg121199.u8", 0x100000, 0x80000, BAD_DUMP CRC(a315ca28) SHA1(0309789362a945d592ee2eda912e4fc2e6ea5be6) ) - ROM_LOAD32_WORD( "ahg121199.u12", 0x100002, 0x80000, BAD_DUMP CRC(4b252c2c) SHA1(8be41fb2b8f8d2829c18ea123a02f3e61c136206) ) + ROM_LOAD32_WORD( "ahg121199.u7", 0x000000, 0x80000, CRC(12b9aaf2) SHA1(1cc86a0c8daefc1e5b5a4ff710319a85f573f526) ) + ROM_LOAD32_WORD( "ahg121199.u11", 0x000002, 0x80000, CRC(b6095f2c) SHA1(d36ceaa0e6545f594f6a50ddfa71d84ca7128f3b) ) + ROM_LOAD32_WORD( "ahg121199.u8", 0x100000, 0x80000, CRC(a315ca28) SHA1(0309789362a945d592ee2eda912e4fc2e6ea5be6) ) // confirmed good + ROM_LOAD32_WORD( "ahg121199.u12", 0x100002, 0x80000, CRC(4b252c2c) SHA1(8be41fb2b8f8d2829c18ea123a02f3e61c136206) ) // confirmed good ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -4444,50 +4456,19 @@ ROM_START( marmagicua ) Checksum code found at 0x000d18 0x000000-0x0eda53 is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0xac229593 - Calculated Checksum 0x67abc369 (BAD) + Calculated Checksum 0xac229593 (OK) 0x0eda54-0x2fffef is the non-Checksummed range still containing data but NOT covered by Checksum 0x0eda54-0x2fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "ehg1559.u7", 0x000000, 0x80000, BAD_DUMP CRC(eab62e8f) SHA1(b125f9a9dc1c82886490d3807e883a7b4e1453a5) ) - ROM_LOAD32_WORD( "ehg1559.u11", 0x000002, 0x80000, BAD_DUMP CRC(0b3c6a11) SHA1(05be4a4d070358600273d5dd4f6b4b37fee47105) ) - ROM_LOAD32_WORD( "ehg1559.u8", 0x100000, 0x80000, BAD_DUMP CRC(db05591e) SHA1(8af241bbd4f744c66fb78fdaf739d9c8bc2580c0) ) - ROM_LOAD32_WORD( "ehg1559.u12", 0x100002, 0x80000, BAD_DUMP CRC(b4458167) SHA1(d1e2040910ad748e58eaccd18ab0569b794b4d97) ) - ROM_LOAD32_WORD( "ehg1559.u9", 0x200000, 0x80000, BAD_DUMP CRC(fc69523a) SHA1(c01b3c905b01671307bc5439d00f4454d0286b20) ) - ROM_LOAD32_WORD( "ehg1559.u13", 0x200002, 0x80000, BAD_DUMP CRC(0cd174df) SHA1(707168fc3bef6c200ae6455c170b7c3e73502965) ) - ROM_LOAD32_WORD( "ehg1559.u10", 0x300000, 0x80000, CRC(3db4e373) SHA1(7150242253ae4a1c4f3211e3068f00e8b1ed51b1) ) // known good dump - ROM_LOAD32_WORD( "ehg1559.u14", 0x300002, 0x80000, CRC(bdfdc0e4) SHA1(0e56f08abc0cdd9dfa5d8e51bb6fe06fa356b3b3) ) // known good dump - - ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ - ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) - ROM_REGION( 0x20000*4, "sram", ROMREGION_ERASE00 ) -ROM_END - - -// US003 / Multi credit / Multi line -// Margarita Magic / NSW/ACT / A - 07/07/2000 -// EHG1559 / This is a twenty-line game -// The playlines are 1, 5, 10, 15 and 20 -// For 20 credit per line the max bet is 400 -// ROM has NSW/ACT strings but it is for US platform -ROM_START( marmagicub ) - ARISTOCRAT_MK5_BIOS - /* - This ROM set is exactly the same version as the parent, yet is bad in a completely different way! - Comparing the ROM data between this one and the above bad dump, it is highly possible that this set can be repaired as this ROM set came from a good dump until it was stripped of carriage return symbols (0x0D) by a web server - The "_a" suffix is to differentiate the ROMs from the above set and does not correspond to the label, the correct label is simply EHG1559. - checksum code not found due to ROMs being corrupted, all files except the last 2 are missing bytes consisting of 0x0D - */ - ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - ROM_LOAD32_WORD( "ehg1559_a.u7", 0x000000, 0x7f03e, BAD_DUMP CRC(473afd5b) SHA1(823f8ad8cd5c3676feba8d740b50f25544a6c046) ) - ROM_LOAD32_WORD( "ehg1559_a.u11", 0x000002, 0x7ff66, BAD_DUMP CRC(c66df0dc) SHA1(015e6aed905bfef2f152137aa8aaaeaae41bc90e) ) - ROM_LOAD32_WORD( "ehg1559_a.u8", 0x100000, 0x7fcfe, BAD_DUMP CRC(5d2760d6) SHA1(655da82ae5dca1bb498399d2ee1efad7a3811cba) ) - ROM_LOAD32_WORD( "ehg1559_a.u12", 0x100002, 0x7fce2, BAD_DUMP CRC(56f9dcab) SHA1(2951a7189e5aa6e7338eb11f929fd6eea2541f0d) ) - ROM_LOAD32_WORD( "ehg1559_a.u9", 0x200000, 0x7ff4d, BAD_DUMP CRC(60323004) SHA1(8f188c7109538454a9ad5e14f21ab4ef76115153) ) - ROM_LOAD32_WORD( "ehg1559_a.u13", 0x200002, 0x7ff61, BAD_DUMP CRC(34320e8d) SHA1(b266d9c53cf746f1a164e006f14079bced2887ed) ) - ROM_LOAD32_WORD( "ehg1559.u10", 0x300000, 0x80000, CRC(3db4e373) SHA1(7150242253ae4a1c4f3211e3068f00e8b1ed51b1) ) - ROM_LOAD32_WORD( "ehg1559.u14", 0x300002, 0x80000, CRC(bdfdc0e4) SHA1(0e56f08abc0cdd9dfa5d8e51bb6fe06fa356b3b3) ) + ROM_LOAD32_WORD( "ehg1559.u7", 0x000000, 0x80000, CRC(dd4e4aa2) SHA1(c061a2d4a5814d62ac655f594dbfe4b96c2f68c4) ) + ROM_LOAD32_WORD( "ehg1559.u11", 0x000002, 0x80000, CRC(f1fd2079) SHA1(9dcd73eb46300dcf682b6165638c2d22e773a117) ) + ROM_LOAD32_WORD( "ehg1559.u8", 0x100000, 0x80000, CRC(db05591e) SHA1(8af241bbd4f744c66fb78fdaf739d9c8bc2580c0) ) + ROM_LOAD32_WORD( "ehg1559.u12", 0x100002, 0x80000, CRC(cbbc99b1) SHA1(96e8d18d12a7df0242fad073faa10fa52e604cf5) ) + ROM_LOAD32_WORD( "ehg1559.u9", 0x200000, 0x80000, CRC(54861629) SHA1(75fce0f47c45b049112a7e7d61b1bb3fba3e2c20) ) + ROM_LOAD32_WORD( "ehg1559.u13", 0x200002, 0x80000, CRC(8c111896) SHA1(60d2ffe82a39ef98d2cf0141773be95381538ace) ) + ROM_LOAD32_WORD( "ehg1559.u10", 0x300000, 0x80000, CRC(3db4e373) SHA1(7150242253ae4a1c4f3211e3068f00e8b1ed51b1) ) + ROM_LOAD32_WORD( "ehg1559.u14", 0x300002, 0x80000, CRC(bdfdc0e4) SHA1(0e56f08abc0cdd9dfa5d8e51bb6fe06fa356b3b3) ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -4969,16 +4950,15 @@ ROM_START( partygrsa ) Checksum code found at 0x000d18 0x000000-0x0a69d3 is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0xf4a004d3 - Calculated Checksum 0x221d04d3 (BAD) + Calculated Checksum 0xf4a004d3 (OK) 0x0a69d4-0x1b953f is the non-Checksummed range still containing data but NOT covered by Checksum 0x0a69d4-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "bhg1284.u7", 0x000000, 0x80000, BAD_DUMP CRC(02ed0631) SHA1(ae2c89c876a030d325ec94490d293deba772630e) ) - ROM_LOAD32_WORD( "bhg1284.u11", 0x000002, 0x80000, BAD_DUMP CRC(7ac80cd9) SHA1(70e910784a1e1ea8820005082e76223a85a3c346) ) - ROM_LOAD32_WORD( "bhg1284.u8", 0x100000, 0x80000, BAD_DUMP CRC(28774b9a) SHA1(ebdd738a73ffa7c5238640f4d7956751f7bb6243) ) - ROM_LOAD32_WORD( "bhg1284.u12", 0x100002, 0x80000, BAD_DUMP CRC(942835c1) SHA1(fefc509311716559ac6b836a56b2c981907d499b) ) + ROM_LOAD32_WORD( "bhg1284.u7", 0x000000, 0x80000, CRC(e9d2248a) SHA1(a010c722129cd78d14043356a24218d20d127a84) ) + ROM_LOAD32_WORD( "bhg1284.u11", 0x000002, 0x80000, CRC(d5da519b) SHA1(44b44b3839c63cde8fd6dee333b8fd70d89a5213) ) + ROM_LOAD32_WORD( "bhg1284.u8", 0x100000, 0x80000, CRC(3f72c99b) SHA1(df3a21d8c644ffa87d6c3ab091df03fa3e0ca4a4) ) + ROM_LOAD32_WORD( "bhg1284.u12", 0x100002, 0x80000, CRC(090ce72f) SHA1(a4783ca84aabd365613357a53a19a3dd48f4df0c) ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -5148,6 +5128,7 @@ ROM_END // BHI0417-03 / 586/7(b) / 10 Credit Multiplier / 9 Line Multiline // Penguin Pays / Export / B - 14/07/97 // All devices are 27c4002 instead of 27c4096 +// marked as 92.130% ROM_START( pengpayu ) ARISTOCRAT_MK5_BIOS_HAVE_EEPROMS /* @@ -6024,14 +6005,18 @@ ROM_END // Sweet Liberty Deluxe / Export / A - 11/02/01 ROM_START( sldeluxe ) ARISTOCRAT_MK5_BIOS - // checksum code not found due to ROMs being corrupted, first 6 files are missing bytes consisting of 0x0D + /* + Checksum code found at 0x000d18 + Expected Checksum 0xa86cc13c + Calculated Checksum 0xa86cc13c (OK) + */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - ROM_LOAD32_WORD( "ahg1575.u7", 0x000000, 0x7f066, BAD_DUMP CRC(cff7ed69) SHA1(04cc65e05cf30807d6616a66ab2b20048114a3dc) ) - ROM_LOAD32_WORD( "ahg1575.u11", 0x000002, 0x7ff6c, BAD_DUMP CRC(7ee540ae) SHA1(053ecb46f9075fe2925303472c8f83f39d38ccf7) ) - ROM_LOAD32_WORD( "ahg1575.u8", 0x100000, 0x7f6ad, BAD_DUMP CRC(08d1f9b2) SHA1(816b0f7087987930afbfeef68860b6ff82b6f208) ) - ROM_LOAD32_WORD( "ahg1575.u12", 0x100002, 0x7f6f8, BAD_DUMP CRC(b8f4fb1a) SHA1(e3536bcffe34515d52f014b45c48003f61fb730d) ) - ROM_LOAD32_WORD( "ahg1575.u9", 0x200000, 0x7f530, BAD_DUMP CRC(5089db27) SHA1(a7d91dab4f2561e3da74cb7f477f82da5cc5b82f) ) - ROM_LOAD32_WORD( "ahg1575.u13", 0x200002, 0x7f56f, BAD_DUMP CRC(452a68d2) SHA1(354ff2965155d8a3e67afb9a159a571b0f713ed1) ) + ROM_LOAD32_WORD( "ahg1575.u7", 0x000000, 0x80000, CRC(5962d463) SHA1(d78c3be7a2aa6d03888e928a5498a65b00ad4135) ) + ROM_LOAD32_WORD( "ahg1575.u11", 0x000002, 0x80000, CRC(93bfa5d9) SHA1(ed7dc7c558bd9889e5b49d81c62a62fd178cdceb) ) + ROM_LOAD32_WORD( "ahg1575.u8", 0x100000, 0x80000, CRC(856797d5) SHA1(f37254ff866fbc3f46c4ba12f7bc7c637ef53123) ) + ROM_LOAD32_WORD( "ahg1575.u12", 0x100002, 0x80000, CRC(ddd6cc1e) SHA1(231e079e44058747f6d80f5d41422a8407ace87f) ) + ROM_LOAD32_WORD( "ahg1575.u9", 0x200000, 0x80000, CRC(b3928eef) SHA1(676d5a1f48b8e71cd8ea0cd8d8ea2de6486b3971) ) + ROM_LOAD32_WORD( "ahg1575.u13", 0x200002, 0x80000, CRC(b4d22493) SHA1(f9d1e974b35f39eedaee34ea4775b86192a11e41) ) ROM_LOAD32_WORD( "ahg1575.u10", 0x300000, 0x80000, CRC(39f0f9f8) SHA1(51361ab74f1e6ae47acfddbccb220cc5da4725dd) ) ROM_LOAD32_WORD( "ahg1575.u14", 0x300002, 0x80000, CRC(bd890100) SHA1(c82b2891287429a3e77ccaf9b66139f0548f1902) ) @@ -6159,16 +6144,15 @@ ROM_START( swhr2u ) Checksum code found at 0x000d08 0x000000-0x0b31cb is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0x0720df2c - Calculated Checksum 0x3dad9905 (BAD) + Calculated Checksum 0x0720df2c (OK) 0x0b31cc-0x155097 is the non-Checksummed range still containing data but NOT covered by Checksum 0x0b31cc-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "phg074202.u7", 0x000000, 0x80000, BAD_DUMP CRC(d6f83014) SHA1(7c6902d67157a04bdbbfc7c7d8ae1e22befd840f) ) - ROM_LOAD32_WORD( "phg074202.u11", 0x000002, 0x80000, BAD_DUMP CRC(3fa6e538) SHA1(958461a54e57c4622151bbcde3de8f4ff3f9ec0a) ) - ROM_LOAD32_WORD( "phg074202.u8", 0x100000, 0x80000, BAD_DUMP CRC(916409f7) SHA1(d5c3cb7afac14a27f4722528a3dac4b4f2d41580) ) - ROM_LOAD32_WORD( "phg074202.u12", 0x100002, 0x80000, BAD_DUMP CRC(92f92875) SHA1(bdb24974c2bf7bfb772c34a02a20e97df9293c0c) ) + ROM_LOAD32_WORD( "phg074202.u7", 0x000000, 0x80000, CRC(2cb692f6) SHA1(d0f9952d01f95dd50078e98652b650b70e1cbb70) ) + ROM_LOAD32_WORD( "phg074202.u11", 0x000002, 0x80000, CRC(287c6a10) SHA1(023e8bd7364ec61fcd113527fa6be47c46faee02) ) + ROM_LOAD32_WORD( "phg074202.u8", 0x100000, 0x80000, CRC(57af1295) SHA1(2fb1a0ab8ea159ea891925a8720d0e88184db6fe) ) + ROM_LOAD32_WORD( "phg074202.u12", 0x100002, 0x80000, CRC(885cde6c) SHA1(a6ccf94ecdae2092a703075c9917d0b4004efa52) ) ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -6456,16 +6440,15 @@ ROM_START( trpdlghtu ) Checksum code found at 0x000d08 0x000000-0x0b2d1f is the Checksummed Range (excluding 0x000020-0x000027 where Checksum is stored) Expected Checksum 0x910fae87 - Calculated Checksum 0x2485ae87 (BAD) + Calculated Checksum 0x910fae87 (OK) 0x0b2d20-0x15384f is the non-Checksummed range still containing data but NOT covered by Checksum 0x0b2d20-0x1fffff is the non-Checksummed range if the additional vectors? at the end are included */ ROM_REGION( 0x400000, "game_prg", ROMREGION_ERASEFF ) - // the checksum only covers part of the first 2 roms, marked all as BAD_DUMP because it can't be trusted without a full redump. - ROM_LOAD32_WORD( "phg062502.u7", 0x000000, 0x80000, BAD_DUMP CRC(3d06765f) SHA1(737d714e4ec48eb6283489f745dd305e7d70dad2) ) // 92.25% - ROM_LOAD32_WORD( "phg062502.u11", 0x000002, 0x80000, BAD_DUMP CRC(3963a3de) SHA1(fc2b06af3d1eba87407425dc4296a8b602952775) ) // 92.25% - ROM_LOAD32_WORD( "phg062502.u8", 0x100000, 0x80000, BAD_DUMP CRC(d4858407) SHA1(acf6776f19448648a26aaf53fcb4bc227c546033) ) // base - ROM_LOAD32_WORD( "phg062502.u12", 0x100002, 0x80000, BAD_DUMP CRC(852e433e) SHA1(17ec568edbabe3ee8649b26f4c5d0f501494f823) ) // base + ROM_LOAD32_WORD( "phg062502.u7", 0x000000, 0x80000, CRC(fe556566) SHA1(fe8c6d699d08577691c766477530abf5cddccf6c) ) // 92.25% + ROM_LOAD32_WORD( "phg062502.u11", 0x000002, 0x80000, CRC(67e77c32) SHA1(178e6bbe2bb8b55afbe97177920b5f3c4a989adf) ) // 92.25% + ROM_LOAD32_WORD( "phg062502.u8", 0x100000, 0x80000, CRC(d4858407) SHA1(acf6776f19448648a26aaf53fcb4bc227c546033) ) // base + ROM_LOAD32_WORD( "phg062502.u12", 0x100002, 0x80000, CRC(0190804b) SHA1(7acb29fb7f77e78bb2afeb74d341475cd089dafb) ) // base ROM_REGION( 0x800000, "maincpu", ROMREGION_ERASE00 ) /* ARM Code */ ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 ) @@ -6942,209 +6925,209 @@ ROM_END #define MACHINE_FLAGS MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND|MACHINE_IMPERFECT_GRAPHICS -// YEAR NAME PARENT MACHINE INPUT STATE INIT ROT COMPANY FULLNAME FLAGS -GAME( 1995, aristmk5, 0, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "MKV Set/Clear Chips (USA)", MACHINE_FLAGS|MACHINE_IS_BIOS_ROOT ) +// YEAR NAME PARENT MACHINE INPUT STATE INIT ROT COMPANY FULLNAME FLAGS +GAME( 1995, aristmk5, 0, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "MKV Set/Clear Chips (USA)", MACHINE_FLAGS|MACHINE_IS_BIOS_ROOT ) // Dates listed below are for the combination (reel layout), not release dates -GAMEL( 1998, adonis, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Adonis (0200751V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/9, A - 25/05/98, Rev 10 -GAMEL( 1998, adonisa, adonis, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Adonis (0100751V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/9, A - 25/05/98, Rev 9 -GAMEL( 1999, adonisce, adonis, aristmk5, adonisce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Adonis - Cash Express (0201005V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/9, C - 06/07/99, Rev 12 -GAMEL( 2002, alchemst, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Alchemist (01J02046, Venezuela)", MACHINE_FLAGS, layout_yukongld ) // JB013/1, A - 22/01/02, Rev 17 -GAMEL( 2000, bparty, aristmk5, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bachelorette Party (BHG1248, US)", MACHINE_FLAGS, layout_bparty ) // MV4119/1, B - 25/08/2000 -GAMEL( 1996, baddog, aristmk5, aristmk5, baddog, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bad Dog Poker (0200428V, NSW/ACT)", MACHINE_FLAGS, layout_baddog ) // 386/56, A - 17/12/96 -GAMEL( 1998, bootsctn, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Boot Scootin' (0100812V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 616/1, B - 11/12/98, Rev 20 -GAMEL( 1999, bootsctnua,bootsctn, aristmk5_usa, pengpuck, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Boot Scootin' (GHG1008-03, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4098/1, A - 27/07/99 -GAMEL( 1996, bumblbug, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bumble Bugs (0200510V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 593, D - 5/07/96, Rev 3 -GAMEL( 1996, bumblbugql,bumblbug, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bumble Bugs (0200456V, Queensland)", MACHINE_FLAGS, layout_swhr2 ) // 593, D - 5/07/96, Rev 1.0 -GAMEL( 1995, buttdeli, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Butterfly Delight (0200143V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 571/4, A - 19/12/95, Rev 1.8.1.0 -GAMEL( 1998, cashcat, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Cat (0100676V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 614/3, A - 03/04/98, Rev 7 -GAMEL( 1997, cashcata, cashcat, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Cat (0100557V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 614/1, B - 01/12/97, Rev 7 -GAMEL( 1999, cashcatnz, cashcat, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Cat (0300863V, New Zealand)", MACHINE_FLAGS, layout_cashcatnz ) // MV4089, A - 4/1/99, Rev 26 -GAMEL( 1997, cashcham, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Chameleon (0100438V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 603/1, C - 15/4/97, Rev 1.25.3.0 -GAMEL( 1998, cashchama, cashcham, aristmk5, cashchama, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Chameleon (0200437V, NSW/ACT)", MACHINE_FLAGS, layout_cashchama ) // 603(a), D - 18/02/98, Rev 3 -GAMEL( 1998, cashchamnz,cashcham, aristmk5, cashchamnz, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Chameleon (0300781V, New Zealand)", MACHINE_FLAGS, layout_cashchamnz ) // MV4067, A - 31/08/98, Rev 21 -GAMEL( 1997, cashcra5, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Crop (0300467V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 607, C - 14/07/97, Rev 6 -GAMEL( 1998, chariotc, aristmk5, aristmk5, chariotc, aristmk5_state, aristmk5, ROT0, "Aristocrat", "The Chariot Challenge (0100787V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 630/1, A - 10/08/98, Rev 11 -GAMEL( 1998, chariotcv, chariotc, aristmk5, chariotcv, aristmk5_state, aristmk5, ROT0, "Aristocrat", "The Chariot Challenge (04J00714, Venezuela)", MACHINE_FLAGS, layout_snowcat ) // 630, A - 10/08/98, Rev 12 -GAMEL( 2001, checkma5, aristmk5, aristmk5, checkma5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Checkmate (01J00681, NSW/ACT)", MACHINE_FLAGS, layout_checkma5 ) // JB011, B - 06/07/01, Rev 17 -GAMEL( 1996, chickna5, aristmk5, aristmk5, chickna5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Chicken (0100351V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 596, A - 27/08/96, Rev 1.24 -GAMEL( 1998, chickna5qld,chickna5,aristmk5, chickna5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Chicken (0200530V, Queensland)", MACHINE_FLAGS, layout_snowcat ) // 596, C - 23/02/98, Rev 1.0 -GAMEL( 1998, chickna5u, chickna5, aristmk5_usa, chickna5u, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Chicken (RHG0730-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 596, C - 23/02/98 -GAMEL( 1998, coralrc2, aristmk5, aristmk5, coralrc2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Coral Riches II (0100919V, NSW/ACT)", MACHINE_FLAGS, layout_coralrc2 ) // 577/7, A - 29/12/98, Rev 12 -GAMEL( 1998, cuckoo, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cuckoo (0200753V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 615/1, D - 03/07/98, Rev 6 -GAMEL( 2000, cuckoou, cuckoo, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cuckoo (CHG1195, US)", MACHINE_FLAGS, layout_cuckoou ) // MV4104, C - 02/02/00 -GAMEL( 1995, dstbloom, aristmk5, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Desert Bloom (0300111V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 577/2, A - 12/10/95, Rev 1.16.4.0 -GAMEL( 1995, dstblooma, dstbloom, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Desert Bloom (0200111V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 577/2, A - 12/10/95, Rev 1.16.4.0 -GAMEL( 1999, diamdove, aristmk5, aristmk5, retrsam, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Diamond Dove (0101018V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 640, B - 19/05/99, Rev 8 -GAMEL( 1996, dmdfever, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Diamond Fever (0200302V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 483/7, E - 05/09/96, Rev 1.23.5.0 -GAMEL( 1997, dimtouch, aristmk5, aristmk5_touch, dimtouch, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Diamond Touch (0400433V, NSW/ACT)", MACHINE_FLAGS, layout_dimtouch ) // 604, E - 30/06/97, Rev 17 -GAMEL( 1996, dolphntr, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure (0200424V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/1, B - 06/12/96, Rev 3 -GAMEL( 1996, dolphntra, dolphntr, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure (0100424V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/1, B - 06/12/96, Rev 1.24.4.0 -GAMEL( 1996, dolphntrb, dolphntr, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure (0100388V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 602, B - 10/12/96, Rev 1.24.4.0 -GAMEL( 1996, dolphntru, dolphntr, aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure (FHG4077-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 602/1, B - 06/12/96 -GAMEL( 1999, dolphntrce,dolphntr, aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure - Cash Express (AHG1607, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4090, D - 22/12/99 -GAMEL( 1999, dolphntrcea,dolphntr,aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure - Cash Express (AHG1606, US)", MACHINE_FLAGS, layout_magimaska ) // MV4090, D - 22/12/99 -GAMEL( 1999, dolphntrceb,dolphntr,aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure - Cash Express (AHG1519, US)", MACHINE_FLAGS, layout_pengpuck ) // MV4090, D - 22/12/99 -GAMEL( 1997, drgneye, aristmk5, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dragon's Eye (0100521V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 610, A - 09/05/97, Rev 1.27 -GAMEL( 1997, dreamwv, aristmk5, aristmk5_touch, dreamwv, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dream Weaver (0200586V, NSW/ACT)", MACHINE_FLAGS, layout_dreamwv ) // 606/2, A - 20/06/97, Rev 16 -GAMEL( 2000, dynajack, aristmk5, aristmk5, dynajack, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dynamite Jack (01J00081, NSW/ACT)", MACHINE_FLAGS, layout_dynajack ) // JB004, A - 12/07/2000, Rev 17 -GAMEL( 1998, eldorda5, aristmk5, aristmk5, reelrock, aristmk5_state, aristmk5, ROT0, "Aristocrat", "El Dorado (0100652V, NSW/ACT)", MACHINE_FLAGS, layout_reelrock ) // 623, B - 24/03/98, Rev 3 -GAMEL( 1995, eforsta5, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Enchanted Forest (0400122V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 570/3, E - 23/06/95, Rev 1.18 -GAMEL( 1998, fastfort, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Fast Fortune (0100651V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 624, D - 07/05/98, Rev 5 -GAMEL( 2000, fortellr, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Fortune Teller (01J00131, NSW/ACT)", MACHINE_FLAGS, layout_fortellr ) // JB006, D - 24/11/2000, Rev 17 -GAMEL( 2001, geisha, aristmk5, aristmk5, geisha, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Geisha (0101408V, New Zealand)", MACHINE_FLAGS, layout_geisha ) // MV4127, A - 05/03/01, Rev 25 -GAMEL( 1999, genmagi, aristmk5, aristmk5_touch, genmagi, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Genie Magic (0200894V, NSW/ACT)", MACHINE_FLAGS, layout_genmagi ) // 632/1, C - 15/02/99, Rev 20 -GAMEL( 1998, gnomeatw, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Gnome Around The World (0100767V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 625, C - 18/12/98, Rev 16 -GAMEL( 1997, goldpyr, aristmk5, aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Golden Pyramids (AHG1205-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4091, B - 13/05/97 -GAMEL( 1998, goldpyrb, goldpyr, aristmk5, goldpyrb, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Golden Pyramids (0100878V, Victoria)", MACHINE_FLAGS, layout_goldpyrb ) // 602/5, C - 19/06/98 -GAMEL( 2000, goldenra, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Golden Ra (0101164V, NSW/ACT)", MACHINE_FLAGS, layout_goldenra ) // 661, A - 10/04/00, Rev 15 -GAMEL( 2000, honeypot, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Honey Pot (03J00241, NSW/ACT)", MACHINE_FLAGS, layout_yukongld ) // JB008, A - 21/11/2000, Rev 17 -GAMEL( 1999, incasun, aristmk5, aristmk5, incasun, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (0100872V, NSW/ACT)", MACHINE_FLAGS, layout_incasun ) // 631/3 B, B - 03/05/99, Rev 15 -GAMEL( 1999, incasunsp, incasun, aristmk5, incasun, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (0100872V, NSW/ACT, Show Program)", MACHINE_FLAGS, layout_incasun ) // 631/3 B, B - 03/05/99, Rev 15 -GAMEL( 2000, incasunnz, incasun, aristmk5, incasunnz, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (0101108V, New Zealand)", MACHINE_FLAGS, layout_incasunnz ) // MV4113, A - 6/3/00, Rev 25 -GAMEL( 2000, incasunu, incasun, aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (CHG1458, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4130/3, A - 05/09/00 -GAMEL( 1998, indrema5, aristmk5, aristmk5, indrema5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Indian Dreaming (0100845V, NSW/ACT)", MACHINE_FLAGS, layout_indrema5 ) // 628/1, B - 15/12/98, Rev 7 -GAMEL( 1996, jumpjoey, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Jumpin' Joey (0100383V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 586/6, C - 13/11/96 -GAMEL( 1996, jungjuic, aristmk5, aristmk5, jungjuic, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Jungle Juice (0200240V, New Zealand)", MACHINE_FLAGS, layout_jungjuic ) // 566/3, F - 06/03/96 -GAMEL( 1995, kgalah, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "King Galah (0200536V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 613/6, A - 21/07/95 -GAMEL( 1995, kgalaha, kgalah, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "King Galah (0100536V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 613, A - 21/07/95 -GAMEL( 1994, kgbirda5, aristmk5, aristmk5, kgbirda5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "K.G. Bird (0200024V, NSW/ACT)", MACHINE_FLAGS, layout_kgbirda5 ) // 540/3, D - 10/10/94 -GAMEL( 2001, koalamnt, aristmk5, aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Koala Mint (CHG1573, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4137, A - 12/09/01 -GAMEL( 1998, kookabuk, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Kooka Bucks (0100677V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 661, A - 03/04/98, Rev 5 -GAMEL( 1997, locoloot, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Loco Loot (0100473V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 599/3, C - 17/06/97, Rev 1.26.13.0 -GAMEL( 1997, locoloota, locoloot, aristmk5, locoloota, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Loco Loot (0100472V, NSW/ACT)", MACHINE_FLAGS, layout_locoloota ) // 599/2, C - 17/06/97, Rev 1.26.13.0 -GAMEL( 1998, locolootnz,locoloot, aristmk5, cashchamnz, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Loco Loot (0600725V, New Zealand)", MACHINE_FLAGS, layout_cashchamnz ) // MV4064, A - 8/7/98, Rev 24 -GAMEL( 1997, lonewolf, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Lone Wolf (0100587V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 621, A - 29/10/97, Rev 1.27.17.0 -GAMEL( 1995, luckyclo, aristmk5, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Lucky Clover (0300109V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 570/6, A - 12/10/95 -GAMEL( 2000, magimask, aristmk5, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Mask (AHG1549, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4115_1, A - 09/05/00 -GAMEL( 2000, magimaska, magimask, aristmk5_usa_touch, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Mask (AHG1548, US)", MACHINE_FLAGS, layout_magimaska ) // MV4115, A - 09/05/00 -GAMEL( 2000, magimaskb, magimask, aristmk5_usa_touch, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Mask (DHG1309, US)", MACHINE_FLAGS, layout_magimaska ) // MV4115, A - 09/05/00 -GAMEL( 1997, magtcha5, aristmk5, aristmk5_touch, dimtouch, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Touch (0300455V, NSW/ACT)", MACHINE_FLAGS, layout_dimtouch ) // 606, A - 06/03/97, Rev 14 -GAMEL( 1997, magtcha5a, magtcha5, aristmk5_touch, dimtouch, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Touch (0200455V, NSW/ACT)", MACHINE_FLAGS, layout_dimtouch ) // 606, A - 06/03/97, Rev 14 -GAMEL( 1997, mammothm, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mammoth Money (0100425V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 595/5, D - 07/04/97, Rev 1.22.14.1 -GAMEL( 2000, marmagic, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Margarita Magic (01J00101, NSW/ACT)", MACHINE_FLAGS, layout_marmagic ) // JB005, A - 07/07/00, Rev 17 -GAMEL( 2000, marmagicu, marmagic, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Margarita Magic (EHG1558, US)", MACHINE_FLAGS, layout_aristmk5_us ) // US003, 07/07/2000 -GAMEL( 1996, minemine, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mine, Mine, Mine (0400115V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 559/2, D - 16/01/96, Rev 1.18.3.0 -GAMEL( 1996, minemineu, minemine, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mine, Mine, Mine (VHG0416-99, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 559/2, E - 14/02/96 -GAMEL( 1997, monmouse, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Money Mouse (0400469V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 607/1, B - 08/04/97, Rev 6 -GAMEL( 1997, monmousea, monmouse, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Money Mouse (0300469V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 607/1, B - 08/04/97, Rev 6 -GAMEL( 2001, montree, aristmk5, aristmk5, montree, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Money Tree (0201397V, New Zealand)", MACHINE_FLAGS, layout_montree ) // MV4126, C - 12/04/01, Rev 5 -GAMEL( 1996, mountmon, aristmk5, aristmk5, mountmon, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mountain Money (0100294V, NSW/ACT)", MACHINE_FLAGS, layout_mountmon ) // 595/3, B - 11/06/96, Rev 1.22.5.0 -GAMEL( 1996, mountmona, mountmon, aristmk5, mystgard, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mountain Money (0100289V, NSW/ACT)", MACHINE_FLAGS, layout_mystgard ) // 595/2, C - 11/06/96, Rev 1.22.5.0 -GAMEL( 2000, multidrw, aristmk5, aristmk5, multidrw, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Multidraw - Free Games (0200956V, NSW/ACT)", MACHINE_FLAGS, layout_multidrw ) // 386/64, E - 08/05/00, Rev 17 -GAMEL( 1996, mystgard, aristmk5, aristmk5, mystgard, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mystic Garden (0100275V, NSW/ACT)", MACHINE_FLAGS, layout_mystgard ) // 595/1, B - 11/06/96, Rev 1.22 -GAMEL( 2001, one4all, aristmk5, aristmk5, one4all, aristmk5_state, aristmk5, ROT0, "Aristocrat", "One For All (0101503V, New Zealand)", MACHINE_FLAGS, layout_one4all ) // MV4141, A - 28/05/01, Rev 11 -GAMEL( 1999, orchidms, aristmk5, aristmk5, orchidms, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Orchid Mist (0200849V, NSW/ACT)", MACHINE_FLAGS, layout_orchidms ) // 601/3, C - 03/02/99, Rev 8 -GAMEL( 1999, orchidmsa, orchidms, aristmk5, orchidms, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Orchid Mist (0100849V, NSW/ACT)", MACHINE_FLAGS, layout_orchidms ) // 601/3, C - 03/02/99, Rev 6 -GAMEL( 1996, oscara5, aristmk5, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Oscar (0200348V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 593/2, C - 20/09/96, Rev 3 -GAMEL( 1996, oscara5a, oscara5, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Oscar (0100348V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 593/2, C - 20/09/96, Rev 1.23.9.1 -GAMEL( 1999, pantmag, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Panther Magic (0101046V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 594/7, A - 06/10/99, Rev 16 -GAMEL( 1999, pantmaga, pantmag, aristmk5, pantmaga, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Panther Magic (0100716V, NSW/ACT)", MACHINE_FLAGS, layout_pantmaga ) // 594/4, A - 13/05/98, Rev 9 -GAMEL( 2001, partygrs, aristmk5, aristmk5_usa_touch, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Party Gras (AHG1567, US)", MACHINE_FLAGS, layout_magimaska ) // MV4115/6, A - 10/11/01 -GAMEL( 2000, peaflut, aristmk5, aristmk5, trstrove, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Peacock Flutter (02J00011, NSW/ACT)", MACHINE_FLAGS, layout_trstrove ) // JB001, A - 10/03/00, Rev 8 -GAMEL( 1997, pengpay, aristmk5, aristmk5, cashchama, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0200460V, NSW/ACT)", MACHINE_FLAGS, layout_cashchama ) // 586/4(a), D - 03/06/97, Rev 3 -GAMEL( 1996, pengpaya, pengpay, aristmk5, cashchama, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0200357V, NSW/ACT)", MACHINE_FLAGS, layout_cashchama ) // 586/4, C - 12/11/96 -GAMEL( 1997, pengpayb, pengpay, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0200359V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 586/3(a), D - 03/06/97, Rev 4 -GAMEL( 1995, pengpayc, pengpay, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0200113V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 586, A - 12/10/95 -GAMEL( 1997, pengpayu, pengpay, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (BHI0417-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 586/7(b), B - 14/07/97 -GAMEL( 2001, pengpuck, pengpay, aristmk5_usa, pengpuck, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays - Penguin Pucks (EHG1257, US)", MACHINE_FLAGS, layout_pengpuck ) // MV4122/1, C - 19/01/01 -GAMEL( 1998, petshop, aristmk5, aristmk5, petshop, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Pet Shop (0100731V, NSW/ACT)", MACHINE_FLAGS, layout_petshop ) // 618/1, A - 17/04/98, Rev 13 -GAMEL( 1995, phantpay, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Phantom Pays (0500005V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 570/1, E - 12/09/95 -GAMEL( 1998, penpir, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pirate (0100674V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 619/1, A - 31/03/98, Rev 10 -GAMEL( 1998, penpira, penpir, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pirate (0200578V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 619, A - 27/02/98, Rev 8 -GAMEL( 1998, penpir2, aristmk5, aristmk5, penpir2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pirate II (0100869V, Victoria)", MACHINE_FLAGS, layout_penpir2 ) // 619/3, A - 17/12/98 -GAMEL( 1996, przfight, aristmk5, aristmk5, przfight, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Prize Fight (0100299V, NSW/ACT)", MACHINE_FLAGS, layout_przfight ) // 578/4, B - 08/08/96 -GAMEL( 1998, qcash, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queens of Cash (0100706V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 603/6, C - 23/07/98, Rev 6 -GAMEL( 1997, qnile, aristmk5, aristmk5, qnile, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0300439V, NSW/ACT)", MACHINE_FLAGS, layout_qnile ) // 602/4, B - 13/05/97, Rev 7 -GAMEL( 1997, qnilea, qnile, aristmk5, qnile, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0200439V, NSW/ACT)", MACHINE_FLAGS, layout_qnile ) // 602/4, B - 13/05/97, Rev 7 -GAMEL( 1997, qnileb, qnile, aristmk5, qnile, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0100439V, NSW/ACT)", MACHINE_FLAGS, layout_qnile ) // 602/4, B - 13/05/97, Rev 1.26.18.1 -GAMEL( 2002, qnilebr, qnile, aristmk5, goldpyrb, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0101707V, Brazil)", MACHINE_FLAGS, layout_goldpyrb ) // MV4162, A - 21/08/02 -GAMEL( 1997, qnilec, qnile, aristmk5, qnilec, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0300440V, NSW/ACT)", MACHINE_FLAGS, layout_qnilec ) // 602/3, B - 13/05/97, Rev 5 -GAMEL( 1999, qniled, qnile, aristmk5, checkma5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0101139V, NSW/ACT)", MACHINE_FLAGS, layout_qniled ) // 602/16, A - 11/10/99, Rev 14 -GAMEL( 2000, qnilenl, qnile, aristmk5, qnilenl, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0301059V, Holland)", MACHINE_FLAGS, layout_qnilenl ) // 602/5, G - 10/04/00 -GAMEL( 1997, qnileu, qnile, aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (GHG4091-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4091, B - 13/05/97 -GAMEL( 1997, qnilev, qnile, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (04J00784, Venezuela)", MACHINE_FLAGS, layout_dolphntrb ) // 602/3, B - 13/05/97, Rev 6 -GAMEL( 2001, qnilece, qnile, aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile - Cash Express (AHG1609, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4091/1, A - 17/01/01 -GAMEL( 2001, qnilecea, qnile, aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile - Cash Express (AHG1525, US)", MACHINE_FLAGS, layout_qnilecea ) // MV4091, F - 17/01/01 -GAMEL( 1999, qnilemax, qnile, aristmk5_touch, trstrove, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile - Maximillions (0401072V, NSW/ACT)", MACHINE_FLAGS, layout_trstrove ) // 602/4, D - 18/06/99, Rev 14 -GAMEL( 1994, qtbird, aristmk5, aristmk5, qtbird, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Q.T. Bird (0500009V, NSW/ACT)", MACHINE_FLAGS, layout_qtbird ) // 581, A - 27/10/94, Rev 1.1.1.0 -GAMEL( 2000, rainwrce, aristmk5, aristmk5, adonisce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Rainbow Warriors - Cash Express (0101332V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 655, B - 02/03/00, Rev 25 -GAMEL( 1998, reelpwr, aristmk5, aristmk5, wizways, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Reel Power (0100400V, NSW/ACT)", MACHINE_FLAGS, layout_wizways ) // 598/2, A - 01/11/96, Rev 1.23.8.0 -GAMEL( 1998, reelrock, aristmk5, aristmk5, reelrock, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Reelin-n-Rockin (0100779V, NSW/ACT)", MACHINE_FLAGS, layout_reelrock ) // 628, A - 13/07/98, Rev 5 -GAMEL( 1997, retrsam, aristmk5, aristmk5, retrsam, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Return of the Samurai (0400549V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 608, A - 17/04/97, Rev 5 -GAMEL( 1997, retrsama, retrsam, aristmk5, retrsam, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Return of the Samurai (0200549V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 608, A - 17/04/97, Rev 1.26.25.3 -GAMEL( 1997, retrsamb, retrsam, aristmk5, retrsamb, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Return of the Samurai (0200506V, NSW/ACT)", MACHINE_FLAGS, layout_retrsamb ) // 608, A - 17/04/97, Rev 1.26.25.3 -GAMEL( 1997, rushrst, aristmk5, aristmk5, rushrst, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Rushin Rooster (0100534V, NSW/ACT)", MACHINE_FLAGS, layout_cashchama ) // 596/3, C - 25/06/97, Rev 1.27.2.3 -GAMEL( 1998, slvrwolf, aristmk5, aristmk5, wamazona, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Silver Wolf (0100673V, NSW/ACT)", MACHINE_FLAGS, layout_wamazona ) // 621/2, A - 23/03/98, Rev 3 -GAMEL( 1996, snowcat, aristmk5, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Snow Cat (0100405V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 599, B - 23/12/96, Rev 1.25.1.0 -GAMEL( 1997, sumospin, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sumo Spins (0200606V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 622, A - 08/12/97, Rev 4 -GAMEL( 1998, sbuk3, aristmk5, aristmk5, sbuk3, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Super Bucks III (0200711V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 626, A - 22/04/98, Rev 8 -GAMEL( 1998, sbuk3a, sbuk3, aristmk5, sbuk3, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Super Bucks III (0100711V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 626, A - 22/04/98, Rev 7 -GAMEL( 1995, swhr2, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweethearts II (0200465V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 577/1, C - 07/09/95, Rev 3 -GAMEL( 1995, swhr2a, swhr2, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweethearts II (0200004V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 577/1, C - 07/09/95, Rev 1.1.3.0 -GAMEL( 1995, swhr2v, swhr2, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweethearts II (01J01986, Venezuela)", MACHINE_FLAGS, layout_swhr2 ) // 577/1, C - 07/09/95, Rev 3 -GAMEL( 1996, thor, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Thor (0200319V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 569/12, B - 14/08/96, Rev 1.23.7.0 -GAMEL( 1996, thndh, aristmk5, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Thunder Heart (0200333V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 570/9, A - 14/08/96, Rev 1.23.6.0 -GAMEL( 1996, thndha, thndh, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Thunder Heart (0200334V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 597/1, A - 14/08/96, Rev 1.23.6.0 -GAMEL( 1997, topbana, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Top Banana (0100550V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 594/3, A - 18/08/97, Rev 1.26.39.2 -GAMEL( 1998, toutango, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Toucan Tango (0100782V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 616/1, A - 17/06/98, Rev 16 -GAMEL( 1999, toutangonl, toutango, aristmk5, toutangonl, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Toucan Tango (0301388V, Holland)", MACHINE_FLAGS, layout_toutangonl ) // 616, C - 11/05/99 -GAMEL( 2000, trstrove, aristmk5, aristmk5, trstrove, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Treasure Trove (01J00161, NSW/ACT)", MACHINE_FLAGS, layout_trstrove ) // JB001/3, A - 5/10/00, Rev 8 -GAMEL( 2002, tritreat, aristmk5, aristmk5, trstrove, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Triple Treat (0201692V, NSW/ACT)", MACHINE_FLAGS, layout_trstrove ) // 692, A - 17/05/02, Rev 25 -GAMEL( 2001, trojhors, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Trojan Horse (01J00851, NSW/ACT)", MACHINE_FLAGS, layout_marmagic ) // JB001/5, A - 30/10/01, Rev 17 -GAMEL( 1996, trpdlght, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Tropical Delight (0100269V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 577/3, B - 15/05/96, Rev 1.22.2.0 -GAMEL( 1998, unicornd, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Unicorn Dreaming (0100791V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 631/1 A, A - 31/08/98, Rev 12 -GAMEL( 1998, unicornda, unicornd, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Unicorn Dreaming (0100813V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 631 A, A - 02/09/98, Rev 14 -GAMEL( 2000, unicorndnz,unicornd, aristmk5, unicorndnz, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Unicorn Dreaming (0101228V, New Zealand)", MACHINE_FLAGS, layout_aristmk5 ) // MV4113/1, A - 05/04/2000, Rev 27 -GAMEL( 2002, venicea5, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Venice (02J02056, Venezuela)", MACHINE_FLAGS, layout_venicea5 ) // JB009/2, B - 11/07/02, Rev 17 -GAMEL( 1996, wamazon, aristmk5, aristmk5, wamazon, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Amazon (0200507V, NSW/ACT)", MACHINE_FLAGS, layout_wamazon ) // 506/8, A - 10/10/96, Rev 3 -GAMEL( 1996, wamazona, wamazon, aristmk5, wamazona, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Amazon (0200285V, NSW/ACT)", MACHINE_FLAGS, layout_wamazona ) // 506/6, A - 7/5/96, Rev 1.22.8.0 -GAMEL( 1996, wamazonv, wamazon, aristmk5, wamazon, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Amazon (01J01996, Venezuela)", MACHINE_FLAGS, layout_wamazon ) // 506/8, A - 10/10/96, Rev 3 -GAMEL( 1997, wikwin, aristmk5, aristmk5, wikwin, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wicked Winnings (0100553V, NSW/ACT)", MACHINE_FLAGS, layout_wikwin ) // 609, B - 01/07/97, Rev 1 -GAMEL( 1996, wldangel, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Angels (0100337V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 600, B - 24/09/96 -GAMEL( 1996, wildbill, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Bill (0100297V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 543/8, C - 15/08/96, Rev 1.22.12.0 -GAMEL( 1996, wcougar, aristmk5, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Cougar (0100167V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 569/9, B - 27/2/96, Rev 1.18.1.0 -GAMEL( 1997, wcougaru, wcougar, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Cougar (NHG0296-04, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 569/8, D - 19/05/97 -GAMEL( 1996, wizways, aristmk5, aristmk5, wizways, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wizard Ways (0200396V, NSW/ACT)", MACHINE_FLAGS, layout_wizways ) // 598/3, A - 04/11/96, Rev 9 -GAMEL( 1997, wnpost, aristmk5, aristmk5_usa, wnpost, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Winning Post (RHG0418-04, US)", MACHINE_FLAGS, layout_wnpost ) // 541/2, G - 11/02/97 -GAMEL( 1999, wthing, aristmk5, aristmk5, retrsam, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Thing (0101158V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 608/4, B - 14/12/99, Rev 8 -GAMEL( 1999, wtiger, aristmk5, aristmk5, wtiger, aristmk5_state, aristmk5, ROT0, "Aristocrat", "White Tiger Classic (0200954V, NSW/ACT)", MACHINE_FLAGS, layout_wtiger ) // 638/1, B - 08/07/99, Rev 13 -GAMEL( 2000, yukongl5, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Yukon Gold (03J00191, NSW/ACT)", MACHINE_FLAGS, layout_yukongld ) // JB005/1, A - 30/10/2000, Rev 17 +GAMEL( 1998, adonis, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Adonis (0200751V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/9, A - 25/05/98, Rev 10 +GAMEL( 1998, adonisa, adonis, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Adonis (0100751V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/9, A - 25/05/98, Rev 9 +GAMEL( 1999, adonisce, adonis, aristmk5, adonisce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Adonis - Cash Express (0201005V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/9, C - 06/07/99, Rev 12 +GAMEL( 2001, adonisu, adonis, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Adonis (BHG1508, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4124/1, B - 31/07/01 +GAMEL( 2002, alchemst, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Alchemist (01J02046, Venezuela)", MACHINE_FLAGS, layout_yukongld ) // JB013/1, A - 22/01/02, Rev 17 +GAMEL( 2000, bparty, aristmk5, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bachelorette Party (BHG1248, US)", MACHINE_FLAGS, layout_bparty ) // MV4119/1, B - 25/08/2000 +GAMEL( 1996, baddog, aristmk5, aristmk5, baddog, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bad Dog Poker (0200428V, NSW/ACT)", MACHINE_FLAGS, layout_baddog ) // 386/56, A - 17/12/96 +GAMEL( 1998, bootsctn, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Boot Scootin' (0100812V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 616/1, B - 11/12/98, Rev 20 +GAMEL( 1999, bootsctnu, bootsctn, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Boot Scootin' (GHG1012-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4098, A - 25/08/99 +GAMEL( 1999, bootsctnua, bootsctn, aristmk5_usa, pengpuck, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Boot Scootin' (GHG1008-03, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4098/1, A - 27/07/99 +GAMEL( 1996, bumblbug, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bumble Bugs (0200510V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 593, D - 5/07/96, Rev 3 +GAMEL( 1996, bumblbugql, bumblbug, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bumble Bugs (0200456V, Queensland)", MACHINE_FLAGS, layout_swhr2 ) // 593, D - 5/07/96, Rev 1.0 +GAMEL( 1997, bumblbugu, bumblbug, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bumble Bugs (CHG0479-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 593, D - 05/07/97 +GAMEL( 1995, buttdeli, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Butterfly Delight (0200143V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 571/4, A - 19/12/95, Rev 1.8.1.0 +GAMEL( 1998, cashcat, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Cat (0100676V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 614/3, A - 03/04/98, Rev 7 +GAMEL( 1997, cashcata, cashcat, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Cat (0100557V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 614/1, B - 01/12/97, Rev 7 +GAMEL( 1999, cashcatnz, cashcat, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Cat (0300863V, New Zealand)", MACHINE_FLAGS, layout_cashcatnz ) // MV4089, A - 4/1/99, Rev 26 +GAMEL( 1997, cashcham, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Chameleon (0100438V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 603/1, C - 15/4/97, Rev 1.25.3.0 +GAMEL( 1998, cashchama, cashcham, aristmk5, cashchama, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Chameleon (0200437V, NSW/ACT)", MACHINE_FLAGS, layout_cashchama ) // 603(a), D - 18/02/98, Rev 3 +GAMEL( 1998, cashchamnz, cashcham, aristmk5, cashchamnz, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Chameleon (0300781V, New Zealand)", MACHINE_FLAGS, layout_cashchamnz ) // MV4067, A - 31/08/98, Rev 21 +GAMEL( 1996, cashchamu, cashcham, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Chameleon (DHG4078-99, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 603(a), B - 06/12/96 +GAMEL( 1997, cashcra5, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Crop (0300467V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 607, C - 14/07/97, Rev 6 +GAMEL( 1998, chariotc, aristmk5, aristmk5, chariotc, aristmk5_state, aristmk5, ROT0, "Aristocrat", "The Chariot Challenge (0100787V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 630/1, A - 10/08/98, Rev 11 +GAMEL( 1998, chariotcv, chariotc, aristmk5, chariotcv, aristmk5_state, aristmk5, ROT0, "Aristocrat", "The Chariot Challenge (04J00714, Venezuela)", MACHINE_FLAGS, layout_snowcat ) // 630, A - 10/08/98, Rev 12 +GAMEL( 2001, checkma5, aristmk5, aristmk5, checkma5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Checkmate (01J00681, NSW/ACT)", MACHINE_FLAGS, layout_checkma5 ) // JB011, B - 06/07/01, Rev 17 +GAMEL( 1996, chickna5, aristmk5, aristmk5, chickna5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Chicken (0100351V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 596, A - 27/08/96, Rev 1.24 +GAMEL( 1998, chickna5qld, chickna5, aristmk5, chickna5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Chicken (0200530V, Queensland)", MACHINE_FLAGS, layout_snowcat ) // 596, C - 23/02/98, Rev 1.0 +GAMEL( 1998, chickna5u, chickna5, aristmk5_usa, chickna5u, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Chicken (RHG0730-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 596, C - 23/02/98 +GAMEL( 1998, coralrc2, aristmk5, aristmk5, coralrc2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Coral Riches II (0100919V, NSW/ACT)", MACHINE_FLAGS, layout_coralrc2 ) // 577/7, A - 29/12/98, Rev 12 +GAMEL( 1998, cuckoo, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cuckoo (0200753V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 615/1, D - 03/07/98, Rev 6 +GAMEL( 2000, cuckoou, cuckoo, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cuckoo (CHG1195, US)", MACHINE_FLAGS, layout_cuckoou ) // MV4104, C - 02/02/00 +GAMEL( 1995, dstbloom, aristmk5, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Desert Bloom (0300111V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 577/2, A - 12/10/95, Rev 1.16.4.0 +GAMEL( 1995, dstblooma, dstbloom, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Desert Bloom (0200111V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 577/2, A - 12/10/95, Rev 1.16.4.0 +GAMEL( 1999, diamdove, aristmk5, aristmk5, retrsam, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Diamond Dove (0101018V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 640, B - 19/05/99, Rev 8 +GAMEL( 1996, dmdfever, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Diamond Fever (0200302V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 483/7, E - 05/09/96, Rev 1.23.5.0 +GAMEL( 1997, dimtouch, aristmk5, aristmk5_touch, dimtouch, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Diamond Touch (0400433V, NSW/ACT)", MACHINE_FLAGS, layout_dimtouch ) // 604, E - 30/06/97, Rev 17 +GAMEL( 1996, dolphntr, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure (0200424V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/1, B - 06/12/96, Rev 3 +GAMEL( 1996, dolphntra, dolphntr, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure (0100424V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 602/1, B - 06/12/96, Rev 1.24.4.0 +GAMEL( 1996, dolphntrb, dolphntr, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure (0100388V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 602, B - 10/12/96, Rev 1.24.4.0 +GAMEL( 1996, dolphntru, dolphntr, aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure (FHG4077-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 602/1, B - 06/12/96 +GAMEL( 1999, dolphntrce, dolphntr, aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure - Cash Express (AHG1607, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4090, D - 22/12/99 +GAMEL( 1999, dolphntrcea, dolphntr, aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure - Cash Express (AHG1606, US)", MACHINE_FLAGS, layout_magimaska ) // MV4090, D - 22/12/99 +GAMEL( 1999, dolphntrceb, dolphntr, aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dolphin Treasure - Cash Express (AHG1519, US)", MACHINE_FLAGS, layout_pengpuck ) // MV4090, D - 22/12/99 +GAMEL( 1997, drgneye, aristmk5, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dragon's Eye (0100521V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 610, A - 09/05/97, Rev 1.27 +GAMEL( 1997, dreamwv, aristmk5, aristmk5_touch, dreamwv, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dream Weaver (0200586V, NSW/ACT)", MACHINE_FLAGS, layout_dreamwv ) // 606/2, A - 20/06/97, Rev 16 +GAMEL( 2000, dynajack, aristmk5, aristmk5, dynajack, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dynamite Jack (01J00081, NSW/ACT)", MACHINE_FLAGS, layout_dynajack ) // JB004, A - 12/07/2000, Rev 17 +GAMEL( 1998, eldorda5, aristmk5, aristmk5, reelrock, aristmk5_state, aristmk5, ROT0, "Aristocrat", "El Dorado (0100652V, NSW/ACT)", MACHINE_FLAGS, layout_reelrock ) // 623, B - 24/03/98, Rev 3 +GAMEL( 1995, eforsta5, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Enchanted Forest (0400122V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 570/3, E - 23/06/95, Rev 1.18 +GAMEL( 1997, eforsta5u, eforsta5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Enchanted Forest (JHG0415-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4033, B - 10/02/97 +GAMEL( 1998, fastfort, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Fast Fortune (0100651V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 624, D - 07/05/98, Rev 5 +GAMEL( 2000, fortellr, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Fortune Teller (01J00131, NSW/ACT)", MACHINE_FLAGS, layout_fortellr ) // JB006, D - 24/11/2000, Rev 17 +GAMEL( 1998, gambler, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "The Gambler (EHG0916-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4084/1, A - 30/10/98 +GAMEL( 2001, geisha, aristmk5, aristmk5, geisha, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Geisha (0101408V, New Zealand)", MACHINE_FLAGS, layout_geisha ) // MV4127, A - 05/03/01, Rev 25 +GAMEL( 1999, genmagi, aristmk5, aristmk5_touch, genmagi, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Genie Magic (0200894V, NSW/ACT)", MACHINE_FLAGS, layout_genmagi ) // 632/1, C - 15/02/99, Rev 20 +GAMEL( 1998, gnomeatw, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Gnome Around The World (0100767V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 625, C - 18/12/98, Rev 16 +GAMEL( 1997, goldpyr, aristmk5, aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Golden Pyramids (AHG1205-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4091, B - 13/05/97 +GAMEL( 1997, goldpyra, goldpyr, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Golden Pyramids (AHG1206-99, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 602/2, B - 13/05/97 +GAMEL( 1998, goldpyrb, goldpyr, aristmk5, goldpyrb, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Golden Pyramids (0100878V, Victoria)", MACHINE_FLAGS, layout_goldpyrb ) // 602/5, C - 19/06/98 +GAMEL( 2000, goldenra, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Golden Ra (0101164V, NSW/ACT)", MACHINE_FLAGS, layout_goldenra ) // 661, A - 10/04/00, Rev 15 +GAMEL( 2000, honeypot, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Honey Pot (03J00241, NSW/ACT)", MACHINE_FLAGS, layout_yukongld ) // JB008, A - 21/11/2000, Rev 17 +GAMEL( 1999, incasun, aristmk5, aristmk5, incasun, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (0100872V, NSW/ACT)", MACHINE_FLAGS, layout_incasun ) // 631/3 B, B - 03/05/99, Rev 15 +GAMEL( 1999, incasunsp, incasun, aristmk5, incasun, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (0100872V, NSW/ACT, Show Program)", MACHINE_FLAGS, layout_incasun ) // 631/3 B, B - 03/05/99, Rev 15 +GAMEL( 2000, incasunnz, incasun, aristmk5, incasunnz, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (0101108V, New Zealand)", MACHINE_FLAGS, layout_incasunnz ) // MV4113, A - 6/3/00, Rev 25 +GAMEL( 2000, incasunu, incasun, aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (CHG1458, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4130/3, A - 05/09/00 +GAMEL( 2000, incasunua, incasun, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (DHG1577, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4130, A - 05/09/00 +GAMEL( 1998, indrema5, aristmk5, aristmk5, indrema5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Indian Dreaming (0100845V, NSW/ACT)", MACHINE_FLAGS, layout_indrema5 ) // 628/1, B - 15/12/98, Rev 7 +GAMEL( 1996, jumpjoey, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Jumpin' Joey (0100383V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 586/6, C - 13/11/96 +GAMEL( 1996, jungjuic, aristmk5, aristmk5, jungjuic, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Jungle Juice (0200240V, New Zealand)", MACHINE_FLAGS, layout_jungjuic ) // 566/3, F - 06/03/96 +GAMEL( 1995, kgalah, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "King Galah (0200536V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 613/6, A - 21/07/95 +GAMEL( 1995, kgalaha, kgalah, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "King Galah (0100536V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 613, A - 21/07/95 +GAMEL( 1994, kgbirda5, aristmk5, aristmk5, kgbirda5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "K.G. Bird (0200024V, NSW/ACT)", MACHINE_FLAGS, layout_kgbirda5 ) // 540/3, D - 10/10/94 +GAMEL( 2001, koalamnt, aristmk5, aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Koala Mint (CHG1573, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4137, A - 12/09/01 +GAMEL( 1998, kookabuk, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Kooka Bucks (0100677V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 661, A - 03/04/98, Rev 5 +GAMEL( 1997, locoloot, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Loco Loot (0100473V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 599/3, C - 17/06/97, Rev 1.26.13.0 +GAMEL( 1997, locoloota, locoloot, aristmk5, locoloota, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Loco Loot (0100472V, NSW/ACT)", MACHINE_FLAGS, layout_locoloota ) // 599/2, C - 17/06/97, Rev 1.26.13.0 +GAMEL( 1998, locolootnz, locoloot, aristmk5, cashchamnz, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Loco Loot (0600725V, New Zealand)", MACHINE_FLAGS, layout_cashchamnz ) // MV4064, A - 8/7/98, Rev 24 +GAMEL( 2001, locolootu, locoloot, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Loco Loot (AHG1513, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4134, A - 30/07/01 +GAMEL( 1997, lonewolf, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Lone Wolf (0100587V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 621, A - 29/10/97, Rev 1.27.17.0 +GAMEL( 1995, luckyclo, aristmk5, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Lucky Clover (0300109V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 570/6, A - 12/10/95 +GAMEL( 2000, magimask, aristmk5, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Mask (AHG1549, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4115_1, A - 09/05/00 +GAMEL( 2000, magimaska, magimask, aristmk5_usa_touch, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Mask (AHG1548, US)", MACHINE_FLAGS, layout_magimaska ) // MV4115, A - 09/05/00 +GAMEL( 2000, magimaskb, magimask, aristmk5_usa_touch, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Mask (DHG1309, US)", MACHINE_FLAGS, layout_magimaska ) // MV4115, A - 09/05/00 +GAMEL( 1997, magtcha5, aristmk5, aristmk5_touch, dimtouch, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Touch (0300455V, NSW/ACT)", MACHINE_FLAGS, layout_dimtouch ) // 606, A - 06/03/97, Rev 14 +GAMEL( 1997, magtcha5a, magtcha5, aristmk5_touch, dimtouch, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Touch (0200455V, NSW/ACT)", MACHINE_FLAGS, layout_dimtouch ) // 606, A - 06/03/97, Rev 14 +GAMEL( 1997, mammothm, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mammoth Money (0100425V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 595/5, D - 07/04/97, Rev 1.22.14.1 +GAMEL( 2000, marmagic, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Margarita Magic (01J00101, NSW/ACT)", MACHINE_FLAGS, layout_marmagic ) // JB005, A - 07/07/00, Rev 17 +GAMEL( 2000, marmagicu, marmagic, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Margarita Magic (EHG1558, US)", MACHINE_FLAGS, layout_aristmk5_us ) // US003, 07/07/2000 +GAMEL( 2000, marmagicua, marmagic, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Margarita Magic (EHG1559, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // US003, A - 07/07/00 +GAMEL( 1997, mgarden, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Garden (AHG1211-99, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4033, B - 10/02/97 (alt title for enchanted forest?) +GAMEL( 1996, minemine, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mine, Mine, Mine (0400115V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 559/2, D - 16/01/96, Rev 1.18.3.0 +GAMEL( 1996, minemineu, minemine, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mine, Mine, Mine (VHG0416-99, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 559/2, E - 14/02/96 +GAMEL( 1997, monmouse, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Money Mouse (0400469V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 607/1, B - 08/04/97, Rev 6 +GAMEL( 1997, monmousea, monmouse, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Money Mouse (0300469V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 607/1, B - 08/04/97, Rev 6 +GAMEL( 2001, montree, aristmk5, aristmk5, montree, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Money Tree (0201397V, New Zealand)", MACHINE_FLAGS, layout_montree ) // MV4126, C - 12/04/01, Rev 5 +GAMEL( 1996, mountmon, aristmk5, aristmk5, mountmon, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mountain Money (0100294V, NSW/ACT)", MACHINE_FLAGS, layout_mountmon ) // 595/3, B - 11/06/96, Rev 1.22.5.0 +GAMEL( 1996, mountmona, mountmon, aristmk5, mystgard, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mountain Money (0100289V, NSW/ACT)", MACHINE_FLAGS, layout_mystgard ) // 595/2, C - 11/06/96, Rev 1.22.5.0 +GAMEL( 2000, multidrw, aristmk5, aristmk5, multidrw, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Multidraw - Free Games (0200956V, NSW/ACT)", MACHINE_FLAGS, layout_multidrw ) // 386/64, E - 08/05/00, Rev 17 +GAMEL( 1996, mystgard, aristmk5, aristmk5, mystgard, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mystic Garden (0100275V, NSW/ACT)", MACHINE_FLAGS, layout_mystgard ) // 595/1, B - 11/06/96, Rev 1.22 +GAMEL( 2001, one4all, aristmk5, aristmk5, one4all, aristmk5_state, aristmk5, ROT0, "Aristocrat", "One For All (0101503V, New Zealand)", MACHINE_FLAGS, layout_one4all ) // MV4141, A - 28/05/01, Rev 11 +GAMEL( 1999, orchidms, aristmk5, aristmk5, orchidms, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Orchid Mist (0200849V, NSW/ACT)", MACHINE_FLAGS, layout_orchidms ) // 601/3, C - 03/02/99, Rev 8 +GAMEL( 1999, orchidmsa, orchidms, aristmk5, orchidms, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Orchid Mist (0100849V, NSW/ACT)", MACHINE_FLAGS, layout_orchidms ) // 601/3, C - 03/02/99, Rev 6 +GAMEL( 1996, oscara5, aristmk5, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Oscar (0200348V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 593/2, C - 20/09/96, Rev 3 +GAMEL( 1996, oscara5a, oscara5, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Oscar (0100348V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 593/2, C - 20/09/96, Rev 1.23.9.1 +GAMEL( 1999, pantmag, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Panther Magic (0101046V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 594/7, A - 06/10/99, Rev 16 +GAMEL( 1999, pantmaga, pantmag, aristmk5, pantmaga, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Panther Magic (0100716V, NSW/ACT)", MACHINE_FLAGS, layout_pantmaga ) // 594/4, A - 13/05/98, Rev 9 +GAMEL( 2001, partygrs, aristmk5, aristmk5_usa_touch, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Party Gras (AHG1567, US)", MACHINE_FLAGS, layout_magimaska ) // MV4115/6, A - 10/11/01 +GAMEL( 2001, partygrsa, partygrs, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Party Gras (BHG1284, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4115/3, B - 06/02/01 +GAMEL( 2000, peaflut, aristmk5, aristmk5, trstrove, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Peacock Flutter (02J00011, NSW/ACT)", MACHINE_FLAGS, layout_trstrove ) // JB001, A - 10/03/00, Rev 8 +GAMEL( 1997, pengpay, aristmk5, aristmk5, cashchama, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0200460V, NSW/ACT)", MACHINE_FLAGS, layout_cashchama ) // 586/4(a), D - 03/06/97, Rev 3 +GAMEL( 1996, pengpaya, pengpay, aristmk5, cashchama, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0200357V, NSW/ACT)", MACHINE_FLAGS, layout_cashchama ) // 586/4, C - 12/11/96 +GAMEL( 1997, pengpayb, pengpay, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0200359V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 586/3(a), D - 03/06/97, Rev 4 +GAMEL( 1995, pengpayc, pengpay, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0200113V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 586, A - 12/10/95 +GAMEL( 1997, pengpayu, pengpay, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (BHI0417-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 586/7(b), B - 14/07/97 +GAMEL( 2001, pengpuck, pengpay, aristmk5_usa, pengpuck, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays - Penguin Pucks (EHG1257, US)", MACHINE_FLAGS, layout_pengpuck ) // MV4122/1, C - 19/01/01 +GAMEL( 1998, petshop, aristmk5, aristmk5, petshop, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Pet Shop (0100731V, NSW/ACT)", MACHINE_FLAGS, layout_petshop ) // 618/1, A - 17/04/98, Rev 13 +GAMEL( 1995, phantpay, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Phantom Pays (0500005V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 570/1, E - 12/09/95 +GAMEL( 1998, penpir, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pirate (0100674V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 619/1, A - 31/03/98, Rev 10 +GAMEL( 1998, penpira, penpir, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pirate (0200578V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 619, A - 27/02/98, Rev 8 +GAMEL( 1998, penpir2, aristmk5, aristmk5, penpir2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pirate II (0100869V, Victoria)", MACHINE_FLAGS, layout_penpir2 ) // 619/3, A - 17/12/98 +GAMEL( 1996, przfight, aristmk5, aristmk5, przfight, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Prize Fight (0100299V, NSW/ACT)", MACHINE_FLAGS, layout_przfight ) // 578/4, B - 08/08/96 +GAMEL( 1998, qcash, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queens of Cash (0100706V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 603/6, C - 23/07/98, Rev 6 +GAMEL( 1997, qnile, aristmk5, aristmk5, qnile, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0300439V, NSW/ACT)", MACHINE_FLAGS, layout_qnile ) // 602/4, B - 13/05/97, Rev 7 +GAMEL( 1997, qnilea, qnile, aristmk5, qnile, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0200439V, NSW/ACT)", MACHINE_FLAGS, layout_qnile ) // 602/4, B - 13/05/97, Rev 7 +GAMEL( 1997, qnileb, qnile, aristmk5, qnile, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0100439V, NSW/ACT)", MACHINE_FLAGS, layout_qnile ) // 602/4, B - 13/05/97, Rev 1.26.18.1 +GAMEL( 2002, qnilebr, qnile, aristmk5, goldpyrb, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0101707V, Brazil)", MACHINE_FLAGS, layout_goldpyrb ) // MV4162, A - 21/08/02 +GAMEL( 1997, qnilec, qnile, aristmk5, qnilec, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0300440V, NSW/ACT)", MACHINE_FLAGS, layout_qnilec ) // 602/3, B - 13/05/97, Rev 5 +GAMEL( 1999, qniled, qnile, aristmk5, checkma5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0101139V, NSW/ACT)", MACHINE_FLAGS, layout_qniled ) // 602/16, A - 11/10/99, Rev 14 +GAMEL( 2000, qnilenl, qnile, aristmk5, qnilenl, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (0301059V, Holland)", MACHINE_FLAGS, layout_qnilenl ) // 602/5, G - 10/04/00 +GAMEL( 1997, qnileu, qnile, aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (GHG4091-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4091, B - 13/05/97 +GAMEL( 1997, qnilev, qnile, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile (04J00784, Venezuela)", MACHINE_FLAGS, layout_dolphntrb ) // 602/3, B - 13/05/97, Rev 6 +GAMEL( 2001, qnilece, qnile, aristmk5_usa, dolphntrce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile - Cash Express (AHG1609, US)", MACHINE_FLAGS, layout_dolphntrce ) // MV4091/1, A - 17/01/01 +GAMEL( 2001, qnilecea, qnile, aristmk5_usa, dolphntru, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile - Cash Express (AHG1525, US)", MACHINE_FLAGS, layout_qnilecea ) // MV4091, F - 17/01/01 +GAMEL( 1999, qnilemax, qnile, aristmk5_touch, trstrove, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Queen of the Nile - Maximillions (0401072V, NSW/ACT)", MACHINE_FLAGS, layout_trstrove ) // 602/4, D - 18/06/99, Rev 14 +GAMEL( 1994, qtbird, aristmk5, aristmk5, qtbird, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Q.T. Bird (0500009V, NSW/ACT)", MACHINE_FLAGS, layout_qtbird ) // 581, A - 27/10/94, Rev 1.1.1.0 +GAMEL( 2000, rainwrce, aristmk5, aristmk5, adonisce, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Rainbow Warriors - Cash Express (0101332V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 655, B - 02/03/00, Rev 25 +GAMEL( 1998, reelpwr, aristmk5, aristmk5, wizways, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Reel Power (0100400V, NSW/ACT)", MACHINE_FLAGS, layout_wizways ) // 598/2, A - 01/11/96, Rev 1.23.8.0 +GAMEL( 1998, reelrock, aristmk5, aristmk5, reelrock, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Reelin-n-Rockin (0100779V, NSW/ACT)", MACHINE_FLAGS, layout_reelrock ) // 628, A - 13/07/98, Rev 5 +GAMEL( 1997, retrsam, aristmk5, aristmk5, retrsam, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Return of the Samurai (0400549V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 608, A - 17/04/97, Rev 5 +GAMEL( 1997, retrsama, retrsam, aristmk5, retrsam, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Return of the Samurai (0200549V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 608, A - 17/04/97, Rev 1.26.25.3 +GAMEL( 1997, retrsamb, retrsam, aristmk5, retrsamb, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Return of the Samurai (0200506V, NSW/ACT)", MACHINE_FLAGS, layout_retrsamb ) // 608, A - 17/04/97, Rev 1.26.25.3 +GAMEL( 1997, rushrst, aristmk5, aristmk5, rushrst, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Rushin Rooster (0100534V, NSW/ACT)", MACHINE_FLAGS, layout_cashchama ) // 596/3, C - 25/06/97, Rev 1.27.2.3 +GAMEL( 2001, sldeluxe, aristmk5, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweet Liberty Deluxe (AHG1575, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4137, A - 11/02/01 +GAMEL( 1998, slvrwolf, aristmk5, aristmk5, wamazona, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Silver Wolf (0100673V, NSW/ACT)", MACHINE_FLAGS, layout_wamazona ) // 621/2, A - 23/03/98, Rev 3 +GAMEL( 1996, snowcat, aristmk5, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Snow Cat (0100405V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 599, B - 23/12/96, Rev 1.25.1.0 +GAMEL( 1997, sumospin, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sumo Spins (0200606V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 622, A - 08/12/97, Rev 4 +GAMEL( 1998, sbuk3, aristmk5, aristmk5, sbuk3, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Super Bucks III (0200711V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 626, A - 22/04/98, Rev 8 +GAMEL( 1998, sbuk3a, sbuk3, aristmk5, sbuk3, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Super Bucks III (0100711V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 626, A - 22/04/98, Rev 7 +GAMEL( 1995, swhr2, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweethearts II (0200465V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 577/1, C - 07/09/95, Rev 3 +GAMEL( 1995, swhr2a, swhr2, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweethearts II (0200004V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 577/1, C - 07/09/95, Rev 1.1.3.0 +GAMEL( 1998, swhr2u, swhr2, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweethearts II (PHG0742-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4061, A - 29/06/98 +GAMEL( 1995, swhr2v, swhr2, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweethearts II (01J01986, Venezuela)", MACHINE_FLAGS, layout_swhr2 ) // 577/1, C - 07/09/95, Rev 3 +GAMEL( 1996, thor, aristmk5, aristmk5, cashcham, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Thor (0200319V, NSW/ACT)", MACHINE_FLAGS, layout_cashcham ) // 569/12, B - 14/08/96, Rev 1.23.7.0 +GAMEL( 1996, thndh, aristmk5, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Thunder Heart (0200333V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 570/9, A - 14/08/96, Rev 1.23.6.0 +GAMEL( 1996, thndha, thndh, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Thunder Heart (0200334V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 597/1, A - 14/08/96, Rev 1.23.6.0 +GAMEL( 1997, topbana, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Top Banana (0100550V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 594/3, A - 18/08/97, Rev 1.26.39.2 +GAMEL( 1998, toutango, aristmk5, aristmk5, kgalah, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Toucan Tango (0100782V, NSW/ACT)", MACHINE_FLAGS, layout_kgalah ) // 616/1, A - 17/06/98, Rev 16 +GAMEL( 1999, toutangonl, toutango, aristmk5, toutangonl, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Toucan Tango (0301388V, Holland)", MACHINE_FLAGS, layout_toutangonl ) // 616, C - 11/05/99 +GAMEL( 2000, trstrove, aristmk5, aristmk5, trstrove, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Treasure Trove (01J00161, NSW/ACT)", MACHINE_FLAGS, layout_trstrove ) // JB001/3, A - 5/10/00, Rev 8 +GAMEL( 2002, tritreat, aristmk5, aristmk5, trstrove, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Triple Treat (0201692V, NSW/ACT)", MACHINE_FLAGS, layout_trstrove ) // 692, A - 17/05/02, Rev 25 +GAMEL( 2001, trojhors, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Trojan Horse (01J00851, NSW/ACT)", MACHINE_FLAGS, layout_marmagic ) // JB001/5, A - 30/10/01, Rev 17 +GAMEL( 1996, trpdlght, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Tropical Delight (0100269V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 577/3, B - 15/05/96, Rev 1.22.2.0 +GAMEL( 1997, trpdlghtu, trpdlght, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Tropical Delight (PHG0625-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 577/3, D - 24/09/97 +GAMEL( 1998, unicornd, aristmk5, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Unicorn Dreaming (0100791V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 631/1 A, A - 31/08/98, Rev 12 +GAMEL( 1998, unicornda, unicornd, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Unicorn Dreaming (0100813V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 631 A, A - 02/09/98, Rev 14 +GAMEL( 2000, unicorndnz, unicornd, aristmk5, unicorndnz, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Unicorn Dreaming (0101228V, New Zealand)", MACHINE_FLAGS, layout_aristmk5 ) // MV4113/1, A - 05/04/2000, Rev 27 +GAMEL( 2002, venicea5, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Venice (02J02056, Venezuela)", MACHINE_FLAGS, layout_venicea5 ) // JB009/2, B - 11/07/02, Rev 17 +GAMEL( 1996, wamazon, aristmk5, aristmk5, wamazon, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Amazon (0200507V, NSW/ACT)", MACHINE_FLAGS, layout_wamazon ) // 506/8, A - 10/10/96, Rev 3 +GAMEL( 1996, wamazona, wamazon, aristmk5, wamazona, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Amazon (0200285V, NSW/ACT)", MACHINE_FLAGS, layout_wamazona ) // 506/6, A - 7/5/96, Rev 1.22.8.0 +GAMEL( 1996, wamazonv, wamazon, aristmk5, wamazon, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Amazon (01J01996, Venezuela)", MACHINE_FLAGS, layout_wamazon ) // 506/8, A - 10/10/96, Rev 3 +GAMEL( 1997, wikwin, aristmk5, aristmk5, wikwin, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wicked Winnings (0100553V, NSW/ACT)", MACHINE_FLAGS, layout_wikwin ) // 609, B - 01/07/97, Rev 1 +GAMEL( 1996, wldangel, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Angels (0100337V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 600, B - 24/09/96 +GAMEL( 1996, wildbill, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Bill (0100297V, NSW/ACT)", MACHINE_FLAGS, layout_wildbill ) // 543/8, C - 15/08/96, Rev 1.22.12.0 +GAMEL( 1996, wcougar, aristmk5, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Cougar (0100167V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 569/9, B - 27/2/96, Rev 1.18.1.0 +GAMEL( 1997, wcougaru, wcougar, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Cougar (NHG0296-04, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 569/8, D - 19/05/97 +GAMEL( 1996, wizways, aristmk5, aristmk5, wizways, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wizard Ways (0200396V, NSW/ACT)", MACHINE_FLAGS, layout_wizways ) // 598/3, A - 04/11/96, Rev 9 +GAMEL( 1997, wnpost, aristmk5, aristmk5_usa, wnpost, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Winning Post (RHG0418-04, US)", MACHINE_FLAGS, layout_wnpost ) // 541/2, G - 11/02/97 +GAMEL( 1999, wthing, aristmk5, aristmk5, retrsam, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Thing (0101158V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk3 ) // 608/4, B - 14/12/99, Rev 8 +GAMEL( 1999, wtiger, aristmk5, aristmk5, wtiger, aristmk5_state, aristmk5, ROT0, "Aristocrat", "White Tiger Classic (0200954V, NSW/ACT)", MACHINE_FLAGS, layout_wtiger ) // 638/1, B - 08/07/99, Rev 13 +GAMEL( 2000, yukongl5, aristmk5, aristmk5, goldenra, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Yukon Gold (03J00191, NSW/ACT)", MACHINE_FLAGS, layout_yukongld ) // JB005/1, A - 30/10/2000, Rev 17 // the following parent sets are known bad dumps, and do not boot (confirmed) -GAMEL( 1996, blackpnt, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Black Panther (0200818V, Victoria)", MACHINE_FLAGS, layout_wildbill ) // 594/1, A - 30/07/96 -GAMEL( 1996, canrose, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Canyon Rose (AHG1463, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 603(a), B - 06/12/96 (same as Cash Chameleon) -GAMEL( 2000, diamdest, aristmk5, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Diamond Destiny (AHG1533, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4115_5, A - 09/05/2000 (same as Magic Mask) -GAMEL( 2001, fortfvr, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Fortune Fever (BHG1566, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4122/2, A - 13/05/01 -GAMEL( 1998, gambler, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "The Gambler (EHG0916-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4084/1, A - 30/10/98 -GAMEL( 1996, jumpbean, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Jumping Beans (0100161V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 586/2, A - 25/01/96 -GAMEL( 1997, mgarden, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Magic Garden (AHG1211-99, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4033, B - 10/02/97 -GAMEL( 1999, sbuk2, aristmk5, aristmk5, sbuk2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Super Bucks II (0400501V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk2 ) // 578, G - 26/07/99, Rev 7 -GAMEL( 2001, sldeluxe, aristmk5, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweet Liberty Deluxe (AHG1575, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4137, A - 11/02/01 -GAMEL( 2001, wcoyote, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Coyote (AHG1515, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4134, A - 30/07/01 +GAMEL( 1996, blackpnt, aristmk5, aristmk5, wildbill, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Black Panther (0200818V, Victoria)", MACHINE_FLAGS, layout_wildbill ) // 594/1, A - 30/07/96 +GAMEL( 1996, canrose, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Canyon Rose (AHG1463, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 603(a), B - 06/12/96 (same as Cash Chameleon) +GAMEL( 2000, diamdest, aristmk5, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Diamond Destiny (AHG1533, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4115_5, A - 09/05/2000 (same as Magic Mask) +GAMEL( 2001, fortfvr, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Fortune Fever (BHG1566, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4122/2, A - 13/05/01 +GAMEL( 1996, jumpbean, aristmk5, aristmk5, swhr2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Jumping Beans (0100161V, NSW/ACT)", MACHINE_FLAGS, layout_swhr2 ) // 586/2, A - 25/01/96 +GAMEL( 1999, sbuk2, aristmk5, aristmk5, sbuk2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Super Bucks II (0400501V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk2 ) // 578, G - 26/07/99, Rev 7 +GAMEL( 2001, wcoyote, aristmk5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Coyote (AHG1515, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4134, A - 30/07/01 + // the following clone sets are known bad dumps, and do not boot (confirmed) -GAMEL( 2001, adonisu, adonis, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Adonis (BHG1508, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4124/1, B - 31/07/01 -GAMEL( 1999, bootsctnu, bootsctn, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Boot Scootin' (GHG1012-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4098, A - 25/08/99 -GAMEL( 2000, bpartya, bparty, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bachelorette Party (BHG1579, US)", MACHINE_FLAGS, layout_bparty ) // MV4119/1, B - 25/08/2000 -GAMEL( 1997, bumblbugu, bumblbug, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bumble Bugs (CHG0479-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 593, D - 05/07/97 -GAMEL( 1996, cashchamu, cashcham, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Chameleon (DHG4078-99, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 603(a), B - 06/12/96 -GAMEL( 1997, cashcra5a, cashcra5, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Crop (0300447V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 607/2, C - 29/08/97, Rev 7 -GAMEL( 2001, dynajacku, dynajack, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dynamite Jack (CHG1562, US)", MACHINE_FLAGS, layout_aristmk5_us ) // US002, A - 11/07/01 -GAMEL( 2000, eforsta5ce, eforsta5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Enchanted Forest - Cash Express (CHG1536, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4108/6, C - 17/01/00 -GAMEL( 1997, eforsta5u, eforsta5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Enchanted Forest (JHG0415-03, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4033, B - 10/02/97 -GAMEL( 1997, goldpyra, goldpyr, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Golden Pyramids (AHG1206-99, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 602/2, B - 13/05/97 -GAMEL( 2000, incasunua, incasun, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Inca Sun (DHG1577, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4130, A - 05/09/00 -GAMEL( 2001, locolootu, locoloot, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Loco Loot (AHG1513, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4134, A - 30/07/01 -GAMEL( 2000, marmagicua, marmagic, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Margarita Magic (EHG1559, US, set 1)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // US003, A - 07/07/00 -GAMEL( 2000, marmagicub, marmagic, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Margarita Magic (EHG1559, US, set 2)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // US003, A - 07/07/00 -GAMEL( 2001, mountmonce, mountmon, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mountain Money - Cash Express (AHG1629, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4108/5, A - 10/03/01 -GAMEL( 2001, mountmonu, mountmon, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mountain Money (BHG1465, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4108/5, A - 10/03/01 -GAMEL( 2001, partygrsa, partygrs, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Party Gras (BHG1284, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4115/3, B - 06/02/01 -GAMEL( 2001, partygrsb, partygrs, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Party Gras (AHG1568, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4115/6, A - 10/11/2001, 20 lines -GAMEL( 1995, pengpayd, pengpay, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0300113V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 586, A - 12/10/95, Rev 4 -GAMEL( 1998, petshopa, petshop, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Pet Shop (0100679V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 618, A - 09/03/98, Rev 10 -GAMEL( 1995, sbuk2a, sbuk2, aristmk5, sbuk2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Super Bucks II (0300006V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk2 ) // no data due to missing ROMs -GAMEL( 1998, swhr2u, swhr2, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Sweethearts II (PHG0742-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4061, A - 29/06/98 -GAMEL( 1997, trpdlghtu, trpdlght, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Tropical Delight (PHG0625-02, US)", MACHINE_FLAGS, layout_aristmk5_us ) // 577/3, D - 24/09/97 -GAMEL( 2001, unicorndu, unicornd, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Unicorn Dreaming (BHG1584, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4130/1, C - 10/17/01 -GAMEL( 2000, wthinga, wthing, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Thing (0201176V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 608/5, B - 25/02/00, Rev 11 +GAMEL( 2000, bpartya, bparty, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Bachelorette Party (BHG1579, US)", MACHINE_FLAGS, layout_bparty ) // MV4119/1, B - 25/08/2000 +GAMEL( 1997, cashcra5a, cashcra5, aristmk5, aristmk5_9, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Cash Crop (0300447V, NSW/ACT)", MACHINE_FLAGS, layout_dolphntrb ) // 607/2, C - 29/08/97, Rev 7 +GAMEL( 2001, dynajacku, dynajack, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Dynamite Jack (CHG1562, US)", MACHINE_FLAGS, layout_aristmk5_us ) // US002, A - 11/07/01 +GAMEL( 2000, eforsta5ce, eforsta5, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Enchanted Forest - Cash Express (CHG1536, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4108/6, C - 17/01/00 +GAMEL( 2001, mountmonce, mountmon, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mountain Money - Cash Express (AHG1629, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4108/5, A - 10/03/01 +GAMEL( 2001, mountmonu, mountmon, aristmk5_usa, aristmk5_usa, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Mountain Money (BHG1465, US)", MACHINE_FLAGS, layout_aristmk5_us ) // MV4108/5, A - 10/03/01 +GAMEL( 2001, partygrsb, partygrs, aristmk5_usa_touch, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Party Gras (AHG1568, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4115/6, A - 10/11/2001, 20 lines +GAMEL( 1995, pengpayd, pengpay, aristmk5, wcougar, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Penguin Pays (0300113V, NSW/ACT)", MACHINE_FLAGS, layout_wcougar ) // 586, A - 12/10/95, Rev 4 +GAMEL( 1998, petshopa, petshop, aristmk5, snowcat, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Pet Shop (0100679V, NSW/ACT)", MACHINE_FLAGS, layout_snowcat ) // 618, A - 09/03/98, Rev 10 +GAMEL( 1995, sbuk2a, sbuk2, aristmk5, sbuk2, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Super Bucks II (0300006V, NSW/ACT)", MACHINE_FLAGS, layout_sbuk2 ) // no data due to missing ROMs +GAMEL( 2001, unicorndu, unicornd, aristmk5_usa, bootsctnua, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Unicorn Dreaming (BHG1584, US)", MACHINE_FLAGS, layout_aristmk5_us_200 ) // MV4130/1, C - 10/17/01 +GAMEL( 2000, wthinga, wthing, aristmk5, aristmk5, aristmk5_state, aristmk5, ROT0, "Aristocrat", "Wild Thing (0201176V, NSW/ACT)", MACHINE_FLAGS, layout_aristmk5 ) // 608/5, B - 25/02/00, Rev 11 diff --git a/src/mame/drivers/arsystems.cpp b/src/mame/drivers/arsystems.cpp index 86b05f5e895..986b4aaadd5 100644 --- a/src/mame/drivers/arsystems.cpp +++ b/src/mame/drivers/arsystems.cpp @@ -297,8 +297,8 @@ static MACHINE_CONFIG_START( arcadia ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_512kb_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_NVRAM_ADD_0FILL("nvram") diff --git a/src/mame/drivers/asst128.cpp b/src/mame/drivers/asst128.cpp index 67f2c7b5d01..70f091da1de 100644 --- a/src/mame/drivers/asst128.cpp +++ b/src/mame/drivers/asst128.cpp @@ -99,7 +99,7 @@ static MACHINE_CONFIG_START( asst128 ) MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("mb:pic8259", pic8259_device, inta_cb) MCFG_DEVICE_ADD("mb", ASST128_MOTHERBOARD, 0) - asst128_mb_device::static_set_cputag(*device, "maincpu"); + asst128_mb_device::static_set_cputag(*device, "^maincpu"); MCFG_DEVICE_INPUT_DEFAULTS(asst128) MCFG_DEVICE_MODIFY("mb:cassette") diff --git a/src/mame/drivers/astrocde.cpp b/src/mame/drivers/astrocde.cpp index dd57dfd4b37..0568c4773f7 100644 --- a/src/mame/drivers/astrocde.cpp +++ b/src/mame/drivers/astrocde.cpp @@ -1270,8 +1270,8 @@ static MACHINE_CONFIG_DERIVED( astrocade_16color_base, astrocade_base ) MCFG_DEVICE_ADD("bank4000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank4000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_NVRAM_ADD_0FILL("nvram") @@ -1432,7 +1432,7 @@ static MACHINE_CONFIG_DERIVED( profpac, astrocade_16color_base ) MCFG_DEVICE_MODIFY("bank4000") MCFG_DEVICE_PROGRAM_MAP(profpac_bank4000_map) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) MACHINE_CONFIG_END diff --git a/src/mame/drivers/at.cpp b/src/mame/drivers/at.cpp index 936f4302477..8ec6d0eb9b0 100644 --- a/src/mame/drivers/at.cpp +++ b/src/mame/drivers/at.cpp @@ -4,6 +4,54 @@ IBM AT Compatibles +Commodore PC 30-III and PC 40-III +================================= +Links: http://www.richardlagendijk.nl/cip/computer/item/pc30iii/en , ftp://ftp.zimmers.net/pub/cbm-pc/firmware/pc30/ +Info: The PC 30-III and PC 40-III share the same mainboard. On a PC 30-III the onboard Paradise VGA is not populated. +Form factor: Desktop PC +CPU: Intel 80286-12 +RAM: 1MB on board +Chipset: Faraday +Bus: 3x16 bit ISA, 1x8 bit ISA +Video: PC 30-III: ATI EGA Wonder 800+, PC 40-III: Onboard Paradise VGA, 256KB +Mass storage: One HD disk drive standard, second drive optional; PC 30-III: 20MB, PC 40-III: 40MB AT-IDE HD standard, 80MB or 100MB optional +On board: Serial, Parallel, Commodore 1532 Mouse port (MS Bus mouse compatible), Keyboard, Beeper, Floppy (2 devices), AT-IDE (1 device) +Options: 80287 + +Sanyo MBC-28 +============ +Links: http://www.cc-computerarchiv.de/CC-Archiv/bc-alt/gb-san/gb-san-12_91.html +Form factor: Desktop +CPU: 80386sx-20 +RAM: 1MB - 8MB on board +Mass storage: 1.44MB Floppy disk drive and 80MB IDE hard disk +On board: 2xserial, parallel, bus mouse, keyboard +To-Do: Complains about missing mouse hardware (Bus Mouse), hangs in POST + +Siemens PCD-2 +============= +Links: http://www.z80.eu/siemenspcd2.html , http://www.z80.eu/downloads/Siemens_PCD-2_SW-Monitor-Buchse-Belegung.pdf , https://www.computerwoche.de/a/at-klon-und-lan-ergaenzen-siemens-palette,1166395 +Form Factor: low profile desktop +CPU: 80286-12 on a Tandon supplied slot CPU card +RAM: 1MB - 4MB in four SIMM modules +Mass storage: 1.2MB Floppy disk drive and 20MB or 40MB MFM harddisk +Bus: Vertical passive ISA backplane with six slots +On board: 2xserial, parallel, floppy, keyboard, RTC, MFM harddisk controller piggybacked to bus extension on slot CPU +Options: 80287 + +Compaq Portable III +=================== +Links: http://www.old-computers.com/museum/computer.asp?c=1064 , http://www.freakedenough.at/infoseiten/read.php?id=66 , http://www.1000bit.it/ad/bro/compaq/CompaqProtable3.pdf , http://oldcomputers.net/compaqiii.pdf +Info: The later Compaq Portable 386 uses the same case, screen and video adapter; Models: 1 (no), 20 (20MB) and 40 (40MB harddisk) +Form factor: Luggable +CPU: AMD N80L286-12/S 12MHz (could be downclocked to 8MHz) +RAM: 640KB, attitional RAM cards were 512KB or 2MB to give 1.1MB, 1.6MB, 2.1MB, 2.6MB, 4.6MB or 6.6MB of total RAM +Video: AT&T 6300/Olivetti M24 driver compatible "Super CGA" with a 640x400 red/amber Plasma screen +Mass storage: One 1.2MB floppy disk drive, no/20MB/40MB hard disk +On board: Serial, Parallel, RTC, RGBI (external Monitor), keyboard +Options: 80827, Expansion box with 2 ISA slots, 300/1200Baud internal Modem, Compaq EGA Board +To-Do: Emulate Graphics card fully + ***************************************************************************/ #include "emu.h" @@ -280,6 +328,13 @@ MACHINE_START_MEMBER(at_state,vrom_fix) membank("vrom_bank")->set_base(machine().root_device().memregion("bios")->base()); } +static MACHINE_CONFIG_START( cfg_single_1200K ) + MCFG_DEVICE_MODIFY("fdc:0") + MCFG_SLOT_DEFAULT_OPTION("525hd") + MCFG_DEVICE_MODIFY("fdc:1") + MCFG_SLOT_DEFAULT_OPTION("") +MACHINE_CONFIG_END + static SLOT_INTERFACE_START( pci_devices ) SLOT_INTERFACE_INTERNAL("vt82c505", VT82C505) SLOT_INTERFACE_END @@ -432,6 +487,22 @@ static MACHINE_CONFIG_DERIVED( ct386sx, at386sx ) MCFG_CS8221_ADD("cs8221", "maincpu", "mb:isa", "maincpu") MACHINE_CONFIG_END +// Commodore PC 30-III +static MACHINE_CONFIG_DERIVED( pc30iii, ibm5170 ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_CLOCK(6000000) // should be XTAL_24MHz/2, but doesn't post with that setting + MCFG_DEVICE_MODIFY("isa1") + MCFG_DEVICE_SLOT_INTERFACE(pc_isa16_cards, "vga", false) // should be ATI EGA Wonder 800+ +MACHINE_CONFIG_END + +// Commodore PC 40-III +static MACHINE_CONFIG_DERIVED( pc40iii, ibm5170 ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_CLOCK(6000000) // should be XTAL_24MHz/2, but doesn't post with that setting + MCFG_DEVICE_MODIFY("isa1") + MCFG_DEVICE_SLOT_INTERFACE(pc_isa16_cards, "vga", false) // should be onboard Paradise VGA, see ROM declarations +MACHINE_CONFIG_END + static MACHINE_CONFIG_START( megapc ) MCFG_CPU_ADD("maincpu", I386SX, XTAL_50MHz / 2) MCFG_CPU_PROGRAM_MAP(megapc_map) @@ -593,6 +664,38 @@ static MACHINE_CONFIG_START( ficpio2 ) MCFG_VT82C496_REGION("isa") MACHINE_CONFIG_END +// Compaq Portable III +static MACHINE_CONFIG_START( comportiii ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", I80286, XTAL_48MHz/4 /*12000000*/) + MCFG_CPU_PROGRAM_MAP(at16_map) + MCFG_CPU_IO_MAP(at16_io) + MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("mb:pic8259_master", pic8259_device, inta_cb) + MCFG_80286_SHUTDOWN(DEVWRITELINE("mb", at_mb_device, shutdown)) + + MCFG_DEVICE_ADD("mb", AT_MB, 0) + MCFG_QUANTUM_TIME(attotime::from_hz(60)) + MCFG_FRAGMENT_ADD(at_softlists) + + MCFG_ISA16_SLOT_ADD("mb:isabus","board1", pc_isa16_cards, "fdc", true) + MCFG_SLOT_OPTION_MACHINE_CONFIG("fdc", cfg_single_1200K) + MCFG_ISA16_SLOT_ADD("mb:isabus","board2", pc_isa16_cards, "comat", true) + MCFG_ISA16_SLOT_ADD("mb:isabus","board3", pc_isa16_cards, "hdc", true) + MCFG_ISA16_SLOT_ADD("mb:isabus","board4", pc_isa16_cards, "cga_cportiii", true) + MCFG_ISA16_SLOT_ADD("mb:isabus","isa1", pc_isa16_cards, nullptr, false) + MCFG_ISA16_SLOT_ADD("mb:isabus","isa2", pc_isa16_cards, nullptr, false) + + MCFG_PC_KBDC_SLOT_ADD("mb:pc_kbdc", "kbd", pc_at_keyboards, STR_KBD_IBM_PC_AT_84) + + /* internal ram */ + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("640K") + MCFG_RAM_EXTRA_OPTIONS("1152K,1664K,2176K,2688K,4736K,6784K") +MACHINE_CONFIG_END + +//************************************************************************** +// ROM DEFINITIONS +//************************************************************************** ROM_START( ibm5170 ) ROM_REGION(0x20000,"bios", 0) @@ -728,13 +831,15 @@ ROM_START( at ) ROM_SYSTEM_BIOS(13, "aw303gs", "Award 303GS") ROMX_LOAD( "aw303gs-hi.bin", 0x18001, 0x4000, CRC(82392e18) SHA1(042453b7b29933a1b72301d21fcf8fa6b293c9c9), ROM_SKIP(1) | ROM_BIOS(14) ) ROMX_LOAD( "aw303gs-lo.bin", 0x18000, 0x4000, CRC(a4cf8ba1) SHA1(b73e34be3b2754aaed1ac06471f4441fea06c67c), ROM_SKIP(1) | ROM_BIOS(14) ) + ROM_SYSTEM_BIOS(14, "ami_200960", "AMI 200960") + ROMX_LOAD( "ami_286_bios_sn200960_even.bin", 0x10000, 0x8000, CRC(67745815) SHA1(ca6886c7a0716a92a8720fc71ff2d95328c467a5), ROM_SKIP(1) | ROM_BIOS(15) ) + ROMX_LOAD( "ami_286_bios_sn200960_odd.bin", 0x10001, 0x8000, CRC(360a5f73) SHA1(1b1980fd99779d0cdc4764928a641e081b35ee9f), ROM_SKIP(1) | ROM_BIOS(15) ) + ROM_SYSTEM_BIOS(15, "magitronic_b233", "Magitronic B233") // SUNTAC Chipset, http://toastytech.com/manuals/Magitronic%20B233%20Manual.pdf + ROMX_LOAD( "magitronic_b233_ami_1986_286_bios_plus_even_sa027343.bin", 0x10000, 0x8000, CRC(d4a18444) SHA1(d95242104fc9b51cf26de72ef5b6c52d99ccce30), ROM_SKIP(1) | ROM_BIOS(16) ) + ROMX_LOAD( "magitronic_b233_ami_1986_286_bios_plus_odd_sa027343.bin", 0x10001, 0x8000, CRC(7ac3db56) SHA1(4340140450c4f8b4f6a19eae50a5dc5449edfdf6), ROM_SKIP(1) | ROM_BIOS(16) ) + // ROM_LOAD("magitronic_b233_ami_1986_keyboard_bios_plus_a025352.bin", 0x0000, 0x1000), CRC(84fd28fd) SHA1(43da0f49e52c921844e60b6f3d22f2a316d865cc) ) ROM_END -ROM_START( cmdpc30 ) - ROM_REGION(0x20000,"bios", 0) - ROMX_LOAD( "commodore pc 30 iii even.bin", 0x18000, 0x4000, CRC(36307aa9) SHA1(50237ffea703b867de426ab9ebc2af46bac1d0e1),ROM_SKIP(1)) - ROMX_LOAD( "commodore pc 30 iii odd.bin", 0x18001, 0x4000, CRC(41bae42d) SHA1(27d6ad9554be86359d44331f25591e3122a31519),ROM_SKIP(1)) -ROM_END ROM_START( atvga ) ROM_REGION(0x20000,"bios", 0) @@ -882,34 +987,36 @@ ROM_START( at486 ) ROM_SYSTEM_BIOS(8, "ficgiovt2_326", "FIC 486-GIO-VT2 3.26G") /* 1994-07-06 */ ROMX_LOAD("326g1c00.awd", 0x10000, 0x10000, CRC(2e729ab5) SHA1(b713f97fa0e0b62856dab917f417f5b21020b354), ROM_BIOS(9)) - ROM_SYSTEM_BIOS(9, "ficgiovt2_3276", "FIC 486-GIO-VT2 3.276") /* 1997-07-17 */ - ROMX_LOAD("32760000.bin", 0x10000, 0x10000, CRC(ad179128) SHA1(595f67ba4a1c8eb5e118d75bf657fff3803dcf4f), ROM_BIOS(10)) - - ROM_SYSTEM_BIOS(10, "ficgvt2", "FIC 486-GVT-2 3.07G") /* 1994-11-02 */ - ROMX_LOAD("3073.bin", 0x10000, 0x10000, CRC(a6723863) SHA1(ee93a2f1ec84a3d67e267d0a490029f9165f1533), ROM_BIOS(11)) - ROM_SYSTEM_BIOS(11, "ficgpak2", "FIC 486-PAK-2 5.15S") /* 1995-06-27, includes Phoenix S3 TRIO64 Enhanced VGA BIOS 1.4-01 */ - ROMX_LOAD("515sbd8a.awd", 0x00000, 0x20000, CRC(778247e1) SHA1(07d8f0f2464abf507be1e8dfa06cd88737782411), ROM_BIOS(12)) - - ROM_SYSTEM_BIOS(12, "ficpio3g7", "FIC 486-PIO-3 1.15G705") /* pnp */ - ROMX_LOAD("115g705.awd", 0x00000, 0x20000, CRC(ddb1544a) SHA1(d165c9ecdc9397789abddfe0fef69fdf954fa41b), ROM_BIOS(13)) - ROM_SYSTEM_BIOS(13, "ficpio3g1", "FIC 486-PIO-3 1.15G105") /* non-pnp */ - ROMX_LOAD("115g105.awd", 0x00000, 0x20000, CRC(b327eb83) SHA1(9e1ff53e07ca035d8d43951bac345fec7131678d), ROM_BIOS(14)) - - ROM_SYSTEM_BIOS(14, "ficpos", "FIC 486-POS") - ROMX_LOAD("116di6b7.bin", 0x00000, 0x20000, CRC(d1d84616) SHA1(2f2b27ce100cf784260d8e155b48db8cfbc63285), ROM_BIOS(15)) - ROM_SYSTEM_BIOS(15, "ficpvt", "FIC 486-PVT 5.15") /* 1995-06-27 */ - ROMX_LOAD("5150eef3.awd", 0x00000, 0x20000, CRC(eb35785d) SHA1(1e601bc8da73f22f11effe9cdf5a84d52576142b), ROM_BIOS(16)) - ROM_SYSTEM_BIOS(16, "ficpvtio", "FIC 486-PVT-IO 5.162W2") /* 1995-10-05 */ - ROMX_LOAD("5162cf37.awd", 0x00000, 0x20000, CRC(378d813d) SHA1(aa674eff5b972b31924941534c3c988f6f78dc93), ROM_BIOS(17)) - ROM_SYSTEM_BIOS(17, "ficvipio426", "FIC 486-VIP-IO 4.26GN2") /* 1994-12-07 */ - ROMX_LOAD("426gn2.awd", 0x00000, 0x20000, CRC(5f472aa9) SHA1(9160abefae32b450e973651c052657b4becc72ba), ROM_BIOS(18)) - ROM_SYSTEM_BIOS(18, "ficvipio427", "FIC 486-VIP-IO 4.27GN2A") /* 1996-02-14 */ - ROMX_LOAD("427gn2a.awd", 0x00000, 0x20000, CRC(035ad56d) SHA1(0086db3eff711fc710b30e7f422fc5b4ab8d47aa), ROM_BIOS(19)) - ROM_SYSTEM_BIOS(19, "ficvipio2", "FIC 486-VIP-IO2") - ROMX_LOAD("1164g701.awd", 0x00000, 0x20000, CRC(7b762683) SHA1(84debce7239c8b1978246688ae538f7c4f519d13), ROM_BIOS(20)) - - ROM_SYSTEM_BIOS(20, "qdi", "QDI PX486DX33/50P3") - ROMX_LOAD("qdi_px486.u23", 0x10000, 0x10000, CRC(c80ecfb6) SHA1(34cc9ef68ff719cd0771297bf184efa83a805f3e), ROM_BIOS(21)) + ROM_SYSTEM_BIOS(9, "486_gio_vt2","VBS1.08H 486-GVT-2") /* 1995-06-19 */ + ROMX_LOAD("award_486_gio_vt2.bin", 0x10000, 0x10000, CRC(58d7c7f9) SHA1(097f15ec2bd672cb3f1763298ca802c7ff26021f), ROM_BIOS(10)) // Vobis version, Highscreen boot logo + ROM_SYSTEM_BIOS(10, "ficgiovt2_3276", "FIC 486-GIO-VT2 3.276") /* 1997-07-17 */ + ROMX_LOAD("32760000.bin", 0x10000, 0x10000, CRC(ad179128) SHA1(595f67ba4a1c8eb5e118d75bf657fff3803dcf4f), ROM_BIOS(11)) + + ROM_SYSTEM_BIOS(11, "ficgvt2", "FIC 486-GVT-2 3.07G") /* 1994-11-02 */ + ROMX_LOAD("3073.bin", 0x10000, 0x10000, CRC(a6723863) SHA1(ee93a2f1ec84a3d67e267d0a490029f9165f1533), ROM_BIOS(12)) + ROM_SYSTEM_BIOS(12, "ficgpak2", "FIC 486-PAK-2 5.15S") /* 1995-06-27, includes Phoenix S3 TRIO64 Enhanced VGA BIOS 1.4-01 */ + ROMX_LOAD("515sbd8a.awd", 0x00000, 0x20000, CRC(778247e1) SHA1(07d8f0f2464abf507be1e8dfa06cd88737782411), ROM_BIOS(13)) + + ROM_SYSTEM_BIOS(13, "ficpio3g7", "FIC 486-PIO-3 1.15G705") /* pnp */ + ROMX_LOAD("115g705.awd", 0x00000, 0x20000, CRC(ddb1544a) SHA1(d165c9ecdc9397789abddfe0fef69fdf954fa41b), ROM_BIOS(14)) + ROM_SYSTEM_BIOS(14, "ficpio3g1", "FIC 486-PIO-3 1.15G105") /* non-pnp */ + ROMX_LOAD("115g105.awd", 0x00000, 0x20000, CRC(b327eb83) SHA1(9e1ff53e07ca035d8d43951bac345fec7131678d), ROM_BIOS(15)) + + ROM_SYSTEM_BIOS(15, "ficpos", "FIC 486-POS") + ROMX_LOAD("116di6b7.bin", 0x00000, 0x20000, CRC(d1d84616) SHA1(2f2b27ce100cf784260d8e155b48db8cfbc63285), ROM_BIOS(16)) + ROM_SYSTEM_BIOS(16, "ficpvt", "FIC 486-PVT 5.15") /* 1995-06-27 */ + ROMX_LOAD("5150eef3.awd", 0x00000, 0x20000, CRC(eb35785d) SHA1(1e601bc8da73f22f11effe9cdf5a84d52576142b), ROM_BIOS(17)) + ROM_SYSTEM_BIOS(17, "ficpvtio", "FIC 486-PVT-IO 5.162W2") /* 1995-10-05 */ + ROMX_LOAD("5162cf37.awd", 0x00000, 0x20000, CRC(378d813d) SHA1(aa674eff5b972b31924941534c3c988f6f78dc93), ROM_BIOS(18)) + ROM_SYSTEM_BIOS(18, "ficvipio426", "FIC 486-VIP-IO 4.26GN2") /* 1994-12-07 */ + ROMX_LOAD("426gn2.awd", 0x00000, 0x20000, CRC(5f472aa9) SHA1(9160abefae32b450e973651c052657b4becc72ba), ROM_BIOS(19)) + ROM_SYSTEM_BIOS(19, "ficvipio427", "FIC 486-VIP-IO 4.27GN2A") /* 1996-02-14 */ + ROMX_LOAD("427gn2a.awd", 0x00000, 0x20000, CRC(035ad56d) SHA1(0086db3eff711fc710b30e7f422fc5b4ab8d47aa), ROM_BIOS(20)) + ROM_SYSTEM_BIOS(20, "ficvipio2", "FIC 486-VIP-IO2") + ROMX_LOAD("1164g701.awd", 0x00000, 0x20000, CRC(7b762683) SHA1(84debce7239c8b1978246688ae538f7c4f519d13), ROM_BIOS(21)) + + ROM_SYSTEM_BIOS(21, "qdi", "QDI PX486DX33/50P3") + ROMX_LOAD("qdi_px486.u23", 0x10000, 0x10000, CRC(c80ecfb6) SHA1(34cc9ef68ff719cd0771297bf184efa83a805f3e), ROM_BIOS(22)) ROM_END @@ -938,6 +1045,32 @@ ROM_START( c386sx16 ) ROM_LOAD16_BYTE( "390915-01.u38", 0x10001, 0x8000, CRC(ee4bad92) SHA1(6e02ef97a7ce336485814c06a1693bc099ce5cfb)) /* 390915-01 V1.03 CS-2100 U38 Copyright (C) 1990 CBM */ ROM_END +// Commodore PC 30-III +ROM_START( pc30iii ) + ROM_REGION(0x20000,"bios", 0) + ROM_SYSTEM_BIOS(0, "pc30iii_v200", "PC 30-III v2.00") + ROMX_LOAD( "pc30iii_390339-02_3e58.bin", 0x18000, 0x4000, CRC(f4a5860e) SHA1(b843744fe928bcfd8e037b0208cc85c0746535cf),ROM_SKIP(1) | ROM_BIOS(1) ) + ROMX_LOAD( "pc30iii_390340-02_42a8.bin", 0x18001, 0x4000, CRC(934df54a) SHA1(3b1c8916ba2b2517bc9f26dd74254586bcf0e91d),ROM_SKIP(1) | ROM_BIOS(1) ) + ROM_SYSTEM_BIOS(1, "pc30iii_v201", "PC 30-III v2.01") + ROMX_LOAD( "cbm-pc30c-bios-lo-v2.01-390339-03-35c1.bin", 0x18000, 0x4000, CRC(36307aa9) SHA1(50237ffea703b867de426ab9ebc2af46bac1d0e1),ROM_SKIP(1) | ROM_BIOS(2) ) + ROMX_LOAD( "cbm-pc30c-bios-hi-v2.01-390340-03-3f3f.bin", 0x18001, 0x4000, CRC(41bae42d) SHA1(27d6ad9554be86359d44331f25591e3122a31519),ROM_SKIP(1) | ROM_BIOS(2) ) +ROM_END + +// Commodore PC 40-III +ROM_START( pc40iii ) + // VGA BIOS + // ROM_LOAD( "pc40iii_390337-01_v2.0_f930.bin", 0x00000, 0x4000, CRC(82b210d3) SHA1(1380107deef02455c6ce4d12162fdc32e375cbde)) + // ROM_LOAD( "pc40iii_390338-01_v2.0_b6d0.bin", 0x00001, 0x4000, CRC(526d7424) SHA1(60511ca0e856b7611d556aa82219d646f96c9b94)) + + ROM_REGION(0x20000,"bios", 0) + ROM_SYSTEM_BIOS(0, "pc40iii_v200", "PC 40-III v2.00") + ROMX_LOAD( "pc40iii_390339-01_v2.0_473a.bin", 0x18000, 0x4000, CRC(2ad2dc0f) SHA1(b41d5988fda8cc23418c3f665d780c617aa3fc2b),ROM_SKIP(1) | ROM_BIOS(1) ) + ROMX_LOAD( "pc40iii_390340-01_v2.0_4bc6.bin", 0x18001, 0x4000, CRC(62dc7d93) SHA1(e741528697b1d00450fd18e3db8b925606e0bd22),ROM_SKIP(1) | ROM_BIOS(1) ) + ROM_SYSTEM_BIOS(1, "pc40iii_v201", "PC 40-III v2.03") + ROMX_LOAD( "cbm-pc40c-bios-lo-v2.03-390339-04-03bc.bin", 0x18000, 0x4000, CRC(e5fd11c6) SHA1(18c21d9a4ae687eef5464b76a0d614b9dfd30ec8),ROM_SKIP(1) | ROM_BIOS(2) ) + ROMX_LOAD( "cbm-pc40c-bios-hi-v2.03-390340-04-3344.bin", 0x18001, 0x4000, CRC(63d6f0f7) SHA1(a88dee7694baa71913acbe76cb4e2a4e95979ad9),ROM_SKIP(1) | ROM_BIOS(2) ) +ROM_END + ROM_START( xb42663 ) ROM_REGION(0x20000,"bios", 0) ROM_LOAD16_BYTE( "qi310223.lo", 0x00000, 0x10000, CRC(53047f49) SHA1(7b38e533f7f27295269549c63e5477d950239167)) @@ -1095,58 +1228,93 @@ ROM_START( pc2386 ) ROM_LOAD( "40211.ic801", 0x000, 0x1000, CRC(4440d981) SHA1(a76006a929f26c178e09908c66f28abc92e7744c) ) ROM_END +// Kaypro 286i ROM_START( k286i ) ROM_REGION(0x20000,"bios", 0) ROM_LOAD16_BYTE( "81_1598", 0x18000, 0x4000, CRC(e25a1e43) SHA1(d00b976ac94323f3867b1c256e315839c906dd5a) ) ROM_LOAD16_BYTE( "81_1599", 0x18001, 0x4000, CRC(08e2a17b) SHA1(a86ef116e82eb9240e60b52f76e5e510cdd393fd) ) ROM_END +// Sanyo MBC-28 +ROM_START( mbc28 ) // Complains about missing mouse hardware + ROM_REGION(0x20000,"bios", 0) + ROM_LOAD16_BYTE( "mbc-28_sl-dt_ver.1620_low_din_checksum_(454f00)_27c256-15.bin", 0x10000, 0x8000, CRC(423b4693) SHA1(08e877baa59ebd9a1817dcdd27138c638edcbb84) ) + ROM_LOAD16_BYTE( "mbc-28_sl-dt_ver.1620_high_din_checksum_(45ae00)_27c256-15.bin", 0x10001, 0x8000, CRC(557b7346) SHA1(c0dca88627f8451211172441fefb4020839fb87f) ) +ROM_END + +// Siemens PCD-2 +ROM_START( pcd2 ) + ROM_REGION(0x20000,"bios", 0) + ROM_LOAD16_BYTE( "bios_tandon_188782-032a_rev_5.21_low.bin", 0x10000, 0x8000, CRC(a8fbffd3) SHA1(8a3ad5bc7f86ff984be10a8b1ae4542be4c80e5f) ) + ROM_LOAD16_BYTE( "bios_tandon_188782-031a_rev_5.21_high.bin", 0x10001, 0x8000, CRC(8d7dfdcc) SHA1(d1d58c0ad7db60399f9a93db48feb10e44ffd624) ) + // ROM_LOAD( "kbd_8742_award_upi_1.61_rev_1.01.bin", 0x0000, 0x0800, CRC(bb8a1979) SHA(43d35ecf76e5e8d5ddf6c32b0f6f628a7542d6e4) ) // 8742 keyboard controller + // ROM_LOAD( "vga_nmc27c256q_435-0029-04_1988_video7_arrow.bin", 0x8000, 0x0800, CRC(0d8d7dff) SHA(cb5b2ab78d480ec3164d16c9c75f1449fa81a0e7) ) // Video7 VGA card + // ROM_LOAD( "vga_nmc27c256q_435-0030-04_1988_video7_arrow.bin", 0x8000, 0x0800, CRC(0935c003) SHA(35ac571818f616b856da8bbf6a7a9172f68b3ab6) ) +ROM_END + +// Compaq Portable III +ROM_START( comportiii ) + ROM_REGION(0x20000,"bios", 0) + ROM_SYSTEM_BIOS(0, "106779-002", "106779-002") + ROMX_LOAD( "cpiii_87c128_106779-002.bin", 0x18000, 0x4000, CRC(aef8f532) SHA1(b0374d5aa8766f11043cbaee007e6d311f792e44), ROM_SKIP(1) | ROM_BIOS(1) ) + ROMX_LOAD( "cpiii_87c128_106778-002.bin", 0x18001, 0x4000, CRC(c259f628) SHA1(df0ca8aaead617114fbecb4ececbd1a3bb1d5f30), ROM_SKIP(1) | ROM_BIOS(1) ) + // ROM_LOAD( "cpiii_106436-001.bin", 0x0000, 0x1000, CRC(5acc716b) SHA(afe166ecf99136d15269e44ebf2d66317945bf9c) ) // keyboard + ROM_SYSTEM_BIOS(1, "109737-002", "109737-002") + ROMX_LOAD( "109738-002.bin", 0x10000, 0x8000, CRC(db131b8a) SHA1(6a8517a771272edf16870501fc1ed94c7555ef45), ROM_SKIP(1) | ROM_BIOS(2) ) + ROMX_LOAD( "109737-002.bin", 0x10001, 0x8000, CRC(8463cc41) SHA1(cb9801591e4a2cd13bbcc40739c9e675ba84c079), ROM_SKIP(1) | ROM_BIOS(2) ) +ROM_END + /*************************************************************************** Game driver(s) ***************************************************************************/ -/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ -COMP ( 1984, ibm5170, 0, ibm5150, ibm5170, 0, at_state, at, "International Business Machines", "IBM PC/AT 5170", MACHINE_NOT_WORKING ) -COMP ( 1985, ibm5170a, ibm5170, 0, ibm5170a, 0, at_state, at, "International Business Machines", "IBM PC/AT 5170 8MHz", MACHINE_NOT_WORKING ) -COMP ( 1985, ibm5162, ibm5170, 0, ibm5162, 0, at_state, at, "International Business Machines", "IBM PC/XT-286 5162", MACHINE_NOT_WORKING ) -COMP ( 1989, ibmps1es, ibm5170, 0, ibmps1, 0, at_state, at, "International Business Machines", "IBM PS/1 (Spanish)", MACHINE_NOT_WORKING ) -COMP ( 1987, at, ibm5170, 0, ibm5162, 0, at_state, at, "<generic>", "PC/AT (CGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) -COMP ( 1987, atvga, ibm5170, 0, atvga, 0, at_state, at, "<generic>", "PC/AT (VGA, MF2 Keyboard)" , MACHINE_NOT_WORKING ) -COMP ( 1988, at386, ibm5170, 0, at386, 0, at_state, at, "<generic>", "PC/AT 386 (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) -COMP ( 1988, ct386sx, ibm5170, 0, ct386sx, 0, at_state, at, "<generic>", "NEAT 386SX (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) -COMP ( 1988, at386sx, ibm5170, 0, at386sx, 0, at_state, at, "<generic>", "PC/AT 386SX (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) -COMP ( 1990, at486, ibm5170, 0, at486, 0, at_state, at, "<generic>", "PC/AT 486 (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) -COMP ( 1989, neat, ibm5170, 0, neat, 0, at_state, at, "<generic>", "NEAT (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) -COMP ( 1989, ec1842, ibm5150, 0, ec1842, 0, at_state, at, "<unknown>", "EC-1842", MACHINE_NOT_WORKING ) -COMP ( 1993, ec1849, ibm5170, 0, ec1842, 0, at_state, at, "<unknown>", "EC-1849", MACHINE_NOT_WORKING ) -COMP ( 1993, megapc, 0, 0, megapc, 0, megapc_state, megapc, "Amstrad plc", "MegaPC", MACHINE_NOT_WORKING ) -COMP ( 199?, megapcpl, megapc, 0, megapcpl, 0, megapc_state, megapcpl, "Amstrad plc", "MegaPC Plus", MACHINE_NOT_WORKING ) -COMP ( 199?, megapcpla, megapc, 0, megapcpla, 0, at_state, megapcpla,"Amstrad plc", "MegaPC Plus (WINBUS chipset)", MACHINE_NOT_WORKING ) -COMP ( 1989, pc2386, ibm5170, 0, at386l, 0, at_state, at, "Amstrad plc", "Amstrad PC2386", MACHINE_NOT_WORKING ) -COMP ( 1991, aprfte, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot FT//ex 486 (J3 Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1991, ftsserv, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot FTs (Scorpion)", MACHINE_NOT_WORKING ) -COMP ( 1992, aprpand, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot FTs (Panther Rev F 1.02.26)", MACHINE_NOT_WORKING ) -COMP ( 1990, aplanst, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot LANstation (Krypton Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1990, aplannb, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot LANstation (Novell Remote Boot)", MACHINE_NOT_WORKING ) -COMP ( 1992, aplscar, ibm5170, 0, at486l, 0, at_state, at, "Apricot", "Apricot LS Pro (Caracal Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1992, aplsbon, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot LS Pro (Bonsai Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1988, xb42663, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot Qi 300 (Rev D,E & F Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1988, qi600, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot Qi 600 (Neptune Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1990, qi900, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot Qi 900 (Scorpion Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1989, apvxft, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot VX FT server", MACHINE_NOT_WORKING ) -COMP ( 1991, apxenls3, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot XEN-LS (Venus IV Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1993, apxlsam, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot XEN-LS II (Samurai Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1987, apxeni, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot XEN-i 386 (Leopard Motherboard)" , MACHINE_NOT_WORKING ) -COMP ( 1989, xb42639, ibm5170, 0, xb42639, 0, at_state, at, "Apricot", "Apricot XEN-S (Venus I Motherboard 286)" , MACHINE_NOT_WORKING ) -COMP ( 1990, xb42639a, ibm5170, 0, xb42639, 0, at_state, at, "Apricot", "Apricot XEN-S (Venus II Motherboard 286)" , MACHINE_NOT_WORKING ) -COMP ( 1989, xb42664, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot XEN-S (Venus I Motherboard 386)" , MACHINE_NOT_WORKING ) -COMP ( 1990, xb42664a, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot XEN-S (Venus II Motherboard 386)" , MACHINE_NOT_WORKING ) -COMP ( 1993, apxena1, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot XEN PC (A1 Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1993, apxenp2, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot XEN PC (P2 Motherboard)", MACHINE_NOT_WORKING ) -COMP ( 1990, c386sx16, ibm5170, 0, at386sx, 0, at_state, at, "Commodore Business Machines", "Commodore 386SX-16", MACHINE_NOT_WORKING ) -COMP ( 1988, cmdpc30, ibm5170, 0, ibm5162, 0, at_state, at, "Commodore Business Machines", "PC 30 III", MACHINE_NOT_WORKING ) -COMP ( 1995, ficpio2, ibm5170, 0, ficpio2, 0, at_state, atpci, "FIC", "486-PIO-2", MACHINE_NOT_WORKING ) -COMP ( 1985, k286i, ibm5170, 0, k286i, 0, at_state, at, "Kaypro", "286i", MACHINE_NOT_WORKING ) -COMP ( 1991, t2000sx, ibm5170, 0, at386sx, 0, at_state, at, "Toshiba", "T2000SX", MACHINE_NOT_WORKING ) +// YEAR NAME PARENT COMPAT MACHINE INIT INPUT STATE COMPANY FULLNAME FLAGS +COMP ( 1984, ibm5170, 0, ibm5150, ibm5170, 0, at_state, at, "International Business Machines", "IBM PC/AT 5170", MACHINE_NOT_WORKING ) +COMP ( 1985, ibm5170a, ibm5170, 0, ibm5170a, 0, at_state, at, "International Business Machines", "IBM PC/AT 5170 8MHz", MACHINE_NOT_WORKING ) +COMP ( 1985, ibm5162, ibm5170, 0, ibm5162, 0, at_state, at, "International Business Machines", "IBM PC/XT-286 5162", MACHINE_NOT_WORKING ) +COMP ( 1989, ibmps1es, ibm5170, 0, ibmps1, 0, at_state, at, "International Business Machines", "IBM PS/1 (Spanish)", MACHINE_NOT_WORKING ) +COMP ( 1987, at, ibm5170, 0, ibm5162, 0, at_state, at, "<generic>", "PC/AT (CGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) +COMP ( 1987, atvga, ibm5170, 0, atvga, 0, at_state, at, "<generic>", "PC/AT (VGA, MF2 Keyboard)" , MACHINE_NOT_WORKING ) +COMP ( 1988, at386, ibm5170, 0, at386, 0, at_state, at, "<generic>", "PC/AT 386 (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) +COMP ( 1988, ct386sx, ibm5170, 0, ct386sx, 0, at_state, at, "<generic>", "NEAT 386SX (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) +COMP ( 1988, at386sx, ibm5170, 0, at386sx, 0, at_state, at, "<generic>", "PC/AT 386SX (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) +COMP ( 1990, at486, ibm5170, 0, at486, 0, at_state, at, "<generic>", "PC/AT 486 (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) +COMP ( 1989, neat, ibm5170, 0, neat, 0, at_state, at, "<generic>", "NEAT (VGA, MF2 Keyboard)", MACHINE_NOT_WORKING ) +COMP ( 1989, ec1842, ibm5150, 0, ec1842, 0, at_state, at, "<unknown>", "EC-1842", MACHINE_NOT_WORKING ) +COMP ( 1993, ec1849, ibm5170, 0, ec1842, 0, at_state, at, "<unknown>", "EC-1849", MACHINE_NOT_WORKING ) +COMP ( 1993, megapc, 0, 0, megapc, 0, megapc_state, megapc, "Amstrad plc", "MegaPC", MACHINE_NOT_WORKING ) +COMP ( 199?, megapcpl, megapc, 0, megapcpl, 0, megapc_state, megapcpl, "Amstrad plc", "MegaPC Plus", MACHINE_NOT_WORKING ) +COMP ( 199?, megapcpla, megapc, 0, megapcpla, 0, at_state, megapcpla,"Amstrad plc", "MegaPC Plus (WINBUS chipset)", MACHINE_NOT_WORKING ) +COMP ( 1989, pc2386, ibm5170, 0, at386l, 0, at_state, at, "Amstrad plc", "Amstrad PC2386", MACHINE_NOT_WORKING ) +COMP ( 1991, aprfte, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot FT//ex 486 (J3 Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1991, ftsserv, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot FTs (Scorpion)", MACHINE_NOT_WORKING ) +COMP ( 1992, aprpand, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot FTs (Panther Rev F 1.02.26)", MACHINE_NOT_WORKING ) +COMP ( 1990, aplanst, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot LANstation (Krypton Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1990, aplannb, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot LANstation (Novell Remote Boot)", MACHINE_NOT_WORKING ) +COMP ( 1992, aplscar, ibm5170, 0, at486l, 0, at_state, at, "Apricot", "Apricot LS Pro (Caracal Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1992, aplsbon, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot LS Pro (Bonsai Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1988, xb42663, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot Qi 300 (Rev D,E & F Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1988, qi600, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot Qi 600 (Neptune Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1990, qi900, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot Qi 900 (Scorpion Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1989, apvxft, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot VX FT server", MACHINE_NOT_WORKING ) +COMP ( 1991, apxenls3, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot XEN-LS (Venus IV Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1993, apxlsam, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot XEN-LS II (Samurai Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1987, apxeni, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot XEN-i 386 (Leopard Motherboard)" , MACHINE_NOT_WORKING ) +COMP ( 1989, xb42639, ibm5170, 0, xb42639, 0, at_state, at, "Apricot", "Apricot XEN-S (Venus I Motherboard 286)" , MACHINE_NOT_WORKING ) +COMP ( 1990, xb42639a, ibm5170, 0, xb42639, 0, at_state, at, "Apricot", "Apricot XEN-S (Venus II Motherboard 286)" , MACHINE_NOT_WORKING ) +COMP ( 1989, xb42664, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot XEN-S (Venus I Motherboard 386)" , MACHINE_NOT_WORKING ) +COMP ( 1990, xb42664a, ibm5170, 0, at386, 0, at_state, at, "Apricot", "Apricot XEN-S (Venus II Motherboard 386)" , MACHINE_NOT_WORKING ) +COMP ( 1993, apxena1, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot XEN PC (A1 Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1993, apxenp2, ibm5170, 0, at486, 0, at_state, at, "Apricot", "Apricot XEN PC (P2 Motherboard)", MACHINE_NOT_WORKING ) +COMP ( 1990, c386sx16, ibm5170, 0, at386sx, 0, at_state, at, "Commodore Business Machines", "Commodore 386SX-16", MACHINE_NOT_WORKING ) +COMP ( 1988, pc30iii, ibm5170, 0, pc30iii, 0, at_state, at, "Commodore Business Machines", "PC 30-III", MACHINE_NOT_WORKING ) +COMP ( 1988, pc40iii, ibm5170, 0, pc40iii, 0, at_state, at, "Commodore Business Machines", "PC 40-III", MACHINE_NOT_WORKING ) +COMP ( 1995, ficpio2, ibm5170, 0, ficpio2, 0, at_state, atpci, "FIC", "486-PIO-2", MACHINE_NOT_WORKING ) +COMP ( 1985, k286i, ibm5170, 0, k286i, 0, at_state, at, "Kaypro", "286i", MACHINE_NOT_WORKING ) +COMP ( 1991, t2000sx, ibm5170, 0, at386sx, 0, at_state, at, "Toshiba", "T2000SX", MACHINE_NOT_WORKING ) +COMP ( 199?, mbc28, ibm5170, 0, at386sx, 0, at_state, at, "Sanyo", "MBC-28", MACHINE_NOT_WORKING ) +COMP ( 1986, pcd2, ibm5170, 0, ibm5170, 0, at_state, at, "Siemens", "PCD-2", MACHINE_NOT_WORKING ) +COMP ( 1987, comportiii,ibm5170, 0, comportiii,0, at_state, at, "Compaq", "Portable III", MACHINE_NOT_WORKING ) + diff --git a/src/mame/drivers/atarist.cpp b/src/mame/drivers/atarist.cpp index 3d41bf3293c..d8ea63c8e22 100644 --- a/src/mame/drivers/atarist.cpp +++ b/src/mame/drivers/atarist.cpp @@ -1260,10 +1260,8 @@ static ADDRESS_MAP_START( st_map, AS_PROGRAM, 16, st_state ) AM_RANGE(0xff8a3c, 0xff8a3d) AM_READWRITE(blitter_ctrl_r, blitter_ctrl_w) #endif AM_RANGE(0xfffa00, 0xfffa3f) AM_DEVREADWRITE8(MC68901_TAG, mc68901_device, read, write, 0x00ff) - AM_RANGE(0xfffc00, 0xfffc01) AM_DEVREADWRITE8(MC6850_0_TAG, acia6850_device, status_r, control_w, 0xff00) - AM_RANGE(0xfffc02, 0xfffc03) AM_DEVREADWRITE8(MC6850_0_TAG, acia6850_device, data_r, data_w, 0xff00) - AM_RANGE(0xfffc04, 0xfffc05) AM_DEVREADWRITE8(MC6850_1_TAG, acia6850_device, status_r, control_w, 0xff00) - AM_RANGE(0xfffc06, 0xfffc07) AM_DEVREADWRITE8(MC6850_1_TAG, acia6850_device, data_r, data_w, 0xff00) + AM_RANGE(0xfffc00, 0xfffc03) AM_DEVREADWRITE8(MC6850_0_TAG, acia6850_device, read, write, 0xff00) + AM_RANGE(0xfffc04, 0xfffc07) AM_DEVREADWRITE8(MC6850_1_TAG, acia6850_device, read, write, 0xff00) ADDRESS_MAP_END @@ -1304,10 +1302,8 @@ static ADDRESS_MAP_START( megast_map, AS_PROGRAM, 16, megast_state ) AM_RANGE(0xff8a3c, 0xff8a3d) AM_READWRITE(blitter_ctrl_r, blitter_ctrl_w) AM_RANGE(0xfffa00, 0xfffa3f) AM_DEVREADWRITE8(MC68901_TAG, mc68901_device, read, write, 0x00ff) AM_RANGE(0xfffa40, 0xfffa57) AM_READWRITE(fpu_r, fpu_w) - AM_RANGE(0xfffc00, 0xfffc01) AM_DEVREADWRITE8(MC6850_0_TAG, acia6850_device, status_r, control_w, 0xff00) - AM_RANGE(0xfffc02, 0xfffc03) AM_DEVREADWRITE8(MC6850_0_TAG, acia6850_device, data_r, data_w, 0xff00) - AM_RANGE(0xfffc04, 0xfffc05) AM_DEVREADWRITE8(MC6850_1_TAG, acia6850_device, status_r, control_w, 0xff00) - AM_RANGE(0xfffc06, 0xfffc07) AM_DEVREADWRITE8(MC6850_1_TAG, acia6850_device, data_r, data_w, 0xff00) + AM_RANGE(0xfffc00, 0xfffc03) AM_DEVREADWRITE8(MC6850_0_TAG, acia6850_device, read, write, 0xff00) + AM_RANGE(0xfffc04, 0xfffc07) AM_DEVREADWRITE8(MC6850_1_TAG, acia6850_device, read, write, 0xff00) AM_RANGE(0xfffc20, 0xfffc3f) AM_DEVREADWRITE8(RP5C15_TAG, rp5c15_device, read, write, 0x00ff) ADDRESS_MAP_END diff --git a/src/mame/drivers/atarisy4.cpp b/src/mame/drivers/atarisy4.cpp index d9e9f9a3d6e..e574272d416 100644 --- a/src/mame/drivers/atarisy4.cpp +++ b/src/mame/drivers/atarisy4.cpp @@ -847,6 +847,7 @@ void atarisy4_state::load_ldafile(address_space &space, const uint8_t *file) uint8_t sum = 1; uint16_t len; uint16_t addr; + uint8_t pval = 0; if (READ_CHAR() != 0x01) fatalerror("Bad .LDA file\n"); @@ -879,7 +880,11 @@ void atarisy4_state::load_ldafile(address_space &space, const uint8_t *file) { uint8_t data = READ_CHAR(); sum += data; - space.write_byte(addr++, data); + if (addr & 1) + space.write_word(addr >> 1, (pval << 8) | data); + else + pval = data; + addr ++; } while (--len); sum += READ_CHAR(); diff --git a/src/mame/drivers/atpci.cpp b/src/mame/drivers/atpci.cpp index 64311f56053..c0090ef0b92 100644 --- a/src/mame/drivers/atpci.cpp +++ b/src/mame/drivers/atpci.cpp @@ -121,13 +121,31 @@ ROM_START( at586 ) ROMX_LOAD("asus_txp4.bin", 0x20000, 0x20000, CRC(a1321bb1) SHA1(92e5f14d8505119f85b148a63510617ac12bcdf3), ROM_BIOS(5)) ROM_END -ROM_START( at586x3 ) +ROM_START(at586x3) ROM_REGION32_LE(0x40000, "isa", 0) ROM_SYSTEM_BIOS(0, "5hx29", "5HX29") - ROMX_LOAD("5hx29.bin", 0x20000, 0x20000, CRC(07719a55) SHA1(b63993fd5186cdb4f28c117428a507cd069e1f68), ROM_BIOS(1)) + ROMX_LOAD("5hx29.bin", 0x20000, 0x20000, CRC(07719a55) SHA1(b63993fd5186cdb4f28c117428a507cd069e1f68), ROM_BIOS(1)) - ROM_SYSTEM_BIOS(1, "n7ns04", "Version 21/01/98, without integrated sound") // SMSC FDC37C93X I/O - ROMX_LOAD("m7ns04.rom", 0x00000, 0x40000, CRC(9c1f656b) SHA1(f4a0a522d8c47b6ddb6c01fe9a34ddf5b1977f8d), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS(1, "n7ns04", "Version 21/01/98, without integrated sound") // Micronics M7S-HI with SMSC FDC37C93X I/O + ROMX_LOAD("m7ns04.rom", 0x00000, 0x40000, CRC(9c1f656b) SHA1(f4a0a522d8c47b6ddb6c01fe9a34ddf5b1977f8d), ROM_BIOS(2)) + + ROM_SYSTEM_BIOS(2, "n7s04", "Version 21/01/98, with integrated sound") + ROMX_LOAD("m7s04.rom", 0x00000, 0x40000, CRC(3689f5a9) SHA1(8daacdb0dc6783d2161680564ffe83ac2515f7ef), ROM_BIOS(3)) + + ROM_SYSTEM_BIOS(3, "m55ns04", "m55ns04") // Micronics M55HI-Plus with no sound + ROMX_LOAD("M55-04ns.rom", 0x20000, 0x20000, CRC(0116B2B0) SHA1(19b0203decfd4396695334517488d488aec3ccde), ROM_BIOS(4)) + + ROM_SYSTEM_BIOS(4, "m55s04", "m55n04") // with sound + ROMX_LOAD("M55-04s.rom", 0x20000, 0x20000, CRC(34A7422E) SHA1(68753fe373c97844beff83ea75c634c77cfedb8f), ROM_BIOS(5)) + + ROM_SYSTEM_BIOS(5, "m55ns03", "m55ns03") // Micronics M55HI-Plus with no sound + ROMX_LOAD("M55NS03.ROM", 0x20000, 0x20000, CRC(6a3deb49) SHA1(78bfc20e0f8699f4d153d241a757153afcde3efb), ROM_BIOS(6)) + + ROM_SYSTEM_BIOS(6, "m55hi03", "m55hi03") // with sound + ROMX_LOAD("M55HI03.ROM", 0x20000, 0x20000, CRC(bd476200) SHA1(7633ba27819ad45c6253abb728b1ef0c49229743), ROM_BIOS(7)) + + ROM_SYSTEM_BIOS(7, "m7shi03", "m7shi03") // Micronics M7S-Hi + ROMX_LOAD("M7SHI03.SND", 0x00000, 0x40000, CRC(3a35a939) SHA1(74af69eb5ca546b0960540e7c3ea62a532157f2a), ROM_BIOS(8)) ROM_END /* FIC VT-503 (Intel TX chipset, ITE 8679 Super I/O) */ diff --git a/src/mame/drivers/att4425.cpp b/src/mame/drivers/att4425.cpp index c1221db576a..5e8ea2a9770 100644 --- a/src/mame/drivers/att4425.cpp +++ b/src/mame/drivers/att4425.cpp @@ -50,6 +50,11 @@ public: , m_screen(*this, SCREEN_TAG) { } + DECLARE_WRITE8_MEMBER(port10_w); + DECLARE_WRITE8_MEMBER(port14_w); + DECLARE_READ8_MEMBER(port14_r); + DECLARE_READ8_MEMBER(port15_r); + DECLARE_WRITE_LINE_MEMBER(write_line_clock); DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock); @@ -69,19 +74,42 @@ private: /* Memory Maps */ +WRITE8_MEMBER(att4425_state::port10_w) +{ + logerror("Writing %02X to port 10\n", data); +} + +WRITE8_MEMBER(att4425_state::port14_w) +{ + logerror("Writing %02X to port 14\n", data); +} + +READ8_MEMBER(att4425_state::port14_r) +{ + // only complement of bit 0 used? + return 0; +} + +READ8_MEMBER(att4425_state::port15_r) +{ + // status of something (at least bits 2 and 3 used) + return 0; +} + static ADDRESS_MAP_START( att4425_mem, AS_PROGRAM, 8, att4425_state ) AM_RANGE(0x0000, 0x7fff) AM_ROM AM_REGION(Z80_TAG, 0) AM_RANGE(0x8000, 0xffff) AM_RAM AM_SHARE("videoram") // c000..f7af? ADDRESS_MAP_END static ADDRESS_MAP_START( att4425_io, AS_IO, 8, att4425_state ) - AM_RANGE(0x0000, 0x0000) AM_MIRROR(0xff00) AM_DEVREADWRITE(I8251_TAG, i8251_device, data_r, data_w) - AM_RANGE(0x0001, 0x0001) AM_MIRROR(0xff00) AM_DEVREADWRITE(I8251_TAG, i8251_device, status_r, control_w) - AM_RANGE(0x0008, 0x0008) AM_MIRROR(0xff00) AM_UNMAP // write 08 - AM_RANGE(0x0010, 0x0010) AM_MIRROR(0xff00) AM_UNMAP // write 10 - AM_RANGE(0x0014, 0x0015) AM_MIRROR(0xff00) AM_UNMAP // NVRAM? read 14, 15; write 14 - AM_RANGE(0x0018, 0x001b) AM_MIRROR(0xff00) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_device, read, write) - AM_RANGE(0x001c, 0x001f) AM_MIRROR(0xff00) AM_DEVREADWRITE(Z80SIO_TAG, z80sio_device, ba_cd_r, ba_cd_w) + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x00, 0x00) AM_DEVREADWRITE(I8251_TAG, i8251_device, data_r, data_w) + AM_RANGE(0x01, 0x01) AM_DEVREADWRITE(I8251_TAG, i8251_device, status_r, control_w) + AM_RANGE(0x10, 0x10) AM_WRITE(port10_w) + AM_RANGE(0x14, 0x14) AM_READWRITE(port14_r, port14_w) + AM_RANGE(0x15, 0x15) AM_READ(port15_r) + AM_RANGE(0x18, 0x1b) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_device, read, write) + AM_RANGE(0x1c, 0x1f) AM_DEVREADWRITE(Z80SIO_TAG, z80sio_device, ba_cd_r, ba_cd_w) ADDRESS_MAP_END /* Input Ports */ diff --git a/src/mame/drivers/att630.cpp b/src/mame/drivers/att630.cpp new file mode 100644 index 00000000000..c0ade7cae8e --- /dev/null +++ b/src/mame/drivers/att630.cpp @@ -0,0 +1,65 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +Skeleton driver for AT&T 630 MTG terminal. + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/m68000/m68000.h" +#include "machine/mc68681.h" + + +class att630_state : public driver_device +{ +public: + att630_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { } + +private: + required_device<cpu_device> m_maincpu; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 16, att630_state ) + AM_RANGE(0x000000, 0x03ffff) AM_ROM AM_REGION("maincpu", 0) + AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE8("duart1", scn2681_device, read, write, 0x00ff) + AM_RANGE(0x200020, 0x20003f) AM_DEVREADWRITE8("duart2", scn2681_device, read, write, 0x00ff) + AM_RANGE(0x760000, 0x77ffff) AM_RAM + AM_RANGE(0x780000, 0x7bffff) AM_RAM + AM_RANGE(0x7c0000, 0x7fffff) AM_RAM + AM_RANGE(0xe00000, 0xe03fff) AM_NOP // 0x00ff mask +ADDRESS_MAP_END + +static INPUT_PORTS_START( att630 ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( att630 ) + MCFG_CPU_ADD("maincpu", M68000, XTAL_40MHz / 4) // clock not confirmed + MCFG_CPU_PROGRAM_MAP(mem_map) + + MCFG_DEVICE_ADD("duart1", SCN2681, XTAL_3_6864MHz) + + MCFG_DEVICE_ADD("duart2", SCN2681, XTAL_3_6864MHz) +MACHINE_CONFIG_END + + +/************************************************************************************************************** + +AT&T 630 MTG. +Chips: 2x SCN2681A, AT&T 492F proprietory, blank chip, MC68000P10, MB113F316 (square), MB113F316 (DIL), PAL16R4ACN +Crystals: 40MHz, 87.18336, 3.6864? (hard to read) + +***************************************************************************************************************/ + +ROM_START( att630 ) + ROM_REGION(0x40000, "maincpu", 0) + ROM_LOAD16_BYTE( "460621-1.bin", 0x00000, 0x10000, CRC(136749cd) SHA1(15378c292ddc7384cc69a35de55b69257a9f2a1c) ) + ROM_LOAD16_BYTE( "460620-1.bin", 0x00001, 0x10000, CRC(27ab77f0) SHA1(5ff1d9ee5a69dee308d62c447ee67e1888afab0e) ) + ROM_LOAD16_BYTE( "460623-1.bin", 0x20000, 0x10000, CRC(aeae12fb) SHA1(fa3ce26e4622875aa1dea7cf1bd1df237010ff2b) ) + ROM_LOAD16_BYTE( "460622-1.bin", 0x20001, 0x10000, CRC(c108c1e0) SHA1(ef01349e890b8a4117c01e78d1c23fbd113ba58f) ) +ROM_END + +COMP( 1987, att630, 0, 0, att630, att630, att630_state, 0, "AT&T", "630 MTG", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/attache.cpp b/src/mame/drivers/attache.cpp index 09128f14682..ca68ba5c3ec 100644 --- a/src/mame/drivers/attache.cpp +++ b/src/mame/drivers/attache.cpp @@ -43,11 +43,24 @@ * nnnnY - I/O port receive (nnnn = address of data loaded) * Z - Auto Disk Test (1Z for drive B) * + * For the 8086 board (will display an 'x' if the 8086 board is not installed): + * [ - 8086 RAM Test + * ] - SCC Test + * ( - GPIB Listener/Talker Test + * ) - GPIB Controller Test + * + * The Attache 8:16 is an upgraded Attache adding an 8086 (+ optional 8087) board with its own 256kB of RAM, + * and optionally a GPIB controller (TMS9914A) and serial synchronous port (Z8530 SCC). It also has modifications + * to the main Z80 board, specifically the display circuitry, adding a high-resolution display, and replacing + * the character ROM with a larger ROM containing an IBM character set. + * It effectively allows the Attache to run MS-DOS and use a 10MB hard disk. * * TODO: * - Keyboard repeat * - Get at least some of the system tests to pass * - and probably lots more I've forgotten, too. + * - improve Z80-8086 comms on the 8:16, saving a file to the RAM disk under CP/M often ends in deadlock. + * - add Z8530 SCC and TMS9914A GPIB to the 8:16. These are optional devices, so aren't strictly required at this stage. * */ @@ -61,11 +74,12 @@ #include "machine/ram.h" #include "machine/upd765.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80pio.h" +#include "machine/i8255.h" +#include "cpu/i86/i86.h" #include "sound/ay8910.h" #include "video/tms9927.h" - #include "screen.h" #include "softlist.h" #include "speaker.h" @@ -172,7 +186,7 @@ private: required_device<msm5832_device> m_rtc; required_device<ay8912_device> m_psg; required_device<upd765a_device> m_fdc; - required_device<z80sio0_device> m_sio; + required_device<z80sio_device> m_sio; required_device<z80pio_device> m_pio; required_device<z80ctc_device> m_ctc; required_device<tms9927_device> m_crtc; @@ -215,6 +229,42 @@ private: uint8_t m_memmap; }; +class attache816_state : public attache_state +{ +public: + attache816_state(const machine_config &mconfig, device_type type, const char *tag) + : attache_state(mconfig, type, tag), + m_extcpu(*this,"extcpu"), + m_ppi(*this,"ppi"), + m_comms_val(0), + m_x86_irq_enable(0), + m_z80_rx_ready(false), + m_z80_tx_ready(false) + { } + + DECLARE_WRITE8_MEMBER(x86_comms_w); + DECLARE_READ8_MEMBER(x86_comms_r); + DECLARE_WRITE8_MEMBER(x86_irq_enable); + DECLARE_WRITE8_MEMBER(x86_iobf_enable_w); + DECLARE_READ8_MEMBER(z80_comms_r); + DECLARE_WRITE8_MEMBER(z80_comms_w); + DECLARE_READ8_MEMBER(z80_comms_status_r); + DECLARE_WRITE8_MEMBER(z80_comms_ctrl_w); + DECLARE_WRITE_LINE_MEMBER(ppi_irq); + DECLARE_WRITE_LINE_MEMBER(x86_dsr); + + virtual void machine_reset() override; + +private: + required_device<cpu_device> m_extcpu; + required_device<i8255_device> m_ppi; + + uint8_t m_comms_val; + uint8_t m_x86_irq_enable; + bool m_z80_rx_ready; + bool m_z80_tx_ready; +}; + // Attributes (based on schematics): // bit 0 = ALT // bit 1 = RW @@ -285,7 +335,7 @@ uint32_t attache_state::screen_update(screen_device &screen, bitmap_rgb32 &bitma for(scan=0;scan<10;scan++) // 10 scanlines per line { - data = m_char_rom->base()[ch*16+scan]; + data = m_char_rom->base()[(ch*16+scan)]; if((m_attr_ram[(vy*128)+x] & 0xc0) != 0xc0) // if not strikethrough { if(m_attr_ram[(vy*128)+x] & 0x40) // superscript @@ -743,7 +793,112 @@ WRITE_LINE_MEMBER( attache_state::fdc_dack_w ) { } -static ADDRESS_MAP_START( attache_map , AS_PROGRAM, 8, attache_state) +/* + * Z80 <-> 8086 communication + */ + +WRITE8_MEMBER(attache816_state::x86_comms_w) +{ + m_comms_val = data; + m_z80_rx_ready = false; + machine().scheduler().synchronize(); + logerror("x86 writes %02x to comms\n",data); +} + +READ8_MEMBER(attache816_state::x86_comms_r) +{ + m_z80_tx_ready = false; + logerror("x86 reads %02x from comms\n",m_comms_val); + machine().scheduler().synchronize(); + return m_comms_val; +} + +// PPI Port B - IRQ enable +// bit 0: i8255A PPI +// bit 1: TMS9914A GPIB +// bit 2: Z8530 SCC +// bit 3: 8087 FPU +// bit 4: enable WAIT logic +// bit 5: enable high-resolution graphics +WRITE8_MEMBER(attache816_state::x86_irq_enable) +{ + m_x86_irq_enable = data; +} + +WRITE8_MEMBER(attache816_state::x86_iobf_enable_w) +{ + switch(offset) + { + case 0x00: + m_ppi->pc6_w(0); + break; + case 0x01: + m_ppi->pc6_w(1); + break; + case 0x04: + m_ppi->pc4_w(0); + break; + case 0x05: + m_ppi->pc4_w(1); + break; + default: + logerror("Invalid x86 IRQ enable write offset %02x data %02x\n",offset,data); + } +} + +READ8_MEMBER(attache816_state::z80_comms_r) +{ + m_z80_rx_ready = true; + m_ppi->pc6_w(0); + logerror("z80 reads %02x from comms\n",m_comms_val); + machine().scheduler().synchronize(); + return m_comms_val; +} + +WRITE8_MEMBER(attache816_state::z80_comms_w) +{ + m_comms_val = data; + logerror("z80 writes %02x to comms\n",data); + m_z80_tx_ready = true; + m_ppi->pc4_w(0); + machine().scheduler().synchronize(); +// m_ppi->write(space,0,data); +} + +// Z80 comms status +// bit 0: set if no data is ready +// bit 1: set if ready to accept data +READ8_MEMBER(attache816_state::z80_comms_status_r) +{ + uint8_t ret = 0xf0; // low nibble always high? + + if(m_z80_rx_ready) + ret |= 0x01; + if(m_z80_tx_ready) + ret |= 0x02; + + return ret; +} + +// Z80 comms controller +// bit 0: Reset 8086 +WRITE8_MEMBER(attache816_state::z80_comms_ctrl_w) +{ + m_extcpu->set_input_line(INPUT_LINE_RESET,(data & 0x01) ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER(attache816_state::ppi_irq) +{ + if(m_x86_irq_enable & 0x01) + m_extcpu->set_input_line_and_vector(0,state,0x03); +} + +WRITE_LINE_MEMBER(attache816_state::x86_dsr) +{ + // TODO: /DSR to Z8530 SCC +} + +static ADDRESS_MAP_START( attache_map, AS_PROGRAM, 8, attache_state) AM_RANGE(0x0000,0x1fff) AM_RAMBANK("bank1") AM_RANGE(0x2000,0x3fff) AM_RAMBANK("bank2") AM_RANGE(0x4000,0x5fff) AM_RAMBANK("bank3") @@ -754,11 +909,11 @@ static ADDRESS_MAP_START( attache_map , AS_PROGRAM, 8, attache_state) AM_RANGE(0xe000,0xffff) AM_RAMBANK("bank8") ADDRESS_MAP_END -static ADDRESS_MAP_START( attache_io , AS_IO, 8, attache_state) +static ADDRESS_MAP_START( attache_io, AS_IO, 8, attache_state) AM_RANGE(0xe0, 0xed) AM_DEVREADWRITE("dma",am9517a_device,read,write) AM_MIRROR(0xff00) AM_RANGE(0xee, 0xee) AM_WRITE(display_command_w) AM_MIRROR(0xff00) AM_RANGE(0xef, 0xef) AM_READWRITE(dma_mask_r, dma_mask_w) AM_MIRROR(0xff00) - AM_RANGE(0xe6, 0xe7) AM_DEVREADWRITE("sio",z80sio0_device,ba_cd_r, ba_cd_w) AM_MIRROR(0xff00) + AM_RANGE(0xe6, 0xe7) AM_DEVREADWRITE("sio",z80sio_device,ba_cd_r, ba_cd_w) AM_MIRROR(0xff00) AM_RANGE(0xf4, 0xf7) AM_DEVREADWRITE("ctc",z80ctc_device,read,write) AM_MIRROR(0xff00) AM_RANGE(0xf8, 0xfb) AM_DEVREADWRITE("pio",z80pio_device,read_alt,write_alt) AM_MIRROR(0xff00) AM_RANGE(0xfc, 0xfd) AM_DEVICE("fdc",upd765a_device,map) AM_MIRROR(0xff00) @@ -766,6 +921,33 @@ static ADDRESS_MAP_START( attache_io , AS_IO, 8, attache_state) AM_RANGE(0xff, 0xff) AM_READWRITE(memmap_r, memmap_w) AM_MIRROR(0xff00) ADDRESS_MAP_END +static ADDRESS_MAP_START( attache816_io, AS_IO, 8, attache816_state) + AM_RANGE(0xb8, 0xb8) AM_READWRITE(z80_comms_status_r, z80_comms_ctrl_w) AM_MIRROR(0xff00) + AM_RANGE(0xb9, 0xb9) AM_READWRITE(z80_comms_r, z80_comms_w) AM_MIRROR(0xff00) + AM_RANGE(0xe0, 0xed) AM_DEVREADWRITE("dma",am9517a_device,read,write) AM_MIRROR(0xff00) + AM_RANGE(0xee, 0xee) AM_WRITE(display_command_w) AM_MIRROR(0xff00) + AM_RANGE(0xef, 0xef) AM_READWRITE(dma_mask_r, dma_mask_w) AM_MIRROR(0xff00) + AM_RANGE(0xe6, 0xe7) AM_DEVREADWRITE("sio",z80sio_device,ba_cd_r, ba_cd_w) AM_MIRROR(0xff00) + AM_RANGE(0xf4, 0xf7) AM_DEVREADWRITE("ctc",z80ctc_device,read,write) AM_MIRROR(0xff00) + AM_RANGE(0xf8, 0xfb) AM_DEVREADWRITE("pio",z80pio_device,read_alt,write_alt) AM_MIRROR(0xff00) + AM_RANGE(0xfc, 0xfd) AM_DEVICE("fdc",upd765a_device,map) AM_MIRROR(0xff00) + AM_RANGE(0xfe, 0xfe) AM_READWRITE(display_data_r, display_data_w) AM_SELECT(0xff00) + AM_RANGE(0xff, 0xff) AM_READWRITE(memmap_r, memmap_w) AM_MIRROR(0xff00) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( attache_x86_map, AS_PROGRAM, 16, attache816_state) + AM_RANGE(0x00000, 0x3ffff) AM_RAM + AM_RANGE(0xb0000, 0xbffff) AM_NOP // triggers IRQ? + AM_RANGE(0xfe000, 0xfffff) AM_ROM AM_REGION("x86bios",0x0000) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( attache_x86_io, AS_IO, 16, attache816_state) + AM_RANGE(0x100, 0x107) AM_DEVREADWRITE8("ppi",i8255_device,read,write,0x00ff) + AM_RANGE(0x108, 0x10d) AM_WRITE8(x86_iobf_enable_w,0xffff); +// 0x140/2/4/6 - Z8530 SCC serial +// 0x180/2/4/6/8/a/c/e - GPIB (TMS9914A) +ADDRESS_MAP_END + static INPUT_PORTS_START(attache) PORT_START("row0") PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) @@ -912,6 +1094,11 @@ void attache_state::machine_reset() m_kb_bitpos = 0; } +void attache816_state::machine_reset() +{ + attache_state::machine_reset(); +} + static MACHINE_CONFIG_START( attache ) MCFG_CPU_ADD("maincpu",Z80,XTAL_8MHz / 2) MCFG_CPU_PROGRAM_MAP(attache_map) @@ -942,7 +1129,7 @@ static MACHINE_CONFIG_START( attache ) MCFG_Z80PIO_IN_PB_CB(READ8(attache_state, pio_portB_r)) MCFG_Z80PIO_OUT_PB_CB(WRITE8(attache_state, pio_portB_w)) - MCFG_DEVICE_ADD("sio", Z80SIO0, XTAL_8MHz / 26) + MCFG_DEVICE_ADD("sio", Z80SIO, XTAL_8MHz / 26) MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_8MHz / 4) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) @@ -973,15 +1160,89 @@ static MACHINE_CONFIG_START( attache ) MCFG_SOFTWARE_LIST_ADD("disk_list","attache") MACHINE_CONFIG_END +static MACHINE_CONFIG_START( attache816 ) + MCFG_CPU_ADD("maincpu",Z80,XTAL_8MHz / 2) + MCFG_CPU_PROGRAM_MAP(attache_map) + MCFG_CPU_IO_MAP(attache816_io) + MCFG_Z80_DAISY_CHAIN(attache_daisy_chain) + + MCFG_QUANTUM_TIME(attotime::from_hz(60)) + + MCFG_CPU_ADD("extcpu",I8086,XTAL_24MHz / 3) + MCFG_CPU_PROGRAM_MAP(attache_x86_map) + MCFG_CPU_IO_MAP(attache_x86_io) + + MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(64)) /* not accurate */ + MCFG_SCREEN_SIZE(640,240) + MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 240-1) + MCFG_SCREEN_UPDATE_DRIVER(attache_state, screen_update) + MCFG_SCREEN_VBLANK_CALLBACK(DEVWRITELINE("ctc", z80ctc_device, trg2)) + + MCFG_PALETTE_ADD_MONOCHROME_HIGHLIGHT("palette") + + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("psg", AY8912, XTAL_8MHz / 4) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) + + MCFG_MSM5832_ADD("rtc",XTAL_32_768kHz) + + MCFG_DEVICE_ADD("pio", Z80PIO, XTAL_8MHz/26) + MCFG_Z80PIO_IN_PA_CB(READ8(attache_state, pio_portA_r)) + MCFG_Z80PIO_OUT_PA_CB(WRITE8(attache_state, pio_portA_w)) + MCFG_Z80PIO_IN_PB_CB(READ8(attache_state, pio_portB_r)) + MCFG_Z80PIO_OUT_PB_CB(WRITE8(attache_state, pio_portB_w)) + + MCFG_DEVICE_ADD("sio", Z80SIO, XTAL_8MHz / 26) + + MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_8MHz / 4) + MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + + MCFG_DEVICE_ADD("ppi", I8255A, 0) + MCFG_I8255_OUT_PORTA_CB(WRITE8(attache816_state, x86_comms_w)) + MCFG_I8255_IN_PORTA_CB(READ8(attache816_state, x86_comms_r)) + MCFG_I8255_OUT_PORTB_CB(WRITE8(attache816_state, x86_irq_enable)) + MCFG_I8255_OUT_PORTC_CB(WRITELINE(attache816_state, x86_dsr)) MCFG_DEVCB_BIT(0) + MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE(attache816_state, ppi_irq)) MCFG_DEVCB_BIT(7) MCFG_DEVCB_INVERT + + MCFG_DEVICE_ADD("dma", AM9517A, XTAL_8MHz / 4) + MCFG_AM9517A_OUT_HREQ_CB(WRITELINE(attache_state, hreq_w)) + MCFG_AM9517A_OUT_EOP_CB(WRITELINE(attache_state, eop_w)) + MCFG_AM9517A_IN_MEMR_CB(READ8(attache_state, dma_mem_r)) + MCFG_AM9517A_OUT_MEMW_CB(WRITE8(attache_state, dma_mem_w)) + MCFG_AM9517A_IN_IOR_0_CB(READ8(attache_state, fdc_dma_r)) + MCFG_AM9517A_OUT_IOW_0_CB(WRITE8(attache_state, fdc_dma_w)) + // MCFG_AM9517A_OUT_DACK_0_CB(WRITELINE(attache_state, fdc_dack_w)) + + MCFG_UPD765A_ADD("fdc", true, true) + MCFG_UPD765_INTRQ_CALLBACK(DEVWRITELINE("ctc", z80ctc_device, trg3)) + MCFG_UPD765_DRQ_CALLBACK(DEVWRITELINE("dma", am9517a_device, dreq0_w)) MCFG_DEVCB_INVERT + MCFG_FLOPPY_DRIVE_ADD("fdc:0", attache_floppies, "525dd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD("fdc:1", attache_floppies, "525dd", floppy_image_device::default_floppy_formats) + + MCFG_DEVICE_ADD("crtc", TMS9927, 12324000) + MCFG_TMS9927_CHAR_WIDTH(8) + + MCFG_NVRAM_ADD_0FILL("nvram") + + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("64k") + + MCFG_SOFTWARE_LIST_ADD("disk_list","attache") +MACHINE_CONFIG_END + ROM_START( attache ) ROM_REGION(0x10000, "maincpu", 0) ROM_FILL(0x0000,0x10000,0x00) ROM_REGION(0x1000, "boot", 0) - ROM_SYSTEM_BIOS(0, "u252revg", "Boot Rev.G") - ROMX_LOAD("u252revg.bin", 0x0000, 0x1000, CRC(113136b7) SHA1(845afd9ed2fd2b28c39921d8f2ba99e5295e0330), ROM_BIOS(1)) - ROM_SYSTEM_BIOS(1, "u252revf", "Boot Rev.F") - ROMX_LOAD("u252revf.bin", 0x0000, 0x1000, CRC(b49eb3b2) SHA1(5b1b348301b2f76b1f250ba68bb8733fc15d18c2), ROM_BIOS(2)) + ROM_SYSTEM_BIOS(0, "u252revh", "Boot Rev.H") + ROMX_LOAD("u252revh.bin", 0x0000, 0x1000, CRC(a06f0bdf) SHA1(d526cf23bfe0f8f9bcde812cd864a2a4cbc8b673), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(1, "u252revg", "Boot Rev.G") + ROMX_LOAD("u252revg.bin", 0x0000, 0x1000, CRC(113136b7) SHA1(845afd9ed2fd2b28c39921d8f2ba99e5295e0330), ROM_BIOS(2)) + ROM_SYSTEM_BIOS(2, "u252revf", "Boot Rev.F") + ROMX_LOAD("u252revf.bin", 0x0000, 0x1000, CRC(b49eb3b2) SHA1(5b1b348301b2f76b1f250ba68bb8733fc15d18c2), ROM_BIOS(3)) ROM_REGION(0x1000, "video", 0) ROM_LOAD("u416vid.bin", 0x0000, 0x1000, CRC(e376ec59) SHA1(7b9e9db575e77ce2f479eb9ae913528e4f0d125d) ) @@ -994,7 +1255,40 @@ ROM_START( attache ) ROM_REGION(0x100, "floppy", 0) ROM_LOAD("u630.bin", 0x0000, 0x0100, CRC(f7a5c821) SHA1(fea07d9ac7e4e5f4f72aa7b2159deaedbd662ead) ) + +ROM_END + +ROM_START( attache816 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_FILL(0x0000,0x10000,0x00) + + ROM_REGION(0x1000, "boot", 0) + ROM_SYSTEM_BIOS(0, "u252revh", "Boot Rev.H") + ROMX_LOAD("u252revh.bin", 0x0000, 0x1000, CRC(a06f0bdf) SHA1(d526cf23bfe0f8f9bcde812cd864a2a4cbc8b673), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(1, "u252revg", "Boot Rev.G") + ROMX_LOAD("u252revg.bin", 0x0000, 0x1000, CRC(113136b7) SHA1(845afd9ed2fd2b28c39921d8f2ba99e5295e0330), ROM_BIOS(2)) + ROM_SYSTEM_BIOS(2, "u252revf", "Boot Rev.F") + ROMX_LOAD("u252revf.bin", 0x0000, 0x1000, CRC(b49eb3b2) SHA1(5b1b348301b2f76b1f250ba68bb8733fc15d18c2), ROM_BIOS(3)) + + ROM_REGION(0x2000, "video", 0) + ROM_LOAD("u416vid2.bin", 0x0000, 0x2000, CRC(0bdaed8d) SHA1(eee1e8505906e7c3587ecdf9dd9227a2a3b3cdd4) ) + + ROM_REGION(0x100, "attr", 0) + ROM_LOAD("u413.bin", 0x0000, 0x0100, CRC(5b60e622) SHA1(43450c747db1394466eabe5c26a61bf75a4f3b52) ) + + ROM_REGION(0x200, "iosel", 0) + ROM_LOAD("u110.bin", 0x0000, 0x0200, CRC(70dd255a) SHA1(36dcce07a2c14eefc069433459c422341bd47efb) ) + + ROM_REGION(0x100, "floppy", 0) + ROM_LOAD("u630.bin", 0x0000, 0x0100, CRC(f7a5c821) SHA1(fea07d9ac7e4e5f4f72aa7b2159deaedbd662ead) ) + + // chip locations based on schematics + ROM_REGION(0x2000, "x86bios", 0) + ROM_LOAD16_BYTE("u4.bin", 0x0000, 0x1000, CRC(658c8f93) SHA1(ce4b388af5b73884194f548afa706964305462f7) ) + ROM_LOAD16_BYTE("u9.bin", 0x0001, 0x1000, CRC(cc4cd938) SHA1(6a1d316628641f9b4de5c8c46f9430ef5bd6120f) ) + ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT DEVICE INIT COMPANY FULLNAME FLAGS COMP( 1982, attache, 0, 0, attache, attache, attache_state, 0, "Otrona", "Attach\xC3\xA9", MACHINE_IMPERFECT_GRAPHICS ) +COMP( 1983, attache816, attache,0, attache816, attache, attache816_state, 0, "Otrona", "Attach\xC3\xA9 8:16", MACHINE_IMPERFECT_GRAPHICS ) diff --git a/src/mame/drivers/aussiebyte.cpp b/src/mame/drivers/aussiebyte.cpp index 15836bae959..fdf46923f6e 100644 --- a/src/mame/drivers/aussiebyte.cpp +++ b/src/mame/drivers/aussiebyte.cpp @@ -53,7 +53,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( aussiebyte_io, AS_IO, 8, aussiebyte_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("sio1", z80sio0_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("sio1", z80sio_device, ba_cd_r, ba_cd_w) AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("pio1", z80pio_device, read, write) AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) AM_RANGE(0x0c, 0x0f) AM_NOP // winchester interface @@ -68,7 +68,7 @@ static ADDRESS_MAP_START( aussiebyte_io, AS_IO, 8, aussiebyte_state ) AM_RANGE(0x1b, 0x1b) AM_WRITE(port1b_w) // winchester control AM_RANGE(0x1c, 0x1f) AM_WRITE(port1c_w) // gpebh select AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("pio2", z80pio_device, read, write) - AM_RANGE(0x24, 0x27) AM_DEVREADWRITE("sio2", z80sio0_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x24, 0x27) AM_DEVREADWRITE("sio2", z80sio_device, ba_cd_r, ba_cd_w) AM_RANGE(0x28, 0x28) AM_READ(port28_r) AM_DEVWRITE("votrax", votrax_sc01_device, write) AM_RANGE(0x2c, 0x2c) AM_DEVWRITE("votrax", votrax_sc01_device, inflection_w) AM_RANGE(0x30, 0x30) AM_WRITE(address_w) @@ -368,29 +368,8 @@ static const z80_daisy_config daisy_chain_intf[] = ************************************************************/ // baud rate generator. All inputs are 1.2288MHz. -WRITE_LINE_MEMBER( aussiebyte_state::clock_w ) -{ - m_ctc->trg0(state); - m_ctc->trg1(state); - m_ctc->trg2(state); -} - -WRITE_LINE_MEMBER( aussiebyte_state::ctc_z0_w ) -{ - m_sio1->rxca_w(state); - m_sio1->txca_w(state); -} - -WRITE_LINE_MEMBER( aussiebyte_state::ctc_z1_w ) -{ - m_sio1->rxtxcb_w(state); - m_sio2->rxca_w(state); - m_sio2->txca_w(state); -} - WRITE_LINE_MEMBER( aussiebyte_state::ctc_z2_w ) { - m_sio2->rxtxcb_w(state); m_ctc->trg3(1); m_ctc->trg3(0); } @@ -496,13 +475,19 @@ static MACHINE_CONFIG_START( aussiebyte ) MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics") MCFG_DEVICE_ADD("ctc_clock", CLOCK, XTAL_4_9152MHz / 4) - MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(aussiebyte_state, clock_w)) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc", z80ctc_device, trg0)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc", z80ctc_device, trg1)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc", z80ctc_device, trg2)) MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_16MHz / 4) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_Z80CTC_ZC0_CB(WRITELINE(aussiebyte_state, ctc_z0_w)) // SIO1 Ch A - MCFG_Z80CTC_ZC1_CB(WRITELINE(aussiebyte_state, ctc_z1_w)) // SIO1 Ch B, SIO2 Ch A + MCFG_Z80CTC_ZC0_CB(DEVWRITELINE("sio1", z80sio_device, rxca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio1", z80sio_device, txca_w)) + MCFG_Z80CTC_ZC1_CB(DEVWRITELINE("sio1", z80sio_device, rxtxcb_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio2", z80sio_device, rxca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio2", z80sio_device, txca_w)) MCFG_Z80CTC_ZC2_CB(WRITELINE(aussiebyte_state, ctc_z2_w)) // SIO2 Ch B, CTC Ch 3 + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio2", z80sio_device, rxtxcb_w)) MCFG_DEVICE_ADD("dma", Z80DMA, XTAL_16MHz / 4) MCFG_Z80DMA_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) @@ -523,21 +508,21 @@ static MACHINE_CONFIG_START( aussiebyte ) MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_Z80PIO_OUT_PA_CB(WRITE8(aussiebyte_state, port20_w)) - MCFG_DEVICE_ADD("sio1", Z80SIO0, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_Z80DART_OUT_WRDYA_CB(WRITELINE(aussiebyte_state, sio1_rdya_w)) - MCFG_Z80DART_OUT_WRDYB_CB(WRITELINE(aussiebyte_state, sio1_rdyb_w)) + MCFG_DEVICE_ADD("sio1", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80SIO_OUT_WRDYA_CB(WRITELINE(aussiebyte_state, sio1_rdya_w)) + MCFG_Z80SIO_OUT_WRDYB_CB(WRITELINE(aussiebyte_state, sio1_rdyb_w)) - MCFG_DEVICE_ADD("sio2", Z80SIO0, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_Z80DART_OUT_WRDYA_CB(WRITELINE(aussiebyte_state, sio2_rdya_w)) - MCFG_Z80DART_OUT_WRDYB_CB(WRITELINE(aussiebyte_state, sio2_rdyb_w)) - MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) - MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) - MCFG_Z80DART_OUT_RTSA_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_DEVICE_ADD("sio2", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80SIO_OUT_WRDYA_CB(WRITELINE(aussiebyte_state, sio2_rdya_w)) + MCFG_Z80SIO_OUT_WRDYB_CB(WRITELINE(aussiebyte_state, sio2_rdyb_w)) + MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRA_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSA_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "keyboard") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio2", z80sio0_device, rxa_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio2", z80sio_device, rxa_w)) MCFG_WD2797_ADD("fdc", XTAL_16MHz / 16) MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(aussiebyte_state, fdc_intrq_w)) diff --git a/src/mame/drivers/avigo.cpp b/src/mame/drivers/avigo.cpp index 8647b452712..9b486dc2ce3 100644 --- a/src/mame/drivers/avigo.cpp +++ b/src/mame/drivers/avigo.cpp @@ -802,13 +802,13 @@ static MACHINE_CONFIG_START( avigo ) MCFG_DEVICE_ADD("bank0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(avigo_banked_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("bank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(avigo_banked_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_NVRAM_ADD_CUSTOM_DRIVER("nvram", avigo_state, nvram_init) diff --git a/src/mame/drivers/balsente.cpp b/src/mame/drivers/balsente.cpp index 97b0dc57676..3ac9c893e11 100644 --- a/src/mame/drivers/balsente.cpp +++ b/src/mame/drivers/balsente.cpp @@ -1800,6 +1800,39 @@ ROM_START( gimeabrk ) MOTHERBOARD_PALS ROM_END +ROM_START( grudge ) + ROM_REGION( 0x40000, "maincpu", 0 ) /* 64k for code for the first CPU, plus 128k of banked ROMs */ + ROM_LOAD( "gm-3a.bin", 0x10000, 0x8000, CRC(eabeec2b) SHA1(92098512e3dbcda36f42e10fada01323fab4b08a) ) + ROM_LOAD( "gm-4a.bin", 0x18000, 0x8000, CRC(72664f18) SHA1(98202d7a775792d2d1c44a26540ac35afaffa6b2) ) + ROM_LOAD( "gm-1a.bin", 0x20000, 0x8000, CRC(ad168726) SHA1(c4d084e3752d6c4365d2460ca3146b148dcccc1d) ) + ROM_LOAD( "gm-2a.bin", 0x28000, 0x8000, CRC(1de8dd2e) SHA1(6b538dcf35105bca1ae1bb5387a08b4d1d4f410c) ) + ROM_LOAD( "gm-6b.bin", 0x2e000, 0x2000, CRC(513d8cdd) SHA1(563e5a2b7e71b4e1447bd41339174129a5884517) ) // mostly the same as 2a/5a except for a small table, corrupt text if we don't use this here.. + + ROM_LOAD( "gm-5a.bin", 0x38000, 0x8000, CRC(1de8dd2e) SHA1(6b538dcf35105bca1ae1bb5387a08b4d1d4f410c) ) // same as 2a, not being used.. + + SOUNDBOARD_ROMS + + ROM_REGION( 0x10000, "gfx1", 0 ) /* up to 64k of sprites */ + ROM_LOAD( "gm-6a.bin", 0x00000, 0x8000, CRC(b9681f53) SHA1(bb0c516408f1769e018f0ec8707786d4d1e9ef7e) ) + + MOTHERBOARD_PALS +ROM_END + +ROM_START( grudgep ) + ROM_REGION( 0x40000, "maincpu", 0 ) /* 64k for code for the first CPU, plus 128k of banked ROMs */ + ROM_LOAD( "grudge.ab0", 0x10000, 0x8000, CRC(260965ca) SHA1(79eb5dc6605974ece3d5564f10c4598204907398) ) + ROM_LOAD( "grudge.ab4", 0x18000, 0x8000, CRC(c6cd734d) SHA1(076546569e9c8ff40f96bd2cac014bcabc53099d) ) + ROM_LOAD( "grudge.cd0", 0x20000, 0x8000, CRC(e51db1f2) SHA1(57fc0f1df358dd6ea982dcbe9c3f79b3f072be53) ) + ROM_LOAD( "grudge.cd4", 0x28000, 0x8000, CRC(6b60e47e) SHA1(5a399942d4ef9b7349fffd07c07092b667cf6247) ) + + ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for Z80 */ + ROM_LOAD( "sentesnd", 0x00000, 0x2000, CRC(4dd0a525) SHA1(f0c447adc5b67917851a9df978df851247e75c43) ) + + ROM_REGION( 0x8000, "gfx1", 0 ) /* up to 64k of sprites */ + ROM_LOAD( "grudge.gr0", 0x00000, 0x8000, CRC(b9681f53) SHA1(bb0c516408f1769e018f0ec8707786d4d1e9ef7e) ) + + MOTHERBOARD_PALS +ROM_END ROM_START( minigolf ) ROM_REGION( 0x40000, "maincpu", 0 ) /* 64k for code for the first CPU, plus 128k of banked ROMs */ @@ -2142,21 +2175,7 @@ ROM_START( rescraida ) ROM_END -ROM_START( grudge ) - ROM_REGION( 0x40000, "maincpu", 0 ) /* 64k for code for the first CPU, plus 128k of banked ROMs */ - ROM_LOAD( "grudge.ab0", 0x10000, 0x8000, CRC(260965ca) SHA1(79eb5dc6605974ece3d5564f10c4598204907398) ) - ROM_LOAD( "grudge.ab4", 0x18000, 0x8000, CRC(c6cd734d) SHA1(076546569e9c8ff40f96bd2cac014bcabc53099d) ) - ROM_LOAD( "grudge.cd0", 0x20000, 0x8000, CRC(e51db1f2) SHA1(57fc0f1df358dd6ea982dcbe9c3f79b3f072be53) ) - ROM_LOAD( "grudge.cd4", 0x28000, 0x8000, CRC(6b60e47e) SHA1(5a399942d4ef9b7349fffd07c07092b667cf6247) ) - ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for Z80 */ - ROM_LOAD( "sentesnd", 0x00000, 0x2000, CRC(4dd0a525) SHA1(f0c447adc5b67917851a9df978df851247e75c43) ) - - ROM_REGION( 0x8000, "gfx1", 0 ) /* up to 64k of sprites */ - ROM_LOAD( "grudge.gr0", 0x00000, 0x8000, CRC(b9681f53) SHA1(bb0c516408f1769e018f0ec8707786d4d1e9ef7e) ) - - MOTHERBOARD_PALS -ROM_END ROM_START( shrike ) @@ -2389,6 +2408,8 @@ GAME( 1985, gimeabrk, 0, balsente, gimeabrk, balsente_state, gimeabrk, RO GAME( 1985, minigolf, 0, balsente, minigolf, balsente_state, minigolf, ROT0, "Bally/Sente", "Mini Golf (11/25/85)", MACHINE_SUPPORTS_SAVE ) GAME( 1985, minigolf2,minigolf, balsente, minigolf2,balsente_state, minigolf2,ROT0, "Bally/Sente", "Mini Golf (10/8/85)", MACHINE_SUPPORTS_SAVE ) GAME( 1984, triviabb, 0, balsente, triviag1, balsente_state, triviag2, ROT0, "Bally/Sente", "Trivial Pursuit (Baby Boomer Edition) (3/20/85)", MACHINE_SUPPORTS_SAVE ) +GAME( 198?, grudge, 0, balsente, grudge, balsente_state, grudge, ROT0, "Bally Midway", "Grudge Match (v00.90, Italy, location test?)", MACHINE_SUPPORTS_SAVE ) // newer than set below, had a complete cabinet + art +GAME( 198?, grudgep, grudge, balsente, grudge, balsente_state, grudge, ROT0, "Bally Midway", "Grudge Match (v00.80, prototype)", MACHINE_SUPPORTS_SAVE ) /* Board: Unknown */ GAME( 1984, triviag1, 0, balsente, triviag1, balsente_state, triviag1, ROT0, "Bally/Sente", "Trivial Pursuit (Think Tank - Genus Edition) (set 1)", MACHINE_SUPPORTS_SAVE ) @@ -2417,5 +2438,4 @@ GAME( 1987, rescraid, 0, balsente, rescraid, balsente_state, rescraid, RO /* Board: Unknown */ GAME( 1986, shrike, 0, shrike, shrike, balsente_state, shrike, ROT0, "Bally/Sente", "Shrike Avenger (prototype)", MACHINE_SUPPORTS_SAVE ) GAME( 1987, rescraida,rescraid, balsente, rescraid, balsente_state, rescraid, ROT0, "Bally Midway", "Rescue Raider (stand-alone)", MACHINE_SUPPORTS_SAVE ) -GAME( 198?, grudge, 0, balsente, grudge, balsente_state, grudge, ROT0, "Bally Midway", "Grudge Match (prototype)", MACHINE_SUPPORTS_SAVE ) GAME( 1985, teamht, 0, balsente, teamht, balsente_state, teamht, ROT0, "Bally/Sente", "Team Hat Trick", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/basic52.cpp b/src/mame/drivers/basic52.cpp index e2daa857e20..b998fe53ba6 100644 --- a/src/mame/drivers/basic52.cpp +++ b/src/mame/drivers/basic52.cpp @@ -37,22 +37,22 @@ to discover the special features of this Basic. #include "machine/i8255.h" #include "machine/terminal.h" -#define TERMINAL_TAG "terminal" class basic52_state : public driver_device { public: basic52_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu") - { - } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { } void kbd_put(u8 data); DECLARE_READ8_MEMBER(unk_r); + DECLARE_READ8_MEMBER(from_term); + +private: uint8_t m_term_data; required_device<mcs51_cpu_device> m_maincpu; - DECLARE_READ8_MEMBER(from_term); }; @@ -103,11 +103,11 @@ static MACHINE_CONFIG_START( basic31 ) MCFG_CPU_ADD("maincpu", I8031, XTAL_11_0592MHz) MCFG_CPU_PROGRAM_MAP(basic52_mem) MCFG_CPU_IO_MAP(basic52_io) - MCFG_MCS51_SERIAL_TX_CB(DEVWRITE8(TERMINAL_TAG, generic_terminal_device, write)) + MCFG_MCS51_SERIAL_TX_CB(DEVWRITE8("terminal", generic_terminal_device, write)) MCFG_MCS51_SERIAL_RX_CB(READ8(basic52_state, from_term)) /* video hardware */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) + MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(basic52_state, kbd_put)) MCFG_DEVICE_ADD("ppi8255", I8255, 0) @@ -118,7 +118,7 @@ static MACHINE_CONFIG_DERIVED( basic52, basic31 ) MCFG_CPU_REPLACE("maincpu", I8052, XTAL_11_0592MHz) MCFG_CPU_PROGRAM_MAP(basic52_mem) MCFG_CPU_IO_MAP(basic52_io) - MCFG_MCS51_SERIAL_TX_CB(DEVWRITE8(TERMINAL_TAG, generic_terminal_device, write)) + MCFG_MCS51_SERIAL_TX_CB(DEVWRITE8("terminal", generic_terminal_device, write)) MCFG_MCS51_SERIAL_RX_CB(READ8(basic52_state, from_term)) MACHINE_CONFIG_END diff --git a/src/mame/drivers/bbc.cpp b/src/mame/drivers/bbc.cpp index 3e8734da8f7..ed6c9312fe2 100644 --- a/src/mame/drivers/bbc.cpp +++ b/src/mame/drivers/bbc.cpp @@ -153,8 +153,7 @@ static ADDRESS_MAP_START( bbca_mem, AS_PROGRAM, 8, bbc_state ) /* fe00-feff SHEILA Address Page */ AM_RANGE(0xfe00, 0xfe00) AM_MIRROR(0x06) AM_DEVREADWRITE("hd6845", hd6845_device, status_r, address_w) /* fe00-fe07 6845 CRTC Video controller */ AM_RANGE(0xfe01, 0xfe01) AM_MIRROR(0x06) AM_DEVREADWRITE("hd6845", hd6845_device, register_r, register_w) - AM_RANGE(0xfe08, 0xfe08) AM_MIRROR(0x06) AM_DEVREADWRITE("acia6850", acia6850_device, status_r, control_w) /* fe08-fe0F 6850 ACIA Serial controller */ - AM_RANGE(0xfe09, 0xfe09) AM_MIRROR(0x06) AM_DEVREADWRITE("acia6850", acia6850_device, data_r, data_w) + AM_RANGE(0xfe08, 0xfe09) AM_MIRROR(0x06) AM_DEVREADWRITE("acia6850", acia6850_device, read, write) /* fe08-fe0f 6850 ACIA Serial controller */ AM_RANGE(0xfe10, 0xfe17) AM_READWRITE(bbc_fe_r, bbc_SerialULA_w) /* fe10-fe17 Serial ULA Serial system chip */ AM_RANGE(0xfe18, 0xfe1f) AM_NOP /* fe18-fe1f INTOFF/STATID # ECONET Interrupt Off / ID No. */ AM_RANGE(0xfe20, 0xfe2f) AM_READWRITE(bbc_fe_r, bbc_videoULA_w) /* R: fe20-fe2f INTON # ECONET Interrupt On */ @@ -179,8 +178,7 @@ static ADDRESS_MAP_START( bbc_base, AS_PROGRAM, 8, bbc_state ) /* fe00-feff SHEILA Address Page */ AM_RANGE(0xfe00, 0xfe00) AM_MIRROR(0x06) AM_DEVREADWRITE("hd6845", hd6845_device, status_r, address_w) /* fe00-fe07 6845 CRTC Video controller */ AM_RANGE(0xfe01, 0xfe01) AM_MIRROR(0x06) AM_DEVREADWRITE("hd6845", hd6845_device, register_r, register_w) - AM_RANGE(0xfe08, 0xfe08) AM_MIRROR(0x06) AM_DEVREADWRITE("acia6850", acia6850_device, status_r, control_w) /* fe08-fe0F 6850 ACIA Serial controller */ - AM_RANGE(0xfe09, 0xfe09) AM_MIRROR(0x06) AM_DEVREADWRITE("acia6850", acia6850_device, data_r, data_w) + AM_RANGE(0xfe08, 0xfe09) AM_MIRROR(0x06) AM_DEVREADWRITE("acia6850", acia6850_device, read, write) /* fe08-fe0f 6850 ACIA Serial controller */ AM_RANGE(0xfe10, 0xfe17) AM_READWRITE(bbc_fe_r, bbc_SerialULA_w) /* fe10-fe17 Serial ULA Serial system chip */ AM_RANGE(0xfe18, 0xfe1f) AM_READ_PORT("STATID") /* fe18-fe1f INTOFF/STATID ECONET Interrupt Off / ID No. */ AM_RANGE(0xfe20, 0xfe2f) AM_READWRITE(bbc_fe_r, bbc_videoULA_w) /* R: fe20-fe2f INTON ECONET Interrupt On */ @@ -225,7 +223,7 @@ static ADDRESS_MAP_START( bbcbp_mem, AS_PROGRAM, 8, bbc_state ) AM_RANGE(0xb000, 0xbfff) AM_READ_BANK("bank6") /* b000-bfff Rest of paged ROM area */ AM_RANGE(0xfe30, 0xfe3f) AM_READWRITE(bbc_fe_r, bbc_page_selectbp_w) /* R: fe30-fe3f NC Not Connected */ /* W: fe30-fe3f 84LS161 Paged ROM selector */ - AM_RANGE(0xfe80, 0xfe83) AM_WRITE(bbc_wd1770_status_w) /* fe80-fe83 1770 FDC Drive control register */ + AM_RANGE(0xfe80, 0xfe83) AM_READWRITE(bbc_fe_r, bbc_wd1770_status_w) /* fe80-fe83 1770 FDC Drive control register */ AM_RANGE(0xfe84, 0xfe9f) AM_DEVREADWRITE("wd1770", wd1770_device, read, write) /* fe84-fe9f 1770 FDC Floppy disc controller */ AM_RANGE(0xfee0, 0xfeff) AM_DEVREADWRITE("tube", bbc_tube_slot_device, host_r, host_w) /* fee0-feff Tube ULA Tube system interface */ AM_IMPORT_FROM(bbc_base) @@ -239,7 +237,7 @@ static ADDRESS_MAP_START( bbcbp128_mem, AS_PROGRAM, 8, bbc_state ) AM_RANGE(0xb000, 0xbfff) AM_READ_BANK("bank6") AM_WRITE(bbc_memorybp6_128_w) /* b000-bfff Rest of paged ROM area */ AM_RANGE(0xfe30, 0xfe3f) AM_READWRITE(bbc_fe_r, bbc_page_selectbp_w) /* R: fe30-fe3f NC Not Connected */ /* W: fe30-fe3f 84LS161 Paged ROM selector */ - AM_RANGE(0xfe80, 0xfe83) AM_WRITE(bbc_wd1770_status_w) /* fe80-fe83 1770 FDC Drive control register */ + AM_RANGE(0xfe80, 0xfe83) AM_READWRITE(bbc_fe_r, bbc_wd1770_status_w) /* fe80-fe83 1770 FDC Drive control register */ AM_RANGE(0xfe84, 0xfe9f) AM_DEVREADWRITE("wd1770", wd1770_device, read, write) /* fe84-fe9f 1770 FDC Floppy disc controller */ AM_RANGE(0xfee0, 0xfeff) AM_DEVREADWRITE("tube", bbc_tube_slot_device, host_r, host_w) /* fee0-feff Tube ULA Tube system interface */ AM_IMPORT_FROM(bbc_base) @@ -422,8 +420,13 @@ static INPUT_PORTS_START(bbc_keyboard) /* Keyboard columns 10 -> 12 are reserved for BBC Master */ PORT_START("COL10") + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_START("COL11") + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_START("COL12") + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) INPUT_PORTS_END @@ -526,7 +529,7 @@ static INPUT_PORTS_START(bbc_dipswitch) PORT_MODIFY("COL6") PORT_DIPNAME(0x01, 0x01, "Boot") PORT_DIPLOCATION("KBD:5") - PORT_DIPSETTING( 0x00, "SHIFT" ) + PORT_DIPSETTING( 0x00, "BREAK" ) PORT_DIPSETTING( 0x01, "SHIFT-BREAK" ) PORT_MODIFY("COL7") @@ -778,7 +781,7 @@ FLOPPY_FORMATS_MEMBER( bbc_state::floppy_formats_bbc ) FLOPPY_OPUS_DDCPM_FORMAT, FLOPPY_FSD_FORMAT, FLOPPY_PC_FORMAT -FLOPPY_FORMATS_END0 +FLOPPY_FORMATS_END FLOPPY_FORMATS_MEMBER( bbc_state::floppy_formats_bbcm ) FLOPPY_ACORN_SSD_FORMAT, @@ -788,11 +791,11 @@ FLOPPY_FORMATS_MEMBER( bbc_state::floppy_formats_bbcm ) FLOPPY_ACORN_DOS_FORMAT, FLOPPY_FSD_FORMAT, FLOPPY_PC_FORMAT -FLOPPY_FORMATS_END0 +FLOPPY_FORMATS_END FLOPPY_FORMATS_MEMBER( bbc_state::floppy_formats_bbcmc ) FLOPPY_ACORN_ADFS_OLD_FORMAT -FLOPPY_FORMATS_END0 +FLOPPY_FORMATS_END static SLOT_INTERFACE_START( bbc_floppies_525 ) SLOT_INTERFACE("525sssd", FLOPPY_525_SSSD) @@ -957,12 +960,12 @@ static MACHINE_CONFIG_DERIVED( bbcb, bbca ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) /* user via */ - MCFG_DEVICE_ADD("via6522_1", VIA6522, XTAL_16MHz / 16) - MCFG_VIA6522_READPB_HANDLER(READ8(bbc_state, bbcb_via_user_read_portb)) - MCFG_VIA6522_WRITEPA_HANDLER(DEVWRITE8("cent_data_out", output_latch_device, write)) - MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(bbc_state, bbcb_via_user_write_portb)) - MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE("centronics", centronics_device, write_strobe)) - MCFG_VIA6522_IRQ_HANDLER(DEVWRITELINE("irqs", input_merger_device, in_w<2>)) + MCFG_DEVICE_ADD("via6522_1", VIA6522, XTAL_16MHz / 16) + MCFG_VIA6522_WRITEPA_HANDLER(DEVWRITE8("cent_data_out", output_latch_device, write)) + MCFG_VIA6522_READPB_HANDLER(DEVREAD8("userport", bbc_userport_slot_device, pb_r)) + MCFG_VIA6522_WRITEPB_HANDLER(DEVWRITE8("userport", bbc_userport_slot_device, pb_w)) + MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE("centronics", centronics_device, write_strobe)) + MCFG_VIA6522_IRQ_HANDLER(DEVWRITELINE("irqs", input_merger_device, in_w<2>)) /* adc */ MCFG_DEVICE_ADD("upd7002", UPD7002, 0) @@ -989,7 +992,7 @@ static MACHINE_CONFIG_DERIVED( bbcb, bbca ) MCFG_ECONET_SLOT_ADD("econet254", 254, econet_devices, nullptr) /* analogue port */ - MCFG_BBC_ANALOGUE_SLOT_ADD("analogue", bbc_analogue_devices, "acornjoy") + MCFG_BBC_ANALOGUE_SLOT_ADD("analogue", bbc_analogue_devices, nullptr) /* 1mhz bus port */ MCFG_BBC_1MHZBUS_SLOT_ADD("1mhzbus", bbc_1mhzbus_devices, nullptr) @@ -1002,6 +1005,8 @@ static MACHINE_CONFIG_DERIVED( bbcb, bbca ) /* user port */ MCFG_BBC_USERPORT_SLOT_ADD("userport", bbc_userport_devices, nullptr) + MCFG_BBC_USERPORT_CB1_HANDLER(DEVWRITELINE("via6522_1", via6522_device, write_cb1)) + MCFG_BBC_USERPORT_CB2_HANDLER(DEVWRITELINE("via6522_1", via6522_device, write_cb2)) /* software lists */ MCFG_SOFTWARE_LIST_ADD("cass_ls_b", "bbcb_cass") @@ -1255,7 +1260,6 @@ static MACHINE_CONFIG_DERIVED( reutapm, bbcbp ) /* expansion ports */ MCFG_DEVICE_REMOVE("analogue") MCFG_DEVICE_REMOVE("1mhzbus") - MCFG_DEVICE_REMOVE("userport") MACHINE_CONFIG_END @@ -1402,12 +1406,12 @@ static MACHINE_CONFIG_START( bbcm ) MCFG_VIA6522_IRQ_HANDLER(DEVWRITELINE("irqs", input_merger_device, in_w<1>)) /* user via */ - MCFG_DEVICE_ADD("via6522_1", VIA6522, XTAL_16MHz / 16) - MCFG_VIA6522_READPB_HANDLER(READ8(bbc_state, bbcb_via_user_read_portb)) - MCFG_VIA6522_WRITEPA_HANDLER(DEVWRITE8("cent_data_out", output_latch_device, write)) - MCFG_VIA6522_WRITEPB_HANDLER(WRITE8(bbc_state, bbcb_via_user_write_portb)) - MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE("centronics", centronics_device, write_strobe)) - MCFG_VIA6522_IRQ_HANDLER(DEVWRITELINE("irqs", input_merger_device, in_w<2>)) + MCFG_DEVICE_ADD("via6522_1", VIA6522, XTAL_16MHz / 16) + MCFG_VIA6522_WRITEPA_HANDLER(DEVWRITE8("cent_data_out", output_latch_device, write)) + MCFG_VIA6522_READPB_HANDLER(DEVREAD8("userport", bbc_userport_slot_device, pb_r)) + MCFG_VIA6522_WRITEPB_HANDLER(DEVWRITE8("userport", bbc_userport_slot_device, pb_w)) + MCFG_VIA6522_CA2_HANDLER(DEVWRITELINE("centronics", centronics_device, write_strobe)) + MCFG_VIA6522_IRQ_HANDLER(DEVWRITELINE("irqs", input_merger_device, in_w<2>)) /* fdc */ MCFG_WD1770_ADD("wd1770", XTAL_16MHz / 2) @@ -1429,7 +1433,7 @@ static MACHINE_CONFIG_START( bbcm ) MCFG_ECONET_SLOT_ADD("econet254", 254, econet_devices, nullptr) /* analogue port */ - MCFG_BBC_ANALOGUE_SLOT_ADD("analogue", bbc_analogue_devices, "acornjoy") + MCFG_BBC_ANALOGUE_SLOT_ADD("analogue", bbc_analogue_devices, nullptr) /* 1mhz bus port */ MCFG_BBC_1MHZBUS_SLOT_ADD("1mhzbus", bbc_1mhzbus_devices, nullptr) @@ -1444,6 +1448,8 @@ static MACHINE_CONFIG_START( bbcm ) /* user port */ MCFG_BBC_USERPORT_SLOT_ADD("userport", bbc_userport_devices, nullptr) + MCFG_BBC_USERPORT_CB1_HANDLER(DEVWRITELINE("via6522_1", via6522_device, write_cb1)) + MCFG_BBC_USERPORT_CB2_HANDLER(DEVWRITELINE("via6522_1", via6522_device, write_cb2)) MACHINE_CONFIG_END @@ -1471,6 +1477,7 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( bbcmet, bbcm ) /* printer */ MCFG_DEVICE_REMOVE("centronics") + MCFG_DEVICE_REMOVE("cent_data_out") /* cassette */ MCFG_DEVICE_REMOVE("cassette") @@ -1497,6 +1504,9 @@ static MACHINE_CONFIG_DERIVED( bbcmet, bbcm ) /* expansion ports */ MCFG_DEVICE_REMOVE("analogue") + MCFG_DEVICE_REMOVE("extube") + MCFG_DEVICE_REMOVE("1mhzbus") + MCFG_DEVICE_REMOVE("userport") MACHINE_CONFIG_END @@ -1510,12 +1520,9 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( bbcmarm, bbcm ) /* Add ARM co-processor */ - //MCFG_DEVICE_MODIFY("extube") - //MCFG_SLOT_DEFAULT_OPTION("arm") - //MCFG_SLOT_FIXED(true) - - /* software lists */ - MCFG_SOFTWARE_LIST_ADD("flop_ls_arm", "bbc_flop_arm") + MCFG_DEVICE_MODIFY("extube") + MCFG_SLOT_DEFAULT_OPTION("arm") + MCFG_SLOT_FIXED(true) MACHINE_CONFIG_END @@ -1535,6 +1542,26 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( cfa3000, bbcm ) + MCFG_MACHINE_START_OVERRIDE(bbc_state, cfa3000) + + /* fdc */ + MCFG_DEVICE_MODIFY("wd1770:0") + MCFG_DEVICE_SLOT_INTERFACE(bbc_floppies_525, nullptr, false) + MCFG_DEVICE_MODIFY("wd1770:1") + MCFG_DEVICE_SLOT_INTERFACE(bbc_floppies_525, nullptr, false) + + /* keyboard */ + MCFG_DEVICE_MODIFY("userport") + MCFG_SLOT_DEFAULT_OPTION("cfa3000kbd") + + /* option board */ + MCFG_DEVICE_MODIFY("1mhzbus") + MCFG_SLOT_DEFAULT_OPTION("cfa3000opt") + + /* analogue dials/sensors */ + MCFG_DEVICE_MODIFY("analogue") + MCFG_SLOT_DEFAULT_OPTION("cfa3000a") + /* software lists */ MCFG_SOFTWARE_LIST_REMOVE("cass_ls_m") MCFG_SOFTWARE_LIST_REMOVE("cass_ls_a") @@ -2023,7 +2050,7 @@ ROM_START(bbcm) ROM_SYSTEM_BIOS( 1, "mos350", "Enhanced MOS 3.50" ) ROMX_LOAD("mos350.ic24", 0x20000, 0x20000, CRC(141027b9) SHA1(85211b5bc7c7a269952d2b063b7ec0e1f0196803), ROM_BIOS(2)) ROM_COPY("option", 0x20000, 0x40000, 0x4000) /* Move loaded roms into place */ - ROM_FILL(0x20000, 0x4000, 0xFFFF) + ROM_FILL(0x20000, 0x4000, 0xff) /* 00000 rom 0 SK3 Rear Cartridge bottom 16K */ /* 04000 rom 1 SK3 Rear Cartridge top 16K */ /* 08000 rom 2 SK4 Front Cartridge bottom 16K */ @@ -2064,7 +2091,7 @@ ROM_START(bbcmaiv) ROM_SYSTEM_BIOS( 0, "mos320", "MOS 3.20" ) ROMX_LOAD("mos320.ic24", 0x20000, 0x20000, CRC(0f747ebe) SHA1(eacacbec3892dc4809ad5800e6c8299ff9eb528f), ROM_BIOS(1)) ROM_COPY("option", 0x20000, 0x40000, 0x4000) /* Move loaded roms into place */ - ROM_FILL(0x20000, 0x4000, 0xFFFF) + ROM_FILL(0x20000, 0x4000, 0xff) /* 00000 rom 0 SK3 Rear Cartridge bottom 16K */ /* 04000 rom 1 SK3 Rear Cartridge top 16K */ /* 08000 rom 2 SK4 Front Cartridge bottom 16K */ @@ -2101,7 +2128,7 @@ ROM_START(bbcmet) ROMX_LOAD("mos400.ic24", 0x30000, 0x10000, CRC(81729034) SHA1(d4bc2c7f5e66b5298786138f395908e70c772971), ROM_BIOS(1)) ROM_COPY("option", 0x34000, 0x24000, 0xC000) /* Mirror */ ROM_COPY("option", 0x30000, 0x40000, 0x4000) /* Move loaded roms into place */ - ROM_FILL(0x30000, 0x4000, 0xFFFF) + ROM_FILL(0x30000, 0x4000, 0xff) /* 00000 rom 0 SK3 Rear Cartridge bottom 16K */ /* 04000 rom 1 SK3 Rear Cartridge top 16K */ /* 08000 rom 2 SK4 Front Cartridge bottom 16K */ @@ -2136,7 +2163,7 @@ ROM_START(bbcmarm) ROM_SYSTEM_BIOS( 0, "mos320", "Original MOS 3.20" ) ROMX_LOAD("mos320.ic24", 0x20000, 0x20000, CRC(0f747ebe) SHA1(eacacbec3892dc4809ad5800e6c8299ff9eb528f), ROM_BIOS(1)) ROM_COPY("option", 0x20000, 0x40000, 0x4000) /* Move loaded roms into place */ - ROM_FILL(0x20000, 0x4000, 0xFFFF) + ROM_FILL(0x20000, 0x4000, 0xff) /* 00000 rom 0 SK3 Rear Cartridge bottom 16K */ /* 04000 rom 1 SK3 Rear Cartridge top 16K */ /* 08000 rom 2 SK4 Front Cartridge bottom 16K */ @@ -2174,7 +2201,7 @@ ROM_START(bbcmc) ROM_SYSTEM_BIOS( 1, "mos500", "Original MOS 5.00" ) ROMX_LOAD("mos500.ic49", 0x30000, 0x10000, CRC(f6170023) SHA1(140d002d2d9cd34b47197a2ba823505af2a84633), ROM_BIOS(2)) ROM_COPY("option", 0x30000, 0x40000, 0x4000) /* Move loaded roms into place */ - ROM_FILL(0x30000, 0x4000, 0xFFFF) + ROM_FILL(0x30000, 0x4000, 0xff) /* 00000 rom 0 EXTERNAL */ /* 04000 rom 1 EXTERNAL */ /* 08000 rom 2 IC23 SPARE SOCKET */ @@ -2205,7 +2232,7 @@ ROM_START(bbcmc_ar) ROM_SYSTEM_BIOS( 0, "mos511i", "International MOS 5.11" ) ROMX_LOAD("mos511.ic49", 0x30000, 0x10000, BAD_DUMP CRC(8708803c) SHA1(d2170c8b9b536f3ad84a4a603a7fe712500cc751), ROM_BIOS(1)) /* Merged individual ROM bank dumps */ ROM_COPY("option", 0x30000, 0x40000, 0x4000) /* Move loaded roms into place */ - ROM_FILL(0x30000, 0x4000, 0xFFFF) + ROM_FILL(0x30000, 0x4000, 0xff) /* 00000 rom 0 EXTERNAL */ /* 04000 rom 1 EXTERNAL */ /* 08000 rom 2 IC23 International */ @@ -2238,7 +2265,7 @@ ROM_START(pro128s) ROM_SYSTEM_BIOS(0, "mos510o", "Olivetti MOS 5.10") ROMX_LOAD("mos510o.ic49", 0x30000, 0x10000, CRC(c16858d3) SHA1(ad231ed21a55e493b553703285530d1cacd3de7a), ROM_BIOS(1)) ROM_COPY("option", 0x30000, 0x40000, 0x4000) /* Move loaded roms into place */ - ROM_FILL(0x30000, 0x4000, 0xFFFF) + ROM_FILL(0x30000, 0x4000, 0xff) /* 00000 rom 0 EXTERNAL */ /* 04000 rom 1 EXTERNAL */ /* 08000 rom 2 IC23 SPARE SOCKET */ @@ -2269,7 +2296,7 @@ ROM_START(discmate) ROM_SYSTEM_BIOS(0, "mos320", "Original MOS 3.20") ROMX_LOAD("mos320.ic24", 0x20000, 0x20000, CRC(0f747ebe) SHA1(eacacbec3892dc4809ad5800e6c8299ff9eb528f), ROM_BIOS(1)) ROM_COPY("option", 0x20000, 0x40000, 0x4000) /* Move loaded roms into place */ - ROM_FILL(0x20000, 0x4000, 0xFFFF) + ROM_FILL(0x20000, 0x4000, 0xff) /* 00000 rom 0 SK3 Rear Cartridge bottom 16K */ /* 04000 rom 1 SK3 Rear Cartridge top 16K */ /* 08000 rom 2 SK4 Front Cartridge bottom 16K */ @@ -2303,10 +2330,10 @@ ROM_START(cfa3000) ROM_REGION(0x44000, "option", 0) /* ROM */ ROM_LOAD("CFA3000_3_4_Iss10.3.ic41", 0x10000, 0x08000, CRC(ecb385ab) SHA1(eafa9b34cb1cf63790f74332bb7d85ee356b6973)) ROM_LOAD("CFA3000_SM_Iss10.3.ic37", 0x18000, 0x08000, CRC(c07aee5f) SHA1(1994e3755dc15d1ea7e105bc19cd57893b719779)) - ROM_LOAD("Acorn_MOS_(Tinsley_64K)_Iss10.3.ic24", 0x30000, 0x10000, CRC(4413c3ee) SHA1(76d0462b4dabe2461010fce2341570ff3d606d54)) - //ROM_COPY("option", 0x20000, 0x30000, 0x10000) /* Mirror MOS */ + ROM_LOAD("Acorn_MOS_(Tinsley_64K)_Iss10.3.ic24", 0x20000, 0x10000, CRC(4413c3ee) SHA1(76d0462b4dabe2461010fce2341570ff3d606d54)) + ROM_COPY("option", 0x20000, 0x30000, 0x10000) /* Mirror MOS */ ROM_COPY("option", 0x30000, 0x40000, 0x04000) /* Move loaded roms into place */ - ROM_FILL(0x30000, 0x4000, 0xFFFF) + ROM_FILL(0x30000, 0x4000, 0xff) /* 00000 rom 0 SK3 Rear Cartridge bottom 16K */ /* 04000 rom 1 SK3 Rear Cartridge top 16K */ /* 08000 rom 2 SK4 Front Cartridge bottom 16K */ @@ -2315,13 +2342,13 @@ ROM_START(cfa3000) /* 14000 rom 5 IC41 SWRAM or top 16K */ /* 18000 rom 6 IC37 SWRAM or bottom 16K */ /* 1c000 rom 7 IC37 SWRAM or top 16K */ - /* 20000 rom 8 IC27 ANFS */ - /* 24000 rom 9 IC24 DFS + SRAM */ - /* 28000 rom 10 IC24 Viewsheet */ - /* 2c000 rom 11 IC24 Edit */ - /* 30000 rom 12 IC24 BASIC */ - /* 34000 rom 13 IC24 ADFS */ - /* 38000 rom 14 IC24 View + MOS code */ + /* 20000 rom 8 IC27 */ + /* 24000 rom 9 IC24 */ + /* 28000 rom 10 IC24 */ + /* 2c000 rom 11 IC24 */ + /* 30000 rom 12 IC24 */ + /* 34000 rom 13 IC24 DFS */ + /* 38000 rom 14 IC24 BASIC */ /* 3c000 rom 15 IC24 Terminal + Tube host + CFS */ ROM_REGION(0x4000, "os", 0) @@ -2358,7 +2385,7 @@ COMP ( 1986, bbcmt, bbcm, 0, bbcmt, bbcm, bbc_state, bbc, COMP ( 1986, bbcmaiv, bbcm, 0, bbcmaiv, bbcm, bbc_state, bbc, "Acorn", "BBC Master AIV", MACHINE_NOT_WORKING) COMP ( 1986, bbcmet, bbcm, 0, bbcmet, bbcm, bbc_state, bbc, "Acorn", "BBC Master ET", MACHINE_IMPERFECT_GRAPHICS) COMP ( 1986, bbcm512, bbcm, 0, bbcm512, bbcm, bbc_state, bbc, "Acorn", "BBC Master 512", MACHINE_NOT_WORKING) -COMP ( 1986, bbcmarm, bbcm, 0, bbcmarm, bbcm, bbc_state, bbc, "Acorn", "ARM Evaluation System", MACHINE_NOT_WORKING) +COMP ( 1986, bbcmarm, bbcm, 0, bbcmarm, bbcm, bbc_state, bbc, "Acorn", "BBC Master (ARM Evaluation)", MACHINE_NOT_WORKING) COMP ( 1986, ltmpm, bbcm, 0, ltmpm, ltmpm, bbc_state, bbc, "Lawrie T&M Ltd.", "LTM Portable (Master)", MACHINE_IMPERFECT_GRAPHICS) COMP ( 1986, bbcmc, 0, bbcm, bbcmc, bbcm, bbc_state, bbc, "Acorn", "BBC Master Compact", MACHINE_IMPERFECT_GRAPHICS) COMP ( 1986, bbcmc_ar, bbcmc, 0, bbcmc, bbcm, bbc_state, bbc, "Acorn", "BBC Master Compact (Arabic)", MACHINE_IMPERFECT_GRAPHICS) @@ -2366,4 +2393,4 @@ COMP ( 1987, pro128s, bbcmc, 0, pro128s, bbcm, bbc_state, bbc, //COMP ( 1988, discmon, bbcm, 0, discmon, bbcm, bbc_state, bbc, "Arbiter Leisure", "Arbiter Discmonitor A-01", MACHINE_NOT_WORKING) COMP ( 1988, discmate, bbcm, 0, discmate, bbcm, bbc_state, bbc, "Arbiter Leisure", "Arbiter Discmate A-02", MACHINE_NOT_WORKING) //COMP ( 1988, discmast, bbcm, 0, discmast, bbcm, bbc_state, bbc, "Arbiter Leisure", "Arbiter Discmaster A-03", MACHINE_NOT_WORKING) -COMP ( 1988, cfa3000, bbcm, 0, cfa3000, bbcm, bbc_state, bbc, "Tinsley Medical Instruments", "Henson CFA 3000", MACHINE_NOT_WORKING) +COMP ( 1989, cfa3000, bbcm, 0, cfa3000, bbcm, bbc_state, bbc, "Tinsley Medical Instruments", "Henson CFA 3000", MACHINE_NOT_WORKING) diff --git a/src/mame/drivers/bbcbc.cpp b/src/mame/drivers/bbcbc.cpp index e5b8a07fa64..ea0ba852ccb 100644 --- a/src/mame/drivers/bbcbc.cpp +++ b/src/mame/drivers/bbcbc.cpp @@ -40,34 +40,33 @@ class bbcbc_state : public driver_device { public: bbcbc_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_buttons(*this, "BUTTONS.%u", 0) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_buttons(*this, "BUTTONS.%u", 0) { } - required_device<cpu_device> m_maincpu; - required_ioport_array<3> m_buttons; + DECLARE_READ8_MEMBER(input_r); + DECLARE_WRITE8_MEMBER(input_select_w); +private: uint8_t m_input_select; - virtual void machine_start() override; virtual void machine_reset() override; - - DECLARE_READ8_MEMBER(input_r); - DECLARE_WRITE8_MEMBER(input_select_w); + required_device<cpu_device> m_maincpu; + required_ioport_array<3> m_buttons; }; #define MAIN_CLOCK XTAL_4_433619MHz -static ADDRESS_MAP_START( bbcbc_prg, AS_PROGRAM, 8, bbcbc_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, bbcbc_state ) AM_RANGE(0x0000, 0x3fff) AM_ROM AM_RANGE(0x4000, 0xbfff) AM_DEVREAD("cartslot", generic_slot_device, read_rom) AM_RANGE(0xe000, 0xe7ff) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( bbcbc_io, AS_IO, 8, bbcbc_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, bbcbc_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x7f) AM_DEVREADWRITE_MOD("z80pio", z80pio_device, read, write, rshift<5>) AM_RANGE(0x80, 0x80) AM_DEVREADWRITE("tms9129", tms9129_device, vram_read, vram_write) @@ -108,8 +107,8 @@ static const z80_daisy_config bbcbc_daisy_chain[] = static MACHINE_CONFIG_START( bbcbc ) MCFG_CPU_ADD( "maincpu", Z80, MAIN_CLOCK / 8 ) - MCFG_CPU_PROGRAM_MAP(bbcbc_prg) - MCFG_CPU_IO_MAP(bbcbc_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_Z80_DAISY_CHAIN(bbcbc_daisy_chain) MCFG_DEVICE_ADD("z80pio", Z80PIO, MAIN_CLOCK/8) diff --git a/src/mame/drivers/bbusters.cpp b/src/mame/drivers/bbusters.cpp index c13f29c1e82..65df69e083e 100644 --- a/src/mame/drivers/bbusters.cpp +++ b/src/mame/drivers/bbusters.cpp @@ -881,8 +881,8 @@ ROM_END ROM_START( bbustersj ) ROM_REGION( 0x80000, "maincpu", 0 ) - ROM_LOAD16_BYTE( "bb3_ver2_j2.k10", 0x000000, 0x20000, CRC(605eb62f) SHA1(b13afd561731ad9115c5b997b8a7a79a57557612) ) /* red "J2" stamped on program labels - 2 Player version */ - ROM_LOAD16_BYTE( "bb5_ver2_j2.k12", 0x000001, 0x20000, CRC(9deea26f) SHA1(c5436db0c55da9b0c5e0e053f59a1e17ee4690a6) ) + ROM_LOAD16_BYTE( "bb3_ver2_j3.k10", 0x000000, 0x20000, CRC(6a1cd941) SHA1(d29775703f30b0a440e5e960006c0d33bb09992c) ) /* red "J3" stamped on program labels - 3 Player version */ + ROM_LOAD16_BYTE( "bb5_ver2_j3.k12", 0x000001, 0x20000, CRC(7b180752) SHA1(7ae98e3eb81b19a9208e8dae1cdd64796021d034) ) ROM_LOAD16_BYTE( "bb-2.k8", 0x040000, 0x20000, CRC(20141805) SHA1(0958579681bda81bcf48d020a14bc147c1e575f1) ) ROM_LOAD16_BYTE( "bb-4.k11", 0x040001, 0x20000, CRC(d482e0e9) SHA1(e56ca92965e8954b613ba4b0e3975e3a12840c30) ) @@ -929,8 +929,8 @@ ROM_END ROM_START( bbustersja ) ROM_REGION( 0x80000, "maincpu", 0 ) - ROM_LOAD16_BYTE( "bb3_ver2_j3.k10", 0x000000, 0x20000, CRC(6a1cd941) SHA1(d29775703f30b0a440e5e960006c0d33bb09992c) ) /* red "J3" stamped on program labels - 3 Player version */ - ROM_LOAD16_BYTE( "bb5_ver2_j3.k12", 0x000001, 0x20000, CRC(7b180752) SHA1(7ae98e3eb81b19a9208e8dae1cdd64796021d034) ) + ROM_LOAD16_BYTE( "bb3_ver2_j2.k10", 0x000000, 0x20000, CRC(605eb62f) SHA1(b13afd561731ad9115c5b997b8a7a79a57557612) ) /* red "J2" stamped on program labels - 2 Player version */ + ROM_LOAD16_BYTE( "bb5_ver2_j2.k12", 0x000001, 0x20000, CRC(9deea26f) SHA1(c5436db0c55da9b0c5e0e053f59a1e17ee4690a6) ) ROM_LOAD16_BYTE( "bb-2.k8", 0x040000, 0x20000, CRC(20141805) SHA1(0958579681bda81bcf48d020a14bc147c1e575f1) ) ROM_LOAD16_BYTE( "bb-4.k11", 0x040001, 0x20000, CRC(d482e0e9) SHA1(e56ca92965e8954b613ba4b0e3975e3a12840c30) ) @@ -1164,8 +1164,8 @@ ROM_END GAME( 1989, bbusters, 0, bbusters, bbusters, bbusters_state, 0, ROT0, "SNK", "Beast Busters (World)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1989, bbustersu, bbusters, bbusters, bbusters, bbusters_state, 0, ROT0, "SNK", "Beast Busters (US, Version 3)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1989, bbustersua, bbusters, bbusters, bbusters, bbusters_state, 0, ROT0, "SNK", "Beast Busters (US, Version 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1989, bbustersj, bbusters, bbusters, bbusters, bbusters_state, 0, ROT0, "SNK", "Beast Busters (Japan, Version 2, 2 Player)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1989, bbustersja, bbusters, bbusters, bbusters, bbusters_state, 0, ROT0, "SNK", "Beast Busters (Japan, Version 2, 3 Player)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1989, bbustersj, bbusters, bbusters, bbusters, bbusters_state, 0, ROT0, "SNK", "Beast Busters (Japan, Version 2, 3 Player)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1989, bbustersja, bbusters, bbusters, bbusters, bbusters_state, 0, ROT0, "SNK", "Beast Busters (Japan, Version 2, 2 Player)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1989, mechatt, 0, mechatt, mechatt, bbusters_state, 0, ROT0, "SNK", "Mechanized Attack (World)", MACHINE_SUPPORTS_SAVE ) GAME( 1989, mechattj, mechatt, mechatt, mechattj, bbusters_state, 0, ROT0, "SNK", "Mechanized Attack (Japan)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/beezer.cpp b/src/mame/drivers/beezer.cpp index c5f58b7c924..324c40c82b4 100644 --- a/src/mame/drivers/beezer.cpp +++ b/src/mame/drivers/beezer.cpp @@ -467,8 +467,8 @@ static MACHINE_CONFIG_START( beezer ) MCFG_DEVICE_ADD("sysbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(banked_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(15) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(15) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", beezer_state, scanline_cb, "screen", 0, 1) diff --git a/src/mame/drivers/bfcobra.cpp b/src/mame/drivers/bfcobra.cpp index c67b8af85e0..7af75c64ae9 100644 --- a/src/mame/drivers/bfcobra.cpp +++ b/src/mame/drivers/bfcobra.cpp @@ -1262,10 +1262,8 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( z80_io_map, AS_IO, 8, bfcobra_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x23) AM_READWRITE(chipset_r, chipset_w) - AM_RANGE(0x24, 0x24) AM_DEVWRITE("acia6850_0", acia6850_device, control_w) - AM_RANGE(0x25, 0x25) AM_DEVWRITE("acia6850_0", acia6850_device, data_w) - AM_RANGE(0x26, 0x26) AM_DEVREAD("acia6850_0", acia6850_device, status_r) - AM_RANGE(0x27, 0x27) AM_DEVREAD("acia6850_0", acia6850_device, data_r) + AM_RANGE(0x24, 0x25) AM_DEVWRITE("acia6850_0", acia6850_device, write) + AM_RANGE(0x26, 0x27) AM_DEVREAD("acia6850_0", acia6850_device, read) AM_RANGE(0x30, 0x30) AM_READ(fdctrl_r) AM_RANGE(0x31, 0x31) AM_READWRITE(fddata_r, fdctrl_w) AM_RANGE(0x40, 0x40) AM_WRITE(rombank_w) @@ -1400,10 +1398,8 @@ static ADDRESS_MAP_START( m6809_prog_map, AS_PROGRAM, 8, bfcobra_state ) AM_RANGE(0x2E00, 0x2E00) AM_READ(int_latch_r) AM_RANGE(0x3001, 0x3001) AM_DEVWRITE("aysnd", ay8910_device, data_w) AM_RANGE(0x3201, 0x3201) AM_DEVWRITE("aysnd", ay8910_device, address_w) - AM_RANGE(0x3404, 0x3404) AM_DEVREADWRITE("acia6850_1", acia6850_device, status_r, control_w) - AM_RANGE(0x3405, 0x3405) AM_DEVREADWRITE("acia6850_1", acia6850_device, data_r, data_w) - AM_RANGE(0x3406, 0x3406) AM_DEVREADWRITE("acia6850_2", acia6850_device, status_r, control_w) - AM_RANGE(0x3407, 0x3407) AM_DEVREADWRITE("acia6850_2", acia6850_device, data_r, data_w) + AM_RANGE(0x3404, 0x3405) AM_DEVREADWRITE("acia6850_1", acia6850_device, read, write) + AM_RANGE(0x3406, 0x3407) AM_DEVREADWRITE("acia6850_2", acia6850_device, read, write) // AM_RANGE(0x3408, 0x3408) AM_NOP // AM_RANGE(0x340A, 0x340A) AM_NOP // AM_RANGE(0x3600, 0x3600) AM_NOP diff --git a/src/mame/drivers/bfm_sc4.cpp b/src/mame/drivers/bfm_sc4.cpp index 4dafa976eff..89e174d597c 100644 --- a/src/mame/drivers/bfm_sc4.cpp +++ b/src/mame/drivers/bfm_sc4.cpp @@ -905,7 +905,7 @@ MACHINE_CONFIG_START( sc4_common ) MCFG_NVRAM_ADD_1FILL("nvram") - MCFG_MC68681_ADD("duart68681", 16000000/4) // ?? Mhz + MCFG_DEVICE_ADD("duart68681", MC68681, 16000000/4) // ?? Mhz MCFG_MC68681_SET_EXTERNAL_CLOCKS(XTAL_16MHz/2/8, XTAL_16MHz/2/16, XTAL_16MHz/2/16, XTAL_16MHz/2/8) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(sc4_state, bfm_sc4_duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(WRITELINE(sc4_state, bfm_sc4_duart_txa)) diff --git a/src/mame/drivers/bfm_sc5.cpp b/src/mame/drivers/bfm_sc5.cpp index bf7f9fcc339..9619d4516eb 100644 --- a/src/mame/drivers/bfm_sc5.cpp +++ b/src/mame/drivers/bfm_sc5.cpp @@ -217,7 +217,7 @@ MACHINE_CONFIG_START( bfm_sc5 ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_MC68681_ADD("duart68681", 16000000/4) // ?? Mhz + MCFG_DEVICE_ADD("duart68681", MC68681, 16000000/4) // ?? Mhz MCFG_MC68681_SET_EXTERNAL_CLOCKS(16000000/2/8, 16000000/2/16, 16000000/2/16, 16000000/2/8) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(bfm_sc5_state, bfm_sc5_duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(WRITELINE(bfm_sc5_state, bfm_sc5_duart_txa)) diff --git a/src/mame/drivers/bfmsys85.cpp b/src/mame/drivers/bfmsys85.cpp index 7933bc6866d..d41c9523d39 100644 --- a/src/mame/drivers/bfmsys85.cpp +++ b/src/mame/drivers/bfmsys85.cpp @@ -373,11 +373,8 @@ static ADDRESS_MAP_START( memmap, AS_PROGRAM, 8, bfmsys85_state ) AM_RANGE(0x3001, 0x3001) AM_READNOP //sound latch AM_RANGE(0x3200, 0x3200) AM_DEVWRITE("aysnd", ay8910_device, address_w) - AM_RANGE(0x3402, 0x3402) AM_DEVWRITE("acia6850_0", acia6850_device, control_w) - AM_RANGE(0x3403, 0x3403) AM_DEVWRITE("acia6850_0", acia6850_device, data_w) - - AM_RANGE(0x3406, 0x3406) AM_DEVREAD("acia6850_0", acia6850_device, status_r) - AM_RANGE(0x3407, 0x3407) AM_DEVREAD("acia6850_0", acia6850_device, data_r) + AM_RANGE(0x3402, 0x3403) AM_DEVWRITE("acia6850_0", acia6850_device, write) + AM_RANGE(0x3406, 0x3407) AM_DEVREAD("acia6850_0", acia6850_device, read) AM_RANGE(0x3600, 0x3600) AM_WRITE(mux_enable_w) // mux enable diff --git a/src/mame/drivers/bingor.cpp b/src/mame/drivers/bingor.cpp index 1f3ae749023..7fc6e3665ba 100644 --- a/src/mame/drivers/bingor.cpp +++ b/src/mame/drivers/bingor.cpp @@ -914,4 +914,4 @@ GAME( 2002, bingor3, 0, bingor, bingor, bingor_state, 0, ROT0, GAME( 2002, bingor4, 0, bingor, bingor, bingor_state, 0, ROT0, "<unknown>", "Bingo Roll / Bell Star? (set 4)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) GAME( 2002, bingor5, 0, bingor, bingor, bingor_state, 0, ROT0, "<unknown>", "Bingo Roll / Bell Star V3? (set 5)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -GAME( 2001, vip2000, 0, vip2000, bingor, bingor_state, 0, ROT0, "Paloma-Elektronik?", "Unknown 'VIP 2000' game", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +GAME( 2001, vip2000, 0, vip2000, bingor, bingor_state, 0, ROT0, "Paloma-Elektronik?", "unknown 'VIP 2000' game", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/bishi.cpp b/src/mame/drivers/bishi.cpp index cb3fcf0776a..a6e2abffa0b 100644 --- a/src/mame/drivers/bishi.cpp +++ b/src/mame/drivers/bishi.cpp @@ -166,6 +166,7 @@ ADDRESS_MAP_END static INPUT_PORTS_START( bishi ) /* Currently, this "IN0" is not read */ + // TODO: leftover? PORT_START("IN0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) @@ -260,7 +261,6 @@ static INPUT_PORTS_START( bishi ) PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START2 ) INPUT_PORTS_END - /* The game will respond to the 'player 2' inputs from the normal input define if mapped, however, the game will function in an abnormal way as the game code isn't designed to handle it. The 'player 3' inputs from @@ -361,6 +361,76 @@ static INPUT_PORTS_START( bishi2p ) PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED ) // 'p2' START INPUT_PORTS_END +static INPUT_PORTS_START( dobouchn ) + PORT_INCLUDE( bishi ) + + PORT_MODIFY("IN0") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_MODIFY("INPUTS") + PORT_BIT( 0x001f, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 Shoot") + PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_MODIFY("SYSTEM") + PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("M. Ack") // ??? + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_NAME("Coin 2 (Medal)") + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0xf000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_MODIFY("DSW") + PORT_DIPNAME( 0x07, 0x07, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:1,2,3") + PORT_DIPSETTING( 0x00, "5 Coins / 2 Credits" ) + PORT_DIPSETTING( 0x01, DEF_STR( 4C_3C ) ) + PORT_DIPSETTING( 0x02, DEF_STR( 2C_3C ) ) + PORT_DIPSETTING( 0x03, DEF_STR( 5C_1C ) ) + PORT_DIPSETTING( 0x04, DEF_STR( 4C_1C ) ) + PORT_DIPSETTING( 0x05, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x06, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x07, DEF_STR( 1C_1C ) ) + PORT_DIPUNUSED_DIPLOC( 0x08, 0x08, "SW1:4" ) + PORT_DIPNAME( 0x70, 0x70, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:5,6,7") + PORT_DIPSETTING( 0x00, "15 Medals" ) + PORT_DIPSETTING( 0x10, "13 Medals" ) + PORT_DIPSETTING( 0x20, "11 Medals" ) + PORT_DIPSETTING( 0x30, "9 Medals" ) + PORT_DIPSETTING( 0x40, "7 Medals" ) + PORT_DIPSETTING( 0x50, "5 Medals" ) + PORT_DIPSETTING( 0x60, "3 Medals" ) + PORT_DIPSETTING( 0x70, "2 Medals" ) + PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW1:8" ) + + PORT_DIPNAME( 0x0f00, 0x0f00, "Payout" ) PORT_DIPLOCATION("SW2:1,2,3,4") + PORT_DIPSETTING( 0x000, "90%" ) + PORT_DIPSETTING( 0x100, "85%" ) + PORT_DIPSETTING( 0x200, "80%" ) + PORT_DIPSETTING( 0x300, "75%" ) + PORT_DIPSETTING( 0x400, "70%" ) + PORT_DIPSETTING( 0x500, "65%" ) + PORT_DIPSETTING( 0x600, "60%" ) + PORT_DIPSETTING( 0x700, "55%" ) + PORT_DIPSETTING( 0x800, "50%" ) + PORT_DIPSETTING( 0x900, "45%" ) + PORT_DIPSETTING( 0xa00, "40%" ) + PORT_DIPSETTING( 0xb00, "35%" ) + PORT_DIPSETTING( 0xc00, "30%" ) + PORT_DIPSETTING( 0xd00, "25%" ) + PORT_DIPSETTING( 0xe00, "20%" ) + PORT_DIPSETTING( 0xf00, "15%" ) + PORT_DIPNAME( 0x3000, 0x3000, "Play Timer" ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPSETTING( 0x0000, "30 seconds" ) + PORT_DIPSETTING( 0x1000, "24 seconds" ) + PORT_DIPSETTING( 0x2000, "18 seconds" ) + PORT_DIPSETTING( 0x3000, "12 seconds" ) + // TODO: needs NVRAM hookup and default hookup + PORT_DIPNAME( 0x4000, 0x0000, "Backup RAM clear" ) PORT_DIPLOCATION("SW2:7") + PORT_DIPSETTING( 0x4000, DEF_STR( No ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( Yes ) ) + PORT_DIPNAME( 0x8000, 0x0000, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8") + PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) +INPUT_PORTS_END void bishi_state::machine_start() { @@ -414,6 +484,13 @@ static MACHINE_CONFIG_START( bishi ) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( dobouchn, bishi ) +// TODO: change accordingly (ASCII charset definitely not 8bpp, 5bpp perhaps?) + MCFG_DEVICE_MODIFY("k056832") +// MCFG_K056832_CB(bishi_state, dobouchn_tile_callback) + MCFG_K056832_CONFIG("gfx1", K056832_BPP_8, 1, 0, "none") +MACHINE_CONFIG_END + // ROM definitions @@ -507,8 +584,13 @@ ROM_START( dobouchn ) ROM_LOAD16_WORD_SWAP( "640-a05-2n.bin", 0x000000, 0x080000, CRC(7643dbc6) SHA1(3b55a782f04a741088b93954279b35c1c90af622) ) ROM_REGION( 0x200000, "gfx1", 0 ) + // makes GFX ROM test to pass + // must return 0xf0c3 and 0xee9e, check snippets at 0x2e1c and 0x2e42 + // TODO: might require a different K056832_rom_r callback instead ROM_LOAD16_BYTE( "640-a06-14n.bin", 0x000000, 0x080000, CRC(c6c5016c) SHA1(ad0b5258e2c1d0ba95dfc0d8fc6332b524f2c1e2) ) - ROM_LOAD16_BYTE( "640-a07-17n.bin", 0x080000, 0x080000, CRC(614fee32) SHA1(080fea72c0417752eb0a0b109b524d87379b2921) ) + ROM_RELOAD( 0x100001, 0x080000 ) + ROM_LOAD16_BYTE( "640-a07-17n.bin", 0x000001, 0x080000, CRC(614fee32) SHA1(080fea72c0417752eb0a0b109b524d87379b2921) ) + ROM_RELOAD( 0x100000, 0x080000 ) // dummy region (game has no sprites, but we want to use the GX mixer) ROM_REGION( 0x80000, "gfx2", ROMREGION_ERASE00 ) @@ -518,8 +600,8 @@ ROM_START( dobouchn ) ROM_LOAD( "640-a02-4f.bin", 0x080000, 0x080000, CRC(ab6593f5) SHA1(95907ee4a2cdf3bf27b7c0c1283b2bc36b868d9d) ) ROM_END -GAME( 1996, bishi, 0, bishi, bishi, bishi_state, 0, ROT0, "Konami", "Bishi Bashi Championship Mini Game Senshuken (ver JAA, 3 Players)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1998, sbishi, 0, bishi, bishi2p, bishi_state, 0, ROT0, "Konami", "Super Bishi Bashi Championship (ver JAA, 2 Players)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1998, sbishik, sbishi, bishi, bishi, bishi_state, 0, ROT0, "Konami", "Super Bishi Bashi Championship (ver KAB, 3 Players)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1998, sbishika, sbishi, bishi, bishi, bishi_state, 0, ROT0, "Konami", "Super Bishi Bashi Championship (ver KAA, 3 Players)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1996, dobouchn, 0, bishi, bishi, bishi_state, 0, ROT0, "Konami", "Dobou-Chan (ver JAA)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1996, bishi, 0, bishi, bishi, bishi_state, 0, ROT0, "Konami", "Bishi Bashi Championship Mini Game Senshuken (ver JAA, 3 Players)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1998, sbishi, 0, bishi, bishi2p, bishi_state, 0, ROT0, "Konami", "Super Bishi Bashi Championship (ver JAA, 2 Players)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1998, sbishik, sbishi, bishi, bishi, bishi_state, 0, ROT0, "Konami", "Super Bishi Bashi Championship (ver KAB, 3 Players)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1998, sbishika, sbishi, bishi, bishi, bishi_state, 0, ROT0, "Konami", "Super Bishi Bashi Championship (ver KAA, 3 Players)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1996, dobouchn, 0, dobouchn, dobouchn, bishi_state, 0, ROT0, "Konami", "Dobou-Chan (ver JAA)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/blockhl.cpp b/src/mame/drivers/blockhl.cpp index 3d53d8a2f5a..1aa28bc2aa9 100644 --- a/src/mame/drivers/blockhl.cpp +++ b/src/mame/drivers/blockhl.cpp @@ -279,8 +279,8 @@ static MACHINE_CONFIG_START( blockhl ) MCFG_DEVICE_ADD("bank5800", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank5800_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(12) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(12) MCFG_ADDRESS_MAP_BANK_STRIDE(0x0800) MCFG_CPU_ADD("audiocpu", Z80, XTAL_3_579545MHz) diff --git a/src/mame/drivers/bloodbro.cpp b/src/mame/drivers/bloodbro.cpp index aec77b66985..b9660c759c7 100644 --- a/src/mame/drivers/bloodbro.cpp +++ b/src/mame/drivers/bloodbro.cpp @@ -10,9 +10,8 @@ driver by Carlos A. Lozano Baides TODO: West Story: -- sound (still has IRQ problems) -- some bad sprites (2 bad sprite roms, should the actual decoded data match?) - +- sound (still has IRQ problems) - seems way too fast but using actual + measurements from a real PCB Blood Bros (c) 1990 Nihon System [Seibu hardware] ----------- @@ -23,11 +22,6 @@ The manual states: This works for all sets and the bootleg. -Fabtek licensed this game for the U.S. along with other games by Seibu and TAD. -Though no Fabtek-licensed set has been dumped yet, and the program code does -not appear to test a region byte, the TAD strings displayed on the title screen -are both space-justified to the same length as the unused string "U.S. LICENSEE -FABTEK, INC." Sky Smasher (c) 1990 Nihon System [Seibu hardware] ----------- @@ -127,6 +121,20 @@ Stephh's notes (based on the games M68000 code and some tests) : DIP locations verified for Blood Bros. & Sky Smasher via manual & DIP-SW setting screens at power up. +Actual clock measurements from the Datsu bootleg PCB: + +CPUs: + 68000 @ 10MHz (20MHz/2) + Z80 @ 5MHz (20MHz/4) + +Sound: + OKI MSMS6295 @ 1.250MHz (20MHz/16), PIN7 is HIGH + YM3812 @ ~4.9MHz (20MHz/4 or 4.7017MHz = 9.8034MHz OSC / 2) + +Video: + H-SYNC @ 15.62KHz + V-SYNC @ 59Hz + **************************************************************************/ #include "emu.h" @@ -561,6 +569,7 @@ static MACHINE_CONFIG_DERIVED( weststry, bloodbro ) MCFG_CPU_VBLANK_INT_DRIVER("screen", bloodbro_state, irq6_line_hold) MCFG_CPU_MODIFY("audiocpu") + MCFG_CPU_CLOCK(XTAL_20MHz/4) /* 5MHz - verified on PCB */ MCFG_CPU_PROGRAM_MAP(weststry_sound_map) MCFG_GFXDECODE_MODIFY("gfxdecode", weststry) @@ -570,12 +579,18 @@ static MACHINE_CONFIG_DERIVED( weststry, bloodbro ) // Bootleg video hardware is non-Seibu MCFG_SCREEN_MODIFY("screen") + MCFG_SCREEN_REFRESH_RATE(59) /* verified on PCB */ MCFG_SCREEN_UPDATE_DRIVER(bloodbro_state, screen_update_weststry) MCFG_DEVICE_REMOVE("crtc") // Bootleg sound hardware is close copy of Seibu, but uses different interrupts - MCFG_SOUND_MODIFY("ymsnd") + + MCFG_OKIM6295_REPLACE("oki", XTAL_20MHz/16, PIN7_HIGH) /* 1.25MHz - verified on PCB */ + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) + + MCFG_SOUND_REPLACE("ymsnd", YM3812, XTAL_20MHz/4) /* ~4.9MHz - see notes at top */ MCFG_YM3812_IRQ_HANDLER(WRITELINE(bloodbro_state, weststry_opl_irq_w)) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) MCFG_DEVICE_MODIFY("seibu_sound") MCFG_SEIBU_SOUND_YM_WRITE_CB(WRITE8(bloodbro_state, weststry_opl_w)) @@ -595,10 +610,10 @@ MACHINE_CONFIG_END ROM_START( bloodbro ) ROM_REGION( 0x80000, "maincpu", 0 ) - ROM_LOAD16_BYTE( "2j.u021.7n", 0x00001, 0x20000, CRC(c0fdc3e4) SHA1(31968f693de2054a0c8ba50a8d44a371dd9c2848) ) - ROM_LOAD16_BYTE( "1j.u022.8n", 0x00000, 0x20000, CRC(2d7e0fdf) SHA1(8fe22d8a1ef7d562a475a5b6c98303b0cb1af561) ) - ROM_LOAD16_BYTE( "bb_04.u023.7l", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) - ROM_LOAD16_BYTE( "bb_03.u024.8l", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) + ROM_LOAD16_BYTE( "2.u021.7n", 0x00001, 0x20000, CRC(204dca6e) SHA1(f04cb2116d699ac2deec2d55597beb5d7b3dc793) ) + ROM_LOAD16_BYTE( "1.u022.8n", 0x00000, 0x20000, CRC(ac6719e7) SHA1(bcefd61ed5d2f5eeb4424243f03037c7d123b9f6) ) + ROM_LOAD16_BYTE( "4.u023.7l", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) + ROM_LOAD16_BYTE( "3.u024.8l", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) ROM_REGION( 0x20000, "audiocpu", 0 ) ROM_LOAD( "bb_07.u1016.6a", 0x000000, 0x08000, CRC(411b94e8) SHA1(6968441f64212c0935afeca68f07deaadf86d614) ) @@ -622,12 +637,12 @@ ROM_START( bloodbro ) ROM_LOAD( "cb006.u083.6c", 0x0000, 0x0100, CRC(b2b89a74) SHA1(1878823801048d677aef9702feedd5bf775e62d0) ) // N82S135N ROM_END -ROM_START( bloodbroa ) +ROM_START( bloodbroj ) ROM_REGION( 0x80000, "maincpu", 0 ) - ROM_LOAD16_BYTE( "2j_a.u021.7n", 0x00001, 0x20000, CRC(e8ca21b8) SHA1(65330368c29ec64ca03124d28a7f8b49d7a15566) ) - ROM_LOAD16_BYTE( "1j_a.u022.8n", 0x00000, 0x20000, CRC(6b28cfc7) SHA1(dedd06cab61381f3e27dc14315f283d707d06bcb) ) - ROM_LOAD16_BYTE( "bb_04.u023.7l", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) - ROM_LOAD16_BYTE( "bb_03.u024.8l", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) + ROM_LOAD16_BYTE( "2j_a.u021.7n", 0x00001, 0x20000, CRC(e8ca21b8) SHA1(65330368c29ec64ca03124d28a7f8b49d7a15566) ) + ROM_LOAD16_BYTE( "1j_a.u022.8n", 0x00000, 0x20000, CRC(6b28cfc7) SHA1(dedd06cab61381f3e27dc14315f283d707d06bcb) ) + ROM_LOAD16_BYTE( "4.u023.7l", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) + ROM_LOAD16_BYTE( "3.u024.8l", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) ROM_REGION( 0x20000, "audiocpu", 0 ) ROM_LOAD( "bb_07.u1016.6a", 0x000000, 0x08000, CRC(411b94e8) SHA1(6968441f64212c0935afeca68f07deaadf86d614) ) @@ -651,12 +666,12 @@ ROM_START( bloodbroa ) ROM_LOAD( "cb006.u083.6c", 0x0000, 0x0100, CRC(b2b89a74) SHA1(1878823801048d677aef9702feedd5bf775e62d0) ) // N82S135N ROM_END -ROM_START( bloodbrob ) +ROM_START( bloodbroja ) ROM_REGION( 0x80000, "maincpu", 0 ) - ROM_LOAD16_BYTE( "bloodbros02.u021.7n", 0x00001, 0x20000, CRC(204dca6e) SHA1(f04cb2116d699ac2deec2d55597beb5d7b3dc793) ) - ROM_LOAD16_BYTE( "bloodbros01.u022.8n", 0x00000, 0x20000, CRC(ac6719e7) SHA1(bcefd61ed5d2f5eeb4424243f03037c7d123b9f6) ) - ROM_LOAD16_BYTE( "bb_04.u023.7l", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) - ROM_LOAD16_BYTE( "bb_03.u024.8l", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) + ROM_LOAD16_BYTE( "2j.u021.7n", 0x00001, 0x20000, CRC(c0fdc3e4) SHA1(31968f693de2054a0c8ba50a8d44a371dd9c2848) ) + ROM_LOAD16_BYTE( "1j.u022.8n", 0x00000, 0x20000, CRC(2d7e0fdf) SHA1(8fe22d8a1ef7d562a475a5b6c98303b0cb1af561) ) + ROM_LOAD16_BYTE( "4.u023.7l", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) + ROM_LOAD16_BYTE( "3.u024.8l", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) ROM_REGION( 0x20000, "audiocpu", 0 ) ROM_LOAD( "bb_07.u1016.6a", 0x000000, 0x08000, CRC(411b94e8) SHA1(6968441f64212c0935afeca68f07deaadf86d614) ) @@ -680,13 +695,41 @@ ROM_START( bloodbrob ) ROM_LOAD( "cb006.u083.6c", 0x0000, 0x0100, CRC(b2b89a74) SHA1(1878823801048d677aef9702feedd5bf775e62d0) ) // N82S135N ROM_END +ROM_START( bloodbrou ) + ROM_REGION( 0x80000, "maincpu", 0 ) + ROM_LOAD16_BYTE( "2u.u021.7n", 0x00001, 0x20000, CRC(45186bd3) SHA1(414e2d048b5266a932e70ec27b776833090b3cda) ) + ROM_LOAD16_BYTE( "1u.u022.8n", 0x00000, 0x20000, CRC(f2cb95c1) SHA1(c047a6a222087bfea4229d45a115f0d89f112985) ) + ROM_LOAD16_BYTE( "4.u023.7l", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) + ROM_LOAD16_BYTE( "3.u024.8l", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) + + ROM_REGION( 0x20000, "audiocpu", 0 ) + ROM_LOAD( "bb_07.u1016.6a", 0x000000, 0x08000, CRC(411b94e8) SHA1(6968441f64212c0935afeca68f07deaadf86d614) ) + ROM_CONTINUE( 0x010000, 0x08000 ) + ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) + + ROM_REGION( 0x20000, "gfx1", 0 ) + ROM_LOAD( "bb_05.u061.6f", 0x00000, 0x10000, CRC(04ba6d19) SHA1(7333075c3323756d51917418b5234d785a9bee00) ) /* characters */ + ROM_LOAD( "bb_06.u063.6d", 0x10000, 0x10000, CRC(7092e35b) SHA1(659d30b2e2fd9ffa34a47e98193c8f0a87ac1315) ) + + ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_LOAD( "blood_bros_bk__(c)1990_tad_corp.u064.4d", 0x00000, 0x100000, CRC(1aa87ee6) SHA1(e7843c1e8a0f3a685f0b5d6e3a2eb3176c410847) ) /* Background+Foreground */ + + ROM_REGION( 0x100000, "gfx3", 0 ) + ROM_LOAD( "blood_bros_obj__(c)1990_tad_corp.u078.2n", 0x00000, 0x100000, CRC(d27c3952) SHA1(de7306432b682f238b911507ad7aa2fa8acbee80) ) /* sprites */ + + ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM samples */ + ROM_LOAD( "bb_08.u095.5a", 0x00000, 0x20000, CRC(deb1b975) SHA1(08f2e9a0a23171201b71d381d091edcd3787c287) ) + + ROM_REGION( 0x0100, "proms", 0 ) + ROM_LOAD( "cb006.u083.6c", 0x0000, 0x0100, CRC(b2b89a74) SHA1(1878823801048d677aef9702feedd5bf775e62d0) ) // N82S135N +ROM_END -ROM_START( weststry ) +ROM_START( weststory ) ROM_REGION( 0x80000, "maincpu", 0 ) /* 64k for cpu code; based on bloodbrob */ ROM_LOAD16_BYTE( "ws13.bin", 0x00001, 0x20000, CRC(158e302a) SHA1(52cc1bf526424ff025a6b79f3fc7bba4b9bbfcbb) ) ROM_LOAD16_BYTE( "ws15.bin", 0x00000, 0x20000, CRC(672e9027) SHA1(71cb9fcef04edb972ba88de45d605dcff539ea2d) ) - ROM_LOAD16_BYTE( "bb_04.bin", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) - ROM_LOAD16_BYTE( "bb_03.bin", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) + ROM_LOAD16_BYTE( "ws14.bin", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) + ROM_LOAD16_BYTE( "ws16.bin", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) ROM_REGION( 0x20000, "audiocpu", 0 ) /* 64k for sound cpu code; based on different revision of original Seibu code */ ROM_LOAD( "ws17.bin", 0x000000, 0x08000, CRC(e00a8f09) SHA1(e7247ce0ab99d0726f31dee5de5ba33f4ebd183e) ) @@ -714,17 +757,63 @@ ROM_START( weststry ) ROM_LOAD( "ws08.bin", 0xc0000, 0x20000, CRC(4d6783b3) SHA1(9870fe9570afeff179b6080581fd6bb187898ff0) ) ROM_REGION( 0x100000, "gfx3", ROMREGION_INVERT ) - ROM_LOAD( "ws25.bin", 0x00000, 0x20000, BAD_DUMP CRC(8092e8e9) SHA1(eabe58ac0f88234b0dddf361f56aad509a83012e) ) /* sprites */ - ROM_LOAD( "ws26.bin", 0x20000, 0x20000, BAD_DUMP CRC(f6a1f42c) SHA1(6d5503e1a9b00104970292d22301ed28893c5223) ) + ROM_LOAD( "ws25.bin", 0x00000, 0x20000, CRC(8092e8e9) SHA1(eabe58ac0f88234b0dddf361f56aad509a83012e) ) /* sprites */ + ROM_LOAD( "ws26.bin", 0x20000, 0x20000, CRC(f6a1f42c) SHA1(6d5503e1a9b00104970292d22301ed28893c5223) ) ROM_LOAD( "ws23.bin", 0x40000, 0x20000, CRC(43d58e24) SHA1(99e255faa9716d9102a1223419084fc209ab4024) ) - ROM_LOAD( "ws24.bin", 0x60000, 0x20000, CRC(20a867ea) SHA1(d3985002931fd4180fc541d61a94371871f3709d) ) - ROM_LOAD( "ws21.bin", 0x80000, 0x20000, CRC(e23d7296) SHA1(33bbced960be22efc7d2681e06a27feba09e0fc0) ) + ROM_LOAD( "ws24.bin", 0x60000, 0x20000, CRC(20a867ea) SHA1(d3985002931fd4180fc541d61a94371871f3709d) ) /* if the original MASK rom is converted then offset 1ECFE = 06 not 02, confirmed on 2 bootlegs, maybe original mask dump is bad? */ + ROM_LOAD( "ws21.bin", 0x80000, 0x20000, CRC(5ef55779) SHA1(8ca786ef56173305a01452defc2be6e775bef374) ) ROM_LOAD( "ws22.bin", 0xa0000, 0x20000, CRC(7150a060) SHA1(73bdd7d6752f7fe9e23073d835dbc468d57865fa) ) ROM_LOAD( "ws19.bin", 0xc0000, 0x20000, CRC(c5dd0a96) SHA1(4696ab1b02d40c54a7dacf0bdf90b624b7d6812e) ) ROM_LOAD( "ws20.bin", 0xe0000, 0x20000, CRC(f1245c16) SHA1(f3941bf5830995f65a5378326fdb72687fbbddcf) ) ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM samples */ - ROM_LOAD( "bb_08.bin", 0x00000, 0x20000, CRC(deb1b975) SHA1(08f2e9a0a23171201b71d381d091edcd3787c287) ) + ROM_LOAD( "ws18.bin", 0x00000, 0x20000, CRC(deb1b975) SHA1(08f2e9a0a23171201b71d381d091edcd3787c287) ) +ROM_END + +ROM_START( weststorya ) + ROM_REGION( 0x80000, "maincpu", 0 ) /* 64k for cpu code; based on bloodbrob */ + ROM_LOAD16_BYTE( "13.bin", 0x00001, 0x20000, CRC(d50e1dfd) SHA1(b0ed90a602ae079c897de6d4cbed61f389f4b220) ) + ROM_LOAD16_BYTE( "15.bin", 0x00000, 0x20000, CRC(fd419c7b) SHA1(f3b23a3f1d550b1739059aeb0fa92076d2b86f69) ) + ROM_LOAD16_BYTE( "ws14.bin", 0x40001, 0x20000, CRC(fd951c2c) SHA1(f4031bf303c67c82f2f78f7456f78382d8c1ac85) ) + ROM_LOAD16_BYTE( "ws16.bin", 0x40000, 0x20000, CRC(18d3c460) SHA1(93b86af1199f0fedeaf1fe64d27ffede4b819e42) ) + + ROM_REGION( 0x20000, "audiocpu", 0 ) /* 64k for sound cpu code; based on different revision of original Seibu code */ + ROM_LOAD( "ws17.bin", 0x000000, 0x08000, CRC(e00a8f09) SHA1(e7247ce0ab99d0726f31dee5de5ba33f4ebd183e) ) + ROM_CONTINUE( 0x010000, 0x08000 ) + ROM_COPY( "audiocpu", 0x000000, 0x018000, 0x08000 ) + + ROM_REGION( 0x20000, "gfx1", 0 ) // first half of these is blank + ROM_LOAD( "ws09.bin", 0x00000, 0x08000, CRC(f05b2b3e) SHA1(6570d795d68655ace9668f32dc0bf5c2d2372411) ) /* characters */ + ROM_CONTINUE( 0x00000, 0x08000 ) + ROM_LOAD( "ws11.bin", 0x08000, 0x08000, CRC(2b10e3d2) SHA1(0f5045615b44e2300745fd3afac7f1441352cca5) ) + ROM_CONTINUE( 0x08000, 0x08000 ) + ROM_LOAD( "ws10.bin", 0x10000, 0x08000, CRC(efdf7c82) SHA1(65392697f56473cfe90d9733b9c49f2da6f9b7e6) ) + ROM_CONTINUE( 0x10000, 0x08000 ) + ROM_LOAD( "ws12.bin", 0x18000, 0x08000, CRC(af993578) SHA1(b250b562deeab3bb2c79002e5e1f0b6e17986848) ) + ROM_CONTINUE( 0x18000, 0x08000 ) + + ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_LOAD( "ws01.bin", 0x20000, 0x20000, CRC(32bda4bc) SHA1(ed0c0740c7af513b341b2b7ff3e0bf6045e930e9) ) /* Foreground */ + ROM_LOAD( "ws03.bin", 0x60000, 0x20000, CRC(046b51f8) SHA1(25af752caebdec762582fc0130cf14546110bb54) ) + ROM_LOAD( "ws02.bin", 0xa0000, 0x20000, CRC(ed9d682e) SHA1(0f79ea09a7af367d175081f72f2bc94f6caad463) ) + ROM_LOAD( "ws04.bin", 0xe0000, 0x20000, CRC(75f082e5) SHA1(b29f09a3cc9a0ac3f982be3981f5e895050c49e8) ) + ROM_LOAD( "ws05.bin", 0x00000, 0x20000, CRC(007c8dc0) SHA1(f44576da3b89d6a889fdb564825ac6ce3bb4cffe) ) /* Background */ + ROM_LOAD( "ws07.bin", 0x40000, 0x20000, CRC(0f0c8d9a) SHA1(f5fe9b5ee4c8ffd7caf5313d13fb5f6e181ed9b6) ) + ROM_LOAD( "ws06.bin", 0x80000, 0x20000, CRC(459d075e) SHA1(24cd0bffe7c5bbccf653ced0b73579059603d187) ) + ROM_LOAD( "ws08.bin", 0xc0000, 0x20000, CRC(4d6783b3) SHA1(9870fe9570afeff179b6080581fd6bb187898ff0) ) + + ROM_REGION( 0x100000, "gfx3", ROMREGION_INVERT ) + ROM_LOAD( "ws25.bin", 0x00000, 0x20000, CRC(8092e8e9) SHA1(eabe58ac0f88234b0dddf361f56aad509a83012e) ) /* sprites */ + ROM_LOAD( "ws26.bin", 0x20000, 0x20000, CRC(f6a1f42c) SHA1(6d5503e1a9b00104970292d22301ed28893c5223) ) + ROM_LOAD( "ws23.bin", 0x40000, 0x20000, CRC(43d58e24) SHA1(99e255faa9716d9102a1223419084fc209ab4024) ) + ROM_LOAD( "ws24.bin", 0x60000, 0x20000, CRC(20a867ea) SHA1(d3985002931fd4180fc541d61a94371871f3709d) ) /* if the original MASK rom is converted then offset 1ECFE = 06 not 02, confirmed on 2 bootlegs, maybe original mask dump is bad? */ + ROM_LOAD( "ws21.bin", 0x80000, 0x20000, CRC(5ef55779) SHA1(8ca786ef56173305a01452defc2be6e775bef374) ) + ROM_LOAD( "ws22.bin", 0xa0000, 0x20000, CRC(7150a060) SHA1(73bdd7d6752f7fe9e23073d835dbc468d57865fa) ) + ROM_LOAD( "ws19.bin", 0xc0000, 0x20000, CRC(c5dd0a96) SHA1(4696ab1b02d40c54a7dacf0bdf90b624b7d6812e) ) + ROM_LOAD( "ws20.bin", 0xe0000, 0x20000, CRC(f1245c16) SHA1(f3941bf5830995f65a5378326fdb72687fbbddcf) ) + + ROM_REGION( 0x40000, "oki", 0 ) /* ADPCM samples */ + ROM_LOAD( "ws18.bin", 0x00000, 0x20000, CRC(deb1b975) SHA1(08f2e9a0a23171201b71d381d091edcd3787c287) ) ROM_END ROM_START( skysmash ) @@ -764,6 +853,16 @@ DRIVER_INIT_MEMBER(bloodbro_state,weststry) z80_rom->as_u8(0x160e) = 0x00; z80_rom->as_u8(0x1610) = 0x00; + + uint8_t *sprites = memregion("gfx3")->base(); + + for (int i = 0; i < 0x40000; i++) + { + /* sprite roms ws25 and ws26 have 2 bits swapped + there is also an address swap but that is currently handled in the video implementation */ + sprites[i] = BITSWAP8(sprites[i],7,6,4,5,3,2,1,0); + } + m_weststry_opl_irq = false; m_weststry_soundnmi_mask = true; @@ -774,8 +873,10 @@ DRIVER_INIT_MEMBER(bloodbro_state,weststry) /* Game Drivers */ -GAME( 1990, bloodbro, 0, bloodbro, bloodbro, bloodbro_state, 0, ROT0, "TAD Corporation", "Blood Bros. (set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1990, bloodbroa,bloodbro, bloodbro, bloodbro, bloodbro_state, 0, ROT0, "TAD Corporation", "Blood Bros. (set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1990, bloodbrob,bloodbro, bloodbro, bloodbro, bloodbro_state, 0, ROT0, "TAD Corporation", "Blood Bros. (set 3)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1990, weststry, bloodbro, weststry, weststry, bloodbro_state, weststry, ROT0, "bootleg (Datsu)", "West Story (bootleg of Blood Bros.)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) -GAME( 1990, skysmash, 0, skysmash, skysmash, bloodbro_state, 0, ROT270, "Nihon System", "Sky Smasher", MACHINE_SUPPORTS_SAVE ) +GAME( 1990, bloodbro, 0, bloodbro, bloodbro, bloodbro_state, 0, ROT0, "TAD Corporation", "Blood Bros. (World?)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, bloodbroj, bloodbro, bloodbro, bloodbro, bloodbro_state, 0, ROT0, "TAD Corporation", "Blood Bros. (Japan, rev A)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, bloodbroja, bloodbro, bloodbro, bloodbro, bloodbro_state, 0, ROT0, "TAD Corporation", "Blood Bros. (Japan)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, bloodbrou, bloodbro, bloodbro, bloodbro, bloodbro_state, 0, ROT0, "TAD Corporation (Fabtek license)", "Blood Bros. (US)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, weststory, bloodbro, weststry, weststry, bloodbro_state, weststry, ROT0, "bootleg (Datsu)", "West Story (bootleg of Blood Bros., set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, weststorya, bloodbro, weststry, weststry, bloodbro_state, weststry, ROT0, "bootleg (Datsu)", "West Story (bootleg of Blood Bros., set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, skysmash, 0, skysmash, skysmash, bloodbro_state, 0, ROT270, "Nihon System", "Sky Smasher", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/bml3.cpp b/src/mame/drivers/bml3.cpp index 18ac954bf63..60f48b3df09 100644 --- a/src/mame/drivers/bml3.cpp +++ b/src/mame/drivers/bml3.cpp @@ -401,8 +401,7 @@ static ADDRESS_MAP_START(bml3_mem, AS_PROGRAM, 8, bml3_state) AM_RANGE(0x4400, 0x9fff) AM_RAM AM_RANGE(0xff40, 0xff46) AM_NOP // lots of unknown reads and writes AM_RANGE(0xffc0, 0xffc3) AM_DEVREADWRITE("pia", pia6821_device, read, write) - AM_RANGE(0xffc4, 0xffc4) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0xffc5, 0xffc5) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0xffc4, 0xffc5) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0xffc6, 0xffc7) AM_READWRITE(bml3_6845_r,bml3_6845_w) // KBNMI - Keyboard "Break" key non-maskable interrupt AM_RANGE(0xffc8, 0xffc8) AM_READ(bml3_keyb_nmi_r) // keyboard nmi diff --git a/src/mame/drivers/bogeyman.cpp b/src/mame/drivers/bogeyman.cpp index bad65f36d24..b1db26a4231 100644 --- a/src/mame/drivers/bogeyman.cpp +++ b/src/mame/drivers/bogeyman.cpp @@ -238,10 +238,12 @@ static MACHINE_CONFIG_START( bogeyman ) // video hardware MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) - MCFG_SCREEN_SIZE(32*8, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) +// MCFG_SCREEN_REFRESH_RATE(60) +// MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) +// MCFG_SCREEN_SIZE(32*8, 32*8) +// MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) + // DECO video CRTC, unverified + MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,384,0,256,272,8,248) MCFG_SCREEN_UPDATE_DRIVER(bogeyman_state, screen_update) MCFG_SCREEN_PALETTE("palette") @@ -253,11 +255,12 @@ static MACHINE_CONFIG_START( bogeyman ) // sound hardware MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("ay1", AY8910, 1500000) /* Verified */ + // verified to be YM2149s from PCB pic + MCFG_SOUND_ADD("ay1", YM2149, 1500000) /* Verified */ MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(bogeyman_state, colbank_w)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30) - MCFG_SOUND_ADD("ay2", AY8910, 1500000) /* Verified */ + MCFG_SOUND_ADD("ay2", YM2149, 1500000) /* Verified */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30) MACHINE_CONFIG_END diff --git a/src/mame/drivers/bwing.cpp b/src/mame/drivers/bwing.cpp index 26226d1cb7b..270a84903f0 100644 --- a/src/mame/drivers/bwing.cpp +++ b/src/mame/drivers/bwing.cpp @@ -377,8 +377,8 @@ static MACHINE_CONFIG_START( bwing ) MCFG_DEVICE_ADD("vrambank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(15) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(15) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) // video hardware diff --git a/src/mame/drivers/c10.cpp b/src/mame/drivers/c10.cpp index 7128a632e2f..b0cf1d5b62f 100644 --- a/src/mame/drivers/c10.cpp +++ b/src/mame/drivers/c10.cpp @@ -1,16 +1,20 @@ // license:BSD-3-Clause // copyright-holders:Robbbert -/*************************************************************************** +/***************************************************************************************************** - Cromemco C-10 Personal Computer +Cromemco C-10 Personal Computer - 30/08/2010 Skeleton driver +2010-08-30 Skeleton driver - Driver currently gets to a loop where it waits for an interrupt. - The interrupt routine presumably writes to FE69 which the loop is - constantly looking at. +Photos show: Intersil 74954-1, Mostek MK3880N-4 (Z80A), CROMEMCO 011-0082-01, CROMEMCO 011-0095, + Intel P8275-2, AM92128BPC (16K ROM), NEC D8257C-5, CROMEMCO 011-0083, WDC FD1793B-02, + 2x 8251. Crystals: 8MHz, 13.028MHz -****************************************************************************/ +Driver currently gets to a loop where it waits for an interrupt. +The interrupt routine presumably writes to FE69 which the loop is +constantly looking at. + +*****************************************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" @@ -151,7 +155,7 @@ GFXDECODE_END static MACHINE_CONFIG_START( c10 ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", Z80, XTAL_16MHz / 4) + MCFG_CPU_ADD("maincpu", Z80, XTAL_8MHz / 2) MCFG_CPU_PROGRAM_MAP(c10_mem) MCFG_CPU_IO_MAP(c10_io) @@ -176,10 +180,10 @@ DRIVER_INIT_MEMBER(c10_state,c10) /* ROM definition */ ROM_START( c10 ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "c10_cros.bin", 0x8000, 0x4000, CRC(2ccf5983) SHA1(52f7c497f5284bf5df9eb0d6e9142bb1869d8c24)) + ROM_LOAD( "502-0055.ic16", 0x8000, 0x4000, CRC(2ccf5983) SHA1(52f7c497f5284bf5df9eb0d6e9142bb1869d8c24)) ROM_REGION( 0x2000, "chargen", 0 ) - ROM_LOAD( "c10_char.bin", 0x0000, 0x2000, CRC(cb530b6f) SHA1(95590bbb433db9c4317f535723b29516b9b9fcbf)) + ROM_LOAD( "c10_char.ic9", 0x0000, 0x2000, CRC(cb530b6f) SHA1(95590bbb433db9c4317f535723b29516b9b9fcbf)) ROM_END /* Driver */ diff --git a/src/mame/drivers/c65.cpp b/src/mame/drivers/c65.cpp index 0dee7a7ce6b..3f39e5ba2c4 100644 --- a/src/mame/drivers/c65.cpp +++ b/src/mame/drivers/c65.cpp @@ -6,10 +6,6 @@ C=65 / C=64DX (c) 1991 Commodore Attempt at rewriting the driver ... -TODO: -- I need to subtract border color to -1 in order to get blue color (-> register is 6 and blue color is 5 in palette array). - Also top-left logo seems to draw wrong palette for entries 4,5,6,7. CPU core bug? - Note: - VIC-4567 will be eventually be added via compile switch, once that I get the hang of the system (and checking where the old code fails @@ -62,13 +58,16 @@ public: uint8_t *m_iplrom; uint8_t m_keyb_input[10]; - uint8_t m_keyb_mux; + uint8_t m_keyb_c0_c7; + uint8_t m_keyb_c8_c9; DECLARE_READ8_MEMBER(vic4567_dummy_r); DECLARE_WRITE8_MEMBER(vic4567_dummy_w); DECLARE_WRITE8_MEMBER(PalRed_w); DECLARE_WRITE8_MEMBER(PalGreen_w); DECLARE_WRITE8_MEMBER(PalBlue_w); + DECLARE_READ8_MEMBER(uart_r); + DECLARE_WRITE8_MEMBER(uart_w); DECLARE_WRITE8_MEMBER(DMAgic_w); DECLARE_READ8_MEMBER(CIASelect_r); DECLARE_WRITE8_MEMBER(CIASelect_w); @@ -97,6 +96,8 @@ private: uint8_t m_VIC2_IRQPend, m_VIC2_IRQMask; /* 0x20: border color (TODO: different thread?) */ uint8_t m_VIC2_EXTColor; + uint8_t m_VIC2_VS_CB_Base; + uint8_t m_VIC2_BK0_Color; /* 0x30: banking + PAL + EXT SYNC */ uint8_t m_VIC3_ControlA; /* 0x31: video modes */ @@ -125,28 +126,44 @@ int c65_state::inner_y_char(int yoffs) uint32_t c65_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) { - int y,x; - int border_color = m_VIC2_EXTColor & 0xf; + int pixel_width = (m_VIC3_ControlB & 0x80) ? 1 : 2; + int columns = 80 / pixel_width; + + uint8_t *cptr = &m_iplrom[((m_VIC3_ControlA & 0x40) ? 0x9000: 0xd000) + ((m_VIC2_VS_CB_Base & 0x2) << 10)]; // TODO: border area - for(y=0;y<m_screen->height();y++) + for(int y=cliprect.min_y;y<=cliprect.max_y;y++) { - for(x=0;x<m_screen->width();x++) + for(int x=cliprect.min_x;x<=cliprect.max_x;x++) { //int, xi,yi,xm,ym,dot_x; - int xi = inner_x_char(x); + int xi = inner_x_char(x / pixel_width); int yi = inner_y_char(y); - int xm = 7 - (x & 7); + int xm = 7 - ((x / pixel_width) & 7); int ym = (y & 7); - uint8_t tile = m_workram[xi+yi*80+0x800]; - uint8_t attr = m_cram[xi+yi*80]; - if(attr & 0xf0) - attr = machine().rand() & 0xf; + uint8_t tile = m_workram[xi+yi*columns+0x800]; + uint8_t attr = m_cram[xi+yi*columns]; + int foreground_color = attr & 0xf; + int background_color = m_VIC2_BK0_Color & 0xf; + int highlight_color = 0; + + int enable_dot = ((cptr[(tile<<3)+ym] >> xm) & 1); - int enable_dot = ((m_iplrom[(tile<<3)+ym+0xd000] >> xm) & 1); + if (attr & 0x10) + { + if ((machine().time().attoseconds() / (ATTOSECONDS_PER_SECOND / 2)) & 1) + attr &= 0x0f; + else if ((attr & 0xf0) != 0x10) + attr &= ~0x10; + } + + if ((attr & 0x80) && ym == 7) enable_dot = 1; + if (attr & 0x40) highlight_color = 16; + if (attr & 0x20) enable_dot = !enable_dot; + if (attr & 0x10) enable_dot = 0; //if(cliprect.contains(x, y)) - bitmap.pix16(y, x) = m_palette->pen((enable_dot) ? attr & 0xf : border_color); + bitmap.pix16(y, x) = m_palette->pen(highlight_color + ((enable_dot) ? foreground_color : background_color)); //gfx->opaque(bitmap,cliprect,tile,0,0,0,x*8,y*8); @@ -171,6 +188,10 @@ READ8_MEMBER(c65_state::vic4567_dummy_r) return res; case 0x15: return 0xff; // silence log for now + + case 0x18: + return m_VIC2_VS_CB_Base; + case 0x19: return m_VIC2_IRQPend; @@ -180,6 +201,9 @@ READ8_MEMBER(c65_state::vic4567_dummy_r) case 0x20: return m_VIC2_EXTColor; + case 0x21: + return m_VIC2_BK0_Color; + case 0x30: return m_VIC3_ControlA; case 0x31: @@ -195,6 +219,9 @@ WRITE8_MEMBER(c65_state::vic4567_dummy_w) { switch(offset) { + case 0x18: + m_VIC2_VS_CB_Base = data; + break; case 0x19: m_VIC2_IRQPend &= ~data; IRQCheck(0); @@ -206,6 +233,10 @@ WRITE8_MEMBER(c65_state::vic4567_dummy_w) case 0x20: m_VIC2_EXTColor = data & 0xf; break; + case 0x21: + m_VIC2_BK0_Color = data & 0xf; + break; + /* KEY register, handles vic-iii and vic-ii modes via two consecutive writes 0xa5 -> 0x96 vic-iii mode any other write vic-ii mode @@ -250,6 +281,29 @@ WRITE8_MEMBER(c65_state::PalBlue_w) PalEntryFlush(offset); } +READ8_MEMBER(c65_state::uart_r) +{ + switch (offset) + { + case 7: + return ioport("CAPS")->read(); + } + return 0xff; +} + +WRITE8_MEMBER(c65_state::uart_w) +{ + switch (offset) + { + case 7: + m_keyb_c8_c9 = (~data >> 1) & 3; + break; + case 8: + // ddr? + break; + } +} + void c65_state::DMAgicExecute(address_space &space,uint32_t address) { uint8_t cmd;// = space.read_byte(address++); @@ -377,25 +431,34 @@ READ8_MEMBER(c65_state::cia0_porta_r) READ8_MEMBER(c65_state::cia0_portb_r) { - static const char *const c64ports[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7" }; + static const char *const c64ports[] = { "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7" }; + static const char *const c65ports[] = { "C8", "C9" }; uint8_t res; res = 0xff; for(int i=0;i<8;i++) { - m_keyb_input[i] = machine().root_device().ioport(c64ports[i])->read(); + m_keyb_input[i] = ioport(c64ports[i])->read(); - if(m_keyb_mux & 1 << (i)) + if(m_keyb_c0_c7 & 1 << (i)) res &= m_keyb_input[i]; } + for(int i=0;i<2;i++) + { + m_keyb_input[i+8] = ioport(c65ports[i])->read(); + + if(m_keyb_c8_c9 & 1 << (i)) + res &= m_keyb_input[i+8]; + } + return res; } WRITE8_MEMBER(c65_state::cia0_porta_w) { - m_keyb_mux = ~data; - printf("%02x\n",m_keyb_mux); + m_keyb_c0_c7 = ~data; +// printf("%02x\n",m_keyb_c0_c7); } WRITE8_MEMBER(c65_state::cia0_portb_w) @@ -418,7 +481,7 @@ static ADDRESS_MAP_START( c65_map, AS_PROGRAM, 8, c65_state ) AM_RANGE(0x0d300, 0x0d3ff) AM_RAM_WRITE(PalBlue_w) AM_SHARE("bluepal") // 0x0d300, 0x0d3ff Blue Palette // 0x0d400, 0x0d4*f Right SID // 0x0d440, 0x0d4*f Left SID - AM_RANGE(0x0d600, 0x0d6ff) AM_RAM // 0x0d600, 0x0d6** UART + AM_RANGE(0x0d600, 0x0d6ff) AM_READWRITE(uart_r, uart_w) AM_RANGE(0x0d700, 0x0d702) AM_WRITE(DMAgic_w) AM_SHARE("dmalist") // 0x0d700, 0x0d7** DMAgic //AM_RANGE(0x0d703, 0x0d703) AM_READ(DMAgic_r) // 0x0d800, 0x0d8** Color matrix @@ -436,86 +499,108 @@ ADDRESS_MAP_END static INPUT_PORTS_START( c65 ) - PORT_START( "ROW0" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Crsr Down Up") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F5)) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F3)) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F7)) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Crsr Right Left") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_START( "C0" ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INST DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_CHAR(UCHAR_MAMEKEY(INSERT)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Return") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Crsr Right Left") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F7)) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F3)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F5)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Crsr Down Up") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_START( "ROW1" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Shift (Left)") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_START( "C1" ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Shift (Left)") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_START( "ROW2" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_START( "C2" ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') - PORT_START( "ROW3" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_START( "C3" ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') - PORT_START( "ROW4" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_START( "C4" ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') - PORT_START( "ROW5" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CHAR('[') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_START( "C5" ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('+') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(':') PORT_CHAR('[') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_START( "ROW6" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x91 Pi") PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x2191) PORT_CHAR(0x03C0) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('=') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Shift (Right)") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CLR HOME") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(HOME)) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CHAR(']') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('*') + PORT_START( "C6" ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR(0xA3) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('*') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(';') PORT_CHAR(']') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CLR HOME") PORT_CODE(KEYCODE_INSERT) PORT_CHAR(UCHAR_MAMEKEY(HOME)) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Shift (Right)") PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('=') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x91 Pi") PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x2191) PORT_CHAR(0x03C0) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_START( "ROW7" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RUN STOP") PORT_CODE(KEYCODE_HOME) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CBM") PORT_CODE(KEYCODE_LALT) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(UCHAR_SHIFT_2) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x90") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(0x2190) + PORT_START( "C7" ) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xE2\x86\x90") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(0x2190) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CBM") PORT_CODE(KEYCODE_LALT) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RUN STOP") PORT_CODE(KEYCODE_HOME) + PORT_START( "C8" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("NO SCROLL") PORT_CODE(KEYCODE_SCRLOCK) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RALT) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("HELP") PORT_CODE(KEYCODE_F9) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5) PORT_CHAR(UCHAR_MAMEKEY(F9)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6) PORT_CHAR(UCHAR_MAMEKEY(F11)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7) PORT_CHAR(UCHAR_MAMEKEY(F13)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) + + PORT_START( "C9") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("UNKNOWN1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("UNKNOWN2") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("linefeed?") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("cursor left?") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("UNKNOWN5") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("UNKNOWN6") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("UNKNOWN7") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("UNKNOWN8") + + PORT_START( "CAPS" ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CAPS LOCK") PORT_CODE(KEYCODE_F8) PORT_TOGGLE INPUT_PORTS_END @@ -533,7 +618,8 @@ void c65_state::machine_reset() PALETTE_INIT_MEMBER(c65_state, c65) { - // TODO: initial state? + for (int i = 0; i < 0x100; i++) + PalEntryFlush(i); } static const gfx_layout charlayout = @@ -573,9 +659,9 @@ WRITE_LINE_MEMBER(c65_state::cia0_irq) #if 0 if(state) { - static const char *const c64ports[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7" }; + static const char *const c64ports[] = { "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7" }; for(int i=0;i<8;i++) - m_keyb_input[i] = machine().root_device().ioport(c64ports[i])->read(); + m_keyb_input[i] = ioport(c64ports[i])->read(); } #endif // m_cia0_irq = state; @@ -637,20 +723,20 @@ MACHINE_CONFIG_END ROM_START( c65 ) ROM_REGION( 0x20000, "maincpu", 0 ) - ROM_SYSTEM_BIOS( 0, "910111", "V0.9.910111" ) + ROM_SYSTEM_BIOS( 0, "910111", "V0.9.910111" ) // sum16 CAFF, this shows up on the picture from a spare, unused rom on the 20171102 c64dx auction as "390488-02 CAFF" with the 02 scratched off on the chip and 03 written in pen, unclear what the "correct" label is. ROMX_LOAD( "910111.bin", 0x0000, 0x20000, CRC(c5d8d32e) SHA1(71c05f098eff29d306b0170e2c1cdeadb1a5f206), ROM_BIOS(1) ) - ROM_SYSTEM_BIOS( 1, "910523", "V0.9.910523" ) + ROM_SYSTEM_BIOS( 1, "910523", "V0.9.910523" ) // sum16 B96B ROMX_LOAD( "910523.bin", 0x0000, 0x20000, CRC(e8235dd4) SHA1(e453a8e7e5b95de65a70952e9d48012191e1b3e7), ROM_BIOS(2) ) - ROM_SYSTEM_BIOS( 2, "910626", "V0.9.910626" ) + ROM_SYSTEM_BIOS( 2, "910626", "V0.9.910626" ) // sum16 888C ROMX_LOAD( "910626.bin", 0x0000, 0x20000, CRC(12527742) SHA1(07c185b3bc58410183422f7ac13a37ddd330881b), ROM_BIOS(3) ) - ROM_SYSTEM_BIOS( 3, "910828", "V0.9.910828" ) + ROM_SYSTEM_BIOS( 3, "910828", "V0.9.910828" ) // sum16 C9CD ROMX_LOAD( "910828.bin", 0x0000, 0x20000, CRC(3ee40b06) SHA1(b63d970727a2b8da72a0a8e234f3c30a20cbcb26), ROM_BIOS(4) ) - ROM_SYSTEM_BIOS( 4, "911001", "V0.9.911001" ) + ROM_SYSTEM_BIOS( 4, "911001", "V0.9.911001" ) // sum16 4BCF ROMX_LOAD( "911001.bin", 0x0000, 0x20000, CRC(0888b50f) SHA1(129b9a2611edaebaa028ac3e3f444927c8b1fc5d), ROM_BIOS(5) ) ROM_END ROM_START( c64dx ) - ROM_REGION( 0x20000, "maincpu", 0 ) + ROM_REGION( 0x20000, "maincpu", 0 ) // "v0.90.910429", sum16 E96A ROM_LOAD( "910429.bin", 0x0000, 0x20000, CRC(b025805c) SHA1(c3b05665684f74adbe33052a2d10170a1063ee7d) ) ROM_END diff --git a/src/mame/drivers/calomega.cpp b/src/mame/drivers/calomega.cpp index ce4405dc98d..142048db837 100644 --- a/src/mame/drivers/calomega.cpp +++ b/src/mame/drivers/calomega.cpp @@ -830,8 +830,7 @@ static ADDRESS_MAP_START( sys903_map, AS_PROGRAM, 8, calomega_state ) AM_RANGE(0x0881, 0x0881) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w) AM_RANGE(0x08c4, 0x08c7) AM_DEVREADWRITE("pia0", pia6821_device, read, write) AM_RANGE(0x08c8, 0x08cb) AM_DEVREADWRITE("pia1", pia6821_device, read, write) - AM_RANGE(0x08d0, 0x08d0) AM_DEVREADWRITE("acia6850_0", acia6850_device, status_r, control_w) - AM_RANGE(0x08d1, 0x08d1) AM_DEVREADWRITE("acia6850_0", acia6850_device, data_r, data_w) + AM_RANGE(0x08d0, 0x08d1) AM_DEVREADWRITE("acia6850_0", acia6850_device, read, write) AM_RANGE(0x1000, 0x13ff) AM_RAM_WRITE(calomega_videoram_w) AM_SHARE("videoram") AM_RANGE(0x1400, 0x17ff) AM_RAM_WRITE(calomega_colorram_w) AM_SHARE("colorram") AM_RANGE(0x1800, 0x3fff) AM_ROM diff --git a/src/mame/drivers/cat.cpp b/src/mame/drivers/cat.cpp index 9634752eba1..42f61e413f1 100644 --- a/src/mame/drivers/cat.cpp +++ b/src/mame/drivers/cat.cpp @@ -1070,7 +1070,7 @@ static MACHINE_CONFIG_START( cat ) MCFG_VIDEO_START_OVERRIDE(cat_state,cat) - MCFG_MC68681_ADD( "duartn68681", (XTAL_19_968MHz*2)/11 ) // duart is normally clocked by 3.6864mhz xtal, but cat seemingly uses a divider from the main xtal instead which probably yields 3.63054545Mhz. There is a trace to cut and a mounting area to allow using an actual 3.6864mhz xtal if you so desire + MCFG_DEVICE_ADD( "duartn68681", MC68681, (XTAL_19_968MHz*2)/11 ) // duart is normally clocked by 3.6864mhz xtal, but cat seemingly uses a divider from the main xtal instead which probably yields 3.63054545Mhz. There is a trace to cut and a mounting area to allow using an actual 3.6864mhz xtal if you so desire MCFG_MC68681_IRQ_CALLBACK(WRITELINE(cat_state, cat_duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(WRITELINE(cat_state, cat_duart_txa)) MCFG_MC68681_B_TX_CALLBACK(WRITELINE(cat_state, cat_duart_txb)) diff --git a/src/mame/drivers/cave.cpp b/src/mame/drivers/cave.cpp index 9ab27cc75b2..7734583a4c2 100644 --- a/src/mame/drivers/cave.cpp +++ b/src/mame/drivers/cave.cpp @@ -1155,6 +1155,30 @@ ADDRESS_MAP_END /*************************************************************************** + Pac-Eight +***************************************************************************/ + +//TODO: leds need verifying + +static ADDRESS_MAP_START( paceight_map, AS_PROGRAM, 16, cave_state ) + AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM + AM_RANGE(0x100000, 0x10ffff) AM_RAM AM_SHARE("nvram") // RAM (battery) + AM_RANGE(0x200000, 0x207fff) AM_RAM AM_SHARE("spriteram.0") // Sprites + AM_RANGE(0x208000, 0x20ffff) AM_RAM AM_SHARE("spriteram_2.0") // Sprite bank 2 + AM_RANGE(0x300000, 0x307fff) AM_RAM_WRITE(cave_vram_0_w) AM_SHARE("vram.0") // Layer 0 + AM_RANGE(0x400000, 0x40ffff) AM_RAM AM_SHARE("paletteram.0") // Palette + AM_RANGE(0x500000, 0x500001) AM_READ_PORT("IN0") // Inputs + EEPROM + Hopper + AM_RANGE(0x500002, 0x500003) AM_READ_PORT("IN1") // Inputs + AM_RANGE(0x600000, 0x600005) AM_WRITEONLY AM_SHARE("vctrl.0") // Layer 0 Control + AM_RANGE(0x700000, 0x700007) AM_READ(cave_irq_cause_r) // IRQ Cause + AM_RANGE(0x700068, 0x700069) AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w) // Watchdog + AM_RANGE(0x700000, 0x70007f) AM_WRITEONLY AM_SHARE("videoregs.0") // Video Regs + AM_RANGE(0x800000, 0x800001) AM_DEVREADWRITE8("oki1", okim6295_device, read, write, 0x00ff) // M6295 + AM_RANGE(0xc00000, 0xc00001) AM_WRITE(pacslot_leds_w) // Leds + Hopper + AM_RANGE(0xe00000, 0xe00001) AM_WRITE(tjumpman_eeprom_lsb_w) // EEPROM +ADDRESS_MAP_END + +/*************************************************************************** Uo Poko ***************************************************************************/ @@ -1728,7 +1752,7 @@ static INPUT_PORTS_START( pacslot ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME( "Pac-Man" ) PORT_CODE(KEYCODE_Y) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME( "Bet" ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, cave_state,tjumpman_hopper_r, nullptr) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, cave_state, tjumpman_hopper_r, nullptr) PORT_START("IN1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) @@ -1743,6 +1767,16 @@ static INPUT_PORTS_START( pacslot ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) INPUT_PORTS_END +static INPUT_PORTS_START( paceight ) + PORT_INCLUDE( pacslot ) + + PORT_MODIFY("IN0") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME( "Left" ) PORT_CODE(KEYCODE_Y) + + PORT_MODIFY("IN1") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME( "Right" ) PORT_CODE(KEYCODE_N) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME( "Max Bet" ) +INPUT_PORTS_END static INPUT_PORTS_START( ppsatan ) PORT_START("SYSTEM") // $200000 @@ -2569,7 +2603,10 @@ static MACHINE_CONFIG_START( pacslot ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0) MACHINE_CONFIG_END - +static MACHINE_CONFIG_DERIVED( paceight, pacslot ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(paceight_map) +MACHINE_CONFIG_END /*************************************************************************** Poka Poka Satan ***************************************************************************/ @@ -4244,12 +4281,55 @@ ROM_START( pacslot ) ROM_REGION( 0x117 * 3, "plds", 0 ) ROM_LOAD( "n44u1a.u1", 0x117*0, 0x117, NO_DUMP ) // GAL16V8B-15LP (Protected) ROM_LOAD( "n44u3a.u3", 0x117*1, 0x117, NO_DUMP ) // GAL16V8B-15LP (Protected) - ROM_LOAD( "n44u51a.u51", 0x117*2, 0x117, NO_DUMP ) // GAL16V8B-15LP (Protected) + ROM_LOAD( "n44u51a.u51", 0x117*2, 0x117, CRC(3c5e9bc5) SHA1(b4e04c4fa91ff33542b73971f67e71d13e24c5ec) ) // GAL16V8B-15LP (Protected, dumped from the paceight PCB) ROM_END /*************************************************************************** + Pac-Eight by Namco, 1996 (according to http://pacman.com/ja/museum/index.html) + Namco N-44 EM VIDEO platform, PCB C0348 + + TMP 68HC000P-16 + + 013 9341E7002 + 038 9635WY003 + + OKI M6295 x 2 + + Battery + 93C46 EEPROM (at U24) + + 28MHz XTAL + +***************************************************************************/ + +ROM_START( paceight ) + ROM_REGION( 0x80000, "maincpu", 0 ) /* 68000 code */ + ROM_LOAD16_WORD_SWAP( "pae1-mpro.u41", 0x00000, 0x80000, CRC(bb026f97) SHA1(70d48f05275c64b25f37f03206219ef3ee9c0ee2) ) // 27c240 + + ROM_REGION( 0x100000 * 2, "sprites0", 0 ) /* Sprites: * 2 */ + ROM_LOAD16_BYTE( "pae1-obj0.u52", 0x00000, 0x80000, CRC(2cd99155) SHA1(146ed2b3f2763232a60e6b238a16067d3ccfa959) ) // 27c040 + ROM_LOAD16_BYTE( "pae1-obj1.u53", 0x00001, 0x80000, CRC(9ae2685b) SHA1(5eed5f00d28d803358c8ffaf42c4979af23a0a8c) ) // "" + + ROM_REGION( 0x80000, "layer0", 0 ) /* Layer 0 */ + ROM_LOAD( "pae1-cha0.u60", 0x00000, 0x40000, CRC(757263e3) SHA1(668060e9e209752474f48362752a3f819ff82d72) ) // 27c020? not readable + ROM_LOAD( "pae1-cha1.u61", 0x40000, 0x40000, CRC(0396d241) SHA1(79382805fa4486d8dae792f9afc0f02aee1bbb33) ) // "" + + ROM_REGION( 0x40000, "oki1", 0 ) /* OKIM6295 #1 Samples */ + ROM_LOAD( "pae1-vo10.u27", 0x00000, 0x40000, CRC(0be7b94f) SHA1(4179e2ab2d2d1df0cc6cfd71e277ea114578f147) ) // 27c? not readable + + ROM_REGION( 0x40000, "oki2", ROMREGION_ERASE00 ) /* OKIM6295 #2 Samples */ + // empty ROM socket + + ROM_REGION( 0x117 * 3, "plds", 0 ) + ROM_LOAD( "n44u1c.u1", 0x117*0, 0x117, CRC(903fc2d8) SHA1(becbae356efde873225ef64af462d9702aac03f0) ) // GAL16V8B-15LP + ROM_LOAD( "n44u3c.u3", 0x117*1, 0x117, CRC(72201412) SHA1(6ad7d22e612e27343eac5c38f00d548df644d52c) ) // GAL16V8B-15LP + ROM_LOAD( "n44u51a.u51", 0x117*2, 0x117, CRC(3c5e9bc5) SHA1(b4e04c4fa91ff33542b73971f67e71d13e24c5ec) ) // GAL16V8B-15LP +ROM_END + +/*************************************************************************** + Poka Poka Satan - wack-a-mole game with one frontal upright screen and two table-top touch screens to bang on with plastic "hammers" @@ -5346,7 +5426,8 @@ GAME( 1996, agalletah, agallet, sailormn, cave, cave_state, agallet, RO GAME( 1996, hotdogst, 0, hotdogst, cave, cave_state, hotdogst, ROT90, "Marble", "Hotdog Storm (International)", MACHINE_SUPPORTS_SAVE ) -GAME( 1996, pacslot, 0, pacslot, pacslot, cave_state, tjumpman, ROT0, "Namco", "Pac-Slot", MACHINE_SUPPORTS_SAVE ) +GAME( 1996, pacslot, 0, pacslot, pacslot, cave_state, tjumpman, ROT0, "Namco", "Pac-Slot", MACHINE_SUPPORTS_SAVE ) +GAME( 1996, paceight, 0, paceight, paceight, cave_state, tjumpman, ROT0, "Namco", "Pac-Eight", MACHINE_SUPPORTS_SAVE ) GAME( 1996, ppsatan, 0, ppsatan, ppsatan, cave_state, ppsatan, ROT0, "Kato Seisakujo Co., Ltd.", "Poka Poka Satan (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS ) diff --git a/src/mame/drivers/cb2001.cpp b/src/mame/drivers/cb2001.cpp index 738e4b73ca5..0c0afba925a 100644 --- a/src/mame/drivers/cb2001.cpp +++ b/src/mame/drivers/cb2001.cpp @@ -80,6 +80,7 @@ public: DECLARE_PALETTE_INIT(cb2001); uint32_t screen_update_cb2001(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(vblank_irq); + DECLARE_READ8_MEMBER(irq_ack_r); required_device<cpu_device> m_maincpu; required_device<gfxdecode_device> m_gfxdecode; required_device<palette_device> m_palette; @@ -578,7 +579,7 @@ static ADDRESS_MAP_START( cb2001_io, AS_IO, 16, cb2001_state ) AM_RANGE(0x20, 0x21) AM_DEVREAD8("aysnd", ay8910_device, data_r, 0xff00) AM_RANGE(0x22, 0x23) AM_DEVWRITE8("aysnd", ay8910_device, data_address_w, 0xffff) - AM_RANGE(0x30, 0x31) AM_WRITE(cb2001_vidctrl_w) + AM_RANGE(0x30, 0x31) AM_READ8(irq_ack_r, 0x00ff) AM_WRITE(cb2001_vidctrl_w) AM_RANGE(0x32, 0x33) AM_WRITE(cb2001_vidctrl2_w) ADDRESS_MAP_END @@ -747,7 +748,13 @@ INPUT_PORTS_END INTERRUPT_GEN_MEMBER(cb2001_state::vblank_irq) { - generic_pulse_irq_line(device.execute(), NEC_INPUT_LINE_INTP0, 1); + m_maincpu->set_input_line(NEC_INPUT_LINE_INTP0, ASSERT_LINE); +} + +READ8_MEMBER(cb2001_state::irq_ack_r) +{ + m_maincpu->set_input_line(NEC_INPUT_LINE_INTP0, CLEAR_LINE); + return 0xff; } static const gfx_layout cb2001_layout = diff --git a/src/mame/drivers/cball.cpp b/src/mame/drivers/cball.cpp index 1a389a62907..fe294667f9e 100644 --- a/src/mame/drivers/cball.cpp +++ b/src/mame/drivers/cball.cpp @@ -114,7 +114,7 @@ TIMER_CALLBACK_MEMBER(cball_state::interrupt_callback) { int scanline = param; - generic_pulse_irq_line(*m_maincpu, 0, 1); + m_maincpu->pulse_input_line(0, m_maincpu->minimum_quantum_time()); scanline = scanline + 32; diff --git a/src/mame/drivers/cc40.cpp b/src/mame/drivers/cc40.cpp index bd4aa8d35cc..562f7f0cb9d 100644 --- a/src/mame/drivers/cc40.cpp +++ b/src/mame/drivers/cc40.cpp @@ -381,11 +381,6 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, cc40_state ) AM_RANGE(0xd000, 0xefff) AM_ROMBANK("sysbank") ADDRESS_MAP_END -static ADDRESS_MAP_START( main_io_map, AS_IO, 8, cc40_state ) - AM_RANGE(TMS7000_PORTA, TMS7000_PORTA) AM_READ(keyboard_r) - AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_WRITE(keyboard_w) -ADDRESS_MAP_END - /*************************************************************************** @@ -584,7 +579,8 @@ static MACHINE_CONFIG_START( cc40 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", TMS70C20, XTAL_5MHz / 2) MCFG_CPU_PROGRAM_MAP(main_map) - MCFG_CPU_IO_MAP(main_io_map) + MCFG_TMS7000_IN_PORTA_CB(READ8(cc40_state, keyboard_r)) + MCFG_TMS7000_OUT_PORTB_CB(WRITE8(cc40_state, keyboard_w)) MCFG_NVRAM_ADD_0FILL("sysram.0") MCFG_NVRAM_ADD_0FILL("sysram.1") diff --git a/src/mame/drivers/ccs2810.cpp b/src/mame/drivers/ccs2810.cpp index 0cd00a0b08a..c7120a266e8 100644 --- a/src/mame/drivers/ccs2810.cpp +++ b/src/mame/drivers/ccs2810.cpp @@ -65,6 +65,7 @@ ToDo: #include "emu.h" #include "cpu/z80/z80.h" #include "bus/rs232/rs232.h" +//#include "bus/s100/s100.h" #include "machine/ins8250.h" #include "machine/ram.h" #include "machine/wd_fdc.h" diff --git a/src/mame/drivers/cd2650.cpp b/src/mame/drivers/cd2650.cpp index 88a3dba1c9c..95ffe911d2c 100644 --- a/src/mame/drivers/cd2650.cpp +++ b/src/mame/drivers/cd2650.cpp @@ -2,11 +2,27 @@ // copyright-holders:Robbbert /*************************************************************************** -Central Data cd2650 +Central Data 2650 Computer System 2010-04-08 Skeleton driver. -No info available on this computer apart from a few newsletters. +No info available on this computer apart from a few newsletters and +magazine articles. The computer was described in a series of articles +published between April and June 1977 in Radio-Electronics, which include +supposedly complete schematics and fairly detailed subsystem descriptions. +There is supposed to be a “Computer System Manual” with definitive revised +schematics, but this has not been found yet. + +All signals to and from the 2650 board (including the built-in 300 baud +Kansas City standard cassette tape interface) are passed through six ribbon +cables. Central Data later produced an “extender board” that adapted the +bus signals to a S-100 backplane. This interface was missing a considerable +number of standard S-100 timing signals, though it was compatible at least +with some dynamic RAM boards released by the company. + +The unusual XTAL frequency seems deliberately chosen to produce a vertical +sync rate of exactly 60 Hz. + The system only uses 1000-14FF for videoram and 17F0-17FF for scratch ram. All other ram is optional. @@ -23,15 +39,21 @@ V Verify? Press Esc to exit most commands. TODO -- Lots, probably. The computer is a complete mystery. No manuals or schematics exist. +- Lots, probably. The computer is a complete mystery. No manuals are known to exist. - Cassette doesn't work. ****************************************************************************/ +#define CHARACTER_WIDTH 8 +#define CHARACTER_HEIGHT 8 +#define CHARACTER_LINES 12 + #include "emu.h" #include "cpu/s2650/s2650.h" +//#include "bus/s100/s100.h" #include "imagedev/cassette.h" #include "imagedev/snapquik.h" +#include "machine/74259.h" #include "machine/keyboard.h" #include "sound/beep.h" #include "sound/wave.h" @@ -46,14 +68,13 @@ public: , m_maincpu(*this, "maincpu") , m_p_videoram(*this, "videoram") , m_p_chargen(*this, "chargen") - , m_beep(*this, "beeper") , m_cass(*this, "cassette") { } DECLARE_READ8_MEMBER(keyin_r); - DECLARE_WRITE8_MEMBER(beep_w); void kbd_put(u8 data); + DECLARE_WRITE_LINE_MEMBER(tape_deck_on_w); DECLARE_READ_LINE_MEMBER(cass_r); DECLARE_WRITE_LINE_MEMBER(cass_w); DECLARE_QUICKLOAD_LOAD_MEMBER(cd2650); @@ -65,28 +86,27 @@ private: required_device<cpu_device> m_maincpu; required_shared_ptr<uint8_t> m_p_videoram; required_region_ptr<u8> m_p_chargen; - required_device<beep_device> m_beep; required_device<cassette_image_device> m_cass; }; -WRITE8_MEMBER( cd2650_state::beep_w ) +WRITE_LINE_MEMBER(cd2650_state::tape_deck_on_w) { - if (data & 7) - m_beep->set_state(BIT(data, 3)); + // output polarity not verified + logerror("Cassette tape deck turned %s\n", state ? "on" : "off"); } -WRITE_LINE_MEMBER( cd2650_state::cass_w ) +WRITE_LINE_MEMBER(cd2650_state::cass_w) { m_cass->output(state ? -1.0 : +1.0); } -READ_LINE_MEMBER( cd2650_state::cass_r ) +READ_LINE_MEMBER(cd2650_state::cass_r) { return (m_cass->input() > 0.03) ? 1 : 0; } -READ8_MEMBER( cd2650_state::keyin_r ) +READ8_MEMBER(cd2650_state::keyin_r) { uint8_t ret = m_term_data; m_term_data = ret | 0x80; @@ -95,8 +115,8 @@ READ8_MEMBER( cd2650_state::keyin_r ) static ADDRESS_MAP_START(cd2650_mem, AS_PROGRAM, 8, cd2650_state) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE( 0x0000, 0x03ff) AM_ROM AM_REGION("roms", 0) - AM_RANGE( 0x1000, 0x7fff) AM_RAM AM_SHARE("videoram") + AM_RANGE(0x0000, 0x0fff) AM_ROM AM_REGION("roms", 0) + AM_RANGE(0x1000, 0x7fff) AM_RAM AM_SHARE("videoram") ADDRESS_MAP_END static ADDRESS_MAP_START( cd2650_io, AS_IO, 8, cd2650_state) @@ -105,7 +125,7 @@ static ADDRESS_MAP_START( cd2650_io, AS_IO, 8, cd2650_state) ADDRESS_MAP_END static ADDRESS_MAP_START( cd2650_data, AS_DATA, 8, cd2650_state) - AM_RANGE(S2650_DATA_PORT,S2650_DATA_PORT) AM_READWRITE(keyin_r, beep_w) + AM_RANGE(S2650_DATA_PORT,S2650_DATA_PORT) AM_READ(keyin_r) AM_DEVWRITE("outlatch", f9334_device, write_nibble_d3) ADDRESS_MAP_END /* Input ports */ @@ -116,7 +136,6 @@ INPUT_PORTS_END void cd2650_state::machine_reset() { m_term_data = 0x80; - m_beep->set_state(0); } uint32_t cd2650_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -132,14 +151,14 @@ uint32_t cd2650_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap for (y = 0; y < 16; y++) { - for (ra = 0; ra < 10; ra++) + for (ra = 0; ra < CHARACTER_LINES; ra++) { uint16_t *p = &bitmap.pix16(sy++); for (x = 0; x < 80; x++) { gfx = 0; - if ((ra) && (ra < 9)) + if (ra < CHARACTER_HEIGHT) { mem = offset + y + (x<<4); @@ -148,7 +167,7 @@ uint32_t cd2650_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap chr = m_p_videoram[mem] & 0x3f; - gfx = m_p_chargen[(BITSWAP8(chr,7,6,2,1,0,3,4,5)<<3) | (ra-1) ]; + gfx = m_p_chargen[(BITSWAP8(chr,7,6,2,1,0,3,4,5)<<3) | ra]; } /* Display a scanline of a character */ @@ -261,21 +280,27 @@ QUICKLOAD_LOAD_MEMBER( cd2650_state, cd2650 ) static MACHINE_CONFIG_START( cd2650 ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu",S2650, XTAL_1MHz) + MCFG_CPU_ADD("maincpu", S2650, XTAL_14_192640MHz / 12) // 1.182720MHz according to RE schematic MCFG_CPU_PROGRAM_MAP(cd2650_mem) MCFG_CPU_IO_MAP(cd2650_io) MCFG_CPU_DATA_MAP(cd2650_data) MCFG_S2650_SENSE_INPUT(READLINE(cd2650_state, cass_r)) MCFG_S2650_FLAG_OUTPUT(WRITELINE(cd2650_state, cass_w)) + MCFG_DEVICE_ADD("outlatch", F9334, 0) // IC26 + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE(cd2650_state, tape_deck_on_w)) // TD ON + MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(DEVWRITELINE("beeper", beep_device, set_state)) // OUT6 + // Q1-Q7 = OUT 0-6, not defined in RE + // The connection of OUT6 to a 700-1200 Hz noise generator is suggested + // in Central Data 2650 Newsletter, Volume 1, Issue 3 for use with the + // "Morse Code" program by Mike Durham. + /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ + MCFG_SCREEN_RAW_PARAMS(XTAL_14_192640MHz, 112 * CHARACTER_WIDTH, 0, 80 * CHARACTER_WIDTH, 22 * CHARACTER_LINES, 0, 16 * CHARACTER_LINES) MCFG_SCREEN_UPDATE_DRIVER(cd2650_state, screen_update) - MCFG_SCREEN_SIZE(640, 160) - MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 159) MCFG_SCREEN_PALETTE("palette") + MCFG_GFXDECODE_ADD("gfxdecode", "palette", cd2650) MCFG_PALETTE_ADD_MONOCHROME("palette") @@ -297,7 +322,7 @@ MACHINE_CONFIG_END /* ROM definition */ ROM_START( cd2650 ) - ROM_REGION( 0x0400, "roms", 0 ) + ROM_REGION( 0x1000, "roms", 0 ) ROM_LOAD( "cd2650.rom", 0x0000, 0x0400, CRC(5397328e) SHA1(7106fdb60e1ad2bc5e8e45527f348c23296e8d6a)) ROM_REGION( 0x0600, "chargen", 0 ) @@ -319,4 +344,4 @@ ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1977, cd2650, 0, 0, cd2650, cd2650, cd2650_state, 0, "Central Data", "CD 2650", 0 ) +COMP( 1977, cd2650, 0, 0, cd2650, cd2650, cd2650_state, 0, "Central Data", "2650 Computer System", 0 ) diff --git a/src/mame/drivers/cdc721.cpp b/src/mame/drivers/cdc721.cpp index efcb2f64363..2bf98041385 100644 --- a/src/mame/drivers/cdc721.cpp +++ b/src/mame/drivers/cdc721.cpp @@ -11,6 +11,7 @@ Control Data Corporation CDC 721 Terminal (Viking) #include "emu.h" #include "cpu/z80/z80.h" +#include "video/tms9927.h" #include "screen.h" @@ -19,30 +20,35 @@ class cdc721_state : public driver_device public: cdc721_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) - , m_p_videoram(*this, "videoram") , m_maincpu(*this, "maincpu") , m_p_chargen(*this, "chargen") - { - } + , m_p_videoram(*this, "videoram") + { } uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + DECLARE_DRIVER_INIT(init); DECLARE_PALETTE_INIT(cdc721); +// DECLARE_WRITE8_MEMBER(port70_w) { membank("bankr0")->set_entry(BIT(data, 3)); } private: + u8 m_flashcnt; virtual void machine_reset() override; - required_shared_ptr<uint8_t> m_p_videoram; required_device<cpu_device> m_maincpu; required_region_ptr<u8> m_p_chargen; + required_shared_ptr<u8> m_p_videoram; }; -static ADDRESS_MAP_START( cdc721_mem, AS_PROGRAM, 8, cdc721_state ) - AM_RANGE(0x0000, 0x3fff) AM_ROM AM_REGION("maincpu", 0) - AM_RANGE(0x4000, 0xf097) AM_RAM - AM_RANGE(0xf098, 0xffff) AM_RAM AM_SHARE("videoram") +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, cdc721_state ) + AM_RANGE(0x0000, 0x4fff) AM_ROM AM_REGION("maincpu", 0x10000) +// AM_RANGE(0x0000, 0x4fff) AM_READ_BANK("bankr0") AM_WRITE_BANK("bankw0") + AM_RANGE(0x8000, 0xe10f) AM_RAM + AM_RANGE(0xe110, 0xffff) AM_RAM AM_SHARE("videoram") ADDRESS_MAP_END -static ADDRESS_MAP_START( cdc721_io, AS_IO, 8, cdc721_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, cdc721_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x10, 0x1f) AM_DEVREADWRITE("crtc", tms9927_device, read, write) +// AM_RANGE(0x70, 0x70) AM_WRITE(port70_w) ADDRESS_MAP_END static INPUT_PORTS_START( cdc721 ) @@ -50,6 +56,17 @@ INPUT_PORTS_END void cdc721_state::machine_reset() { +// membank("bankr0")->set_entry(0); +// membank("bankw0")->set_entry(0); +} + +DRIVER_INIT_MEMBER( cdc721_state, init ) +{ +// uint8_t *main = memregion("maincpu")->base(); + +// membank("bankr0")->configure_entry(1, &main[0x14000]); +// membank("bankr0")->configure_entry(0, &main[0x4000]); +// membank("bankw0")->configure_entry(0, &main[0x4000]); } /* F4 Character Displayer */ @@ -80,33 +97,45 @@ PALETTE_INIT_MEMBER( cdc721_state, cdc721 ) uint32_t cdc721_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - uint8_t y,ra,chr,gfx; + uint8_t y,ra,chr,gfx,attr,pen; uint16_t sy=0,ma=0,x; + m_flashcnt++; - for (y = 0; y < 24; y++) + for (y = 0; y < 30; y++) { - for (ra = 3; ra < 13; ra++) + for (ra = 0; ra < 16; ra++) { uint16_t *p = &bitmap.pix16(sy++); for (x = 0; x < 160; x+=2) { + pen = 1; chr = m_p_videoram[x+ma]; - + attr = m_p_videoram[x+ma+1]; gfx = m_p_chargen[chr | (ra << 8) ]; + if (BIT(attr, 0)) // blank + pen = 0; + if (BIT(attr, 1) && (ra == 14)) // underline + gfx = 0xff; + if (BIT(attr, 4)) // dim + pen = 2; + if (BIT(attr, 2)) // rv + gfx ^= 0xff; + if (BIT(attr, 3) && BIT(m_flashcnt, 6)) // blink + gfx = 0; /* Display a scanline of a character */ - *p++ = BIT(gfx, 0); - *p++ = BIT(gfx, 1); - *p++ = BIT(gfx, 2); - *p++ = BIT(gfx, 3); - *p++ = BIT(gfx, 4); - *p++ = BIT(gfx, 5); - *p++ = BIT(gfx, 6); - *p++ = BIT(gfx, 7); + *p++ = BIT(gfx, 0) ? pen : 0; + *p++ = BIT(gfx, 1) ? pen : 0; + *p++ = BIT(gfx, 2) ? pen : 0; + *p++ = BIT(gfx, 3) ? pen : 0; + *p++ = BIT(gfx, 4) ? pen : 0; + *p++ = BIT(gfx, 5) ? pen : 0; + *p++ = BIT(gfx, 6) ? pen : 0; + *p++ = BIT(gfx, 7) ? pen : 0; } } - ma+=160; + ma+=264; } return 0; } @@ -114,31 +143,37 @@ uint32_t cdc721_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap static MACHINE_CONFIG_START( cdc721 ) // basic machine hardware MCFG_CPU_ADD("maincpu", Z80, 4000000) - MCFG_CPU_PROGRAM_MAP(cdc721_mem) - MCFG_CPU_IO_MAP(cdc721_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ MCFG_SCREEN_UPDATE_DRIVER(cdc721_state, screen_update) - MCFG_SCREEN_SIZE(640, 240) - MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 239) + MCFG_SCREEN_SIZE(640, 480) + MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 479) MCFG_SCREEN_PALETTE("palette") MCFG_PALETTE_ADD("palette", 3) MCFG_PALETTE_INIT_OWNER(cdc721_state, cdc721) MCFG_GFXDECODE_ADD("gfxdecode", "palette", cdc721) + + MCFG_DEVICE_ADD("crtc", TMS9927, 2000000) // clock guess + MCFG_TMS9927_CHAR_WIDTH(8) MACHINE_CONFIG_END ROM_START( cdc721 ) - ROM_REGION( 0x6000, "maincpu", 0 ) - ROM_LOAD( "66315359", 0x0000, 0x2000, CRC(20ff3eb4) SHA1(5f15cb14893d75a46dc66d3042356bb054d632c2) ) - ROM_LOAD( "66315361", 0x2000, 0x2000, CRC(21d59d09) SHA1(9c087537d68c600ddf1eb9b009cf458231c279f4) ) - ROM_LOAD( "66315360", 0x4000, 0x1000, CRC(feaa0fc5) SHA1(f06196553a1f10c07b2f7e495823daf7ea26edee) ) // rom @ 4000 - ROM_LOAD( "66307828", 0x5000, 0x1000, CRC(ac97136f) SHA1(0d280e1aa4b9502bd390d260f83af19bf24905cd) ) // keyboard + ROM_REGION( 0x15000, "maincpu", 0 ) + ROM_LOAD( "66315359", 0x10000, 0x2000, CRC(20ff3eb4) SHA1(5f15cb14893d75a46dc66d3042356bb054d632c2) ) + ROM_LOAD( "66315361", 0x12000, 0x2000, CRC(21d59d09) SHA1(9c087537d68c600ddf1eb9b009cf458231c279f4) ) + ROM_LOAD( "66315360", 0x14000, 0x1000, CRC(feaa0fc5) SHA1(f06196553a1f10c07b2f7e495823daf7ea26edee) ) + //ROM_FILL(0x14157,1,0xe0) + + ROM_REGION( 0x1000, "keyboard", 0 ) + ROM_LOAD( "66307828", 0x0000, 0x1000, CRC(ac97136f) SHA1(0d280e1aa4b9502bd390d260f83af19bf24905cd) ) // keyboard lookup ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD( "66315039", 0x0000, 0x1000, CRC(5c9aa968) SHA1(3ec7c5f25562579e6ed3fda7562428ff5e6b9550) ) // chargen + ROM_LOAD( "66315039", 0x0000, 0x1000, CRC(5c9aa968) SHA1(3ec7c5f25562579e6ed3fda7562428ff5e6b9550) ) ROM_END -COMP( 1981, cdc721, 0, 0, cdc721, cdc721, cdc721_state, 0, "Control Data Corporation", "CDC721 Terminal", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) +COMP( 1981, cdc721, 0, 0, cdc721, cdc721, cdc721_state, init, "Control Data Corporation", "CDC721 Terminal", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) diff --git a/src/mame/drivers/cdi.cpp b/src/mame/drivers/cdi.cpp index 1e2acade9cb..f4aab089c3e 100644 --- a/src/mame/drivers/cdi.cpp +++ b/src/mame/drivers/cdi.cpp @@ -1200,8 +1200,8 @@ ROM_START( quizard3 ) /* CD-ROM printed ??/?? */ DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "quizard34", 0, BAD_DUMP SHA1(37ad49b72b5175afbb87141d57bc8604347fe032) ) - ROM_REGION(0x1000, "mcu", 0) - ROM_LOAD( "quizard3_d8751.bin", 0x0000, 0x1000, NO_DUMP ) + ROM_REGION(0x1000, "mcu", 0) // d8751h + ROM_LOAD( "DE132D3.bin", 0x0000, 0x1000, CRC(8858251e) SHA1(2c1005a74bb6f0c2918dff4ab6326528eea48e1f) ) // confirmed good on original hardware ROM_END ROM_START( quizard3_32 ) @@ -1217,8 +1217,8 @@ ROM_START( quizard3_32 ) DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "quizard32", 0, BAD_DUMP SHA1(31e9fa2169aa44d799c37170b238134ab738e1a1) ) - ROM_REGION(0x1000, "mcu", 0) - ROM_LOAD( "quizard3_d8751.bin", 0x0000, 0x1000, NO_DUMP ) + ROM_REGION(0x1000, "mcu", 0) // d8751h + ROM_LOAD( "DE132D3.bin", 0x0000, 0x1000, CRC(8858251e) SHA1(2c1005a74bb6f0c2918dff4ab6326528eea48e1f) ) // confirmed good on original hardware ROM_END diff --git a/src/mame/drivers/cedar_magnet.cpp b/src/mame/drivers/cedar_magnet.cpp index c5cdfb8720e..a9d44f52dd2 100644 --- a/src/mame/drivers/cedar_magnet.cpp +++ b/src/mame/drivers/cedar_magnet.cpp @@ -765,22 +765,22 @@ static MACHINE_CONFIG_START( cedar_magnet ) MCFG_DEVICE_ADD("bank0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(cedar_bank0) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_DEVICE_ADD("mb_sub_ram", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(cedar_magnet_mainboard_sub_ram_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_DEVICE_ADD("mb_sub_pal", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(cedar_magnet_mainboard_sub_pal_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(8+6) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(8+6) MCFG_ADDRESS_MAP_BANK_STRIDE(0x100) MCFG_DEVICE_ADD("z80pio_ic48", Z80PIO, 4000000/2) diff --git a/src/mame/drivers/cfx9850.cpp b/src/mame/drivers/cfx9850.cpp index 945f2df348b..f94172d285b 100644 --- a/src/mame/drivers/cfx9850.cpp +++ b/src/mame/drivers/cfx9850.cpp @@ -158,7 +158,7 @@ static INPUT_PORTS_START(cfx9850) PORT_START("KO2") /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EXE Enter") PORT_CODE(KEYCODE_ENTER) - /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(-) Ares") PORT_CODE(KEYCODE_MINUS) + /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("(-) Ans") PORT_CODE(KEYCODE_MINUS) /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EXP Pi") PORT_CODE(KEYCODE_EQUALS) /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(". SPACE") PORT_CODE(KEYCODE_SPACE) /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("0 Z") PORT_CODE(KEYCODE_Z) @@ -181,37 +181,37 @@ static INPUT_PORTS_START(cfx9850) PORT_BIT(0x83, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO5") - /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DEL DG") PORT_CODE(KEYCODE_BACKSPACE) + /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("DEL INS") PORT_CODE(KEYCODE_BACKSPACE) /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("9 O") PORT_CODE(KEYCODE_O) /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("8 N") PORT_CODE(KEYCODE_N) /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("7 M") PORT_CODE(KEYCODE_M) PORT_BIT(0x87, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO6") - /* KI2 */ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("TAB L") PORT_CODE(KEYCODE_L) + /* KI2 */ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("-> L") PORT_CODE(KEYCODE_L) /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(", K") PORT_CODE(KEYCODE_K) /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME(") x^-1 J") PORT_CODE(KEYCODE_J) - /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("( .. I") PORT_CODE(KEYCODE_I) - /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F<=>0 H") PORT_CODE(KEYCODE_H) + /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("( x^(1/3) I") PORT_CODE(KEYCODE_I) + /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("F<=>D H") PORT_CODE(KEYCODE_H) /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("a b/c G") PORT_CODE(KEYCODE_G) PORT_BIT(0x81, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO7") /* KI2 */ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("tan tan^-1 F") PORT_CODE(KEYCODE_F) - /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("cos cas^-1 E") PORT_CODE(KEYCODE_E) + /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("cos cos^-1 E") PORT_CODE(KEYCODE_E) /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("sin sin^-1 D") PORT_CODE(KEYCODE_D) /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ln e^x C") PORT_CODE(KEYCODE_C) /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("log 10^x B") PORT_CODE(KEYCODE_B) - /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("x,d,t A") PORT_CODE(KEYCODE_A) + /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("x,theta,t A") PORT_CODE(KEYCODE_A) PORT_BIT(0x81, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO8") /* KI2 */ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Right") PORT_CODE(KEYCODE_RIGHT) /* KI3 */ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN) /* KI4 */ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("EXIT QUIT") PORT_CODE(KEYCODE_STOP) - /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("/\\ .. ..") PORT_CODE(KEYCODE_COMMA) - /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("x^2 sqrt ..") PORT_CODE(KEYCODE_SLASH) - /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ALPHA ..-LOCK") PORT_CODE(KEYCODE_CAPSLOCK) + /* KI5 */ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("^ root theta") PORT_CODE(KEYCODE_COMMA) + /* KI6 */ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("x^2 sqrt ro") PORT_CODE(KEYCODE_SLASH) + /* KI7 */ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ALPHA ALPHA-LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_BIT(0x81, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("KO9") diff --git a/src/mame/drivers/champbas.cpp b/src/mame/drivers/champbas.cpp index 112356e9e6c..3e40112eb40 100644 --- a/src/mame/drivers/champbas.cpp +++ b/src/mame/drivers/champbas.cpp @@ -81,6 +81,7 @@ TODO: #include "emu.h" #include "includes/champbas.h" #include "cpu/z80/z80.h" +#include "cpu/m6805/m68705.h" #include "machine/74259.h" #include "machine/gen_latch.h" #include "machine/watchdog.h" @@ -223,6 +224,11 @@ static ADDRESS_MAP_START( champbb2_map, AS_PROGRAM, 8, champbas_state ) AM_IMPORT_FROM( champbasj_map ) ADDRESS_MAP_END +static ADDRESS_MAP_START( tbasebal_map, AS_PROGRAM, 8, champbas_state ) + AM_RANGE(0x7800, 0x7fff) AM_ROM + AM_IMPORT_FROM( champbas_map ) +ADDRESS_MAP_END + // more sprites in exctsccr static ADDRESS_MAP_START( exctsccr_map, AS_PROGRAM, 8, champbas_state ) AM_RANGE(0x7000, 0x7001) AM_UNMAP // aysnd is controlled by audiocpu @@ -614,6 +620,7 @@ static MACHINE_CONFIG_DERIVED( champbasj, champbas ) MCFG_QUANTUM_PERFECT_CPU("alpha_8201:mcu") MACHINE_CONFIG_END + static MACHINE_CONFIG_DERIVED( champbasja, champbas ) /* basic machine hardware */ @@ -636,6 +643,17 @@ static MACHINE_CONFIG_DERIVED( champbb2, champbasj ) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( tbasebal, champbas ) + + /* basic machine hardware */ + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(tbasebal_map) + + MCFG_CPU_ADD("mcu", M68705P3, XTAL_18_432MHz/6) // ?Mhz +MACHINE_CONFIG_END + + + static MACHINE_CONFIG_START( exctsccr ) /* basic machine hardware */ @@ -909,32 +927,30 @@ ROM_START( champbb2 ) ROM_LOAD( "pr5956", 0x0020, 0x100, CRC(872dd450) SHA1(6c1e2c4a2fc072f4bf4996c731adb0b01b347506) ) /* look-up table */ ROM_END -ROM_START( champbb2a ) +ROM_START( tbasebal ) ROM_REGION( 0x10000, "maincpu", 0 ) - ROM_LOAD( "1.bin", 0x0000, 0x2000, CRC(9b75b44d) SHA1(35b67638a5e48cbe999907e3c9c3a33da9d76bba) ) - ROM_LOAD( "2.bin", 0x2000, 0x2000, CRC(736a1b62) SHA1(24c2d57506754ca789b378a595c03b7591eb5b5c) ) - ROM_LOAD( "3.bin", 0x4000, 0x2000, CRC(cf5f28cb) SHA1(d553f2085c9c8c77b241b4239cc1ad1764b490d0) ) - ROM_LOAD( "4.bin", 0x7800, 0x0800, NO_DUMP ) + ROM_LOAD( "1.2E.2764", 0x0000, 0x2000, CRC(9b75b44d) SHA1(35b67638a5e48cbe999907e3c9c3a33da9d76bba) ) + ROM_LOAD( "2_P9.2G.2764", 0x2000, 0x2000, CRC(736a1b62) SHA1(24c2d57506754ca789b378a595c03b7591eb5b5c) ) + ROM_LOAD( "3.2H.2764", 0x4000, 0x2000, CRC(cf5f28cb) SHA1(d553f2085c9c8c77b241b4239cc1ad1764b490d0) ) + ROM_LOAD( "IC2.2764", 0x6000, 0x2000, CRC(aacb9647) SHA1(4f3830ffc18f8578064babbc638efb5a59ef1a3d) ) // on sub-board with MCU - /* not in this set, but probably the same */ ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "epr5933", 0x0000, 0x2000, CRC(26ab3e16) SHA1(019b9d34233a6b7a53e204154b782ceb42915d2b) ) - ROM_LOAD( "epr5934", 0x2000, 0x2000, CRC(7c01715f) SHA1(b15b2001b8c110f2599eee3aeed79f67686ebd7e) ) - ROM_LOAD( "epr5935", 0x4000, 0x2000, CRC(3c911786) SHA1(eea0c467e213d237b5bb9d04b19a418d6090c2dc) ) + ROM_LOAD( "6.2K.2764", 0x0000, 0x2000, CRC(24c482ee) SHA1(c25bdf77014e095fc11a9a6b17f16858f19db451) ) + ROM_LOAD( "7.2L.2764", 0x2000, 0x2000, CRC(f10b148b) SHA1(d66516d509f6f16e51ee59d27c4867e276064c3f) ) + ROM_LOAD( "8.2N.2764", 0x4000, 0x2000, CRC(2dc484dd) SHA1(28bd68c787d7e6989849ca52009948dbd5cdcc79) ) - // the pcb has a 8302 on it, though only the 8201 instructions are used - ROM_REGION( 0x2000, "alpha_8201:mcu", 0 ) - ROM_LOAD( "alpha-8302_44801b35.bin", 0x0000, 0x2000, CRC(edabac6c) SHA1(eaf1c51b63023256df526b0d3fd53cffc919c901) ) + ROM_REGION( 0x0800, "mcu", 0 ) /* MC68705P5 */ + ROM_LOAD( "IC3_mc68705p3_rom.bin", 0x0000, 0x0800, CRC(6b477f5f) SHA1(c773a4bed22106346fb2347b6d5a32958be8213c) ) ROM_REGION( 0x2000, "gfx1", 0 ) // chars + sprites: rearranged by DRIVER_INIT to leave only chars - ROM_LOAD( "epr5936", 0x0000, 0x2000, CRC(c4a4df75) SHA1(7b85dbf405697b0b8881f910c08f6db6c828b19a) ) + ROM_LOAD( "4.5E.2764", 0x0000, 0x2000, CRC(c4a4df75) SHA1(7b85dbf405697b0b8881f910c08f6db6c828b19a) ) ROM_REGION( 0x2000, "gfx2", 0 ) // chars + sprites: rearranged by DRIVER_INIT to leave only sprites - ROM_LOAD( "epr5937", 0x0000, 0x2000, CRC(5c80ec42) SHA1(9b79737577e48a6b2ec20ce145252545955e82c3) ) + ROM_LOAD( "5.5G.2764", 0x0000, 0x2000, CRC(5c80ec42) SHA1(9b79737577e48a6b2ec20ce145252545955e82c3) ) ROM_REGION( 0x0120, "proms", 0 ) - ROM_LOAD( "pr5957", 0x0000, 0x020, CRC(f5ce825e) SHA1(956f580840f1a7d24bfbd72b2929d14e9ee1b660) ) /* palette */ - ROM_LOAD( "pr5956", 0x0020, 0x100, CRC(872dd450) SHA1(6c1e2c4a2fc072f4bf4996c731adb0b01b347506) ) /* look-up table */ + ROM_LOAD( "1e.bpr", 0x0000, 0x0020, CRC(f5ce825e) SHA1(956f580840f1a7d24bfbd72b2929d14e9ee1b660) ) /* palette - wasn't dumped from this set, could be wrong */ + ROM_LOAD( "5K.82S129", 0x0020, 0x0100, CRC(2e481ffa) SHA1(bc8979efd43bee8be0ce96ebdacc873a5821e06e) ) /* look-up table */ ROM_END ROM_START( champbb2j ) @@ -1278,8 +1294,8 @@ GAME( 1983, champbasj, champbas, champbasj, champbas, champbas_state, champbas GAME( 1983, champbasja, champbas, champbasja, champbas, champbas_state, champbas, ROT0, "Alpha Denshi Co.", "Champion Base Ball (Japan set 2)", MACHINE_SUPPORTS_SAVE ) // simplified protection, no mcu GAME( 1983, champbasjb, champbas, champbasjb, champbas, champbas_state, champbas, ROT0, "Alpha Denshi Co.", "Champion Base Ball (Japan set 3)", MACHINE_SUPPORTS_SAVE ) // no protection GAME( 1983, champbb2, 0, champbb2, champbas, champbas_state, champbas, ROT0, "Alpha Denshi Co. (Sega license)", "Champion Base Ball Part-2 (set 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, champbb2a, champbb2, champbb2, champbas, champbas_state, champbas, ROT0, "Alpha Denshi Co.", "Champion Base Ball Part-2 (set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // incomplete dump GAME( 1983, champbb2j, champbb2, champbb2, champbas, champbas_state, champbas, ROT0, "Alpha Denshi Co.", "Champion Base Ball Part-2 (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, tbasebal, champbb2, tbasebal, champbas, champbas_state, champbas, ROT0, "Alpha Denshi Co.", "Taikyoku Base Ball", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // 68705 protection instead GAME( 1983, exctsccr, 0, exctsccr, exctsccr, champbas_state, exctsccr, ROT270, "Alpha Denshi Co.", "Exciting Soccer", MACHINE_SUPPORTS_SAVE ) GAME( 1983, exctsccru, exctsccr, exctsccr, exctsccr, champbas_state, exctsccr, ROT270, "Alpha Denshi Co.", "Exciting Soccer (US)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/chanbara.cpp b/src/mame/drivers/chanbara.cpp index 2c04f13c23f..7a7536f75de 100644 --- a/src/mame/drivers/chanbara.cpp +++ b/src/mame/drivers/chanbara.cpp @@ -347,9 +347,9 @@ static const gfx_layout spritelayout = static GFXDECODE_START( chanbara ) GFXDECODE_ENTRY( "gfx1", 0x00000, tilelayout, 0x40, 32 ) GFXDECODE_ENTRY( "sprites", 0x00000, spritelayout, 0x80, 16 ) - GFXDECODE_ENTRY( "gfx3", 0x00000, tile16layout, 0, 32 ) GFXDECODE_END + /***************************************************************************/ @@ -387,16 +387,18 @@ void chanbara_state::machine_reset() static MACHINE_CONFIG_START( chanbara ) - MCFG_CPU_ADD("maincpu", M6809, 12000000/8) + MCFG_CPU_ADD("maincpu", M6809, XTAL_12MHz/8) MCFG_CPU_PROGRAM_MAP(chanbara_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(57.4122) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) - MCFG_SCREEN_SIZE(32*8, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0, 32*8-1, 2*8, 30*8-1) +// MCFG_SCREEN_REFRESH_RATE(57.4122) +// MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) +// MCFG_SCREEN_SIZE(32*8, 32*8) +// MCFG_SCREEN_VISIBLE_AREA(0, 32*8-1, 2*8, 30*8-1) + // DECO video CRTC + MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,384,0,256,272,16,240) MCFG_SCREEN_UPDATE_DRIVER(chanbara_state, screen_update_chanbara) MCFG_SCREEN_PALETTE("palette") @@ -409,8 +411,6 @@ static MACHINE_CONFIG_START( chanbara ) MCFG_SOUND_ADD("ymsnd", YM2203, 12000000/8) MCFG_YM2203_IRQ_HANDLER(INPUTLINE("maincpu", 0)) - - MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(chanbara_state, chanbara_ay_out_0_w)) MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(chanbara_state, chanbara_ay_out_1_w)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) diff --git a/src/mame/drivers/changela.cpp b/src/mame/drivers/changela.cpp index cb224a39160..6ea7203b6ce 100644 --- a/src/mame/drivers/changela.cpp +++ b/src/mame/drivers/changela.cpp @@ -352,7 +352,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(changela_state::changela_scanline) INTERRUPT_GEN_MEMBER(changela_state::chl_mcu_irq) { - generic_pulse_irq_line(*m_mcu, 0, 1); + m_mcu->pulse_input_line(0, m_mcu->minimum_quantum_time()); } void changela_state::machine_start() diff --git a/src/mame/drivers/chaos.cpp b/src/mame/drivers/chaos.cpp index a7057551c45..72a19e5558f 100644 --- a/src/mame/drivers/chaos.cpp +++ b/src/mame/drivers/chaos.cpp @@ -4,8 +4,8 @@ Chaos2 - 08/04/2010 Skeleton driver. - 19/05/2012 Connected to a terminal, system is usable [Robbbert] + 2010-04-08 Skeleton driver. + 2012-05-19 Connected to a terminal, system is usable [Robbbert] This is a homebrew system: http://koo.corpus.cam.ac.uk/chaos/ @@ -60,12 +60,12 @@ private: }; -static ADDRESS_MAP_START( chaos_mem, AS_PROGRAM, 8, chaos_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, chaos_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x7fff) AM_RAM AM_SHARE("ram") ADDRESS_MAP_END -static ADDRESS_MAP_START( chaos_io, AS_IO, 8, chaos_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, chaos_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x1e, 0x1e) AM_READ(port1e_r) AM_RANGE(0x1f, 0x1f) AM_READWRITE(port90_r, port1f_w) @@ -74,7 +74,7 @@ static ADDRESS_MAP_START( chaos_io, AS_IO, 8, chaos_state ) AM_RANGE(0x92, 0x92) AM_DEVWRITE("terminal", generic_terminal_device, write) ADDRESS_MAP_END -static ADDRESS_MAP_START( chaos_data, AS_DATA, 8, chaos_state ) +static ADDRESS_MAP_START( data_map, AS_DATA, 8, chaos_state ) AM_RANGE(S2650_DATA_PORT, S2650_DATA_PORT) AM_NOP // stops error log filling up while using debug ADDRESS_MAP_END @@ -144,9 +144,9 @@ void chaos_state::machine_reset() static MACHINE_CONFIG_START( chaos ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", S2650, XTAL_1MHz) - MCFG_CPU_PROGRAM_MAP(chaos_mem) - MCFG_CPU_IO_MAP(chaos_io) - MCFG_CPU_DATA_MAP(chaos_data) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + MCFG_CPU_DATA_MAP(data_map) /* video hardware */ MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) diff --git a/src/mame/drivers/chqflag.cpp b/src/mame/drivers/chqflag.cpp index e5197879165..23fa7862807 100644 --- a/src/mame/drivers/chqflag.cpp +++ b/src/mame/drivers/chqflag.cpp @@ -71,22 +71,33 @@ WRITE8_MEMBER(chqflag_state::chqflag_vreg_w) /* Bits 3 and 7 are set in night stages, where the background should get darker and */ /* the headlight (which have the shadow bit set) become highlights */ /* Maybe one of the bits inverts the SHAD line while the other darkens the background. */ - if (data & 0x08) - m_palette->set_shadow_factor(1 / PALETTE_DEFAULT_SHADOW_FACTOR); - else - m_palette->set_shadow_factor(PALETTE_DEFAULT_SHADOW_FACTOR); - + /* + * Update according to a reference: + * 0x00 is certainly shadow (car pit-in shadow when zoomed in/clouds before rain) + * 0x80 is used when rain shows up (which should be white/highlighted) + * 0x88 is for when night shows up (max amount of highlight) + * 0x08 is used at dawn after 0x88 state + * The shadow part looks ugly when rain starts/ends pouring (-> black colored with a setting of 0x00), + * the reference shows dimmed background when this event occurs (which is handled via reg 1 bit 0 of k051960 device), + * might be actually disabling the shadow here (-> setting 1.0f instead). + * + * TODO: true values aren't known, also shadow_factors table probably scales towards zero instead (game doesn't use those) + */ + const double shadow_factors[4] = {0.8, 1.33, 1.66, 2.0 }; + const double highlight_factors[4] = {1.0, 1.33, 1.66, 2.0 }; + uint8_t shadow_value = ((data & 0x80) >> 6) | ((data & 0x08) >> 3); + + m_palette->set_shadow_factor(m_last_vreg != 0 ? highlight_factors[shadow_value] : shadow_factors[shadow_value] ); + + #if 0 if ((data & 0x80) != m_last_vreg) { - double brt = (data & 0x80) ? PALETTE_DEFAULT_SHADOW_FACTOR : 1.0; - int i; - m_last_vreg = data & 0x80; /* only affect the background */ - for (i = 512; i < 1024; i++) - m_palette->set_pen_contrast(i, brt); + update_background_shadows(data); } + #endif //if ((data & 0xf8) && (data & 0xf8) != 0x88) // popmessage("chqflag_vreg_w %02x",data); @@ -286,6 +297,27 @@ void chqflag_state::machine_reset() m_analog_ctrl = 0; m_accel = 0; m_wheel = 0; + update_background_shadows(0); +} + +inline void chqflag_state::update_background_shadows(uint8_t data) +{ + double brt = (data & 1) ? 0.8 : 1.0; + + for (int i = 512; i < 1024; i++) + m_palette->set_pen_contrast(i, brt); +} + + +WRITE_LINE_MEMBER(chqflag_state::background_brt_w) +{ +// popmessage("%d",state); + + if (state != m_last_vreg) + { + m_last_vreg = state; + update_background_shadows(state); + } } static MACHINE_CONFIG_START( chqflag ) @@ -300,8 +332,8 @@ static MACHINE_CONFIG_START( chqflag ) MCFG_DEVICE_ADD("bank1000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank1000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MCFG_QUANTUM_TIME(attotime::from_hz(600)) @@ -326,6 +358,7 @@ static MACHINE_CONFIG_START( chqflag ) MCFG_K051960_CB(chqflag_state, sprite_callback) MCFG_K051960_IRQ_HANDLER(INPUTLINE("maincpu", KONAMI_IRQ_LINE)) MCFG_K051960_NMI_HANDLER(INPUTLINE("maincpu", INPUT_LINE_NMI)) + MCFG_K051960_VREG_CONTRAST_HANDLER(WRITELINE(chqflag_state,background_brt_w)) MCFG_DEVICE_ADD("k051316_1", K051316, 0) MCFG_GFX_PALETTE("palette") diff --git a/src/mame/drivers/cischeat.cpp b/src/mame/drivers/cischeat.cpp index 22cdefce06a..8fe886141c7 100644 --- a/src/mame/drivers/cischeat.cpp +++ b/src/mame/drivers/cischeat.cpp @@ -3602,13 +3602,13 @@ DRIVER_INIT_MEMBER(cischeat_state, captflag) ***************************************************************************/ -GAMEL( 1989, bigrun, 0, bigrun, bigrun, cischeat_state, bigrun, ROT0, "Jaleco", "Big Run (11th Rallye version)", MACHINE_IMPERFECT_GRAPHICS, layout_cischeat ) // there's a 13th Rallye version (1991) (only on the SNES? Could just be updated title, 1989 -> 11th Paris-Dakar ...) -GAMEL( 1990, cischeat, 0, cischeat, cischeat, cischeat_state, cischeat, ROT0, "Jaleco", "Cisco Heat", MACHINE_IMPERFECT_GRAPHICS, layout_cischeat ) -GAMEL( 1991, f1gpstar, 0, f1gpstar, f1gpstar, cischeat_state, f1gpstar, ROT0, "Jaleco", "Grand Prix Star (v3.0)", MACHINE_IMPERFECT_GRAPHICS, layout_f1gpstar ) -GAMEL( 1991, f1gpstaro,f1gpstar, f1gpstar, f1gpstar, cischeat_state, f1gpstar, ROT0, "Jaleco", "Grand Prix Star (v2.0)", MACHINE_IMPERFECT_GRAPHICS, layout_f1gpstar ) +GAMEL( 1989, bigrun, 0, bigrun, bigrun, cischeat_state, bigrun, ROT0, "Jaleco", "Big Run (11th Rallye version)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN, layout_cischeat ) // there's a 13th Rallye version (1991) (only on the SNES? Could just be updated title, 1989 -> 11th Paris-Dakar ...) +GAMEL( 1990, cischeat, 0, cischeat, cischeat, cischeat_state, cischeat, ROT0, "Jaleco", "Cisco Heat", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN, layout_cischeat ) +GAMEL( 1991, f1gpstar, 0, f1gpstar, f1gpstar, cischeat_state, f1gpstar, ROT0, "Jaleco", "Grand Prix Star (v3.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN, layout_f1gpstar ) +GAMEL( 1991, f1gpstaro,f1gpstar, f1gpstar, f1gpstar, cischeat_state, f1gpstar, ROT0, "Jaleco", "Grand Prix Star (v2.0)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN, layout_f1gpstar ) GAME ( 1992, armchmp2, 0, armchmp2, armchmp2, cischeat_state, 0, ROT270, "Jaleco", "Arm Champs II v2.6", MACHINE_IMPERFECT_GRAPHICS ) GAME ( 1992, armchmp2o,armchmp2, armchmp2, armchmp2, cischeat_state, 0, ROT270, "Jaleco", "Arm Champs II v1.7", MACHINE_IMPERFECT_GRAPHICS ) GAME ( 1992, wildplt, 0, wildplt, wildplt, cischeat_state, f1gpstar, ROT0, "Jaleco", "Wild Pilot", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) // busted timings -GAMEL( 1993, f1gpstr2, 0, f1gpstr2, f1gpstr2, cischeat_state, f1gpstar, ROT0, "Jaleco", "F-1 Grand Prix Star II", MACHINE_IMPERFECT_GRAPHICS, layout_f1gpstar ) +GAMEL( 1993, f1gpstr2, 0, f1gpstr2, f1gpstr2, cischeat_state, f1gpstar, ROT0, "Jaleco", "F-1 Grand Prix Star II", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN, layout_f1gpstar ) GAME ( 1993, captflag, 0, captflag, captflag, cischeat_state, captflag, ROT270, "Jaleco", "Captain Flag (Japan)", MACHINE_IMPERFECT_GRAPHICS ) GAME ( 1994, scudhamm, 0, scudhamm, scudhamm, cischeat_state, 0, ROT270, "Jaleco", "Scud Hammer", MACHINE_IMPERFECT_GRAPHICS ) diff --git a/src/mame/drivers/cit220.cpp b/src/mame/drivers/cit220.cpp new file mode 100644 index 00000000000..f06a3b92e7a --- /dev/null +++ b/src/mame/drivers/cit220.cpp @@ -0,0 +1,118 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +Skeleton driver for VT220-compatible terminals by C. Itoh/CIE Terminals. + +The CIT-220+ Video Terminal was introduced as a direct competitor to DEC's VT220. It copied the design of the VT220 closely +enough to provoke a lawsuit, which led to its eventual withdrawal in favor of its successor, the CIT224. + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/i8085/i8085.h" +#include "machine/i8251.h" +#include "machine/mc68681.h" +#include "video/scn2674.h" +#include "screen.h" + + +class cit220_state : public driver_device +{ +public: + cit220_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_screen(*this, "screen") + //, m_p_chargen(*this, "chargen") + { } + + DECLARE_WRITE_LINE_MEMBER(sod_w); + SCN2674_DRAW_CHARACTER_MEMBER(draw_character); + +private: + required_device<cpu_device> m_maincpu; + required_device<screen_device> m_screen; + //required_region_ptr<u8> m_p_chargen; +}; + + +WRITE_LINE_MEMBER(cit220_state::sod_w) +{ + // probably asserts PBREQ on SCN2674 to access memory at Exxx +} + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, cit220_state ) + AM_RANGE(0x0000, 0x7fff) AM_ROM AM_REGION("maincpu", 0) + AM_RANGE(0x8000, 0x87ff) AM_RAM + AM_RANGE(0xa000, 0xa1ff) AM_ROM AM_REGION("eeprom", 0x800) + AM_RANGE(0xe000, 0xe7ff) AM_RAM // ??? +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_IO, 8, cit220_state ) + AM_RANGE(0x00, 0x0f) AM_DEVREADWRITE("duart", scn2681_device, read, write) + AM_RANGE(0x10, 0x10) AM_DEVREADWRITE("usart", i8251_device, data_r, data_w) + AM_RANGE(0x11, 0x11) AM_DEVREADWRITE("usart", i8251_device, status_r, control_w) + AM_RANGE(0x20, 0x27) AM_DEVREADWRITE("avdc", scn2674_device, read, write) + AM_RANGE(0xa0, 0xa0) AM_UNMAP // ??? + AM_RANGE(0xc0, 0xc0) AM_UNMAP // ??? +ADDRESS_MAP_END + + +SCN2674_DRAW_CHARACTER_MEMBER(cit220_state::draw_character) +{ +} + +static ADDRESS_MAP_START( vram_map, 0, 8, cit220_state ) + AM_RANGE(0x0000, 0x27ff) AM_NOP +ADDRESS_MAP_END + + +static INPUT_PORTS_START( cit220p ) +INPUT_PORTS_END + + +static MACHINE_CONFIG_START( cit220p ) + MCFG_CPU_ADD("maincpu", I8085A, 6000000) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + MCFG_I8085A_SOD(WRITELINE(cit220_state, sod_w)) + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ + MCFG_SCREEN_SIZE(720, 360) + MCFG_SCREEN_VISIBLE_AREA(0, 720-1, 0, 360-1) + MCFG_SCREEN_UPDATE_DEVICE("avdc", scn2674_device, screen_update) + + MCFG_DEVICE_ADD("avdc", SCN2674, 4000000) + MCFG_SCN2674_INTR_CALLBACK(INPUTLINE("maincpu", I8085_RST65_LINE)) + MCFG_SCN2674_TEXT_CHARACTER_WIDTH(8) + MCFG_SCN2674_GFX_CHARACTER_WIDTH(8) + MCFG_SCN2674_DRAW_CHARACTER_CALLBACK_OWNER(cit220_state, draw_character) + MCFG_DEVICE_ADDRESS_MAP(0, vram_map) + MCFG_VIDEO_SET_SCREEN("screen") + + MCFG_DEVICE_ADD("duart", SCN2681, 3686400) + MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", I8085_RST55_LINE)) + + MCFG_DEVICE_ADD("usart", I8251, 3000000) +MACHINE_CONFIG_END + + +ROM_START( cit220p ) + ROM_REGION(0x8000, "maincpu", 0) + ROM_LOAD( "v17_001a.ic23", 0x0000, 0x4000, CRC(2cc43026) SHA1(366f57292c6e44571368c29e3258203779847356) ) + ROM_LOAD( "v17_001b.ic24", 0x4000, 0x4000, CRC(a56b16f1) SHA1(c68f26b35453153f7defcf1cf2b7ad7fe36cc9e7) ) + + ROM_REGION(0x1000, "eeprom", 0) + ROM_LOAD( "eeprom.bin", 0x0000, 0x1000, CRC(7b24878a) SHA1(20086fb792a24339b65abe627aefbcf48e2abcf4) ) // don't know where this fits in + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "v20_cg.ic17", 0x0000, 0x1000, CRC(76ef7ca9) SHA1(6e7799ca0a41350fbc369bbbd4ab581150f37b10) ) + + ROM_REGION(0x10000, "keyboard", 0) + ROM_LOAD( "v00_kbd.bin", 0x0000, 0x1000, CRC(f9d24190) SHA1(c4e9ef8188afb18de373f2a537ca9b7a315bfb76) ) +ROM_END + +COMP( 1983, cit220p, 0, 0, cit220p, cit220p, cit220_state, 0, "C. Itoh", "CIT-220+ Video Terminal", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/clcd.cpp b/src/mame/drivers/clcd.cpp index 5ac1b9124fd..207da3b035e 100644 --- a/src/mame/drivers/clcd.cpp +++ b/src/mame/drivers/clcd.cpp @@ -771,25 +771,25 @@ static MACHINE_CONFIG_START(clcd) MCFG_DEVICE_ADD("bank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(clcd_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) MCFG_DEVICE_ADD("bank2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(clcd_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) MCFG_DEVICE_ADD("bank3", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(clcd_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) MCFG_DEVICE_ADD("bank4", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(clcd_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) MCFG_DEVICE_ADD("rtc", MSM58321, XTAL_32_768kHz) diff --git a/src/mame/drivers/clshroad.cpp b/src/mame/drivers/clshroad.cpp index 5eb316ab9f2..6dda2467f64 100644 --- a/src/mame/drivers/clshroad.cpp +++ b/src/mame/drivers/clshroad.cpp @@ -306,7 +306,7 @@ static MACHINE_CONFIG_START( firebatl ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("custom", WIPING, 0) + MCFG_SOUND_ADD("custom", WIPING_CUSTOM, 96000) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) MACHINE_CONFIG_END @@ -346,7 +346,7 @@ static MACHINE_CONFIG_START( clshroad ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("custom", WIPING, 0) + MCFG_SOUND_ADD("custom", WIPING_CUSTOM, 96000) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) MACHINE_CONFIG_END @@ -560,15 +560,9 @@ ROM_END DRIVER_INIT_MEMBER(clshroad_state,firebatl) { -/* -Pugsy> firebatl:0:05C6:C3:100:Fix the Game:It's a hack but seems to make it work! -Pugsy> firebatl:0:05C7:8D:600:Fix the Game (2/3) -Pugsy> firebatl:0:05C8:23:600:Fix the Game (3/3) - -without this the death sequence never ends so the game is unplayable after you -die once, it would be nice to avoid the hack however - -*/ + // applying HACK to fix the game + // without this the death sequence never ends so the game is unplayable after you + // die once, it would be nice to avoid the hack however uint8_t *ROM = memregion("maincpu")->base(); ROM[0x05C6] = 0xc3; diff --git a/src/mame/drivers/cm1800.cpp b/src/mame/drivers/cm1800.cpp index 10d8b700a24..b4d294bccdd 100644 --- a/src/mame/drivers/cm1800.cpp +++ b/src/mame/drivers/cm1800.cpp @@ -2,15 +2,15 @@ // copyright-holders:Miodrag Milanovic, Robbbert /*************************************************************************** - CM-1800 - (note name is in cyrilic letters) +CM-1800 +(note name is in cyrilic letters) - more info at http://ru.wikipedia.org/wiki/%D0%A1%D0%9C_%D0%AD%D0%92%D0%9C - and http://sapr.lti-gti.ru/index.php?id=66 +more info at http://ru.wikipedia.org/wiki/%D0%A1%D0%9C_%D0%AD%D0%92%D0%9C + and http://www.computer-museum.ru/histussr/sm1800.htm - 26/04/2011 Skeleton driver. +2011-04-26 Skeleton driver. -Commands: +Commands to be in uppercase: C Compare D Dump F Fill @@ -35,7 +35,8 @@ to be a save command. #include "emu.h" #include "cpu/i8085/i8085.h" -#include "machine/terminal.h" +#include "machine/ay31015.h" +#include "bus/rs232/rs232.h" class cm1800_state : public driver_device @@ -43,51 +44,48 @@ class cm1800_state : public driver_device public: cm1800_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) - , m_terminal(*this, "terminal") , m_maincpu(*this, "maincpu") + , m_uart(*this, "uart") { } - DECLARE_READ8_MEMBER( term_status_r ); - DECLARE_READ8_MEMBER( term_r ); - void kbd_put(u8 data); + DECLARE_READ8_MEMBER(port00_r); + DECLARE_READ8_MEMBER(port01_r); + DECLARE_WRITE8_MEMBER(port00_w); private: virtual void machine_reset() override; - - uint8_t m_term_data; - - required_device<generic_terminal_device> m_terminal; required_device<cpu_device> m_maincpu; + required_device<ay31015_device> m_uart; }; -READ8_MEMBER( cm1800_state::term_status_r ) +WRITE8_MEMBER( cm1800_state::port00_w ) { - return (m_term_data) ? 5 : 4; + m_uart->set_transmit_data(data); } -READ8_MEMBER( cm1800_state::term_r ) +READ8_MEMBER( cm1800_state::port01_r ) { - uint8_t ret = m_term_data; - m_term_data = 0; - return ret; + return (m_uart->get_output_pin(AY31015_DAV)) | (m_uart->get_output_pin(AY31015_TBMT) << 2); } -void cm1800_state::kbd_put(u8 data) +READ8_MEMBER( cm1800_state::port00_r ) { - m_term_data = data; + m_uart->set_input_pin(AY31015_RDAV, 0); + u8 result = m_uart->get_received_data(); + m_uart->set_input_pin(AY31015_RDAV, 1); + return result; } -static ADDRESS_MAP_START(cm1800_mem, AS_PROGRAM, 8, cm1800_state) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, cm1800_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0x07ff ) AM_ROM AM_REGION("roms", 0) AM_RANGE( 0x0800, 0xffff ) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( cm1800_io , AS_IO, 8, cm1800_state) +static ADDRESS_MAP_START( io_map, AS_IO, 8, cm1800_state ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x00, 0x00) AM_READ(term_r) AM_DEVWRITE("terminal", generic_terminal_device, write) - AM_RANGE(0x01, 0x01) AM_READ(term_status_r) - AM_RANGE(0x03, 0x03) // unknown uart, initialisation bytes 08 then 48, so not 6551. + AM_RANGE(0x00, 0x00) AM_READWRITE(port00_r,port00_w) + AM_RANGE(0x01, 0x01) AM_READ(port01_r) ADDRESS_MAP_END /* Input ports */ @@ -97,17 +95,31 @@ INPUT_PORTS_END void cm1800_state::machine_reset() { + m_uart->set_input_pin(AY31015_XR, 0); + m_uart->set_input_pin(AY31015_XR, 1); + m_uart->set_input_pin(AY31015_SWE, 0); + m_uart->set_input_pin(AY31015_NP, 1); + m_uart->set_input_pin(AY31015_TSB, 0); + m_uart->set_input_pin(AY31015_NB1, 1); + m_uart->set_input_pin(AY31015_NB2, 1); + m_uart->set_input_pin(AY31015_EPS, 1); + m_uart->set_input_pin(AY31015_CS, 1); + m_uart->set_input_pin(AY31015_CS, 0); } static MACHINE_CONFIG_START( cm1800 ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu",I8080, XTAL_2MHz) - MCFG_CPU_PROGRAM_MAP(cm1800_mem) - MCFG_CPU_IO_MAP(cm1800_io) + MCFG_CPU_ADD("maincpu", I8080, XTAL_2MHz) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ - MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) - MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(cm1800_state, kbd_put)) + MCFG_DEVICE_ADD("uart", AY51013, 0) // exact uart type is unknown + MCFG_AY51013_TX_CLOCK(153600) + MCFG_AY51013_RX_CLOCK(153600) + MCFG_AY51013_READ_SI_CB(DEVREADLINE("rs232", rs232_port_device, rxd_r)) + MCFG_AY51013_WRITE_SO_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") MACHINE_CONFIG_END /* ROM definition */ diff --git a/src/mame/drivers/cmi.cpp b/src/mame/drivers/cmi.cpp index 32bb6a385c9..19a268bf5bd 100644 --- a/src/mame/drivers/cmi.cpp +++ b/src/mame/drivers/cmi.cpp @@ -1081,10 +1081,8 @@ static ADDRESS_MAP_START( muskeys_map, AS_PROGRAM, 8, cmi_state) AM_RANGE(0x0000, 0x007f) AM_RAM AM_RANGE(0x0080, 0x0083) AM_DEVREADWRITE("cmi10_pia_u21", pia6821_device, read, write) AM_RANGE(0x0090, 0x0093) AM_DEVREADWRITE("cmi10_pia_u20", pia6821_device, read, write) - AM_RANGE(0x00a0, 0x00a0) AM_DEVREADWRITE("acia_mkbd_kbd", acia6850_device, status_r, control_w) - AM_RANGE(0x00a1, 0x00a1) AM_DEVREADWRITE("acia_mkbd_kbd", acia6850_device, data_r, data_w) - AM_RANGE(0x00b0, 0x00b0) AM_DEVREADWRITE("acia_mkbd_cmi", acia6850_device, status_r, control_w) - AM_RANGE(0x00b1, 0x00b1) AM_DEVREADWRITE("acia_mkbd_cmi", acia6850_device, data_r, data_w) + AM_RANGE(0x00a0, 0x00a1) AM_DEVREADWRITE("acia_mkbd_kbd", acia6850_device, read, write) + AM_RANGE(0x00b0, 0x00b1) AM_DEVREADWRITE("acia_mkbd_cmi", acia6850_device, read, write) AM_RANGE(0x4000, 0x47ff) AM_RAM AM_RANGE(0xb000, 0xb400) AM_ROM AM_RANGE(0xf000, 0xffff) AM_ROM diff --git a/src/mame/drivers/coco12.cpp b/src/mame/drivers/coco12.cpp index 0a1cee38e71..88141100f81 100644 --- a/src/mame/drivers/coco12.cpp +++ b/src/mame/drivers/coco12.cpp @@ -26,7 +26,16 @@ #include "emu.h" #include "includes/coco12.h" +#include "bus/coco/coco_dcmodem.h" #include "bus/coco/coco_dwsock.h" +#include "bus/coco/coco_fdc.h" +#include "bus/coco/coco_gmc.h" +#include "bus/coco/coco_multi.h" +#include "bus/coco/coco_orch90.h" +#include "bus/coco/coco_pak.h" +#include "bus/coco/coco_rs232.h" +#include "bus/coco/coco_ssc.h" +#include "bus/coco/coco_t4426.h" #include "cpu/m6809/m6809.h" #include "imagedev/cassette.h" @@ -230,6 +239,107 @@ static INPUT_PORTS_START( coco ) INPUT_PORTS_END +//------------------------------------------------- +// INPUT_PORTS( cp400c2_keyboard ) +//------------------------------------------------- +// +// CP400 Color II keyboard +// +// PB0 PB1 PB2 PB3 PB4 PB5 PB6 PB7 +// PA6: Enter Clear Break Ctrl PA1 PA2 PA3 Shift +// PA5: 8 9 : ; , - . / +// PA4: 0 1 2 3 4 5 6 7 +// PA3: X Y Z Up Down Left Right Space +// PA2: P Q R S T U V W +// PA1: H I J K L M N O +// PA0: @ A B C D E F G +//------------------------------------------------- + +static INPUT_PORTS_START( cp400c2_keyboard ) + PORT_START("row0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + + PORT_START("row1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + + PORT_START("row2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + + PORT_START("row3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP), '^') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN), 10) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(UCHAR_MAMEKEY(LEFT), 8) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT), 9) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + + PORT_START("row4") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('\"') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + + PORT_START("row5") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_MINUS) PORT_CHAR(':') PORT_CHAR('*') + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('-') PORT_CHAR('=') + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + + PORT_START("row6") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("CLEAR") PORT_CODE(KEYCODE_HOME) PORT_CHAR(12) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("BREAK") PORT_CODE(KEYCODE_END) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("PA1") PORT_CODE(KEYCODE_LALT) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("PA2") PORT_CODE(KEYCODE_RALT) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("PA3") PORT_CODE(KEYCODE_BACKSLASH) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CHANGED_MEMBER(DEVICE_SELF, coco12_state, coco_state::keyboard_changed, nullptr) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) +INPUT_PORTS_END + + +//------------------------------------------------- +// INPUT_PORTS( cp400c2 ) +//------------------------------------------------- + +static INPUT_PORTS_START( cp400c2 ) + PORT_INCLUDE( cp400c2_keyboard ) + PORT_INCLUDE( coco_joystick ) + PORT_INCLUDE( coco_analog_control ) + PORT_INCLUDE( coco_rtc ) + PORT_INCLUDE( coco_beckerport ) +INPUT_PORTS_END + //************************************************************************** // MACHINE CONFIGURATION @@ -243,7 +353,8 @@ SLOT_INTERFACE_START( coco_cart ) SLOT_INTERFACE("fdc", COCO_FDC) SLOT_INTERFACE("fdcv11", COCO_FDC_V11) SLOT_INTERFACE("cc3hdb1", COCO3_HDB1) - SLOT_INTERFACE("cp400_fdc", CP400_FDC) + SLOT_INTERFACE("cp450_fdc", CP450_FDC) + SLOT_INTERFACE("cd6809_fdc", CD6809_FDC) SLOT_INTERFACE("rs232", COCO_RS232) SLOT_INTERFACE("dcmodem", COCO_DCMODEM) SLOT_INTERFACE("orch90", COCO_ORCH90) @@ -296,8 +407,8 @@ MACHINE_CONFIG_START( coco_floating ) MCFG_DEVICE_ADD(FLOATING_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(coco_floating_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MACHINE_CONFIG_END @@ -419,7 +530,7 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( cp400, coco ) MCFG_COCO_CARTRIDGE_REMOVE(CARTRIDGE_TAG) - MCFG_COCO_CARTRIDGE_ADD(CARTRIDGE_TAG, coco_cart, "cp400_fdc") + MCFG_COCO_CARTRIDGE_ADD(CARTRIDGE_TAG, coco_cart, "cp450_fdc") MCFG_COCO_CARTRIDGE_CART_CB(WRITELINE(coco_state, cart_w)) MCFG_COCO_CARTRIDGE_NMI_CB(INPUTLINE(MAINCPU_TAG, INPUT_LINE_NMI)) MCFG_COCO_CARTRIDGE_HALT_CB(INPUTLINE(MAINCPU_TAG, INPUT_LINE_HALT)) @@ -434,6 +545,14 @@ static MACHINE_CONFIG_DERIVED( t4426, coco2 ) MCFG_SLOT_FIXED(true) // This cart is fixed so no way to change it MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( cd6809, coco ) + MCFG_COCO_CARTRIDGE_REMOVE(CARTRIDGE_TAG) + MCFG_COCO_CARTRIDGE_ADD(CARTRIDGE_TAG, coco_cart, "cd6809_fdc") + MCFG_COCO_CARTRIDGE_CART_CB(WRITELINE(coco_state, cart_w)) + MCFG_COCO_CARTRIDGE_NMI_CB(INPUTLINE(MAINCPU_TAG, INPUT_LINE_NMI)) + MCFG_COCO_CARTRIDGE_HALT_CB(INPUTLINE(MAINCPU_TAG, INPUT_LINE_HALT)) +MACHINE_CONFIG_END + //************************************************************************** // ROMS //************************************************************************** @@ -466,34 +585,54 @@ ROM_START(cp400) ROM_LOAD("cp400bas.rom", 0x0000, 0x4000, CRC(878396a5) SHA1(292c545da3c77978e043b00a3dbc317201d18c3b)) ROM_END -ROM_START(mx1600 ) +ROM_START(cp400c2) + ROM_REGION(0x8000,MAINCPU_TAG,0) + ROM_LOAD("cp400bas.rom", 0x0000, 0x4000, CRC(878396a5) SHA1(292c545da3c77978e043b00a3dbc317201d18c3b)) +ROM_END + +ROM_START(mx1600) ROM_REGION(0x8000,MAINCPU_TAG,0) ROM_LOAD("mx1600bas.rom", 0x2000, 0x2000, CRC(d918156e) SHA1(70a464edf3a654ed4ffe687e6dee4f0d2acc758b)) ROM_LOAD("mx1600extbas.rom", 0x0000, 0x2000, CRC(322a3d58) SHA1(9079a477c3f22e46cebb1e68b61df5bd607c71a4)) ROM_END -ROM_START( t4426 ) +ROM_START(t4426) ROM_REGION(0x8000,MAINCPU_TAG,0) ROM_LOAD("SOFT4426-U13-1.2.bin", 0x2000, 0x2000, CRC(3c1af94a) SHA1(1dc57b3e4a6ef6a743ca21d8f111a74b1ea9d54e)) ROM_LOAD("SOFT4426-U14-1.2.bin", 0x0000, 0x2000, CRC(e031d076) SHA1(7275f1e3f165ff6a4657e4e5e24cb8b817239f54)) ROM_END -ROM_START(lzcolor64 ) +ROM_START(lzcolor64) + ROM_REGION(0x8000,MAINCPU_TAG,0) + ROM_LOAD("color_basic.ci24", 0x2000, 0x2000, CRC(b0717d71) SHA1(ad1beef9d6f095ada69f91d0b8ad75985172d86f)) + ROM_LOAD("extendido.ci23", 0x0000, 0x2000, CRC(d1b1560d) SHA1(7252de9df405ade453282e992eb1f1910adc8e50)) +ROM_END + +ROM_START(cd6809) ROM_REGION(0x8000,MAINCPU_TAG,0) - ROM_LOAD("color64bas.rom", 0x2000, 0x2000, CRC(b0717d71) SHA1(ad1beef9d6f095ada69f91d0b8ad75985172d86f)) - ROM_LOAD("color64extbas.rom", 0x0000, 0x2000, CRC(d1b1560d) SHA1(7252de9df405ade453282e992eb1f1910adc8e50)) + ROM_DEFAULT_BIOS("84") + + ROM_SYSTEM_BIOS( 0, "83", "1983" ) + ROMX_LOAD("cd6809bas83.rom", 0x2000, 0x2000, CRC(f8e64142) SHA1(c0fd689119e2619ec226a2d67aeeb32070c14e38), ROM_BIOS(1)) + ROMX_LOAD("cd6809extbas83.rom", 0x0000, 0x2000, CRC(e5d5aa15) SHA1(0cd4a3d9e4af1d0176964e35e3d15a9fa0e68ac4), ROM_BIOS(1)) + + ROM_SYSTEM_BIOS( 1, "84", "1984" ) + ROMX_LOAD("cd6809bas84.rom", 0x2000, 0x2000, CRC(8a9971da) SHA1(5cb5f1ffc983a85ba92af68b1d571b270f6db559), ROM_BIOS(2)) + ROMX_LOAD("cd6809extbas84.rom", 0x0000, 0x2000, CRC(8dc853e2) SHA1(d572ce4497c115af53d2b0feeb52d3c7a7fec175), ROM_BIOS(2)) ROM_END //************************************************************************** // SYSTEM DRIVERS //************************************************************************** -// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -COMP( 1980, coco, 0, 0, coco, coco, coco12_state, 0, "Tandy Radio Shack", "Color Computer", 0 ) -COMP( 1981, cocoe, coco, 0, cocoe, coco, coco12_state, 0, "Tandy Radio Shack", "Color Computer (Extended BASIC 1.0)", 0 ) -COMP( 1983, coco2, coco, 0, coco2, coco, coco12_state, 0, "Tandy Radio Shack", "Color Computer 2", 0 ) -COMP( 1985?, coco2b, coco, 0, coco2b, coco, coco12_state, 0, "Tandy Radio Shack", "Color Computer 2B", 0 ) -COMP( 1984, cp400, coco, 0, cp400, coco, coco12_state, 0, "Prologica", "CP400", 0 ) -COMP( 1984, lzcolor64, coco, 0, coco, coco, coco12_state, 0, "Digiponto", "LZ Color64", 0 ) -COMP( 1984, mx1600, coco, 0, coco, coco, coco12_state, 0, "Dynacom", "MX-1600", 0 ) -COMP( 1986, t4426, coco, 0, t4426, coco, coco12_state, 0, "Terco AB", "Terco 4426 CNC Programming station", 0 ) +// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS +COMP( 1980, coco, 0, 0, coco, coco, coco12_state, 0, "Tandy Radio Shack", "Color Computer", 0 ) +COMP( 1981, cocoe, coco, 0, cocoe, coco, coco12_state, 0, "Tandy Radio Shack", "Color Computer (Extended BASIC 1.0)", 0 ) +COMP( 1983, coco2, coco, 0, coco2, coco, coco12_state, 0, "Tandy Radio Shack", "Color Computer 2", 0 ) +COMP( 1985?, coco2b, coco, 0, coco2b, coco, coco12_state, 0, "Tandy Radio Shack", "Color Computer 2B", 0 ) +COMP( 1983, cp400, coco, 0, cp400, coco, coco12_state, 0, "Prológica", "CP400", 0 ) +COMP( 1985, cp400c2, coco, 0, cp400, cp400c2, coco12_state, 0, "Prológica", "CP400 Color II", 0 ) +COMP( 1983, lzcolor64, coco, 0, coco, coco, coco12_state, 0, "Novo Tempo / LZ Equipamentos", "Color64", 0 ) +COMP( 1983, cd6809, coco, 0, cd6809, coco, coco12_state, 0, "Codimex", "CD-6809", 0 ) +COMP( 1984, mx1600, coco, 0, coco, coco, coco12_state, 0, "Dynacom", "MX-1600", 0 ) +COMP( 1986, t4426, coco, 0, t4426, coco, coco12_state, 0, "Terco AB", "Terco 4426 CNC Programming station", 0 ) diff --git a/src/mame/drivers/codata.cpp b/src/mame/drivers/codata.cpp index 934a6db514d..6c38d90d554 100644 --- a/src/mame/drivers/codata.cpp +++ b/src/mame/drivers/codata.cpp @@ -21,11 +21,10 @@ class codata_state : public driver_device { public: codata_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_p_base(*this, "rambase"), - m_maincpu(*this, "maincpu") - { - } + : driver_device(mconfig, type, tag) + , m_p_base(*this, "rambase") + , m_maincpu(*this, "maincpu") + { } private: virtual void machine_reset() override; @@ -33,7 +32,7 @@ private: required_device<cpu_device> m_maincpu; }; -static ADDRESS_MAP_START(codata_mem, AS_PROGRAM, 16, codata_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 16, codata_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x000000, 0x1fffff) AM_RAM AM_SHARE("rambase") AM_RANGE(0x200000, 0x203fff) AM_ROM AM_REGION("user1", 0); @@ -60,15 +59,10 @@ void codata_state::machine_reset() m_maincpu->reset(); } -static DEVICE_INPUT_DEFAULTS_START( terminal ) - DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9615 ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9615 ) -DEVICE_INPUT_DEFAULTS_END - static MACHINE_CONFIG_START( codata ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",M68000, XTAL_16MHz / 2) - MCFG_CPU_PROGRAM_MAP(codata_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) MCFG_DEVICE_ADD("uart", UPD7201_NEW, XTAL_16MHz / 4) MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs423a", rs232_port_device, write_txd)) @@ -90,7 +84,6 @@ static MACHINE_CONFIG_START( codata ) MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart", upd7201_new_device, rxa_w)) MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart", upd7201_new_device, dcda_w)) MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart", upd7201_new_device, ctsa_w)) - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) MCFG_RS232_PORT_ADD("rs423b", default_rs232_devices, nullptr) MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart", upd7201_new_device, rxb_w)) diff --git a/src/mame/drivers/coolpool.cpp b/src/mame/drivers/coolpool.cpp index ef09bce91c0..80cab473371 100644 --- a/src/mame/drivers/coolpool.cpp +++ b/src/mame/drivers/coolpool.cpp @@ -112,13 +112,13 @@ TMS340X0_SCANLINE_RGB32_CB_MEMBER(coolpool_state::coolpool_scanline) TMS340X0_TO_SHIFTREG_CB_MEMBER(coolpool_state::to_shiftreg) { - memcpy(shiftreg, &m_vram_base[TOWORD(address) & ~TOWORD(0xfff)], TOBYTE(0x1000)); + memcpy(shiftreg, &m_vram_base[(address & ~0xfff) >> 4], 0x200); } TMS340X0_FROM_SHIFTREG_CB_MEMBER(coolpool_state::from_shiftreg) { - memcpy(&m_vram_base[TOWORD(address) & ~TOWORD(0xfff)], shiftreg, TOBYTE(0x1000)); + memcpy(&m_vram_base[(address & ~0xfff) >> 4], shiftreg, 0x2000); } diff --git a/src/mame/drivers/coolridr.cpp b/src/mame/drivers/coolridr.cpp index da086c8a82d..4fdeb9a63a0 100644 --- a/src/mame/drivers/coolridr.cpp +++ b/src/mame/drivers/coolridr.cpp @@ -468,21 +468,26 @@ public: struct cool_render_object { - uint8_t* indirect_tiles; - uint32_t* indirect_zoom; + cool_render_object(coolridr_state &s) : state(s), colbase(s.m_colbase) + { + std::copy(std::begin(s.m_spriteblit), std::end(s.m_spriteblit), std::begin(spriteblit)); + } + + std::unique_ptr<uint8_t []> indirect_tiles; + std::unique_ptr<uint32_t []> indirect_zoom; uint32_t spriteblit[12]; - bitmap_ind16* drawbitmap; - //bitmap_ind16* zbitmap; - uint16_t zpri; - uint8_t blittype; - coolridr_state* state; + bitmap_ind16* drawbitmap = nullptr; + //bitmap_ind16* zbitmap = nullptr; + uint16_t zpri = 0; + uint8_t blittype = 0; + coolridr_state& state; uint32_t clipvals[3]; - int screen; + int screen = 0; int colbase; }; - struct cool_render_object **m_cool_render_object_list1; - struct cool_render_object **m_cool_render_object_list2; + std::unique_ptr<std::unique_ptr<cool_render_object> []> m_cool_render_object_list1; + std::unique_ptr<std::unique_ptr<cool_render_object> []> m_cool_render_object_list2; int m_listcount1; int m_listcount2; @@ -1020,11 +1025,11 @@ uint32_t coolridr_state::screen_update_coolridr2(screen_device &screen, bitmap_i } \ if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) \ { \ - object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi_decoded = true; \ + object->state.decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi_decoded = true; \ if (blankcount==0) \ - object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank = true; \ + object->state.decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank = true; \ else \ - object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank = false; \ + object->state.decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank = false; \ /* if (object->screen==0) printf("marking offset %04x as decoded (sprite number %08x ptr %08x)\n", v*used_hCellCount + h, spriteNumber, ((uint64_t)(void*)tempshape)&0xffffffff);*/ \ } \ } \ @@ -1055,7 +1060,7 @@ uint32_t coolridr_state::screen_update_coolridr2(screen_device &screen, bitmap_i } \ if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) \ { \ - if (object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank == true) \ + if (object->state.decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].is_blank == true) \ continue; \ } \ else \ @@ -1292,7 +1297,7 @@ TODO: fix anything that isn't text. void *coolridr_state::draw_object_threaded(void *param, int threadid) { - cool_render_object *object = reinterpret_cast<cool_render_object *>(param); + const std::unique_ptr<cool_render_object> object(reinterpret_cast<cool_render_object *>(param)); bitmap_ind16* drawbitmap = object->drawbitmap; /************* object->spriteblit[3] *************/ @@ -1317,8 +1322,8 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) - uint16_t* rearranged_16bit_gfx = object->state->m_rearranged_16bit_gfx.get(); - uint16_t* expanded_10bit_gfx = object->state->m_expanded_10bit_gfx.get(); + uint16_t* rearranged_16bit_gfx = object->state.m_rearranged_16bit_gfx.get(); + uint16_t* expanded_10bit_gfx = object->state.m_expanded_10bit_gfx.get(); int16_t clipminX = CLIPMINX_FULL; int16_t clipmaxX = CLIPMAXX_FULL; @@ -1338,7 +1343,7 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) if (b1mode) { - // b1colorNumber = object->state->machine().rand()&0xfff; + // b1colorNumber = object->state.machine().rand()&0xfff; } /************* object->spriteblit[3] *************/ @@ -1410,9 +1415,9 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) // note the road always has 0x8000 bit set in the palette. I *think* this is because they do a gradual blend of some kind between the road types // see the number of transitional road bits which have various values above set - if (blit4blendlevel==object->state->debug_randompal) + if (blit4blendlevel==object->state.debug_randompal) { - b1colorNumber = object->state->machine().rand()&0xfff; + b1colorNumber = object->state.machine().rand()&0xfff; } @@ -1439,18 +1444,7 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) // if we have no vertical zoom value there's no point in going any further // because there are no known vertical indirect modes if (!vZoom) - { - // abort, but make sure we clean up - if (object->indirect_tiles) - free(object->indirect_tiles); - - if (object->indirect_zoom) - free(object->indirect_zoom); - - free (object); - return nullptr; - } /************* object->spriteblit[9] *************/ @@ -1781,7 +1775,7 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) if (clipminY>clipmaxY) clipminY = clipmaxY; - //b1colorNumber = object->state->machine().rand()&0xfff; + //b1colorNumber = object->state.machine().rand()&0xfff; } /* DRAW */ @@ -1820,16 +1814,16 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) for (int k=0;k<DECODECACHE_NUMOBJECTCACHES;k++) { - if(((object->state->decode[screen].objcache[k].lastromoffset == b3romoffset)) && - ((object->state->decode[screen].objcache[k].lastused_flipx == used_flipx)) && - ((object->state->decode[screen].objcache[k].lastused_flipy == used_flipy)) && - ((object->state->decode[screen].objcache[k].lastblit_rotate == blit_rotate)) && - ((object->state->decode[screen].objcache[k].lastb1mode == b1mode)) && - ((object->state->decode[screen].objcache[k].lastb1colorNumber == b1colorNumber)) && - ((object->state->decode[screen].objcache[k].lastb2colorNumber == b2colorNumber)) && - ((object->state->decode[screen].objcache[k].lastused_hCellCount == used_hCellCount)) && - ((object->state->decode[screen].objcache[k].lastused_vCellCount == used_vCellCount)) && - ((object->state->decode[screen].objcache[k].lastb2altpenmask == b2altpenmask))) + if(((object->state.decode[screen].objcache[k].lastromoffset == b3romoffset)) && + ((object->state.decode[screen].objcache[k].lastused_flipx == used_flipx)) && + ((object->state.decode[screen].objcache[k].lastused_flipy == used_flipy)) && + ((object->state.decode[screen].objcache[k].lastblit_rotate == blit_rotate)) && + ((object->state.decode[screen].objcache[k].lastb1mode == b1mode)) && + ((object->state.decode[screen].objcache[k].lastb1colorNumber == b1colorNumber)) && + ((object->state.decode[screen].objcache[k].lastb2colorNumber == b2colorNumber)) && + ((object->state.decode[screen].objcache[k].lastused_hCellCount == used_hCellCount)) && + ((object->state.decode[screen].objcache[k].lastused_vCellCount == used_vCellCount)) && + ((object->state.decode[screen].objcache[k].lastb2altpenmask == b2altpenmask))) { found = k; break; @@ -1838,32 +1832,32 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) if (found != -1) { - object->state->decode[screen].objcache[found].repeatcount++; + object->state.decode[screen].objcache[found].repeatcount++; use_object = found; } else { - use_object = object->state->decode[screen].current_object; + use_object = object->state.decode[screen].current_object; // dirty the cache for (int i=0;i<DECODECACHE_NUMSPRITETILES;i++) - object->state->decode[screen].objcache[use_object].tiles[i].tempshape_multi_decoded = false; - - object->state->decode[screen].objcache[use_object].lastromoffset = b3romoffset; - object->state->decode[screen].objcache[use_object].lastused_flipx = used_flipx; - object->state->decode[screen].objcache[use_object].lastused_flipy = used_flipy; - object->state->decode[screen].objcache[use_object].lastblit_rotate = blit_rotate; - object->state->decode[screen].objcache[use_object].lastb1mode = b1mode; - object->state->decode[screen].objcache[use_object].lastb1colorNumber = b1colorNumber; - object->state->decode[screen].objcache[use_object].lastb2colorNumber = b2colorNumber; - object->state->decode[screen].objcache[use_object].lastused_hCellCount = used_hCellCount; - object->state->decode[screen].objcache[use_object].lastused_vCellCount = used_vCellCount; - object->state->decode[screen].objcache[use_object].lastb2altpenmask = b2altpenmask; - object->state->decode[screen].objcache[use_object].repeatcount = 0; - - object->state->decode[screen].current_object++; - if (object->state->decode[screen].current_object >= DECODECACHE_NUMOBJECTCACHES) - object->state->decode[screen].current_object = 0; + object->state.decode[screen].objcache[use_object].tiles[i].tempshape_multi_decoded = false; + + object->state.decode[screen].objcache[use_object].lastromoffset = b3romoffset; + object->state.decode[screen].objcache[use_object].lastused_flipx = used_flipx; + object->state.decode[screen].objcache[use_object].lastused_flipy = used_flipy; + object->state.decode[screen].objcache[use_object].lastblit_rotate = blit_rotate; + object->state.decode[screen].objcache[use_object].lastb1mode = b1mode; + object->state.decode[screen].objcache[use_object].lastb1colorNumber = b1colorNumber; + object->state.decode[screen].objcache[use_object].lastb2colorNumber = b2colorNumber; + object->state.decode[screen].objcache[use_object].lastused_hCellCount = used_hCellCount; + object->state.decode[screen].objcache[use_object].lastused_vCellCount = used_vCellCount; + object->state.decode[screen].objcache[use_object].lastb2altpenmask = b2altpenmask; + object->state.decode[screen].objcache[use_object].repeatcount = 0; + + object->state.decode[screen].current_object++; + if (object->state.decode[screen].current_object >= DECODECACHE_NUMOBJECTCACHES) + object->state.decode[screen].current_object = 0; } } @@ -1957,8 +1951,8 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) if (!indirect_tile_enable && size < DECODECACHE_NUMSPRITETILES) { - tempshape = object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi; - current_decoded = object->state->decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi_decoded; + tempshape = object->state.decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi; + current_decoded = object->state.decode[screen].objcache[use_object].tiles[v*used_hCellCount + h].tempshape_multi_decoded; /* if (object->screen==0) { @@ -1970,7 +1964,7 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) else { //if (object->screen==0) printf("using base tempshape\n"); - tempshape = object->state->decode[screen].tempshape; + tempshape = object->state.decode[screen].tempshape; } @@ -2127,14 +2121,6 @@ void *coolridr_state::draw_object_threaded(void *param, int threadid) end: - if (object->indirect_tiles) - free(object->indirect_tiles); - - if (object->indirect_zoom) - free(object->indirect_zoom); - - free (object); - return nullptr; } @@ -2239,13 +2225,7 @@ void coolridr_state::blit_current_sprite(address_space &space) return; } - cool_render_object* testobject = (cool_render_object *)malloc(sizeof(cool_render_object)); - - testobject->state = this; - testobject->colbase = m_colbase; - - for (int i=0;i<12;i++) - testobject->spriteblit[i] = m_spriteblit[i]; + std::unique_ptr<cool_render_object> testobject(new cool_render_object(*this)); // cache some values that are looked up from RAM to be safe.. alternatively we could stall the rendering if they get written to, but they're a direct memory pointer.. int test_indirect_tile_enable = (m_spriteblit[5] & 0x00010000)>>16; @@ -2256,7 +2236,7 @@ void coolridr_state::blit_current_sprite(address_space &space) uint16_t test_hCellCount = (m_spriteblit[6] & 0x00003ff); uint16_t test_vCellCount = (m_spriteblit[6] & 0x03ff0000) >> 16; int bytes = test_vCellCount*test_hCellCount; - testobject->indirect_tiles = (uint8_t*)malloc(bytes); + testobject->indirect_tiles = std::make_unique<uint8_t []>(bytes); for (int i=0;i<bytes;i++) { testobject->indirect_tiles[i] = space.read_byte(test_textlookup + i); @@ -2273,7 +2253,7 @@ void coolridr_state::blit_current_sprite(address_space &space) uint32_t test_blit10 = m_spriteblit[10]; uint16_t test_vCellCount = (m_spriteblit[6] & 0x03ff0000) >> 16; int bytes = test_vCellCount * 4 * 16; - testobject->indirect_zoom = (uint32_t*)malloc(bytes); + testobject->indirect_zoom = std::make_unique<uint32_t []>(bytes/4); for (int i=0;i<bytes/4;i++) { testobject->indirect_zoom[i] = space.read_dword(test_blit10 + i*4); @@ -2320,11 +2300,11 @@ void coolridr_state::blit_current_sprite(address_space &space) #if 0 if (m_usethreads) { - osd_work_item_queue(queue, draw_object_threaded, testobject, WORK_ITEM_FLAG_AUTO_RELEASE); + osd_work_item_queue(queue, draw_object_threaded, testobject.release(), WORK_ITEM_FLAG_AUTO_RELEASE); } else { - draw_object_threaded((void*)testobject,0); + draw_object_threaded(testobject.release(), 0); } #else @@ -2332,7 +2312,7 @@ void coolridr_state::blit_current_sprite(address_space &space) { if (m_listcount1<1000000) { - m_cool_render_object_list1[m_listcount1] = testobject; + m_cool_render_object_list1[m_listcount1] = std::move(testobject); m_listcount1++; } else @@ -2344,7 +2324,7 @@ void coolridr_state::blit_current_sprite(address_space &space) { if (m_listcount2<1000000) { - m_cool_render_object_list2[m_listcount2] = testobject; + m_cool_render_object_list2[m_listcount2] = std::move(testobject); m_listcount2++; } else @@ -2587,16 +2567,12 @@ WRITE32_MEMBER(coolridr_state::sysh1_fb_data_w) m_clipblitterMode[0] = 0xff; /* bubble sort, might be something better to use instead */ - for (int pass = 0 ; pass < ( m_listcount1 - 1 ); pass++) + for (int pass = 0 ; pass < (m_listcount1 - 1); pass++) { for (int elem2 = 0 ; elem2 < m_listcount1 - pass - 1; elem2++) { if (m_cool_render_object_list1[elem2]->zpri > m_cool_render_object_list1[elem2+1]->zpri) - { - cool_render_object* temp = m_cool_render_object_list1[elem2]; - m_cool_render_object_list1[elem2] = m_cool_render_object_list1[elem2+1]; - m_cool_render_object_list1[elem2+1] = temp; - } + std::swap(m_cool_render_object_list1[elem2], m_cool_render_object_list1[elem2+1]); } } @@ -2604,11 +2580,11 @@ WRITE32_MEMBER(coolridr_state::sysh1_fb_data_w) { if (m_usethreads) { - osd_work_item_queue(m_work_queue[0], draw_object_threaded, m_cool_render_object_list1[i], WORK_ITEM_FLAG_AUTO_RELEASE); + osd_work_item_queue(m_work_queue[0], draw_object_threaded, m_cool_render_object_list1[i].release(), WORK_ITEM_FLAG_AUTO_RELEASE); } else { - draw_object_threaded((void*)m_cool_render_object_list1[i],0); + draw_object_threaded((void*)m_cool_render_object_list1[i].release(), 0); } } @@ -2638,17 +2614,13 @@ WRITE32_MEMBER(coolridr_state::sysh1_fb_data_w) m_clipvals[1][2] = 0; m_clipblitterMode[1] = 0xff; - /* bubble sort, might be something better to use instead */ - for (int pass = 0 ; pass < ( m_listcount2 - 1 ); pass++) + /* bubble sort, might be something better to use instead */ + for (int pass = 0 ; pass < (m_listcount2 - 1); pass++) { for (int elem2 = 0 ; elem2 < m_listcount2 - pass - 1; elem2++) { if (m_cool_render_object_list2[elem2]->zpri > m_cool_render_object_list2[elem2+1]->zpri) - { - cool_render_object* temp = m_cool_render_object_list2[elem2]; - m_cool_render_object_list2[elem2] = m_cool_render_object_list2[elem2+1]; - m_cool_render_object_list2[elem2+1] = temp; - } + std::swap(m_cool_render_object_list2[elem2], m_cool_render_object_list2[elem2+1]); } } @@ -2656,11 +2628,11 @@ WRITE32_MEMBER(coolridr_state::sysh1_fb_data_w) { if (m_usethreads) { - osd_work_item_queue(m_work_queue[1], draw_object_threaded, m_cool_render_object_list2[i], WORK_ITEM_FLAG_AUTO_RELEASE); + osd_work_item_queue(m_work_queue[1], draw_object_threaded, m_cool_render_object_list2[i].release(), WORK_ITEM_FLAG_AUTO_RELEASE); } else { - draw_object_threaded((void*)m_cool_render_object_list2[i],0); + draw_object_threaded((void*)m_cool_render_object_list2[i].release(), 0); } } @@ -3666,10 +3638,10 @@ void coolridr_state::machine_start() m_h1_pcg = make_unique_clear<uint8_t[]>(VRAM_SIZE); m_h1_pal = make_unique_clear<uint16_t[]>(VRAM_SIZE); - m_cool_render_object_list1 = auto_alloc_array_clear(machine(), struct cool_render_object*, 1000000); + m_cool_render_object_list1 = std::make_unique<std::unique_ptr<cool_render_object> []>(1000000); m_listcount1 = 0; - m_cool_render_object_list2 = auto_alloc_array_clear(machine(), struct cool_render_object*, 1000000); + m_cool_render_object_list2 = std::make_unique<std::unique_ptr<cool_render_object> []>(1000000); m_listcount2 = 0; m_work_queue[0] = osd_work_queue_alloc(WORK_QUEUE_FLAG_HIGH_FREQ); diff --git a/src/mame/drivers/cortex.cpp b/src/mame/drivers/cortex.cpp index a92bb5ddf7b..c4e87619bd7 100644 --- a/src/mame/drivers/cortex.cpp +++ b/src/mame/drivers/cortex.cpp @@ -37,12 +37,13 @@ public: , m_p_ram(*this, "ram") { } +private: virtual void machine_reset() override; required_device<tms9995_device> m_maincpu; required_shared_ptr<uint8_t> m_p_ram; }; -static ADDRESS_MAP_START( cortex_mem, AS_PROGRAM, 8, cortex_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, cortex_state ) AM_RANGE(0x0000, 0xefff) AM_RAM AM_SHARE("ram") AM_RANGE(0xf100, 0xf11f) AM_RAM // memory mapping unit AM_RANGE(0xf120, 0xf120) AM_DEVREADWRITE("tms9928a", tms9928a_device, vram_read, vram_write) @@ -50,7 +51,7 @@ static ADDRESS_MAP_START( cortex_mem, AS_PROGRAM, 8, cortex_state ) //AM_RANGE(0xf140, 0xf147) // fdc tms9909 ADDRESS_MAP_END -static ADDRESS_MAP_START( cortex_io, AS_IO, 8, cortex_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, cortex_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x000f) AM_MIRROR(0x0030) AM_DEVWRITE("control", ls259_device, write_a0) //AM_RANGE(0x0000, 0x000f) AM_MIRROR(0x0020) AM_READ(pio_r) @@ -81,7 +82,7 @@ static MACHINE_CONFIG_START( cortex ) /* TMS9995 CPU @ 12.0 MHz */ // Standard variant, no overflow int // No lines connected yet - MCFG_TMS99xx_ADD("maincpu", TMS9995, 12000000, cortex_mem, cortex_io) + MCFG_TMS99xx_ADD("maincpu", TMS9995, 12000000, mem_map, io_map) MCFG_DEVICE_ADD("control", LS259, 0) // IC64 //MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE(cortex_state, basic_led_w)) @@ -103,12 +104,12 @@ MACHINE_CONFIG_END ROM_START( cortex ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) ROM_SYSTEM_BIOS(0, "basic", "Cortex Bios") - ROMX_LOAD( "cortex_ic47.bin", 0x0000, 0x2000, CRC(bdb8c7bd) SHA1(340829dcb7a65f2e830fd5aff82a312e3ed7918f), ROM_BIOS(1)) - ROMX_LOAD( "cortex_ic46.bin", 0x2000, 0x2000, CRC(4de459ea) SHA1(00a42fe556d4ffe1f85b2ce369f544b07fbd06d9), ROM_BIOS(1)) - ROMX_LOAD( "cortex_ic45.bin", 0x4000, 0x2000, CRC(b0c9b6e8) SHA1(4e20c3f0b7546b803da4805cd3b8616f96c3d923), ROM_BIOS(1)) + ROMX_LOAD( "cortex.ic47", 0x0000, 0x2000, CRC(bdb8c7bd) SHA1(340829dcb7a65f2e830fd5aff82a312e3ed7918f), ROM_BIOS(1)) + ROMX_LOAD( "cortex.ic46", 0x2000, 0x2000, CRC(4de459ea) SHA1(00a42fe556d4ffe1f85b2ce369f544b07fbd06d9), ROM_BIOS(1)) + ROMX_LOAD( "cortex.ic45", 0x4000, 0x2000, CRC(b0c9b6e8) SHA1(4e20c3f0b7546b803da4805cd3b8616f96c3d923), ROM_BIOS(1)) ROM_SYSTEM_BIOS(1, "forth", "FIG-Forth") - ROMX_LOAD( "forth_ic47.bin", 0x0000, 0x2000, CRC(999034be) SHA1(0dcc7404c38aa0ae913101eb0aa98da82104b5d4), ROM_BIOS(2)) - ROMX_LOAD( "forth_ic46.bin", 0x2000, 0x2000, CRC(8eca54cc) SHA1(0f1680e941ef60bb9bde9a4b843b78f30dff3202), ROM_BIOS(2)) + ROMX_LOAD( "forth.ic47", 0x0000, 0x2000, CRC(999034be) SHA1(0dcc7404c38aa0ae913101eb0aa98da82104b5d4), ROM_BIOS(2)) + ROMX_LOAD( "forth.ic46", 0x2000, 0x2000, CRC(8eca54cc) SHA1(0f1680e941ef60bb9bde9a4b843b78f30dff3202), ROM_BIOS(2)) ROM_END /* Driver */ diff --git a/src/mame/drivers/cps2.cpp b/src/mame/drivers/cps2.cpp index bae702d1d62..8998908d2df 100644 --- a/src/mame/drivers/cps2.cpp +++ b/src/mame/drivers/cps2.cpp @@ -9359,8 +9359,8 @@ ROM_END ROM_START( xmvsfur1 ) ROM_REGION( CODE_SIZE, "maincpu", 0 ) /* 68000 code */ - ROM_LOAD16_WORD_SWAP( "xvsu.03h", 0x000000, 0x80000, CRC(5481155a) SHA1(799a2488684cbead33206498d13261b79624a46e) ) /* also found as rev I */ - ROM_LOAD16_WORD_SWAP( "xvsu.04h", 0x080000, 0x80000, CRC(1e236388) SHA1(329c08103840fadbc4176785c4b24013a7a2b1bc) ) /* also found as rev I */ + ROM_LOAD16_WORD_SWAP( "xvsu.03i", 0x000000, 0x80000, CRC(5481155a) SHA1(799a2488684cbead33206498d13261b79624a46e) ) + ROM_LOAD16_WORD_SWAP( "xvsu.04i", 0x080000, 0x80000, CRC(1e236388) SHA1(329c08103840fadbc4176785c4b24013a7a2b1bc) ) ROM_LOAD16_WORD_SWAP( "xvs.05a", 0x100000, 0x80000, CRC(7db6025d) SHA1(2d74f48f83f45359bfaca28ab686625766af12ee) ) ROM_LOAD16_WORD_SWAP( "xvs.06a", 0x180000, 0x80000, CRC(e8e2c75c) SHA1(929408cb5d98e95cec75ea58e4701b0cbdbcd016) ) ROM_LOAD16_WORD_SWAP( "xvs.07", 0x200000, 0x80000, CRC(08f0abed) SHA1(ef16c376232dba63b0b9bc3aa0640f9001ccb68a) ) @@ -9901,12 +9901,12 @@ GAME( 1993, ssf2j, ssf2, cps2, cps2_2p6b, cps_state, cps2, ROT0, GAME( 1993, ssf2jr1, ssf2, cps2, cps2_2p6b, cps_state, cps2, ROT0, "Capcom", "Super Street Fighter II: The New Challengers (Japan 930911)", MACHINE_SUPPORTS_SAVE ) GAME( 1993, ssf2jr2, ssf2, cps2, cps2_2p6b, cps_state, cps2, ROT0, "Capcom", "Super Street Fighter II: The New Challengers (Japan 930910)", MACHINE_SUPPORTS_SAVE ) GAME( 1993, ssf2h, ssf2, cps2, cps2_2p6b, cps_state, cps2, ROT0, "Capcom", "Super Street Fighter II: The New Challengers (Hispanic 930911)", MACHINE_SUPPORTS_SAVE ) -GAME( 1993, ssf2tb, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (World 931119)", MACHINE_SUPPORTS_SAVE ) // works, but not in tournament mode -GAME( 1993, ssf2tbr1, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (World 930911)", MACHINE_SUPPORTS_SAVE ) // works, but not in tournament mode -GAME( 1993, ssf2tbj, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (Japan 931005)", MACHINE_SUPPORTS_SAVE ) // works, but not in tournament mode -GAME( 1993, ssf2tbj1, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (Japan 930911)", MACHINE_SUPPORTS_SAVE ) // works, but not in tournament mode -GAME( 1993, ssf2tba, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (Asia 931005)", MACHINE_SUPPORTS_SAVE ) // works, but not in tournament mode -GAME( 1993, ssf2tbh, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (Hispanic 931005)", MACHINE_SUPPORTS_SAVE ) // works, but not in tournament mode +GAME( 1993, ssf2tb, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (World 931119)", MACHINE_SUPPORTS_SAVE | MACHINE_NODEVICE_LAN ) // works, but not in tournament mode +GAME( 1993, ssf2tbr1, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (World 930911)", MACHINE_SUPPORTS_SAVE | MACHINE_NODEVICE_LAN ) // works, but not in tournament mode +GAME( 1993, ssf2tbj, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (Japan 931005)", MACHINE_SUPPORTS_SAVE | MACHINE_NODEVICE_LAN ) // works, but not in tournament mode +GAME( 1993, ssf2tbj1, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (Japan 930911)", MACHINE_SUPPORTS_SAVE | MACHINE_NODEVICE_LAN ) // works, but not in tournament mode +GAME( 1993, ssf2tba, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (Asia 931005)", MACHINE_SUPPORTS_SAVE | MACHINE_NODEVICE_LAN ) // works, but not in tournament mode +GAME( 1993, ssf2tbh, ssf2, cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "Capcom", "Super Street Fighter II: The Tournament Battle (Hispanic 931005)", MACHINE_SUPPORTS_SAVE | MACHINE_NODEVICE_LAN ) // works, but not in tournament mode GAME( 1993, ecofghtr, 0, cps2, ecofghtr, cps_state, ecofghtr, ROT0, "Capcom", "Eco Fighters (World 931203)", MACHINE_SUPPORTS_SAVE ) GAME( 1993, ecofghtru, ecofghtr, cps2, ecofghtr, cps_state, ecofghtr, ROT0, "Capcom", "Eco Fighters (USA 940215)", MACHINE_SUPPORTS_SAVE ) GAME( 1993, ecofghtru1, ecofghtr, cps2, ecofghtr, cps_state, ecofghtr, ROT0, "Capcom", "Eco Fighters (USA 931203)", MACHINE_SUPPORTS_SAVE ) @@ -11651,7 +11651,7 @@ ROM_END GAME( 1993, ddtodd, ddtod, dead_cps2, cps2_4p4b, cps_state, cps2, ROT0, "bootleg", "Dungeons & Dragons: Tower of Doom (Euro 940412 Phoenix Edition) (bootleg)", MACHINE_SUPPORTS_SAVE ) GAME( 1993, ecofghtrd,ecofghtr, dead_cps2, ecofghtr, cps_state, ecofghtr,ROT0, "bootleg", "Eco Fighters (World 931203 Phoenix Edition) (bootleg)", MACHINE_SUPPORTS_SAVE ) GAME( 1993, ssf2ud, ssf2, dead_cps2, cps2_2p6b, cps_state, cps2, ROT0, "bootleg", "Super Street Fighter II: The New Challengers (USA 930911 Phoenix Edition) (bootleg)", MACHINE_SUPPORTS_SAVE ) -GAME( 1993, ssf2tbd, ssf2, dead_cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "bootleg", "Super Street Fighter II: The Tournament Battle (World 931119 Phoenix Edition) (bootleg)", MACHINE_SUPPORTS_SAVE ) +GAME( 1993, ssf2tbd, ssf2, dead_cps2, cps2_2p6b, cps_state, ssf2tb, ROT0, "bootleg", "Super Street Fighter II: The Tournament Battle (World 931119 Phoenix Edition) (bootleg)", MACHINE_SUPPORTS_SAVE | MACHINE_NODEVICE_LAN ) GAME( 1994, armwar1d, armwar, dead_cps2, cps2_3p3b, cps_state, cps2, ROT0, "bootleg", "Armored Warriors (Euro 941011 Phoenix Edition) (bootleg)", MACHINE_SUPPORTS_SAVE ) GAME( 1994, avspd, avsp, dead_cps2, cps2_3p3b, cps_state, cps2, ROT0, "bootleg", "Alien vs. Predator (Euro 940520 Phoenix Edition) (bootleg)", MACHINE_SUPPORTS_SAVE ) GAME( 1994, dstlku1d, dstlk, dead_cps2, cps2_2p6b, cps_state, cps2, ROT0, "bootleg", "Darkstalkers: The Night Warriors (USA 940705 Phoenix Edition) (bootleg)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/cps3.cpp b/src/mame/drivers/cps3.cpp index e062ed9d7c6..e96091e6a8a 100644 --- a/src/mame/drivers/cps3.cpp +++ b/src/mame/drivers/cps3.cpp @@ -3942,15 +3942,15 @@ GAME( 1999, jojobaner1,jojoba, jojoba, cps3_jojo, cps3_state, jojoba, ROT0 // bootlegs, hold START1 during bootup to change games // newest revision, fixes some issues with Warzard decryption. -GAME( 1999, cps3boot, 0, sfiii3, cps3_jojo, cps3_state, cps3boot, ROT0, "bootleg", "CPS3 Multi-game bootleg for HD6417095 type SH2 (V4)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1999, cps3boota, cps3boot, sfiii3, cps3_jojo, cps3_state, sfiii2, ROT0, "bootleg", "CPS3 Multi-game bootleg for dead security cart (V5)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1999, cps3boot, 0, sfiii3, cps3, cps3_state, cps3boot, ROT0, "bootleg", "CPS3 Multi-game bootleg for HD6417095 type SH2 (V4)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1999, cps3boota, cps3boot, sfiii3, cps3, cps3_state, sfiii2, ROT0, "bootleg", "CPS3 Multi-game bootleg for dead security cart (V5)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1999, cps3booto, cps3boot, sfiii3, cps3_jojo, cps3_state, cps3boot, ROT0, "bootleg", "CPS3 Multi-game bootleg for HD6417095 type SH2 (older)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1999, cps3bootao, cps3boot, sfiii3, cps3_jojo, cps3_state, sfiii2, ROT0, "bootleg", "CPS3 Multi-game bootleg for dead security cart (older)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1999, cps3booto, cps3boot, sfiii3, cps3, cps3_state, cps3boot, ROT0, "bootleg", "CPS3 Multi-game bootleg for HD6417095 type SH2 (older)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1999, cps3bootao, cps3boot, sfiii3, cps3, cps3_state, sfiii2, ROT0, "bootleg", "CPS3 Multi-game bootleg for dead security cart (older)", MACHINE_IMPERFECT_GRAPHICS ) // this doesn't play 2nd Impact despite it being listed. 2nd Impact uses separate data/code encryption and can't be decrypted cleanly for a standard SH2. Selecting it just flashes in a copy of 3rd Strike with the 2nd Impact loading screen -GAME( 1999, cps3booto2, cps3boot, sfiii3, cps3_jojo, cps3_state, cps3boot, ROT0, "bootleg", "CPS3 Multi-game bootleg for HD6417095 type SH2 (oldest) (New Generation, 3rd Strike, JoJo's Venture, JoJo's Bizarre Adventure and Red Earth only)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1999, cps3booto2, cps3boot, sfiii3, cps3, cps3_state, cps3boot, ROT0, "bootleg", "CPS3 Multi-game bootleg for HD6417095 type SH2 (oldest) (New Generation, 3rd Strike, JoJo's Venture, JoJo's Bizarre Adventure and Red Earth only)", MACHINE_IMPERFECT_GRAPHICS ) // this does not play Red Earth or the 2 Jojo games. New Generation and 3rd Strike have been heavily modified to work with the separate code/data encryption a dead cart / 2nd Impact cart has. Selecting the other games will give an 'invalid CD' message. -GAME( 1999, cps3bootao2, cps3boot, sfiii3, cps3_jojo, cps3_state, sfiii2, ROT0, "bootleg", "CPS3 Multi-game bootleg for dead security cart (oldest) (New Generation, 2nd Impact and 3rd Strike only)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1999, cps3bootao2, cps3boot, sfiii3, cps3, cps3_state, sfiii2, ROT0, "bootleg", "CPS3 Multi-game bootleg for dead security cart (oldest) (New Generation, 2nd Impact and 3rd Strike only)", MACHINE_IMPERFECT_GRAPHICS ) // these are test bootleg CDs for running 2nd Impact on a standard SH2 -GAME( 1999, cps3bs32, cps3boot, sfiii3, cps3_jojo, cps3_state, cps3boot, ROT0, "bootleg", "Street Fighter III 2nd Impact: Giant Attack (USA 970930, bootleg for HD6417095 type SH2, V3)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1999, cps3bs32a, cps3boot, sfiii3, cps3_jojo, cps3_state, cps3boot, ROT0, "bootleg", "Street Fighter III 2nd Impact: Giant Attack (USA 970930, bootleg for HD6417095 type SH2, older)", MACHINE_IMPERFECT_GRAPHICS ) // older / buggier hack +GAME( 1999, cps3bs32, cps3boot, sfiii3, cps3, cps3_state, cps3boot, ROT0, "bootleg", "Street Fighter III 2nd Impact: Giant Attack (USA 970930, bootleg for HD6417095 type SH2, V3)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1999, cps3bs32a, cps3boot, sfiii3, cps3, cps3_state, cps3boot, ROT0, "bootleg", "Street Fighter III 2nd Impact: Giant Attack (USA 970930, bootleg for HD6417095 type SH2, older)", MACHINE_IMPERFECT_GRAPHICS ) // older / buggier hack diff --git a/src/mame/drivers/crgolf.cpp b/src/mame/drivers/crgolf.cpp index 8396adabafc..4c5d45d7f80 100644 --- a/src/mame/drivers/crgolf.cpp +++ b/src/mame/drivers/crgolf.cpp @@ -373,6 +373,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( mastrglf_map, AS_PROGRAM, 8, crgolf_state ) AM_RANGE(0x0000, 0x3fff) AM_ROM + AM_RANGE(0x4000, 0x5fff) AM_ROMBANK("bank1") AM_RANGE(0x6000, 0x8fff) AM_RAM // maybe RAM and ROM here? AM_RANGE(0x9000, 0x9fff) AM_RAM AM_RANGE(0xa000, 0xffff) AM_DEVICE("vrambank", address_map_bank_device, amap8) @@ -383,7 +384,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( mastrglf_io, AS_IO, 8, crgolf_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x07) AM_DEVWRITE("mainlatch", ls259_device, write_d0) -// AM_RANGE(0x20, 0x20) AM_WRITE( main_to_sound_w ) +// AM_RANGE(0x20, 0x20) AM_WRITE(rom_bank_select_w) AM_RANGE(0x40, 0x40) AM_WRITE( main_to_sound_w ) AM_RANGE(0xa0, 0xa0) AM_READ( sound_to_main_r ) ADDRESS_MAP_END @@ -418,13 +419,14 @@ WRITE8_MEMBER(crgolf_state::unk_sub_0c_w) static ADDRESS_MAP_START( mastrglf_subio, AS_IO, 8, crgolf_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0x00, 0x00) AM_WRITE(sound_to_main_w) + AM_RANGE(0x00, 0x00) AM_READ(main_to_sound_r) AM_WRITENOP AM_RANGE(0x02, 0x02) AM_READ(unk_sub_02_r ) AM_RANGE(0x05, 0x05) AM_READ(unk_sub_05_r ) + AM_RANGE(0x06, 0x06) AM_READNOP AM_RANGE(0x07, 0x07) AM_READ(unk_sub_07_r ) - + AM_RANGE(0x08, 0x08) AM_WRITE(sound_to_main_w) AM_RANGE(0x0c, 0x0c) AM_WRITE(unk_sub_0c_w) - AM_RANGE(0x06, 0x06) AM_READ(main_to_sound_r) + AM_RANGE(0x10, 0x11) AM_DEVWRITE("aysnd", ay8910_device, address_data_w) ADDRESS_MAP_END @@ -534,8 +536,8 @@ static MACHINE_CONFIG_START( crgolf ) MCFG_DEVICE_ADD("vrambank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vrambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) /* technically 0x6000, but powers of 2 makes the memory map / address masking cleaner. */ MCFG_PALETTE_ADD("palette", 0x20) @@ -829,4 +831,4 @@ GAME( 1984, crgolfc, crgolf, crgolf, crgolf, crgolf_state, 0, ROT0, "N GAME( 1984, crgolfbt, crgolf, crgolf, crgolf, crgolf_state, 0, ROT0, "bootleg", "Champion Golf (bootleg)", MACHINE_SUPPORTS_SAVE ) GAME( 1985, crgolfhi, 0, crgolfhi, crgolf, crgolf_state, crgolfhi, ROT0, "Nasco Japan", "Crowns Golf in Hawaii", MACHINE_SUPPORTS_SAVE ) -GAME( 198?, mastrglf, 0, mastrglf, crgolf, crgolf_state, 0, ROT0, "Nasco", "Master's Golf", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) +GAME( 1985, mastrglf, 0, mastrglf, crgolf, crgolf_state, 0, ROT0, "Nasco", "Master's Golf", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) diff --git a/src/mame/drivers/crimfght.cpp b/src/mame/drivers/crimfght.cpp index ed3e8cf900c..b9da7dfa178 100644 --- a/src/mame/drivers/crimfght.cpp +++ b/src/mame/drivers/crimfght.cpp @@ -311,8 +311,8 @@ static MACHINE_CONFIG_START( crimfght ) MCFG_DEVICE_ADD("bank0000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank0000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(11) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(11) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) MCFG_WATCHDOG_ADD("watchdog") diff --git a/src/mame/drivers/cubo.cpp b/src/mame/drivers/cubo.cpp index a5f10ffcbfe..16dc1625f2c 100644 --- a/src/mame/drivers/cubo.cpp +++ b/src/mame/drivers/cubo.cpp @@ -1033,8 +1033,8 @@ static MACHINE_CONFIG_START( cubo ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_2mb_map32) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_I2CMEM_ADD("i2cmem") diff --git a/src/mame/drivers/cultures.cpp b/src/mame/drivers/cultures.cpp index 0cf708fa830..57af8705e75 100644 --- a/src/mame/drivers/cultures.cpp +++ b/src/mame/drivers/cultures.cpp @@ -405,8 +405,8 @@ static MACHINE_CONFIG_START( cultures ) MCFG_DEVICE_ADD("vrambank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vrambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(15) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(15) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) diff --git a/src/mame/drivers/cv1k.cpp b/src/mame/drivers/cv1k.cpp index 870787cbdb7..da9cf4f3cad 100644 --- a/src/mame/drivers/cv1k.cpp +++ b/src/mame/drivers/cv1k.cpp @@ -138,7 +138,7 @@ Information by The Sheep, rtw, Ex-Cyber, BrianT & Guru ------------------------------------------------------ - To enter service mode in most cases hold down 0 (Service 2) for a few seconds + To enter service mode in most cases hold down Service (F2) for a few seconds (I believe it's the test button on the PCB) Some games also use the test dipswitch as an alternative method. @@ -367,17 +367,18 @@ static ADDRESS_MAP_START( cv1k_port, AS_IO, 64, cv1k_state ) ADDRESS_MAP_END -static INPUT_PORTS_START( cv1k ) +static INPUT_PORTS_START( cv1k_base ) PORT_START("DSW") // 18000050.l (18000050.b + 3 i.e. MSB + 3, is shown as DIPSW) -// PORT_BIT( 0xfcfffffc, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_DIPNAME( 0x00000002, 0x00000000, DEF_STR( Unknown ) ) // S2 2 - PORT_DIPSETTING( 0x00000000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00000002, DEF_STR( On ) ) - PORT_SERVICE( 0x00000001, IP_ACTIVE_HIGH ) // S2 1 + // note: physical switch have default/Off position marked as "ON" which is a bit confusing + PORT_DIPUNUSED_DIPLOC( 0x01, 0x00, "S2:1" ) + PORT_DIPUNUSED_DIPLOC( 0x02, 0x00, "S2:2" ) + PORT_DIPUNUSED_DIPLOC( 0x04, 0x00, "S2:3" ) + PORT_DIPUNUSED_DIPLOC( 0x08, 0x00, "S2:4" ) + PORT_BIT(0xfffffff0, IP_ACTIVE_HIGH, IPT_UNKNOWN) PORT_START("PORT_C") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) // Service coin - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE3 ) // Test Button on JAMMA Edge + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE2 ) // Test Button on JAMMA Edge PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 ) // TODO: IMPLEMENT COIN ERROR! PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) @@ -395,7 +396,7 @@ static INPUT_PORTS_START( cv1k ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_START("PORT_F") - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE2 ) // S3 Test Push Button + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_SERVICE3 ) // S3 Test Push Button PORT_BIT( 0xfd, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("PORT_L") // 4000134.b, 4000136.b @@ -422,6 +423,22 @@ static INPUT_PORTS_START( cv1k ) PORT_ADJUSTER(50, "Blitter Delay") INPUT_PORTS_END +static INPUT_PORTS_START( cv1k ) + PORT_INCLUDE( cv1k_base ) + + PORT_MODIFY("PORT_F") + PORT_SERVICE_NO_TOGGLE( 0x02, IP_ACTIVE_LOW ) // S3 Test Push Button +INPUT_PORTS_END + +static INPUT_PORTS_START( cv1ks ) + PORT_INCLUDE( cv1k_base ) + + PORT_MODIFY("DSW") + PORT_SERVICE_DIPLOC( 0x01, IP_ACTIVE_HIGH, "S2:1") + PORT_DIPNAME( 0x02, 0x00, "Special Mode" ) PORT_DIPLOCATION("S2:2") // also require hold P1 A+B while booting + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x02, DEF_STR( On ) ) +INPUT_PORTS_END void cv1k_state::machine_reset() { @@ -832,6 +849,18 @@ ROM_START( dfkbl ) ROM_LOAD16_WORD_SWAP( "u24", 0x400000, 0x400000, CRC(31f9eb0a) SHA1(322158779e969bb321241065dd49c1167b91ff6c) ) ROM_END +ROM_START( akatana ) + ROM_REGION( 0x400000, "maincpu", ROMREGION_ERASEFF) + ROM_LOAD16_WORD_SWAP( "u4", 0x000000, 0x400000, CRC(613fd380) SHA1(6e28480eef3b483d00b42d811a9d2c7fa1097924) ) // (2010/ 8/13 MASTER VER.) + + ROM_REGION( 0x8400000, "game", ROMREGION_ERASEFF) + ROM_LOAD( "u2", 0x000000, 0x8400000, CRC(89a2e1a5) SHA1(e6f4ec974406283665697fdd52bd606d0337dd11) ) + + ROM_REGION( 0x800000, "ymz770", ROMREGION_ERASEFF) + ROM_LOAD16_WORD_SWAP( "u23", 0x000000, 0x400000, CRC(34a67e24) SHA1(78a7e82123b86311f1116a80c39f147b8b695549) ) + ROM_LOAD16_WORD_SWAP( "u24", 0x400000, 0x400000, CRC(10760fed) SHA1(b70f4506c00f3901ff38f5efd4b897af1afc7a0c) ) +ROM_END + READ64_MEMBER(cv1k_state::speedup_r) { offs_t pc = downcast<cpu_device *>(&space.device())->pc(); @@ -892,7 +921,6 @@ DRIVER_INIT_MEMBER(cv1k_state,deathsml) DRIVER_INIT_MEMBER(cv1k_state,dpddfk) { install_speedups(0x02310, 0xc1d1346, true); - } #define GAME_FLAGS (MACHINE_IMPERFECT_TIMING) @@ -905,11 +933,11 @@ GAME( 2004, mushisama, mushisam, cv1k, cv1k, cv1k_state, ibara, ROT270, " GAME( 2004, mushisamb, mushisam, cv1k, cv1k, cv1k_state, mushisam, ROT270, "Cave (AMI license)", "Mushihime-Sama (2004/10/12 MASTER VER)", GAME_FLAGS ) // CA012 Ibara -GAME( 2005, ibara, 0, cv1k, cv1k, cv1k_state, ibara, ROT270, "Cave (AMI license)", "Ibara (2005/03/22 MASTER VER..)", GAME_FLAGS ) +GAME( 2005, ibara, 0, cv1k, cv1ks,cv1k_state, ibara, ROT270, "Cave (AMI license)", "Ibara (2005/03/22 MASTER VER..)", GAME_FLAGS ) // CA012B Ibara Kuro Black Label -GAME( 2006, ibarablk, 0, cv1k, cv1k, cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Ibara Kuro Black Label (2006/02/06. MASTER VER.)", GAME_FLAGS ) -GAME( 2006, ibarablka, ibarablk, cv1k, cv1k, cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Ibara Kuro Black Label (2006/02/06 MASTER VER.)", GAME_FLAGS ) +GAME( 2006, ibarablk, 0, cv1k, cv1ks,cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Ibara Kuro Black Label (2006/02/06. MASTER VER.)", GAME_FLAGS ) +GAME( 2006, ibarablka, ibarablk, cv1k, cv1ks,cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Ibara Kuro Black Label (2006/02/06 MASTER VER.)", GAME_FLAGS ) // CA013 Espgaluda II GAME( 2005, espgal2, 0, cv1k, cv1k, cv1k_state, espgal2, ROT270, "Cave (AMI license)", "Espgaluda II (2005/11/14 MASTER VER)", GAME_FLAGS ) @@ -919,10 +947,10 @@ GAME( 2005, mushitam, 0, cv1k, cv1k, cv1k_state, mushitam, ROT0, " GAME( 2005, mushitama, mushitam, cv1k, cv1k, cv1k_state, mushitam, ROT0, "Cave (AMI license)", "Puzzle! Mushihime-Tama (2005/09/09 MASTER VER)", GAME_FLAGS ) // CA014 Pink Sweets: Ibara Sorekara -GAME( 2006, pinkswts, 0, cv1k, cv1k, cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Pink Sweets: Ibara Sorekara (2006/04/06 MASTER VER....)", GAME_FLAGS ) -GAME( 2006, pinkswtsa, pinkswts, cv1k, cv1k, cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Pink Sweets: Ibara Sorekara (2006/04/06 MASTER VER...)", GAME_FLAGS ) -GAME( 2006, pinkswtsb, pinkswts, cv1k, cv1k, cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Pink Sweets: Ibara Sorekara (2006/04/06 MASTER VER.)", GAME_FLAGS ) -GAME( 2006, pinkswtsx, pinkswts, cv1k, cv1k, cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Pink Sweets: Ibara Sorekara (2006/xx/xx MASTER VER.)", GAME_FLAGS ) // defaults to freeplay, possibly bootlegged from show/dev version? +GAME( 2006, pinkswts, 0, cv1k, cv1ks,cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Pink Sweets: Ibara Sorekara (2006/04/06 MASTER VER....)", GAME_FLAGS ) +GAME( 2006, pinkswtsa, pinkswts, cv1k, cv1ks,cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Pink Sweets: Ibara Sorekara (2006/04/06 MASTER VER...)", GAME_FLAGS ) +GAME( 2006, pinkswtsb, pinkswts, cv1k, cv1ks,cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Pink Sweets: Ibara Sorekara (2006/04/06 MASTER VER.)", GAME_FLAGS ) +GAME( 2006, pinkswtsx, pinkswts, cv1k, cv1ks,cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Pink Sweets: Ibara Sorekara (2006/xx/xx MASTER VER.)", GAME_FLAGS ) // defaults to freeplay, possibly bootlegged from show/dev version? // CA015 Mushihime-Sama Futari GAME( 2006, futari15, 0, cv1k, cv1k, cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Mushihime-Sama Futari Ver 1.5 (2006/12/8.MASTER VER. 1.54.)", GAME_FLAGS ) @@ -934,7 +962,7 @@ GAME( 2007, futaribl, 0, cv1k, cv1k, cv1k_state, pinkswts, ROT270, " GAME( 2007, futariblj, futaribl, cv1k, cv1k, cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Mushihime-Sama Futari Black Label (2007/12/11 BLACK LABEL VER)", GAME_FLAGS ) // CA016 Muchi Muchi Pork! -GAME( 2007, mmpork, 0, cv1k, cv1k, cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Muchi Muchi Pork! (2007/ 4/17 MASTER VER.)", GAME_FLAGS ) +GAME( 2007, mmpork, 0, cv1k, cv1ks,cv1k_state, pinkswts, ROT270, "Cave (AMI license)", "Muchi Muchi Pork! (2007/ 4/17 MASTER VER.)", GAME_FLAGS ) // CA017 Deathsmiles GAME( 2007, deathsml, 0, cv1k, cv1k, cv1k_state, deathsml, ROT0, "Cave (AMI license)", "Deathsmiles (2007/10/09 MASTER VER)", GAME_FLAGS ) @@ -949,5 +977,8 @@ GAME( 2008, ddpdfk10, ddpdfk, cv1k_d, cv1k, cv1k_state, dpddfk, ROT270, " // CA019B Do-Don-Pachi Dai-Fukkatsu Black Label GAME( 2010, dfkbl, 0, cv1k_d, cv1k, cv1k_state, dpddfk, ROT270, "Cave (AMI license)", "DoDonPachi Dai-Fukkatsu Black Label (2010/1/18 BLACK LABEL)", GAME_FLAGS ) +// CA021 Akai Katana +GAME( 2010, akatana, 0, cv1k_d, cv1k, cv1k_state, dpddfk, ROT0, "Cave (AMI license)", "Akai Katana (2010/ 8/13 MASTER VER.)", GAME_FLAGS ) + // CMDL01 Medal Mahjong Moukari Bancho GAME( 2007, mmmbanc, 0, cv1k, cv1k, cv1k_state, pinkswts, ROT0, "Cave (AMI license)", "Medal Mahjong Moukari Bancho (2007/06/05 MASTER VER.)", MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/cvs.cpp b/src/mame/drivers/cvs.cpp index 0dddf8e6a87..8581b6b4a36 100644 --- a/src/mame/drivers/cvs.cpp +++ b/src/mame/drivers/cvs.cpp @@ -227,8 +227,7 @@ WRITE8_MEMBER(cvs_state::cvs_s2636_2_or_character_ram_w) INTERRUPT_GEN_MEMBER(cvs_state::cvs_main_cpu_interrupt) { - device.execute().set_input_line_vector(0, 0x03); - generic_pulse_irq_line(device.execute(), 0, 1); + device.execute().pulse_input_line_and_vector(0, 0x03, device.execute().minimum_quantum_time()); cvs_scroll_stars(); } diff --git a/src/mame/drivers/cyclemb.cpp b/src/mame/drivers/cyclemb.cpp index 99ba6e1790e..65d6b3fa6fb 100644 --- a/src/mame/drivers/cyclemb.cpp +++ b/src/mame/drivers/cyclemb.cpp @@ -102,7 +102,7 @@ public: required_device<cpu_device> m_audiocpu; required_device<gfxdecode_device> m_gfxdecode; required_device<palette_device> m_palette; - required_device<generic_latch_8_device> m_soundlatch; + optional_device<generic_latch_8_device> m_soundlatch; required_shared_ptr<uint8_t> m_vram; required_shared_ptr<uint8_t> m_cram; @@ -127,6 +127,9 @@ public: DECLARE_WRITE8_MEMBER(cyclemb_flip_w); DECLARE_READ8_MEMBER(skydest_i8741_0_r); DECLARE_WRITE8_MEMBER(skydest_i8741_0_w); + DECLARE_READ8_MEMBER(skydest_i8741_1_r); + DECLARE_WRITE8_MEMBER(skydest_i8741_1_w); +// DECLARE_WRITE_LINE_MEMBER(ym_irq); DECLARE_DRIVER_INIT(skydest); DECLARE_DRIVER_INIT(cyclemb); @@ -542,16 +545,22 @@ WRITE8_MEMBER( cyclemb_state::skydest_i8741_0_w ) } else { - //printf("%02x DATA PC=%04x\n",data,m_maincpu->pc()); - m_mcu[0].txd = data; + m_mcu[1].rst = 0; + m_soundlatch->write(space, 0, data & 0xff); + if(m_mcu[0].txd == 0x41) m_mcu[0].state = 1; - if(m_mcu[0].txd == 0x42) + else if(m_mcu[0].txd == 0x42) m_mcu[0].state = 2; - if(m_mcu[0].txd == 0x44) + else if(m_mcu[0].txd == 0x44) m_mcu[0].state = 3; + else + { + + //m_audiocpu->set_input_line(0, HOLD_LINE); + } } } @@ -592,10 +601,35 @@ static ADDRESS_MAP_START( cyclemb_sound_map, AS_PROGRAM, 8, cyclemb_state ) ADDRESS_MAP_END +READ8_MEMBER(cyclemb_state::skydest_i8741_1_r) +{ + // status + if(offset == 1) + return 1; + + if(m_mcu[1].rst == 1) + return 0x40; + + return m_soundlatch->read(space,0); +} + +WRITE8_MEMBER(cyclemb_state::skydest_i8741_1_w) +{ +// printf("%02x %02x\n",offset,data); + if(offset == 1) + { + if(data == 0xf0) + m_mcu[1].rst = 1; + } + //else + // m_soundlatch->clear_w(space, 0, 0); +} + + static ADDRESS_MAP_START( cyclemb_sound_io, AS_IO, 8, cyclemb_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x01) AM_DEVREADWRITE("ymsnd", ym2203_device, read, write) - AM_RANGE(0x40, 0x40) AM_DEVREAD("soundlatch", generic_latch_8_device, read) AM_DEVWRITE("soundlatch2", generic_latch_8_device, write) + AM_RANGE(0x40, 0x41) AM_READWRITE(skydest_i8741_1_r, skydest_i8741_1_w) ADDRESS_MAP_END @@ -822,12 +856,11 @@ static INPUT_PORTS_START( skydest ) PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x18, 0x10, DEF_STR( Lives ) ) + PORT_DIPSETTING( 0x00, "4" ) + PORT_DIPSETTING( 0x08, "3" ) + PORT_DIPSETTING( 0x10, "2" ) + PORT_DIPSETTING( 0x18, "1" ) PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("DSW2") @@ -849,7 +882,7 @@ static INPUT_PORTS_START( skydest ) PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("DSW3") - PORT_DIPNAME( 0x01, 0x01, "DSW3" ) + PORT_DIPNAME( 0x01, 0x01, DEF_STR( Demo_Sounds ) ) PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x02, 0x00, DEF_STR( Free_Play ) ) @@ -868,6 +901,8 @@ static INPUT_PORTS_START( skydest ) PORT_DIPNAME( 0x80, 0x00, "Invincibility (Cheat)" ) PORT_DIPSETTING( 0x80, DEF_STR( Yes ) ) PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + + INPUT_PORTS_END static const gfx_layout charlayout = @@ -927,6 +962,7 @@ static MACHINE_CONFIG_START( cyclemb ) MCFG_CPU_ADD("audiocpu", Z80, XTAL_18MHz/6) MCFG_CPU_PROGRAM_MAP(cyclemb_sound_map) MCFG_CPU_IO_MAP(cyclemb_sound_io) + MCFG_CPU_PERIODIC_INT_DRIVER(cyclemb_state, irq0_line_hold, 60) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -949,6 +985,8 @@ static MACHINE_CONFIG_START( cyclemb ) MCFG_GENERIC_LATCH_8_ADD("soundlatch2") MCFG_SOUND_ADD("ymsnd", YM2203, XTAL_18MHz/12) +// MCFG_YM2203_IRQ_HANDLER(WRITELINE(cyclemb_state, ym_irq)) +// MCFG_AY8910_PORT_B_READ_CB(IOPORT("UNK")) /* port B read */ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) MACHINE_CONFIG_END @@ -1042,15 +1080,35 @@ ROM_END DRIVER_INIT_MEMBER(cyclemb_state,cyclemb) { + uint8_t *rom = memregion("audiocpu")->base(); + membank("bank1")->configure_entries(0, 4, memregion("maincpu")->base() + 0x10000, 0x1000); m_dsw_pc_hack = 0x760; + + // patch audio CPU crash + ROM checksum + rom[0x282] = 0x00; + rom[0x283] = 0x00; + rom[0x284] = 0x00; + rom[0xa36] = 0x00; + rom[0xa37] = 0x00; + rom[0xa38] = 0x00; } DRIVER_INIT_MEMBER(cyclemb_state,skydest) { + uint8_t *rom = memregion("audiocpu")->base(); + membank("bank1")->configure_entries(0, 4, memregion("maincpu")->base() + 0x10000, 0x1000); m_dsw_pc_hack = 0x554; + + // patch audio CPU crash + ROM checksum + rom[0x286] = 0x00; + rom[0x287] = 0x00; + rom[0x288] = 0x00; + rom[0xa36] = 0x00; + rom[0xa37] = 0x00; + rom[0xa38] = 0x00; } -GAME( 1984, cyclemb, 0, cyclemb, cyclemb, cyclemb_state, cyclemb, ROT0, "Taito Corporation", "Cycle Maabou (Japan)", MACHINE_NO_COCKTAIL | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1985, skydest, 0, skydest, skydest, cyclemb_state, skydest, ROT0, "Taito Corporation", "Sky Destroyer (Japan)", MACHINE_NO_COCKTAIL | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, cyclemb, 0, cyclemb, cyclemb, cyclemb_state, cyclemb, ROT0, "Taito Corporation", "Cycle Maabou (Japan)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1985, skydest, 0, skydest, skydest, cyclemb_state, skydest, ROT0, "Taito Corporation", "Sky Destroyer (Japan)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/czk80.cpp b/src/mame/drivers/czk80.cpp index 0606970f2c7..1f91ac23027 100644 --- a/src/mame/drivers/czk80.cpp +++ b/src/mame/drivers/czk80.cpp @@ -55,12 +55,11 @@ class czk80_state : public driver_device { public: czk80_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG), - m_fdc(*this, "fdc") - { - } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_terminal(*this, "terminal") + , m_fdc(*this, "fdc") + { } DECLARE_DRIVER_INIT(czk80); DECLARE_MACHINE_RESET(czk80); @@ -112,10 +111,10 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(czk80_io, AS_IO, 8, czk80_state) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x40, 0x40) AM_WRITE(port40_w) - AM_RANGE(0x4c, 0x4f) AM_DEVREADWRITE("z80pio", z80pio_device, read, write) - AM_RANGE(0x50, 0x53) AM_DEVREADWRITE("z80dart", z80dart_device, cd_ba_r, cd_ba_w) - AM_RANGE(0x54, 0x57) AM_DEVREADWRITE("z80ctc", z80ctc_device, read, write) - AM_RANGE(0x80, 0x80) AM_READ(port80_r) AM_DEVWRITE(TERMINAL_TAG, generic_terminal_device, write) + AM_RANGE(0x4c, 0x4f) AM_DEVREADWRITE("pio", z80pio_device, read, write) + AM_RANGE(0x50, 0x53) AM_DEVREADWRITE("dart", z80dart_device, cd_ba_r, cd_ba_w) + AM_RANGE(0x54, 0x57) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) + AM_RANGE(0x80, 0x80) AM_READ(port80_r) AM_DEVWRITE("terminal", generic_terminal_device, write) AM_RANGE(0x81, 0x81) AM_READ(port81_r) /* Select one of the below */ //AM_RANGE(0xc0, 0xc0) AM_READ(portc0_r) @@ -130,9 +129,9 @@ INPUT_PORTS_END static const z80_daisy_config daisy_chain[] = { - { "z80pio" }, - { "z80dart" }, - { "z80ctc" }, + { "pio" }, + { "dart" }, + { "ctc" }, { nullptr } }; @@ -196,24 +195,24 @@ static MACHINE_CONFIG_START( czk80 ) MCFG_Z80_DAISY_CHAIN(daisy_chain) MCFG_MACHINE_RESET_OVERRIDE(czk80_state, czk80) - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) + MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(czk80_state, kbd_put)) MCFG_UPD765A_ADD("fdc", false, true) MCFG_FLOPPY_DRIVE_ADD("fdc:0", czk80_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_DEVICE_ADD("z80ctc", Z80CTC, XTAL_16MHz / 4) + MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_16MHz / 4) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_Z80CTC_ZC0_CB(WRITELINE(czk80_state, ctc_z0_w)) MCFG_Z80CTC_ZC1_CB(WRITELINE(czk80_state, ctc_z1_w)) MCFG_Z80CTC_ZC2_CB(WRITELINE(czk80_state, ctc_z2_w)) - MCFG_DEVICE_ADD("z80dart", Z80DART, XTAL_16MHz / 4) + MCFG_DEVICE_ADD("dart", Z80DART, XTAL_16MHz / 4) //MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) //MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) //MCFG_Z80DART_OUT_RTSA_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("z80pio", Z80PIO, XTAL_16MHz/4) + MCFG_DEVICE_ADD("pio", Z80PIO, XTAL_16MHz/4) MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MACHINE_CONFIG_END diff --git a/src/mame/drivers/d400.cpp b/src/mame/drivers/d400.cpp new file mode 100644 index 00000000000..d3d943d8eb0 --- /dev/null +++ b/src/mame/drivers/d400.cpp @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +Skeleton driver for Data General Dasher 400 series terminals. + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/m6809/m6809.h" +#include "machine/mc68681.h" +#include "machine/x2212.h" + +class d400_state : public driver_device +{ +public: + d400_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { } + +private: + required_device<cpu_device> m_maincpu; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, d400_state ) + AM_RANGE(0x0000, 0x3fff) AM_RAM + AM_RANGE(0x4800, 0x48ff) AM_RAM + AM_RANGE(0x5000, 0x50ff) AM_RAM + AM_RANGE(0x6000, 0x6fff) AM_RAM + AM_RANGE(0x7800, 0x780f) AM_DEVREADWRITE("duart", scn2681_device, read, write) + AM_RANGE(0x7880, 0x78bf) AM_DEVREADWRITE("novram", x2210_device, read, write) + AM_RANGE(0x7c00, 0x7c00) AM_WRITENOP + AM_RANGE(0x8000, 0xffff) AM_ROM AM_REGION("maincpu", 0) +ADDRESS_MAP_END + +static INPUT_PORTS_START( d461 ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( d461 ) + MCFG_CPU_ADD("maincpu", M6809, 4'000'000) + MCFG_CPU_PROGRAM_MAP(mem_map) + + MCFG_DEVICE_ADD("novram", X2210, 0) + + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) +MACHINE_CONFIG_END + + + +/************************************************************************************************************** + +Data General D461. +Chips: SCN2681A, X2210P, 2x HM6116P-2, 2x HM6264P-20, HD68B09EP, CRT9007, 1x 8-sw dip. +Crystals: 3.6864, 59.2920 + +***************************************************************************************************************/ + +ROM_START( d461 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "dgc_100_5776-05.bin", 0x0000, 0x8000, CRC(fdce2132) SHA1(82eac1751c31f99d4490505e16af5e7e7a52b310) ) +ROM_END + +COMP( 1986, d461, 0, 0, d461, d461, d400_state, 0, "Data General", "Dasher D461", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/d6809.cpp b/src/mame/drivers/d6809.cpp index 7a49d95d000..8f3a08878c6 100644 --- a/src/mame/drivers/d6809.cpp +++ b/src/mame/drivers/d6809.cpp @@ -87,25 +87,25 @@ devices. #include "machine/mos6551.h" #include "machine/terminal.h" -#define TERMINAL_TAG "terminal" class d6809_state : public driver_device { public: d6809_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG) - { - } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_terminal(*this, "terminal") + { } - required_device<cpu_device> m_maincpu; - required_device<generic_terminal_device> m_terminal; - void kbd_put(u8 data); DECLARE_READ8_MEMBER( term_r ); DECLARE_WRITE8_MEMBER( term_w ); + void kbd_put(u8 data); + +private: uint8_t m_term_data; virtual void machine_reset() override; + required_device<cpu_device> m_maincpu; + required_device<generic_terminal_device> m_terminal; }; READ8_MEMBER( d6809_state::term_r ) @@ -121,14 +121,14 @@ WRITE8_MEMBER( d6809_state::term_w ) m_terminal->write(space, 0, data); } -static ADDRESS_MAP_START( d6809_mem, AS_PROGRAM, 8, d6809_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, d6809_state ) ADDRESS_MAP_UNMAP_HIGH // 00-FF is for various devices. AM_RANGE(0x0000, 0x0003) AM_DEVREADWRITE("acia1", mos6551_device, read, write) AM_RANGE(0x0004, 0x0007) AM_DEVREADWRITE("acia2", mos6551_device, read, write) AM_RANGE(0x00ff, 0x00ff) AM_READWRITE(term_r,term_w) AM_RANGE(0x1000, 0xdfff) AM_RAM - AM_RANGE(0xe000, 0xffff) AM_ROM + AM_RANGE(0xe000, 0xffff) AM_ROM AM_REGION("roms", 0) ADDRESS_MAP_END @@ -150,20 +150,20 @@ void d6809_state::machine_reset() static MACHINE_CONFIG_START( d6809 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M6809, XTAL_14_7456MHz / 8) // MC68B09EP - MCFG_CPU_PROGRAM_MAP(d6809_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) MCFG_DEVICE_ADD("acia1", MOS6551, XTAL_14_7456MHz / 8) // uses Q clock MCFG_DEVICE_ADD("acia2", MOS6551, XTAL_14_7456MHz / 8) // uses Q clock /* video hardware */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) + MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(d6809_state, kbd_put)) MACHINE_CONFIG_END /* ROM definition */ ROM_START( d6809 ) - ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "d6809.rom", 0xe000, 0x2000, CRC(2ceb40b8) SHA1(780111541234b4f0f781a118d955df61daa56e7e)) + ROM_REGION( 0x2000, "roms", 0 ) + ROM_LOAD( "d6809.rom", 0x0000, 0x2000, CRC(2ceb40b8) SHA1(780111541234b4f0f781a118d955df61daa56e7e)) ROM_END /* Driver */ diff --git a/src/mame/drivers/darius.cpp b/src/mame/drivers/darius.cpp index a59127405ec..907e3614e88 100644 --- a/src/mame/drivers/darius.cpp +++ b/src/mame/drivers/darius.cpp @@ -170,65 +170,21 @@ WRITE16_MEMBER(darius_state::cpua_ctrl_w) GAME INPUTS **********************************************************/ -READ16_MEMBER(darius_state::darius_ioc_r) +READ16_MEMBER(darius_state::coin_r) { - switch (offset) - { - case 0x01: - return (m_ciu->master_comm_r(space, 0) & 0xff); /* sound interface read */ - - case 0x04: - return ioport("P1")->read(); - - case 0x05: - return ioport("P2")->read(); - - case 0x06: - return ioport("SYSTEM")->read(); - - case 0x07: - return m_coin_word; /* bits 3&4 coin lockouts, must return zero */ - - case 0x08: - return ioport("DSW")->read(); - } - -logerror("CPU #0 PC %06x: warning - read unmapped ioc offset %06x\n",space.device().safe_pc(),offset); - - return 0xff; + return m_coin_word; /* bits 3&4 coin lockouts, must return zero */ } -WRITE16_MEMBER(darius_state::darius_ioc_w) +WRITE16_MEMBER(darius_state::coin_w) { - switch (offset) - { - case 0x00: /* sound interface write */ - - m_ciu->master_port_w(space, 0, data & 0xff); - return; - - case 0x01: /* sound interface write */ - - m_ciu->master_comm_w(space, 0, data & 0xff); - return; - - case 0x28: /* unknown, written by both cpus - always 0? */ -//popmessage(" address %04x value %04x",offset,data); - return; - - case 0x30: /* coin control */ - /* bits 7,5,4,0 used on reset */ - /* bit 4 used whenever bg is blanked ? */ - machine().bookkeeping().coin_lockout_w(0, ~data & 0x02); - machine().bookkeeping().coin_lockout_w(1, ~data & 0x04); - machine().bookkeeping().coin_counter_w(0, data & 0x08); - machine().bookkeeping().coin_counter_w(1, data & 0x40); - m_coin_word = data & 0xffff; -//popmessage(" address %04x value %04x",offset,data); - return; - } - -logerror("CPU #0 PC %06x: warning - write unmapped ioc offset %06x with %04x\n",space.device().safe_pc(),offset,data); + /* coin control */ + /* bits 7,5,4,0 used on reset */ + /* bit 4 used whenever bg is blanked ? */ + machine().bookkeeping().coin_lockout_w(0, ~data & 0x02); + machine().bookkeeping().coin_lockout_w(1, ~data & 0x04); + machine().bookkeeping().coin_counter_w(0, data & 0x08); + machine().bookkeeping().coin_counter_w(1, data & 0x40); + m_coin_word = data; } @@ -240,8 +196,16 @@ static ADDRESS_MAP_START( darius_map, AS_PROGRAM, 16, darius_state ) AM_RANGE(0x000000, 0x05ffff) AM_ROM AM_RANGE(0x080000, 0x08ffff) AM_RAM /* main RAM */ AM_RANGE(0x0a0000, 0x0a0001) AM_WRITE(cpua_ctrl_w) - AM_RANGE(0x0b0000, 0x0b0001) AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w) - AM_RANGE(0xc00000, 0xc0007f) AM_READWRITE(darius_ioc_r, darius_ioc_w) /* inputs, sound */ + AM_RANGE(0x0b0000, 0x0b0001) AM_DEVREADWRITE("watchdog", watchdog_timer_device, reset16_r, reset16_w) + AM_RANGE(0xc00000, 0xc00001) AM_READNOP AM_DEVWRITE8("ciu", pc060ha_device, master_port_w, 0x00ff) + AM_RANGE(0xc00002, 0xc00003) AM_DEVREADWRITE8("ciu", pc060ha_device, master_comm_r, master_comm_w, 0x00ff) + AM_RANGE(0xc00008, 0xc00009) AM_READ_PORT("P1") + AM_RANGE(0xc0000a, 0xc0000b) AM_READ_PORT("P2") + AM_RANGE(0xc0000c, 0xc0000d) AM_READ_PORT("SYSTEM") + AM_RANGE(0xc0000e, 0xc0000f) AM_READ(coin_r) + AM_RANGE(0xc00010, 0xc00011) AM_READ_PORT("DSW") + AM_RANGE(0xc00050, 0xc00051) AM_NOP // unknown, written by both cpus - always 0? + AM_RANGE(0xc00060, 0xc00061) AM_WRITE(coin_w) AM_RANGE(0xd00000, 0xd0ffff) AM_DEVREADWRITE("pc080sn", pc080sn_device, word_r, word_w) /* tilemaps */ AM_RANGE(0xd20000, 0xd20003) AM_DEVWRITE("pc080sn", pc080sn_device, yscroll_word_w) AM_RANGE(0xd40000, 0xd40003) AM_DEVWRITE("pc080sn", pc080sn_device, xscroll_word_w) @@ -256,7 +220,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( darius_cpub_map, AS_PROGRAM, 16, darius_state ) AM_RANGE(0x000000, 0x03ffff) AM_ROM AM_RANGE(0x040000, 0x04ffff) AM_RAM /* local RAM */ - AM_RANGE(0xc00000, 0xc0007f) AM_WRITE(darius_ioc_w) /* only writes $c00050 (?) */ + AM_RANGE(0xc00050, 0xc00051) AM_NOP // unknown, written by both cpus - always 0? AM_RANGE(0xd80000, 0xd80fff) AM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") AM_RANGE(0xe00100, 0xe00fff) AM_RAM AM_SHARE("spriteram") AM_RANGE(0xe01000, 0xe02fff) AM_RAM AM_SHARE("share2") diff --git a/src/mame/drivers/datum.cpp b/src/mame/drivers/datum.cpp index aee05bd229b..4525617cc4c 100644 --- a/src/mame/drivers/datum.cpp +++ b/src/mame/drivers/datum.cpp @@ -84,8 +84,7 @@ static ADDRESS_MAP_START(datum_mem, AS_PROGRAM, 8, datum_state) ADDRESS_MAP_GLOBAL_MASK (0x7fff) // A15 not used AM_RANGE(0x0000, 0x007f) AM_RAM // inside CPU AM_RANGE(0x1000, 0x13ff) AM_MIRROR(0x0c00) AM_RAM // main ram 2x 2114 - AM_RANGE(0x4000, 0x4000) AM_MIRROR(0x0ffe) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0x4001, 0x4001) AM_MIRROR(0x0ffe) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0x4000, 0x4001) AM_MIRROR(0x0ffe) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0x5000, 0x5003) AM_MIRROR(0x0ffc) AM_DEVREADWRITE("pia2", pia6821_device, read, write) AM_RANGE(0x6000, 0x6003) AM_MIRROR(0x0ffc) AM_DEVREADWRITE("pia1", pia6821_device, read, write) AM_RANGE(0x7000, 0x77ff) AM_MIRROR(0x0800) AM_ROM AM_REGION("roms", 0) diff --git a/src/mame/drivers/dccons.cpp b/src/mame/drivers/dccons.cpp index 746d7979e8a..9f3e959a2ae 100644 --- a/src/mame/drivers/dccons.cpp +++ b/src/mame/drivers/dccons.cpp @@ -752,5 +752,5 @@ ROM_END CONS( 1999, dc, dcjp, 0, dc, dc, dc_cons_state, dcus, "Sega", "Dreamcast (USA, NTSC)", MACHINE_NOT_WORKING ) CONS( 1998, dcjp, 0, 0, dc, dc, dc_cons_state, dcjp, "Sega", "Dreamcast (Japan, NTSC)", MACHINE_NOT_WORKING ) CONS( 1999, dceu, dcjp, 0, dc, dc, dc_cons_state, dcus, "Sega", "Dreamcast (Europe, PAL)", MACHINE_NOT_WORKING ) -CONS( 200?, dctream,dcjp, 0, dc, dc, dc_cons_state, dcus,"unknown", "Treamcast", MACHINE_NOT_WORKING ) +CONS( 200?, dctream,dcjp, 0, dc, dc, dc_cons_state, dcus, "<unknown>", "Treamcast", MACHINE_NOT_WORKING ) CONS( 1998, dcdev, 0, 0, dc, dc, dc_cons_state, dc, "Sega", "HKT-0120 Sega Dreamcast Development Box", MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/ddenlovr.cpp b/src/mame/drivers/ddenlovr.cpp index 5ebb9394feb..1129d1aef94 100644 --- a/src/mame/drivers/ddenlovr.cpp +++ b/src/mame/drivers/ddenlovr.cpp @@ -4273,8 +4273,8 @@ static MACHINE_CONFIG_START( htengoku ) MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(htengoku_banked_map) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MCFG_MACHINE_START_OVERRIDE(ddenlovr_state,dynax) diff --git a/src/mame/drivers/dec0.cpp b/src/mame/drivers/dec0.cpp index 5a010d14dd6..82e09f425dd 100644 --- a/src/mame/drivers/dec0.cpp +++ b/src/mame/drivers/dec0.cpp @@ -48,7 +48,7 @@ ToDo: - graphics are completely broken in Secret Agent (bootleg); - Fighting Fantasy (bootleg) doesn't move on when killing the Lamia, is the MCU involved? - Hook up the 68705 in Midnight Resistance (bootleg) (it might not be used, leftover from the Fighting Fantasy bootleg on the same PCB?) -- Get rid of ROM patches in Sly Spy and Hippodrome; +- Get rid of ROM patch in Hippodrome; - background pen in Birdie Try is presumably wrong. - Pixel clock frequency isn't verified; - Finally, get a proper decap of the MCUs used by Dragonninja and Birdie Try; @@ -500,14 +500,20 @@ READ16_MEMBER(dec0_state::slyspy_controls_r) return ~0; } +// TODO: this can be a timer access, maybe video counter returns (and used as RNG in both games) READ16_MEMBER(dec0_state::slyspy_protection_r) { - /* These values are for Boulderdash, I have no idea what they do in Slyspy */ - switch (offset<<1) { + switch (offset<<1) + { + /* These values are for Boulderdash, I have no idea what they do in Slyspy */ case 0: return 0; case 2: return 0x13; case 4: return 0; case 6: return 0x2; + // sly spy uses this port as RNG, for now let's do same thing as bootleg (i.e. reads 0x306028) + // chances are that it actually ties to the main CPU xtal instead. + // (reads at 6958 6696) + case 0xc: return m_ram[0x2028/2] >> 8; } logerror("%04x, Unknown protection read at 30c000 %d\n", space.device().safe_pc(), offset); @@ -564,7 +570,7 @@ READ16_MEMBER(dec0_state::slyspy_state_r) static ADDRESS_MAP_START( slyspy_protection_map, AS_PROGRAM, 16, dec0_state ) - AM_RANGE(0x04000, 0x04001) AM_MIRROR(0x30000) AM_READ(slyspy_state_r) + AM_RANGE(0x04000, 0x04001) AM_MIRROR(0x30000) AM_READ(slyspy_state_r) AM_WRITENOP AM_RANGE(0x0a000, 0x0a001) AM_MIRROR(0x30000) AM_WRITE(slyspy_state_w) // Default state (called by Traps 1, 3, 4, 7, C) AM_RANGE(0x00000, 0x00007) AM_DEVWRITE("tilegen2", deco_bac06_device, pf_control_0_w) @@ -669,15 +675,59 @@ ADDRESS_MAP_END /* Physical memory map (21 bits) */ static ADDRESS_MAP_START( slyspy_s_map, AS_PROGRAM, 8, dec0_state ) AM_RANGE(0x000000, 0x00ffff) AM_ROM - AM_RANGE(0x090000, 0x090001) AM_DEVWRITE("ym2", ym3812_device, write) - AM_RANGE(0x0a0000, 0x0a0001) AM_READNOP /* Protection counter */ - AM_RANGE(0x0b0000, 0x0b0001) AM_DEVWRITE("ym1", ym2203_device, write) - AM_RANGE(0x0e0000, 0x0e0001) AM_DEVREADWRITE("oki", okim6295_device, read, write) - AM_RANGE(0x0f0000, 0x0f0001) AM_DEVREAD("soundlatch", generic_latch_8_device, read) + AM_RANGE(0x080000, 0x0fffff) AM_DEVICE("sndprotect", address_map_bank_device, amap8 ) AM_RANGE(0x1f0000, 0x1f1fff) AM_RAMBANK("bank8") AM_RANGE(0x1ff400, 0x1ff403) AM_DEVWRITE("audiocpu", h6280_device, irq_status_w) ADDRESS_MAP_END +// sly spy sound state protection machine emulation +// similar to the video state machine +// current bank is at 0x1f0045, incremented by 1 then here is read +READ8_MEMBER(dec0_state::slyspy_sound_state_r) +{ + m_slyspy_sound_state ++; + m_slyspy_sound_state &= 3; + m_sndprotect->set_bank(m_slyspy_sound_state); + + // returned value doesn't matter + return 0xff; +} + +READ8_MEMBER(dec0_state::slyspy_sound_state_reset_r) +{ + m_slyspy_sound_state = 0; + m_sndprotect->set_bank(m_slyspy_sound_state); + + // returned value doesn't matter + return 0xff; +} + +static ADDRESS_MAP_START( slyspy_sound_protection_map, AS_PROGRAM, 8, dec0_state ) + AM_RANGE(0x020000, 0x020001) AM_MIRROR(0x180000) AM_READ(slyspy_sound_state_r) /* Protection counter */ + AM_RANGE(0x050000, 0x050001) AM_MIRROR(0x180000) AM_READ(slyspy_sound_state_reset_r) + // state 0 + AM_RANGE(0x010000, 0x010001) AM_DEVWRITE("ym2", ym3812_device, write) + AM_RANGE(0x030000, 0x030001) AM_DEVWRITE("ym1", ym2203_device, write) + AM_RANGE(0x060000, 0x060001) AM_DEVREADWRITE("oki", okim6295_device, read, write) + AM_RANGE(0x070000, 0x070001) AM_DEVREAD("soundlatch", generic_latch_8_device, read) + // state 1 + AM_RANGE(0x090000, 0x090001) AM_DEVREADWRITE("oki", okim6295_device, read, write) + AM_RANGE(0x0c0000, 0x0c0001) AM_DEVREAD("soundlatch", generic_latch_8_device, read) + AM_RANGE(0x0e0000, 0x0e0001) AM_DEVWRITE("ym1", ym2203_device, write) + AM_RANGE(0x0f0000, 0x0f0001) AM_DEVWRITE("ym2", ym3812_device, write) + // state 2 + AM_RANGE(0x110000, 0x110001) AM_DEVREAD("soundlatch", generic_latch_8_device, read) + AM_RANGE(0x130000, 0x130001) AM_DEVREADWRITE("oki", okim6295_device, read, write) + AM_RANGE(0x140000, 0x140001) AM_DEVWRITE("ym1", ym2203_device, write) + AM_RANGE(0x170000, 0x170001) AM_DEVWRITE("ym2", ym3812_device, write) + // state 3 + AM_RANGE(0x190000, 0x190001) AM_DEVWRITE("ym2", ym3812_device, write) + AM_RANGE(0x1c0000, 0x1c0001) AM_DEVWRITE("ym1", ym2203_device, write) + AM_RANGE(0x1e0000, 0x1e0001) AM_DEVREAD("soundlatch", generic_latch_8_device, read) + AM_RANGE(0x1f0000, 0x1f0001) AM_DEVREADWRITE("oki", okim6295_device, read, write) +ADDRESS_MAP_END + + static ADDRESS_MAP_START( midres_s_map, AS_PROGRAM, 8, dec0_state ) AM_RANGE(0x000000, 0x00ffff) AM_ROM AM_RANGE(0x108000, 0x108001) AM_DEVWRITE("ym2", ym3812_device, write) @@ -1543,15 +1593,10 @@ GFXDECODE_END -/* This is guesswork, in order to get ~57,41 Hz. - * If real Pixel Clock isn't 5 MHz then htotal/vtotal is different too ... */ -#define DEC0_PIXEL_CLOCK XTAL_20MHz/4 -#define DEC0_HTOTAL 320 -#define DEC0_HBEND 0 -#define DEC0_HBSTART 256 -#define DEC0_VTOTAL 272 -#define DEC0_VBEND 8 -#define DEC0_VBSTART 256-8 +// DECO video CRTC, pixel clock is unverified (actually 24MHz/4?) +#define MCFG_SCREEN_RAW_PARAMS_DATA_EAST \ + MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,384,0,256,272,8,248) + static MACHINE_CONFIG_START( dec0_base ) @@ -1560,7 +1605,7 @@ static MACHINE_CONFIG_START( dec0_base ) MCFG_SCREEN_ADD("screen", RASTER) //MCFG_SCREEN_REFRESH_RATE(57.41) //MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529) /* 57.41 Hz, 529us Vblank */) - MCFG_SCREEN_RAW_PARAMS(DEC0_PIXEL_CLOCK,DEC0_HTOTAL,DEC0_HBEND,DEC0_HBSTART,DEC0_VTOTAL,DEC0_VBEND,DEC0_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST //MCFG_SCREEN_SIZE(32*8, 32*8) //MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) //MCFG_SCREEN_UPDATE_DRIVER differs per game @@ -1693,7 +1738,7 @@ static MACHINE_CONFIG_START( automat ) MCFG_SCREEN_ADD("screen", RASTER) // MCFG_SCREEN_REFRESH_RATE(57.41) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529) /* 57.41 Hz, 529us Vblank */) - MCFG_SCREEN_RAW_PARAMS(DEC0_PIXEL_CLOCK,DEC0_HTOTAL,DEC0_HBEND,DEC0_HBSTART,DEC0_VTOTAL,DEC0_VBEND,DEC0_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec0_automat_state, screen_update_automat) MCFG_SCREEN_PALETTE("palette") @@ -1768,7 +1813,7 @@ static MACHINE_CONFIG_START( secretab ) MCFG_SCREEN_ADD("screen", RASTER) // MCFG_SCREEN_REFRESH_RATE(57.41) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529) /* 57.41 Hz, 529us Vblank */) - MCFG_SCREEN_RAW_PARAMS(DEC0_PIXEL_CLOCK,DEC0_HTOTAL,DEC0_HBEND,DEC0_HBSTART,DEC0_VTOTAL,DEC0_VBEND,DEC0_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec0_automat_state, screen_update_secretab) MCFG_SCREEN_PALETTE("palette") @@ -1906,6 +1951,8 @@ MACHINE_RESET_MEMBER(dec0_state,slyspy) // set initial memory map m_slyspy_state = 0; m_pfprotect->set_bank(m_slyspy_state); + m_slyspy_sound_state = 0; + m_sndprotect->set_bank(m_slyspy_sound_state); } static MACHINE_CONFIG_DERIVED( slyspy, dec1 ) @@ -1915,16 +1962,25 @@ static MACHINE_CONFIG_DERIVED( slyspy, dec1 ) MCFG_CPU_PROGRAM_MAP(slyspy_map) MCFG_CPU_VBLANK_INT_DRIVER("screen", dec0_state, irq6_line_hold) /* VBL, apparently it auto-acks */ - MCFG_CPU_ADD("audiocpu", H6280, XTAL_12MHz/2/3) /* verified on pcb (6Mhz is XIN on pin 10 of H6280, verified on pcb */ + // TODO: both games doesn't like /3 here, MT #06740 + MCFG_CPU_ADD("audiocpu", H6280, XTAL_12MHz/2/2) /* verified on pcb (6Mhz is XIN on pin 10 of H6280) */ MCFG_CPU_PROGRAM_MAP(slyspy_s_map) MCFG_DEVICE_ADD("pfprotect", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(slyspy_protection_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) + MCFG_DEVICE_ADD("sndprotect", ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(slyspy_sound_protection_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(21) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000) + + /* video hardware */ MCFG_SCREEN_MODIFY("screen") MCFG_SCREEN_UPDATE_DRIVER(dec0_state, screen_update_slyspy) diff --git a/src/mame/drivers/dec8.cpp b/src/mame/drivers/dec8.cpp index 6305631504b..be1d52c24f3 100644 --- a/src/mame/drivers/dec8.cpp +++ b/src/mame/drivers/dec8.cpp @@ -1949,14 +1949,10 @@ void dec8_state::machine_reset() } -/* TODO: These are raw guesses, only to get ~57,41 Hz, assume to be the same as dec0 */ -#define DEC8_PIXEL_CLOCK XTAL_20MHz/4 -#define DEC8_HTOTAL 320 -#define DEC8_HBEND 0 -#define DEC8_HBSTART 256 -#define DEC8_VTOTAL 272 -#define DEC8_VBEND 8 -#define DEC8_VBSTART 256-8 +// DECO video CRTC, unverified +#define MCFG_SCREEN_RAW_PARAMS_DATA_EAST \ + MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,384,0,256,272,8,248) + static MACHINE_CONFIG_START( lastmisn ) @@ -1985,7 +1981,7 @@ static MACHINE_CONFIG_START( lastmisn ) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* 58Hz, 529ms Vblank duration */) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MCFG_SCREEN_RAW_PARAMS(DEC8_PIXEL_CLOCK, DEC8_HTOTAL, DEC8_HBEND, DEC8_HBSTART, DEC8_VTOTAL, DEC8_VBEND, DEC8_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec8_state, screen_update_lastmisn) MCFG_SCREEN_PALETTE("palette") @@ -2039,7 +2035,7 @@ static MACHINE_CONFIG_START( shackled ) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* 58Hz, 529ms Vblank duration */) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MCFG_SCREEN_RAW_PARAMS(DEC8_PIXEL_CLOCK, DEC8_HTOTAL, DEC8_HBEND, DEC8_HBSTART, DEC8_VTOTAL, DEC8_VBEND, DEC8_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec8_state, screen_update_shackled) MCFG_SCREEN_PALETTE("palette") @@ -2092,7 +2088,7 @@ static MACHINE_CONFIG_START( gondo ) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529) /* 58Hz, 529ms Vblank duration */) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MCFG_SCREEN_RAW_PARAMS(DEC8_PIXEL_CLOCK, DEC8_HTOTAL, DEC8_HBEND, DEC8_HBSTART, DEC8_VTOTAL, DEC8_VBEND, DEC8_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec8_state, screen_update_gondo) MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(dec8_state, screen_vblank_dec8)) MCFG_SCREEN_PALETTE("palette") @@ -2146,7 +2142,7 @@ static MACHINE_CONFIG_START( garyoret ) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529) /* 58Hz, 529ms Vblank duration */) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MCFG_SCREEN_RAW_PARAMS(DEC8_PIXEL_CLOCK, DEC8_HTOTAL, DEC8_HBEND, DEC8_HBSTART, DEC8_VTOTAL, DEC8_VBEND, DEC8_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec8_state, screen_update_garyoret) MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(dec8_state, screen_vblank_dec8)) MCFG_SCREEN_PALETTE("palette") @@ -2204,7 +2200,7 @@ static MACHINE_CONFIG_START( ghostb ) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* 58Hz, 529ms Vblank duration */) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MCFG_SCREEN_RAW_PARAMS(DEC8_PIXEL_CLOCK, DEC8_HTOTAL, DEC8_HBEND, DEC8_HBSTART, DEC8_VTOTAL, DEC8_VBEND, DEC8_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec8_state, screen_update_ghostb) MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(dec8_state, screen_vblank_dec8)) MCFG_SCREEN_PALETTE("palette") @@ -2262,7 +2258,7 @@ static MACHINE_CONFIG_START( csilver ) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529) /* 58Hz, 529ms Vblank duration */) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MCFG_SCREEN_RAW_PARAMS(DEC8_PIXEL_CLOCK, DEC8_HTOTAL, DEC8_HBEND, DEC8_HBSTART, DEC8_VTOTAL, DEC8_VBEND, DEC8_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec8_state, screen_update_lastmisn) MCFG_SCREEN_PALETTE("palette") @@ -2325,7 +2321,7 @@ static MACHINE_CONFIG_START( oscar ) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* 58Hz, 529ms Vblank duration */) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MCFG_SCREEN_RAW_PARAMS(DEC8_PIXEL_CLOCK, DEC8_HTOTAL, DEC8_HBEND, DEC8_HBSTART, DEC8_VTOTAL, DEC8_VBEND, DEC8_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec8_state, screen_update_oscar) MCFG_SCREEN_PALETTE("palette") @@ -2375,7 +2371,7 @@ static MACHINE_CONFIG_START( srdarwin ) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529) /* 58Hz, 529ms Vblank duration */) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MCFG_SCREEN_RAW_PARAMS(DEC8_PIXEL_CLOCK, DEC8_HTOTAL, DEC8_HBEND, DEC8_HBSTART, DEC8_VTOTAL, DEC8_VBEND, DEC8_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec8_state, screen_update_srdarwin) MCFG_SCREEN_PALETTE("palette") @@ -2433,7 +2429,7 @@ static MACHINE_CONFIG_START( cobracom ) // MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529) /* 58Hz, 529ms Vblank duration */) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MCFG_SCREEN_RAW_PARAMS(DEC8_PIXEL_CLOCK, DEC8_HTOTAL, DEC8_HBEND, DEC8_HBSTART, DEC8_VTOTAL, DEC8_VBEND, DEC8_VBSTART) + MCFG_SCREEN_RAW_PARAMS_DATA_EAST MCFG_SCREEN_UPDATE_DRIVER(dec8_state, screen_update_cobracom) MCFG_SCREEN_PALETTE("palette") diff --git a/src/mame/drivers/deco_ld.cpp b/src/mame/drivers/deco_ld.cpp index 7a62b86dfb5..7fb5db179cd 100644 --- a/src/mame/drivers/deco_ld.cpp +++ b/src/mame/drivers/deco_ld.cpp @@ -274,8 +274,7 @@ static ADDRESS_MAP_START( rblaster_map, AS_PROGRAM, 8, deco_ld_state ) AM_RANGE(0x1003, 0x1003) AM_READ_PORT("IN1") AM_RANGE(0x1004, 0x1004) AM_DEVREAD("soundlatch2", generic_latch_8_device, read) AM_WRITE(decold_sound_cmd_w) AM_RANGE(0x1005, 0x1005) AM_READ(sound_status_r) - //AM_RANGE(0x1006, 0x1006) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - //AM_RANGE(0x1007, 0x1007) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + //AM_RANGE(0x1006, 0x1007) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0x1006, 0x1006) AM_READ(acia_status_hack_r) AM_RANGE(0x1007, 0x1007) AM_DEVREADWRITE("laserdisc", sony_ldp1000_device, status_r, command_w) AM_RANGE(0x1800, 0x1fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") diff --git a/src/mame/drivers/dectalk.cpp b/src/mame/drivers/dectalk.cpp index c4ce9352a6f..af810c8aca9 100644 --- a/src/mame/drivers/dectalk.cpp +++ b/src/mame/drivers/dectalk.cpp @@ -261,7 +261,7 @@ public: : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_dsp(*this, "dsp"), - m_duart(*this, "duartn68681"), + m_duart(*this, "duart"), m_nvram(*this, "x2212"), m_dac(*this, "dac") { @@ -277,27 +277,27 @@ public: uint8_t m_outfifo_count; uint8_t m_outfifo_tail_ptr; uint8_t m_outfifo_head_ptr; - uint8_t m_infifo_semaphore; // latch for status of output fifo, d-latch 74ls74 @ E64 'lower half' - uint8_t m_spc_error_latch; // latch for error status of speech dsp, d-latch 74ls74 @ E64 'upper half' - uint8_t m_m68k_spcflags_latch; // latch for initializing the speech dsp, d-latch 74ls74 @ E29 'lower half', AND latch for spc irq enable, d-latch 74ls74 @ E29 'upper half'; these are stored in bits 0 and 6 respectively, the rest of the bits stored here MUST be zeroed! - uint8_t m_m68k_tlcflags_latch; // latch for telephone interface stuff, d-latches 74ls74 @ E93 'upper half' and @ 103 'upper and lower halves' - uint8_t m_simulate_outfifo_error; // simulate an error on the outfifo, which does something unusual to the dsp latches - uint8_t m_tlc_tonedetect; - uint8_t m_tlc_ringdetect; + bool m_infifo_semaphore; // latch for status of output fifo, d-latch 74ls74 @ E64 'lower half' + bool m_spc_error_latch; // latch for error status of speech dsp, d-latch 74ls74 @ E64 'upper half' + uint8_t m_m68k_spcflags_latch; // latch for initializing the speech dsp, d-latch 74ls74 @ E29 'lower half', AND latch for spc irq enable, d-latch 74ls74 @ E29 'upper half'; these are stored in bits 0 and 6 respectively, the rest of the bits stored here MUST be zeroed! // TODO: Split this into two separate booleans! + uint8_t m_m68k_tlcflags_latch; // latch for telephone interface stuff, d-latches 74ls74 @ E93 'upper half' and @ 103 'upper and lower halves' // TODO: Split this into three separate booleans! + bool m_simulate_outfifo_error; // simulate an error on the outfifo, which does something unusual to the dsp latches + bool m_tlc_tonedetect; + bool m_tlc_ringdetect; uint8_t m_tlc_dtmf; // dtmf holding reg uint8_t m_duart_inport; // low 4 bits of duart input uint8_t m_duart_outport; // most recent duart output - uint8_t m_hack_self_test; // temp variable for hack below + bool m_hack_self_test_is_second_read; // temp variable for hack below required_device<m68000_base_device> m_maincpu; required_device<cpu_device> m_dsp; - required_device<mc68681_device> m_duart; + required_device<scn2681_device> m_duart; required_device<x2212_device> m_nvram; required_device<dac_word_interface> m_dac; - DECLARE_WRITE_LINE_MEMBER(dectalk_duart_irq_handler); - DECLARE_WRITE_LINE_MEMBER(dectalk_duart_txa); - DECLARE_READ8_MEMBER(dectalk_duart_input); - DECLARE_WRITE8_MEMBER(dectalk_duart_output); + DECLARE_WRITE_LINE_MEMBER(duart_irq_handler); + DECLARE_WRITE_LINE_MEMBER(duart_txa); + DECLARE_READ8_MEMBER(duart_input); + DECLARE_WRITE8_MEMBER(duart_output); DECLARE_READ8_MEMBER(nvram_recall); DECLARE_WRITE8_MEMBER(led_write); DECLARE_WRITE8_MEMBER(nvram_store); @@ -315,10 +315,10 @@ public: virtual void machine_start() override; TIMER_CALLBACK_MEMBER(outfifo_read_cb); emu_timer *m_outfifo_read_timer; - void dectalk_outfifo_check(); - void dectalk_clear_all_fifos(); - void dectalk_semaphore_w(uint16_t data); - uint16_t dectalk_outfifo_r(); + void outfifo_check(); + void clear_all_fifos(); + void dsp_semaphore_w(bool state); + uint16_t dsp_outfifo_r(); DECLARE_WRITE_LINE_MEMBER(dectalk_reset); protected: @@ -327,24 +327,24 @@ protected: /* 2681 DUART */ -WRITE_LINE_MEMBER(dectalk_state::dectalk_duart_irq_handler) +WRITE_LINE_MEMBER(dectalk_state::duart_irq_handler) { m_maincpu->set_input_line_and_vector(M68K_IRQ_6, state, M68K_INT_ACK_AUTOVECTOR); //drvstate->m_maincpu->set_input_line_and_vector(M68K_IRQ_6, CLEAR_LINE, M68K_INT_ACK_AUTOVECTOR); //drvstate->m_maincpu->set_input_line_and_vector(M68K_IRQ_6, HOLD_LINE, vector); } -READ8_MEMBER(dectalk_state::dectalk_duart_input) +READ8_MEMBER(dectalk_state::duart_input) { uint8_t data = 0; data |= m_duart_inport&0xf; data |= (ioport("duart_in")->read()&0xf0); - if ((m_hack_self_test == 1) && (ioport("hacks")->read()&0x01)) data |= 0x10; // hack to prevent hang if selftest disable bit is kept low past the first read; i suppose the proper use of this bit was an incremental switch, or perhaps its expecting an interrupt later from serial in or tone in? added a dipswitch to disable the hack for testing - m_hack_self_test = 1; + if ((m_hack_self_test_is_second_read) && (ioport("hacks")->read()&0x01)) data |= 0x10; // hack to prevent hang if selftest disable bit is kept low past the first read; i suppose the proper use of this bit was an incremental switch, or perhaps its expecting an interrupt later from serial in or tone in? added a dipswitch to disable the hack for testing + m_hack_self_test_is_second_read = true; return data; } -WRITE8_MEMBER(dectalk_state::dectalk_duart_output) +WRITE8_MEMBER(dectalk_state::duart_output) { m_duart_outport = data; #ifdef SERIAL_TO_STDERR @@ -352,7 +352,7 @@ WRITE8_MEMBER(dectalk_state::dectalk_duart_output) #endif } -WRITE_LINE_MEMBER(dectalk_state::dectalk_duart_txa) +WRITE_LINE_MEMBER(dectalk_state::duart_txa) { //TODO: this needs to be plumbed so it shows up optionally on a second terminal somehow, or connects to diserial // it is the second 'alternate' serial connection on the DTC-01, used for a serial passthru and other stuff. @@ -365,7 +365,7 @@ WRITE_LINE_MEMBER(dectalk_state::dectalk_duart_txa) #define SPC_INITIALIZE state->m_m68k_spcflags_latch&0x1 // speech initialize flag #define SPC_IRQ_ENABLED ((state->m_m68k_spcflags_latch&0x40)>>6) // irq enable flag -void dectalk_state::dectalk_outfifo_check () +void dectalk_state::outfifo_check() { // check if output fifo is full; if it isn't, set the int on the dsp if (m_outfifo_count < 16) @@ -374,7 +374,7 @@ void dectalk_state::dectalk_outfifo_check () m_dsp->set_input_line(0, CLEAR_LINE); // TMS32010 INT } -void dectalk_state::dectalk_clear_all_fifos( ) +void dectalk_state::clear_all_fifos() { // clear fifos (TODO: memset would work better here...) int i; @@ -384,14 +384,14 @@ void dectalk_state::dectalk_clear_all_fifos( ) for (i=0; i<32; i++) m_infifo[i] = 0; m_infifo_count = 0; m_infifo_tail_ptr = m_infifo_head_ptr = 0; - dectalk_outfifo_check(); + outfifo_check(); } // helper for dsp infifo_semaphore flag to make dealing with interrupts easier -void dectalk_state::dectalk_semaphore_w ( uint16_t data ) +void dectalk_state::dsp_semaphore_w(bool state) { - m_infifo_semaphore = data&1; - if ((m_infifo_semaphore == 1) && (m_m68k_spcflags_latch&0x40)) + m_infifo_semaphore = state; + if ((m_infifo_semaphore) && (m_m68k_spcflags_latch&0x40)) { #ifdef VERBOSE logerror("speech int fired!\n"); @@ -403,7 +403,7 @@ void dectalk_state::dectalk_semaphore_w ( uint16_t data ) } // read the output fifo and set the interrupt line active on the dsp -uint16_t dectalk_state::dectalk_outfifo_r ( ) +uint16_t dectalk_state::dsp_outfifo_r ( ) { uint16_t data = 0xffff; #ifdef USE_LOOSE_TIMING_OUTPUT @@ -422,7 +422,7 @@ uint16_t dectalk_state::dectalk_outfifo_r ( ) m_outfifo_count--; } m_outfifo_tail_ptr&=0xf; - dectalk_outfifo_check(); + outfifo_check(); return ((data&0xfff0)^0x8000); // yes this is right, top bit is inverted and bottom 4 are ignored //return data; // not right but want to get it working first } @@ -430,7 +430,7 @@ uint16_t dectalk_state::dectalk_outfifo_r ( ) /* Machine reset and friends: stuff that needs setting up which IS directly affected by reset */ WRITE_LINE_MEMBER(dectalk_state::dectalk_reset) { - m_hack_self_test = 0; // hack + m_hack_self_test_is_second_read = false; // hack // stuff that is DIRECTLY affected by the RESET line machine().device<x2212_device>("x2212")->recall(0); machine().device<x2212_device>("x2212")->recall(1); @@ -439,12 +439,12 @@ WRITE_LINE_MEMBER(dectalk_state::dectalk_reset) m_m68k_tlcflags_latch = 0; // initial status is tone detect int(d6) off, answer phone(d8) off, ring detect int(d14) off m_duart->reset(); // reset the DUART // stuff that is INDIRECTLY affected by the RESET line - dectalk_clear_all_fifos(); // speech reset clears the fifos, though we have to do it explicitly here since we're not actually in the m68k_spcflags_w function. - dectalk_semaphore_w(0); // on the original DECtalk DTC-01 pcb revision, this is a semaphore for the INPUT fifo, later dec hacked on a check for the 3 output fifo chips to see if they're in sync, and set both of these latches if true. - m_spc_error_latch = 0; // spc error latch is cleared on /reset + clear_all_fifos(); // speech reset clears the fifos, though we have to do it explicitly here since we're not actually in the m68k_spcflags_w function. + dsp_semaphore_w(false); // on the original DECtalk DTC-01 pcb revision, this is a semaphore for the INPUT fifo, later dec hacked on a check for the 3 output fifo chips to see if they're in sync, and set both of these latches if true. + m_spc_error_latch = false; // spc error latch is cleared on /reset m_dsp->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); // speech reset forces the CLR line active on the tms32010 - m_tlc_tonedetect = 0; // TODO, needed for selftest pass - m_tlc_ringdetect = 0; // TODO + m_tlc_tonedetect = false; // TODO, needed for selftest pass + m_tlc_ringdetect = false; // TODO m_tlc_dtmf = 0; // TODO m_duart_inport = 0xf; m_duart_outport = 0; @@ -472,9 +472,9 @@ void dectalk_state::machine_start() save_item(NAME(m_tlc_dtmf)); save_item(NAME(m_duart_inport)); save_item(NAME(m_duart_outport)); - save_item(NAME(m_hack_self_test)); - dectalk_clear_all_fifos(); - m_simulate_outfifo_error = 0; + save_item(NAME(m_hack_self_test_is_second_read)); + clear_all_fifos(); + m_simulate_outfifo_error = false; // TODO: HACK for now, should be hooked to a fake dipswitch to simulate fifo errors } void dectalk_state::machine_reset() @@ -541,8 +541,8 @@ READ16_MEMBER(dectalk_state::m68k_spcflags_r)// 68k read from the speech flags { uint8_t data = 0; data |= m_m68k_spcflags_latch; // bits 0 and 6 - data |= m_spc_error_latch<<5; // bit 5 - data |= m_infifo_semaphore<<7; // bit 7 + data |= m_spc_error_latch?0x20:0; // bit 5 + data |= m_infifo_semaphore?0x80:0; // bit 7 #ifdef SPC_LOG_68K logerror("m68k: SPC flags read, returning data = %04X\n",data); #endif @@ -564,11 +564,11 @@ WRITE16_MEMBER(dectalk_state::m68k_spcflags_w)// 68k write to the speech flags ( #ifdef SPC_LOG_68K logerror(" | 0x01: initialize speech: fifos reset, clear error+semaphore latches and dsp reset\n"); #endif - dectalk_clear_all_fifos(); + clear_all_fifos(); m_dsp->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); // speech reset forces the CLR line active on the tms32010 // clear the two speech side latches - m_spc_error_latch = 0; - dectalk_semaphore_w(0); + m_spc_error_latch = false; + dsp_semaphore_w(false); } else // (data&0x1) == 0 { @@ -583,15 +583,15 @@ WRITE16_MEMBER(dectalk_state::m68k_spcflags_w)// 68k write to the speech flags ( logerror(" | 0x02: clear error+semaphore latches\n"); #endif // clear the two speech side latches - m_spc_error_latch = 0; - dectalk_semaphore_w(0); + m_spc_error_latch = false; + dsp_semaphore_w(false); } if ((data&0x40) == 0x40) // bit 6 - spc irq enable { #ifdef SPC_LOG_68K logerror(" | 0x40: speech int enabled\n"); #endif - if (m_infifo_semaphore == 1) + if (m_infifo_semaphore) { #ifdef SPC_LOG_68K logerror(" speech int fired!\n"); @@ -611,9 +611,9 @@ WRITE16_MEMBER(dectalk_state::m68k_spcflags_w)// 68k write to the speech flags ( READ16_MEMBER(dectalk_state::m68k_tlcflags_r)// dtmf flags read { uint16_t data = 0; - data |= m_m68k_tlcflags_latch; // bits 6, 8, 14; - data |= m_tlc_tonedetect<<7; // bit 7 is tone detect - data |= m_tlc_ringdetect<<14; // bit 15 is ring detect + data |= m_m68k_tlcflags_latch; // bits 6, 8, 14: tone detected int enable, answer phone relay enable, and ring int enable respectively + data |= m_tlc_tonedetect?0x0080:0; // bit 7 is tone detected + data |= m_tlc_ringdetect?0x8000:0; // bit 15 is ring detected #ifdef TLC_LOG logerror("m68k: TLC flags read, returning data = %04X\n",data); #endif @@ -626,12 +626,12 @@ WRITE16_MEMBER(dectalk_state::m68k_tlcflags_w)// dtmf flags write logerror("m68k: TLC flags written with %04X, only storing %04X\n",data, data&0x4140); #endif m_m68k_tlcflags_latch = data&0x4140; // ONLY store bits 6 8 and 14! - if ((data&0x40) == 0x40) // bit 6: tone detect interrupt enable + if (data&0x40) // bit 6: tone detect interrupt enable { #ifdef TLC_LOG logerror(" | 0x40: tone detect int enabled\n"); #endif - if (m_tlc_tonedetect == 1) + if (m_tlc_tonedetect) { #ifdef TLC_LOG logerror(" TLC int fired!\n"); @@ -644,10 +644,10 @@ WRITE16_MEMBER(dectalk_state::m68k_tlcflags_w)// dtmf flags write #ifdef TLC_LOG logerror(" | 0x40 = 0: tone detect int disabled\n"); #endif - if (((data&0x4000)!=0x4000) || (m_tlc_ringdetect == 0)) // check to be sure we don't disable int if both ints fired at once + if ((!(data&0x4000)) || (!m_tlc_ringdetect)) // check to be sure we don't disable int if both ints fired at once m_maincpu->set_input_line_and_vector(M68K_IRQ_4, CLEAR_LINE, M68K_INT_ACK_AUTOVECTOR); // clear int because int is now disabled } - if ((data&0x100) == 0x100) // bit 8: answer phone relay enable + if (data&0x100) // bit 8: answer phone relay enable { #ifdef TLC_LOG logerror(" | 0x100: answer phone relay enabled\n"); @@ -659,7 +659,7 @@ WRITE16_MEMBER(dectalk_state::m68k_tlcflags_w)// dtmf flags write logerror(" | 0x100 = 0: answer phone relay disabled\n"); #endif } - if ((data&0x4000) == 0x4000) // bit 14: ring int enable + if (data&0x4000) // bit 14: ring int enable { #ifdef TLC_LOG logerror(" | 0x4000: ring detect int enabled\n"); @@ -677,7 +677,7 @@ WRITE16_MEMBER(dectalk_state::m68k_tlcflags_w)// dtmf flags write #ifdef TLC_LOG logerror(" | 0x4000 = 0: ring detect int disabled\n"); #endif - if (((data&0x40)!=0x40) || (m_tlc_tonedetect == 0)) // check to be sure we don't disable int if both ints fired at once + if ((!(data&0x40)) || (!m_tlc_tonedetect)) // check to be sure we don't disable int if both ints fired at once m_maincpu->set_input_line_and_vector(M68K_IRQ_4, CLEAR_LINE, M68K_INT_ACK_AUTOVECTOR); // clear int because int is now disabled } } @@ -702,7 +702,7 @@ WRITE16_MEMBER(dectalk_state::spc_latch_outfifo_error_stats)// latch 74ls74 @ E6 #ifdef SPC_LOG_DSP logerror("dsp: set fifo semaphore and set error status = %01X\n",data&1); #endif - dectalk_semaphore_w((~m_simulate_outfifo_error)&1); // always set to 1 here, unless outfifo desync-between-the-three-parallel-fifo-chips error occurs. + dsp_semaphore_w(m_simulate_outfifo_error?false:true); // always set to true here, unless outfifo desync-between-the-three-parallel-fifo-chips error occurs. m_spc_error_latch = (data&1); // latch the dsp 'soft error' state aka "ERROR DETECTED D5 H" on schematics (different from the outfifo error state above!) } @@ -742,7 +742,7 @@ WRITE16_MEMBER(dectalk_state::spc_outfifo_data_w) m_outfifo_head_ptr++; m_outfifo_count++; m_outfifo_head_ptr&=0xf; - //dectalk_outfifo_check(); // outfifo check should only be done in the audio 10khz polling function + //outfifo_check(); // outfifo check should only be done in the audio 10khz polling function } READ_LINE_MEMBER(dectalk_state::spc_semaphore_r)// Return state of d-latch 74ls74 @ E64 'lower half' in d0 which indicates whether infifo is readable @@ -780,10 +780,10 @@ a23 a22 a21 a20 a19 a18 a17 a16 a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 0 x x x 1 x x 1 0 1 x x x x 0 * * * * * * * * 1 RW NVRAM (read/write volatile ram, does not store to eeprom) 0 x x x 1 x x 1 0 1 x x x x 1 * * * * * * * * 1 RW NVRAM (all reads do /recall from eeprom, all writes do /store to eeprom) 0 x x x 1 x x 1 1 0 x x x x x x x x x * * * * x RW DUART (keep in mind that a0 is not connected) -0 x x x 1 x x 1 1 1 x x x x x x x x x x x 0 0 * RW SPC flags: fifo writable (readonly, d7), spc irq suppress (readwrite, d6), fifo error status (readonly, d5), 'fifo release'/clear-tms-fifo-error-status-bits (writeonly, d1), speech initialize/clear (readwrite, d0) [see schematic sheet 4] -0 x x x 1 x x 1 1 1 x x x x x x x x x x x 0 1 0? W SPC fifo write (clocks fifo) -0 x x x 1 x x 1 1 1 x x x x x x x x x x x 1 0 * RW TLC flags: ring detect (readonly, d15), ring detected irq enable (readwrite, d14), answer phone (readwrite, d8), tone detected (readonly, d7), tone detected irq enable (readwrite, d6) [see schematic sheet 6] -0 x x x 1 x x 1 1 1 x x x x x x x x x x x 1 1 * R TLC tone chip read, reads on bits d0-d7 only, d4-d7 are tied low; d15-d8 are probably open bus +0 x x x 1 x x 1 1 1 x x x x x x x x x x x 0 0 0? RW SPC SR (flags): fifo-not-full (spc writable) flag (readonly, d7), fifo-not-full spc irq mask (readwrite, d6), fifo error status (readonly, d5), 'fifo release'/clear-tms-fifo-error-status-bits (writeonly, d1), speech initialize/clear (readwrite, d0) [see schematic sheet 4] +0 x x x 1 x x 1 1 1 x x x x x x x x x x x 0 1 * W SPC DR fifo write (clocks fifo) +0 x x x 1 x x 1 1 1 x x x x x x x x x x x 1 0 * RW TLC SR (flags): ring detect (readonly, d15), ring detected irq enable (readwrite, d14), answer phone (readwrite, d8), tone detected (readonly, d7), tone detected irq enable (readwrite, d6) [see schematic sheet 6] +0 x x x 1 x x 1 1 1 x x x x x x x x x x x 1 1 * R TLC DR tone chip read, reads on bits d0-d7 only, d4-d7 are tied low; d15-d8 are probably open bus 1 x x x x x x x x x x x x x x x x x x x x x x x OPEN BUS | | | | | */ @@ -795,18 +795,13 @@ static ADDRESS_MAP_START(m68k_mem, AS_PROGRAM, 16, dectalk_state ) AM_RANGE(0x094000, 0x0943ff) AM_MIRROR(0x763c00) AM_WRITE8(led_write, 0x00ff) /* LED array */ AM_RANGE(0x094000, 0x0941ff) AM_MIRROR(0x763c00) AM_DEVREADWRITE8("x2212", x2212_device, read, write, 0xff00) /* Xicor X2212 NVRAM */ AM_RANGE(0x094200, 0x0943ff) AM_MIRROR(0x763c00) AM_READWRITE8(nvram_recall, nvram_store, 0xff00) /* Xicor X2212 NVRAM */ - AM_RANGE(0x098000, 0x09801f) AM_MIRROR(0x763fe0) AM_DEVREADWRITE8("duartn68681", mc68681_device, read, write, 0xff ) /* DUART */ + AM_RANGE(0x098000, 0x09801f) AM_MIRROR(0x763fe0) AM_DEVREADWRITE8("duart", scn2681_device, read, write, 0x00ff ) /* DUART */ AM_RANGE(0x09c000, 0x09c001) AM_MIRROR(0x763ff8) AM_READWRITE(m68k_spcflags_r, m68k_spcflags_w) /* SPC flags reg */ AM_RANGE(0x09c002, 0x09c003) AM_MIRROR(0x763ff8) AM_WRITE(m68k_infifo_w) /* SPC fifo reg */ AM_RANGE(0x09c004, 0x09c005) AM_MIRROR(0x763ff8) AM_READWRITE(m68k_tlcflags_r, m68k_tlcflags_w) /* telephone status flags */ AM_RANGE(0x09c006, 0x09c007) AM_MIRROR(0x763ff8) AM_READ(m68k_tlc_dtmf_r) /* telephone dtmf read */ ADDRESS_MAP_END -// do we even need this below? -static ADDRESS_MAP_START(m68k_io, AS_IO, 16, dectalk_state ) - ADDRESS_MAP_GLOBAL_MASK(0xff) -ADDRESS_MAP_END - static ADDRESS_MAP_START(tms32010_mem, AS_PROGRAM, 16, dectalk_state ) AM_RANGE(0x000, 0x7ff) AM_ROM /* ROM */ ADDRESS_MAP_END @@ -858,8 +853,7 @@ void dectalk_state::device_timer(emu_timer &timer, device_timer_id id, int param TIMER_CALLBACK_MEMBER(dectalk_state::outfifo_read_cb) { - uint16_t data; - data = dectalk_outfifo_r(); + uint16_t data = dsp_outfifo_r(); #ifdef VERBOSE if (data!= 0x8000) logerror("sample output: %04X\n", data); #endif @@ -867,24 +861,23 @@ TIMER_CALLBACK_MEMBER(dectalk_state::outfifo_read_cb) m_dac->write(data >> 4); // hack for break key, requires hacked up duart core so disabled for now // also it doesn't work well, the setup menu is badly corrupt - /*device_t *duart = machine().device("duartn68681"); + /*device_t *duart = machine().device("duart"); if (machine.input().code_pressed(KEYCODE_F1)) - duart68681_rx_break(duart, 1, 1); + duart_rx_break(duart, 1, 1); else - duart68681_rx_break(duart, 1, 0);*/ + duart_rx_break(duart, 1, 0);*/ } static MACHINE_CONFIG_START( dectalk ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M68000, XTAL_20MHz/2) /* E74 20MHz OSC (/2) */ MCFG_CPU_PROGRAM_MAP(m68k_mem) - MCFG_CPU_IO_MAP(m68k_io) - MCFG_MC68681_ADD( "duartn68681", XTAL_3_6864MHz ) /* 2681 duart (not 68681!); Y3 3.6864MHz Xtal */ - MCFG_MC68681_IRQ_CALLBACK(WRITELINE(dectalk_state, dectalk_duart_irq_handler)) - MCFG_MC68681_A_TX_CALLBACK(WRITELINE(dectalk_state, dectalk_duart_txa)) + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) // MC2681 DUART ; Y3 3.6864MHz xtal */ + MCFG_MC68681_IRQ_CALLBACK(WRITELINE(dectalk_state, duart_irq_handler)) + MCFG_MC68681_A_TX_CALLBACK(WRITELINE(dectalk_state, duart_txa)) MCFG_MC68681_B_TX_CALLBACK(DEVWRITELINE("rs232", rs232_port_device, write_txd)) - MCFG_MC68681_INPORT_CALLBACK(READ8(dectalk_state, dectalk_duart_input)) - MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(dectalk_state, dectalk_duart_output)) + MCFG_MC68681_INPORT_CALLBACK(READ8(dectalk_state, duart_input)) + MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(dectalk_state, duart_output)) MCFG_CPU_ADD("dsp", TMS32010, XTAL_20MHz) /* Y1 20MHz xtal */ MCFG_CPU_PROGRAM_MAP(tms32010_mem) @@ -909,7 +902,7 @@ static MACHINE_CONFIG_START( dectalk ) /* Y2 is a 3.579545 MHz xtal for the dtmf decoder chip */ MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duartn68681", mc68681_device, rx_b_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_b_w)) MACHINE_CONFIG_END diff --git a/src/mame/drivers/didact.cpp b/src/mame/drivers/didact.cpp index 4e83b8f2e6b..7258d24df52 100644 --- a/src/mame/drivers/didact.cpp +++ b/src/mame/drivers/didact.cpp @@ -1049,10 +1049,7 @@ READ8_MEMBER( can09t_state::read ) { case X0XX: // ACIA LOGPLA("-- ACIA\n"); - if (offset & 1) - byte = m_acia->data_r(space, 0); - else - byte = m_acia->status_r(space, 0); + byte = m_acia->read(space, offset & 1); break; case X1XX: // SYSPIA LOGPLA("-- SYSPIA\n"); @@ -1134,10 +1131,7 @@ WRITE8_MEMBER( can09t_state::write ) { case X0XX: // ACIA LOGPLA("-- ACIA\n"); - if (offset & 1) - m_acia->data_w(space, 0, data); - else - m_acia->control_w(space, 0, data); + m_acia->write(space, offset & 1, data); break; case X1XX: // SYSPIA LOGPLA("-- SYSPIA\n"); @@ -1393,8 +1387,7 @@ static ADDRESS_MAP_START( can09_map, AS_PROGRAM, 8, can09_state ) AM_RANGE(0xe034, 0xe037) AM_DEVREADWRITE(PIA1_TAG, pia6821_device, read, write) #if 0 - AM_RANGE(0xb100, 0xb100) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0xb101, 0xb101) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0xb100, 0xb101) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0xb110, 0xb113) AM_DEVREADWRITE(PIA1_TAG, pia6821_device, read_alt, write_alt) AM_RANGE(0xb120, 0xb123) AM_DEVREADWRITE(PIA2_TAG, pia6821_device, read_alt, write_alt) AM_RANGE(0xb130, 0xb137) AM_DEVREADWRITE("ptm", ptm6840_device, read, write) diff --git a/src/mame/drivers/discoboy.cpp b/src/mame/drivers/discoboy.cpp index 6bf30e5ad3d..96e4e596a88 100644 --- a/src/mame/drivers/discoboy.cpp +++ b/src/mame/drivers/discoboy.cpp @@ -457,8 +457,8 @@ static MACHINE_CONFIG_START( discoboy ) MCFG_DEVICE_ADD("rambank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(rambank1_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x800) /* video hardware */ diff --git a/src/mame/drivers/dlair.cpp b/src/mame/drivers/dlair.cpp index 81f78b66a21..ad4efd600c3 100644 --- a/src/mame/drivers/dlair.cpp +++ b/src/mame/drivers/dlair.cpp @@ -42,7 +42,7 @@ #include "machine/ldstub.h" #include "machine/watchdog.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "sound/ay8910.h" #include "sound/spkrdev.h" #include "render.h" @@ -408,7 +408,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( dleuro_io_map, AS_IO, 8, dlair_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x03) AM_MIRROR(0x7c) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) - AM_RANGE(0x80, 0x83) AM_MIRROR(0x7c) AM_DEVREADWRITE("sio", z80dart_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x80, 0x83) AM_MIRROR(0x7c) AM_DEVREADWRITE("sio", z80sio_device, ba_cd_r, ba_cd_w) ADDRESS_MAP_END @@ -755,8 +755,8 @@ static MACHINE_CONFIG_START( dleuro ) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_Z80CTC_ZC0_CB(WRITELINE(dlair_state, write_speaker)) - MCFG_DEVICE_ADD("sio", Z80SIO0, MASTER_CLOCK_EURO/4 /* same as "maincpu" */) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio", Z80SIO, MASTER_CLOCK_EURO/4 /* same as "maincpu" */) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) // TODO: hook up tx and rx callbacks MCFG_WATCHDOG_ADD("watchdog") diff --git a/src/mame/drivers/dms86.cpp b/src/mame/drivers/dms86.cpp index 10be2529544..1ac2811406b 100644 --- a/src/mame/drivers/dms86.cpp +++ b/src/mame/drivers/dms86.cpp @@ -7,16 +7,21 @@ 11/01/2010 Skeleton driver. Monitor commands: -A +A Display incoming terminal data in hex B boot to HiNet +C copy memory D dump memory to screen +F fill memory +G go (eg G address [breakpoint]) I in port -L memory test +M memory test O out port (e.g. O 84 77) -P +P set segment S write a byte to memory -T +T type ascii string into the address set by D or S X display registers +? help +: load intel hex format file Note that bit 3 of port 82 is tested at boot. If low, the computer bypasses @@ -26,73 +31,68 @@ the monitor and goes straight to "Joining HiNet". #include "emu.h" #include "cpu/i86/i86.h" +#include "machine/z80ctc.h" +#include "machine/z80sio.h" +#include "machine/clock.h" +#include "bus/rs232/rs232.h" #include "machine/terminal.h" -#define TERMINAL_TAG "terminal" class dms86_state : public driver_device { public: dms86_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG) - { - } - - DECLARE_READ16_MEMBER( dms86_82_r ); - DECLARE_READ16_MEMBER( dms86_84_r ); - DECLARE_READ16_MEMBER( dms86_86_r ); - DECLARE_READ16_MEMBER( dms86_9a_r ); + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { } + + DECLARE_READ16_MEMBER( port82_r ); + DECLARE_READ16_MEMBER( port9a_r ); + DECLARE_READ16_MEMBER( port9c_r ); void kbd_put(u8 data); -protected: - required_device<cpu_device> m_maincpu; - required_device<generic_terminal_device> m_terminal; - uint8_t *m_ram; - uint8_t m_term_data; +private: + u8 m_term_data; virtual void machine_reset() override; + required_device<cpu_device> m_maincpu; }; -READ16_MEMBER( dms86_state::dms86_82_r ) + +READ16_MEMBER( dms86_state::port82_r ) { // HiNet / Monitor switch - return 0xff; + return 8; } -READ16_MEMBER( dms86_state::dms86_84_r ) +READ16_MEMBER( dms86_state::port9a_r ) { - uint8_t ret = m_term_data; - m_term_data = 0; - return ret; + return m_term_data ? 0x40 : 0; } -READ16_MEMBER( dms86_state::dms86_86_r ) +READ16_MEMBER( dms86_state::port9c_r ) { - return 4 | (m_term_data ? 1 : 0); -} - -READ16_MEMBER( dms86_state::dms86_9a_r ) -{ - return 0; + uint8_t ret = m_term_data; + m_term_data = 0; + return ret; } -static ADDRESS_MAP_START(dms86_mem, AS_PROGRAM, 16, dms86_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 16, dms86_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00000, 0x1ffff) AM_RAM - AM_RANGE(0xfe000, 0xfffff) AM_ROM AM_REGION("user1",0) + AM_RANGE(0xfe000, 0xfffff) AM_ROM AM_REGION("roms",0) ADDRESS_MAP_END -static ADDRESS_MAP_START(dms86_io, AS_IO, 16, dms86_state) +static ADDRESS_MAP_START(io_map, AS_IO, 16, dms86_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0x82, 0x83) AM_READ(dms86_82_r) - AM_RANGE(0x84, 0x85) AM_READ(dms86_84_r) AM_DEVWRITE8(TERMINAL_TAG, generic_terminal_device, write, 0xff) - AM_RANGE(0x86, 0x87) AM_READ(dms86_86_r) - AM_RANGE(0x9A, 0x9B) AM_READ(dms86_9a_r) - AM_RANGE(0x9c, 0x9d) AM_DEVWRITE8(TERMINAL_TAG, generic_terminal_device, write, 0xff) + AM_RANGE(0x82, 0x83) AM_READ(port82_r) + //AM_RANGE(0x80, 0x87) AM_DEVREADWRITE8("sio1", z80sio_device, ba_cd_r, ba_cd_w, 0x00ff) + AM_RANGE(0x88, 0x8f) AM_DEVREADWRITE8("ctc", z80ctc_device, read, write, 0x00ff) + AM_RANGE(0x90, 0x97) AM_DEVREADWRITE8("sio2", z80sio_device, ba_cd_r, ba_cd_w, 0x00ff) + AM_RANGE(0x9A, 0x9B) AM_READ(port9a_r) // parallel SASI port + AM_RANGE(0x9c, 0x9d) AM_READ(port9c_r) AM_DEVWRITE8("terminal", generic_terminal_device, write, 0xff) ADDRESS_MAP_END /* Input ports */ @@ -111,18 +111,45 @@ void dms86_state::kbd_put(u8 data) static MACHINE_CONFIG_START( dms86 ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu",I8086, XTAL_9_8304MHz) - MCFG_CPU_PROGRAM_MAP(dms86_mem) - MCFG_CPU_IO_MAP(dms86_io) - - - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) + MCFG_CPU_ADD("maincpu", I8086, XTAL_14_7456MHz / 3) // according to the manual... hmm + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + + // According to the manual the clock is 14,765,600 / 4 but that couldn't possibly work. + // By maths, clock should be 9600*32*4*16 = 19,660,800 but not working either + // So, commented out because it makes the whole thing crawl, only get 18% on my machine + //MCFG_DEVICE_ADD("ctc_clock", CLOCK, 19660800) //XTAL_14_7456MHz / 4) + //MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc" ,z80ctc_device, trg0)) + //MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc" ,z80ctc_device, trg1)) + //MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc" ,z80ctc_device, trg2)) + + MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_14_7456MHz / 3) + //MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) // frame rate interrupt to maincpu + MCFG_Z80CTC_ZC0_CB(DEVWRITELINE("sio1", z80sio_device, rxtxcb_w)) // SIO1 Ch B + MCFG_Z80CTC_ZC1_CB(DEVWRITELINE("sio1", z80sio_device, txca_w)) // SIO1 Ch A + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio1" ,z80sio_device, rxca_w)) + MCFG_Z80CTC_ZC2_CB(DEVWRITELINE("sio2", z80sio_device, rxtxcb_w)) // SIO2 + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio2" ,z80sio_device, rxca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio2" ,z80sio_device, rxca_w)) + + MCFG_DEVICE_ADD("sio1", Z80SIO, XTAL_14_7456MHz / 3) + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio1", z80sio_device, rxb_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio1", z80sio_device, dcdb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio1", z80sio_device, ctsb_w)) MCFG_DEVCB_INVERT + + MCFG_DEVICE_ADD("sio2", Z80SIO, XTAL_14_7456MHz / 3) + MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(dms86_state, kbd_put)) MACHINE_CONFIG_END /* ROM definition */ ROM_START( dms86 ) - ROM_REGION( 0x2000, "user1", ROMREGION_ERASEFF ) + ROM_REGION( 0x2000, "roms", ROMREGION_ERASEFF ) ROM_LOAD16_BYTE( "hns-86_54-8678.bin", 0x0000, 0x1000, CRC(95f58e1c) SHA1(6fc8f087f0c887d8b429612cd035c6c1faab570c)) ROM_LOAD16_BYTE( "hns-86_54-8677.bin", 0x0001, 0x1000, CRC(78fad756) SHA1(ddcbff1569ec6975b8489935cdcfa80eba413502)) ROM_END diff --git a/src/mame/drivers/dotrikun.cpp b/src/mame/drivers/dotrikun.cpp index 547e003e064..e3e0eb57274 100644 --- a/src/mame/drivers/dotrikun.cpp +++ b/src/mame/drivers/dotrikun.cpp @@ -33,6 +33,8 @@ TODO: #include "dotrikun.lh" +#define MASTER_CLOCK XTAL_4MHz + class dotrikun_state : public driver_device { @@ -68,12 +70,12 @@ public: TIMER_DEVICE_CALLBACK_MEMBER(dotrikun_state::interrupt) { - generic_pulse_irq_line(*m_maincpu, 0, 1); + m_maincpu->pulse_input_line(0, attotime::from_hz(MASTER_CLOCK/128)); } TIMER_DEVICE_CALLBACK_MEMBER(dotrikun_state::scanline_off) { - m_maincpu->set_unscaled_clock(XTAL_4MHz); + m_maincpu->set_unscaled_clock(MASTER_CLOCK); } TIMER_DEVICE_CALLBACK_MEMBER(dotrikun_state::scanline_on) @@ -81,7 +83,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(dotrikun_state::scanline_on) // on vram fetch(every 8 pixels during active display), z80 is stalled for 2 clocks if (param < 192) { - m_maincpu->set_unscaled_clock(XTAL_4MHz * 0.75); + m_maincpu->set_unscaled_clock(MASTER_CLOCK * 0.75); m_scanline_off_timer->adjust(m_screen->time_until_pos(param, 128)); } @@ -189,7 +191,7 @@ void dotrikun_state::machine_reset() static MACHINE_CONFIG_START( dotrikun ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", Z80, XTAL_4MHz) + MCFG_CPU_ADD("maincpu", Z80, MASTER_CLOCK) MCFG_CPU_PROGRAM_MAP(dotrikun_map) MCFG_CPU_IO_MAP(io_map) MCFG_TIMER_DRIVER_ADD_SCANLINE("scanline_on", dotrikun_state, scanline_on, "screen", 0, 1) @@ -198,7 +200,7 @@ static MACHINE_CONFIG_START( dotrikun ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_RAW_PARAMS(XTAL_4MHz, 128+128, 0, 128, 192+64, 0, 192) + MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK, 128+128, 0, 128, 192+64, 0, 192) MCFG_SCREEN_UPDATE_DRIVER(dotrikun_state, screen_update) MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_ALWAYS_UPDATE) MCFG_SCREEN_PALETTE("palette") diff --git a/src/mame/drivers/dps1.cpp b/src/mame/drivers/dps1.cpp index b961f1d29ef..93bf9775b78 100644 --- a/src/mame/drivers/dps1.cpp +++ b/src/mame/drivers/dps1.cpp @@ -6,15 +6,18 @@ Ithaca Intersystems DPS-1 The last commercial release of a computer fitted with a front panel. +It needs to boot from floppy before anything appears on screen. + ToDo: - Need artwork of the front panel switches and LEDs, and port FF. -- Replace terminal with s2651 UART and RS232. ***************************************************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" #include "machine/upd765.h" -#include "machine/terminal.h" +#include "machine/mc2661.h" +#include "bus/rs232/rs232.h" +//#include "bus/s100/s100.h" #include "softlist.h" class dps1_state : public driver_device @@ -26,11 +29,8 @@ public: , m_fdc(*this, "fdc") , m_floppy0(*this, "fdc:0") //, m_floppy1(*this, "fdc:1") - , m_terminal(*this, "terminal") { } - DECLARE_READ8_MEMBER(port00_r); - DECLARE_WRITE8_MEMBER(port00_w); DECLARE_WRITE8_MEMBER(portb2_w); DECLARE_WRITE8_MEMBER(portb4_w); DECLARE_WRITE8_MEMBER(portb6_w); @@ -43,28 +43,25 @@ public: DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); DECLARE_DRIVER_INIT(dps1); DECLARE_MACHINE_RESET(dps1); - void kbd_put(u8 data); private: bool m_dma_dir; uint16_t m_dma_adr; - uint8_t m_term_data; required_device<cpu_device> m_maincpu; required_device<upd765_family_device> m_fdc; required_device<floppy_connector> m_floppy0; //required_device<floppy_connector> m_floppy1; - required_device<generic_terminal_device> m_terminal; }; -static ADDRESS_MAP_START( dps1_mem, AS_PROGRAM, 8, dps1_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, dps1_state ) AM_RANGE(0x0000, 0x03ff) AM_READ_BANK("bankr0") AM_WRITE_BANK("bankw0") AM_RANGE(0x0400, 0xffff) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( dps1_io, AS_IO, 8, dps1_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, dps1_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x00, 0x03) AM_READWRITE(port00_r,port00_w) // 2651 uart + AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("uart", mc2661_device, read, write) // S2651 AM_RANGE(0xb0, 0xb1) AM_DEVICE("fdc", upd765_family_device, map) AM_RANGE(0xb2, 0xb3) AM_WRITE(portb2_w) // set dma fdc->memory AM_RANGE(0xb4, 0xb5) AM_WRITE(portb4_w) // set dma memory->fdc @@ -74,35 +71,14 @@ static ADDRESS_MAP_START( dps1_io, AS_IO, 8, dps1_state ) AM_RANGE(0xbc, 0xbd) AM_WRITE(portbc_w) // set A0-7 AM_RANGE(0xbe, 0xbf) AM_WRITE(portbe_w) // disable eprom AM_RANGE(0xff, 0xff) AM_READWRITE(portff_r, portff_w) + // other allocated ports, optional + // AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("uart2", mc2661_device, read, write) // S2651 + // AM_RANGE(0x08, 0x0b) parallel ports + AM_RANGE(0x10, 0x17) AM_NOP // pair of AM9519 interrupt controllers + // AM_RANGE(0x18, 0x1f) control lines 0 to 7 + AM_RANGE(0xe0, 0xe3) AM_NOP //unknown device ADDRESS_MAP_END -// uart in -READ8_MEMBER( dps1_state::port00_r ) -{ - uint8_t data = 0x4e; - switch(offset) - { - case 0: - data = m_term_data; - m_term_data = 0; - break; - case 1: - data = (m_term_data) ? 3 : 1; - break; - case 3: - data = 0x27; - default: - break; - } - return data; -} - -// uart out -WRITE8_MEMBER( dps1_state::port00_w ) -{ - if (offset == 0) - m_terminal->write(space, 0, data); -} // read from disk, to memory WRITE8_MEMBER( dps1_state::portb2_w ) @@ -201,11 +177,6 @@ DRIVER_INIT_MEMBER( dps1_state, dps1 ) static INPUT_PORTS_START( dps1 ) INPUT_PORTS_END -void dps1_state::kbd_put(u8 data) -{ - m_term_data = data; -} - static SLOT_INTERFACE_START( floppies ) SLOT_INTERFACE( "floppy0", FLOPPY_8_DSDD ) SLOT_INTERFACE_END @@ -213,13 +184,20 @@ SLOT_INTERFACE_END static MACHINE_CONFIG_START( dps1 ) // basic machine hardware MCFG_CPU_ADD("maincpu", Z80, 4000000) - MCFG_CPU_PROGRAM_MAP(dps1_mem) - MCFG_CPU_IO_MAP(dps1_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_MACHINE_RESET_OVERRIDE(dps1_state, dps1) /* video hardware */ - MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) - MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(dps1_state, kbd_put)) + MCFG_DEVICE_ADD("uart", MC2661, XTAL_5_0688MHz) + MCFG_MC2661_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_MC2661_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_MC2661_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart",mc2661_device,rx_w)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart",mc2661_device,dsr_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart",mc2661_device,cts_w)) // floppy MCFG_UPD765A_ADD("fdc", false, true) diff --git a/src/mame/drivers/dragon.cpp b/src/mame/drivers/dragon.cpp index a6c56109853..ae9c8552187 100644 --- a/src/mame/drivers/dragon.cpp +++ b/src/mame/drivers/dragon.cpp @@ -19,6 +19,11 @@ #include "formats/sdf_dsk.h" #include "imagedev/flopdrv.h" +#include "bus/coco/dragon_fdc.h" +#include "bus/coco/dragon_jcbsnd.h" +#include "bus/coco/coco_pak.h" +#include "bus/coco/coco_ssc.h" + //************************************************************************** // ADDRESS MAPS @@ -175,7 +180,7 @@ SLOT_INTERFACE_END static MACHINE_CONFIG_START( dragon_base ) MCFG_DEVICE_MODIFY(":") - MCFG_DEVICE_CLOCK(XTAL_4_433619MHz) + MCFG_DEVICE_CLOCK(XTAL_14_218MHz/4) // basic machine hardware MCFG_CPU_ADD("maincpu", M6809E, DERIVED_CLOCK(1, 1)) @@ -200,7 +205,7 @@ static MACHINE_CONFIG_START( dragon_base ) MCFG_PIA_IRQA_HANDLER(WRITELINE(coco_state, pia1_firq_a)) MCFG_PIA_IRQB_HANDLER(WRITELINE(coco_state, pia1_firq_b)) - MCFG_SAM6883_ADD(SAM_TAG, XTAL_4_433619MHz, MAINCPU_TAG, AS_PROGRAM) + MCFG_SAM6883_ADD(SAM_TAG, XTAL_14_218MHz/4, MAINCPU_TAG, AS_PROGRAM) MCFG_SAM6883_RES_CALLBACK(READ8(dragon_state, sam_read)) MCFG_CASSETTE_ADD("cassette") MCFG_CASSETTE_FORMATS(coco_cassette_formats) @@ -280,7 +285,7 @@ static MACHINE_CONFIG_DERIVED( d64plus, dragon64 ) MCFG_PALETTE_ADD_MONOCHROME("palette") // crtc - MCFG_MC6845_ADD("crtc", HD6845, "plus_screen", 14218000 / 8) /* unknown clock, hand tuned to get ~50 fps */ + MCFG_MC6845_ADD("crtc", HD6845, "plus_screen", XTAL_14_218MHz/4/2) MCFG_MC6845_SHOW_BORDER_AREA(false) MCFG_MC6845_CHAR_WIDTH(8) MCFG_MC6845_UPDATE_ROW_CB(d64plus_state, crtc_update_row) diff --git a/src/mame/drivers/dsb46.cpp b/src/mame/drivers/dsb46.cpp index 57c1f7936f4..a488d18a55a 100644 --- a/src/mame/drivers/dsb46.cpp +++ b/src/mame/drivers/dsb46.cpp @@ -65,7 +65,7 @@ static ADDRESS_MAP_START( dsb46_io, AS_IO, 8, dsb46_state ) AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE("ctc1", z80ctc_device, read, write) AM_RANGE(0x1a, 0x1a) AM_WRITE(port1a_w) //AM_RANGE(0x10, 0x10) disk related - //AM_RANGE(0x14, 0x14) ?? + //AM_RANGE(0x14, 0x14) ?? (read after CTC1 TRG3) //AM_RANGE(0x18, 0x18) ?? //AM_RANGE(0x1c, 0x1c) disk data //AM_RANGE(0x1d, 0x1d) disk status (FF = no fdc) @@ -104,7 +104,7 @@ static const z80_daisy_config daisy_chain[] = static MACHINE_CONFIG_START( dsb46 ) // basic machine hardware - MCFG_CPU_ADD("maincpu", Z80, 4000000) + MCFG_CPU_ADD("maincpu", Z80, XTAL_24MHz / 6) MCFG_CPU_PROGRAM_MAP(dsb46_mem) MCFG_CPU_IO_MAP(dsb46_io) MCFG_Z80_DAISY_CHAIN(daisy_chain) @@ -112,12 +112,12 @@ static MACHINE_CONFIG_START( dsb46 ) MCFG_MACHINE_RESET_OVERRIDE(dsb46_state, dsb46) /* video hardware */ - MCFG_DEVICE_ADD("uart_clock", CLOCK, 153600) - MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("sio", z80sio_device, txca_w)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio", z80sio_device, rxca_w)) + MCFG_DEVICE_ADD("ctc_clock", CLOCK, XTAL_1_8432MHz) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc1", z80ctc_device, trg0)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc1", z80ctc_device, trg2)) /* Devices */ - MCFG_DEVICE_ADD("sio", Z80SIO, XTAL_4MHz) + MCFG_DEVICE_ADD("sio", Z80SIO, XTAL_24MHz / 6) MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) MCFG_Z80SIO_OUT_DTRA_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) @@ -127,8 +127,12 @@ static MACHINE_CONFIG_START( dsb46 ) MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio_device, rxa_w)) MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio_device, ctsa_w)) - MCFG_DEVICE_ADD("ctc1", Z80CTC, XTAL_4MHz) + MCFG_DEVICE_ADD("ctc1", Z80CTC, XTAL_24MHz / 6) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80CTC_ZC0_CB(DEVWRITELINE("sio", z80sio_device, rxca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio", z80sio_device, txca_w)) + MCFG_Z80CTC_ZC2_CB(DEVWRITELINE("sio", z80sio_device, rxcb_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio", z80sio_device, txcb_w)) MACHINE_CONFIG_END ROM_START( dsb46 ) diff --git a/src/mame/drivers/dual68.cpp b/src/mame/drivers/dual68.cpp index 214d58dd4e9..bf152f1b346 100644 --- a/src/mame/drivers/dual68.cpp +++ b/src/mame/drivers/dual68.cpp @@ -11,6 +11,8 @@ #include "emu.h" #include "cpu/m68000/m68000.h" #include "cpu/i8085/i8085.h" +//#include "bus/s100/s100.h" +#include "machine/i8251.h" #include "machine/terminal.h" @@ -25,7 +27,7 @@ public: { } void kbd_put(u8 data); - DECLARE_WRITE16_MEMBER(dual68_terminal_w); + DECLARE_WRITE16_MEMBER(terminal_w); private: virtual void machine_reset() override; @@ -37,7 +39,7 @@ private: -WRITE16_MEMBER( dual68_state::dual68_terminal_w ) +WRITE16_MEMBER( dual68_state::terminal_w ) { m_terminal->write(space, 0, data >> 8); } @@ -46,7 +48,7 @@ static ADDRESS_MAP_START(dual68_mem, AS_PROGRAM, 16, dual68_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00000000, 0x0000ffff) AM_RAM AM_SHARE("ram") AM_RANGE(0x00080000, 0x00081fff) AM_ROM AM_REGION("user1",0) - AM_RANGE(0x007f0000, 0x007f0001) AM_WRITE(dual68_terminal_w) + AM_RANGE(0x007f0000, 0x007f0001) AM_WRITE(terminal_w) AM_RANGE(0x00800000, 0x00801fff) AM_ROM AM_REGION("user1",0) ADDRESS_MAP_END @@ -58,6 +60,14 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(sio4_io, AS_IO, 8, dual68_state) ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x22, 0x22) AM_DEVREADWRITE("uart1", i8251_device, status_r, control_w) + AM_RANGE(0x23, 0x23) AM_DEVREADWRITE("uart1", i8251_device, data_r, data_w) + AM_RANGE(0x2a, 0x2a) AM_DEVREADWRITE("uart2", i8251_device, status_r, control_w) + AM_RANGE(0x2b, 0x2b) AM_DEVREADWRITE("uart2", i8251_device, data_r, data_w) + AM_RANGE(0x32, 0x32) AM_DEVREADWRITE("uart3", i8251_device, status_r, control_w) + AM_RANGE(0x33, 0x33) AM_DEVREADWRITE("uart3", i8251_device, data_r, data_w) + AM_RANGE(0x3a, 0x3a) AM_DEVREADWRITE("uart4", i8251_device, status_r, control_w) + AM_RANGE(0x3b, 0x3b) AM_DEVREADWRITE("uart4", i8251_device, data_r, data_w) ADDRESS_MAP_END /* Input ports */ @@ -91,6 +101,11 @@ static MACHINE_CONFIG_START( dual68 ) /* video hardware */ MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(dual68_state, kbd_put)) + + MCFG_DEVICE_ADD("uart1", I8251, 0) + MCFG_DEVICE_ADD("uart2", I8251, 0) + MCFG_DEVICE_ADD("uart3", I8251, 0) + MCFG_DEVICE_ADD("uart4", I8251, 0) MACHINE_CONFIG_END /* ROM definition */ diff --git a/src/mame/drivers/dynax.cpp b/src/mame/drivers/dynax.cpp index 06e77fc2181..dc4ec3aef85 100644 --- a/src/mame/drivers/dynax.cpp +++ b/src/mame/drivers/dynax.cpp @@ -4300,8 +4300,8 @@ static MACHINE_CONFIG_START( hnoridur ) MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(hnoridur_banked_map) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MCFG_NVRAM_ADD_0FILL("nvram") @@ -4363,8 +4363,8 @@ static MACHINE_CONFIG_START( hjingi ) MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(hjingi_banked_map) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MCFG_NVRAM_ADD_0FILL("nvram") @@ -4569,7 +4569,7 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( mjangels, yarunara ) MCFG_DEVICE_MODIFY("bankdev") MCFG_DEVICE_PROGRAM_MAP(mjangels_banked_map) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(21) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(21) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( quiztvqq, mjangels ) @@ -4805,8 +4805,8 @@ static MACHINE_CONFIG_START( tenkai ) MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(tenkai_banked_map) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MCFG_MACHINE_START_OVERRIDE(dynax_state,dynax) @@ -4877,8 +4877,8 @@ static MACHINE_CONFIG_START( gekisha ) MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(gekisha_banked_map) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(17) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(17) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MCFG_MACHINE_START_OVERRIDE(dynax_state,dynax) diff --git a/src/mame/drivers/ec65.cpp b/src/mame/drivers/ec65.cpp index 49d04fa7788..cbd2865f5d1 100644 --- a/src/mame/drivers/ec65.cpp +++ b/src/mame/drivers/ec65.cpp @@ -2,9 +2,9 @@ // copyright-holders:Miodrag Milanovic, Robbbert /*************************************************************************** - EC-65 +EC-65 (also known as Octopus) - 16/07/2009 Initial driver. +2009-07-16 Initial driver. ****************************************************************************/ @@ -67,8 +67,7 @@ static ADDRESS_MAP_START(ec65_mem, AS_PROGRAM, 8, ec65_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0xdfff) AM_RAM AM_RANGE(0xe000, 0xe003) AM_DEVREADWRITE(PIA6821_TAG, pia6821_device, read, write) - AM_RANGE(0xe010, 0xe010) AM_DEVREADWRITE(ACIA6850_TAG, acia6850_device, status_r, control_w) - AM_RANGE(0xe011, 0xe011) AM_DEVREADWRITE(ACIA6850_TAG, acia6850_device, data_r, data_w) + AM_RANGE(0xe010, 0xe011) AM_DEVREADWRITE(ACIA6850_TAG, acia6850_device, read, write) AM_RANGE(0xe100, 0xe10f) AM_DEVREADWRITE(VIA6522_0_TAG, via6522_device, read, write) AM_RANGE(0xe110, 0xe11f) AM_DEVREADWRITE(VIA6522_1_TAG, via6522_device, read, write) AM_RANGE(0xe130, 0xe133) AM_DEVREADWRITE(ACIA6551_TAG, mos6551_device, read, write) @@ -239,10 +238,10 @@ ROM_START( ec65k ) ROM_LOAD( "ec65k.ic19", 0xf000, 0x1000, CRC(5e5a890a) SHA1(daa006f2179fd156833e11c73b37881cafe5dede)) ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD( "chargen.ic19", 0x0000, 0x1000, CRC(9b56a28d) SHA1(41c04fd9fb542c50287bc0e366358a61fc4b0cd4)) // Located on VDU card + ROM_LOAD( "chargen.ic19", 0x0000, 0x1000, CRC(9b56a28d) SHA1(41c04fd9fb542c50287bc0e366358a61fc4b0cd4)) // Located on VDU card, suspect bad dump ROM_END /* Driver */ /* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */ -COMP( 1985, ec65, 0, 0, ec65, ec65, ec65_state, 0, "Elektor Electronics", "EC-65", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) -COMP( 1985, ec65k, ec65, 0, ec65k, ec65, ec65k_state, 0, "Elektor Electronics", "EC-65K", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) +COMP( 1985, ec65, 0, 0, ec65, ec65, ec65_state, 0, "Elektor Electronics", "EC-65", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) +COMP( 1985, ec65k, ec65, 0, ec65k, ec65, ec65k_state, 0, "Elektor Electronics", "EC-65K", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW) diff --git a/src/mame/drivers/einstein.cpp b/src/mame/drivers/einstein.cpp index 4a333745f5b..ce1d75f413b 100644 --- a/src/mame/drivers/einstein.cpp +++ b/src/mame/drivers/einstein.cpp @@ -1,79 +1,162 @@ -// license:GPL-2.0+ -// copyright-holders:Kevin Thacker, Dirk Best, Phill Harvey-Smith +// license: GPL-2.0+ +// copyright-holders: Kevin Thacker, Dirk Best, Phill Harvey-Smith +// thanks-to: Chris Coxall, Andrew Dunipace /****************************************************************************** Tatung Einstein - TMS9129 VDP Graphics - 16k ram - - Z80 CPU (4 MHz) - - Z80 CTC (4 MHz) - channel 0 is serial transmit clock - channel 1 is serial receive clock - trigger for channel 0,1 and 2 is a 2 MHz clock - trigger for channel 3 is the terminal count of channel 2 - - Intel 8251 Serial (2 MHz clock?) - - WD1770 Floppy Disc controller - density is fixed, 4 drives and double sided supported - - AY-3-8910 PSG (2 MHz) - port A and port B are connected to the keyboard. Port A is keyboard - line select, Port B is data. - - printer connected to port A of PIO. /ACK from printer is connected to /ASTB. - D7-D0 of PIO port A is printer data lines. - ARDY of PIO is connected to /STROBE on printer. - - user port is port B of PIO - keyboard connected to port A and port B of PSG - TODO: - - The ADC is not emulated! - - printer emulation needs checking! - - Many thanks to Chris Coxall for the schematics of the TC-01, the dump of the - system rom and a dump of a Xtal boot disc. - - Many thanks to Andrew Dunipace for his help with the 80-column card - and Speculator hardware (Spectrum emulator). - - Kevin Thacker [MESS driver] - - - 2011-Mar-14, Phill Harvey-Smith. - Having traced out the circuit of the TK02 80 coumn card, I have changed the - emulation to match what the hardware does, the emulation was mostly correct, - just some minor issues with the addressing of the VRAM, and bit 0 of the - status register is the latched output of the 6845 DE, and not vblank. - - Also added defines to stop the log being flooded with keyboard messages :) + - Einstein 256 support (need bios dump) ******************************************************************************/ #include "emu.h" -#include "includes/einstein.h" - #include "cpu/z80/z80.h" #include "cpu/z80/z80daisy.h" +#include "cpu/z80/z80daisy_generic.h" +#include "bus/centronics/ctronics.h" +#include "bus/einstein/pipe/pipe.h" +#include "bus/einstein/userport/userport.h" +#include "bus/rs232/rs232.h" +#include "machine/adc0844.h" #include "machine/clock.h" +#include "machine/i8251.h" +#include "machine/ram.h" +#include "machine/rescap.h" +#include "machine/timer.h" +#include "machine/wd_fdc.h" +#include "machine/z80ctc.h" #include "machine/z80pio.h" +#include "video/tms9928a.h" #include "sound/ay8910.h" +#include "screen.h" #include "softlist.h" #include "speaker.h" +/*************************************************************************** + CONSTANTS +***************************************************************************/ + #define VERBOSE_KEYBOARD 0 #define VERBOSE_DISK 0 +#define XTAL_X001 XTAL_10_738635MHz +#define XTAL_X002 XTAL_8MHz + +#define IC_I001 "i001" /* Z8400A */ +#define IC_I030 "i030" /* AY-3-8910 */ +#define IC_I038 "i038" /* TMM9129 */ +#define IC_I042 "i042" /* WD1770-PH */ +#define IC_I050 "i050" /* ADC0844CCN */ +#define IC_I058 "i058" /* Z8430A */ +#define IC_I060 "i060" /* uPD8251A */ +#define IC_I063 "i063" /* Z8420A */ + + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +class einstein_state : public driver_device +{ +public: + einstein_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, IC_I001), + m_keyboard_daisy(*this, "keyboard_daisy"), + m_adc_daisy(*this, "adc_daisy"), + m_fire_daisy(*this, "fire_daisy"), + m_pipe(*this, "pipe"), + m_fdc(*this, IC_I042), + m_ram(*this, RAM_TAG), + m_psg(*this, IC_I030), + m_centronics(*this, "centronics"), + m_strobe_timer(*this, "strobe"), + m_bios(*this, "bios"), + m_bank1(*this, "bank1"), + m_bank2(*this, "bank2"), + m_bank3(*this, "bank3"), + m_floppy{ { *this, IC_I042 ":0" }, { *this, IC_I042 ":1" }, { *this, IC_I042 ":2" }, { *this, IC_I042 ":3" } }, + m_line(*this, "LINE%u", 0), + m_extra(*this, "EXTRA"), + m_buttons(*this, "BUTTONS"), + m_rom_enabled(0), + m_keyboard_line(0), m_keyboard_data(0xff), + m_centronics_busy(0), m_centronics_perror(0), m_centronics_fault(0), m_strobe(-1), + m_int(0) + {} + + DECLARE_INPUT_CHANGED_MEMBER(joystick_button); + TIMER_DEVICE_CALLBACK_MEMBER(keyboard_timer_callback); + DECLARE_WRITE8_MEMBER(keyboard_line_write); + DECLARE_READ8_MEMBER(keyboard_data_read); + DECLARE_READ8_MEMBER(reset_r); + DECLARE_WRITE8_MEMBER(reset_w); + DECLARE_READ8_MEMBER(rom_r); + DECLARE_WRITE8_MEMBER(rom_w); + template <int src> DECLARE_WRITE_LINE_MEMBER(int_w); + DECLARE_READ8_MEMBER(kybint_msk_r); + DECLARE_WRITE8_MEMBER(kybint_msk_w); + DECLARE_WRITE8_MEMBER(adcint_msk_w); + DECLARE_WRITE8_MEMBER(fireint_msk_w); + DECLARE_WRITE8_MEMBER(drsel_w); + DECLARE_WRITE_LINE_MEMBER(write_centronics_busy); + DECLARE_WRITE_LINE_MEMBER(write_centronics_perror); + DECLARE_WRITE_LINE_MEMBER(write_centronics_fault); + DECLARE_WRITE_LINE_MEMBER(ardy_w); + TIMER_DEVICE_CALLBACK_MEMBER(strobe_callback); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + void einstein_scan_keyboard(); + + required_device<cpu_device> m_maincpu; + required_device<z80daisy_generic_device> m_keyboard_daisy; + required_device<z80daisy_generic_device> m_adc_daisy; + required_device<z80daisy_generic_device> m_fire_daisy; + required_device<tatung_pipe_device> m_pipe; + required_device<wd1770_device> m_fdc; + required_device<ram_device> m_ram; + required_device<ay8910_device> m_psg; + required_device<centronics_device> m_centronics; + required_device<timer_device> m_strobe_timer; + required_memory_region m_bios; + required_memory_bank m_bank1; + required_memory_bank m_bank2; + required_memory_bank m_bank3; + required_device<floppy_connector> m_floppy[4]; + required_ioport_array<8> m_line; + required_ioport m_extra; + required_ioport m_buttons; + + int m_rom_enabled; + + uint8_t m_keyboard_line; + uint8_t m_keyboard_data; + + int m_centronics_busy; + int m_centronics_perror; + int m_centronics_fault; + int m_strobe; + + int m_int; +}; + /*************************************************************************** KEYBOARD ***************************************************************************/ +INPUT_CHANGED_MEMBER( einstein_state::joystick_button ) +{ + int button_down = (m_buttons->read() & 0x03) != 0x03; + m_fire_daisy->int_w(button_down ? ASSERT_LINE : CLEAR_LINE); +} + /* refresh keyboard data. It is refreshed when the keyboard line is written */ void einstein_state::einstein_scan_keyboard() { @@ -91,26 +174,16 @@ void einstein_state::einstein_scan_keyboard() m_keyboard_data = data; } -TIMER_DEVICE_CALLBACK_MEMBER(einstein_state::einstein_keyboard_timer_callback) +TIMER_DEVICE_CALLBACK_MEMBER( einstein_state::keyboard_timer_callback ) { /* re-scan keyboard */ einstein_scan_keyboard(); - /* if /fire1 or /fire2 is 0, signal a fire interrupt */ - if ((m_buttons->read() & 0x03) != 0) - { - m_interrupt |= EINSTEIN_FIRE_INT; - } - - /* keyboard data changed? */ if (m_keyboard_data != 0xff) - { - /* generate interrupt */ - m_interrupt |= EINSTEIN_KEY_INT; - } + m_keyboard_daisy->int_w(ASSERT_LINE); } -WRITE8_MEMBER(einstein_state::einstein_keyboard_line_write) +WRITE8_MEMBER( einstein_state::keyboard_line_write ) { if (VERBOSE_KEYBOARD) logerror("einstein_keyboard_line_write: %02x\n", data); @@ -121,7 +194,7 @@ WRITE8_MEMBER(einstein_state::einstein_keyboard_line_write) einstein_scan_keyboard(); } -READ8_MEMBER(einstein_state::einstein_keyboard_data_read) +READ8_MEMBER( einstein_state::keyboard_data_read ) { /* re-scan the keyboard */ einstein_scan_keyboard(); @@ -137,62 +210,58 @@ READ8_MEMBER(einstein_state::einstein_keyboard_data_read) FLOPPY DRIVES ***************************************************************************/ -WRITE8_MEMBER(einstein_state::einstein_drsel_w) +WRITE8_MEMBER(einstein_state::drsel_w) { - if(VERBOSE_DISK) - logerror("%s: einstein_drsel_w %02x\n", machine().describe_context(), data); + if (VERBOSE_DISK) + logerror("%s: drsel_w %02x\n", machine().describe_context(), data); - /* bit 0 to 3 select the drive */ - static const char *names[] = { IC_I042 ":0", IC_I042 ":1", IC_I042 ":2", IC_I042 ":3" }; floppy_image_device *floppy = nullptr; - for(int i=0; i<4; i++) { - if(BIT(data, i)) { - floppy_connector *con = machine().device<floppy_connector>(names[i]); - if(con) - floppy = con->get_device(); - } - } - /* double sided drive connected? */ - if (m_config->read() & data) - { - /* bit 4 selects the side then */ - //floppy->ss_w(BIT(data, 4)); - } - if (floppy) floppy->ss_w(0); + if (BIT(data, 0)) floppy = m_floppy[0]->get_device(); + if (BIT(data, 1)) floppy = m_floppy[1]->get_device(); + if (BIT(data, 2)) floppy = m_floppy[2]->get_device(); + if (BIT(data, 3)) floppy = m_floppy[3]->get_device(); + + if (floppy) + floppy->ss_w(BIT(data, 4)); + m_fdc->set_floppy(floppy); } /*************************************************************************** - UART + CENTRONICS ***************************************************************************/ -WRITE_LINE_MEMBER(einstein_state::einstein_serial_transmit_clock) +WRITE_LINE_MEMBER( einstein_state::write_centronics_busy ) { - m_uart->write_txc(state); + m_centronics_busy = state; } -WRITE_LINE_MEMBER(einstein_state::einstein_serial_receive_clock) +WRITE_LINE_MEMBER( einstein_state::write_centronics_perror ) { - m_uart->write_rxc(state); + m_centronics_perror = state; } +WRITE_LINE_MEMBER( einstein_state::write_centronics_fault ) +{ + m_centronics_fault = state; +} -/*************************************************************************** - MEMORY BANKING -***************************************************************************/ - -void einstein_state::einstein_page_rom() +WRITE_LINE_MEMBER( einstein_state::ardy_w ) { - m_bank1->set_base(m_rom_enabled ? m_region_bios->base() : m_ram->pointer()); + if (m_strobe == 0 && state == 1) + { + m_centronics->write_strobe(1); + m_strobe_timer->adjust(attotime::from_double(TIME_OF_74LS123(RES_K(10), CAP_N(1)))); + } + + m_strobe = state; } -/* writing to this port is a simple trigger, and switches between RAM and ROM */ -WRITE8_MEMBER(einstein_state::einstein_rom_w) +TIMER_DEVICE_CALLBACK_MEMBER( einstein_state::strobe_callback ) { - m_rom_enabled ^= 1; - einstein_page_rom(); + m_centronics->write_strobe(0); } @@ -200,8 +269,6 @@ WRITE8_MEMBER(einstein_state::einstein_rom_w) INTERRUPTS ***************************************************************************/ -/* int priority */ -/* keyboard int->ctc/adc->pio */ static const z80_daisy_config einstein_daisy_chain[] = { { "keyboard_daisy" }, @@ -212,30 +279,39 @@ static const z80_daisy_config einstein_daisy_chain[] = { nullptr } }; -WRITE_LINE_MEMBER(einstein_state::write_centronics_busy) -{ - m_centronics_busy = state; -} - -WRITE_LINE_MEMBER(einstein_state::write_centronics_perror) +template <int src> WRITE_LINE_MEMBER( einstein_state::int_w ) { - m_centronics_perror = state; -} + int old = m_int; -WRITE_LINE_MEMBER(einstein_state::write_centronics_fault) -{ - m_centronics_fault = state; + if (state) + { + m_int |= (1 << src); + if (!old) + { + m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); + m_pipe->host_int_w(ASSERT_LINE); + } + } + else + { + m_int &= ~(1 << src); + if (old && !m_int) + { + m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); + m_pipe->host_int_w(CLEAR_LINE); + } + } } -READ8_MEMBER(einstein_state::einstein_kybintmsk_r) +READ8_MEMBER( einstein_state::kybint_msk_r ) { uint8_t data = 0; - /* clear key int. a read of this I/O port will do this or a reset */ - m_interrupt &= ~EINSTEIN_KEY_INT; + // reading this port clears the keyboard interrupt + m_keyboard_daisy->int_w(CLEAR_LINE); /* bit 0 and 1: fire buttons on the joysticks */ - data |= m_buttons->read(); + data |= m_buttons->read() & 0x03; /* bit 2 to 4: printer status */ data |= m_centronics_busy << 2; @@ -246,62 +322,27 @@ READ8_MEMBER(einstein_state::einstein_kybintmsk_r) data |= m_extra->read(); if(VERBOSE_KEYBOARD) - logerror("%s: einstein_kybintmsk_r %02x\n", machine().describe_context(), data); + logerror("%s: kybint_msk_r %02x\n", machine().describe_context(), data); return data; } -WRITE8_MEMBER(einstein_state::einstein_kybintmsk_w) +WRITE8_MEMBER( einstein_state::kybint_msk_w ) { - logerror("%s: einstein_kybintmsk_w %02x\n", machine().describe_context(), data); - - /* set mask from bit 0 */ - if (data & 0x01) - { - logerror("key int is disabled\n"); - m_interrupt_mask &= ~EINSTEIN_KEY_INT; - } - else - { - logerror("key int is enabled\n"); - m_interrupt_mask |= EINSTEIN_KEY_INT; - } + logerror("KEY interrupt %s\n", BIT(data, 0) ? "disabled" : "enabled"); + m_keyboard_daisy->mask_w(BIT(data, 0)); } -/* writing to this I/O port sets the state of the mask; D0 is used */ -/* writing 0 enables the /ADC interrupt */ -WRITE8_MEMBER(einstein_state::einstein_adcintmsk_w) +WRITE8_MEMBER( einstein_state::adcint_msk_w ) { - logerror("%s: einstein_adcintmsk_w %02x\n", machine().describe_context(), data); - - if (data & 0x01) - { - logerror("adc int is disabled\n"); - m_interrupt_mask &= ~EINSTEIN_ADC_INT; - } - else - { - logerror("adc int is enabled\n"); - m_interrupt_mask |= EINSTEIN_ADC_INT; - } + logerror("ADC interrupt %s\n", BIT(data, 0) ? "disabled" : "enabled"); + m_adc_daisy->mask_w(BIT(data, 0)); } -/* writing to this I/O port sets the state of the mask; D0 is used */ -/* writing 0 enables the /FIRE interrupt */ -WRITE8_MEMBER(einstein_state::einstein_fire_int_w) +WRITE8_MEMBER( einstein_state::fireint_msk_w ) { - logerror("%s: einstein_fire_int_w %02x\n", machine().describe_context(), data); - - if (data & 0x01) - { - logerror("fire int is disabled\n"); - m_interrupt_mask &= ~EINSTEIN_FIRE_INT; - } - else - { - logerror("fire int is enabled\n"); - m_interrupt_mask |= EINSTEIN_FIRE_INT; - } + logerror("FIRE interrupt %s\n", BIT(data, 0) ? "disabled" : "enabled"); + m_fire_daisy->mask_w(BIT(data, 0)); } @@ -309,8 +350,42 @@ WRITE8_MEMBER(einstein_state::einstein_fire_int_w) MACHINE EMULATION ***************************************************************************/ +READ8_MEMBER( einstein_state::rom_r ) +{ + m_rom_enabled ^= 1; + m_bank1->set_entry(m_rom_enabled); + + return 0xff; +} + +WRITE8_MEMBER( einstein_state::rom_w ) +{ + m_rom_enabled ^= 1; + m_bank1->set_entry(m_rom_enabled); +} + +READ8_MEMBER( einstein_state::reset_r ) +{ + m_psg->reset(); + m_fdc->reset(); + + return 0xff; +} + +WRITE8_MEMBER( einstein_state::reset_w ) +{ + m_psg->reset(); + m_fdc->reset(); +} + void einstein_state::machine_start() { + // initialize memory mapping + m_bank1->configure_entry(0, m_ram->pointer()); + m_bank1->configure_entry(1, m_bios->base()); + m_bank2->set_base(m_ram->pointer()); + m_bank3->set_base(m_ram->pointer() + 0x8000); + // setup expansion slot m_pipe->set_program_space(&m_maincpu->space(AS_PROGRAM)); m_pipe->set_io_space(&m_maincpu->space(AS_IO)); @@ -318,16 +393,16 @@ void einstein_state::machine_start() void einstein_state::machine_reset() { - /* initialize memory mapping */ - m_bank2->set_base(m_ram->pointer()); - m_bank3->set_base(m_ram->pointer() + 0x8000); + // rom enabled on reset m_rom_enabled = 1; - einstein_page_rom(); + m_bank1->set_entry(m_rom_enabled); - /* a reset causes the fire int, adc int, keyboard int mask - to be set to 1, which causes all these to be DISABLED */ - m_interrupt = 0; - m_interrupt_mask = 0; + // interrupt mask enabled + m_keyboard_daisy->mask_w(1); + m_adc_daisy->mask_w(1); + m_fire_daisy->mask_w(1); + + m_strobe = -1; } @@ -340,34 +415,25 @@ static ADDRESS_MAP_START( einstein_mem, AS_PROGRAM, 8, einstein_state ) AM_RANGE(0x8000, 0x0ffff) AM_RAMBANK("bank3") ADDRESS_MAP_END -/* The I/O ports are decoded into 8 blocks using address lines A3 to A7 */ +// I/O ports are decoded into 8 blocks using address lines A3 to A7 static ADDRESS_MAP_START( einstein_io, AS_IO, 8, einstein_state ) ADDRESS_MAP_UNMAP_HIGH - /* block 0, ay8910 psg */ + AM_RANGE(0x00, 0x00) AM_MIRROR(0xff04) AM_READWRITE(reset_r, reset_w) AM_RANGE(0x02, 0x02) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I030, ay8910_device, data_r, address_w) AM_RANGE(0x03, 0x03) AM_MIRROR(0xff04) AM_DEVWRITE(IC_I030, ay8910_device, data_w) - /* block 1, tms9928a vdp */ - AM_RANGE(0x08, 0x08) AM_MIRROR(0xff06) AM_DEVREADWRITE("tms9929a", tms9929a_device, vram_read, vram_write) - AM_RANGE(0x09, 0x09) AM_MIRROR(0xff06) AM_DEVREADWRITE("tms9929a", tms9929a_device, register_read, register_write) - /* block 2, i8251 uart */ + AM_RANGE(0x08, 0x08) AM_MIRROR(0xff06) AM_DEVREADWRITE("vdp", tms9129_device, vram_read, vram_write) + AM_RANGE(0x09, 0x09) AM_MIRROR(0xff06) AM_DEVREADWRITE("vdp", tms9129_device, register_read, register_write) AM_RANGE(0x10, 0x10) AM_MIRROR(0xff06) AM_DEVREADWRITE(IC_I060, i8251_device, data_r, data_w) AM_RANGE(0x11, 0x11) AM_MIRROR(0xff06) AM_DEVREADWRITE(IC_I060, i8251_device, status_r, control_w) - /* block 3, wd1770 floppy controller */ AM_RANGE(0x18, 0x1b) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I042, wd1770_device, read, write) - /* block 4, internal controls */ - AM_RANGE(0x20, 0x20) AM_MIRROR(0xff00) AM_READWRITE(einstein_kybintmsk_r, einstein_kybintmsk_w) - AM_RANGE(0x21, 0x21) AM_MIRROR(0xff00) AM_WRITE(einstein_adcintmsk_w) - AM_RANGE(0x23, 0x23) AM_MIRROR(0xff00) AM_WRITE(einstein_drsel_w) - AM_RANGE(0x24, 0x24) AM_MIRROR(0xff00) AM_WRITE(einstein_rom_w) - AM_RANGE(0x25, 0x25) AM_MIRROR(0xff00) AM_WRITE(einstein_fire_int_w) - /* block 5, z80ctc */ + AM_RANGE(0x20, 0x20) AM_MIRROR(0xff00) AM_READWRITE(kybint_msk_r, kybint_msk_w) + AM_RANGE(0x21, 0x21) AM_MIRROR(0xff00) AM_WRITE(adcint_msk_w) + AM_RANGE(0x23, 0x23) AM_MIRROR(0xff00) AM_WRITE(drsel_w) + AM_RANGE(0x24, 0x24) AM_MIRROR(0xff00) AM_READWRITE(rom_r, rom_w) + AM_RANGE(0x25, 0x25) AM_MIRROR(0xff00) AM_WRITE(fireint_msk_w) AM_RANGE(0x28, 0x2b) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I058, z80ctc_device, read, write) - /* block 6, z80pio */ - AM_RANGE(0x30, 0x33) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I063, z80pio_device, read, write) -#if 0 - /* block 7, adc */ - AM_RANGE(0x38, 0x38) AM_MIRROR(0xff07) AM_DEVREADWRITE_LEGACY(IC_I050, adc0844_r, adc0844_w) -#endif + AM_RANGE(0x30, 0x33) AM_MIRROR(0xff04) AM_DEVREADWRITE(IC_I063, z80pio_device, read_alt, write_alt) + AM_RANGE(0x38, 0x38) AM_MIRROR(0xff07) AM_DEVREADWRITE("adc", adc0844_device, read, write) ADDRESS_MAP_END @@ -462,41 +528,31 @@ static INPUT_PORTS_START( einstein ) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("CONTROL") PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - /* fire buttons for analogue joysticks */ + // fire buttons for analogue joysticks PORT_START("BUTTONS") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Joystick 1 Button 1") PORT_PLAYER(1) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Joystick 2 Button 1") PORT_PLAYER(2) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Joystick 1 Button 1") PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, einstein_state, joystick_button, nullptr) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Joystick 2 Button 1") PORT_PLAYER(2) PORT_CHANGED_MEMBER(DEVICE_SELF, einstein_state, joystick_button, nullptr) PORT_BIT(0xfc, IP_ACTIVE_HIGH, IPT_UNUSED) - /* analog joystick 1 x axis */ - PORT_START("JOY1_X") - PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) PORT_PLAYER(1) PORT_REVERSE - - /* analog joystick 1 y axis */ - PORT_START("JOY1_Y") - PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) PORT_PLAYER(1) PORT_REVERSE - - /* analog joystick 2 x axis */ - PORT_START("JOY2_X") - PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) PORT_PLAYER(2) PORT_REVERSE - - /* analog joystick 2 Y axis */ - PORT_START("JOY2_Y") - PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(1) PORT_MINMAX(1,0xff) PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) PORT_PLAYER(2) PORT_REVERSE - - PORT_START("config") - PORT_CONFNAME(0x01, 0x00, "Floppy drive #1") - PORT_CONFSETTING(0x00, "Single sided") - PORT_CONFSETTING(0x01, "Double sided") - PORT_CONFNAME(0x02, 0x00, "Floppy drive #2") - PORT_CONFSETTING(0x00, "Single sided") - PORT_CONFSETTING(0x02, "Double sided") - PORT_CONFNAME(0x04, 0x00, "Floppy drive #3") - PORT_CONFSETTING(0x00, "Single sided") - PORT_CONFSETTING(0x04, "Double sided") - PORT_CONFNAME(0x08, 0x00, "Floppy drive #4") - PORT_CONFSETTING(0x00, "Single sided") - PORT_CONFSETTING(0x08, "Double sided") + PORT_START("analogue_1_x") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0,0xff) PORT_PLAYER(1) + PORT_CODE_DEC(KEYCODE_4_PAD) PORT_CODE_INC(KEYCODE_6_PAD) + PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) + + PORT_START("analogue_1_y") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0,0xff) PORT_PLAYER(1) + PORT_CODE_DEC(KEYCODE_8_PAD) PORT_CODE_INC(KEYCODE_2_PAD) + PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) + PORT_REVERSE + + PORT_START("analogue_2_x") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0,0xff) PORT_PLAYER(2) + PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) + + PORT_START("analogue_2_y") + PORT_BIT(0xff, 0x80, IPT_AD_STICK_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(100) PORT_CENTERDELTA(100) PORT_MINMAX(0,0xff) PORT_PLAYER(2) + PORT_CODE_DEC(JOYCODE_Y_UP_SWITCH) PORT_CODE_INC(JOYCODE_Y_DOWN_SWITCH) + PORT_REVERSE INPUT_PORTS_END @@ -505,7 +561,12 @@ INPUT_PORTS_END ***************************************************************************/ static SLOT_INTERFACE_START( einstein_floppies ) - SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) + SLOT_INTERFACE("3ss", TEAC_FD_30A) + SLOT_INTERFACE("3ds", FLOPPY_3_DSDD) + SLOT_INTERFACE("525ssqd", FLOPPY_525_SSQD) + SLOT_INTERFACE("525qd", FLOPPY_525_QD) + SLOT_INTERFACE("35ssdd", FLOPPY_35_SSDD) + SLOT_INTERFACE("35dd", FLOPPY_35_DD) SLOT_INTERFACE_END static MACHINE_CONFIG_START( einstein ) @@ -517,17 +578,20 @@ static MACHINE_CONFIG_START( einstein ) /* this is actually clocked at the system clock 4 MHz, but this would be too fast for our driver. So we update at 50Hz and hope this is good enough. */ - MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard", einstein_state, einstein_keyboard_timer_callback, attotime::from_hz(50)) + MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard", einstein_state, keyboard_timer_callback, attotime::from_hz(50)) MCFG_DEVICE_ADD(IC_I063, Z80PIO, XTAL_X002 / 2) - MCFG_Z80PIO_OUT_INT_CB(INPUTLINE(IC_I001, INPUT_LINE_IRQ0)) + MCFG_Z80PIO_OUT_INT_CB(WRITELINE(einstein_state, int_w<0>)) MCFG_Z80PIO_OUT_PA_CB(DEVWRITE8("cent_data_out", output_latch_device, write)) - MCFG_Z80PIO_OUT_PB_CB(DEVWRITELINE("centronics", centronics_device, write_strobe)) + MCFG_Z80PIO_OUT_ARDY_CB(WRITELINE(einstein_state, ardy_w)) + MCFG_Z80PIO_IN_PB_CB(DEVREAD8("user", einstein_userport_device, read)) + MCFG_Z80PIO_OUT_PB_CB(DEVWRITE8("user", einstein_userport_device, write)) + MCFG_Z80PIO_OUT_BRDY_CB(DEVWRITELINE("user", einstein_userport_device, brdy_w)) MCFG_DEVICE_ADD(IC_I058, Z80CTC, XTAL_X002 / 2) - MCFG_Z80CTC_INTR_CB(INPUTLINE(IC_I001, INPUT_LINE_IRQ0)) - MCFG_Z80CTC_ZC0_CB(WRITELINE(einstein_state, einstein_serial_transmit_clock)) - MCFG_Z80CTC_ZC1_CB(WRITELINE(einstein_state, einstein_serial_receive_clock)) + MCFG_Z80CTC_INTR_CB(WRITELINE(einstein_state, int_w<1>)) + MCFG_Z80CTC_ZC0_CB(DEVWRITELINE(IC_I060, i8251_device, write_txc)) + MCFG_Z80CTC_ZC1_CB(DEVWRITELINE(IC_I060, i8251_device, write_rxc)) MCFG_Z80CTC_ZC2_CB(DEVWRITELINE(IC_I058, z80ctc_device, trg3)) MCFG_CLOCK_ADD("ctc_trigger", XTAL_X002 / 4) @@ -536,24 +600,34 @@ static MACHINE_CONFIG_START( einstein ) MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE(IC_I058, z80ctc_device, trg2)) /* Einstein daisy chain support for non-Z80 devices */ - MCFG_DEVICE_ADD("keyboard_daisy", EINSTEIN_KEYBOARD_DAISY, 0) - MCFG_DEVICE_ADD("adc_daisy", EINSTEIN_ADC_DAISY, 0) - MCFG_DEVICE_ADD("fire_daisy", EINSTEIN_FIRE_DAISY, 0) + MCFG_Z80DAISY_GENERIC_ADD("keyboard_daisy", 0xf7) + MCFG_Z80DAISY_GENERIC_INT_CB(WRITELINE(einstein_state, int_w<2>)) + MCFG_Z80DAISY_GENERIC_ADD("adc_daisy", 0xfb) + MCFG_Z80DAISY_GENERIC_INT_CB(WRITELINE(einstein_state, int_w<3>)) + MCFG_Z80DAISY_GENERIC_ADD("fire_daisy", 0xfd) + MCFG_Z80DAISY_GENERIC_INT_CB(WRITELINE(einstein_state, int_w<4>)) /* video hardware */ - MCFG_DEVICE_ADD( "tms9929a", TMS9929A, XTAL_10_738635MHz / 2 ) - MCFG_TMS9928A_VRAM_SIZE(0x4000) /* 16k RAM, provided by IC i040 and i041 */ + MCFG_DEVICE_ADD("vdp", TMS9129, XTAL_10_738635MHz / 2) + MCFG_TMS9928A_VRAM_SIZE(0x4000) // 16k RAM, provided by IC i040 and i041 MCFG_TMS9928A_SET_SCREEN("screen") MCFG_TMS9928A_SCREEN_ADD_PAL("screen") - MCFG_SCREEN_UPDATE_DEVICE("tms9929a", tms9929a_device, screen_update) + MCFG_SCREEN_UPDATE_DEVICE("vdp", tms9129_device, screen_update) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD(IC_I030, AY8910, XTAL_X002 / 4) - MCFG_AY8910_PORT_B_READ_CB(READ8(einstein_state, einstein_keyboard_data_read)) - MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(einstein_state, einstein_keyboard_line_write)) + MCFG_AY8910_PORT_B_READ_CB(READ8(einstein_state, keyboard_data_read)) + MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(einstein_state, keyboard_line_write)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.20) + MCFG_ADC0844_ADD("adc") + MCFG_ADC0844_INTR_CB(DEVWRITELINE("adc_daisy", z80daisy_generic_device, int_w)) + MCFG_ADC0844_CH1_CB(IOPORT("analogue_1_x")) + MCFG_ADC0844_CH2_CB(IOPORT("analogue_1_y")) + MCFG_ADC0844_CH3_CB(IOPORT("analogue_2_x")) + MCFG_ADC0844_CH4_CB(IOPORT("analogue_2_y")) + /* printer */ MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") MCFG_CENTRONICS_ACK_HANDLER(DEVWRITELINE(IC_I063, z80pio_device, strobe_a)) @@ -563,15 +637,27 @@ static MACHINE_CONFIG_START( einstein ) MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics") - /* uart */ - MCFG_DEVICE_ADD(IC_I060, I8251, 0) + MCFG_TIMER_DRIVER_ADD("strobe", einstein_state, strobe_callback) + // uart + MCFG_DEVICE_ADD(IC_I060, I8251, XTAL_X002 / 4) + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + + // rs232 port + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE(IC_I060, i8251_device, write_rxd)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE(IC_I060, i8251_device, write_dsr)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE(IC_I060, i8251_device, write_cts)) + + // floppy MCFG_WD1770_ADD(IC_I042, XTAL_X002) - MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":0", einstein_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":1", einstein_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":2", einstein_floppies, "525dd", floppy_image_device::default_floppy_formats) - MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":3", einstein_floppies, "525dd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":0", einstein_floppies, "3ss", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":1", einstein_floppies, "3ss", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":2", einstein_floppies, "525qd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD(IC_I042 ":3", einstein_floppies, "525qd", floppy_image_device::default_floppy_formats) /* software lists */ MCFG_SOFTWARE_LIST_ADD("disk_list","einstein") @@ -583,6 +669,11 @@ static MACHINE_CONFIG_START( einstein ) // tatung pipe connector MCFG_TATUNG_PIPE_ADD("pipe") + MCFG_TATUNG_PIPE_NMI_HANDLER(INPUTLINE(IC_I001, INPUT_LINE_NMI)) + + // user port + MCFG_EINSTEIN_USERPORT_ADD("user") + MCFG_EINSTEIN_USERPORT_BSTB_HANDLER(DEVWRITELINE(IC_I063, z80pio_device, strobe_b)) MACHINE_CONFIG_END @@ -609,7 +700,7 @@ ROM_END ROM_START( einst256 ) ROM_REGION(0x8000, "bios", 0) - ROM_LOAD("tc256.rom", 0x0000, 0x4000, CRC(ef8dad88) SHA1(eb2102d3bef572db7161c26a7c68a5fcf457b4d0) ) + ROM_LOAD("tc256.rom", 0x0000, 0x4000, BAD_DUMP CRC(ef8dad88) SHA1(eb2102d3bef572db7161c26a7c68a5fcf457b4d0) ) ROM_END @@ -619,4 +710,4 @@ ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS COMP( 1984, einstein, 0, 0, einstein, einstein, einstein_state, 0, "Tatung", "Einstein TC-01", 0 ) -COMP( 1984, einst256, 0, 0, einstein, einstein, einstein_state, 0, "Tatung", "Einstein 256", MACHINE_NOT_WORKING ) +COMP( 1986, einst256, 0, 0, einstein, einstein, einstein_state, 0, "Tatung", "Einstein 256", MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/electron.cpp b/src/mame/drivers/electron.cpp index 82f7d94dda1..dcbff9e12d6 100644 --- a/src/mame/drivers/electron.cpp +++ b/src/mame/drivers/electron.cpp @@ -57,12 +57,7 @@ Incomplete: - Graphics (seems to be wrong for several games) - 1 MHz bus is not emulated - Bus claiming by ULA is not implemented - - Currently the cartridge support always loads the upper rom in page 12 - and the lower rom in page 0. This might need further documentation in - the software list and loading code. -Missing: - - Other peripherals ******************************************************************************/ #include "emu.h" @@ -229,9 +224,6 @@ static MACHINE_CONFIG_START( electron ) MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY) MCFG_CASSETTE_INTERFACE("electron_cass") - MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "electron_cart") - MCFG_GENERIC_LOAD(electron_state, electron_cart) - /* expansion port */ MCFG_ELECTRON_EXPANSION_SLOT_ADD("exp", electron_expansion_devices, "plus3", false) MCFG_ELECTRON_EXPANSION_SLOT_IRQ_HANDLER(INPUTLINE("maincpu", M6502_IRQ_LINE)) @@ -240,6 +232,7 @@ static MACHINE_CONFIG_START( electron ) /* software lists */ MCFG_SOFTWARE_LIST_ADD("cass_list", "electron_cass") MCFG_SOFTWARE_LIST_ADD("cart_list", "electron_cart") + MCFG_SOFTWARE_LIST_ADD("flop_list", "electron_flop") MACHINE_CONFIG_END @@ -259,7 +252,7 @@ MACHINE_CONFIG_END /* Electron Rom Load */ ROM_START(electron) ROM_REGION( 0x44000, "user1", 0 ) /* OS Rom */ - ROM_LOAD( "os.rom", 0x40000, 0x4000, CRC(bf63fb1f) SHA1(a48b8fa0cfb09140e808ac8a187316c605a0b32e) ) /* OS rom */ + ROM_LOAD( "b02_acornos-1.rom", 0x40000, 0x4000, CRC(a0c2cf43) SHA1(a27ce645472cc5497690e4bfab43710efbb0792d) ) /* OS rom */ /* 00000 0 Second external socket on the expansion module (SK2) */ /* 04000 1 Second external socket on the expansion module (SK2) */ /* 08000 2 First external socket on the expansion module (SK1) */ diff --git a/src/mame/drivers/elekscmp.cpp b/src/mame/drivers/elekscmp.cpp index bf5b9882a55..7813e4d8d6f 100644 --- a/src/mame/drivers/elekscmp.cpp +++ b/src/mame/drivers/elekscmp.cpp @@ -2,11 +2,10 @@ // copyright-holders:Miodrag Milanovic, Robbbert /*************************************************************************** - Elektor SC/MP +Elektor SC/MP - 22/11/2009 Skeleton driver. - - 10/MAY/2012 Added keyboard [Robbbert] +2009-11-22 Skeleton driver. +2012-05-10 Added keyboard [Robbbert] To Use: - Press MINUS to enter data input mode @@ -33,18 +32,19 @@ class elekscmp_state : public driver_device { public: elekscmp_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_x0(*this, "X0"), - m_x1(*this, "X1"), - m_x2(*this, "X2"), - m_x3(*this, "X3") { } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_x0(*this, "X0") + , m_x1(*this, "X1") + , m_x2(*this, "X2") + , m_x3(*this, "X3") + { } DECLARE_READ8_MEMBER(keyboard_r); DECLARE_WRITE8_MEMBER(hex_display_w); uint8_t convert_key(uint8_t data); -protected: +private: required_device<cpu_device> m_maincpu; required_ioport m_x0; required_ioport m_x1; @@ -60,8 +60,7 @@ WRITE8_MEMBER(elekscmp_state::hex_display_w) uint8_t elekscmp_state::convert_key(uint8_t data) { - uint8_t i; - for (i = 0; i < 8; i++) + for (u8 i = 0; i < 8; i++) if (BIT(data, i)) return i; @@ -95,7 +94,7 @@ READ8_MEMBER(elekscmp_state::keyboard_r) return 0; } -static ADDRESS_MAP_START(elekscmp_mem, AS_PROGRAM, 8, elekscmp_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, elekscmp_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0x0fff) AM_RANGE(0x000, 0x5ff) AM_ROM // ROM @@ -144,7 +143,7 @@ INPUT_PORTS_END static MACHINE_CONFIG_START( elekscmp ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",INS8060, XTAL_4MHz) - MCFG_CPU_PROGRAM_MAP(elekscmp_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) /* video hardware */ MCFG_DEFAULT_LAYOUT(layout_elekscmp) diff --git a/src/mame/drivers/elwro800.cpp b/src/mame/drivers/elwro800.cpp index 78fdeb8f573..db006dce814 100644 --- a/src/mame/drivers/elwro800.cpp +++ b/src/mame/drivers/elwro800.cpp @@ -620,12 +620,12 @@ static MACHINE_CONFIG_START( elwro800 ) MCFG_DEVICE_ADD("bank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(elwro800_bank1) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_DEVICE_ADD("bank2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(elwro800_bank2) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MACHINE_CONFIG_END diff --git a/src/mame/drivers/enmirage.cpp b/src/mame/drivers/enmirage.cpp index 7f5d00f250b..1bec1447996 100644 --- a/src/mame/drivers/enmirage.cpp +++ b/src/mame/drivers/enmirage.cpp @@ -125,8 +125,7 @@ static ADDRESS_MAP_START( mirage_map, AS_PROGRAM, 8, enmirage_state ) AM_RANGE(0x0000, 0x7fff) AM_RAMBANK("sndbank") // 32k window on 128k of wave RAM AM_RANGE(0x8000, 0xbfff) AM_RAM // main RAM AM_RANGE(0xc000, 0xdfff) AM_RAM // expansion RAM - AM_RANGE(0xe100, 0xe100) AM_DEVREADWRITE("acia6850", acia6850_device, status_r, control_w) - AM_RANGE(0xe101, 0xe101) AM_DEVREADWRITE("acia6850", acia6850_device, data_r, data_w) + AM_RANGE(0xe100, 0xe101) AM_DEVREADWRITE("acia6850", acia6850_device, read, write) AM_RANGE(0xe200, 0xe2ff) AM_DEVREADWRITE("via6522", via6522_device, read, write) AM_RANGE(0xe400, 0xe4ff) AM_NOP AM_RANGE(0xe800, 0xe803) AM_DEVREADWRITE("wd1772", wd1772_device, read, write) diff --git a/src/mame/drivers/equites.cpp b/src/mame/drivers/equites.cpp index ff9d5f98c16..d10fbe2b4c6 100644 --- a/src/mame/drivers/equites.cpp +++ b/src/mame/drivers/equites.cpp @@ -416,7 +416,7 @@ WRITE8_MEMBER(equites_state::equites_c0f8_w) case 1: // c0f9: RST75 trigger (written by NMI handler) // Note: solder pad CP3 on the pcb would allow to disable this - generic_pulse_irq_line(*m_audiocpu, I8085_RST75_LINE, 1); + m_audiocpu->pulse_input_line(I8085_RST75_LINE, m_audiocpu->minimum_quantum_time()); break; case 2: // c0fa: INTR trigger (written by NMI handler) diff --git a/src/mame/drivers/esprit.cpp b/src/mame/drivers/esprit.cpp new file mode 100644 index 00000000000..4b5ec164966 --- /dev/null +++ b/src/mame/drivers/esprit.cpp @@ -0,0 +1,158 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-02 Skeleton + +Hazeltine Esprit terminals. + +Espirit: R6502P, R6531, HD46505RP, MC6850P, 16.5888 + +Espirit3: 2x R6551AP, HD46850P (6850), R6502BP, R6545-1AP, R6522AP, 1.8432, 17.9712 + + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/m6502/m6502.h" +#include "video/mc6845.h" +#include "screen.h" + +class esprit_state : public driver_device +{ +public: + esprit_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_p_chargen(*this, "chargen") + , m_p_videoram(*this, "videoram") + , m_palette(*this, "palette") + { } + + MC6845_UPDATE_ROW(crtc_update_row); + DECLARE_DRIVER_INIT(init); + +private: + required_device<cpu_device> m_maincpu; + required_region_ptr<u8> m_p_chargen; + required_shared_ptr<u8> m_p_videoram; + optional_device<palette_device> m_palette; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, esprit_state ) + ADDRESS_MAP_GLOBAL_MASK (0x7fff) + AM_RANGE(0x0058,0x0058) AM_DEVREADWRITE("crtc", mc6845_device, status_r, address_w) + AM_RANGE(0x0059,0x0059) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w) + AM_RANGE(0x0080,0x1fff) AM_RAM + AM_RANGE(0x2000,0x6fff) AM_RAM AM_SHARE("videoram") + AM_RANGE(0x7000,0x7fff) AM_ROM AM_REGION("roms", 0) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( mem3_map, AS_PROGRAM, 8, esprit_state ) + AM_RANGE(0x0000,0x202f) AM_RAM + AM_RANGE(0x2030,0x3fff) AM_RAM AM_SHARE("videoram") // it might start at 3000 + AM_RANGE(0x81c0,0x81c0) AM_DEVREADWRITE("crtc", mc6845_device, status_r, address_w) + AM_RANGE(0x81c1,0x81c1) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w) + AM_RANGE(0xe000,0xffff) AM_ROM AM_REGION("roms", 0) +ADDRESS_MAP_END + +static INPUT_PORTS_START( esprit ) +INPUT_PORTS_END + +MC6845_UPDATE_ROW( esprit_state::crtc_update_row ) +{ + const rgb_t *pens = m_palette->palette()->entry_list_raw(); + uint8_t chr,gfx; + uint16_t mem,x; + uint32_t *p = &bitmap.pix32(y); + + for (x = 0; x < x_count; x++) + { + mem = (ma + x) & 0x7ff; + chr = m_p_videoram[mem]; + + /* get pattern of pixels for that character scanline */ + gfx = m_p_chargen[(chr<<4) | ra] ^ ((x == cursor_x) ? 0xff : 0); + + /* Display a scanline of a character (8 pixels) */ + *p++ = pens[BIT(gfx, 7)]; + *p++ = pens[BIT(gfx, 6)]; + *p++ = pens[BIT(gfx, 5)]; + *p++ = pens[BIT(gfx, 4)]; + *p++ = pens[BIT(gfx, 3)]; + *p++ = pens[BIT(gfx, 2)]; + *p++ = pens[BIT(gfx, 1)]; + *p++ = pens[BIT(gfx, 0)]; + } +} + +/* F4 Character Displayer */ +static const gfx_layout esprit_charlayout = +{ + 8, 12, /* 8 x 12 characters */ + 256, /* 256 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 0, 8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static GFXDECODE_START( esprit ) + GFXDECODE_ENTRY( "chargen", 0x0000, esprit_charlayout, 0, 1 ) +GFXDECODE_END + +DRIVER_INIT_MEMBER( esprit_state, init ) +{ + // chargen is incomplete, copy the first half into the vacant second half + for (u16 i = 0; i < 0x800; i++) + m_p_chargen[0x800 | i] = m_p_chargen[i]; +} + + +static MACHINE_CONFIG_START( esprit ) + MCFG_CPU_ADD("maincpu", M6502, 1000000) // no idea of clock + MCFG_CPU_PROGRAM_MAP(mem_map) + + /* video hardware */ + MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // not correct + MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update) + MCFG_SCREEN_SIZE(32*8, 32*8) + MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1) + MCFG_GFXDECODE_ADD("gfxdecode", "palette", esprit) + MCFG_PALETTE_ADD_MONOCHROME("palette") + + /* Devices */ + MCFG_MC6845_ADD("crtc", MC6845, "screen", 1000000) // clk unknown + MCFG_MC6845_SHOW_BORDER_AREA(false) + MCFG_MC6845_CHAR_WIDTH(8) + MCFG_MC6845_UPDATE_ROW_CB(esprit_state, crtc_update_row) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( esprit3, esprit ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(mem3_map) +MACHINE_CONFIG_END + +ROM_START( esprit ) + // Esprit + ROM_REGION( 0x1000, "roms", 0 ) + ROM_LOAD( "hazeltine_esprit.u19", 0x0000, 0x1000, CRC(6fdec792) SHA1(a1d1d68c8793e7e15ab5cd17682c299dff3985cb) ) + ROM_REGION( 0x1000, "chargen", ROMREGION_INVERT ) + ROM_LOAD( "hazeltine_esprit.u26", 0x0000, 0x0804, CRC(93f45f13) SHA1(1f493b44124c348759469e24fdfa8b7c52fe6fac) ) +ROM_END + +ROM_START( esprit3 ) + // Esprit III + ROM_REGION( 0x10000, "roms", 0 ) + ROM_LOAD( "hazeltine_espritiii.u5", 0x0000, 0x2000, CRC(fd63dad1) SHA1(b2a3e7db8480b28cab2b2834ad89fb6257f13cba) ) + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD( "hazeltine_espritiii.u19", 0x0000, 0x1000, CRC(33e4a8ef) SHA1(e19c84a3c5f94812928ea84bab3ede7970dd5e72) ) +ROM_END + +COMP( 1981, esprit, 0, 0, esprit, esprit, esprit_state, init, "Hazeltine", "Esprit", MACHINE_IS_SKELETON ) +COMP( 1981, esprit3, esprit, 0, esprit3, esprit, esprit_state, 0, "Hazeltine", "Esprit III", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/esq1.cpp b/src/mame/drivers/esq1.cpp index 773ce100727..600341203e9 100644 --- a/src/mame/drivers/esq1.cpp +++ b/src/mame/drivers/esq1.cpp @@ -396,7 +396,7 @@ public: { } required_device<cpu_device> m_maincpu; - required_device<mc68681_device> m_duart; + required_device<scn2681_device> m_duart; required_device<esq1_filters> m_filters; optional_device<wd1772_device> m_fdc; optional_device<esqpanel2x40_device> m_panel; @@ -409,7 +409,6 @@ public: DECLARE_WRITE8_MEMBER(mapper_w); DECLARE_WRITE8_MEMBER(analog_w); - DECLARE_WRITE_LINE_MEMBER(duart_irq_handler); DECLARE_WRITE_LINE_MEMBER(duart_tx_a); DECLARE_WRITE_LINE_MEMBER(duart_tx_b); DECLARE_WRITE8_MEMBER(duart_output); @@ -503,7 +502,7 @@ static ADDRESS_MAP_START( esq1_map, AS_PROGRAM, 8, esq1_state ) AM_RANGE(0x0000, 0x1fff) AM_RAM // OSRAM AM_RANGE(0x4000, 0x5fff) AM_RAM // SEQRAM AM_RANGE(0x6000, 0x63ff) AM_DEVREADWRITE("es5503", es5503_device, read, write) - AM_RANGE(0x6400, 0x640f) AM_DEVREADWRITE("duart", mc68681_device, read, write) + AM_RANGE(0x6400, 0x640f) AM_DEVREADWRITE("duart", scn2681_device, read, write) AM_RANGE(0x6800, 0x68ff) AM_WRITE(analog_w) AM_RANGE(0x7000, 0x7fff) AM_ROMBANK("osbank") AM_RANGE(0x8000, 0xffff) AM_ROM AM_REGION("osrom", 0x8000) // OS "high" ROM is always mapped here @@ -514,7 +513,7 @@ static ADDRESS_MAP_START( sq80_map, AS_PROGRAM, 8, esq1_state ) AM_RANGE(0x4000, 0x5fff) AM_RAM // SEQRAM // AM_RANGE(0x4000, 0x5fff) AM_READWRITE(seqdosram_r, seqdosram_w) AM_RANGE(0x6000, 0x63ff) AM_DEVREADWRITE("es5503", es5503_device, read, write) - AM_RANGE(0x6400, 0x640f) AM_DEVREADWRITE("duart", mc68681_device, read, write) + AM_RANGE(0x6400, 0x640f) AM_DEVREADWRITE("duart", scn2681_device, read, write) AM_RANGE(0x6800, 0x68ff) AM_WRITE(analog_w) AM_RANGE(0x6c00, 0x6dff) AM_WRITE(mapper_w) AM_RANGE(0x6e00, 0x6fff) AM_READWRITE(wd1772_r, wd1772_w) @@ -537,11 +536,6 @@ ADDRESS_MAP_END // OP5 = metronome hi // OP6/7 = tape out -WRITE_LINE_MEMBER(esq1_state::duart_irq_handler) -{ - m_maincpu->set_input_line(M6809_IRQ_LINE, state); -} - WRITE8_MEMBER(esq1_state::duart_output) { int bank = ((data >> 1) & 0x7); @@ -588,18 +582,18 @@ static MACHINE_CONFIG_START( esq1 ) MCFG_CPU_ADD("maincpu", M6809E, 4000000) // how fast is it? MCFG_CPU_PROGRAM_MAP(esq1_map) - MCFG_MC68681_ADD("duart", 4000000) - MCFG_MC68681_SET_EXTERNAL_CLOCKS(500000, 500000, 1000000, 1000000) - MCFG_MC68681_IRQ_CALLBACK(WRITELINE(esq1_state, duart_irq_handler)) + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_8MHz / 2) + MCFG_MC68681_SET_EXTERNAL_CLOCKS(XTAL_8MHz / 16, XTAL_8MHz / 16, XTAL_8MHz / 8, XTAL_8MHz / 8) + MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", M6809_IRQ_LINE)) MCFG_MC68681_A_TX_CALLBACK(WRITELINE(esq1_state, duart_tx_a)) MCFG_MC68681_B_TX_CALLBACK(WRITELINE(esq1_state, duart_tx_b)) MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(esq1_state, duart_output)) MCFG_ESQPANEL2X40_ADD("panel") - MCFG_ESQPANEL_TX_CALLBACK(DEVWRITELINE("duart", mc68681_device, rx_b_w)) + MCFG_ESQPANEL_TX_CALLBACK(DEVWRITELINE("duart", scn2681_device, rx_b_w)) MCFG_MIDI_PORT_ADD("mdin", midiin_slot, "midiin") - MCFG_MIDI_RX_HANDLER(DEVWRITELINE("duart", mc68681_device, rx_a_w)) // route MIDI Tx send directly to 68681 channel A Rx + MCFG_MIDI_RX_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_a_w)) // route MIDI Tx send directly to 68681 channel A Rx MCFG_MIDI_PORT_ADD("mdout", midiout_slot, "midiout") @@ -609,7 +603,7 @@ static MACHINE_CONFIG_START( esq1 ) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) - MCFG_ES5503_ADD("es5503", 7000000) + MCFG_ES5503_ADD("es5503", XTAL_8MHz) MCFG_ES5503_OUTPUT_CHANNELS(8) MCFG_ES5503_IRQ_FUNC(WRITELINE(esq1_state, esq1_doc_irq)) MCFG_ES5503_ADC_FUNC(READ8(esq1_state, esq1_adc_read)) @@ -696,6 +690,6 @@ ROM_START( esqm ) ROM_END -CONS( 1986, esq1, 0 , 0, esq1, esq1, esq1_state, 0, "Ensoniq", "ESQ-1", MACHINE_NOT_WORKING ) -CONS( 1986, esqm, esq1, 0, esq1, esq1, esq1_state, 0, "Ensoniq", "ESQ-M", MACHINE_NOT_WORKING ) -CONS( 1988, sq80, 0, 0, sq80, esq1, esq1_state, 0, "Ensoniq", "SQ-80", MACHINE_NOT_WORKING ) +CONS( 1986, esq1, 0 , 0, esq1, esq1, esq1_state, 0, "Ensoniq", "ESQ-1 Digital Wave Synthesizer", MACHINE_NOT_WORKING ) +CONS( 1986, esqm, esq1, 0, esq1, esq1, esq1_state, 0, "Ensoniq", "ESQ-M Digital Wave Synthesizer Module", MACHINE_NOT_WORKING ) +CONS( 1988, sq80, 0, 0, sq80, esq1, esq1_state, 0, "Ensoniq", "SQ-80 Cross Wave Synthesizer", MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/esq5505.cpp b/src/mame/drivers/esq5505.cpp index 9e7ed769967..bc48e68781f 100644 --- a/src/mame/drivers/esq5505.cpp +++ b/src/mame/drivers/esq5505.cpp @@ -616,7 +616,7 @@ static MACHINE_CONFIG_START( vfx ) MCFG_ESQPANEL_TX_CALLBACK(DEVWRITELINE("duart", mc68681_device, rx_b_w)) MCFG_ESQPANEL_ANALOG_CALLBACK(WRITE16(esq5505_state, analog_w)) - MCFG_MC68681_ADD("duart", 4000000) + MCFG_DEVICE_ADD("duart", MC68681, 4000000) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(esq5505_state, duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(WRITELINE(esq5505_state, duart_tx_a)) MCFG_MC68681_B_TX_CALLBACK(WRITELINE(esq5505_state, duart_tx_b)) @@ -693,7 +693,7 @@ static MACHINE_CONFIG_START(vfx32) MCFG_ESQPANEL_TX_CALLBACK(DEVWRITELINE("duart", mc68681_device, rx_b_w)) MCFG_ESQPANEL_ANALOG_CALLBACK(WRITE16(esq5505_state, analog_w)) - MCFG_MC68681_ADD("duart", 4000000) + MCFG_DEVICE_ADD("duart", MC68681, 4000000) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(esq5505_state, duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(WRITELINE(esq5505_state, duart_tx_a)) MCFG_MC68681_B_TX_CALLBACK(WRITELINE(esq5505_state, duart_tx_b)) @@ -851,8 +851,12 @@ ROM_END ROM_START( vfxsd ) ROM_REGION(0x40000, "osrom", 0) - ROM_LOAD16_BYTE( "vfxsd_200_lower.bin", 0x000000, 0x010000, CRC(7bd31aea) SHA1(812bf73c4861a5d963f128def14a4a98171c93ad) ) - ROM_LOAD16_BYTE( "vfxsd_200_upper.bin", 0x000001, 0x010000, CRC(9a40efa2) SHA1(e38a2a4514519c1573361cb1526139bfcf94e45a) ) + ROM_SYSTEM_BIOS( 0, "v200", "V200" ) + ROMX_LOAD( "vfxsd_200_lower.bin", 0x000000, 0x010000, CRC(7bd31aea) SHA1(812bf73c4861a5d963f128def14a4a98171c93ad), ROM_SKIP(1) | ROM_BIOS(1) ) + ROMX_LOAD( "vfxsd_200_upper.bin", 0x000001, 0x010000, CRC(9a40efa2) SHA1(e38a2a4514519c1573361cb1526139bfcf94e45a), ROM_SKIP(1) | ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "v133", "V133" ) + ROMX_LOAD( "vfxsd_133_lower.bin", 0x000000, 0x010000, CRC(65407fcf) SHA1(83952a19f6f9ae7886ac828d8bd5ea7fee8d0fe3), ROM_SKIP(1) | ROM_BIOS(2) ) + ROMX_LOAD( "vfxsd_133_upper.bin", 0x000001, 0x010000, CRC(150fcd18) SHA1(e42cf08604b52fab248d15d761de7d835a076940), ROM_SKIP(1) | ROM_BIOS(2) ) ROM_REGION(0x200000, "waverom", ROMREGION_ERASE00) ROM_LOAD16_BYTE( "u57.bin", 0x000001, 0x080000, CRC(85592299) SHA1(1aa7cf612f91972baeba15991d9686ccde01599c) ) diff --git a/src/mame/drivers/esqkt.cpp b/src/mame/drivers/esqkt.cpp index a3e5d5ef931..c20cf0f1c63 100644 --- a/src/mame/drivers/esqkt.cpp +++ b/src/mame/drivers/esqkt.cpp @@ -8,7 +8,7 @@ Hardware: CPU: 68EC020-16 CPU - Serial/timers: SCN2681 (MC68681 clone) + Serial/timers: SCN2681 Sound: 2xES5506 Effects: ES5510 @@ -114,7 +114,7 @@ public: required_device<m68ec020_device> m_maincpu; required_device<es5510_device> m_esp; - required_device<mc68681_device> m_duart; + required_device<scn2681_device> m_duart; required_device<esqpanel2x16_sq1_device> m_sq1panel; required_device<midi_port_device> m_mdout; @@ -144,7 +144,7 @@ static ADDRESS_MAP_START( kt_map, AS_PROGRAM, 32, esqkt_state ) AM_RANGE(0x200000, 0x20003f) AM_DEVREADWRITE8("ensoniq", es5506_device, read, write, 0xffffffff) AM_RANGE(0x240000, 0x24003f) AM_DEVREADWRITE8("ensoniq2", es5506_device, read, write, 0xffffffff) AM_RANGE(0x280000, 0x2801ff) AM_DEVREADWRITE8("esp", es5510_device, host_r, host_w, 0xffffffff) - AM_RANGE(0x300000, 0x30001f) AM_DEVREADWRITE8("duart", mc68681_device, read, write, 0xffffffff) + AM_RANGE(0x300000, 0x30001f) AM_DEVREADWRITE8("duart", scn2681_device, read, write, 0xffffffff) AM_RANGE(0xff0000, 0xffffff) AM_RAM AM_SHARE("osram") ADDRESS_MAP_END @@ -209,9 +209,9 @@ static MACHINE_CONFIG_START( kt ) MCFG_DEVICE_DISABLE() MCFG_ESQPANEL2X16_SQ1_ADD("sq1panel") - MCFG_ESQPANEL_TX_CALLBACK(DEVWRITELINE("duart", mc68681_device, rx_b_w)) + MCFG_ESQPANEL_TX_CALLBACK(DEVWRITELINE("duart", scn2681_device, rx_b_w)) - MCFG_MC68681_ADD("duart", 4000000) + MCFG_DEVICE_ADD("duart", SCN2681, 4000000) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(esqkt_state, duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(WRITELINE(esqkt_state, duart_tx_a)) MCFG_MC68681_B_TX_CALLBACK(WRITELINE(esqkt_state, duart_tx_b)) @@ -220,7 +220,7 @@ static MACHINE_CONFIG_START( kt ) MCFG_MC68681_SET_EXTERNAL_CLOCKS(500000, 500000, 1000000, 1000000) MCFG_MIDI_PORT_ADD("mdin", midiin_slot, "midiin") - MCFG_MIDI_RX_HANDLER(DEVWRITELINE("duart", mc68681_device, rx_a_w)) // route MIDI Tx send directly to 68681 channel A Rx + MCFG_MIDI_RX_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_a_w)) // route MIDI Tx send directly to 68681 channel A Rx MCFG_MIDI_PORT_ADD("mdout", midiout_slot, "midiout") diff --git a/src/mame/drivers/et3400.cpp b/src/mame/drivers/et3400.cpp index ba098e30954..e3d140c5c63 100644 --- a/src/mame/drivers/et3400.cpp +++ b/src/mame/drivers/et3400.cpp @@ -2,29 +2,30 @@ // copyright-holders:Robbbert /*************************************************************************** - ET-3400 +ET-3400 - 2009-05-12 Skeleton driver. - 2016-04-29 Added Accessory. +2009-05-12 Skeleton driver. +2016-04-29 Added Accessory. - ETA-3400 Memory I/O Accessory - - Provides Tiny Basic, a Terminal, a Serial Interface, a Cassette - interface, and 1k to 4k of expansion RAM. All parts are working. - - The roms are U105 (Monitor), U106 (Tiny Basic), both type NMOS2316E, - and U108 (address decoder PROM). - - Navigating: - LED to Monitor: D1400 - Monitor to Basic: G 1C00 - Monitor to LED: G FC00 - Basic to Monitor: BYE - - All commands in Basic and Monitor are UPPERCASE only. - - Terminal is defaulted to 9600 baud, 7 bits, 2 stop bits. +ETA-3400 Memory I/O Accessory +- Provides Tiny Basic, a Terminal, a Serial Interface, a Cassette + interface, and 1k to 4k of expansion RAM. All parts are working. +- The roms are U105 (Monitor), U106 (Tiny Basic), both type NMOS2316E, + and U108 (address decoder PROM). +- Navigating: + LED to Monitor: D1400 + Monitor to Basic: G 1C00 + Monitor to LED: G FC00 + Basic to Monitor: BYE +- All commands in Basic and Monitor are UPPERCASE only. +- Terminal is defaulted to 9600 baud, 7 bits, 2 stop bits. ****************************************************************************/ #include "emu.h" #include "cpu/m6800/m6800.h" +#include "machine/74259.h" #include "machine/6821pia.h" #include "bus/rs232/rs232.h" #include "imagedev/cassette.h" @@ -41,26 +42,31 @@ public: : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_pia(*this, "pia") + , m_displatch(*this, "displatch%u", 1) , m_rs232(*this, "rs232") , m_cass(*this, "cassette") { } DECLARE_READ8_MEMBER(keypad_r); DECLARE_WRITE8_MEMBER(display_w); + template<int digit> DECLARE_WRITE8_MEMBER(led_w); DECLARE_READ8_MEMBER(pia_ar); DECLARE_WRITE8_MEMBER(pia_aw); DECLARE_READ8_MEMBER(pia_br); DECLARE_WRITE8_MEMBER(pia_bw); + DECLARE_WRITE_LINE_MEMBER(reset_key_w); + DECLARE_WRITE_LINE_MEMBER(segment_test_w); private: required_device<cpu_device> m_maincpu; required_device<pia6821_device> m_pia; + required_device_array<ls259_device, 6> m_displatch; required_device<rs232_port_device> m_rs232; required_device<cassette_image_device> m_cass; }; -READ8_MEMBER( et3400_state::keypad_r ) +READ8_MEMBER(et3400_state::keypad_r) { uint8_t data = 0xff; @@ -74,51 +80,50 @@ READ8_MEMBER( et3400_state::keypad_r ) return data; } -WRITE8_MEMBER( et3400_state::display_w ) +WRITE8_MEMBER(et3400_state::display_w) { -/* This computer sets each segment, one at a time. */ - - static const uint8_t segments[8]={0x40,0x20,0x10,0x08,0x04,0x02,0x01,0x80}; + // A6-A4 decoded by IC22 (74LS42); D0 inverted by one gate of IC21 (74S00) uint8_t digit = (offset >> 4) & 7; - uint8_t segment = segments[offset & 7]; - uint8_t segdata = output().get_digit_value(digit); - - if (data & 1) - segdata |= segment; - else - segdata &= ~segment; + if (digit >= 1 && digit <= 6) + m_displatch[digit - 1]->write_bit(offset & 7, !BIT(data, 0)); +} +template<int digit> +WRITE8_MEMBER(et3400_state::led_w) +{ +/* This computer sets each segment, one at a time. */ + uint8_t segdata = BITSWAP8(~data, 7, 0, 1, 2, 3, 4, 5, 6); output().set_digit_value(digit, segdata); } // d1,2,3 = Baud rate // d4 = gnd // d7 = rs232 in -READ8_MEMBER( et3400_state::pia_ar ) +READ8_MEMBER(et3400_state::pia_ar) { return ioport("BAUD")->read() | (m_rs232->rxd_r() << 7); } // d0 = rs232 out -WRITE8_MEMBER( et3400_state::pia_aw ) +WRITE8_MEMBER(et3400_state::pia_aw) { m_rs232->write_txd(BIT(data, 0)); } // d7 = cass in -READ8_MEMBER( et3400_state::pia_br ) +READ8_MEMBER(et3400_state::pia_br) { return (m_cass->input() > +0.0) << 7; } // d0 = cass out -WRITE8_MEMBER( et3400_state::pia_bw ) +WRITE8_MEMBER(et3400_state::pia_bw) { m_cass->output(BIT(data, 0) ? -1.0 : +1.0); } -static ADDRESS_MAP_START(et3400_mem, AS_PROGRAM, 8, et3400_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, et3400_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0x0fff ) AM_RAM AM_RANGE( 0x1000, 0x1003 ) AM_MIRROR(0x03fc) AM_DEVREADWRITE("pia", pia6821_device, read, write) @@ -128,6 +133,22 @@ static ADDRESS_MAP_START(et3400_mem, AS_PROGRAM, 8, et3400_state) AM_RANGE( 0xfc00, 0xffff ) AM_ROM AM_REGION("roms", 0x1000) ADDRESS_MAP_END +WRITE_LINE_MEMBER(et3400_state::reset_key_w) +{ + // delivered through MC6875 (or 74LS241 on ET-3400A) + m_maincpu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE); + + // PIA also uses reset line + if (!state) + m_pia->reset(); +} + +WRITE_LINE_MEMBER(et3400_state::segment_test_w) +{ + for (int d = 0; d < 6; d++) + m_displatch[d]->clear_w(state); +} + /* Input ports */ static INPUT_PORTS_START( et3400 ) PORT_START("X0") @@ -145,8 +166,7 @@ static INPUT_PORTS_START( et3400 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("8 SS") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("5 CC") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("2 ACCB") PORT_CODE(KEYCODE_2) PORT_CHAR('2') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(".") PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') - PORT_BIT( 0xc0, 0xc0, IPT_UNUSED ) + PORT_BIT( 0xe0, 0xe0, IPT_UNUSED ) PORT_START("X2") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("F FWD") PORT_CODE(KEYCODE_F) PORT_CHAR('F') @@ -165,6 +185,12 @@ static INPUT_PORTS_START( et3400 ) PORT_DIPSETTING( 0x06, "2400" ) PORT_DIPSETTING( 0x04, "4800" ) PORT_DIPSETTING( 0x02, "9600" ) + + PORT_START("RESET") // RESET is directly next to 0, but electrically separate from key matrix + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_STOP) PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, et3400_state, reset_key_w) + + PORT_START("TEST") // No input mechanism for "Segment Test" defined other than shorting pins together + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Segment Test") PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, et3400_state, segment_test_w) INPUT_PORTS_END @@ -180,7 +206,7 @@ DEVICE_INPUT_DEFAULTS_END static MACHINE_CONFIG_START( et3400 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M6800, XTAL_4MHz / 4 ) // 1MHz with memory i/o accessory, or 500khz without it - MCFG_CPU_PROGRAM_MAP(et3400_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) /* video hardware */ MCFG_DEFAULT_LAYOUT(layout_et3400) @@ -194,6 +220,19 @@ static MACHINE_CONFIG_START( et3400 ) MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) + MCFG_DEVICE_ADD("displatch1", LS259, 0) // IC28 + MCFG_ADDRESSABLE_LATCH_PARALLEL_OUT_CB(WRITE8(et3400_state, led_w<1>)) + MCFG_DEVICE_ADD("displatch2", LS259, 0) // IC27 + MCFG_ADDRESSABLE_LATCH_PARALLEL_OUT_CB(WRITE8(et3400_state, led_w<2>)) + MCFG_DEVICE_ADD("displatch3", LS259, 0) // IC26 + MCFG_ADDRESSABLE_LATCH_PARALLEL_OUT_CB(WRITE8(et3400_state, led_w<3>)) + MCFG_DEVICE_ADD("displatch4", LS259, 0) // IC25 + MCFG_ADDRESSABLE_LATCH_PARALLEL_OUT_CB(WRITE8(et3400_state, led_w<4>)) + MCFG_DEVICE_ADD("displatch5", LS259, 0) // IC24 + MCFG_ADDRESSABLE_LATCH_PARALLEL_OUT_CB(WRITE8(et3400_state, led_w<5>)) + MCFG_DEVICE_ADD("displatch6", LS259, 0) // IC23 + MCFG_ADDRESSABLE_LATCH_PARALLEL_OUT_CB(WRITE8(et3400_state, led_w<6>)) + MCFG_CASSETTE_ADD("cassette") MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED) MCFG_SPEAKER_STANDARD_MONO("mono") @@ -213,4 +252,4 @@ ROM_END /* Driver */ /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP( 1976, et3400, 0, 0, et3400, et3400, et3400_state, 0, "Heath Inc", "Heathkit ET-3400", 0 ) +COMP( 1976, et3400, 0, 0, et3400, et3400, et3400_state, 0, "Heath Company", "Heathkit Model ET-3400 Microprocessor Trainer", 0 ) diff --git a/src/mame/drivers/eti660.cpp b/src/mame/drivers/eti660.cpp index 62b13eed4be..82781b86bd2 100644 --- a/src/mame/drivers/eti660.cpp +++ b/src/mame/drivers/eti660.cpp @@ -80,7 +80,7 @@ WRITE8_MEMBER( eti660_state::colorram_w ) /* Memory Maps */ -static ADDRESS_MAP_START( eti660_map, AS_PROGRAM, 8, eti660_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, eti660_state ) ADDRESS_MAP_GLOBAL_MASK(0xfff) AM_RANGE(0x0000, 0x03ff) AM_ROM AM_RANGE(0x0400, 0x047f) AM_RAM @@ -88,7 +88,7 @@ static ADDRESS_MAP_START( eti660_map, AS_PROGRAM, 8, eti660_state ) AM_RANGE(0x0600, 0x0fff) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( eti660_io_map, AS_IO, 8, eti660_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, eti660_state ) AM_RANGE(0x01, 0x01) AM_DEVREADWRITE(CDP1864_TAG, cdp1864_device, dispon_r, step_bgcolor_w) AM_RANGE(0x02, 0x02) AM_READWRITE(pia_r, pia_w) AM_RANGE(0x03, 0x03) AM_WRITE(colorram_w) @@ -305,8 +305,8 @@ QUICKLOAD_LOAD_MEMBER( eti660_state, eti660 ) static MACHINE_CONFIG_START( eti660 ) /* basic machine hardware */ MCFG_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_8_867238MHz/5) - MCFG_CPU_PROGRAM_MAP(eti660_map) - MCFG_CPU_IO_MAP(eti660_io_map) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_COSMAC_WAIT_CALLBACK(VCC) MCFG_COSMAC_CLEAR_CALLBACK(READLINE(eti660_state, clear_r)) MCFG_COSMAC_EF2_CALLBACK(READLINE(eti660_state, ef2_r)) diff --git a/src/mame/drivers/eurocom2.cpp b/src/mame/drivers/eurocom2.cpp index d7051c55b08..e5abeb0124d 100644 --- a/src/mame/drivers/eurocom2.cpp +++ b/src/mame/drivers/eurocom2.cpp @@ -330,8 +330,7 @@ static ADDRESS_MAP_START(eurocom2_map, AS_PROGRAM, 8, eurocom2_state) AM_RANGE(0x0000, 0xefff) AM_RAM AM_SHARE("videoram") AM_RANGE(0xf000, 0xfcef) AM_ROM AM_REGION("maincpu", 0) AM_RANGE(0xfcf0, 0xfcf3) AM_DEVREADWRITE("pia1", pia6821_device, read, write) - AM_RANGE(0xfcf4, 0xfcf4) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0xfcf5, 0xfcf5) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0xfcf4, 0xfcf5) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0xfcf6, 0xfcf7) AM_WRITE(vico_w) AM_RANGE(0xfcf8, 0xfcfb) AM_DEVREADWRITE("pia2", pia6821_device, read, write) AM_RANGE(0xfd30, 0xfd37) AM_DEVREADWRITE("fdc", fd1793_device, read, write) diff --git a/src/mame/drivers/evmbug.cpp b/src/mame/drivers/evmbug.cpp index 92949083e06..f93e2da9e2d 100644 --- a/src/mame/drivers/evmbug.cpp +++ b/src/mame/drivers/evmbug.cpp @@ -15,23 +15,21 @@ #include "cpu/tms9900/tms9995.h" #include "machine/terminal.h" -#define TERMINAL_TAG "terminal" class evmbug_state : public driver_device { public: evmbug_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG) - { - } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_terminal(*this, "terminal") + { } DECLARE_READ8_MEMBER(rs232_r); DECLARE_WRITE8_MEMBER(rs232_w); void kbd_put(u8 data); -protected: +private: virtual void machine_reset() override; uint8_t m_term_data; uint8_t m_term_out; @@ -39,12 +37,12 @@ protected: required_device<generic_terminal_device> m_terminal; }; -static ADDRESS_MAP_START( evmbug_mem, AS_PROGRAM, 8, evmbug_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, evmbug_state ) AM_RANGE(0x0000, 0x17ff) AM_ROM AM_RANGE(0xec00, 0xefff) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( evmbug_io, AS_IO, 8, evmbug_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, evmbug_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x0007) AM_WRITE(rs232_w) AM_RANGE(0x0000, 0x0002) AM_READ(rs232_r) @@ -98,10 +96,10 @@ static MACHINE_CONFIG_START( evmbug ) // basic machine hardware // TMS9995 CPU @ 12.0 MHz // We have no lines connected yet - MCFG_TMS99xx_ADD("maincpu", TMS9995, 12000000, evmbug_mem, evmbug_io ) + MCFG_TMS99xx_ADD("maincpu", TMS9995, 12000000, mem_map, io_map ) /* video hardware */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) + MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(evmbug_state, kbd_put)) MACHINE_CONFIG_END diff --git a/src/mame/drivers/excali64.cpp b/src/mame/drivers/excali64.cpp index 1a55acf3d5a..a9bc490617b 100644 --- a/src/mame/drivers/excali64.cpp +++ b/src/mame/drivers/excali64.cpp @@ -91,7 +91,7 @@ public: MC6845_UPDATE_ROW(update_row); DECLARE_WRITE_LINE_MEMBER(crtc_hs); DECLARE_WRITE_LINE_MEMBER(crtc_vs); - DECLARE_WRITE8_MEMBER(motor_w); + DECLARE_WRITE_LINE_MEMBER(motor_w); DECLARE_MACHINE_RESET(excali64); required_device<palette_device> m_palette; @@ -117,7 +117,7 @@ private: required_device<floppy_connector> m_floppy1; }; -static ADDRESS_MAP_START(excali64_mem, AS_PROGRAM, 8, excali64_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, excali64_state) AM_RANGE(0x0000, 0x1FFF) AM_READ_BANK("bankr1") AM_WRITE_BANK("bankw1") AM_RANGE(0x2000, 0x2FFF) AM_READ_BANK("bankr2") AM_WRITE_BANK("bankw2") AM_RANGE(0x3000, 0x3FFF) AM_READ_BANK("bankr3") AM_WRITE_BANK("bankw3") @@ -125,7 +125,7 @@ static ADDRESS_MAP_START(excali64_mem, AS_PROGRAM, 8, excali64_state) AM_RANGE(0xC000, 0xFFFF) AM_RAM AM_REGION("rambank", 0xC000) ADDRESS_MAP_END -static ADDRESS_MAP_START(excali64_io, AS_IO, 8, excali64_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, excali64_state) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x0f) AM_READ(port00_r) AM_RANGE(0x10, 0x10) AM_MIRROR(0x0e) AM_DEVREADWRITE("uart",i8251_device, data_r, data_w) @@ -240,9 +240,9 @@ static SLOT_INTERFACE_START( excali64_floppies ) SLOT_INTERFACE_END // pulses from port E4 bit 5 restart the 74123. After 3.6 secs without a pulse, the motor gets turned off. -WRITE8_MEMBER( excali64_state::motor_w ) +WRITE_LINE_MEMBER( excali64_state::motor_w ) { - m_motor = BIT(data, 0); + m_motor = state; m_floppy1->get_device()->mon_w(!m_motor); m_floppy0->get_device()->mon_w(!m_motor); } @@ -265,7 +265,7 @@ WRITE8_MEMBER( excali64_state::porte4_w ) if (floppy) floppy->ss_w(BIT(data, 4)); - m_u12->b_w(space,offset, BIT(data, 5)); // motor pulse + m_u12->b_w(BIT(data, 5)); // motor pulse } /* @@ -546,8 +546,8 @@ MC6845_UPDATE_ROW( excali64_state::update_row ) static MACHINE_CONFIG_START( excali64 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, XTAL_16MHz / 4) - MCFG_CPU_PROGRAM_MAP(excali64_mem) - MCFG_CPU_IO_MAP(excali64_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_MACHINE_RESET_OVERRIDE(excali64_state, excali64) @@ -616,7 +616,7 @@ static MACHINE_CONFIG_START( excali64 ) MCFG_TTL74123_A_PIN_VALUE(0) /* A pin - grounded */ MCFG_TTL74123_B_PIN_VALUE(1) /* B pin - driven by port e4 bit 5 */ MCFG_TTL74123_CLEAR_PIN_VALUE(1) /* Clear pin - pulled high */ - MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITE8(excali64_state, motor_w)) + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(excali64_state, motor_w)) MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(excali64_state, cent_busy_w)) diff --git a/src/mame/drivers/exelv.cpp b/src/mame/drivers/exelv.cpp index c93e804d625..46ea2c588aa 100644 --- a/src/mame/drivers/exelv.cpp +++ b/src/mame/drivers/exelv.cpp @@ -420,18 +420,6 @@ static ADDRESS_MAP_START(tms7020_mem, AS_PROGRAM, 8, exelv_state) AM_RANGE(0xc800, 0xf7ff) AM_NOP ADDRESS_MAP_END -static ADDRESS_MAP_START(tms7020_port, AS_IO, 8, exelv_state) - AM_RANGE(TMS7000_PORTA, TMS7000_PORTA) AM_READ(tms7020_porta_r) - AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_WRITE(tms7020_portb_w) -ADDRESS_MAP_END - -static ADDRESS_MAP_START(tms7041_port, AS_IO, 8, exelv_state) - AM_RANGE(TMS7000_PORTA, TMS7000_PORTA) AM_READ(tms7041_porta_r) - AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_WRITE(tms7041_portb_w) - AM_RANGE(TMS7000_PORTC, TMS7000_PORTC) AM_READWRITE(tms7041_portc_r, tms7041_portc_w) - AM_RANGE(TMS7000_PORTD, TMS7000_PORTD) AM_READWRITE(tms7041_portd_r, tms7041_portd_w) -ADDRESS_MAP_END - static ADDRESS_MAP_START(tms7040_mem, AS_PROGRAM, 8, exelv_state) AM_RANGE(0x0080, 0x00ff) AM_NOP @@ -490,12 +478,19 @@ static MACHINE_CONFIG_START( exl100 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", TMS7020_EXL, XTAL_4_9152MHz) MCFG_CPU_PROGRAM_MAP(tms7020_mem) - MCFG_CPU_IO_MAP(tms7020_port) + MCFG_TMS7000_IN_PORTA_CB(READ8(exelv_state, tms7020_porta_r)) + MCFG_TMS7000_OUT_PORTB_CB(WRITE8(exelv_state, tms7020_portb_w)) + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", exelv_state, exelv_hblank_interrupt, "screen", 0, 1) MCFG_MACHINE_START_OVERRIDE(exelv_state, exl100) MCFG_CPU_ADD("tms7041", TMS7041, XTAL_4_9152MHz) - MCFG_CPU_IO_MAP(tms7041_port) + MCFG_TMS7000_IN_PORTA_CB(READ8(exelv_state, tms7041_porta_r)) + MCFG_TMS7000_OUT_PORTB_CB(WRITE8(exelv_state, tms7041_portb_w)) + MCFG_TMS7000_IN_PORTC_CB(READ8(exelv_state, tms7041_portc_r)) + MCFG_TMS7000_OUT_PORTC_CB(WRITE8(exelv_state, tms7041_portc_w)) + MCFG_TMS7000_IN_PORTD_CB(READ8(exelv_state, tms7041_portd_r)) + MCFG_TMS7000_OUT_PORTD_CB(WRITE8(exelv_state, tms7041_portd_w)) MCFG_QUANTUM_PERFECT_CPU("maincpu") @@ -539,12 +534,19 @@ static MACHINE_CONFIG_START( exeltel ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", TMS7040, XTAL_4_9152MHz) MCFG_CPU_PROGRAM_MAP(tms7040_mem) - MCFG_CPU_IO_MAP(tms7020_port) + MCFG_TMS7000_IN_PORTA_CB(READ8(exelv_state, tms7020_porta_r)) + MCFG_TMS7000_OUT_PORTB_CB(WRITE8(exelv_state, tms7020_portb_w)) + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", exelv_state, exelv_hblank_interrupt, "screen", 0, 1) MCFG_MACHINE_START_OVERRIDE(exelv_state, exeltel) MCFG_CPU_ADD("tms7042", TMS7042, XTAL_4_9152MHz) - MCFG_CPU_IO_MAP(tms7041_port) + MCFG_TMS7000_IN_PORTA_CB(READ8(exelv_state, tms7041_porta_r)) + MCFG_TMS7000_OUT_PORTB_CB(WRITE8(exelv_state, tms7041_portb_w)) + MCFG_TMS7000_IN_PORTC_CB(READ8(exelv_state, tms7041_portc_r)) + MCFG_TMS7000_OUT_PORTC_CB(WRITE8(exelv_state, tms7041_portc_w)) + MCFG_TMS7000_IN_PORTD_CB(READ8(exelv_state, tms7041_portd_r)) + MCFG_TMS7000_OUT_PORTD_CB(WRITE8(exelv_state, tms7041_portd_w)) MCFG_QUANTUM_PERFECT_CPU("maincpu") diff --git a/src/mame/drivers/exterm.cpp b/src/mame/drivers/exterm.cpp index b2e54ffc8af..d99cc694f23 100644 --- a/src/mame/drivers/exterm.cpp +++ b/src/mame/drivers/exterm.cpp @@ -93,13 +93,13 @@ void exterm_state::machine_start() WRITE16_MEMBER(exterm_state::exterm_host_data_w) { - m_slave->host_w(space,offset / TOWORD(0x00100000), data, 0xffff); + m_slave->host_w(space,offset / 0x0010000, data, 0xffff); } READ16_MEMBER(exterm_state::exterm_host_data_r) { - return m_slave->host_r(space,offset / TOWORD(0x00100000), 0xffff); + return m_slave->host_r(space,offset / 0x0010000, 0xffff); } diff --git a/src/mame/drivers/f1gp.cpp b/src/mame/drivers/f1gp.cpp index e4174b238dd..a2f11028f8f 100644 --- a/src/mame/drivers/f1gp.cpp +++ b/src/mame/drivers/f1gp.cpp @@ -104,8 +104,7 @@ static ADDRESS_MAP_START( f1gp_cpu2_map, AS_PROGRAM, 16, f1gp_state ) AM_RANGE(0x000000, 0x01ffff) AM_ROM AM_RANGE(0xff8000, 0xffbfff) AM_RAM AM_RANGE(0xffc000, 0xffcfff) AM_RAM AM_SHARE("sharedram") - AM_RANGE(0xfff030, 0xfff031) AM_DEVREADWRITE8("acia", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0xfff032, 0xfff033) AM_DEVREADWRITE8("acia", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0xfff030, 0xfff033) AM_DEVREADWRITE8("acia", acia6850_device, read, write, 0x00ff) ADDRESS_MAP_END static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, f1gp_state ) @@ -183,8 +182,7 @@ static ADDRESS_MAP_START( f1gpb_cpu2_map, AS_PROGRAM, 16, f1gp_state ) AM_RANGE(0x000000, 0x01ffff) AM_ROM AM_RANGE(0xff8000, 0xffbfff) AM_RAM AM_RANGE(0xffc000, 0xffcfff) AM_RAM AM_SHARE("sharedram") - AM_RANGE(0xfff030, 0xfff031) AM_DEVREADWRITE8("acia", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0xfff032, 0xfff033) AM_DEVREADWRITE8("acia", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0xfff030, 0xfff033) AM_DEVREADWRITE8("acia", acia6850_device, read, write, 0x00ff) ADDRESS_MAP_END static INPUT_PORTS_START( f1gp ) diff --git a/src/mame/drivers/fccpu30.cpp b/src/mame/drivers/fccpu30.cpp index 9ebc11d44f1..bbcf9280765 100644 --- a/src/mame/drivers/fccpu30.cpp +++ b/src/mame/drivers/fccpu30.cpp @@ -416,7 +416,7 @@ WRITE32_MEMBER (cpu30_state::bootvect_w){ LOG("%s\n", FUNCNAME); m_sysram[offset % sizeof(m_sysram)] &= ~mem_mask; m_sysram[offset % sizeof(m_sysram)] |= (data & mem_mask); - m_sysrom = &m_sysram[0]; // redirect all upcomming accesses to masking RAM until reset. + m_sysrom = &m_sysram[0]; // redirect all upcoming accesses to masking RAM until reset. } /* diff --git a/src/mame/drivers/fidel6502.cpp b/src/mame/drivers/fidel6502.cpp index 1c1dd67351a..46c144b0db0 100644 --- a/src/mame/drivers/fidel6502.cpp +++ b/src/mame/drivers/fidel6502.cpp @@ -1708,8 +1708,8 @@ static MACHINE_CONFIG_START( sc12 ) MCFG_DEVICE_ADD("sc12_map", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(sc12_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", fidelbase_state, display_decay_tick, attotime::from_msec(1)) MCFG_DEFAULT_LAYOUT(layout_fidel_sc12) diff --git a/src/mame/drivers/fidel68k.cpp b/src/mame/drivers/fidel68k.cpp index 8f563634155..d2c94518b55 100644 --- a/src/mame/drivers/fidel68k.cpp +++ b/src/mame/drivers/fidel68k.cpp @@ -1,6 +1,6 @@ // license:BSD-3-Clause // copyright-holders:hap -// thanks-to:Berger +// thanks-to:Berger,yoyo_chessboard /****************************************************************************** Fidelity Electronics 68000 based board driver @@ -12,7 +12,6 @@ TODO: - fex68km3 addressmap RAM mirror? PCB has 2*32K RAM, emulated has 16K+64K - - how does dual-CPU work? - USART is not emulated - V9(68030 @ 32MHz) is faster than V10(68040 @ 25MHz) but it should be the other way around, culprit is unemulated cache? @@ -37,6 +36,20 @@ I/O is via TTL, overall very similar to EAG. ****************************************************************************** +Designer Mach III Master 2265 (model 6113) +------------------------------------------ +80KB RAM(2*KM6264AL-10, 2*KM62256AP-10), 64KB ROM(2*WSI 27C256L-12) +MC68HC000P12F CPU, 16MHz XTAL +IRQ(IPL2) from 555 timer, 1.67ms low, 6us high +PCB label 510.1134A02 + +ROM address/data lines are scrambled, presumed for easy placement on PCB and not +for obfuscation. I/O is nearly the same as Designer Display on 6502 hardware. + + +****************************************************************************** + + Elite Avant Garde (EAG, model 6114) ----------------------------------- @@ -168,6 +181,7 @@ B0000x-xxxxxx: see V7, -800000 #include "speaker.h" // internal artwork +#include "fidel_desdis_68k.lh" // clickable #include "fidel_ex_68k.lh" // clickable #include "fidel_eag_68k.lh" // clickable @@ -188,6 +202,12 @@ public: // Excel 68000 DECLARE_WRITE8_MEMBER(fex68k_mux_w); + // Designer Master + DECLARE_WRITE8_MEMBER(fdes2265_control_w); + DECLARE_READ8_MEMBER(fdes2265_input_r); + DECLARE_WRITE8_MEMBER(fdes2265_lcd_w); + DECLARE_DRIVER_INIT(fdes2265); + // EAG(6114/6117) DECLARE_DRIVER_INIT(eag); void eag_prepare_display(); @@ -219,6 +239,76 @@ WRITE8_MEMBER(fidel68k_state::fex68k_mux_w) /****************************************************************************** + Designer Master +******************************************************************************/ + +WRITE8_MEMBER(fidel68k_state::fdes2265_control_w) +{ + u8 q3_old = m_led_select & 8; + + // a1-a3,d0: 74259 + u8 mask = 1 << offset; + m_led_select = (m_led_select & ~mask) | ((data & 1) ? mask : 0); + + // 74259 Q4-Q7: 7442 a0-a3 + // 7442 0-8: led data, input mux + u16 sel = 1 << (m_led_select >> 4 & 0xf) & 0x3ff; + m_inp_mux = sel & 0x1ff; + + // 7442 9: speaker out + m_dac->write(BIT(sel, 9)); + + // 74259 Q0,Q1: led select (active low) + display_matrix(9, 2, m_inp_mux, ~m_led_select & 3, false); + + // 74259 Q3: lcd common, update on rising edge + if (~q3_old & m_led_select & 8) + { + for (int i = 0; i < 4; i++) + m_display_state[i+2] = m_7seg_data >> (8*i) & 0xff; + } + + m_display_maxy += 4; + set_display_segmask(0x3c, 0x7f); + display_update(); +} + +READ8_MEMBER(fidel68k_state::fdes2265_input_r) +{ + // a1-a3,d7(d15): multiplexed inputs (active low) + return (read_inputs(9) >> offset & 1) ? 0 : 0x80; +} + +WRITE8_MEMBER(fidel68k_state::fdes2265_lcd_w) +{ + // a1-a3,d0-d3: 4*74259 to lcd digit segments + u32 mask = BITSWAP8(1 << offset,3,7,6,0,1,2,4,5); + for (int i = 0; i < 4; i++) + { + m_7seg_data = (m_7seg_data & ~mask) | ((data >> i & 1) ? mask : 0); + mask <<= 8; + } +} + +DRIVER_INIT_MEMBER(fidel68k_state, fdes2265) +{ + u16 *rom = (u16*)memregion("maincpu")->base(); + unsigned const len = memregion("maincpu")->bytes() / 2; + + // descramble data lines + for (int i = 0; i < len; i++) + rom[i] = BITSWAP16(rom[i], 15,14,8,13,9,12,10,11, 3,4,5,7,6,0,1,2); + + // descramble address lines + std::vector<u16> buf(len); + memcpy(&buf[0], rom, len*2); + for (int i = 0; i < len; i++) + rom[i] = buf[BITSWAP24(i, 23,22,21,20,19,18,17,16, 15,14,13,12,11,8,10,9, 7,6,5,4,3,2,1,0)]; +} + + + +/****************************************************************************** EAG ******************************************************************************/ @@ -298,6 +388,19 @@ static ADDRESS_MAP_START( fex68km3_map, AS_PROGRAM, 16, fidel68k_state ) ADDRESS_MAP_END +// Designer Master + +static ADDRESS_MAP_START( fdes2265_map, AS_PROGRAM, 16, fidel68k_state ) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x000000, 0x00ffff) AM_ROM + AM_RANGE(0x000000, 0x00000f) AM_WRITE8(fdes2265_lcd_w, 0x00ff) + AM_RANGE(0x044000, 0x047fff) AM_RAM + AM_RANGE(0x100000, 0x10ffff) AM_RAM + AM_RANGE(0x140000, 0x14000f) AM_READ8(fdes2265_input_r, 0xff00) + AM_RANGE(0x140000, 0x14000f) AM_WRITE8(fdes2265_control_w, 0x00ff) +ADDRESS_MAP_END + + // EAG DRIVER_INIT_MEMBER(fidel68k_state, eag) @@ -366,6 +469,21 @@ static INPUT_PORTS_START( fex68k ) INPUT_PORTS_END +static INPUT_PORTS_START( fdes ) + PORT_INCLUDE( fidel_cb_buttons ) + + PORT_START("IN.8") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Clear") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("Move / Alternate") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_G) PORT_NAME("Hint / Info") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_F) PORT_NAME("Take Back / Replay") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_C) PORT_NAME("Level / New") + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_B) PORT_NAME("Option / Time") + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("Verify / Problem") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("Shift") +INPUT_PORTS_END + + static INPUT_PORTS_START( eag ) PORT_INCLUDE( fidel_cb_magnets ) @@ -429,6 +547,25 @@ static MACHINE_CONFIG_DERIVED( fex68km3, fex68k ) MCFG_CPU_PROGRAM_MAP(fex68km3_map) MACHINE_CONFIG_END +static MACHINE_CONFIG_START( fdes2265 ) + + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", M68000, XTAL_16MHz) // MC68HC000P12F + MCFG_CPU_PROGRAM_MAP(fdes2265_map) + MCFG_TIMER_DRIVER_ADD_PERIODIC("irq_on", fidel68k_state, irq_on, attotime::from_hz(597)) // from 555 timer, measured + MCFG_TIMER_START_DELAY(attotime::from_hz(597) - attotime::from_nsec(6000)) // active for 6us + MCFG_TIMER_DRIVER_ADD_PERIODIC("irq_off", fidel68k_state, irq_off, attotime::from_hz(597)) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", fidelbase_state, display_decay_tick, attotime::from_msec(1)) + MCFG_DEFAULT_LAYOUT(layout_fidel_desdis_68k) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("speaker") + MCFG_SOUND_ADD("dac", DAC_1BIT, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.25) + MCFG_DEVICE_ADD("vref", VOLTAGE_REGULATOR, 0) MCFG_VOLTAGE_REGULATOR_OUTPUT(5.0) + MCFG_SOUND_ROUTE_EX(0, "dac", 1.0, DAC_VREF_POS_INPUT) +MACHINE_CONFIG_END + static MACHINE_CONFIG_START( eag ) /* basic machine hardware */ @@ -519,6 +656,13 @@ ROM_START( fex68km3 ) // model 6098, PCB label 510.1120B01 ROM_END +ROM_START( fdes2265 ) // model 6113, PCB label 510.1134A02 + ROM_REGION16_BE( 0x10000, "maincpu", 0 ) + ROM_LOAD16_BYTE("13e_red.ic11", 0x00000, 0x08000, CRC(15a35628) SHA1(8213862e129951c6943a80f73cd0b63a31bb1357) ) // 27c256 + ROM_LOAD16_BYTE("13o_blue.ic10", 0x00001, 0x08000, CRC(81ce7ab2) SHA1(f01a70bcf2fbfe66c7a77d3c4437d897e5cc682d) ) // " +ROM_END + + ROM_START( feagv2 ) // from a V2 board ROM_REGION16_BE( 0x20000, "maincpu", 0 ) ROM_LOAD16_BYTE("6114_e5_yellow.u22", 0x00000, 0x10000, CRC(f9c7bada) SHA1(60e545f829121b9a4f1100d9e85ac83797715e80) ) // 27c512 @@ -571,15 +715,17 @@ ROM_END Drivers ******************************************************************************/ -// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS -CONS( 1987, fex68k, 0, 0, fex68k, fex68k, fidel68k_state, 0, "Fidelity Electronics", "Excel 68000", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) -CONS( 1988, fex68km2, fex68k, 0, fex68km2, fex68k, fidel68k_state, 0, "Fidelity Electronics", "Excel 68000 Mach II (rev. C+)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) -CONS( 1988, fex68km3, fex68k, 0, fex68km3, fex68k, fidel68k_state, 0, "Fidelity Electronics", "Excel 68000 Mach III", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) - -CONS( 1989, feagv2, 0, 0, eag, eag, fidel68k_state, eag, "Fidelity Electronics", "Elite Avant Garde (model 6114-2/3/4, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) -CONS( 1989, feagv2a, feagv2, 0, eag, eag, fidel68k_state, eag, "Fidelity Electronics", "Elite Avant Garde (model 6114-2/3/4, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) -CONS( 1990, feagv7, feagv2, 0, eagv7, eag, fidel68k_state, 0, "Fidelity Electronics", "Elite Avant Garde (model 6117-7, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) -CONS( 1990, feagv7a, feagv2, 0, eagv7, eag, fidel68k_state, 0, "Fidelity Electronics", "Elite Avant Garde (model 6117-7, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) -CONS( 1990, feagv9, feagv2, 0, eagv9, eag, fidel68k_state, 0, "Fidelity Electronics", "Elite Avant Garde (model 6117-9)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) -CONS( 1990, feagv10, feagv2, 0, eagv10, eag, fidel68k_state, 0, "Fidelity Electronics", "Elite Avant Garde (model 6117-10)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS | MACHINE_IMPERFECT_TIMING ) -CONS( 2002, feagv11, feagv2, 0, eagv11, eag, fidel68k_state, 0, "hack (Wilfried Bucke)", "Elite Avant Garde (model 6117-11)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS | MACHINE_IMPERFECT_TIMING ) +// YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS +CONS( 1987, fex68k, 0, 0, fex68k, fex68k, fidel68k_state, 0, "Fidelity Electronics", "Excel 68000", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) +CONS( 1988, fex68km2, fex68k, 0, fex68km2, fex68k, fidel68k_state, 0, "Fidelity Electronics", "Excel 68000 Mach II (rev. C+)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) +CONS( 1988, fex68km3, fex68k, 0, fex68km3, fex68k, fidel68k_state, 0, "Fidelity Electronics", "Excel 68000 Mach III", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) + +CONS( 1989, fdes2265, 0, 0, fdes2265, fdes, fidel68k_state, fdes2265, "Fidelity Electronics", "Designer Mach III Master 2265", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) + +CONS( 1989, feagv2, 0, 0, eag, eag, fidel68k_state, eag, "Fidelity Electronics", "Elite Avant Garde (model 6114-2/3/4, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) +CONS( 1989, feagv2a, feagv2, 0, eag, eag, fidel68k_state, eag, "Fidelity Electronics", "Elite Avant Garde (model 6114-2/3/4, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) +CONS( 1990, feagv7, feagv2, 0, eagv7, eag, fidel68k_state, 0, "Fidelity Electronics", "Elite Avant Garde (model 6117-7, set 1)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) +CONS( 1990, feagv7a, feagv2, 0, eagv7, eag, fidel68k_state, 0, "Fidelity Electronics", "Elite Avant Garde (model 6117-7, set 2)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) +CONS( 1990, feagv9, feagv2, 0, eagv9, eag, fidel68k_state, 0, "Fidelity Electronics", "Elite Avant Garde (model 6117-9)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS ) +CONS( 1990, feagv10, feagv2, 0, eagv10, eag, fidel68k_state, 0, "Fidelity Electronics", "Elite Avant Garde (model 6117-10)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS | MACHINE_IMPERFECT_TIMING ) +CONS( 2002, feagv11, feagv2, 0, eagv11, eag, fidel68k_state, 0, "hack (Wilfried Bucke)", "Elite Avant Garde (model 6117-11)", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK | MACHINE_IMPERFECT_CONTROLS | MACHINE_IMPERFECT_TIMING ) diff --git a/src/mame/drivers/firetrap.cpp b/src/mame/drivers/firetrap.cpp index e4063e437cf..50ed76237e6 100644 --- a/src/mame/drivers/firetrap.cpp +++ b/src/mame/drivers/firetrap.cpp @@ -347,8 +347,7 @@ WRITE8_MEMBER(firetrap_state::flip_screen_w) flip_screen_set(data); } - -static ADDRESS_MAP_START( firetrap_map, AS_PROGRAM, 8, firetrap_state ) +static ADDRESS_MAP_START( firetrap_base_map, AS_PROGRAM, 8, firetrap_state ) AM_RANGE(0x0000, 0x7fff) AM_ROM AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank1") AM_RANGE(0xc000, 0xcfff) AM_RAM @@ -371,32 +370,15 @@ static ADDRESS_MAP_START( firetrap_map, AS_PROGRAM, 8, firetrap_state ) AM_RANGE(0xf012, 0xf012) AM_READ_PORT("IN2") AM_RANGE(0xf013, 0xf013) AM_READ_PORT("DSW0") AM_RANGE(0xf014, 0xf014) AM_READ_PORT("DSW1") +ADDRESS_MAP_END + +static ADDRESS_MAP_START( firetrap_map, AS_PROGRAM, 8, firetrap_state ) + AM_IMPORT_FROM( firetrap_base_map ) AM_RANGE(0xf016, 0xf016) AM_READ(firetrap_8751_r) ADDRESS_MAP_END static ADDRESS_MAP_START( firetrap_bootleg_map, AS_PROGRAM, 8, firetrap_state ) - AM_RANGE(0x0000, 0x7fff) AM_ROM - AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("bank1") - AM_RANGE(0xc000, 0xcfff) AM_RAM - AM_RANGE(0xd000, 0xd7ff) AM_RAM_WRITE(firetrap_bg1videoram_w) AM_SHARE("bg1videoram") - AM_RANGE(0xd800, 0xdfff) AM_RAM_WRITE(firetrap_bg2videoram_w) AM_SHARE("bg2videoram") - AM_RANGE(0xe000, 0xe7ff) AM_RAM_WRITE(firetrap_fgvideoram_w) AM_SHARE("fgvideoram") - AM_RANGE(0xe800, 0xe97f) AM_RAM AM_SHARE("spriteram") - AM_RANGE(0xf000, 0xf000) AM_WRITENOP /* IRQ acknowledge */ - AM_RANGE(0xf001, 0xf001) AM_DEVWRITE("soundlatch", generic_latch_8_device, write) - AM_RANGE(0xf002, 0xf002) AM_WRITE(firetrap_bankselect_w) - AM_RANGE(0xf003, 0xf003) AM_WRITE(flip_screen_w) - AM_RANGE(0xf004, 0xf004) AM_WRITE(firetrap_nmi_disable_w) - AM_RANGE(0xf005, 0xf005) AM_WRITENOP - AM_RANGE(0xf008, 0xf009) AM_WRITE(firetrap_bg1_scrollx_w) - AM_RANGE(0xf00a, 0xf00b) AM_WRITE(firetrap_bg1_scrolly_w) - AM_RANGE(0xf00c, 0xf00d) AM_WRITE(firetrap_bg2_scrollx_w) - AM_RANGE(0xf00e, 0xf00f) AM_WRITE(firetrap_bg2_scrolly_w) - AM_RANGE(0xf010, 0xf010) AM_READ_PORT("IN0") - AM_RANGE(0xf011, 0xf011) AM_READ_PORT("IN1") - AM_RANGE(0xf012, 0xf012) AM_READ_PORT("IN2") - AM_RANGE(0xf013, 0xf013) AM_READ_PORT("DSW0") - AM_RANGE(0xf014, 0xf014) AM_READ_PORT("DSW1") + AM_IMPORT_FROM( firetrap_base_map ) AM_RANGE(0xf016, 0xf016) AM_READ(firetrap_8751_bootleg_r) AM_RANGE(0xf800, 0xf8ff) AM_ROM /* extra ROM in the bootleg with unprotection code */ ADDRESS_MAP_END @@ -646,10 +628,12 @@ static MACHINE_CONFIG_START( firetrap ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(57.4034) // PCB measurement - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) - MCFG_SCREEN_SIZE(32*8, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) +// MCFG_SCREEN_REFRESH_RATE(57.4034) // PCB measurement +// MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) +// MCFG_SCREEN_SIZE(32*8, 32*8) +// MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) + // DECO video CRTC, unverified + MCFG_SCREEN_RAW_PARAMS(FIRETRAP_XTAL/2,384,0,256,272,8,248) MCFG_SCREEN_UPDATE_DRIVER(firetrap_state, screen_update_firetrap) MCFG_SCREEN_PALETTE("palette") @@ -689,10 +673,12 @@ static MACHINE_CONFIG_START( firetrapbl ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(57.4034) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) - MCFG_SCREEN_SIZE(32*8, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) +// MCFG_SCREEN_REFRESH_RATE(57.4034) +// MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) +// MCFG_SCREEN_SIZE(32*8, 32*8) +// MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) + // DECO video CRTC, unverified + MCFG_SCREEN_RAW_PARAMS(FIRETRAP_XTAL/2,384,0,256,272,8,248) MCFG_SCREEN_UPDATE_DRIVER(firetrap_state, screen_update_firetrap) MCFG_SCREEN_PALETTE("palette") diff --git a/src/mame/drivers/firetrk.cpp b/src/mame/drivers/firetrk.cpp index 52936390711..1d8828cf533 100644 --- a/src/mame/drivers/firetrk.cpp +++ b/src/mame/drivers/firetrk.cpp @@ -2,7 +2,7 @@ // copyright-holders:Phil Stroffolino /*************************************************************************** -Atari Fire Truck + Super Bug + Monte Carlo driver + Atari Fire Truck + Super Bug + Monte Carlo driver ***************************************************************************/ @@ -17,7 +17,6 @@ Atari Fire Truck + Super Bug + Monte Carlo driver #define MASTER_CLOCK (XTAL_12_096MHz) - void firetrk_state::set_service_mode(int enable) { m_in_service_mode = enable; @@ -58,7 +57,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(firetrk_state::firetrk_scanline) // periodic IRQs are generated by inverse 16V signal if ((scanline & 0x1f) == 0) - generic_pulse_irq_line(*m_maincpu, 0, 1); + m_maincpu->pulse_input_line(0, attotime::from_hz(MASTER_CLOCK/2/64)); // vblank interrupt // NMIs are disabled during service mode @@ -226,10 +225,8 @@ CUSTOM_INPUT_MEMBER(firetrk_state::gear_r) READ8_MEMBER(firetrk_state::firetrk_input_r) { - int i; - /* update steering wheels */ - for (i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { uint32_t const new_dial = m_steer[i].read_safe(0); int32_t const delta = new_dial - m_dial[i]; @@ -416,20 +413,18 @@ static INPUT_PORTS_START( firetrk ) PORT_START("BIT_0") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Gas") PORT_PLAYER(1) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,steer_dir_r, (void *)0) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,steer_dir_r, (void *)1) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, steer_dir_r, (void *)0) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, steer_dir_r, (void *)1) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Bell") PORT_PLAYER(2) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_TILT ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,skid_r, (void *)2) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Service_Mode ) ) PORT_CODE(KEYCODE_F2) PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,service_mode_switch_changed, 0) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x80, DEF_STR( On ) ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, skid_r, (void *)2) + PORT_SERVICE( 0x80, IP_ACTIVE_HIGH ) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, service_mode_switch_changed, 0) PORT_START("BIT_6") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("Front Player Start") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) PORT_NAME("Back Player Start") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START3 ) PORT_NAME("Both Players Start") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Track Select") PORT_CODE(KEYCODE_SPACE) PORT_PLAYER(1) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Track Select") PORT_PLAYER(1) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen") PORT_DIPNAME( 0x40, 0x40, DEF_STR( Cabinet )) @@ -440,15 +435,15 @@ static INPUT_PORTS_START( firetrk ) PORT_START("BIT_7") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,steer_flag_r, (void *)0) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,steer_flag_r, (void *)1) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, steer_flag_r, (void *)0) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, steer_flag_r, (void *)1) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_COIN2 ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,crash_r, (void *)2) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, crash_r, (void *)2) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME("Diag Step") PORT_START("HORN") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Horn") PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,firetrk_horn_changed, 0) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Horn") PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, firetrk_horn_changed, 0) PORT_START("R27") PORT_ADJUSTER( 20, "R27 - Motor Frequency" ) @@ -460,8 +455,8 @@ static INPUT_PORTS_START( superbug ) PORT_BIT( 0xff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_START("DIP_0") - PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) /* other DIPs connect here */ - PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) /* other DIPs connect here */ + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED ) /* other DIPs connect here */ + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED ) /* other DIPs connect here */ PORT_START("DIP_1") PORT_DIPNAME( 0x03, 0x02, DEF_STR( Coinage )) @@ -486,30 +481,30 @@ static INPUT_PORTS_START( superbug ) PORT_DIPSETTING( 0xc0, DEF_STR( German ) ) PORT_START("BIT_0") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,gear_r, (void *)1) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, gear_r, (void *)1) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Gas") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,steer_dir_r, (void *)0) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Hiscore Reset") PORT_CODE(KEYCODE_H) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, steer_dir_r, (void *)0) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_MEMORY_RESET ) PORT_NAME("Hiscore Reset") PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_SERVICE( 0x20, IP_ACTIVE_HIGH ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,skid_r, (void *)0) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, skid_r, (void *)0) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_TILT ) PORT_START("BIT_7") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,gear_r, (void *)2) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,gear_r, (void *)0) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,steer_flag_r, (void *)0) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, gear_r, (void *)2) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, gear_r, (void *)0) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, steer_flag_r, (void *)0) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START1 ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,crash_r, (void *)0) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Track Select") PORT_CODE(KEYCODE_SPACE) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, crash_r, (void *)0) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Track Select") PORT_START("GEAR") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Gear 1") PORT_CODE(KEYCODE_Z) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,gear_changed, (void *)0) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Gear 2") PORT_CODE(KEYCODE_X) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,gear_changed, (void *)1) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Gear 3") PORT_CODE(KEYCODE_C) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,gear_changed, (void *)2) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Gear 4") PORT_CODE(KEYCODE_V) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,gear_changed, (void *)3) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Gear 1") PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, gear_changed, (void *)0) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Gear 2") PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, gear_changed, (void *)1) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Gear 3") PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, gear_changed, (void *)2) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Gear 4") PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, gear_changed, (void *)3) PORT_START("R62") PORT_ADJUSTER( 20, "R62 - Motor Frequency" ) @@ -558,30 +553,30 @@ static INPUT_PORTS_START( montecar ) PORT_DIPSETTING( 0x00, DEF_STR( German ) ) PORT_START("BIT_6") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,gear_r, (void *)0) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,gear_r, (void *)1) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,gear_r, (void *)2) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Track Select") PORT_CODE(KEYCODE_SPACE) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, gear_r, (void *)0) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, gear_r, (void *)1) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, gear_r, (void *)2) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Track Select") PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Gas") PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,steer_dir_r, (void *)0) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,skid_r, (void *)1) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, steer_dir_r, (void *)0) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, skid_r, (void *)1) PORT_START("BIT_7") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_TILT ) - PORT_SERVICE( 0x04, IP_ACTIVE_HIGH ) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,service_mode_switch_changed, 0) + PORT_SERVICE( 0x04, IP_ACTIVE_HIGH ) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, service_mode_switch_changed, 0) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SPECIAL ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,steer_flag_r, (void *)0) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state,skid_r, (void *)0) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, steer_flag_r, (void *)0) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, firetrk_state, skid_r, (void *)0) PORT_START("GEAR") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Gear 1") PORT_CODE(KEYCODE_Z) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,gear_changed, (void *)0) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Gear 2") PORT_CODE(KEYCODE_X) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,gear_changed, (void *)1) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Gear 3") PORT_CODE(KEYCODE_C) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,gear_changed, (void *)2) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Gear 4") PORT_CODE(KEYCODE_V) PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state,gear_changed, (void *)3) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Gear 1") PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, gear_changed, (void *)0) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Gear 2") PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, gear_changed, (void *)1) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Gear 3") PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, gear_changed, (void *)2) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Gear 4") PORT_CHANGED_MEMBER(DEVICE_SELF, firetrk_state, gear_changed, (void *)3) PORT_START("R89") PORT_ADJUSTER( 20, "R89 - Motor Frequency" ) @@ -868,9 +863,7 @@ static MACHINE_CONFIG_START( firetrk ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_ALWAYS_UPDATE) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_SIZE(320, 262) - MCFG_SCREEN_VISIBLE_AREA(0, 319, 0, 239) + MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK/2, 384, 0, 320, 262, 0, 240) MCFG_SCREEN_UPDATE_DRIVER(firetrk_state, screen_update_firetrk) MCFG_SCREEN_PALETTE("palette") diff --git a/src/mame/drivers/fitfight.cpp b/src/mame/drivers/fitfight.cpp index 7eb816fdd4c..d1ee97d6419 100644 --- a/src/mame/drivers/fitfight.cpp +++ b/src/mame/drivers/fitfight.cpp @@ -258,7 +258,7 @@ WRITE8_MEMBER(fitfight_state::snd_portc_w) INTERRUPT_GEN_MEMBER(fitfight_state::snd_irq) { - generic_pulse_irq_line(device.execute(), UPD7810_INTF2, 1); + device.execute().pulse_input_line(UPD7810_INTF2, device.execute().minimum_quantum_time()); } diff --git a/src/mame/drivers/flower.cpp b/src/mame/drivers/flower.cpp index 17a40c7eb5d..ec690358c79 100644 --- a/src/mame/drivers/flower.cpp +++ b/src/mame/drivers/flower.cpp @@ -2,16 +2,15 @@ // copyright-holders:Angelo Salese /****************************************************************************** - Flower (c) 1986 Clarue + Flower (c) 1986 Clarue (licensed to Komax/Sega) driver by Angelo Salese, original "wiped off due of not anymore licenseable" driver by insideoutboy. TODO: - - sprite zooming; - - some video glitches; - - $a000 outputs; - - sound, third z80 not hooked up; + - priority might be wrong in some places (title screen stars around the + galaxy, planet ship 3rd boss, 2nd boss); + - sound chips (similar to Namco custom chips?) =============================================================================== @@ -23,12 +22,6 @@ There is a PCB picture that shows two stickers, the first says serial number tag also showing "Clarue". GFX ROM contents also show (C) 1986 CLARUE. A Wood Place Inc. spinoff perhaps? - -todo: - -fix sound and timing - - FLOWER CHIP PLACEMENT XTAL: 18.4320 MHz @@ -87,14 +80,22 @@ CHIP # POSITION TYPE #include "emu.h" #include "cpu/z80/z80.h" +#include "machine/gen_latch.h" +#include "audio/flower.h" #include "screen.h" +#include "speaker.h" + +#define MASTER_CLOCK XTAL_18_432MHz class flower_state : public driver_device { public: flower_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), + m_mastercpu(*this, "mastercpu"), + m_slavecpu(*this, "slavecpu"), + m_audiocpu(*this, "audiocpu"), + m_screen(*this, "screen"), m_palette(*this, "palette"), m_gfxdecode(*this, "gfxdecode"), m_txvram(*this, "txvram"), @@ -102,10 +103,35 @@ public: m_fgvram(*this, "fgvram"), m_workram(*this, "workram"), m_bgscroll(*this, "bgscroll"), - m_fgscroll(*this, "fgscroll") + m_fgscroll(*this, "fgscroll"), + m_soundlatch(*this, "soundlatch") { } - required_device<cpu_device> m_maincpu; + DECLARE_WRITE8_MEMBER(flipscreen_w); + DECLARE_WRITE8_MEMBER(coin_counter_w); + DECLARE_WRITE8_MEMBER(sound_command_w); + DECLARE_WRITE8_MEMBER(audio_nmi_mask_w); + DECLARE_WRITE8_MEMBER(bgvram_w); + DECLARE_WRITE8_MEMBER(fgvram_w); + DECLARE_INPUT_CHANGED_MEMBER(coin_inserted); + INTERRUPT_GEN_MEMBER(master_vblank_irq); + INTERRUPT_GEN_MEMBER(slave_vblank_irq); + TILE_GET_INFO_MEMBER(get_bg_tile_info); + TILE_GET_INFO_MEMBER(get_fg_tile_info); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + +protected: + // driver_device overrides + virtual void machine_start() override; + virtual void machine_reset() override; + + virtual void video_start() override; + +private: + required_device<cpu_device> m_mastercpu; + required_device<cpu_device> m_slavecpu; + required_device<cpu_device> m_audiocpu; + required_device<screen_device> m_screen; required_device<palette_device> m_palette; required_device<gfxdecode_device> m_gfxdecode; required_shared_ptr<uint8_t> m_txvram; @@ -114,18 +140,49 @@ public: required_shared_ptr<uint8_t> m_workram; required_shared_ptr<uint8_t> m_bgscroll; required_shared_ptr<uint8_t> m_fgscroll; + required_device<generic_latch_8_device> m_soundlatch; + bitmap_ind16 m_temp_bitmap; + void draw_legacy_text(bitmap_ind16 &bitmap,const rectangle &cliprect); + void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect); - DECLARE_INPUT_CHANGED_MEMBER(coin_inserted); - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void legacy_tx_draw(bitmap_ind16 &bitmap,const rectangle &cliprect); - void legacy_layers_draw(bitmap_ind16 &bitmap,const rectangle &cliprect); - void sprites_draw(bitmap_ind16 &bitmap,const rectangle &cliprect); + bool m_audio_nmi_enable; + bool m_flip_screen; + tilemap_t *m_bg_tilemap; + tilemap_t *m_fg_tilemap; }; +TILE_GET_INFO_MEMBER(flower_state::get_bg_tile_info) +{ + int code = m_bgvram[tile_index]; + int color = (m_bgvram[tile_index+0x100] & 0xf0) >> 4; + + SET_TILE_INFO_MEMBER(1, code, color, 0); +} + +TILE_GET_INFO_MEMBER(flower_state::get_fg_tile_info) +{ + int code = m_fgvram[tile_index]; + int color = (m_fgvram[tile_index+0x100] & 0xf0) >> 4; + + SET_TILE_INFO_MEMBER(1, code, color, 0); +} + +void flower_state::video_start() +{ + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(flower_state::get_bg_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 16, 16); + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(flower_state::get_fg_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 16, 16); + + m_screen->register_screen_bitmap(m_temp_bitmap); + m_fg_tilemap->set_transparent_pen(15); + save_item(NAME(m_flip_screen)); -void flower_state::legacy_tx_draw(bitmap_ind16 &bitmap,const rectangle &cliprect) + m_bg_tilemap->set_scrolldx(16, 0); + m_fg_tilemap->set_scrolldx(16, 0); +} + +void flower_state::draw_legacy_text(bitmap_ind16 &bitmap,const rectangle &cliprect) { gfx_element *gfx_0 = m_gfxdecode->gfx(0); int count; @@ -141,10 +198,10 @@ void flower_state::legacy_tx_draw(bitmap_ind16 &bitmap,const rectangle &cliprect if(attr & 0x03) // debug attr = machine().rand() & 0xfc; - gfx_0->transpen(bitmap,cliprect,tile,attr >> 2,0,0,x*8,y*8,3); + gfx_0->transpen(bitmap,cliprect,tile,attr >> 2,0,0,x*8+16,y*8,3); } - for (count=0;count<4*32;count++) + for (count=0;count<0x40;count++) { int x = count / 32; int y = count % 32; @@ -155,45 +212,7 @@ void flower_state::legacy_tx_draw(bitmap_ind16 &bitmap,const rectangle &cliprect if(attr & 0x03) // debug attr = machine().rand() & 0xfc; - gfx_0->transpen(bitmap,cliprect,tile,attr >> 2,0,0,x*8+256,y*8,3); - } - -} - -void flower_state::legacy_layers_draw(bitmap_ind16 &bitmap,const rectangle &cliprect) -{ - gfx_element *gfx_1 = m_gfxdecode->gfx(1); - int bg_ybase = m_bgscroll[0]; - int fg_ybase = m_fgscroll[0]; - int count; - - for (count=0;count<16*16;count++) - { - int x = count % 16; - int y = count / 16; - uint8_t tile, attr; - - tile = m_bgvram[count]; - attr = m_bgvram[count+0x100]; - if(attr & 0xf) // debug - attr = machine().rand() & 0xf0; - - gfx_1->opaque(bitmap,cliprect, tile, attr >> 4, 0, 0, x*16, (y*16 - bg_ybase) & 0xff); - } - - - for (count=0;count<16*16;count++) - { - int x = count % 16; - int y = count / 16; - uint8_t tile, attr; - - tile = m_fgvram[count]; - attr = m_fgvram[count+0x100]; - if(attr & 0xf) - attr = machine().rand() & 0xf0; - - gfx_1->transpen(bitmap,cliprect, tile, attr >> 4, 0, 0, x*16, (y*16 - fg_ybase) & 0xff, 15); + gfx_0->transpen(bitmap,cliprect,tile,attr >> 2,0,0,x*8+256+16,y*8,3); } } @@ -206,39 +225,58 @@ void flower_state::legacy_layers_draw(bitmap_ind16 &bitmap,const rectangle &clip [5] XXXX XXXX X offset MSB [6] cccc ---- color base */ -void flower_state::sprites_draw(bitmap_ind16 &bitmap,const rectangle &cliprect) +void flower_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect) { uint8_t *spr_ptr = &m_workram[0x1e08]; gfx_element *gfx_2 = m_gfxdecode->gfx(2); - for(int i=0;i<0x1fb;i+=8) + // traverse from top to bottom + for(int i=0x1f0;i>=0;i-=8) { uint8_t tile = (spr_ptr[i+1] & 0x3f); uint8_t color = spr_ptr[i+6] >> 4; - int x = (spr_ptr[i+4] | (spr_ptr[i+5]<<8))-55; + int x = (spr_ptr[i+4] | (spr_ptr[i+5]<<8))-39; int y = 241-spr_ptr[i+0]; uint8_t attr = spr_ptr[i+2]; uint8_t fy = spr_ptr[i+1] & 0x80; uint8_t fx = spr_ptr[i+1] & 0x40; uint8_t ysize = ((spr_ptr[i+3] & 0x80) >> 7) + 1; uint8_t xsize = ((spr_ptr[i+3] & 0x08) >> 3) + 1; + uint8_t ydiv = ysize == 2 ? 1 : 2; + uint8_t xdiv = xsize == 2 ? 1 : 2; + uint32_t yshrink_zoom = ((spr_ptr[i+3] & 0x70) >> 4) + 1; + uint32_t xshrink_zoom = ((spr_ptr[i+3] & 0x07) >> 0) + 1; + yshrink_zoom <<= 13; + xshrink_zoom <<= 13; + int ypixels = (yshrink_zoom*16) >> 16; + int xpixels = (xshrink_zoom*16) >> 16; + + tile |= (attr & 1) << 6; + tile |= (attr & 8) << 4; + + if(flip_screen()) + { + x += xsize*16; + x = 288-x; + y -= 2; + } if(ysize == 2) y-=16; - tile |= (attr & 1) << 6; - tile |= (attr & 8) << 4; - // TODO: zoom for(int yi=0;yi<ysize;yi++) { + int yoffs = (16-ypixels)/ydiv; + for(int xi=0;xi<xsize;xi++) { int tile_offs; + int xoffs = (16-xpixels)/xdiv; tile_offs = fx ? (xsize-xi-1) * 8 : xi*8; tile_offs+= fy ? (ysize-yi-1) : yi; - gfx_2->transpen(bitmap,cliprect, tile+tile_offs, color, fx, fy, x+xi*16, y+yi*16, 15); + gfx_2->zoom_transpen(bitmap,cliprect, tile+tile_offs, color, fx, fy, x+xi*xpixels+xoffs, y+yi*ypixels+yoffs, xshrink_zoom, yshrink_zoom, 15); } } } @@ -246,30 +284,88 @@ void flower_state::sprites_draw(bitmap_ind16 &bitmap,const rectangle &cliprect) uint32_t flower_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) { - legacy_layers_draw(bitmap,cliprect); - sprites_draw(bitmap,cliprect); - legacy_tx_draw(bitmap,cliprect); + m_bg_tilemap->set_scrolly(0, m_bgscroll[0]); + m_fg_tilemap->set_scrolly(0, m_fgscroll[0]); + + m_temp_bitmap.fill(0,cliprect); + m_bg_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0); + m_fg_tilemap->draw(screen, m_temp_bitmap, cliprect, 0, 0); + draw_sprites(m_temp_bitmap,cliprect); + draw_legacy_text(m_temp_bitmap,cliprect); + + copybitmap(bitmap,m_temp_bitmap,m_flip_screen,m_flip_screen,m_flip_screen == true ? -154 : 0, m_flip_screen == true ? -7 : 0, cliprect); return 0; } +WRITE8_MEMBER(flower_state::flipscreen_w) +{ + flip_screen_set(data & 1); + m_flip_screen = BIT(data,0); +} + +WRITE8_MEMBER(flower_state::coin_counter_w) +{ + machine().bookkeeping().coin_counter_w(0,data & 1); +} + +WRITE8_MEMBER(flower_state::sound_command_w) +{ + m_soundlatch->write(space, 0, data & 0xff); + if(m_audio_nmi_enable == true) + m_audiocpu->set_input_line(INPUT_LINE_NMI,PULSE_LINE); +} + +WRITE8_MEMBER(flower_state::audio_nmi_mask_w) +{ + m_audio_nmi_enable = BIT(data,0); +} + +WRITE8_MEMBER(flower_state::bgvram_w) +{ + m_bgvram[offset] = data; + m_bg_tilemap->mark_tile_dirty(offset & 0xff); +} + +WRITE8_MEMBER(flower_state::fgvram_w) +{ + m_fgvram[offset] = data; + m_fg_tilemap->mark_tile_dirty(offset & 0xff); +} + static ADDRESS_MAP_START( shared_map, AS_PROGRAM, 8, flower_state ) AM_RANGE(0x0000, 0x7fff) AM_ROM AM_RANGE(0xc000, 0xdfff) AM_RAM AM_SHARE("workram") AM_RANGE(0xa000, 0xa000) AM_WRITENOP + AM_RANGE(0xa001, 0xa001) AM_WRITE(flipscreen_w) + AM_RANGE(0xa002, 0xa002) AM_WRITENOP // master irq related (0 at start, 1 at end) + AM_RANGE(0xa003, 0xa003) AM_WRITENOP // slave irq related (0 at start, 1 at end) + AM_RANGE(0xa004, 0xa004) AM_WRITE(coin_counter_w) + AM_RANGE(0xa005, 0xa005) AM_WRITENOP AM_RANGE(0xa100, 0xa100) AM_READ_PORT("P1") AM_RANGE(0xa101, 0xa101) AM_READ_PORT("P2") AM_RANGE(0xa102, 0xa102) AM_READ_PORT("DSW1") AM_RANGE(0xa103, 0xa103) AM_READ_PORT("DSW2") + AM_RANGE(0xa400, 0xa400) AM_WRITE(sound_command_w) AM_RANGE(0xe000, 0xefff) AM_RAM AM_SHARE("txvram") - AM_RANGE(0xf000, 0xf1ff) AM_RAM AM_SHARE("bgvram") - AM_RANGE(0xf200, 0xf200) AM_RAM AM_SHARE("bgscroll") - AM_RANGE(0xf800, 0xf9ff) AM_RAM AM_SHARE("fgvram") - AM_RANGE(0xfa00, 0xfa00) AM_RAM AM_SHARE("fgscroll") + AM_RANGE(0xf000, 0xf1ff) AM_RAM_WRITE(fgvram_w) AM_SHARE("fgvram") + AM_RANGE(0xf200, 0xf200) AM_RAM AM_SHARE("fgscroll") + AM_RANGE(0xf800, 0xf9ff) AM_RAM_WRITE(bgvram_w) AM_SHARE("bgvram") + AM_RANGE(0xfa00, 0xfa00) AM_RAM AM_SHARE("bgscroll") +ADDRESS_MAP_END + +static ADDRESS_MAP_START( audio_map, AS_PROGRAM, 8, flower_state ) + AM_RANGE(0x0000, 0x3fff) AM_ROM + AM_RANGE(0x4000, 0x4000) AM_WRITENOP // audio irq related (0 at start, 1 at end) + AM_RANGE(0x4001, 0x4001) AM_WRITE(audio_nmi_mask_w) + AM_RANGE(0x6000, 0x6000) AM_DEVREAD("soundlatch", generic_latch_8_device, read) + AM_RANGE(0x8000, 0x803f) AM_DEVWRITE("flower", flower_sound_device, lower_write) + AM_RANGE(0xa000, 0xa03f) AM_DEVWRITE("flower", flower_sound_device, upper_write) + AM_RANGE(0xc000, 0xc7ff) AM_RAM ADDRESS_MAP_END INPUT_CHANGED_MEMBER(flower_state::coin_inserted) { - m_maincpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE); + m_mastercpu->set_input_line(INPUT_LINE_NMI, newval ? CLEAR_LINE : ASSERT_LINE); } static INPUT_PORTS_START( flower ) @@ -367,31 +463,66 @@ static GFXDECODE_START( flower ) GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 0, 16 ) GFXDECODE_END +void flower_state::machine_start() +{ + save_item(NAME(m_audio_nmi_enable)); +} + +void flower_state::machine_reset() +{ + m_audio_nmi_enable = false; +} + +INTERRUPT_GEN_MEMBER(flower_state::master_vblank_irq) +{ + //if(m_master_irq_enable == true) + device.execute().set_input_line(0, HOLD_LINE); +} + +INTERRUPT_GEN_MEMBER(flower_state::slave_vblank_irq) +{ + //if(m_slave_irq_enable == true) + device.execute().set_input_line(0, HOLD_LINE); +} + + static MACHINE_CONFIG_START( flower ) - MCFG_CPU_ADD("maincpu",Z80,4000000) + MCFG_CPU_ADD("mastercpu",Z80,MASTER_CLOCK/4) MCFG_CPU_PROGRAM_MAP(shared_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", flower_state, irq0_line_hold) + MCFG_CPU_VBLANK_INT_DRIVER("screen", flower_state, master_vblank_irq) - MCFG_CPU_ADD("subcpu",Z80,4000000) + MCFG_CPU_ADD("slavecpu",Z80,MASTER_CLOCK/4) MCFG_CPU_PROGRAM_MAP(shared_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", flower_state, irq0_line_hold) + MCFG_CPU_VBLANK_INT_DRIVER("screen", flower_state, slave_vblank_irq) + + MCFG_CPU_ADD("audiocpu",Z80,MASTER_CLOCK/4) + MCFG_CPU_PROGRAM_MAP(audio_map) + MCFG_CPU_PERIODIC_INT_DRIVER(flower_state, irq0_line_hold, 90) + + MCFG_QUANTUM_PERFECT_CPU("mastercpu") MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_UPDATE_DRIVER(flower_state, screen_update) - MCFG_SCREEN_RAW_PARAMS(XTAL_3_579545MHz*2, 442, 0, 272, 263, 16, 240) /* generic NTSC video timing at 256x224 */ + MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK/3,384,0,288,264,16,240) // derived from Galaxian HW, 60.606060 MCFG_SCREEN_PALETTE("palette") MCFG_GFXDECODE_ADD("gfxdecode", "palette", flower) MCFG_PALETTE_ADD_RRRRGGGGBBBB_PROMS("palette", "proms", 256) + MCFG_GENERIC_LATCH_8_ADD("soundlatch") + + MCFG_SPEAKER_STANDARD_MONO("mono") + + MCFG_SOUND_ADD("flower", FLOWER_CUSTOM, 96000) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) MACHINE_CONFIG_END ROM_START( flower ) /* Komax version */ - ROM_REGION( 0x10000, "maincpu", 0 ) /* main cpu */ + ROM_REGION( 0x10000, "mastercpu", 0 ) /* main cpu */ ROM_LOAD( "1.5j", 0x0000, 0x8000, CRC(a4c3af78) SHA1(d149b0e0d82318273dd9cc5a143b175cdc818d0d) ) - ROM_REGION( 0x10000, "subcpu", 0 ) /* sub cpu */ + ROM_REGION( 0x10000, "slavecpu", 0 ) /* sub cpu */ ROM_LOAD( "2.5f", 0x0000, 0x8000, CRC(7c7ee2d8) SHA1(1e67bfe0f3585be5a6e6719ccf9db764bafbcb01) ) ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */ @@ -412,10 +543,10 @@ ROM_START( flower ) /* Komax version */ ROM_LOAD( "12.16e", 0x4000, 0x2000, CRC(e3779f7f) SHA1(8e12d06b3cdc2fcb7b77cc35f8eca45544cc4873) ) ROM_LOAD( "11.14e", 0x6000, 0x2000, CRC(8801b34f) SHA1(256059fcd16b21e076db1c18fd9669128df1d658) ) - ROM_REGION( 0x8000, "sound1", 0 ) + ROM_REGION( 0x8000, "samples", 0 ) ROM_LOAD( "4.12a", 0x0000, 0x8000, CRC(851ed9fd) SHA1(5dc048b612e45da529502bf33d968737a7b0a646) ) /* 8-bit samples */ - ROM_REGION( 0x4000, "sound2", 0 ) + ROM_REGION( 0x4000, "soundvol", 0 ) ROM_LOAD( "5.16a", 0x0000, 0x4000, CRC(42fa2853) SHA1(cc1e8b8231d6f27f48b05d59390e93ea1c1c0e4c) ) /* volume tables? */ ROM_REGION( 0x300, "proms", 0 ) /* RGB proms */ @@ -431,10 +562,10 @@ ROM_START( flower ) /* Komax version */ ROM_END ROM_START( flowerj ) /* Sega/Alpha version. Sega game number 834-5998 */ - ROM_REGION( 0x10000, "maincpu", 0 ) /* main cpu */ + ROM_REGION( 0x10000, "mastercpu", 0 ) /* main cpu */ ROM_LOAD( "1", 0x0000, 0x8000, CRC(63a2ef04) SHA1(0770f5a18d58b780abcda7e000c2a5e46f96d319) ) // hacked? "AKINA.N" changed to "JUKYUNG" - ROM_REGION( 0x10000, "subcpu", 0 ) /* sub cpu */ + ROM_REGION( 0x10000, "slavecpu", 0 ) /* sub cpu */ ROM_LOAD( "2.5f", 0x0000, 0x8000, CRC(7c7ee2d8) SHA1(1e67bfe0f3585be5a6e6719ccf9db764bafbcb01) ) ROM_REGION( 0x10000, "audiocpu", 0 ) /* sound cpu */ @@ -455,10 +586,10 @@ ROM_START( flowerj ) /* Sega/Alpha version. Sega game number 834-5998 */ ROM_LOAD( "12.16e", 0x4000, 0x2000, CRC(e3779f7f) SHA1(8e12d06b3cdc2fcb7b77cc35f8eca45544cc4873) ) ROM_LOAD( "11.14e", 0x6000, 0x2000, CRC(8801b34f) SHA1(256059fcd16b21e076db1c18fd9669128df1d658) ) - ROM_REGION( 0x8000, "sound1", 0 ) + ROM_REGION( 0x8000, "samples", 0 ) ROM_LOAD( "4.12a", 0x0000, 0x8000, CRC(851ed9fd) SHA1(5dc048b612e45da529502bf33d968737a7b0a646) ) /* 8-bit samples */ - ROM_REGION( 0x4000, "sound2", 0 ) + ROM_REGION( 0x4000, "soundvol", 0 ) ROM_LOAD( "5.16a", 0x0000, 0x4000, CRC(42fa2853) SHA1(cc1e8b8231d6f27f48b05d59390e93ea1c1c0e4c) ) /* volume tables? */ ROM_REGION( 0x300, "proms", 0 ) /* RGB proms */ @@ -474,5 +605,5 @@ ROM_START( flowerj ) /* Sega/Alpha version. Sega game number 834-5998 */ ROM_END -GAME( 1986, flower, 0, flower, flower, flower_state, 0, ROT0, "Clarue (Komax license)", "Flower (US)", MACHINE_NOT_WORKING|MACHINE_NO_SOUND|MACHINE_IMPERFECT_GRAPHICS|MACHINE_NO_COCKTAIL ) -GAME( 1986, flowerj, flower, flower, flower, flower_state, 0, ROT0, "Clarue (Sega / Alpha Denshi Co. license)", "Flower (Japan)", MACHINE_NOT_WORKING|MACHINE_NO_SOUND|MACHINE_IMPERFECT_GRAPHICS|MACHINE_NO_COCKTAIL ) +GAME( 1986, flower, 0, flower, flower, flower_state, 0, ROT0, "Clarue (Komax license)", "Flower (US)", MACHINE_IMPERFECT_SOUND|MACHINE_IMPERFECT_GRAPHICS|MACHINE_NO_COCKTAIL ) +GAME( 1986, flowerj, flower, flower, flower, flower_state, 0, ROT0, "Clarue (Sega / Alpha Denshi Co. license)", "Flower (Japan)", MACHINE_IMPERFECT_SOUND|MACHINE_IMPERFECT_GRAPHICS|MACHINE_NO_COCKTAIL ) diff --git a/src/mame/drivers/fm7.cpp b/src/mame/drivers/fm7.cpp index 5cd069931b0..99e7c8e86ab 100644 --- a/src/mame/drivers/fm7.cpp +++ b/src/mame/drivers/fm7.cpp @@ -2051,7 +2051,7 @@ SLOT_INTERFACE_END MCFG_DEVICE_ADD(tag, ADDRESS_MAP_BANK, 0) \ MCFG_DEVICE_PROGRAM_MAP(fm7_banked_mem) \ MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) \ -MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) \ +MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) \ MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) diff --git a/src/mame/drivers/fmtowns.cpp b/src/mame/drivers/fmtowns.cpp index 83cd95e392e..7d20aba1d41 100644 --- a/src/mame/drivers/fmtowns.cpp +++ b/src/mame/drivers/fmtowns.cpp @@ -2670,6 +2670,9 @@ void towns_state::driver_start() m_towns_cd.buffer_ptr = -1; m_towns_cd.read_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(towns_state::towns_cdrom_read_byte),this), (void*)machine().device("dma_1")); + save_pointer(m_video.towns_crtc_reg,"CRTC registers",32); + save_pointer(m_video.towns_video_reg,"Video registers",2); + m_maincpu->space(AS_PROGRAM).install_ram(0x100000,m_ram->size()-1,nullptr); } @@ -2777,8 +2780,10 @@ static MACHINE_CONFIG_START( towns_base ) MCFG_SCREEN_VISIBLE_AREA(0, 768-1, 0, 512-1) MCFG_SCREEN_UPDATE_DRIVER(towns_state, screen_update) - MCFG_GFXDECODE_ADD("gfxdecode", "palette", towns) - MCFG_PALETTE_ADD("palette", 256) + MCFG_GFXDECODE_ADD("gfxdecode", "palette16_0", towns) + MCFG_PALETTE_ADD("palette256", 256) + MCFG_PALETTE_ADD("palette16_0", 16) + MCFG_PALETTE_ADD("palette16_1", 16) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mame/drivers/force68k.cpp b/src/mame/drivers/force68k.cpp index 0736fdb585d..be6da049d7e 100644 --- a/src/mame/drivers/force68k.cpp +++ b/src/mame/drivers/force68k.cpp @@ -238,12 +238,9 @@ static ADDRESS_MAP_START (force68k_mem, AS_PROGRAM, 16, force68k_state) AM_RANGE (0x080000, 0x083fff) AM_ROM /* System EPROM Area 16Kb DEBUGGER supplied as default on CPU-1B/D */ AM_RANGE (0x084000, 0x09ffff) AM_ROM /* System EPROM Area 112Kb additional space for System ROM */ //AM_RANGE (0x0a0000, 0x0bffff) AM_ROM /* User EPROM/SRAM Area, max 128Kb mapped by a cartslot */ - AM_RANGE (0x0c0040, 0x0c0041) AM_DEVREADWRITE8 ("aciahost", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE (0x0c0042, 0x0c0043) AM_DEVREADWRITE8 ("aciahost", acia6850_device, data_r, data_w, 0x00ff) - AM_RANGE (0x0c0080, 0x0c0081) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, status_r, control_w, 0xff00) - AM_RANGE (0x0c0082, 0x0c0083) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, data_r, data_w, 0xff00) - AM_RANGE (0x0c0100, 0x0c0101) AM_DEVREADWRITE8 ("aciaremt", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE (0x0c0102, 0x0c0103) AM_DEVREADWRITE8 ("aciaremt", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE (0x0c0040, 0x0c0043) AM_DEVREADWRITE8 ("aciahost", acia6850_device, read, write, 0x00ff) + AM_RANGE (0x0c0080, 0x0c0083) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, read, write, 0xff00) + AM_RANGE (0x0c0100, 0x0c0103) AM_DEVREADWRITE8 ("aciaremt", acia6850_device, read, write, 0x00ff) AM_RANGE (0x0c0400, 0x0c042f) AM_DEVREADWRITE8 ("rtc", mm58167_device, read, write, 0x00ff) AM_RANGE (0x0e0000, 0x0e0035) AM_DEVREADWRITE8 ("pit", pit68230_device, read, write, 0x00ff) //AM_RANGE(0x0e0200, 0x0e0380) AM_READWRITE(fpu_r, fpu_w) /* optional FPCP 68881 FPU interface */ diff --git a/src/mame/drivers/ft68m.cpp b/src/mame/drivers/ft68m.cpp index c52e7f32865..674136abb9c 100644 --- a/src/mame/drivers/ft68m.cpp +++ b/src/mame/drivers/ft68m.cpp @@ -46,7 +46,7 @@ READ16_MEMBER( ft68m_state::switches_r ) } -static ADDRESS_MAP_START(ft68m_mem, AS_PROGRAM, 16, ft68m_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 16, ft68m_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xffffff) AM_RANGE(0x000000, 0x1fffff) AM_RAM AM_SHARE("rambase") @@ -82,7 +82,7 @@ static MACHINE_CONFIG_START( ft68m ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M68000, XTAL_19_6608MHz / 2) - MCFG_CPU_PROGRAM_MAP(ft68m_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) MCFG_DEVICE_ADD("mpsc", UPD7201_NEW, 0) MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs232a", rs232_port_device, write_txd)) diff --git a/src/mame/drivers/funkball.cpp b/src/mame/drivers/funkball.cpp index bd0bc704f68..4a098e8ae35 100644 --- a/src/mame/drivers/funkball.cpp +++ b/src/mame/drivers/funkball.cpp @@ -782,8 +782,8 @@ static MACHINE_CONFIG_START( funkball ) MCFG_DEVICE_ADD("flashbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(flashbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) /* video hardware */ diff --git a/src/mame/drivers/funworld.cpp b/src/mame/drivers/funworld.cpp index c5debc4a315..a31afd756f2 100644 --- a/src/mame/drivers/funworld.cpp +++ b/src/mame/drivers/funworld.cpp @@ -7117,10 +7117,10 @@ GAME( 199?, soccernw, 0, royalcd1, royalcrd, funworld_state, soccernw, // Other games... GAME( 198?, funquiz, 0, funquiz, funquiz, funworld_state, 0, ROT0, "Fun World / Oehlinger", "Fun World Quiz (Austrian)", 0 ) GAMEL( 1986, novoplay, 0, fw2ndpal, novoplay, funworld_state, 0, ROT0, "Admiral/Novomatic", "Novo Play Multi Card / Club Card", 0, layout_novoplay ) -GAME( 1991, intrgmes, 0, intrgmes, funworld, funworld_state, 0, ROT0, "Inter Games", "Unknown Inter Games poker", MACHINE_NOT_WORKING ) -GAMEL( 1985, fw_a7_11, 0, fw_a7_11, funworld, funworld_state, 0, ROT0, "Fun World", "Unknown Fun World A7-11 game 1", MACHINE_NOT_WORKING, layout_jollycrd ) -GAMEL( 1985, fw_a7_11a, fw_a7_11, fw_a7_11, funworld, funworld_state, 0, ROT0, "Fun World", "Unknown Fun World A7-11 game 2", MACHINE_NOT_WORKING, layout_jollycrd ) -GAMEL( 1991, fw_a0_1, 0, fw_a7_11, funworld, funworld_state, 0, ROT0, "Fun World", "Unknown Fun World A0-1 game", MACHINE_NOT_WORKING, layout_jollycrd ) +GAME( 1991, intrgmes, 0, intrgmes, funworld, funworld_state, 0, ROT0, "Inter Games", "unknown Inter Games poker", MACHINE_NOT_WORKING ) +GAMEL( 1985, fw_a7_11, 0, fw_a7_11, funworld, funworld_state, 0, ROT0, "Fun World", "unknown Fun World A7-11 game 1", MACHINE_NOT_WORKING, layout_jollycrd ) +GAMEL( 1985, fw_a7_11a, fw_a7_11, fw_a7_11, funworld, funworld_state, 0, ROT0, "Fun World", "unknown Fun World A7-11 game 2", MACHINE_NOT_WORKING, layout_jollycrd ) +GAMEL( 1991, fw_a0_1, 0, fw_a7_11, funworld, funworld_state, 0, ROT0, "Fun World", "unknown Fun World A0-1 game", MACHINE_NOT_WORKING, layout_jollycrd ) // These are 2-in-1 stealth boards, they can run the Poker game, or, using completely separate hardware on the same PCB, a NES / MSX Multigames! GAMEL( 1991, royalcrd_nes, royalcrd, royalcd2, royalcrd, funworld_state, 0, ROT0, "bootleg", "Royal Card (stealth with NES multigame)", MACHINE_NOT_WORKING, layout_jollycrd ) diff --git a/src/mame/drivers/g627.cpp b/src/mame/drivers/g627.cpp index 069c750b811..3c6576f272f 100644 --- a/src/mame/drivers/g627.cpp +++ b/src/mame/drivers/g627.cpp @@ -78,13 +78,13 @@ private: }; -static ADDRESS_MAP_START( g627_map, AS_PROGRAM, 8, g627_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, g627_state ) AM_RANGE(0x0000, 0x1fff) AM_ROM AM_RANGE(0xc000, 0xc0ff) AM_DEVREADWRITE("i8156", i8155_device, memory_r, memory_w) AM_RANGE(0xe000, 0xe0ff) AM_RAM AM_SHARE("nvram") // battery backed ADDRESS_MAP_END -static ADDRESS_MAP_START( g627_io, AS_IO, 8, g627_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, g627_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x02) AM_WRITE(disp_w) AM_RANGE(0x03, 0x07) AM_WRITE(lamp_w) @@ -289,8 +289,8 @@ WRITE8_MEMBER( g627_state::lamp_w ) static MACHINE_CONFIG_START( g627 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, 14138000/8) - MCFG_CPU_PROGRAM_MAP(g627_map) - MCFG_CPU_IO_MAP(g627_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_DEVICE_ADD("i8156", I8156, 14138000/8) MCFG_I8155_IN_PORTA_CB(READ8(g627_state, porta_r)) diff --git a/src/mame/drivers/gaelco3d.cpp b/src/mame/drivers/gaelco3d.cpp index 2d8c43da0ad..e65502e9719 100644 --- a/src/mame/drivers/gaelco3d.cpp +++ b/src/mame/drivers/gaelco3d.cpp @@ -366,7 +366,7 @@ WRITE_LINE_MEMBER(gaelco3d_state::fp_analog_clock_w) if (m_fp_clock == 28) { m_fp_clock = 0; - for (auto i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { u32 ay = m_analog[i * 2].read_safe(0); u32 ax = m_analog[i * 2 + 1].read_safe(0); @@ -561,7 +561,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(gaelco3d_state::adsp_autobuffer_irq) reg = m_adsp_ireg_base; /* generate the (internal, thats why the pulse) irq */ - generic_pulse_irq_line(*m_adsp, ADSP2105_IRQ1, 1); + m_adsp->pulse_input_line(ADSP2105_IRQ1, m_adsp->minimum_quantum_time()); } /* store it */ diff --git a/src/mame/drivers/gal3.cpp b/src/mame/drivers/gal3.cpp index 4dc61cc4a5c..568d0462e8b 100644 --- a/src/mame/drivers/gal3.cpp +++ b/src/mame/drivers/gal3.cpp @@ -867,5 +867,5 @@ ROM_START( gal3 ) ROM_END /* YEAR, NAME PARENT, MACHINE, INPUT, STATE, INIT, MONITOR, COMPANY, FULLNAME, FLAGS */ -GAMEL( 199?, gal3, 0, gal3, gal3, gal3_state, 0, ROT0, "Namco", "Galaxian 3 - Theater 6 : Project Dragoon", MACHINE_NOT_WORKING | MACHINE_NO_SOUND, layout_dualhsxs ) -//GAMEL( 199?, gal3zlgr, 0, gal3, gal3, driver_device, 0, ROT0, "Namco", "Galaxian 3 - Theater 6 J2 : Attack of The Zolgear", MACHINE_NOT_WORKING | MACHINE_NO_SOUND, layout_dualhsxs ) +GAMEL( 1992, gal3, 0, gal3, gal3, gal3_state, 0, ROT0, "Namco", "Galaxian 3 - Theater 6 : Project Dragoon", MACHINE_NOT_WORKING | MACHINE_NO_SOUND, layout_dualhsxs ) +//GAMEL( 1994, gal3zlgr, 0, gal3, gal3, driver_device, 0, ROT0, "Namco", "Galaxian 3 - Theater 6 J2 : Attack of The Zolgear", MACHINE_NOT_WORKING | MACHINE_NO_SOUND, layout_dualhsxs ) diff --git a/src/mame/drivers/galaxian.cpp b/src/mame/drivers/galaxian.cpp index caae5457a0d..8f8894bd8c6 100644 --- a/src/mame/drivers/galaxian.cpp +++ b/src/mame/drivers/galaxian.cpp @@ -1961,7 +1961,7 @@ ADDRESS_MAP_END /* changes from galaxian map: galaxian sound removed - $4800-$57ff: cointains video and object RAM (normally at $5000-$5fff) + $4800-$57ff: contains video and object RAM (normally at $5000-$5fff) $5800-$5fff: AY-8910 access added $6002-$6006: graphics banking controls replace coin lockout, coin counter, and lfo $7002: coin counter (moved from $6003) @@ -10145,7 +10145,7 @@ ROM_START( kingball ) ROM_REGION( 0x10000, "audiocpu", 0 ) /* 64k for sound code */ ROM_LOAD( "kbe1.ic4", 0x0000, 0x0800, CRC(5be2c80a) SHA1(f719a80357bed3d66bce40569690f419740148c5) ) ROM_LOAD( "kbe2.ic5", 0x0800, 0x0800, CRC(bb59e965) SHA1(830e0c415f051e932d76df604025e4e33118a799) ) - ROM_LOAD( "kbe3.ic6", 0x1000, 0x0800, BAD_DUMP CRC(1c94dd31) SHA1(14ab59b8eee741eb1f10ae99ddb99bf7c2dab957) ) // 2nd half missing ("bye bye" voice cut off) + ROM_LOAD( "kbe3.ic6", 0x1000, 0x0800, CRC(fbc7d286) SHA1(11511028920d30f65859b80379b5aab94240a741) ) ROM_LOAD( "kbe2.ic7", 0x1800, 0x0800, CRC(bb59e965) SHA1(830e0c415f051e932d76df604025e4e33118a799) ) ROM_REGION( 0x2000, "gfx1", 0 ) diff --git a/src/mame/drivers/gba.cpp b/src/mame/drivers/gba.cpp index 1fbb615a811..af7fe7991f4 100644 --- a/src/mame/drivers/gba.cpp +++ b/src/mame/drivers/gba.cpp @@ -1181,6 +1181,10 @@ READ32_MEMBER(gba_state::gba_10000000_r) { uint32_t data; uint32_t pc = m_maincpu->state_int(ARM7_PC); + if (pc >= 0x10000000) + { + return 0; + } uint32_t cpsr = m_maincpu->state_int(ARM7_CPSR); if (T_IS_SET( cpsr)) { diff --git a/src/mame/drivers/gei.cpp b/src/mame/drivers/gei.cpp index 6f41c07974b..28c2ffbc11e 100644 --- a/src/mame/drivers/gei.cpp +++ b/src/mame/drivers/gei.cpp @@ -66,7 +66,7 @@ U.S.A. Trivia New Sports General Facts or alt: Adult Sex 2 or alt: Adult Sex 3 or alt: Gay Times NOTE: Trivia Question rom names are the internal names used. IE: read from the file with - a Hex Editor. Any "_alt" extention is used to separate different roms with the same + a Hex Editor. Any "_alt" extension is used to separate different roms with the same label or internal name. */ @@ -90,97 +90,97 @@ public: m_maincpu(*this, "maincpu"), m_dac(*this, "dac"), m_ticket(*this, "ticket"), - m_screen(*this, "screen") { } - - required_device<cpu_device> m_maincpu; - required_device<dac_bit_interface> m_dac; - optional_device<ticket_dispenser_device> m_ticket; - required_device<screen_device> m_screen; - - virtual void video_start() override; + m_screen(*this, "screen"), + m_signature(*this, "signature"), + m_rombank(*this, "rombank") { } uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - bitmap_ind16 m_bitmap; - - uint8_t m_drawctrl[3]; - uint8_t m_color[8]; - int m_prevoffset; - int m_yadd; - int m_signature_answer; - int m_signature_pos; - uint8_t m_nmi_mask; DECLARE_WRITE8_MEMBER(gei_drawctrl_w); DECLARE_WRITE8_MEMBER(gei_bitmap_w); DECLARE_READ8_MEMBER(catchall); - DECLARE_WRITE8_MEMBER(banksel_main_w); - DECLARE_WRITE8_MEMBER(banksel_1_w); - DECLARE_WRITE8_MEMBER(banksel_2_w); - DECLARE_WRITE8_MEMBER(banksel_3_w); - DECLARE_WRITE8_MEMBER(banksel_4_w); - DECLARE_WRITE8_MEMBER(banksel_5_w); - DECLARE_WRITE8_MEMBER(banksel_1_1_w); - DECLARE_WRITE8_MEMBER(banksel_2_1_w); - DECLARE_WRITE8_MEMBER(banksel_3_1_w); - DECLARE_WRITE8_MEMBER(banksel_4_1_w); - DECLARE_WRITE8_MEMBER(banksel_5_1_w); - DECLARE_WRITE8_MEMBER(banksel_1_2_w); - DECLARE_WRITE8_MEMBER(banksel_2_2_w); - DECLARE_WRITE8_MEMBER(banksel_3_2_w); - DECLARE_WRITE8_MEMBER(banksel_4_2_w); - DECLARE_WRITE8_MEMBER(banksel_5_2_w); + template <unsigned N> DECLARE_WRITE8_MEMBER(banksel_w) { m_rombank->set_entry(N); } DECLARE_WRITE8_MEMBER(geimulti_bank_w); - DECLARE_READ8_MEMBER(banksel_1_r); - DECLARE_READ8_MEMBER(banksel_2_r); - DECLARE_READ8_MEMBER(banksel_3_r); - DECLARE_READ8_MEMBER(banksel_4_r); - DECLARE_READ8_MEMBER(banksel_5_r); + template <unsigned N> DECLARE_READ8_MEMBER(banksel_r); DECLARE_READ8_MEMBER(signature_r); DECLARE_WRITE8_MEMBER(signature_w); - DECLARE_WRITE8_MEMBER(signature2_w); DECLARE_WRITE8_MEMBER(lamps_w); DECLARE_WRITE8_MEMBER(sound_w); DECLARE_WRITE8_MEMBER(sound2_w); DECLARE_WRITE8_MEMBER(lamps2_w); DECLARE_WRITE8_MEMBER(nmi_w); DECLARE_READ8_MEMBER(portC_r); - DECLARE_DRIVER_INIT(geimulti); + DECLARE_DRIVER_INIT(setbank); + DECLARE_DRIVER_INIT(bank2k); + DECLARE_DRIVER_INIT(bank8k); + DECLARE_DRIVER_INIT(geimulti); + INTERRUPT_GEN_MEMBER(vblank_irq); + +protected: + virtual void video_start() override; + +private: + bitmap_ind16 m_bitmap; + + uint8_t m_drawctrl[3]; + uint8_t m_color[8]; + int m_prevoffset; + int m_yadd; + int m_signature_answer; + int m_signature_pos; + uint8_t m_nmi_mask; + + required_device<cpu_device> m_maincpu; + required_device<dac_bit_interface> m_dac; + optional_device<ticket_dispenser_device> m_ticket; + required_device<screen_device> m_screen; + optional_region_ptr<uint8_t> m_signature; + optional_memory_bank m_rombank; }; WRITE8_MEMBER(gei_state::gei_drawctrl_w) { m_drawctrl[offset] = data; + if (offset == 2) { - int i; - for (i = 0; i < 8; i++) - if (BIT(m_drawctrl[1],i)) m_color[i] = m_drawctrl[0] & 7; + for (int i = 0; i < 8; i++) + if (BIT(m_drawctrl[1], i)) m_color[i] = m_drawctrl[0] & 7; } } WRITE8_MEMBER(gei_state::gei_bitmap_w) { - int sx,sy; - int i; - - m_yadd = (offset==m_prevoffset) ? (m_yadd+1):0; + m_yadd = (offset == m_prevoffset) ? (m_yadd + 1) : 0; m_prevoffset = offset; - sx = 8 * (offset % 64); - sy = offset / 64; + int sx = 8 * (offset % 64); + int sy = offset / 64; sy = (sy + m_yadd) & 0xff; - - for (i = 0; i < 8; i++) - m_bitmap.pix16(sy, sx+i) = m_color[8-i-1]; + for (int i = 0; i < 8; i++) + m_bitmap.pix16(sy, sx + i) = m_color[8 - i - 1]; } void gei_state::video_start() { m_screen->register_screen_bitmap(m_bitmap); + + save_item(NAME(m_drawctrl)); + save_item(NAME(m_color)); + save_item(NAME(m_prevoffset)); + save_item(NAME(m_yadd)); + save_item(NAME(m_nmi_mask)); + save_item(NAME(m_bitmap)); + + if (m_signature.found()) + { + save_item(NAME(m_signature_answer)); + save_item(NAME(m_signature_pos)); + } } uint32_t gei_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -192,28 +192,28 @@ uint32_t gei_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c WRITE8_MEMBER(gei_state::lamps_w) { /* 5 button lamps */ - output().set_led_value(0,data & 0x01); - output().set_led_value(1,data & 0x02); - output().set_led_value(2,data & 0x04); - output().set_led_value(3,data & 0x08); - output().set_led_value(4,data & 0x10); + output().set_led_value(0, BIT(data, 0)); + output().set_led_value(1, BIT(data, 1)); + output().set_led_value(2, BIT(data, 2)); + output().set_led_value(3, BIT(data, 3)); + output().set_led_value(4, BIT(data, 4)); /* 3 button lamps for deal, cancel, stand in poker games; lamp order verified in poker and selection self tests */ - output().set_led_value(7,data & 0x20); - output().set_led_value(5,data & 0x40); - output().set_led_value(6,data & 0x80); + output().set_led_value(7, BIT(data, 5)); + output().set_led_value(5, BIT(data, 6)); + output().set_led_value(6, BIT(data, 7)); } WRITE8_MEMBER(gei_state::sound_w) { /* bit 3 - coin lockout, lamp10 in poker / lamp6 in trivia test modes */ - machine().bookkeeping().coin_lockout_global_w(~data & 0x08); - output().set_led_value(9,data & 0x08); + machine().bookkeeping().coin_lockout_global_w(BIT(~data, 3)); + output().set_led_value(9, BIT(data, 3)); /* bit 5 - ticket out in trivia games */ if (m_ticket != nullptr) - m_ticket->write(machine().dummy_space(), 0, (data & 0x20)<< 2); + m_ticket->write(machine().dummy_space(), 0, (data & 0x20) << 2); /* bit 6 enables NMI */ m_nmi_mask = data & 0x40; @@ -224,16 +224,16 @@ WRITE8_MEMBER(gei_state::sound_w) WRITE8_MEMBER(gei_state::sound2_w) { - /* bit 3,6 - coin lockout, lamp10+11 in selection test mode */ - machine().bookkeeping().coin_lockout_w(0, ~data & 0x08); - machine().bookkeeping().coin_lockout_w(1, ~data & 0x40); - output().set_led_value(9,data & 0x08); - output().set_led_value(10,data & 0x40); + /* bit 3,6 - coin lockout, lamp 10 + 11 in selection test mode */ + machine().bookkeeping().coin_lockout_w(0, BIT(~data, 3)); + machine().bookkeeping().coin_lockout_w(1, BIT(~data, 6)); + output().set_led_value(9, BIT(data, 3)); + output().set_led_value(10, BIT(data, 6)); /* bit 4,5 - lamps 12, 13 in selection test mode; 12 lights up if dsw maximum bet = 30 an bet > 15 or if dsw maximum bet = 10 an bet = 10 */ - output().set_led_value(11,data & 0x10); - output().set_led_value(12,data & 0x20); + output().set_led_value(11, BIT(data, 4)); + output().set_led_value(12, BIT(data, 5)); /* bit 7 goes directly to the sound amplifier */ m_dac->write(BIT(data, 7)); @@ -242,13 +242,13 @@ WRITE8_MEMBER(gei_state::sound2_w) WRITE8_MEMBER(gei_state::lamps2_w) { /* bit 4 - play/raise button lamp, lamp 9 in poker test mode */ - output().set_led_value(8,data & 0x10); + output().set_led_value(8, BIT(data, 4)); } WRITE8_MEMBER(gei_state::nmi_w) { /* bit 4 - play/raise button lamp, lamp 9 in selection test mode */ - output().set_led_value(8,data & 0x10); + output().set_led_value(8, BIT(data, 4)); /* bit 6 enables NMI */ m_nmi_mask = data & 0x40; @@ -269,71 +269,6 @@ READ8_MEMBER(gei_state::portC_r) return 4; } -WRITE8_MEMBER(gei_state::banksel_main_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x8000); -} -WRITE8_MEMBER(gei_state::banksel_1_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x10000); -} -WRITE8_MEMBER(gei_state::banksel_2_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x18000); -} -WRITE8_MEMBER(gei_state::banksel_3_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x20000); -} -WRITE8_MEMBER(gei_state::banksel_4_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x28000); -} -WRITE8_MEMBER(gei_state::banksel_5_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x30000); -} - -WRITE8_MEMBER(gei_state::banksel_1_1_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x10000); -} -WRITE8_MEMBER(gei_state::banksel_2_1_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x14000); -} -WRITE8_MEMBER(gei_state::banksel_3_1_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x18000); -} -WRITE8_MEMBER(gei_state::banksel_4_1_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x1c000); -} -WRITE8_MEMBER(gei_state::banksel_5_1_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x20000); -} -WRITE8_MEMBER(gei_state::banksel_1_2_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x12000); -} -WRITE8_MEMBER(gei_state::banksel_2_2_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x16000); -} -WRITE8_MEMBER(gei_state::banksel_3_2_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x1a000); -} -WRITE8_MEMBER(gei_state::banksel_4_2_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x1e000); -} -WRITE8_MEMBER(gei_state::banksel_5_2_w) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x22000); -} WRITE8_MEMBER(gei_state::geimulti_bank_w) { @@ -360,36 +295,14 @@ WRITE8_MEMBER(gei_state::geimulti_bank_w) } if (bank != -1) - membank("bank1")->set_base(memregion("bank")->base() + bank*0x8000); -} - -READ8_MEMBER(gei_state::banksel_1_r) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x10000); - return 0x03; -} - -READ8_MEMBER(gei_state::banksel_2_r) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x18000); - return 0x03; -} - -READ8_MEMBER(gei_state::banksel_3_r) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x20000); - return 0x03; -} - -READ8_MEMBER(gei_state::banksel_4_r) -{ - membank("bank1")->set_base(memregion("maincpu")->base() + 0x28000); - return 0x03; + m_rombank->set_entry(bank); } -READ8_MEMBER(gei_state::banksel_5_r) +template <unsigned N> +READ8_MEMBER(gei_state::banksel_r) { - membank("bank1")->set_base(memregion("maincpu")->base() + 0x30000); + if (!machine().side_effect_disabled()) + m_rombank->set_entry(N); return 0x03; } @@ -403,24 +316,10 @@ READ8_MEMBER(gei_state::signature_r) WRITE8_MEMBER(gei_state::signature_w) { if (data == 0) m_signature_pos = 0; - else - { - static const uint8_t signature[8] = { 0xff, 0x01, 0xfd, 0x05, 0xf5, 0x15, 0xd5, 0x55 }; - - m_signature_answer = signature[m_signature_pos++]; - - m_signature_pos &= 7; /* safety; shouldn't happen */ - } -} -WRITE8_MEMBER(gei_state::signature2_w) -{ - if (data == 0) m_signature_pos = 0; else { - static const uint8_t signature[8] = { 0xff, 0x01, 0xf7, 0x11, 0xd7, 0x51, 0x57, 0x51 }; - - m_signature_answer = signature[m_signature_pos++]; + m_signature_answer = m_signature[m_signature_pos++]; m_signature_pos &= 7; /* safety; shouldn't happen */ } @@ -428,20 +327,20 @@ WRITE8_MEMBER(gei_state::signature2_w) static ADDRESS_MAP_START( getrivia_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x0000, 0x1fff) AM_ROM - AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("bank1") + AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("rombank") AM_RANGE(0x4000, 0x47ff) AM_RAM AM_SHARE("nvram") AM_RANGE(0x4800, 0x4803) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) - AM_RANGE(0x600f, 0x600f) AM_WRITE(banksel_5_1_w) - AM_RANGE(0x6017, 0x6017) AM_WRITE(banksel_4_1_w) - AM_RANGE(0x601b, 0x601b) AM_WRITE(banksel_3_1_w) - AM_RANGE(0x601d, 0x601d) AM_WRITE(banksel_2_1_w) - AM_RANGE(0x601e, 0x601e) AM_WRITE(banksel_1_1_w) - AM_RANGE(0x608f, 0x608f) AM_WRITE(banksel_5_2_w) - AM_RANGE(0x6097, 0x6097) AM_WRITE(banksel_4_2_w) - AM_RANGE(0x609b, 0x609b) AM_WRITE(banksel_3_2_w) - AM_RANGE(0x609d, 0x609d) AM_WRITE(banksel_2_2_w) - AM_RANGE(0x609e, 0x609e) AM_WRITE(banksel_1_2_w) + AM_RANGE(0x600f, 0x600f) AM_WRITE(banksel_w<8>) + AM_RANGE(0x6017, 0x6017) AM_WRITE(banksel_w<6>) + AM_RANGE(0x601b, 0x601b) AM_WRITE(banksel_w<4>) + AM_RANGE(0x601d, 0x601d) AM_WRITE(banksel_w<2>) + AM_RANGE(0x601e, 0x601e) AM_WRITE(banksel_w<0>) + AM_RANGE(0x608f, 0x608f) AM_WRITE(banksel_w<9>) + AM_RANGE(0x6097, 0x6097) AM_WRITE(banksel_w<7>) + AM_RANGE(0x609b, 0x609b) AM_WRITE(banksel_w<5>) + AM_RANGE(0x609d, 0x609d) AM_WRITE(banksel_w<3>) + AM_RANGE(0x609e, 0x609e) AM_WRITE(banksel_w<1>) AM_RANGE(0x8000, 0x8002) AM_WRITE(gei_drawctrl_w) AM_RANGE(0x8000, 0x9fff) AM_ROM /* space for diagnostic ROM? */ AM_RANGE(0xa000, 0xbfff) AM_ROM @@ -450,12 +349,12 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( gselect_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x0000, 0x1fff) AM_ROM - AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("bank1") + AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("rombank") AM_RANGE(0x4000, 0x40ff) AM_RAM AM_SHARE("nvram") - AM_RANGE(0x4400, 0x4400) AM_WRITE(banksel_1_1_w) - AM_RANGE(0x4401, 0x4401) AM_WRITE(banksel_1_2_w) - AM_RANGE(0x4402, 0x4402) AM_WRITE(banksel_2_1_w) - AM_RANGE(0x4403, 0x4403) AM_WRITE(banksel_2_2_w) + AM_RANGE(0x4400, 0x4400) AM_WRITE(banksel_w<0>) + AM_RANGE(0x4401, 0x4401) AM_WRITE(banksel_w<1>) + AM_RANGE(0x4402, 0x4402) AM_WRITE(banksel_w<2>) + AM_RANGE(0x4403, 0x4403) AM_WRITE(banksel_w<3>) AM_RANGE(0x4800, 0x4803) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) AM_RANGE(0x8000, 0x8002) AM_WRITE(gei_drawctrl_w) @@ -465,15 +364,15 @@ ADDRESS_MAP_END // TODO: where are mapped the lower 0x2000 bytes of the banks? static ADDRESS_MAP_START( amuse_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x0000, 0x1fff) AM_ROM - AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("bank1") + AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("rombank") AM_RANGE(0x4000, 0x47ff) AM_RAM AM_SHARE("nvram") AM_RANGE(0x4800, 0x4803) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) - AM_RANGE(0x606f, 0x606f) AM_WRITE(banksel_5_1_w) - AM_RANGE(0x6077, 0x6077) AM_WRITE(banksel_4_1_w) - AM_RANGE(0x607b, 0x607b) AM_WRITE(banksel_3_1_w) - AM_RANGE(0x607d, 0x607d) AM_WRITE(banksel_2_1_w) - AM_RANGE(0x607e, 0x607e) AM_WRITE(banksel_1_1_w) + AM_RANGE(0x606f, 0x606f) AM_WRITE(banksel_w<8>) + AM_RANGE(0x6077, 0x6077) AM_WRITE(banksel_w<6>) + AM_RANGE(0x607b, 0x607b) AM_WRITE(banksel_w<4>) + AM_RANGE(0x607d, 0x607d) AM_WRITE(banksel_w<2>) + AM_RANGE(0x607e, 0x607e) AM_WRITE(banksel_w<0>) AM_RANGE(0x8000, 0x8002) AM_WRITE(gei_drawctrl_w) AM_RANGE(0x8000, 0xbfff) AM_ROM AM_RANGE(0xc000, 0xffff) AM_RAM_WRITE(gei_bitmap_w) @@ -481,15 +380,15 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( gepoker_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x0000, 0x1fff) AM_ROM - AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("bank1") + AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("rombank") AM_RANGE(0x4000, 0x47ff) AM_RAM AM_SHARE("nvram") AM_RANGE(0x4800, 0x4803) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) - AM_RANGE(0x60ef, 0x60ef) AM_WRITE(banksel_3_1_w) - AM_RANGE(0x60f7, 0x60f7) AM_WRITE(banksel_2_2_w) - AM_RANGE(0x60fb, 0x60fb) AM_WRITE(banksel_2_1_w) - AM_RANGE(0x60fd, 0x60fd) AM_WRITE(banksel_1_2_w) - AM_RANGE(0x60fe, 0x60fe) AM_WRITE(banksel_1_1_w) + AM_RANGE(0x60ef, 0x60ef) AM_WRITE(banksel_w<4>) + AM_RANGE(0x60f7, 0x60f7) AM_WRITE(banksel_w<3>) + AM_RANGE(0x60fb, 0x60fb) AM_WRITE(banksel_w<2>) + AM_RANGE(0x60fd, 0x60fd) AM_WRITE(banksel_w<1>) + AM_RANGE(0x60fe, 0x60fe) AM_WRITE(banksel_w<0>) AM_RANGE(0x8000, 0x8002) AM_WRITE(gei_drawctrl_w) AM_RANGE(0x8000, 0xbfff) AM_ROM /* space for diagnostic ROM? */ AM_RANGE(0xe000, 0xffff) AM_ROM @@ -498,12 +397,12 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( amuse1_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x0000, 0x1fff) AM_ROM - AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("bank1") + AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("rombank") AM_RANGE(0x4000, 0x43ff) AM_RAM AM_SHARE("nvram") - AM_RANGE(0x4400, 0x4400) AM_WRITE(banksel_1_1_w) - AM_RANGE(0x4401, 0x4401) AM_WRITE(banksel_2_1_w) - AM_RANGE(0x4402, 0x4402) AM_WRITE(banksel_3_1_w) - AM_RANGE(0x4403, 0x4403) AM_WRITE(banksel_4_1_w) + AM_RANGE(0x4400, 0x4400) AM_WRITE(banksel_w<0>) + AM_RANGE(0x4401, 0x4401) AM_WRITE(banksel_w<2>) + AM_RANGE(0x4402, 0x4402) AM_WRITE(banksel_w<4>) + AM_RANGE(0x4403, 0x4403) AM_WRITE(banksel_w<6>) AM_RANGE(0x4800, 0x4803) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) AM_RANGE(0x5800, 0x5fff) AM_ROM @@ -519,16 +418,16 @@ static ADDRESS_MAP_START( findout_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x4800, 0x4803) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) /* banked ROMs are enabled by low 6 bits of the address */ - AM_RANGE(0x601f, 0x601f) AM_WRITE(banksel_main_w) - AM_RANGE(0x602f, 0x602f) AM_WRITE(banksel_5_w) - AM_RANGE(0x6037, 0x6037) AM_WRITE(banksel_4_w) - AM_RANGE(0x603b, 0x603b) AM_WRITE(banksel_3_w) - AM_RANGE(0x603d, 0x603d) AM_WRITE(banksel_2_w) - AM_RANGE(0x603e, 0x603e) AM_WRITE(banksel_1_w) + AM_RANGE(0x601f, 0x601f) AM_WRITE(banksel_w<0>) + AM_RANGE(0x602f, 0x602f) AM_WRITE(banksel_w<5>) + AM_RANGE(0x6037, 0x6037) AM_WRITE(banksel_w<4>) + AM_RANGE(0x603b, 0x603b) AM_WRITE(banksel_w<3>) + AM_RANGE(0x603d, 0x603d) AM_WRITE(banksel_w<2>) + AM_RANGE(0x603e, 0x603e) AM_WRITE(banksel_w<1>) AM_RANGE(0x6200, 0x6200) AM_WRITE(signature_w) AM_RANGE(0x6400, 0x6400) AM_READ(signature_r) AM_RANGE(0x7800, 0x7fff) AM_ROM /*space for diagnostic ROM?*/ - AM_RANGE(0x8000, 0xffff) AM_ROMBANK("bank1") + AM_RANGE(0x8000, 0xffff) AM_ROMBANK("rombank") AM_RANGE(0x8000, 0x8002) AM_WRITE(gei_drawctrl_w) AM_RANGE(0xc000, 0xffff) AM_WRITE(gei_bitmap_w) AM_RANGE(0x0000, 0xffff) AM_READ(catchall) @@ -540,13 +439,13 @@ static ADDRESS_MAP_START( quizvid_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x4800, 0x4803) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) /* banked ROMs are enabled by low 6 bits of the address */ - AM_RANGE(0x602f, 0x602f) AM_READ(banksel_5_r) - AM_RANGE(0x6037, 0x6037) AM_READ(banksel_4_r) - AM_RANGE(0x603b, 0x603b) AM_READ(banksel_3_r) - AM_RANGE(0x603d, 0x603d) AM_READ(banksel_2_r) - AM_RANGE(0x603e, 0x603e) AM_READ(banksel_1_r) + AM_RANGE(0x602f, 0x602f) AM_READ(banksel_r<5>) + AM_RANGE(0x6037, 0x6037) AM_READ(banksel_r<4>) + AM_RANGE(0x603b, 0x603b) AM_READ(banksel_r<3>) + AM_RANGE(0x603d, 0x603d) AM_READ(banksel_r<2>) + AM_RANGE(0x603e, 0x603e) AM_READ(banksel_r<1>) AM_RANGE(0x7800, 0x7fff) AM_ROM /*space for diagnostic ROM?*/ - AM_RANGE(0x8000, 0xffff) AM_ROMBANK("bank1") + AM_RANGE(0x8000, 0xffff) AM_ROMBANK("rombank") AM_RANGE(0x8000, 0x8002) AM_WRITE(gei_drawctrl_w) AM_RANGE(0xc000, 0xffff) AM_WRITE(gei_bitmap_w) AM_RANGE(0x0000, 0xffff) AM_READ(catchall) @@ -557,26 +456,13 @@ static ADDRESS_MAP_START( suprpokr_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x4000, 0x47ff) AM_RAM AM_SHARE("nvram") AM_RANGE(0x4800, 0x4803) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) - AM_RANGE(0x6200, 0x6200) AM_WRITE(signature2_w) + AM_RANGE(0x6200, 0x6200) AM_WRITE(signature_w) AM_RANGE(0x6400, 0x6400) AM_READ(signature_r) AM_RANGE(0x8000, 0x8002) AM_WRITE(gei_drawctrl_w) AM_RANGE(0xc000, 0xffff) AM_WRITE(gei_bitmap_w) AM_RANGE(0x8000, 0xffff) AM_ROM ADDRESS_MAP_END -static ADDRESS_MAP_START( geimulti_map, AS_PROGRAM, 8, gei_state ) - AM_RANGE(0x0000, 0x3fff) AM_ROM - AM_RANGE(0x4000, 0x47ff) AM_RAM AM_SHARE("nvram") - AM_RANGE(0x4800, 0x4803) AM_DEVREADWRITE("ppi8255_0", i8255_device, read, write) - AM_RANGE(0x5000, 0x5003) AM_DEVREADWRITE("ppi8255_1", i8255_device, read, write) - AM_RANGE(0x5800, 0x5fff) AM_ROM - AM_RANGE(0x5a00, 0x5cff) AM_WRITE(geimulti_bank_w) - AM_RANGE(0x6000, 0x7fff) AM_ROM - AM_RANGE(0x8000, 0x8002) AM_WRITE(gei_drawctrl_w) - AM_RANGE(0x8000, 0xffff) AM_ROMBANK("bank1") - AM_RANGE(0xc000, 0xffff) AM_RAM_WRITE(gei_bitmap_w) -ADDRESS_MAP_END - static ADDRESS_MAP_START( sprtauth_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x0000, 0x3fff) AM_ROM AM_RANGE(0x4000, 0x47ff) AM_RAM AM_SHARE("nvram") @@ -587,7 +473,7 @@ static ADDRESS_MAP_START( sprtauth_map, AS_PROGRAM, 8, gei_state ) AM_RANGE(0x5a00, 0x5cff) AM_WRITE(geimulti_bank_w) AM_RANGE(0x6000, 0x7fff) AM_ROM AM_RANGE(0x8000, 0x8002) AM_WRITE(gei_drawctrl_w) - AM_RANGE(0x8000, 0xffff) AM_ROMBANK("bank1") + AM_RANGE(0x8000, 0xffff) AM_ROMBANK("rombank") AM_RANGE(0xc000, 0xffff) AM_RAM_WRITE(gei_bitmap_w) ADDRESS_MAP_END @@ -870,6 +756,37 @@ static INPUT_PORTS_START(sexappl) PORT_INCLUDE(trivia_standard) INPUT_PORTS_END +static INPUT_PORTS_START(bigjoke) + PORT_START("DSWA") + PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:1") + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) + PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:4") + PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x10, 0x10, "Orientation" ) PORT_DIPLOCATION("SW1:5") + PORT_DIPSETTING( 0x10, "Horizontal" ) + PORT_DIPSETTING( 0x00, "Vertical" ) + PORT_DIPNAME( 0x20, 0x20, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW1:6") + PORT_DIPSETTING( 0x20, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) + PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:7") + PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:8") + PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + + PORT_INCLUDE(trivia_standard) +INPUT_PORTS_END + static INPUT_PORTS_START( gt103 ) PORT_START("DSWA") /* DSW A */ PORT_DIPNAME( 0x07, 0x01, "Coinage Multiplier" ) PORT_DIPLOCATION("SW1:1,2,3") @@ -951,7 +868,7 @@ static INPUT_PORTS_START(geimulti) PORT_INCLUDE(gselect) PORT_MODIFY("DSWA") - PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:1,2,3,4") + PORT_DIPNAME( 0x0f, 0x09, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:1,2,3,4") PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) PORT_DIPSETTING( 0x07, DEF_STR( 7C_1C ) ) PORT_DIPSETTING( 0x06, DEF_STR( 6C_1C ) ) @@ -986,7 +903,7 @@ static INPUT_PORTS_START(sprtauth) PORT_INCLUDE(trivia_standard) PORT_START("DSWA") - PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:1,2,3,4") + PORT_DIPNAME( 0x0f, 0x09, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:1,2,3,4") PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) PORT_DIPSETTING( 0x07, DEF_STR( 7C_1C ) ) PORT_DIPSETTING( 0x06, DEF_STR( 6C_1C ) ) @@ -1020,7 +937,7 @@ INPUT_PORTS_END INTERRUPT_GEN_MEMBER(gei_state::vblank_irq) { - if(m_nmi_mask) + if (m_nmi_mask) device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); } @@ -1028,7 +945,7 @@ INTERRUPT_GEN_MEMBER(gei_state::vblank_irq) static MACHINE_CONFIG_START( getrivia ) MCFG_CPU_ADD("maincpu",Z80,4000000) /* 4 MHz */ MCFG_CPU_PROGRAM_MAP(getrivia_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", gei_state, vblank_irq) + MCFG_CPU_VBLANK_INT_DRIVER("screen", gei_state, vblank_irq) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -1145,18 +1062,13 @@ static MACHINE_CONFIG_DERIVED( suprpokr, getrivia ) MCFG_CPU_PROGRAM_MAP(suprpokr_map) MACHINE_CONFIG_END -static MACHINE_CONFIG_DERIVED( geimulti, getrivia ) - - MCFG_CPU_MODIFY("maincpu") - MCFG_CPU_PROGRAM_MAP(geimulti_map) -MACHINE_CONFIG_END - static MACHINE_CONFIG_DERIVED( sprtauth, getrivia ) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_PROGRAM_MAP(sprtauth_map) MACHINE_CONFIG_END + /*************************************************** Rom board is UVM-1A @@ -1200,7 +1112,7 @@ Rom board is UVM-1B Contains: 4 2732 eproms (Program Code) - Battery (3.5V litium battery) backed up NEC 8444XF301 + Battery (3.5V lithium battery) backed up NEC 8444XF301 DM7408N ****************************************************/ @@ -1219,7 +1131,7 @@ Rom board is UVM 10 B Contains: 2 2764 eproms (Program Code) 5 27128 eproms (Question roms) - Battery (3V litium battery) backed up HM6117P-4 + Battery (3V lithium battery) backed up HM6117P-4 SN74LS374 MMI PAL10L8 @@ -1228,7 +1140,7 @@ Sets will be listed by "series" - the program code version is not as important as maintaining the correct questions sets as per known series Missing sets will be filled as dumped, as question roms - are interchangeable, operators did thier own swaps + are interchangeable, operators did their own swaps Note: Question roms that contain "#1" (or 2 ect) are corrected roms (spelling and / or answers) @@ -1357,7 +1269,7 @@ Rom board is UVM-4B Contains 5 2764 eproms, MMI PAL16R4CN -Battery (3V litium battery) backed up HM6117P-4 +Battery (3V lithium battery) backed up HM6117P-4 Roms labeled as: @@ -1408,7 +1320,7 @@ PAL16R4 Roms in this order on the UMV 10 C board: -Label Normaly in the slot +Label Normally in the slot -------------------------------- High Control @@ -1456,7 +1368,7 @@ ROM_START( gepoker1 ) /* v50.02 with roms for ICB dated 9-30-86 */ ROM_LOAD( "blackjack_icb_9-30-86", 0x12000, 0x2000, CRC(82804184) SHA1(2e2e6a80c99c8eb226dc54c1d32d0bf24de300a4) ) ROM_LOAD( "casinoslots_icb_9-30-86", 0x14000, 0x2000, CRC(713c3963) SHA1(a9297c04fc44522ca6891516a2c744712132896a) ) ROM_LOAD( "beatthespread_icb_9-30-86", 0x16000, 0x2000, CRC(93654d2a) SHA1(3aa5a54b91867c03182e93a7f1607545503a33f7) ) - ROM_LOAD( "instantbingo_t24_10-07-86", 0x18000, 0x2000, CRC(de87ed0a) SHA1(4a26d93368c1a39dd38aabe450c34203101f0ef7) ) /* Found with this set, is it compatible or an operater swap? */ + ROM_LOAD( "instantbingo_t24_10-07-86", 0x18000, 0x2000, CRC(de87ed0a) SHA1(4a26d93368c1a39dd38aabe450c34203101f0ef7) ) /* Found with this set, is it compatible or an operator swap? */ ROM_END ROM_START( gepoker2 ) /* v50.02 with control dated 9-30-84 */ @@ -1509,7 +1421,7 @@ Rom board is "GEI, inc UVM-8B" with a date code of "8339" Contains 1 AM2732A eprom, 5 HN4827128G eproms, 1 MMI PAL16R4CN, 1 7474N -Battery (3V litium battery) backed up HM6117P-4 +Battery (3V lithium battery) backed up HM6117P-4 Roms labeled as: @@ -1539,6 +1451,12 @@ ROM_START( suprpokr ) /* Super Poker Version 10.19S BOBC. Rom board UMV-7C */ ROM_LOAD( "supr_pokr_10.19s_#1", 0x00000, 0x4000, CRC(50662b4d) SHA1(967161a755db43d2cfd5ce92e14c5284f1f1f8ad) ) ROM_LOAD( "supr_pokr_10.19s_#2", 0x08000, 0x4000, CRC(22b45aeb) SHA1(006c3072cc44c6fde9b4d15163dc70707bbd5a9c) ) ROM_RELOAD( 0x0c000, 0x4000 ) + + ROM_REGION( 0x0800, "nvram", 0 ) + ROM_LOAD( "suprpokr.nvram", 0x0000, 0x0800, CRC(0e716e23) SHA1(15e35bfbab9a6778834df1c85c25643010054cdb) ) + + ROM_REGION( 0x0008, "signature", 0 ) + ROM_LOAD( "suprpokr.sig", 0x0000, 0x0008, CRC(8f622afe) SHA1(8c1c8cee444c88211760a0f5c3adcfd887da5bb7) ) ROM_END ROM_START( suprpokra ) /* Super Poker Version 10.15S BOBC. Rom board UMV-7C */ @@ -1546,6 +1464,12 @@ ROM_START( suprpokra ) /* Super Poker Version 10.15S BOBC. Rom board UMV-7C */ ROM_LOAD( "supr_pokr_10.15s_#1", 0x00000, 0x4000, CRC(5cc7c1e0) SHA1(1cdca32c4df7227dab77574abe344b291741139e) ) ROM_LOAD( "supr_pokr_10.15s_#2", 0x08000, 0x4000, CRC(e47d6e2a) SHA1(9cabc42275dad8be6cd5b167e381ddb5bf08276d) ) ROM_RELOAD( 0x0c000, 0x4000 ) + + ROM_REGION( 0x0800, "nvram", 0 ) + ROM_LOAD( "suprpokr.nvram", 0x0000, 0x0800, CRC(0e716e23) SHA1(15e35bfbab9a6778834df1c85c25643010054cdb) ) + + ROM_REGION( 0x0008, "signature", 0 ) + ROM_LOAD( "suprpokr.sig", 0x0000, 0x0008, CRC(8f622afe) SHA1(8c1c8cee444c88211760a0f5c3adcfd887da5bb7) ) ROM_END ROM_START( suprpokrb ) /* Super Poker Version 10.10 BOBC. Rom board UMV-7C */ @@ -1553,6 +1477,12 @@ ROM_START( suprpokrb ) /* Super Poker Version 10.10 BOBC. Rom board UMV-7C */ ROM_LOAD( "supr_pokr_10.10_#1", 0x00000, 0x4000, CRC(8324471f) SHA1(c38b7a735ef06feea3e8d4ba6dd963e24d38c792) ) ROM_LOAD( "supr_pokr_10.10_#2", 0x08000, 0x4000, CRC(a82ca9c5) SHA1(3b0f4ad7d53370dc1f00dec696e993359147a496) ) ROM_RELOAD( 0x0c000, 0x4000 ) + + ROM_REGION( 0x0800, "nvram", 0 ) + ROM_LOAD( "suprpokr.nvram", 0x0000, 0x0800, CRC(0e716e23) SHA1(15e35bfbab9a6778834df1c85c25643010054cdb) ) + + ROM_REGION( 0x0008, "signature", 0 ) + ROM_LOAD( "suprpokr.sig", 0x0000, 0x0008, CRC(8f622afe) SHA1(8c1c8cee444c88211760a0f5c3adcfd887da5bb7) ) ROM_END @@ -1565,6 +1495,12 @@ ROM_START( reelfun ) /* v7.03 */ ROM_LOAD( "reelfun-3-phrase", 0x20000, 0x8000, CRC(199e36b0) SHA1(d9dfe39c9a4fca1169150f8941f8ebc499dfbaf5) ) ROM_LOAD( "reelfun-4-person", 0x28000, 0x8000, CRC(49b0710b) SHA1(a38b3251bcb8683d43bdb903036970140a9735e6) ) ROM_LOAD( "reelfun-5-song_title", 0x30000, 0x8000, CRC(cce01c45) SHA1(c484f5828928edf39335cedf21acab0b9e2a6881) ) + + ROM_REGION( 0x0800, "nvram", 0 ) + ROM_LOAD( "reelfun.nvram", 0x0000, 0x0800, CRC(fbb791ce) SHA1(0db77cbc42b5362b3d2ecde46a4289619e8f59a6) ) /* Defaults */ + + ROM_REGION( 0x0008, "signature", 0 ) // bytes 0x03 through 0x0a of each question ROM - to prevent ROM swaps + ROM_LOAD( "reelfun.sig", 0x0000, 0x0008, CRC(c8e944a3) SHA1(d34de9e3163ba61fa4e4f2264caff40434fcc9b0) ) ROM_END ROM_START( reelfun1 ) /* v7.01 */ @@ -1576,6 +1512,12 @@ ROM_START( reelfun1 ) /* v7.01 */ ROM_LOAD( "reelfun-3-phrase", 0x20000, 0x8000, CRC(199e36b0) SHA1(d9dfe39c9a4fca1169150f8941f8ebc499dfbaf5) ) ROM_LOAD( "reelfun-4-person", 0x28000, 0x8000, CRC(49b0710b) SHA1(a38b3251bcb8683d43bdb903036970140a9735e6) ) ROM_LOAD( "reelfun-5-song_title", 0x30000, 0x8000, CRC(cce01c45) SHA1(c484f5828928edf39335cedf21acab0b9e2a6881) ) + + ROM_REGION( 0x0800, "nvram", 0 ) + ROM_LOAD( "reelfun.nvram", 0x0000, 0x0800, CRC(fbb791ce) SHA1(0db77cbc42b5362b3d2ecde46a4289619e8f59a6) ) /* Defaults */ + + ROM_REGION( 0x0008, "signature", 0 ) // bytes 0x03 through 0x0a of each question ROM - to prevent ROM swaps + ROM_LOAD( "reelfun.sig", 0x0000, 0x0008, CRC(c8e944a3) SHA1(d34de9e3163ba61fa4e4f2264caff40434fcc9b0) ) ROM_END ROM_START( findout ) @@ -1590,6 +1532,12 @@ ROM_START( findout ) ROM_REGION( 0x0200, "gfx2", 0 ) ROM_LOAD( "82s147.bin", 0x0000, 0x0200, CRC(f3b663bb) SHA1(5a683951c8d3a2baac4b49e379d6e10e35465c8a) ) /* unknown */ + + ROM_REGION( 0x0800, "nvram", 0 ) + ROM_LOAD( "findout.nvram", 0x0000, 0x0800, CRC(b6950ffc) SHA1(ecc08904b208fb87c7a47d2f6081652405bf73b4) ) /* Defaults */ + + ROM_REGION( 0x0008, "signature", 0 ) // bytes 0x03 through 0x0a of each question ROM - to prevent ROM swaps + ROM_LOAD( "findout.sig", 0x0000, 0x0008, CRC(c8e944a3) SHA1(d34de9e3163ba61fa4e4f2264caff40434fcc9b0) ) ROM_END ROM_START( gt507uk ) @@ -1599,7 +1547,7 @@ ROM_START( gt507uk ) ROM_LOAD( "aerospace", 0x10000, 0x8000, CRC(cb555d46) SHA1(559ae05160d7893ff96311a2177eba039a4cf186) ) /* Also found in Series #11 set */ ROM_LOAD( "english_sport_4", 0x18000, 0x8000, CRC(6ae8a63d) SHA1(c6018141d8bbe0ed7619980bf7da89dd91d7fcc2) ) ROM_LOAD( "general_facts", 0x20000, 0x8000, CRC(f921f108) SHA1(fd72282df5cee0e6ab55268b40785b3dc8e3d65b) ) /* Also found in Series #11 set */ - ROM_LOAD( "horrors", 0x28000, 0x8000, CRC(5f7b262a) SHA1(047480d6bf5c6d0603d538b84c996bd226f07f77) ) /* Possiblely Series #13 rom */ + ROM_LOAD( "horrors", 0x28000, 0x8000, CRC(5f7b262a) SHA1(047480d6bf5c6d0603d538b84c996bd226f07f77) ) /* Possibly Series #13 rom */ ROM_LOAD( "pop_music", 0x30000, 0x8000, CRC(884fec7c) SHA1(b389216c17f516df4e15eee46246719dd4acb587) ) ROM_END @@ -1695,6 +1643,9 @@ ROM_START( gtsers15 ) /* v5.06, From a TRIV3D romboard */ ROM_LOAD( "nfl_football", 0x28000, 0x8000, CRC(42eb2849) SHA1(c24e681a508ef8350f7e5d50aea2c31cf70ce5c9) ) ROM_LOAD( "adult_sex_6", 0x30000, 0x8000, CRC(d66f35f7) SHA1(81b56756230b27b0903d0c5df30439726526afe2) ) /* Missing unknown question rom (and alternate question?) */ + + ROM_REGION( 0x0008, "signature", 0 ) // bytes 0x03 through 0x0a of each question ROM - to prevent ROM swaps + ROM_LOAD( "gtsers15.sig", 0x0000, 0x0008, CRC(c8e944a3) SHA1(d34de9e3163ba61fa4e4f2264caff40434fcc9b0) ) ROM_END ROM_START( gt103a1 ) /* Need to verify which series these belong to */ @@ -1790,6 +1741,27 @@ ROM_START( quiz211 ) ROM_LOAD( "pal10l8cn.bin", 0x0000, 0x002c, CRC(86095226) SHA1(e7496efbd5ca240f0df2dfa5627402342c7f5384) ) ROM_END +ROM_START( bigjoke ) /* TRIV3D PCB, stickered THE JOKE 11/87 */ + ROM_REGION( 0x38000, "maincpu", 0 ) + ROM_LOAD( "joke_cont_128", 0x00000, 0x4000, CRC(acb4355f) SHA1(0fc9a218e94fc49297bd11547fb193d1f91ce90c) ) + ROM_LOAD( "joke_2764", 0x08000, 0x2000, CRC(8a7ac263) SHA1(6f9a18b7f38e83cc2d1f1911e3b01ada7df4d2ba) ) /* banked */ + ROM_LOAD( "joke_drty_nsty_1012", 0x10000, 0x8000, CRC(e3fcd0e3) SHA1(fae1ddfb244e5c84e9ba6d4b90bd265365a4f662) ) /* banked ROMs for solution data */ + ROM_LOAD( "joke_fams_folk_1012", 0x18000, 0x8000, CRC(08eb35f2) SHA1(0dba706750a9276dac9976eb07f64ecf4a42e658) ) + ROM_LOAD( "joke_jmbl_joke_1012", 0x20000, 0x8000, CRC(26daf757) SHA1(76560bf437b4ee851f075b30e79df563367830cf) ) + ROM_LOAD( "joke_racl_ethn_1012", 0x28000, 0x8000, CRC(ca814fa9) SHA1(0c2ac15568bd64c282f257089305309ef7f91411) ) + ROM_LOAD( "joke_wrkg_wrld_1012", 0x30000, 0x8000, CRC(f4b0fa76) SHA1(70b4a29d928729da52948c12e55473ecf83b3daa) ) + + ROM_REGION( 0x0800, "nvram", 0 ) + ROM_LOAD( "bigjoke.nvram", 0x0000, 0x0800, CRC(89e0e325) SHA1(c2398c64f938e8ed036e72a5ba0b703513f31a6d) ) + + ROM_REGION( 0x0400, "pld", 0 ) // probably one of the two GALs provides the "signature" + ROM_LOAD( "gal16v8", 0x0000, 0x0117, NO_DUMP ) /* read protected */ + ROM_LOAD( "gal18v8", 0x0200, 0x0117, NO_DUMP ) /* read protected */ + + ROM_REGION( 0x0008, "signature", 0 ) // bytes 0x03 through 0x0a of each question ROM - to prevent ROM swaps + ROM_LOAD( "bigjoke.sig", 0x0000, 0x0008, CRC(bfa5388b) SHA1(876bf954116fcc14d0bed017a9bec42038c5f89a) ) +ROM_END + ROM_START( sexappl ) /* TRIV3D PCB, stickered SEX APPL 6.02 5/92 */ ROM_REGION( 0x38000, "maincpu", 0 ) ROM_LOAD( "6.02_cont", 0x00000, 0x4000, CRC(63ad3593) SHA1(fd93a71b82ef04757d79485ca4c7e306b2983c76) ) @@ -1802,6 +1774,13 @@ ROM_START( sexappl ) /* TRIV3D PCB, stickered SEX APPL 6.02 5/92 */ ROM_REGION( 0x0800, "nvram", 0 ) ROM_LOAD( "sexappl.nvram", 0x0000, 0x0800, CRC(be65737c) SHA1(5b8a603a9ddecdad4aaef0b9e8ef373885b236c0) ) /* Defaults but with card dispenser OFF! */ + + ROM_REGION( 0x0400, "pld", 0 ) // probably one of the two GALs provides the "signature" + ROM_LOAD( "gal16v8", 0x0000, 0x0117, NO_DUMP ) /* read protected */ + ROM_LOAD( "gal18v8", 0x0200, 0x0117, NO_DUMP ) /* read protected */ + + ROM_REGION( 0x0008, "signature", 0 ) // bytes 0x03 through 0x0a of each question ROM - to prevent ROM swaps + ROM_LOAD( "sexappl.sig", 0x0000, 0x0008, CRC(c8e944a3) SHA1(d34de9e3163ba61fa4e4f2264caff40434fcc9b0) ) ROM_END /* @@ -1859,6 +1838,12 @@ ROM_START( geimulti ) ROM_LOAD( "entr#1", 0x60000, 0x8000, CRC(caceaa7b) SHA1(c51f10f5acd3d3fedce43103b9f11d006139043c) ) ROM_LOAD( "grph", 0x68000, 0x8000, CRC(25e265db) SHA1(6e184309ee67dbe7930570b135ace09eeb1eb333) ) + ROM_REGION( 0x0800, "nvram", 0 ) + ROM_LOAD( "geimulti.nvram", 0x0000, 0x0800, CRC(232bbad1) SHA1(23a4011ad3b322cbda40859a1619dc1f5472fdfc) ) /* Defaults */ + + // strangely checks the signature only for questions "fact#1", "adltsex#1", "nfl#1" and "entr#1" + ROM_REGION( 0x0008, "signature", 0 ) // bytes 0x03 through 0x0a of the listed question ROMs - to prevent ROM swaps + ROM_LOAD( "geimulti.sig", 0x0000, 0x0008, CRC(c8e944a3) SHA1(d34de9e3163ba61fa4e4f2264caff40434fcc9b0) ) ROM_END ROM_START( sprtauth ) @@ -1877,78 +1862,98 @@ ROM_START( sprtauth ) ROM_LOAD( "sprt-auth-supr-bowl.bank9", 0x40000, 0x8000, CRC(3a548fe5) SHA1(6ad35516651a8a878b512cb3eff697952e194dd0) ) ROM_LOAD( "sprt-auth-rev1-kb.grph", 0x68000, 0x8000, CRC(c4f734ac) SHA1(028217fe6d7be75f75e9f67b665d465c729d2995) ) + ROM_REGION( 0x0800, "nvram", 0 ) + ROM_LOAD( "sprtauth.nvram", 0x0000, 0x0800, CRC(969869f9) SHA1(a5a7b679e99255650dc8ea12d2b36e97e6296aae) ) /* Defaults but with card dispenser OFF! */ + + ROM_REGION( 0x0008, "signature", 0 ) // bytes 0x03 through 0x0a of each question ROM - to prevent ROM swaps + ROM_LOAD( "sprtauth.sig", 0x0000, 0x0008, CRC(c8e944a3) SHA1(d34de9e3163ba61fa4e4f2264caff40434fcc9b0) ) ROM_END -DRIVER_INIT_MEMBER(gei_state,setbank) +DRIVER_INIT_MEMBER(gei_state, setbank) +{ + m_rombank->set_base(memregion("maincpu")->base() + 0x2000); +} + +DRIVER_INIT_MEMBER(gei_state, bank2k) +{ + m_rombank->configure_entries(0, 10, memregion("maincpu")->base() + 0x10000, 0x2000); + m_rombank->set_entry(0); +} + +DRIVER_INIT_MEMBER(gei_state, bank8k) { - membank("bank1")->set_base(memregion("maincpu")->base() + 0x2000); + m_rombank->configure_entries(0, 6, memregion("maincpu")->base() + 0x8000, 0x8000); + m_rombank->set_entry(0); } -DRIVER_INIT_MEMBER(gei_state,geimulti) +DRIVER_INIT_MEMBER(gei_state, geimulti) { - membank("bank1")->set_base(memregion("bank")->base() + 0x0000); + m_rombank->configure_entries(0, 14, memregion("bank")->base(), 0x8000); + m_rombank->set_entry(0); } -GAME( 1982, jokpoker, 0, gselect, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Joker Poker (Version 16.03B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1983, jokpokera, jokpoker, jokpokera, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Joker Poker (Version 16.03BI 5-10-85, Joker Poker ICB 9-30-86)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1983, jokpokerb, jokpoker, jokpokera, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Joker Poker (Version 16.04BI 10-19-88, Joker Poker ICB 9-30-86)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1983, jokpokerc, jokpoker, jokpokera, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Joker Poker (Version 16.03BI 5-10-85, Poker No Raise ICB 9-30-86)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1982, superbwl, 0, gselect, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Super Bowl (Version 16.03B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1982, gs4002, 0, gselect, gselect, gei_state, 0, ROT0, "Greyhound Electronics", "Selection (Version 40.02TMB, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1982, gs4002a, gs4002, gselect, gselect, gei_state, 0, ROT0, "Greyhound Electronics", "Selection (Version 40.02TMB, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1982, amuse, 0, amuse, gepoker, gei_state, 0, ROT0, "Greyhound Electronics", "Amuse (Version 50.08 IBA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1982, amuse1, amuse, amuse1, gepoker, gei_state, 0, ROT0, "Greyhound Electronics", "Amuse (Version 30.08 IBA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1983, amuse1a, amuse, amuse1, gepoker, gei_state, 0, ROT0, "Greyhound Electronics", "Amuse (Version 30.08A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1984, gepoker, 0, gepoker, gepoker, gei_state, 0, ROT0, "Greyhound Electronics", "Poker (Version 50.02 ICB, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gepoker1, gepoker, gepoker, gepoker, gei_state, 0, ROT0, "Greyhound Electronics", "Poker (Version 50.02 ICB, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gepoker2, gepoker, gepoker, gepoker, gei_state, 0, ROT0, "Greyhound Electronics", "Poker (Version 50.02 ICB, set 3)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gepoker3, gepoker, gepoker, gepoker, gei_state, 0, ROT0, "Greyhound Electronics", "Poker (Version 50.02 ICB, set 4)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1984, gtsers1, 0, getrivia, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers2, gtsers1, getrivia, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers3, gtsers1, getrivia, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 3)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers4, gtsers1, getrivia, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 4)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers5, gtsers1, getrivia, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 5)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers7, gtsers1, getrivia, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 7)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsersa, gtsers1, getrivia, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Alt revision questions set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsersb, gtsers1, getrivia, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Alt revision questions set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers8, 0, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 8)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers8a, gtsers8, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 8 Alt Question Rom)",MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers9, gtsers8, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 9)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers10, gtsers8, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 10)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers11, gtsers8, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 11)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers11a, gtsers8, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 11 Alt Question Rom)",MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gtsers12, gtsers8, findout, gt103, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 12)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1986, gtsers14, gtsers8, findout, gt103, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 14)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1986, gtsers15, gtsers8, findout, gt103, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Questions Series 15)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gt103a1, gtsers8, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Unsorted question roms)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gt103aa, gtsers8, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Version 1.03a Alt questions 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gt103ab, gtsers8, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Version 1.03a Alt questions 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1984, gt103asx, gtsers8, findout, getrivia, gei_state, 0, ROT0, "Greyhound Electronics", "Trivia (Version 1.03a Sex questions)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1985, sextriv1, 0, getrivia, sextriv1, gei_state, 0, ROT0, "Kinky Kit and Game Co.", "Sexual Trivia (Version 1.02SB, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1985, sextriv2, sextriv1, getrivia, sextriv1, gei_state, 0, ROT0, "Kinky Kit and Game Co.", "Sexual Trivia (Version 1.02SB, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1986, gt507uk, 0, findout, gt507uk, gei_state, 0, ROT0, "Grayhound Electronics", "Trivia (UK Version 5.07)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1986, quiz, 0, findout, quiz, gei_state, 0, ROT0, "Elettronolo", "Quiz (Revision 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1986, quizvid, 0, quizvid, quiz, gei_state, 0, ROT0, "bootleg", "Video Quiz", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1986, reelfun, 0, findout, reelfun, gei_state, 0, ROT0, "Grayhound Electronics", "Reel Fun (Version 7.03)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1986, reelfun1, reelfun, findout, reelfun, gei_state, 0, ROT0, "Grayhound Electronics", "Reel Fun (Version 7.01)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1987, findout, 0, findout, findout, gei_state, 0, ROT0, "Elettronolo", "Find Out (Version 4.04)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1986, suprpokr, 0, suprpokr, suprpokr, gei_state, 0, ROT0, "Grayhound Electronics", "Super Poker (Version 10.19S)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1986, suprpokra, suprpokr, suprpokr, suprpokr, gei_state, 0, ROT0, "Grayhound Electronics", "Super Poker (Version 10.15S)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1986, suprpokrb, suprpokr, suprpokr, suprpokr, gei_state, 0, ROT0, "Grayhound Electronics", "Super Poker (Version 10.10)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1991, quiz211, 0, findout, quiz, gei_state, 0, ROT0, "Elettronolo", "Quiz (Revision 2.11)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1992, sexappl, 0, findout, sexappl, gei_state, 0, ROT0, "Grayhound Electronics", "Sex Appeal (Version 6.02)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1992, geimulti, 0, geimulti, geimulti, gei_state, geimulti, ROT0, "Grayhound Electronics", "GEI Multi Game", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1992, sprtauth, 0, sprtauth, sprtauth, gei_state, geimulti, ROT0, "Classic Games", "Sports Authority", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +GAME( 1982, jokpoker, 0, gselect, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Joker Poker (Version 16.03B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1983, jokpokera, jokpoker, jokpokera, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Joker Poker (Version 16.03BI 5-10-85, Joker Poker ICB 9-30-86)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1983, jokpokerb, jokpoker, jokpokera, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Joker Poker (Version 16.04BI 10-19-88, Joker Poker ICB 9-30-86)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1983, jokpokerc, jokpoker, jokpokera, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Joker Poker (Version 16.03BI 5-10-85, Poker No Raise ICB 9-30-86)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1982, superbwl, 0, gselect, gselect, gei_state, setbank, ROT0, "Greyhound Electronics", "Super Bowl (Version 16.03B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1982, gs4002, 0, gselect, gselect, gei_state, bank2k, ROT0, "Greyhound Electronics", "Selection (Version 40.02TMB, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1982, gs4002a, gs4002, gselect, gselect, gei_state, bank2k, ROT0, "Greyhound Electronics", "Selection (Version 40.02TMB, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1982, amuse, 0, amuse, gepoker, gei_state, bank2k, ROT0, "Greyhound Electronics", "Amuse (Version 50.08 IBA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1982, amuse1, amuse, amuse1, gepoker, gei_state, bank2k, ROT0, "Greyhound Electronics", "Amuse (Version 30.08 IBA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1983, amuse1a, amuse, amuse1, gepoker, gei_state, bank2k, ROT0, "Greyhound Electronics", "Amuse (Version 30.08A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1984, gepoker, 0, gepoker, gepoker, gei_state, bank2k, ROT0, "Greyhound Electronics", "Poker (Version 50.02 ICB, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gepoker1, gepoker, gepoker, gepoker, gei_state, bank2k, ROT0, "Greyhound Electronics", "Poker (Version 50.02 ICB, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gepoker2, gepoker, gepoker, gepoker, gei_state, bank2k, ROT0, "Greyhound Electronics", "Poker (Version 50.02 ICB, set 3)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gepoker3, gepoker, gepoker, gepoker, gei_state, bank2k, ROT0, "Greyhound Electronics", "Poker (Version 50.02 ICB, set 4)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1984, gtsers1, 0, getrivia, getrivia, gei_state, bank2k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers2, gtsers1, getrivia, getrivia, gei_state, bank2k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers3, gtsers1, getrivia, getrivia, gei_state, bank2k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 3)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers4, gtsers1, getrivia, getrivia, gei_state, bank2k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 4)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers5, gtsers1, getrivia, getrivia, gei_state, bank2k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 5)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers7, gtsers1, getrivia, getrivia, gei_state, bank2k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 7)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsersa, gtsers1, getrivia, getrivia, gei_state, bank2k, ROT0, "Greyhound Electronics", "Trivia (Alt revision questions set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsersb, gtsers1, getrivia, getrivia, gei_state, bank2k, ROT0, "Greyhound Electronics", "Trivia (Alt revision questions set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers8, 0, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 8)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers8a, gtsers8, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 8 Alt Question Rom)",MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers9, gtsers8, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 9)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers10, gtsers8, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 10)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers11, gtsers8, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 11)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers11a, gtsers8, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 11 Alt Question Rom)",MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gtsers12, gtsers8, findout, gt103, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 12)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, gtsers14, gtsers8, findout, gt103, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 14)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, gtsers15, gtsers8, findout, gt103, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Questions Series 15)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gt103a1, gtsers8, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Unsorted question roms)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gt103aa, gtsers8, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Version 1.03a Alt questions 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gt103ab, gtsers8, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Version 1.03a Alt questions 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, gt103asx, gtsers8, findout, getrivia, gei_state, bank8k, ROT0, "Greyhound Electronics", "Trivia (Version 1.03a Sex questions)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1985, sextriv1, 0, getrivia, sextriv1, gei_state, bank2k, ROT0, "Kinky Kit and Game Co.", "Sexual Trivia (Version 1.02SB, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1985, sextriv2, sextriv1, getrivia, sextriv1, gei_state, bank2k, ROT0, "Kinky Kit and Game Co.", "Sexual Trivia (Version 1.02SB, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1986, gt507uk, 0, findout, gt507uk, gei_state, bank8k, ROT0, "Grayhound Electronics", "Trivia (UK Version 5.07)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1986, quiz, 0, findout, quiz, gei_state, bank8k, ROT0, "Elettronolo", "Quiz (Revision 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1986, quizvid, 0, quizvid, quiz, gei_state, bank8k, ROT0, "bootleg", "Video Quiz", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1986, reelfun, 0, findout, reelfun, gei_state, bank8k, ROT0, "Grayhound Electronics", "Reel Fun (Version 7.03)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, reelfun1, reelfun, findout, reelfun, gei_state, bank8k, ROT0, "Grayhound Electronics", "Reel Fun (Version 7.01)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1987, findout, 0, findout, findout, gei_state, bank8k, ROT0, "Elettronolo", "Find Out (Version 4.04)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1986, suprpokr, 0, suprpokr, suprpokr, gei_state, 0, ROT0, "Grayhound Electronics", "Super Poker (Version 10.19S)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, suprpokra, suprpokr, suprpokr, suprpokr, gei_state, 0, ROT0, "Grayhound Electronics", "Super Poker (Version 10.15S)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1986, suprpokrb, suprpokr, suprpokr, suprpokr, gei_state, 0, ROT0, "Grayhound Electronics", "Super Poker (Version 10.10)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1987, bigjoke, 0, findout, bigjoke, gei_state, bank8k, ROT0, "Grayhound Electronics", "The Big Joke (Version 0.00)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1991, quiz211, 0, findout, quiz, gei_state, bank8k, ROT0, "Elettronolo", "Quiz (Revision 2.11)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1992, sexappl, 0, findout, sexappl, gei_state, bank8k, ROT0, "Grayhound Electronics", "Sex Appeal (Version 6.02)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) + +GAME( 1992, geimulti, 0, sprtauth, geimulti, gei_state, geimulti, ROT0, "Grayhound Electronics", "GEI Multi Game", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, sprtauth, 0, sprtauth, sprtauth, gei_state, geimulti, ROT0, "Classic Games", "Sports Authority", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/gimix.cpp b/src/mame/drivers/gimix.cpp index abab8c71642..4467b925b56 100644 --- a/src/mame/drivers/gimix.cpp +++ b/src/mame/drivers/gimix.cpp @@ -173,15 +173,13 @@ private: static ADDRESS_MAP_START( gimix_banked_mem, AS_PROGRAM, 8, gimix_state) AM_RANGE(0x00000, 0x0dfff) AM_RAMBANK("lower_ram") - AM_RANGE(0x0e000, 0x0e000) AM_DEVREADWRITE("acia1",acia6850_device,status_r,control_w) - AM_RANGE(0x0e001, 0x0e001) AM_DEVREADWRITE("acia1",acia6850_device,data_r,data_w) - AM_RANGE(0x0e004, 0x0e004) AM_DEVREADWRITE("acia2",acia6850_device,status_r,control_w) - AM_RANGE(0x0e005, 0x0e005) AM_DEVREADWRITE("acia2",acia6850_device,data_r,data_w) + AM_RANGE(0x0e000, 0x0e001) AM_DEVREADWRITE("acia1", acia6850_device, read, write) + AM_RANGE(0x0e004, 0x0e005) AM_DEVREADWRITE("acia2", acia6850_device, read, write) //AM_RANGE(0x0e018, 0x0e01b) AM_READWRITE(fdc_r, fdc_w) // FD1797 FDC (PIO) AM_RANGE(0x0e100, 0x0e1ff) AM_RAM //AM_RANGE(0x0e200, 0x0e20f) // 9511A / 9512 Arithmetic Processor - AM_RANGE(0x0e210, 0x0e21f) AM_DEVREADWRITE("timer",ptm6840_device,read,write) - AM_RANGE(0x0e220, 0x0e23f) AM_DEVREADWRITE("rtc",mm58167_device,read,write) + AM_RANGE(0x0e210, 0x0e21f) AM_DEVREADWRITE("timer", ptm6840_device, read, write) + AM_RANGE(0x0e220, 0x0e23f) AM_DEVREADWRITE("rtc", mm58167_device, read, write) AM_RANGE(0x0e240, 0x0e3af) AM_RAM AM_RANGE(0x0e3b0, 0x0e3b3) AM_READWRITE(dma_r, dma_w) // DMA controller (custom?) AM_RANGE(0x0e3b4, 0x0e3b7) AM_READWRITE(fdc_r, fdc_w) // FD1797 FDC @@ -542,7 +540,7 @@ SLOT_INTERFACE_END MCFG_DEVICE_ADD(tag, ADDRESS_MAP_BANK, 0) \ MCFG_DEVICE_PROGRAM_MAP(gimix_banked_mem) \ MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) \ -MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) \ +MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) \ MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) static MACHINE_CONFIG_START( gimix ) diff --git a/src/mame/drivers/gladiatr.cpp b/src/mame/drivers/gladiatr.cpp index 076e64d772a..6f8e32b0e9e 100644 --- a/src/mame/drivers/gladiatr.cpp +++ b/src/mame/drivers/gladiatr.cpp @@ -224,7 +224,7 @@ WRITE8_MEMBER(gladiatr_state::gladiator_int_control_w) } /* YM2203 IRQ */ -WRITE_LINE_MEMBER(gladiatr_state::gladiator_ym_irq) +WRITE_LINE_MEMBER(gladiatr_state_base::ym_irq) { /* NMI IRQ is not used by gladiator sound program */ m_subcpu->set_input_line(INPUT_LINE_NMI, state ? ASSERT_LINE : CLEAR_LINE); @@ -241,24 +241,38 @@ WRITE8_MEMBER(gladiatr_state::gladiator_adpcm_w) m_msm->vclk_w (BIT(data, 4)); // bit 4 } -WRITE8_MEMBER(gladiatr_state::gladiator_cpu_sound_command_w) +WRITE8_MEMBER(ppking_state::ppking_adpcm_w) +{ + // bit 6 = bank offset + //membank("bank2")->set_entry((data & 0x40) ? 1 : 0); + + m_msm->data_w(data); // bit 0..3 + m_msm->reset_w(BIT(data, 5)); // bit 5 + m_msm->vclk_w (BIT(data, 4)); // bit 4 +} + +WRITE8_MEMBER(ppking_state::cpu2_irq_ack_w) +{ + m_subcpu->set_input_line(0, CLEAR_LINE); +} + +WRITE8_MEMBER(gladiatr_state_base::adpcm_command_w) { m_soundlatch->write(space,0,data); m_audiocpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); } -READ8_MEMBER(gladiatr_state::gladiator_cpu_sound_command_r) +READ8_MEMBER(gladiatr_state_base::adpcm_command_r) { m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); return m_soundlatch->read(space,0); } -WRITE_LINE_MEMBER(gladiatr_state::flipscreen_w) +WRITE_LINE_MEMBER(gladiatr_state_base::flipscreen_w) { flip_screen_set(state); } - #if 1 /* !!!!! patch to IRQ timing for 2nd CPU !!!!! */ WRITE8_MEMBER(gladiatr_state::gladiatr_irq_patch_w) @@ -376,73 +390,233 @@ INPUT_CHANGED_MEMBER(gladiatr_state::p2_s2) READ8_MEMBER(ppking_state::ppking_f1_r) { - return machine().rand(); + return 0xff; } -READ8_MEMBER(ppking_state::ppking_f6a3_r) +/********************************** + * + * Ping Pong King MCU simulation + * + * 0x8ad = + * 0x8f6 = IO check (must return 0x40) + * + **********************************/ + +//#include "debugger.h" + +inline bool ppking_state::mcu_parity_check() { - if (space.device().safe_pcbase() == 0x8e) - m_nvram[0x6a3] = 1; + int i; + uint8_t res = 0; + + for(i=0;i<8;i++) + { + if(m_mcu[0].rxd & (1 << i)) + res++; + } + + if(res % 2) + return false; - return m_nvram[0x6a3]; + return true; } -WRITE8_MEMBER(ppking_state::ppking_qx0_w) +inline void ppking_state::mcu_input_check() { - if(!offset) + if(m_mcu[0].txd == 0x41) + { + m_mcu[0].state = 1; + //m_mcu[0].packet_type = 0; + } + else if(m_mcu[0].txd == 0x42) { - m_data2 = data; - m_flag2 = 1; + m_mcu[0].state = 2; + //m_mcu[0].packet_type = 0; + //machine().debug_break(); + } + else if(m_mcu[0].txd == 0x44) + { + m_mcu[0].state = 3; } } -WRITE8_MEMBER(ppking_state::ppking_qx1_w) +READ8_MEMBER(ppking_state::ppking_qx0_r) { - if(!offset) + // status + if(offset == 1) + return 1; + + if(m_mcu[0].rst) { - m_data1 = data; - m_flag1 = 1; + switch(m_mcu[0].state) + { + case 1: + { + m_mcu[0].packet_type^=1; + + if(m_mcu[0].packet_type & 1) + { + m_mcu[0].rxd = ((ioport("DSW3")->read()) & 0x9f) | 0x20; + } + else + { + m_mcu[0].rxd = ((ioport("SYSTEM")->read()) & 0x9f); + } + + break; + } + + case 2: + { + m_mcu[0].packet_type^=1; + if(m_mcu[0].packet_type & 1) + { + // Host wants this from time to time, otherwise huge input lag happens periodically (protection?) + m_mcu[0].rxd = 0x17; + } + else + { + m_mcu[0].rxd = ((ioport("P1")->read()) & 0x3f); + m_mcu[0].rxd |= ((ioport("SYSTEM")->read()) & 0x80); + } + + break; + } + + case 3: + { + m_mcu[0].packet_type^=1; + if(m_mcu[0].packet_type & 1) + { + // same as above for player 2 + m_mcu[0].rxd = 0x17; + } + else + { + m_mcu[0].rxd = ((ioport("P2")->read()) & 0x3f); + m_mcu[0].rxd |= ((ioport("SYSTEM")->read()) & 0x80); + } + + break; + } + } + + if(mcu_parity_check() == false) + m_mcu[0].rxd |= 0x40; } + + //printf("%04x rst %d\n",m_maincpu->pc(),m_mcu[0].rst); + + return m_mcu[0].rxd; } -WRITE8_MEMBER(ppking_state::ppking_qx2_w) +WRITE8_MEMBER(ppking_state::ppking_qx0_w) { + if(offset == 1) + { + switch(data) + { + case 0: + m_mcu[0].rxd = 0x40; + m_mcu[0].rst = 0; + m_mcu[0].state = 0; + break; + case 1: + /* + status codes: + 0x06 sub NG IOX2 + 0x05 sub NG IOX1 + 0x04 sub NG CIOS + 0x03 sub NG OPN + 0x02 sub NG ROM + 0x01 sub NG RAM + 0x00 ok + */ + m_mcu[0].rxd = 0x40; + m_mcu[0].rst = 0; + break; + case 2: + m_mcu[0].rxd = ((ioport("DSW2")->read() & 0x1f) << 2); + m_mcu[0].rst = 0; + break; + case 3: + mcu_input_check(); + m_mcu[0].rst = 1; + break; + + default: + printf("%02x %02x\n",offset,data); + break; + } + } + else + { + m_mcu[0].txd = data; + + m_mcu[1].rst = 0; + m_soundlatch2->write(space, 0, data & 0xff); + + mcu_input_check(); + + } } -WRITE8_MEMBER(ppking_state::ppking_qx3_w) +WRITE8_MEMBER(ppking_state::ppking_qx1_w) { + if(offset == 1) + { + if(data == 0xf0) + m_mcu[1].rst = 1; + } } -READ8_MEMBER(ppking_state::ppking_qx0_r) +WRITE8_MEMBER(ppking_state::ppking_qx3_w) { - if (!offset) - return m_data1; - else - return m_flag2; } + READ8_MEMBER(ppking_state::ppking_qx1_r) { - if (!offset) - return m_data2; - else - return m_flag1; + // status + if(offset == 1) + return 1; + + if(m_mcu[1].rst == 1) + return 0x40; + + return m_soundlatch2->read(space,0); } -READ8_MEMBER(ppking_state::ppking_qx2_r) +READ8_MEMBER(ppking_state::ppking_qx3_r) { - return machine().rand(); + if(offset == 1) + return 1; + + return 0; } -READ8_MEMBER(ppking_state::ppking_qx3_r) +// serial communication with another board (COMU in service mode) +// NMI is used to acquire data from the other board, +// either sent via 1->0 poll of the 0xc003 port or by reading 0xc0c0 (former more likely) +READ8_MEMBER(ppking_state::ppking_qxcomu_r) { - return machine().rand()&0xf; + if(offset == 1) + return 1; + + return 0; +} + +WRITE8_MEMBER(ppking_state::ppking_qxcomu_w) +{ + // ... } MACHINE_RESET_MEMBER(ppking_state, ppking) { - m_data1 = m_data2 = 0; - m_flag1 = m_flag2 = 1; + // yes, it expects to read DSW1 without sending commands first ... + m_mcu[0].rxd = (ioport("DSW1")->read() & 0x1f) << 2;; + m_mcu[0].rst = 0; + m_mcu[0].state = 0; } static ADDRESS_MAP_START( ppking_cpu1_map, AS_PROGRAM, 8, ppking_state ) @@ -458,25 +632,27 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( ppking_cpu3_map, AS_PROGRAM, 8, ppking_state ) - AM_RANGE(0x2000, 0x2fff) AM_ROM - AM_RANGE(0xc000, 0xffff) AM_ROM + AM_RANGE(0x1000, 0x1fff) AM_WRITE(ppking_adpcm_w) + AM_RANGE(0x2000, 0x2fff) AM_READ(adpcm_command_r) + AM_RANGE(0x8000, 0xffff) AM_ROM AM_WRITENOP ADDRESS_MAP_END static ADDRESS_MAP_START( ppking_cpu1_io, AS_IO, 8, ppking_state ) // ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0xc000, 0xc000) AM_WRITE(spritebuffer_w) - AM_RANGE(0xc004, 0xc004) AM_NOP // WRITE(ppking_irq_patch_w) + AM_RANGE(0xc000, 0xc007) AM_DEVWRITE("mainlatch", ls259_device, write_d0) +// AM_RANGE(0xc004, 0xc004) AM_NOP // WRITE(ppking_irq_patch_w) AM_RANGE(0xc09e, 0xc09f) AM_READ(ppking_qx0_r) AM_WRITE(ppking_qx0_w) - AM_RANGE(0xc0bf, 0xc0bf) AM_NOP + AM_RANGE(0xc0bf, 0xc0bf) AM_NOP // watchdog + AM_RANGE(0xc0c0, 0xc0c1) AM_READ(ppking_qxcomu_r) AM_WRITE(ppking_qxcomu_w) ADDRESS_MAP_END static ADDRESS_MAP_START( ppking_cpu2_io, AS_IO, 8, ppking_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x01) AM_DEVREADWRITE("ymsnd", ym2203_device, read, write) AM_RANGE(0x20, 0x21) AM_READ(ppking_qx1_r) AM_WRITE(ppking_qx1_w) - AM_RANGE(0x40, 0x40) AM_READNOP - AM_RANGE(0x60, 0x61) AM_READWRITE(ppking_qx2_r,ppking_qx2_w) + AM_RANGE(0x40, 0x40) AM_WRITE(cpu2_irq_ack_w) AM_RANGE(0x80, 0x81) AM_READWRITE(ppking_qx3_r,ppking_qx3_w) + AM_RANGE(0xe0, 0xe0) AM_WRITE(adpcm_command_w) ADDRESS_MAP_END @@ -501,8 +677,8 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( gladiatr_cpu3_map, AS_PROGRAM, 8, gladiatr_state ) AM_RANGE(0x1000, 0x1fff) AM_WRITE(gladiator_adpcm_w) - AM_RANGE(0x2000, 0x2fff) AM_READ(gladiator_cpu_sound_command_r) - AM_RANGE(0x4000, 0xffff) AM_ROMBANK("bank2") + AM_RANGE(0x2000, 0x2fff) AM_READ(adpcm_command_r) + AM_RANGE(0x4000, 0xffff) AM_ROMBANK("bank2") AM_WRITENOP ADDRESS_MAP_END @@ -521,10 +697,96 @@ static ADDRESS_MAP_START( gladiatr_cpu2_io, AS_IO, 8, gladiatr_state ) AM_RANGE(0x60, 0x61) AM_DEVREADWRITE("cctl", upi41_cpu_device, upi41_master_r, upi41_master_w) AM_RANGE(0x80, 0x81) AM_DEVREADWRITE("ccpu", upi41_cpu_device, upi41_master_r, upi41_master_w) AM_RANGE(0xa0, 0xa7) AM_DEVWRITE("filtlatch", ls259_device, write_d0) - AM_RANGE(0xe0, 0xe0) AM_WRITE(gladiator_cpu_sound_command_w) + AM_RANGE(0xe0, 0xe0) AM_WRITE(adpcm_command_w) ADDRESS_MAP_END +static INPUT_PORTS_START( ppking ) + PORT_START("P1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) + PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("P2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("SYSTEM") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 ) + PORT_DIPNAME( 0x04, 0x00, "SYSTEM" ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x04, DEF_STR( On ) ) + PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x08, DEF_STR( On ) ) + PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x10, DEF_STR( On ) ) + PORT_BIT( 0x60, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_IMPULSE(2) + + PORT_START("DSW1") + PORT_DIPNAME( 0x03, 0x03, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:7,6") + PORT_DIPSETTING( 0x03, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x02, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x01, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) + PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "SW1:5" ) + PORT_DIPNAME( 0x08, 0x08, "VS Mode (link)" ) PORT_DIPLOCATION("SW1:4") // unemulated + PORT_DIPSETTING( 0x08, DEF_STR( No ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) + PORT_DIPNAME( 0x10, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) + PORT_DIPSETTING( 0x10, DEF_STR( No ) ) + PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("DSW2") + // TODO: coinage not working (controlled by MCU) + PORT_DIPNAME( 0x03, 0x00, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW2:8,7") + PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x01, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x02, DEF_STR( 1C_4C ) ) + PORT_DIPSETTING( 0x03, DEF_STR( 1C_5C ) ) + PORT_DIPNAME( 0x0c, 0x00, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW2:6,5") + PORT_DIPSETTING( 0x00, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x04, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x08, DEF_STR( 4C_1C ) ) + PORT_DIPSETTING( 0x0c, DEF_STR( 5C_1C ) ) + PORT_DIPNAME( 0x10, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW2:4") + PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x10, DEF_STR( Cocktail ) ) + PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("DSW3") + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Free_Play ) ) PORT_DIPLOCATION("SW3:1") + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x01, DEF_STR( Yes ) ) + // Round -> Normal/Round Free in manual, allows player to continue playing even if he loses + PORT_DIPNAME( 0x02, 0x00, "Win Round even when losing (Cheat)" ) PORT_DIPLOCATION("SW3:2") + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x02, DEF_STR( Yes ) ) + // Happens at reset + PORT_DIPNAME( 0x04, 0x00, "Backup RAM Clear" ) PORT_DIPLOCATION("SW3:3") + PORT_DIPSETTING( 0x04, DEF_STR( Yes ) ) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPUNUSED_DIPLOC( 0x08, 0x00, "SW3:4" ) + PORT_DIPNAME( 0x10, 0x00, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION("SW3:5") + PORT_DIPSETTING( 0x10, DEF_STR( Yes ) ) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_BIT( 0x60, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_SERVICE_DIPLOC( 0x80, IP_ACTIVE_HIGH, "SW3:8" ) +INPUT_PORTS_END + static INPUT_PORTS_START( gladiatr ) PORT_START("DSW1") /* (8741-0 parallel port)*/ PORT_DIPNAME( 0x03, 0x02, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:1,2") @@ -682,7 +944,7 @@ static MACHINE_CONFIG_START( ppking ) MCFG_CPU_ADD("sub", Z80, XTAL_12MHz/4) /* verified on pcb */ MCFG_CPU_PROGRAM_MAP(cpu2_map) MCFG_CPU_IO_MAP(ppking_cpu2_io) - MCFG_CPU_VBLANK_INT_DRIVER("screen", ppking_state, irq0_line_hold) + MCFG_CPU_PERIODIC_INT_DRIVER(ppking_state, irq0_line_assert, 60) MCFG_CPU_ADD("audiocpu", M6809, XTAL_12MHz/16) /* verified on pcb */ MCFG_CPU_PROGRAM_MAP(ppking_cpu3_map) @@ -692,12 +954,22 @@ static MACHINE_CONFIG_START( ppking ) MCFG_MACHINE_RESET_OVERRIDE(ppking_state, ppking) MCFG_NVRAM_ADD_0FILL("nvram") + MCFG_DEVICE_ADD("mainlatch", LS259, 0) // 5L on main board + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE(ppking_state, spritebuffer_w)) +// MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(WRITELINE(gladiatr_state, spritebank_w)) +// MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(MEMBANK("bank1")) +// MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(WRITELINE(ppking_state, nmi_mask_w)) +// MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(INPUTLINE("sub", INPUT_LINE_RESET)) // shadowed by aforementioned hack +// Q6 used + MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE(ppking_state, flipscreen_w)) + /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(32*8, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1) +// MCFG_SCREEN_REFRESH_RATE(60) +// MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) +// MCFG_SCREEN_SIZE(32*8, 32*8) +// MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1) + MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,384,0,256,264,16,240) // assume same as Arkanoid MCFG_SCREEN_UPDATE_DRIVER(ppking_state, screen_update_ppking) MCFG_SCREEN_PALETTE("palette") @@ -710,10 +982,12 @@ static MACHINE_CONFIG_START( ppking ) MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_GENERIC_LATCH_8_ADD("soundlatch") + MCFG_GENERIC_LATCH_8_ADD("soundlatch2") MCFG_SOUND_ADD("ymsnd", YM2203, XTAL_12MHz/8) /* verified on pcb */ + MCFG_YM2203_IRQ_HANDLER(WRITELINE(gladiatr_state_base, ym_irq)) MCFG_AY8910_PORT_A_READ_CB(READ8(ppking_state, ppking_f1_r)) - MCFG_AY8910_PORT_B_READ_CB(READ8(ppking_state, ppking_f1_r)) + MCFG_AY8910_PORT_B_READ_CB(IOPORT("DSW3")) /* port B read */ MCFG_SOUND_ROUTE(0, "mono", 0.60) MCFG_SOUND_ROUTE(1, "mono", 0.60) MCFG_SOUND_ROUTE(2, "mono", 0.60) @@ -802,7 +1076,7 @@ static MACHINE_CONFIG_START( gladiatr ) MCFG_GENERIC_LATCH_8_ADD("soundlatch") MCFG_SOUND_ADD("ymsnd", YM2203, XTAL_12MHz/8) /* verified on pcb */ - MCFG_YM2203_IRQ_HANDLER(WRITELINE(gladiatr_state, gladiator_ym_irq)) + MCFG_YM2203_IRQ_HANDLER(WRITELINE(gladiatr_state_base, ym_irq)) MCFG_AY8910_PORT_B_READ_CB(IOPORT("DSW3")) /* port B read */ MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(gladiatr_state, gladiator_int_control_w)) /* port A write */ MCFG_SOUND_ROUTE(0, "mono", 0.60) @@ -837,8 +1111,10 @@ ROM_START( ppking ) ROM_LOAD( "q0_16.6e", 0x4000, 0x2000, CRC(b1e32588) SHA1(13c74479238a34a08e249f9120b42a52d80f8274) ) ROM_REGION( 0x10000, "audiocpu", 0 ) - ROM_LOAD( "q0_19.5n", 0x0c000, 0x2000, CRC(4bcf896d) SHA1(f587a66fcc63e989742ce2d5f4cf2bb464987038) ) + ROM_LOAD( "q0_19.5n", 0x0a000, 0x2000, CRC(4bcf896d) SHA1(f587a66fcc63e989742ce2d5f4cf2bb464987038) ) + ROM_RELOAD( 0x08000, 0x2000 ) ROM_LOAD( "q0_18.5m", 0x0e000, 0x2000, CRC(89ba64f8) SHA1(fa01316ea744b4277ee64d5f14cb6d7e3a949f2b) ) + ROM_RELOAD( 0x0c000, 0x2000 ) ROM_REGION( 0x02000, "gfx1", 0 ) ROM_LOAD( "q0_15.1r", 0x00000, 0x2000, CRC(fbd33219) SHA1(78b9bb327ededaa818d26c41c5e8fd1c041ef142) ) @@ -1174,15 +1450,24 @@ DRIVER_INIT_MEMBER(ppking_state, ppking) rom[i+2*j*0x2000] = rom[i+j*0x2000]; } } - m_maincpu->space(AS_PROGRAM).install_read_handler(0xf6a3,0xf6a3,read8_delegate(FUNC(ppking_state::ppking_f6a3_r),this)); - save_item(NAME(m_data1)); - save_item(NAME(m_data2)); + rom = memregion("sub")->base(); + + // patch audio CPU crash + ROM checksums + rom[0x1b9] = 0x00; + rom[0x1ba] = 0x00; + rom[0x1bb] = 0x00; + rom[0x839] = 0x00; + rom[0x83a] = 0x00; + rom[0x83b] = 0x00; + rom[0x845] = 0x00; + rom[0x846] = 0x00; + rom[0x847] = 0x00; } -GAME( 1985, ppking, 0, ppking, 0, ppking_state, ppking, ROT90, "Taito America Corporation", "Ping-Pong King", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +GAME( 1985, ppking, 0, ppking, ppking, ppking_state, ppking, ROT90, "Taito America Corporation", "Ping-Pong King", MACHINE_IMPERFECT_SOUND | MACHINE_NO_COCKTAIL | MACHINE_NODEVICE_LAN ) GAME( 1986, gladiatr, 0, gladiatr, gladiatr, gladiatr_state, gladiatr, ROT0, "Allumer / Taito America Corporation", "Gladiator (US)", MACHINE_SUPPORTS_SAVE ) GAME( 1986, ogonsiro, gladiatr, gladiatr, gladiatr, gladiatr_state, gladiatr, ROT0, "Allumer / Taito Corporation", "Ougon no Shiro (Japan)", MACHINE_SUPPORTS_SAVE ) GAME( 1986, greatgur, gladiatr, gladiatr, gladiatr, gladiatr_state, gladiatr, ROT0, "Allumer / Taito Corporation", "Great Gurianos (Japan?)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/goldnpkr.cpp b/src/mame/drivers/goldnpkr.cpp index b6fc3b92eb2..a17b44474cb 100644 --- a/src/mame/drivers/goldnpkr.cpp +++ b/src/mame/drivers/goldnpkr.cpp @@ -4656,8 +4656,8 @@ static MACHINE_CONFIG_START( megadpkr ) MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(megadpkr_banked_map) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_CPU_ADD("mcu", M68705P5, CPU_CLOCK) /* unknown */ diff --git a/src/mame/drivers/grfd2301.cpp b/src/mame/drivers/grfd2301.cpp index 09fcb7b1f2d..a4b48dbcc6c 100644 --- a/src/mame/drivers/grfd2301.cpp +++ b/src/mame/drivers/grfd2301.cpp @@ -54,13 +54,13 @@ private: required_region_ptr<u8> m_p_chargen; }; -static ADDRESS_MAP_START( grfd2301_mem, AS_PROGRAM, 8, grfd2301_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, grfd2301_state ) AM_RANGE(0xe000, 0xefff) AM_ROM AM_REGION("maincpu", 0) AM_RANGE(0xf000, 0xf7ff) AM_RAM AM_RANGE(0xf800, 0xffff) AM_RAM AM_SHARE("videoram") ADDRESS_MAP_END -static ADDRESS_MAP_START( grfd2301_io, AS_IO, 8, grfd2301_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, grfd2301_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_END @@ -111,8 +111,8 @@ uint32_t grfd2301_state::screen_update(screen_device &screen, bitmap_ind16 &bitm static MACHINE_CONFIG_START( grfd2301 ) // basic machine hardware MCFG_CPU_ADD("maincpu", Z80, 4000000) - MCFG_CPU_PROGRAM_MAP(grfd2301_mem) - MCFG_CPU_IO_MAP(grfd2301_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) diff --git a/src/mame/drivers/groundfx.cpp b/src/mame/drivers/groundfx.cpp index 34ca7fa2787..ded617299f4 100644 --- a/src/mame/drivers/groundfx.cpp +++ b/src/mame/drivers/groundfx.cpp @@ -361,6 +361,11 @@ ROM_START( groundfx ) ROM_LOAD( "93c46.164", 0x0000, 0x0080, CRC(6f58851d) SHA1(33bd4478f097dca6b5d222adb89699c6d35ed009) ) ROM_END +/*The World version of Ground Effects is not dumped and has the following EPROM labels: +'D51 28' @ IC59 +'D51 31' @ IC77 +'D51 32' @ IC61 +'D51 33' @ IC79*/ READ32_MEMBER(groundfx_state::irq_speedup_r) { diff --git a/src/mame/drivers/gstriker.cpp b/src/mame/drivers/gstriker.cpp index b211ccd3cae..e8650a929f6 100644 --- a/src/mame/drivers/gstriker.cpp +++ b/src/mame/drivers/gstriker.cpp @@ -265,8 +265,7 @@ static ADDRESS_MAP_START( twcup94_map, AS_PROGRAM, 16, gstriker_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( gstriker_map, AS_PROGRAM, 16, gstriker_state ) - AM_RANGE(0x200060, 0x200061) AM_DEVREADWRITE8("acia", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0x200062, 0x200063) AM_DEVREADWRITE8("acia", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0x200060, 0x200063) AM_DEVREADWRITE8("acia", acia6850_device, read, write, 0x00ff) AM_IMPORT_FROM(twcup94_map) ADDRESS_MAP_END diff --git a/src/mame/drivers/guab.cpp b/src/mame/drivers/guab.cpp index 56d18f3568c..c9682f5207f 100644 --- a/src/mame/drivers/guab.cpp +++ b/src/mame/drivers/guab.cpp @@ -121,10 +121,8 @@ static ADDRESS_MAP_START( guab_map, AS_PROGRAM, 16, guab_state ) AM_RANGE(0x0c0020, 0x0c0027) AM_DEVREADWRITE8("i8255_2", i8255_device, read, write, 0x00ff) AM_RANGE(0x0c0040, 0x0c0047) AM_DEVREADWRITE8("i8255_3", i8255_device, read, write, 0x00ff) AM_RANGE(0x0c0060, 0x0c0067) AM_DEVREADWRITE8("i8255_4", i8255_device, read, write, 0x00ff) - AM_RANGE(0x0c0080, 0x0c0081) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0x0c0082, 0x0c0083) AM_DEVREADWRITE8("acia6850_1", acia6850_device, data_r, data_w, 0x00ff) - AM_RANGE(0x0c00a0, 0x0c00a1) AM_DEVREADWRITE8("acia6850_2", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0x0c00a2, 0x0c00a3) AM_DEVREADWRITE8("acia6850_2", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0x0c0080, 0x0c0083) AM_DEVREADWRITE8("acia6850_1", acia6850_device, read, write, 0x00ff) + AM_RANGE(0x0c00a0, 0x0c00a3) AM_DEVREADWRITE8("acia6850_2", acia6850_device, read, write, 0x00ff) AM_RANGE(0x0c00c0, 0x0c00cf) AM_DEVREADWRITE8("6840ptm", ptm6840_device, read, write, 0x00ff) AM_RANGE(0x0c00e0, 0x0c00e7) AM_DEVREADWRITE8("fdc", wd1773_device, read, write, 0x00ff) AM_RANGE(0x080000, 0x080fff) AM_RAM diff --git a/src/mame/drivers/h19.cpp b/src/mame/drivers/h19.cpp index b97cb753f85..882313b8354 100644 --- a/src/mame/drivers/h19.cpp +++ b/src/mame/drivers/h19.cpp @@ -153,14 +153,14 @@ void h19_state::device_timer(emu_timer &timer, device_timer_id id, int param, vo -static ADDRESS_MAP_START(h19_mem, AS_PROGRAM, 8, h19_state) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, h19_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x1fff) AM_MIRROR(0x2000) AM_ROM AM_RANGE(0x4000, 0x4100) AM_MIRROR(0x3e00) AM_RAM AM_RANGE(0xc000, 0xc7ff) AM_MIRROR(0x3800) AM_RAM AM_SHARE("videoram") ADDRESS_MAP_END -static ADDRESS_MAP_START( h19_io, AS_IO, 8, h19_state) +static ADDRESS_MAP_START( io_map, AS_IO, 8, h19_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x00) AM_MIRROR(0x1f) AM_READ_PORT("SW401") @@ -515,8 +515,8 @@ GFXDECODE_END static MACHINE_CONFIG_START( h19 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, H19_CLOCK) // From schematics - MCFG_CPU_PROGRAM_MAP(h19_mem) - MCFG_CPU_IO_MAP(h19_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ // TODO: make configurable, Heath offered 3 different CRTs - White, Green, Amber. diff --git a/src/mame/drivers/harddriv.cpp b/src/mame/drivers/harddriv.cpp index 5cc063e8384..ad742c134a5 100644 --- a/src/mame/drivers/harddriv.cpp +++ b/src/mame/drivers/harddriv.cpp @@ -1446,7 +1446,7 @@ static MACHINE_CONFIG_START( driver_nomsp ) MCFG_M48T02_ADD("200e") // MK48T02 MCFG_EEPROM_2816_ADD("210e") // MK48Z02 - MCFG_MC68681_ADD("duartn68681", XTAL_3_6864MHz) + MCFG_DEVICE_ADD("duartn68681", MC68681, XTAL_3_6864MHz) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(harddriv_state, harddriv_duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE ("rs232", rs232_port_device, write_txd)) diff --git a/src/mame/drivers/hazelgr.cpp b/src/mame/drivers/hazelgr.cpp index cca9a43c63c..b26f5099089 100644 --- a/src/mame/drivers/hazelgr.cpp +++ b/src/mame/drivers/hazelgr.cpp @@ -8,37 +8,97 @@ #include "emu.h" #include "cpu/z80/z80.h" +#include "cpu/z80/z80daisy.h" +#include "machine/clock.h" +#include "machine/z80ctc.h" +#include "machine/z80pio.h" + class haze_state : public driver_device { public: haze_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu") + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") { } -protected: - - // devices +private: required_device<cpu_device> m_maincpu; }; -static ADDRESS_MAP_START( haze_map, AS_PROGRAM, 8, haze_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, haze_state ) AM_RANGE(0x0000, 0x17ff) AM_ROM AM_RANGE(0x9000, 0x9fff) AM_RAM ADDRESS_MAP_END +static ADDRESS_MAP_START( io_map, AS_IO, 8, haze_state ) + ADDRESS_MAP_UNMAP_HIGH + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x80, 0x83) AM_DEVREADWRITE("ctc1", z80ctc_device, read, write) // irq 17E0 => 0183(ch3) + AM_RANGE(0x90, 0x93) AM_DEVREADWRITE("pio1", z80pio_device, read_alt, write_alt) // 91 irq 17F8 => 0A5E + AM_RANGE(0xa0, 0xa3) AM_DEVREADWRITE("pio2", z80pio_device, read_alt, write_alt) // not programmed to interrupt + AM_RANGE(0xb0, 0xb3) AM_DEVREADWRITE("pio3", z80pio_device, read_alt, write_alt) // not programmed to interrupt + AM_RANGE(0xc0, 0xc3) AM_DEVREADWRITE("pio4", z80pio_device, read_alt, write_alt) // not programmed to interrupt + AM_RANGE(0xc4, 0xc7) AM_DEVREADWRITE("ctc2", z80ctc_device, read, write) // irq 17E8 => 023D(ch0),0366(ch1),02BB(ch2),0378(ch3) + AM_RANGE(0xc8, 0xcb) AM_DEVREADWRITE("ctc3", z80ctc_device, read, write) // irq 17F0 => 030E(ch0),038A(ch1) +ADDRESS_MAP_END + static INPUT_PORTS_START( haze ) + PORT_START("TEST") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START3 ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START4 ) INPUT_PORTS_END +static const z80_daisy_config daisy_chain[] = +{ + { "ctc1" }, + { "ctc2" }, + { "ctc3" }, + { "pio1" }, + { nullptr } +}; + +// All frequencies are guesswork, in an effort to get something to happen static MACHINE_CONFIG_START( haze ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80,2000000) /* ? MHz */ - MCFG_CPU_PROGRAM_MAP(haze_map) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + MCFG_Z80_DAISY_CHAIN(daisy_chain) + + MCFG_DEVICE_ADD("ctc_clock", CLOCK, 1'000'000) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc1", z80ctc_device, trg3)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc2", z80ctc_device, trg0)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc2", z80ctc_device, trg1)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc2", z80ctc_device, trg2)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc2", z80ctc_device, trg3)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc3", z80ctc_device, trg0)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc3", z80ctc_device, trg1)) + + MCFG_DEVICE_ADD("ctc1", Z80CTC, 1'000'000 ) + MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + + MCFG_DEVICE_ADD("ctc2", Z80CTC, 1'000'000 ) + MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + + MCFG_DEVICE_ADD("ctc3", Z80CTC, 1'000'000 ) + MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + + MCFG_DEVICE_ADD("pio1", Z80PIO, 1'000'000 ) + MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80PIO_IN_PA_CB(IOPORT("TEST")) + + MCFG_DEVICE_ADD("pio2", Z80PIO, 1'000'000 ) + + MCFG_DEVICE_ADD("pio3", Z80PIO, 1'000'000 ) + + MCFG_DEVICE_ADD("pio4", Z80PIO, 1'000'000 ) MACHINE_CONFIG_END ROM_START( hg_frd ) diff --git a/src/mame/drivers/hh_tms1k.cpp b/src/mame/drivers/hh_tms1k.cpp index 2ee8e34c304..c160c32da96 100644 --- a/src/mame/drivers/hh_tms1k.cpp +++ b/src/mame/drivers/hh_tms1k.cpp @@ -41,6 +41,7 @@ @MP1180 TMS1100 1980, Tomy Power House Pinball @MP1181 TMS1100 1979, Conic Football 2 @MP1183 TMS1100 1980, E.R.S. Superbowl XV Football/Tandy Championship Football (model 60-2151) + *MP1185 TMS1100 1979, Fonas 3-in-1: Football, Basketball, Soccer @MP1193 TMS1100 1980, Tandy Championship Football (model 60-2150) @MP1204 TMS1100 1980, Entex Baseball 3 (6007) *MP1209 TMS1100 1980, U.S. Games Space Cruiser/Strategy Football @@ -52,7 +53,7 @@ @MP1312 TMS1100 1983, Gakken FX-Micom R-165/Tandy Radio Shack Science Fair Microcomputer Trainer *MP1359 TMS1100? 1985, Capsela CRC2000 @MP1525 TMS1170 1980, Coleco Head to Head Baseball - *MP1604 ? 1981, Hanzawa Twinvader III/Tandy Cosmic Fire Away 3000 (? note: VFD-capable) + *MP1604 TMS1370 1982, Gakken Invader 2000/Tandy Cosmic Fire Away 3000 @MP1801 TMS1700 1981, Tiger Ditto/Tandy Pocket Repeat (model 60-2152) @MP2105 TMS1370 1979, Gakken/Entex Poker (6005) @MP2139 TMS1370 1982, Gakken Galaxy Invader 1000/Tandy Cosmic 1000 Fire Away @@ -98,6 +99,7 @@ @M34038 TMS1100 1982, Parker Brothers Lost Treasure M34047 TMS1100 1982, MicroVision cartridge: Super Blockbuster @M34078A TMS1100 1983, Milton Bradley Electronic Arcade Mania + @MP4486A TMS1000C 1983, Vulcan XL 25 @MP6100A TMS0980 1979, Ideal Electronic Detective @MP6101B TMS0980 1979, Parker Brothers Stop Thief *MP6361 ? 1983, Defender Strikes (? note: VFD-capable) @@ -6922,6 +6924,7 @@ public: : hh_tms1k_state(mconfig, type, tag) { } + void prepare_display(); DECLARE_WRITE16_MEMBER(write_r); DECLARE_WRITE16_MEMBER(write_o); DECLARE_READ8_MEMBER(read_k); @@ -6929,6 +6932,11 @@ public: // handlers +void bankshot_state::prepare_display() +{ + display_matrix(7, 11, m_o, m_r & ~3); +} + WRITE16_MEMBER(bankshot_state::write_r) { // R0: speaker out @@ -6938,8 +6946,8 @@ WRITE16_MEMBER(bankshot_state::write_r) m_inp_mux = data >> 2 & 3; // R2-R10: led select - m_r = data & ~3; - display_matrix(7, 11, m_o, m_r); + m_r = data; + prepare_display(); } WRITE16_MEMBER(bankshot_state::write_o) @@ -6947,7 +6955,7 @@ WRITE16_MEMBER(bankshot_state::write_o) // O0-O6: led state // O7: N/C m_o = data & 0x7f; - display_matrix(7, 11, m_o, m_r); + prepare_display(); } READ8_MEMBER(bankshot_state::read_k) @@ -7045,6 +7053,7 @@ public: : hh_tms1k_state(mconfig, type, tag) { } + void prepare_display(); DECLARE_WRITE16_MEMBER(write_r); DECLARE_WRITE16_MEMBER(write_o); DECLARE_READ8_MEMBER(read_k); @@ -7052,6 +7061,11 @@ public: // handlers +void splitsec_state::prepare_display() +{ + display_matrix(7, 8, m_o, m_r); +} + WRITE16_MEMBER(splitsec_state::write_r) { // R8: speaker out @@ -7062,7 +7076,7 @@ WRITE16_MEMBER(splitsec_state::write_r) // R0-R7: led select m_r = data; - display_matrix(7, 8, m_o, m_r); + prepare_display(); } WRITE16_MEMBER(splitsec_state::write_o) @@ -7070,7 +7084,7 @@ WRITE16_MEMBER(splitsec_state::write_o) // O0-O6: led state // O7: N/C m_o = data & 0x7f; - display_matrix(7, 8, m_o, m_r); + prepare_display(); } READ8_MEMBER(splitsec_state::read_k) @@ -8662,6 +8676,172 @@ MACHINE_CONFIG_END /*************************************************************************** + Vulcan XL 25 + * TMS1000SLC MP4486A (die label 1000C/, MP4486A) + * 28 LEDs, 1-bit sound + +***************************************************************************/ + +class xl25_state : public hh_tms1k_state +{ +public: + xl25_state(const machine_config &mconfig, device_type type, const char *tag) + : hh_tms1k_state(mconfig, type, tag) + { } + + void update_halt(); + DECLARE_INPUT_CHANGED_MEMBER(k4_button); + + void prepare_display(); + DECLARE_WRITE16_MEMBER(write_r); + DECLARE_WRITE16_MEMBER(write_o); + DECLARE_READ8_MEMBER(read_k); + +protected: + virtual void machine_reset() override; +}; + +// handlers + +void xl25_state::update_halt() +{ + // O5+K4 go to HALT pin (used when pressing store/recall button) + bool halt = !((m_o & 0x20) || (read_k(machine().dummy_space(), 0) & 4)); + m_maincpu->set_input_line(TMS1XXX_INPUT_LINE_HALT, halt ? ASSERT_LINE : CLEAR_LINE); +} + +void xl25_state::prepare_display() +{ + display_matrix(3, 10, m_o >> 1, m_r); +} + +WRITE16_MEMBER(xl25_state::write_r) +{ + // R0-R9: input mux, led select + m_inp_mux = data; + m_r = data; + prepare_display(); +} + +WRITE16_MEMBER(xl25_state::write_o) +{ + // O1-O3: led data + m_o = data; + prepare_display(); + + // O6: speaker out + m_speaker->level_w(data >> 6 & 1); + + // O5(+K4): MCU halt + update_halt(); +} + +READ8_MEMBER(xl25_state::read_k) +{ + // K: multiplexed inputs + // K4 also goes to MCU halt + return read_inputs(10); +} + + +// config + +static INPUT_PORTS_START( xl25 ) + PORT_START("IN.0") // R0 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_2) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_3) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.1") // R1 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_5) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_6) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.2") // R2 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_7) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_8) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_9) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.3") // R3 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Q) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_W) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_E) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.4") // R4 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_R) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_T) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Y) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.5") // R5 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_U) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_I) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_O) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.6") // R6 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_A) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_S) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_D) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.7") // R7 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_G) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_H) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.8") // R8 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_J) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_K) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_L) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) + + PORT_START("IN.9") // R9 + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_Z) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_X) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_CODE(KEYCODE_C) PORT_CHANGED_MEMBER(DEVICE_SELF, xl25_state, k4_button, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) +INPUT_PORTS_END + +INPUT_CHANGED_MEMBER(xl25_state::k4_button) +{ + update_halt(); +} + +void xl25_state::machine_reset() +{ + hh_tms1k_state::machine_reset(); + update_halt(); +} + +static MACHINE_CONFIG_START( xl25 ) + + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", TMS1000C, 300000) // approximation - RC osc. R=5.6K, C=47pF + MCFG_TMS1XXX_READ_K_CB(READ8(xl25_state, read_k)) + MCFG_TMS1XXX_WRITE_R_CB(WRITE16(xl25_state, write_r)) + MCFG_TMS1XXX_WRITE_O_CB(WRITE16(xl25_state, write_o)) + + MCFG_TIMER_DRIVER_ADD_PERIODIC("display_decay", hh_tms1k_state, display_decay_tick, attotime::from_msec(1)) + MCFG_DEFAULT_LAYOUT(layout_hh_tms1k_test) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) +MACHINE_CONFIG_END + + + + + +/*************************************************************************** + Game driver(s) ***************************************************************************/ @@ -9426,6 +9606,17 @@ ROM_START( ssports4 ) ROM_END +ROM_START( xl25 ) + ROM_REGION( 0x0400, "maincpu", 0 ) + ROM_LOAD( "mp4486a", 0x0000, 0x0400, CRC(bd84b515) SHA1(377fcc68a517260acd51eb9746cd62914a75d739) ) + + ROM_REGION( 867, "maincpu:mpla", 0 ) + ROM_LOAD( "tms1000_common2_micro.pla", 0, 867, BAD_DUMP CRC(d33da3cf) SHA1(13c4ebbca227818db75e6db0d45b66ba5e207776) ) // placeholder + ROM_REGION( 558, "maincpu:opla", 0 ) + ROM_LOAD( "tms1000c_xl25_output.pla", 0, 558, CRC(06ecc6e0) SHA1(e0fa1b9388948197b4de2edd3cd02fbde1dbabbb) ) +ROM_END + + // YEAR NAME PARENT CMP MACHINE INPUT STATE INIT COMPANY, FULLNAME, FLAGS CONS( 1979, matchnum, 0, 0, matchnum, matchnum, matchnum_state, 0, "A-One LSI", "Match Number", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) @@ -9515,5 +9706,7 @@ CONS( 1980, phpball, 0, 0, phpball, phpball, phpball_state, 0, CONS( 1980, ssports4, 0, 0, ssports4, ssports4, ssports4_state, 0, "U.S. Games", "Super Sports-4", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK ) +CONS( 1983, xl25, 0, 0, xl25, xl25, xl25_state, 0, "Vulcan Electronics", "XL 25", MACHINE_SUPPORTS_SAVE ) + // ***: As far as MAME is concerned, the game is emulated fine. But for it to be playable, it requires interaction // with other, unemulatable, things eg. game board/pieces, playing cards, pen & paper, etc. diff --git a/src/mame/drivers/hk68v10.cpp b/src/mame/drivers/hk68v10.cpp index 53d7e11a3e7..064fee8040e 100644 --- a/src/mame/drivers/hk68v10.cpp +++ b/src/mame/drivers/hk68v10.cpp @@ -279,7 +279,7 @@ WRITE16_MEMBER (hk68v10_state::bootvect_w){ LOG (("%s offset %08x, mask %08x, data %04x\n", FUNCNAME, offset, mem_mask, data)); m_sysram[offset % sizeof(m_sysram)] &= ~mem_mask; m_sysram[offset % sizeof(m_sysram)] |= (data & mem_mask); - m_sysrom = &m_sysram[0]; // redirect all upcomming accesses to masking RAM until reset. + m_sysrom = &m_sysram[0]; // redirect all upcoming accesses to masking RAM until reset. } #if 0 diff --git a/src/mame/drivers/hng64.cpp b/src/mame/drivers/hng64.cpp index 9e7eabf078a..d083b926654 100644 --- a/src/mame/drivers/hng64.cpp +++ b/src/mame/drivers/hng64.cpp @@ -219,7 +219,7 @@ The actual carts are mostly only about 1/3rd to 1/2 populated. Some of the IC locations between DG1 and DG2 are different also. See the source code below for the exact number of ROMs used per game and ROM placements. -Games that use the LVS-DG1 cart: Road's Edge +Games that use the LVS-DG1 cart: Road's Edge, Samurai Shodown 64 / Samurai Spirits 64 Games that use the LVS-DG2 cart: Fatal Fury: Wild Ambition, Buriki One, SS 64 II diff --git a/src/mame/drivers/homedata.cpp b/src/mame/drivers/homedata.cpp index c63999ecb61..0dda7b4c7b5 100644 --- a/src/mame/drivers/homedata.cpp +++ b/src/mame/drivers/homedata.cpp @@ -253,7 +253,7 @@ INTERRUPT_GEN_MEMBER(homedata_state::homedata_irq) INTERRUPT_GEN_MEMBER(homedata_state::upd7807_irq) { - generic_pulse_irq_line(device.execute(), UPD7810_INTF1, 1); + device.execute().pulse_input_line(UPD7810_INTF1, device.execute().minimum_quantum_time()); } @@ -1749,6 +1749,103 @@ ROM_START( battlcry ) ROM_END +ROM_START( battlcryc ) + ROM_REGION( 0x02c000, "maincpu", 0 ) /* 6809 Code */ + ROM_LOAD( "s88c01.j14", 0x010000, 0x01c000, CRC(4aa6d637) SHA1(e10c6c4a6adeb3b4837ebe5ff0a49ec1204b2e54) ) // 27C1000 + ROM_CONTINUE( 0x00c000, 0x004000 ) + + ROM_REGION( 0x40000, "audiocpu", 0) /* uPD7807 code */ + ROM_LOAD( "s88b04.f20", 0x000000, 0x040000, CRC(c54b5a5e) SHA1(421082af349b170d74f5214d8b5eed44db472749) ) + + ROM_REGION( 0x200000, "gfx1", 0 ) + ROM_LOAD( "s88c13.e2", 0x000000, 0x80000, CRC(8103f007) SHA1(fcc51e57a1df572ad00000e03db1f5f949dea619) ) + ROM_LOAD( "s88c14.e1", 0x080000, 0x80000, CRC(a7b5fafb) SHA1(7a9448bf13ee680c99bc19a6fac7a14d6ce8ddfc) ) + ROM_LOAD( "s88c15.f2", 0x100000, 0x80000, CRC(597d833b) SHA1(d0c22981b105c1b4b37eae64964af8b683cc4687) ) + ROM_LOAD( "s88c16.f1", 0x180000, 0x80000, CRC(9ca1c1a1) SHA1(30bbb47503631295a16bdd77a5bc08681dd7c63e) ) + + ROM_REGION( 0x100000, "gfx2", 0 ) + ROM_LOAD( "s88c09.e5", 0x000000, 0x80000, CRC(8f77ac3e) SHA1(5903a167ddf69284035967876ef46d7d09582574) ) + ROM_LOAD( "s88c10.e4", 0x080000, 0x80000, CRC(cb44371e) SHA1(96ac9aa0034152ba88afc373475928ad6d9ecd29) ) + + ROM_REGION( 0x080000, "gfx3", 0 ) + ROM_LOAD( "s88c08.e6", 0x000000, 0x80000, CRC(a989cfc2) SHA1(11c39a2ddd5e4be150d2f2ce332e312907df2377) ) + + ROM_REGION( 0x080000, "gfx4", 0 ) + ROM_LOAD( "s88c05.e7", 0x000000, 0x80000, CRC(e7f13340) SHA1(05b0f3ca369c95d4fd50cd9617fc044ad7bdf0d3) ) + + ROM_REGION( 0x010000, "proms", 0 ) /* static palette */ + ROM_LOAD16_BYTE( "s88b18.f10", 0x00000, 0x8000, CRC(fa432edc) SHA1(55c01b6a1175539facdfdd0c3c49d878a59156a4) ) + ROM_LOAD16_BYTE( "s88b17.f9", 0x00001, 0x8000, CRC(7c55568e) SHA1(1e599cd00abe7b67bcb0c8d3f0c467a99ef79658) ) + + ROM_REGION( 0x40000, "user1", 0 ) /* blitter data */ + ROM_LOAD( "s88b02.f19", 0x00000, 0x040000, CRC(7044a542) SHA1(8efaa512f62fe9a37d2474c435c549118c019d67) ) + + ROM_REGION( 0x0100, "user2", 0 ) + ROM_LOAD( "s88a19.l5", 0x0000, 0x0100, CRC(c8ead41e) SHA1(d1e733691de9f9b71c9724de73086d36f381fc74) ) // priority (not used) +ROM_END + + +ROM_START( battlcryp ) // prototype presented at AOU 1989 + ROM_REGION( 0x02c000, "maincpu", 0 ) /* 6809 Code */ + ROM_LOAD( "S88_B01.IC31", 0x010000, 0x01c000, CRC(8dae51b5) SHA1(52a4ec602c9c5bb185dd66b4b98dbfaa91189ced) ) // 27C1000 + ROM_CONTINUE( 0x00c000, 0x004000 ) + + ROM_REGION( 0x40000, "audiocpu", 0) /* uPD7807 code, identical to the released game but split in 27C1000 ROMs */ + ROM_LOAD( "S88_B04_1.IC32", 0x000000, 0x020000, CRC(9995c869) SHA1(9b68d1a15499fed216966ef3a3b68e6381dc01ad) ) + ROM_LOAD( "S88_B04_2.IC55", 0x020000, 0x020000, CRC(aaa2dabe) SHA1(5928c5d265a5d6e521285a8ba29e70ed1887a5c9) ) + + ROM_REGION( 0x200000, "gfx1", 0 ) /* identical to the released game but split in 27C1000 ROMs */ + ROM_LOAD16_BYTE( "S88_B13_1.V30", 0x000000, 0x20000, CRC(913e11df) SHA1(766b9cb1a39697db88f25a9ffc58724699ab9283) ) + ROM_LOAD16_BYTE( "S88_B13_2.V31", 0x000001, 0x20000, CRC(16069926) SHA1(502795838740b7d8641ae3308b7c56f540a9719b) ) + ROM_LOAD16_BYTE( "S88_B13_3.V32", 0x040000, 0x20000, CRC(95fc246f) SHA1(7b5d24cb7529aa4064f6bafa75172e3ce63d17c1) ) + ROM_LOAD16_BYTE( "S88_B13_4.V33", 0x040001, 0x20000, CRC(0eeb1374) SHA1(cae2890248b502888836d73d2d2067fae1a4d589) ) + ROM_LOAD16_BYTE( "S88_B14_1.V34", 0x080000, 0x20000, CRC(61beb857) SHA1(29d390b7f844905ad07e8c6b9fb87b3f7e01cae0) ) + ROM_LOAD16_BYTE( "S88_B14_2.V35", 0x080001, 0x20000, CRC(4a1fec65) SHA1(7f69cdb7e2140114a40562865bf9bdd3df4d2205) ) + ROM_LOAD16_BYTE( "S88_B14_3.V36", 0x0c0000, 0x20000, CRC(2c95a5b4) SHA1(2e2e5206b20b1f3c9323e2e4c78ea29e3dabb1b8) ) + ROM_LOAD16_BYTE( "S88_B14_4.V37", 0x0c0001, 0x20000, CRC(96f713a3) SHA1(97fd143341e267344dd40df71a586bc25540aa95) ) + ROM_LOAD16_BYTE( "S88_B15_1.V38", 0x100000, 0x20000, CRC(e106bc68) SHA1(1e049bf3c705db33b4629d3f8da3011a2aaaf7dd) ) + ROM_LOAD16_BYTE( "S88_B15_2.V39", 0x100001, 0x20000, CRC(cb6d7f09) SHA1(334d89ffe74f067820ef34a68ff70a2b2d0480a7) ) + ROM_LOAD16_BYTE( "S88_B15_3.V3A", 0x140000, 0x20000, CRC(4bc06e17) SHA1(681b994f090799e68922c2de2a0c7d2ccceec5dc) ) + ROM_LOAD16_BYTE( "S88_B15_4.V3B", 0x140001, 0x20000, CRC(ffeb09c3) SHA1(667893d589634cddb87fd459dceb0fd7bb151730) ) + ROM_LOAD16_BYTE( "S88_B16_1.V3C", 0x180000, 0x20000, CRC(bf6fc926) SHA1(3c084d5e742cfd093246e05b1c9537af944ff080) ) + ROM_LOAD16_BYTE( "S88_B16_2.V3D", 0x180001, 0x20000, CRC(5b3afa9c) SHA1(08e65108ba2ae8e9f01104961d9c5462b5607ad5) ) + ROM_LOAD16_BYTE( "S88_B16_3.V3E", 0x1c0000, 0x20000, CRC(df7a54e8) SHA1(a76a5f80a43b54800eb56fe5c20fb2b582b6d737) ) + ROM_LOAD16_BYTE( "S88_B16_4.V3F", 0x1c0001, 0x20000, CRC(fdbff33d) SHA1(10f4ebc1f7e42063b5ee10cb2e2f6b904bff4bc8) ) + + ROM_REGION( 0x100000, "gfx2", 0 ) /* identical to the released game but split in 27C1000 ROMs */ + ROM_LOAD16_BYTE( "S88_B09_1.V20", 0x000000, 0x20000, CRC(bfa2d6d3) SHA1(a10c9433c3215a80a74a8e46bd92595811073237) ) + ROM_LOAD16_BYTE( "S88_B09_2.V21", 0x000001, 0x20000, CRC(e1430cf9) SHA1(ec9b373b050f34219791f6309166a2d3abc43bc9) ) + ROM_LOAD16_BYTE( "S88_B09_3.V22", 0x040000, 0x20000, CRC(54cb22c7) SHA1(5c705fc13f7c866ecf3f51bd115c3dc58884a545) ) + ROM_LOAD16_BYTE( "S88_B09_4.V23", 0x040001, 0x20000, CRC(544f313d) SHA1(cec44c863737e80a2909f0b84d05802048bcb7a3) ) + ROM_LOAD16_BYTE( "S88_B10_1.V24", 0x080000, 0x20000, CRC(9bc86933) SHA1(56fdc99636262683bd6651b4ab021a5e34524c76) ) + ROM_LOAD16_BYTE( "S88_B10_2.V25", 0x080001, 0x20000, CRC(43e3ba91) SHA1(ddd69c0513c865ea1322784b275622bc41464c9b) ) + ROM_LOAD16_BYTE( "S88_B10_3.V26", 0x0c0000, 0x20000, CRC(d3672c33) SHA1(27c81d2c2257c613975e0b8dc41753c85305ddce) ) + ROM_LOAD16_BYTE( "S88_B10_4.V27", 0x0c0001, 0x20000, CRC(ae73723e) SHA1(49e1ab0a2626149f5986bbecf531685375b3695a) ) + + ROM_REGION( 0x080000, "gfx3", 0 ) /* identical to the released game but split in 27C1000 ROMs */ + ROM_LOAD16_BYTE( "S88_B08_1.V10", 0x000000, 0x20000, CRC(5132cd98) SHA1(8999aa64ff6f5c483ae71aab4699fe6ee3169382) ) + ROM_LOAD16_BYTE( "S88_B08_2.V11", 0x000001, 0x20000, CRC(fa661846) SHA1(745a15b801479e451fdb513ec4f334f438ba92c8) ) + ROM_LOAD16_BYTE( "S88_B08_3.V12", 0x040000, 0x20000, CRC(caabbf44) SHA1(d1957121012797372a93689a34ab8f0c3a5130af) ) + ROM_LOAD16_BYTE( "S88_B08_4.V13", 0x040001, 0x20000, CRC(257aacde) SHA1(0ac577864eedc2f778224f91235a011110a7006a) ) + + ROM_REGION( 0x080000, "gfx4", 0 ) /* identical to the released game but split in 27C1000 ROMs */ + ROM_LOAD16_BYTE( "S88_B05_1.V00", 0x000000, 0x20000, CRC(913e11df) SHA1(766b9cb1a39697db88f25a9ffc58724699ab9283) ) + ROM_LOAD16_BYTE( "S88_B05_2.V01", 0x000001, 0x20000, CRC(16069926) SHA1(502795838740b7d8641ae3308b7c56f540a9719b) ) + ROM_LOAD16_BYTE( "S88_B05_3.V02", 0x040000, 0x20000, CRC(3bca50bd) SHA1(b9b8c19ea4e6ff09c3032c18d246ed496552741e) ) + ROM_LOAD16_BYTE( "S88_B05_4.V03", 0x040001, 0x20000, CRC(c526d508) SHA1(fa7ec24a9f6fdaaf1a1b32b4b383e8738ad1c7d1) ) + + ROM_REGION( 0x010000, "proms", 0 ) /* static palette */ + ROM_LOAD16_BYTE( "S88_B18", 0x00000, 0x8000, CRC(fa432edc) SHA1(55c01b6a1175539facdfdd0c3c49d878a59156a4) ) // 27c256 + ROM_LOAD16_BYTE( "S88_B17", 0x00001, 0x8000, CRC(7c55568e) SHA1(1e599cd00abe7b67bcb0c8d3f0c467a99ef79658) ) // 27c256 + + ROM_REGION( 0x40000, "user1", 0 ) /* blitter data, identical to the released game but split in 27C1000 ROMs */ + ROM_LOAD( "S88_B02_1.IC28", 0x00000, 0x020000, CRC(93d8c8ec) SHA1(bb1fcf4d32db6885d0c78416211c20decc48d266) ) + ROM_LOAD( "S88_B02_2.IC27", 0x20000, 0x020000, CRC(8918327b) SHA1(445c0252ec8e71423e77c75190f9524a90f918a9) ) + + ROM_REGION( 0x0100, "user2", 0 ) + ROM_LOAD( "S88_A19.IC42", 0x0000, 0x0100, CRC(c8ead41e) SHA1(d1e733691de9f9b71c9724de73086d36f381fc74) ) // 82s129, priority (not used) +ROM_END + ROM_START( mjkojink ) ROM_REGION( 0x01c000, "maincpu", 0 ) /* 6809 Code */ @@ -2072,7 +2169,9 @@ GAME( 1988, mjclinica, mjclinic, mrokumei, mjhokite, homedata_state, 0, GAME( 1988, mrokumei, 0, mrokumei, mjhokite, homedata_state, 0, ROT0, "Home Data", "Mahjong Rokumeikan (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1988, reikaids, 0, reikaids, reikaids, homedata_state, reikaids, ROT0, "Home Data", "Reikai Doushi (Japan)", MACHINE_SUPPORTS_SAVE ) -GAME( 1991, battlcry, 0, reikaids, battlcry, homedata_state, battlcry, ROT0, "Home Data", "Battlecry", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1991, battlcry, 0, reikaids, battlcry, homedata_state, battlcry, ROT0, "Home Data", "Battlecry (Version E)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1989, battlcryc, battlcry, reikaids, battlcry, homedata_state, battlcry, ROT0, "Home Data", "Battlecry (Version C)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1989, battlcryp, battlcry, reikaids, battlcry, homedata_state, battlcry, ROT0, "Home Data", "Battlecry (Prototype)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1989, mjkojink, 0, pteacher, pteacher, homedata_state, 0, ROT0, "Home Data", "Mahjong Kojinkyouju (Private Teacher) (Japan)", MACHINE_SUPPORTS_SAVE ) GAME( 1988, mjjoship, 0, pteacher, mjjoship, homedata_state, 0, ROT0, "Home Data", "Mahjong Joshi Pro-wres -Give up 5 byou mae- (Japan)", MACHINE_SUPPORTS_SAVE ) GAME( 1989, vitaminc, 0, pteacher, pteacher, homedata_state, 0, ROT0, "Home Data", "Mahjong Vitamin C (Japan)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/hp2100.cpp b/src/mame/drivers/hp2100.cpp new file mode 100644 index 00000000000..2de7897e9e8 --- /dev/null +++ b/src/mame/drivers/hp2100.cpp @@ -0,0 +1,346 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-06 Skeleton + +HP 2100 and HP 1000 minicomputers with a front panel. Produced between 1966 and 1970. The CPU is a 2116A, a hard-wired design. +The computer can have 32K of 16-bit words of magnetic core. It had 16 I/O slots for various accessories. +See https://en.wikipedia.org/wiki/HP_2100 for more info. + +**************** Contents of readme files. +**HP 1000 boot proms: +12992-80002 059F 7905/6/20/25 +12992-80004 0672 ICD +12992-80005 0673 CS80 +12992-80006 073A 1816-0962 magtape +12992-80007 06C6 1816-1051 9885 floppy +12992-80009 0749 cartridge tape + 053A 1816-0420 paper tape + 07FB 1816-0862 + 077F 5081-2361 + +**HP 1000 firmware: + 13207-60001 + + + 1816- + 0545.u2 0539.u3 0540.u4 0541.u5 0542.u6 0543.u7 + 0538.u9 0544.u10 0549.u11 0548.u12 0547.u13 0546.u14 + + + * *-* + *-* * + *-* * + +HP1000 E/F Firmware + PN CKSUM + =========== ===== +2113 Base Set 02113-80006 BCDB + 02113-80007 8741 + 02113-80008 0889 + +2117 Base Set 02117-80016 C08F + 02117-80017 84E4 + 02117-80018 2C45 + +E-FPP 5090-0589 0530 + 5090-0590 C6B6 + 5090-0591 DE78 + +E-DMI 13307-80036 EA76 13307-80033 (same cksum) + 13307-80037 64CA 13307-80034 (same cksum) + 13307-80038 D7B8 13307-80035 (same cksum) + +F-DMI/FFP 5180-0141 FCD1 + 5180-0142 8C42 + 5180-0143 E820 + +F-VIS 12824-80007 FF2C + 12824-80008 F4B8 + 12825-80009 BF83 + +F-SIS 12823-80019 B7E9 + 12823-80020 7EAE + 12823-80021 2CE9 + +SIGNAL/1000 92835-80001 1EEC + 92835-80002 D419 + 92835-80003 C034 + +DS/1000 91740-80067 3F44 + 91740-80068 340A + 91740-80069 FF62 + +RTE-IV EMA 92067-80001 F054 + 92067-80002 B744 + 92067-80003 AAAA + +RTE6/VM OS 92084-80001 E946 + 92084-80102 E116 92084-80002 E10E (earlier rev) + 92084-80103 C670 92084-80003 C654 (earlier rev) + +RTE6/VM EMA/VMA 92084-80004 D166 + 92084-80005 8C02 + 92084-80006 B412 + +2000TSB IOP Firmware (from page 81-11 of M/E/F CE manual) + +1816-0532 ... 1816-0537 (6 proms) 2100 +1816-0538 ... 1816-0549 (12 proms) 21MX 13207-60001 firmware board +1816-0996 ... 1816-1001 (6 proms) 21MX-E 13304A firmware acc board needed + + +E-Series Control Memory Map +=========================== +Control Memory Module Allocation Module No Octal Software Entry Point + +HP Base Set -+ 0 00000-00377 yes 1k + | 1 00400-00777 yes + | 2 01000-01377 yes + + 3 01400-01777 yes +Available For User Microprogramming -+ 4 02000-02377 no 2k + | 5 02400-02777 no + | 6 03000-03377 no + | 7 03400-03777 no + | 8 04000-04377 no 3k + | 9 04400-04777 no + | 10 05000-05377 no + | 11 05400-05777 no + | 12 06000-06377 no 4k + | 13 06400-06777 no + | 14 07000-07377 no + | 15 07400-07777 no + | 16 10000-10377 no 5k + | 17 10400-10777 no + | 18 11000-11377 no + | 19 11400-11777 no + | 20 12000-12377 no 6k + | 21 12400-12777 no + | 22 13000-13377 no + | 23 13400-13777 no + | 24 14000-14377 no 7k + | 25 14400-14777 no + | 26 15000-15377 no + | 27 15400-15777 no + | 28 16000-16377 no 8k + | 29 16400-16777 no + | 30 17000-17377 no + + 31 17400-17777 no 8k +HP Dynamic Mapping System -- 32 20000-20377 yes 9k +HP Fast Fortran Processor -+ 33 20400-20777 no + | 34 21000-21377 yes + + 35 21400-21777 yes +RTE-IV EMA or RTE-6/VM EMA/VMA -+ 36 22000-22377 yes 10k + + 37 22400-22777 yes +DS/1000 -+ 38 23000-23377 yes + + 39 23400-23777 yes +HP Reserved -+ 40 24000-24377 yes 11k + | 41 24400-24777 no + | 42 25000-25377 no + + 43 25400-25777 no +RTE-6/VM Operating System -+ 44 26000-26377 yes 12k + + 45 26400-26777 yes +Recommended For User Microprogramming + 46 27000-27377 yes + | 47 27400-27777 yes + | 48 30000-30377 yes 13k + | 49 30400-30777 yes + | 50 31000-31377 yes + | 51 31400-31777 no + | 52 32000-32377 no 14k + | 53 32400-32777 no + | 54 33000-33377 no + | 55 33400-33777 no + | 56 34000-34377 yes 15k + | 57 34400-34777 yes + | 58 35000-35377 yes + | 59 35400-35777 yes + | 60 36000-36377 yes 16k + | 61 36400-36777 no + | 62 37000-37377 yes + | 63 37400-37777 no + +F-Series Control Memory Map +=========================== +Control Memory Module Allocation Module No Octal Software Entry Point + +HP Base Set -+ 0 00000-00377 yes 1k + | 1 00400-00777 yes + | 2 01000-01377 yes + + 3 01400-01777 yes +HP Reserved -+ 4 02000-02377 yes 2k + | 5 02400-02777 no + | 6 03000-03377 no + | 7 03400-03777 no + | 8 04000-04377 yes 3k + | 9 04400-04777 no + | 10 05000-05377 no + + 11 05400-05777 no +Vector Instruction Set -+ 12 06000-06377 yes 4k + | 13 06400-06777 no + | 14 07000-07377 no + + 15 07400-07777 no +RTE-6/VM Operating System -+ 16 10000-10377 yes 5k + | 17 10400-10777 no +HP Reserved -+ 18 11000-11377 yes + | 19 11400-11777 no + | 20 12000-12377 yes 6k + | 21 12400-12777 no + | 22 13000-13377 no + | 23 13400-13777 no + | 24 14000-14377 no 7k + | 25 14400-14777 no + | 26 15000-15377 no + + 27 15400-15777 no +Available For User Microprogramming -+ 28 16000-16377 no 8k + | 29 16400-16777 no + | 30 17000-17377 no + + 31 17400-17777 no +HP Dynamic Mapping System -- 32 20000-20377 yes 9k +HP Fast Fortran Processor -+ 33 20400-20777 no + | 34 21000-21377 yes + + 35 21400-21777 yes +RTE-IV EMA or RTE-6/VM EMA/VMA -+ 36 22000-22377 yes 10k + + 37 22400-22777 yes +DS/1000 -+ 38 23000-23377 yes + + 39 23400-23777 yes +Scientific Instruction Set -+ 40 24000-24377 yes 11k + | 41 24400-24777 no + | 42 25000-25377 no + + 43 25400-25777 no +HP Reserved -+ 44 26000-26377 no 12k + + 45 26400-26777 no +Recommended For User Microprogramming + 46 27000-27377 yes + | 47 27400-27777 yes + | 48 30000-30377 yes 13k + | 49 30400-30777 yes + | 50 31000-31377 yes + | 51 31400-31777 no + | 52 32000-32377 no 14k + | 53 32400-32777 no + | 54 33000-33377 no + | 55 33400-33777 no + | 56 34000-34377 yes 15k + | 57 34400-34777 yes + | 58 35000-35377 yes + | 59 35400-35777 yes + | 60 36000-36377 yes 16k + | 61 36400-36777 no + | 62 37000-37377 yes + | 63 37400-37777 no + +************************************************************************************************************************************/ + +#include "emu.h" + +class hp2100_state : public driver_device +{ +public: + hp2100_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) +// , m_maincpu(*this, "maincpu") + { } + +private: +// required_device<cpu_device> m_maincpu; +}; + +//static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 16, hp2100_state ) +//ADDRESS_MAP_END + +static INPUT_PORTS_START( hp2100 ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( hp2100 ) +MACHINE_CONFIG_END + +ROM_START( hp2100 ) + ROM_REGION( 0x0400, "maincpu", 0 ) + // HP 2100 firmware + ROM_LOAD( "1816-0054.bin", 0x000000, 0x000100, CRC(7c4192a2) SHA1(1f06e392258dd41f1f7ebd8b744a18ba03514e9d) ) + ROM_LOAD( "1816-0055.bin", 0x000000, 0x000100, CRC(6f0a671d) SHA1(febbbd6672ae1e95141ae4dddaea545b253ad18b) ) + ROM_LOAD( "1816-0056.bin", 0x000000, 0x000100, CRC(2a675e62) SHA1(d044911edc40bee386a8b96b9281250f4d9a4ac0) ) + ROM_LOAD( "1816-0057.bin", 0x000000, 0x000100, CRC(c1b3e302) SHA1(9ab7375ad80bc95efc0d744d23c5a45d42deb75a) ) + ROM_LOAD( "1816-0058.bin", 0x000000, 0x000100, CRC(a03f29e6) SHA1(d2bb3beb947e68bd51783b8730a80dd568b23aef) ) + ROM_LOAD( "1816-0059.bin", 0x000000, 0x000100, CRC(4753cd42) SHA1(bb801c842b82a316e92b6bdee196dc0d2e910590) ) + ROM_LOAD( "1816-0368.bin", 0x000000, 0x000100, CRC(6e4f94e6) SHA1(abac74ff4d57a75e33d35f9f2d1007c953c0d89b) ) + ROM_LOAD( "1816-0369.bin", 0x000000, 0x000100, CRC(be27972a) SHA1(c1dc90614f68adbc6870dd4169d296366f32f335) ) + ROM_LOAD( "1816-0370.bin", 0x000000, 0x000100, CRC(bf9d609b) SHA1(e03467d293b0ce7c3a2f99ac3c72f9d70e1f49ab) ) + ROM_LOAD( "1816-0371.bin", 0x000000, 0x000100, CRC(9292ce4a) SHA1(03ee62752bf1924127eef1decfa974395ccf2d7c) ) + ROM_LOAD( "1816-0372.bin", 0x000000, 0x000100, CRC(e38ada24) SHA1(b5e6ba0fcf49e45d38fd273bb078cc82946cfe5b) ) + ROM_LOAD( "1816-0373.bin", 0x000000, 0x000100, CRC(45e03c99) SHA1(509fe9fec58caf3a5983ad2bdf47c22a6e5376d5) ) + ROM_LOAD( "1816-0490.bin", 0x000000, 0x000100, CRC(61e272b0) SHA1(5d35c135653bf1a1891b7672a5a65958e7e52189) ) + ROM_LOAD( "1816-0491.bin", 0x000000, 0x000100, CRC(9e1504bd) SHA1(6258fa775f1979f0031ad930bf23938ea61afad8) ) + ROM_LOAD( "1816-0492.bin", 0x000000, 0x000100, CRC(0c4e7f1f) SHA1(951c69053de4a0d368d1d3cc851e48645cb69ed0) ) + ROM_LOAD( "1816-0493.bin", 0x000000, 0x000100, CRC(fc3f785e) SHA1(7398ef7bf0fe4f689a1c836cc4295ee6a7ef628b) ) + ROM_LOAD( "1816-0494.bin", 0x000000, 0x000100, CRC(a2424034) SHA1(e99f577dc3c23c82a12b6689c65b2d9e20e7f591) ) + ROM_LOAD( "1816-0495.bin", 0x000000, 0x000100, CRC(e79f1401) SHA1(13812f3acd3129e9ab2e2d790bdb25ed966061af) ) + ROM_LOAD( "1816-0862.bin", 0x000000, 0x000100, CRC(780e180b) SHA1(db4bedf30d347b618101efc5da5b15a822e10f6f) ) + ROM_LOAD( "1816-0869.bin", 0x000000, 0x000100, CRC(897e94a9) SHA1(805a4ebc837daeb0b84b44d2eddbde8862ff9a32) ) + // HP 1000 boot proms + ROM_LOAD( "12992-80002.bin", 0x000000, 0x000100, CRC(62a32a93) SHA1(fadc7b3c8d9d983ba8834ae3be87b3fef4da5a2c) ) + ROM_LOAD( "12992-80004.bin", 0x000000, 0x000100, CRC(9d699b3b) SHA1(dea16198bc959056782333b87893ec88a8fc8e6d) ) + ROM_LOAD( "12992-80005.bin", 0x000000, 0x000100, CRC(f4fb0410) SHA1(c93c47f3e5c41eb5fae60f5bbe81586e62bc278f) ) + ROM_LOAD( "12992-80006.bin", 0x000000, 0x000100, CRC(a18c008e) SHA1(c5b4237f256732f8e3c044dc728e65510e190056) ) + ROM_LOAD( "12992-80007.bin", 0x000000, 0x000100, CRC(505bb24b) SHA1(3579aaf97534768bfb59b376a685a1104330ebd8) ) + ROM_LOAD( "12992-80009.bin", 0x000000, 0x000100, CRC(38904247) SHA1(e41abd203e918d966ace66f198c53953f7c8547d) ) + ROM_LOAD( "1816-0420.bin", 0x000000, 0x000100, CRC(f3d7c188) SHA1(f63287cbb0aa6d20dd179a7f2d15755c8f34f027) ) + ROM_LOAD( "1816-0796.bin", 0x000000, 0x000100, CRC(d3a675a7) SHA1(1f64f40e46d80f770cc00c2c2c9f251f96ff47b0) ) + ROM_LOAD( "5081-2361.bin", 0x000000, 0x000100, CRC(29f71b0c) SHA1(767cc9d57b5921f755dbd3e376a30dd21cfa33cd) ) + // HP 1000 firmware + ROM_LOAD( "02113-80006.bin", 0x000000, 0x000400, CRC(8cd6f92a) SHA1(fa0048897362b2151bb417b36712f33a6a346113) ) + ROM_LOAD( "02113-80007.bin", 0x000000, 0x000400, CRC(5f92b933) SHA1(461a24aabc631dec2d980c595fbb36207fa08d40) ) + ROM_LOAD( "02113-80008.bin", 0x000000, 0x000400, CRC(52382fef) SHA1(bc05f8860b495c8e46cda7308858730738f76e4f) ) + ROM_LOAD( "02117-80016.bin", 0x000000, 0x000400, CRC(b43e2864) SHA1(b4753042d8750e169f24333545309838d9540a9a) ) + ROM_LOAD( "02117-80017.bin", 0x000000, 0x000400, CRC(03485b73) SHA1(8c5b6c5aed2351aa6e2455205a8bd6d32e69f978) ) + ROM_LOAD( "02117-80018.bin", 0x000000, 0x000400, CRC(dfeffc0c) SHA1(b062faa150bc2df6c92dc312e302e632def8fb00) ) + ROM_LOAD( "12823-80019.bin", 0x000000, 0x000400, CRC(219412d1) SHA1(71175efb74eaaebbcd80ff57bada53b9ac1fc31a) ) + ROM_LOAD( "12823-80020.bin", 0x000000, 0x000400, CRC(797932e2) SHA1(64f722e5893b397f87a94a9d0e06015658d3687d) ) + ROM_LOAD( "12823-80021.bin", 0x000000, 0x000400, CRC(7b79a419) SHA1(06ed29f9f728d16aed4de348aa8de5508ec65eb7) ) + ROM_LOAD( "12824-80007.bin", 0x000000, 0x000400, CRC(11617b11) SHA1(792f9867ced452fc33ed00e44f12e77e7d59de1c) ) + ROM_LOAD( "12824-80008.bin", 0x000000, 0x000400, CRC(72deee30) SHA1(85fb0c3d513c996b25864e1707bbd29a8d9bb50a) ) + ROM_LOAD( "12824-80009.bin", 0x000000, 0x000400, CRC(349fdb59) SHA1(c3de054e7d03428a1c7afc77fcae4e9b29b2d681) ) + ROM_LOAD( "13307-80036.bin", 0x000000, 0x000400, CRC(85cef205) SHA1(e0192c1dcc2d89c8862ba3c28ec173138c1a44ee) ) + ROM_LOAD( "13307-80033.bin", 0x000000, 0x000400, CRC(85cef205) SHA1(e0192c1dcc2d89c8862ba3c28ec173138c1a44ee) ) + ROM_LOAD( "13307-80034.bin", 0x000000, 0x000400, CRC(c726dd35) SHA1(fafd35727b0b29817ccd9278bd7e642aa7163082) ) + ROM_LOAD( "13307-80037.bin", 0x000000, 0x000400, CRC(c726dd35) SHA1(fafd35727b0b29817ccd9278bd7e642aa7163082) ) + ROM_LOAD( "13307-80035.bin", 0x000000, 0x000400, CRC(26c33e75) SHA1(cf40f18dd10b4c43bb93fecc0ca0fd5b0c5425c7) ) + ROM_LOAD( "13307-80038.bin", 0x000000, 0x000400, CRC(26c33e75) SHA1(cf40f18dd10b4c43bb93fecc0ca0fd5b0c5425c7) ) + ROM_LOAD( "1816-0538.u9.bin", 0x000000, 0x000100, CRC(9cf6fe69) SHA1(7fe6c4d890bdc9eb91fa5c0a7218b8994a62fa6c) ) + ROM_LOAD( "1816-0539.u3.bin", 0x000000, 0x000100, CRC(519a08bf) SHA1(fac12d2bb9ebc289fc7da5ffb3b784459fd75285) ) + ROM_LOAD( "1816-0540.u4.bin", 0x000000, 0x000100, CRC(fccb14f8) SHA1(9f71317303d9e0e9d5e32022d78fb0851e614ab5) ) + ROM_LOAD( "1816-0541.u5.bin", 0x000000, 0x000100, CRC(afeb0709) SHA1(6f9c4ab0975b3364940c60f3085824209e40f018) ) + ROM_LOAD( "1816-0542.u6.bin", 0x000000, 0x000100, CRC(bbafb8d8) SHA1(d3e8e0b0b04d79d55f1931585ba82310166f8614) ) + ROM_LOAD( "1816-0543.u7.bin", 0x000000, 0x000100, CRC(6df287d4) SHA1(5a2cd835ecd2082a418e6a672af9ca4d236eb394) ) + ROM_LOAD( "1816-0544.u10.bin", 0x000000, 0x000100, CRC(363c4c2b) SHA1(3a39a871c2833d16b16d74ca43f772d9b7196729) ) + ROM_LOAD( "1816-0545.u2.bin", 0x000000, 0x000100, CRC(11d99e86) SHA1(ccef7b22840ee8030dbac8e4d712cb488c403e35) ) + ROM_LOAD( "1816-0546.u14.bin", 0x000000, 0x000100, CRC(88c78dc0) SHA1(dae14d4fcf86d80c1a1df0fbd8f9aaa4bb5257d8) ) + ROM_LOAD( "1816-0547.u13.bin", 0x000000, 0x000100, CRC(db1f149a) SHA1(279099b2c438114e0ab722b16c956f3be8871f96) ) + ROM_LOAD( "1816-0548.u12.bin", 0x000000, 0x000100, CRC(fb0ad4ad) SHA1(97c4e55a3983181782ba41685b99d7c5a4a692e8) ) + ROM_LOAD( "1816-0549.u11.bin", 0x000000, 0x000100, CRC(8bf77f30) SHA1(6aa73d95b954ff33c1a69a19dd47b30712a574ad) ) + ROM_LOAD( "5090-0589.bin", 0x000000, 0x000400, CRC(e33752ca) SHA1(5956190e9bf4126065992de46a59ebd83757a9b1) ) + ROM_LOAD( "5090-0590.bin", 0x000000, 0x000400, CRC(b423b55c) SHA1(7931f155666da04d09e34d9c9e323c6a6a3e7621) ) + ROM_LOAD( "5090-0591.bin", 0x000000, 0x000400, CRC(f8653fc6) SHA1(3341fc65cd73c1adb0c56f1e0518041206d8b4de) ) + ROM_LOAD( "5180-0141.bin", 0x000000, 0x000400, CRC(215c5f5c) SHA1(1ec17050e63a447f07291f5de479dedf6ff6bdc7) ) + ROM_LOAD( "5180-0142.bin", 0x000000, 0x000400, CRC(919119f3) SHA1(18ebcaf355af1c6920fb90688f692e73d2ca9abf) ) + ROM_LOAD( "5180-0143.bin", 0x000000, 0x000400, CRC(82bf297a) SHA1(34ff0ac268b06072533fdf90d2365a4cf049e9f3) ) + ROM_LOAD( "91740-80067.bin", 0x000000, 0x000400, CRC(d65f5c3f) SHA1(bc3ef3623f0b475499f708647e779c3f82c9998b) ) + ROM_LOAD( "91740-80068.bin", 0x000000, 0x000400, CRC(5c62a4db) SHA1(6064c9d1179ea115c84e7f9133f93c9d0a85d1ab) ) + ROM_LOAD( "91740-80069.bin", 0x000000, 0x000400, CRC(7e8b5ebe) SHA1(2a2c56ab55bc32d5b60c29166969653297354e16) ) + ROM_LOAD( "92067-80001.bin", 0x000000, 0x000400, CRC(4366dafe) SHA1(559b5494cb57f1dc862717b881df51dde22b9ea1) ) + ROM_LOAD( "92067-80002.bin", 0x000000, 0x000400, CRC(b31eed07) SHA1(43004a14080176707bd492335be84ee9e776f97f) ) + ROM_LOAD( "92067-80003.bin", 0x000000, 0x000400, CRC(9f97bbe6) SHA1(e37e6c48786bc3ad6eb1ea9307c8b6e188524276) ) + ROM_LOAD( "92084-80001.bin", 0x000000, 0x000400, CRC(8ebbf4a8) SHA1(f770da090f1df7a9e8c9e69621b5690264b623d7) ) + ROM_LOAD( "92084-80002.bin", 0x000000, 0x000400, CRC(7b02d33a) SHA1(1a0f7f7fee60f26eec9c9aa06b19944ff5de1b1f) ) + ROM_LOAD( "92084-80003.bin", 0x000000, 0x000400, CRC(9e338250) SHA1(6758fe50931ec9b623247f51b5b63d9cbca47061) ) + ROM_LOAD( "92084-80004.bin", 0x000000, 0x000400, CRC(524ee313) SHA1(d9194d566b59974bf17d290b7f9efbbf0874b410) ) + ROM_LOAD( "92084-80005.bin", 0x000000, 0x000400, CRC(9a62d961) SHA1(f1c1faa0760df0e0406a5a2cb7b4fc6bb12f349f) ) + ROM_LOAD( "92084-80006.bin", 0x000000, 0x000400, CRC(26af135b) SHA1(82dbd9be22a6ffa90cfbfad25f80daa281aa3a14) ) + ROM_LOAD( "92084-80102.bin", 0x000000, 0x000400, CRC(644f8bb2) SHA1(10bef2af538c543bf42c5df109506834fbfbcaa8) ) + ROM_LOAD( "92084-80103.bin", 0x000000, 0x000400, CRC(77b7b66c) SHA1(b8a4afc9b48696dd8691918c4d8b89fba4d2526b) ) + ROM_LOAD( "92835-80001.bin", 0x000000, 0x000400, CRC(f6b71580) SHA1(f0e529f1f81ddf9c3e028d666b65f10289e088bb) ) + ROM_LOAD( "92835-80002.bin", 0x000000, 0x000400, CRC(e417c13a) SHA1(bcbe0421079fb18a1c3989e863b1f9a763f4d548) ) + ROM_LOAD( "92835-80003.bin", 0x000000, 0x000400, CRC(1df52f66) SHA1(84fd048d50f6fde9a79e8df618b5a3435a087f85) ) +ROM_END + +COMP( 1966, hp2100, 0, 0, hp2100, hp2100, hp2100_state, 0, "Hewlett-Packard", "HP 2100", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/hp64k.cpp b/src/mame/drivers/hp64k.cpp index 03ef087c415..7c9bf6e965b 100644 --- a/src/mame/drivers/hp64k.cpp +++ b/src/mame/drivers/hp64k.cpp @@ -210,8 +210,8 @@ public: void hp64k_update_floppy_dma(void); void hp64k_update_floppy_irq(void); void hp64k_update_drv_ctrl(void); - DECLARE_WRITE8_MEMBER(hp64k_floppy0_rdy); - DECLARE_WRITE8_MEMBER(hp64k_floppy1_rdy); + DECLARE_WRITE_LINE_MEMBER(hp64k_floppy0_rdy); + DECLARE_WRITE_LINE_MEMBER(hp64k_floppy1_rdy); void hp64k_floppy_idx_cb(floppy_image_device *floppy , int state); void hp64k_floppy_wpt_cb(floppy_image_device *floppy , int state); @@ -877,18 +877,18 @@ void hp64k_state::hp64k_update_drv_ctrl(void) } } -WRITE8_MEMBER(hp64k_state::hp64k_floppy0_rdy) +WRITE_LINE_MEMBER(hp64k_state::hp64k_floppy0_rdy) { - if (data) { + if (state) { BIT_CLR(m_floppy_status , 0); } else { BIT_SET(m_floppy_status , 0); } } -WRITE8_MEMBER(hp64k_state::hp64k_floppy1_rdy) +WRITE_LINE_MEMBER(hp64k_state::hp64k_floppy1_rdy) { - if (data) { + if (state) { BIT_CLR(m_floppy_status , 3); } else { BIT_SET(m_floppy_status , 3); @@ -898,9 +898,9 @@ WRITE8_MEMBER(hp64k_state::hp64k_floppy1_rdy) void hp64k_state::hp64k_floppy_idx_cb(floppy_image_device *floppy , int state) { if (floppy == m_floppy0->get_device()) { - m_ss0->a_w(machine().dummy_space(), 0, !state); + m_ss0->a_w(!state); } else if (floppy == m_floppy1->get_device()) { - m_ss1->a_w(machine().dummy_space(), 0, !state); + m_ss1->a_w(!state); } if (floppy == m_current_floppy) { @@ -1374,7 +1374,7 @@ static MACHINE_CONFIG_START(hp64k) MCFG_TTL74123_CAPACITOR_VALUE(CAP_U(16)) MCFG_TTL74123_B_PIN_VALUE(1) MCFG_TTL74123_CLEAR_PIN_VALUE(1) - MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITE8(hp64k_state , hp64k_floppy0_rdy)); + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(hp64k_state , hp64k_floppy0_rdy)); MCFG_DEVICE_ADD("fdc_rdy1" , TTL74123 , 0) MCFG_TTL74123_CONNECTION_TYPE(TTL74123_NOT_GROUNDED_NO_DIODE) @@ -1382,7 +1382,7 @@ static MACHINE_CONFIG_START(hp64k) MCFG_TTL74123_CAPACITOR_VALUE(CAP_U(16)) MCFG_TTL74123_B_PIN_VALUE(1) MCFG_TTL74123_CLEAR_PIN_VALUE(1) - MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITE8(hp64k_state , hp64k_floppy1_rdy)); + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(hp64k_state , hp64k_floppy1_rdy)); MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("beeper" , BEEP , 2500) diff --git a/src/mame/drivers/hp80.cpp b/src/mame/drivers/hp80.cpp index 64c7d3d5d4d..803c2dfca78 100644 --- a/src/mame/drivers/hp80.cpp +++ b/src/mame/drivers/hp80.cpp @@ -20,6 +20,7 @@ #include "softlist.h" #include "machine/bankdev.h" #include "bus/hp80_io/hp80_io.h" +#include "imagedev/bitbngr.h" // Debugging #define VERBOSE 1 @@ -27,19 +28,19 @@ // Bit manipulation namespace { - static constexpr unsigned BIT_MASK(unsigned n) + template<typename T> constexpr T BIT_MASK(unsigned n) { - return 1U << n; + return (T)1U << n; } template<typename T> void BIT_CLR(T& w , unsigned n) { - w &= ~(T)BIT_MASK(n); + w &= ~BIT_MASK<T>(n); } template<typename T> void BIT_SET(T& w , unsigned n) { - w |= (T)BIT_MASK(n); + w |= BIT_MASK<T>(n); } template<typename T> void COPY_BIT(bool bit , T& w , unsigned n) @@ -78,6 +79,45 @@ static constexpr unsigned IOP_COUNT = 4; static constexpr unsigned IRQ_BIT_COUNT = IRQ_IOP0_BIT + IOP_COUNT; static constexpr unsigned NO_IRQ = IRQ_BIT_COUNT; +// Internal printer has a moving printhead with 8 vertically-arranged resistors that print dots +// by heating thermal paper. The horizontal span of the printhead covers 224 columns. +// In alpha mode, each sweep prints up to 32 characters. Each character has a 8x7 cell. +// 8 pixels of cell height are covered by the printhead height, whereas 7 pixels of width +// allow for 32 characters on a row (224 = 32 * 7). +// After an alpha line is printed the paper advances by 10 pixel lines, so that a space of +// 2 lines is left between alpha lines. +// In graphic mode, printing starts at column 16 and covers 192 columns. So on each side of +// the printed area there's a 16-column wide margin (224 = 192 + 2 * 16). +// Once a graphic line is printed, paper advances by 8 pixel lines so that no space is inserted +// between successive sweeps. +// A full image of the graphic screen (256 x 192) is printed rotated 90 degrees clockwise. +// The printer controller chip (1MA9) has an embedded character generator ROM that is used +// when printing alpha lines. This ROM is also read by the CPU when drawing text on the graphic +// screen (BASIC "LABEL" instruction). +constexpr unsigned PRT_BUFFER_SIZE = 192; +constexpr unsigned PRTSTS_PAPER_OK_BIT = 7; +constexpr unsigned PRTSTS_DATARDY_BIT = 6; +constexpr unsigned PRTSTS_PRTRDY_BIT = 0; +constexpr unsigned PRTCTL_GRAPHIC_BIT = 7; +//constexpr unsigned PRTCTL_POWERUP_BIT = 6; +constexpr unsigned PRTCTL_READGEN_BIT = 5; +// Time to print a line (nominal speed is 2 lines/s) +constexpr unsigned PRT_BUSY_MSEC = 500; +// Horizontal start position of graphic print (16 columns from left-hand side) +constexpr unsigned PRT_GRAPH_OFFSET = 16; +// Height of printhead +constexpr unsigned PRT_PH_HEIGHT = 8; +// Height of alpha rows +constexpr unsigned PRT_ALPHA_HEIGHT = 10; +// Width of character cells +constexpr unsigned PRT_CELL_WIDTH = 7; +// Height of graphic rows +//constexpr unsigned PRT_GRAPH_HEIGHT = 8; +// Width of graphic sweeps +constexpr unsigned PRT_GRAPH_WIDTH = 192; +// Width of printhead sweeps +constexpr unsigned PRT_WIDTH = 224; + // ************ // hp85_state // ************ @@ -106,6 +146,12 @@ public: DECLARE_WRITE8_MEMBER(clksts_w); DECLARE_READ8_MEMBER(clkdat_r); DECLARE_WRITE8_MEMBER(clkdat_w); + DECLARE_WRITE8_MEMBER(prtlen_w); + DECLARE_READ8_MEMBER(prchar_r); + DECLARE_WRITE8_MEMBER(prchar_w); + DECLARE_READ8_MEMBER(prtsts_r); + DECLARE_WRITE8_MEMBER(prtctl_w); + DECLARE_WRITE8_MEMBER(prtdat_w); DECLARE_WRITE8_MEMBER(rselec_w); DECLARE_READ8_MEMBER(intrsc_r); DECLARE_WRITE8_MEMBER(intrsc_w); @@ -114,6 +160,7 @@ public: TIMER_DEVICE_CALLBACK_MEMBER(vm_timer); TIMER_DEVICE_CALLBACK_MEMBER(timer_update); TIMER_DEVICE_CALLBACK_MEMBER(clk_busy_timer); + TIMER_DEVICE_CALLBACK_MEMBER(prt_busy_timer); DECLARE_WRITE8_MEMBER(irl_w); DECLARE_WRITE8_MEMBER(halt_w); @@ -124,6 +171,7 @@ protected: required_device<palette_device> m_palette; required_device<timer_device> m_vm_timer; required_device<timer_device> m_clk_busy_timer; + required_device<timer_device> m_prt_busy_timer; required_device<beep_device> m_beep; required_device<dac_1bit_device> m_dac; required_ioport m_io_key0; @@ -133,9 +181,12 @@ protected: required_device_array<hp80_optrom_slot_device , 6> m_rom_drawers; required_device<address_map_bank_device> m_rombank; required_device_array<hp80_io_slot_device , IOP_COUNT> m_io_slots; + required_device<bitbanger_device> m_prt_graph_out; + required_device<bitbanger_device> m_prt_alpha_out; - // Character generator + // Character generators required_region_ptr<uint8_t> m_chargen; + required_region_ptr<uint8_t> m_prt_chargen; bitmap_rgb32 m_bitmap; std::vector<uint8_t> m_video_mem; @@ -171,6 +222,15 @@ protected: uint8_t m_timer_idx; bool m_clk_busy; + // Printer + uint8_t m_prtlen; + uint8_t m_prt_idx; + uint8_t m_prchar_r; + uint8_t m_prchar_w; + uint8_t m_prtsts; + uint8_t m_prtctl; + uint8_t m_prt_buffer[ PRT_BUFFER_SIZE ]; + attotime time_to_video_mem_availability() const; static void get_video_addr(uint16_t addr , uint16_t& byte_addr , bool& lsb_nibble); uint8_t video_mem_r(uint16_t addr , uint16_t addr_mask) const; @@ -184,6 +244,12 @@ protected: void irq_en_w(unsigned n_irq , bool state); void update_int_bits(); void update_irl(); + + uint8_t get_prt_font(uint8_t ch , unsigned col) const; + void prt_format_alpha(unsigned row , uint8_t *pixel_row) const; + void prt_format_graphic(unsigned row , uint8_t *pixel_row) const; + void prt_output_row(const uint8_t *pixel_row); + void prt_do_printing(); }; hp85_state::hp85_state(const machine_config &mconfig, device_type type, const char *tag) @@ -193,6 +259,7 @@ hp85_state::hp85_state(const machine_config &mconfig, device_type type, const ch m_palette(*this , "palette"), m_vm_timer(*this , "vm_timer"), m_clk_busy_timer(*this , "clk_busy_timer"), + m_prt_busy_timer(*this , "prt_busy_timer"), m_beep(*this , "beeper"), m_dac(*this , "dac"), m_io_key0(*this , "KEY0"), @@ -202,7 +269,10 @@ hp85_state::hp85_state(const machine_config &mconfig, device_type type, const ch m_rom_drawers(*this , "drawer%u" , 1), m_rombank(*this , "rombank"), m_io_slots(*this , "slot%u" , 1), - m_chargen(*this , "chargen") + m_prt_graph_out(*this , "prt_graphic"), + m_prt_alpha_out(*this , "prt_alpha"), + m_chargen(*this , "chargen"), + m_prt_chargen(*this , "prt_chargen") { } @@ -217,7 +287,7 @@ void hp85_state::machine_reset() m_crt_sad = 0; m_crt_bad = 0; m_crt_sts = 0x7c; - m_crt_ctl = BIT_MASK(CRT_CTL_POWERDN_BIT) | BIT_MASK(CRT_CTL_WIPEOUT_BIT); + m_crt_ctl = BIT_MASK<uint8_t>(CRT_CTL_POWERDN_BIT) | BIT_MASK<uint8_t>(CRT_CTL_WIPEOUT_BIT); m_crt_read_byte = 0; m_crt_write_byte = 0; m_int_serv = 0; @@ -246,6 +316,12 @@ void hp85_state::machine_reset() update_irl(); m_halt_lines = 0; m_cpu->set_input_line(INPUT_LINE_HALT , CLEAR_LINE); + m_prtlen = 0; + m_prt_idx = PRT_BUFFER_SIZE; + m_prchar_r = 0; + m_prchar_w = 0; + m_prtsts = BIT_MASK<uint8_t>(PRTSTS_PAPER_OK_BIT) | BIT_MASK<uint8_t>(PRTSTS_PRTRDY_BIT); + m_prtctl = 0; // Load optional ROMs (if any) // All entries in rombanks [01..FF] initially not present @@ -328,7 +404,8 @@ static const uint8_t vector_table[] = { 0x10, // Slot 1 0x10, // Slot 2 0x10, // Slot 3 - 0x10 // Slot 4 + 0x10, // Slot 4 + 0x00 // No IRQ }; IRQ_CALLBACK_MEMBER(hp85_state::irq_callback) @@ -562,6 +639,73 @@ WRITE8_MEMBER(hp85_state::clkdat_w) } } +WRITE8_MEMBER(hp85_state::prtlen_w) +{ + //LOG("PRTLEN=%u\n" , data); + if (data == 0) { + // Advance paper + memset(m_prt_buffer , 0 , sizeof(m_prt_buffer)); + m_prt_idx = 0; + prt_do_printing(); + } else { + m_prtlen = data; + if (!BIT(m_prtctl , PRTCTL_GRAPHIC_BIT)) { + m_prt_idx = 0; + } + } +} + +READ8_MEMBER(hp85_state::prchar_r) +{ + return m_prchar_r; +} + +WRITE8_MEMBER(hp85_state::prchar_w) +{ + m_prchar_w = data; +} + +READ8_MEMBER(hp85_state::prtsts_r) +{ + return m_prtsts; +} + +WRITE8_MEMBER(hp85_state::prtctl_w) +{ + //LOG("PRTCTL=%02x\n" , data); + m_prtctl = data; + BIT_SET(m_prtsts , PRTSTS_PRTRDY_BIT); + if (BIT(m_prtctl , PRTCTL_READGEN_BIT)) { + // Reading printer char. gen. + m_prchar_r = get_prt_font(m_prchar_w , m_prtctl & 7); + BIT_SET(m_prtsts , PRTSTS_DATARDY_BIT); + } else { + BIT_CLR(m_prtsts , PRTSTS_DATARDY_BIT); + } + if (BIT(m_prtctl , PRTCTL_GRAPHIC_BIT)) { + m_prt_idx = 0; + } +} + +WRITE8_MEMBER(hp85_state::prtdat_w) +{ + m_cpu->flatten_burst(); + //LOG("PRTDAT=%02x\n" , data); + if (m_prt_idx < PRT_BUFFER_SIZE) { + m_prt_buffer[ m_prt_idx++ ] = data; + if (m_prt_idx == PRT_BUFFER_SIZE || (!BIT(m_prtctl , PRTCTL_GRAPHIC_BIT) && m_prt_idx >= m_prtlen)) { + //LOG("Print\n"); + prt_do_printing(); + m_prt_idx = PRT_BUFFER_SIZE; + } + } +} + +TIMER_DEVICE_CALLBACK_MEMBER(hp85_state::prt_busy_timer) +{ + BIT_SET(m_prtsts , PRTSTS_PRTRDY_BIT); +} + WRITE8_MEMBER(hp85_state::rselec_w) { m_rombank->set_bank(data); @@ -698,7 +842,7 @@ bool hp85_state::kb_scan_ioport(ioport_value pressed , unsigned idx_base , uint8 if (keycode != 0xff) { return true; } - ioport_value mask = BIT_MASK(bit_no); + ioport_value mask = BIT_MASK<ioport_value>(bit_no); pressed &= ~mask; } return false; @@ -983,6 +1127,76 @@ void hp85_state::update_irl() m_cpu->set_input_line(0 , m_global_int_en && m_top_pending < IRQ_BIT_COUNT && !BIT(m_int_acked , m_top_pending)); } +uint8_t hp85_state::get_prt_font(uint8_t ch , unsigned col) const +{ + // Bit 7: pixel @ top + // Bit 0: pixel @ bottom + uint8_t column = m_prt_chargen[ (((unsigned)ch & 0x7f) << 3) | col ]; + if (BIT(ch , 7)) { + // Underline + BIT_SET(column , 0); + } + return column; +} + +void hp85_state::prt_format_alpha(unsigned row , uint8_t *pixel_row) const +{ + memset(pixel_row , 0 , PRT_WIDTH); + for (unsigned i = 0; i < m_prt_idx; i++) { + for (unsigned j = 0; j < PRT_CELL_WIDTH; j++) { + uint8_t pixel_col = get_prt_font(m_prt_buffer[ i ] , j); + *pixel_row++ = BIT(pixel_col , 7 - row); + } + } +} + +void hp85_state::prt_format_graphic(unsigned row , uint8_t *pixel_row) const +{ + memset(pixel_row , 0 , PRT_WIDTH); + pixel_row += PRT_GRAPH_OFFSET; + for (unsigned i = 0; i < PRT_GRAPH_WIDTH; i++) { + *pixel_row++ = BIT(m_prt_buffer[ i ] , 7 - row); + } +} + +void hp85_state::prt_output_row(const uint8_t *pixel_row) +{ + for (unsigned i = 0; i < PRT_WIDTH; i++) { + m_prt_graph_out->output(*pixel_row++ != 0 ? '*' : ' '); + } + m_prt_graph_out->output('\n'); +} + +void hp85_state::prt_do_printing() +{ + uint8_t pixel_row[ PRT_WIDTH ]; + for (unsigned row = 0; row < PRT_PH_HEIGHT; row++) { + if (BIT(m_prtctl , PRTCTL_GRAPHIC_BIT)) { + prt_format_graphic(row , pixel_row); + } else { + prt_format_alpha(row , pixel_row); + } + prt_output_row(pixel_row); + } + if (!BIT(m_prtctl , PRTCTL_GRAPHIC_BIT)) { + // Dump the text line to alpha bitbanger + for (unsigned i = 0; i < m_prt_idx; i++) { + m_prt_alpha_out->output(m_prt_buffer[ i ]); + } + m_prt_alpha_out->output('\n'); + // Add 2 empty lines + memset(pixel_row , 0 , PRT_WIDTH); + for (unsigned i = 0; i < (PRT_ALPHA_HEIGHT - PRT_PH_HEIGHT); i++) { + prt_output_row(pixel_row); + } + } + // Start busy timer + BIT_CLR(m_prtsts , PRTSTS_PRTRDY_BIT); + m_prt_busy_timer->adjust(attotime::from_msec(PRT_BUSY_MSEC)); +} + +#define IOP_MASK(x) BIT_MASK<ioport_value>((x)) + static INPUT_PORTS_START(hp85) // Keyboard is arranged in a matrix of 10 rows and 8 columns. In addition there are 3 keys with // dedicated input lines: SHIFT, SHIFT LOCK & CONTROL. @@ -990,95 +1204,95 @@ static INPUT_PORTS_START(hp85) // n = r / 4 // b = (r % 4) * 8 + c PORT_START("KEY0") - PORT_BIT(BIT_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME("Down AUTO") // 0,0: Down / Auto - PORT_BIT(BIT_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME("Up Home") // 0,1: Up / Home - PORT_BIT(BIT_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_NAME("k4 k8") // 0,2: k4 / k8 - PORT_BIT(BIT_MASK(3) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_NAME("k3 k7") // 0,3: k3 / k7 - PORT_BIT(BIT_MASK(4) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("k2 k6") // 0,4: k2 / k6 - PORT_BIT(BIT_MASK(5) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_NAME("k1 k5") // 0,5: k1 / k5 - PORT_BIT(BIT_MASK(6) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("LABEL KEY") // 0,6: LABEL KEY - PORT_BIT(BIT_MASK(7) , IP_ACTIVE_HIGH , IPT_UNUSED) // 0,7: N/U - PORT_BIT(BIT_MASK(8) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') // 1,0: 8 - PORT_BIT(BIT_MASK(9) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') // 1,1: 7 - PORT_BIT(BIT_MASK(10) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') // 1,2: 6 - PORT_BIT(BIT_MASK(11) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') // 1,3: 5 - PORT_BIT(BIT_MASK(12) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') // 1,4: 4 - PORT_BIT(BIT_MASK(13) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') // 1,5: 3 - PORT_BIT(BIT_MASK(14) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') // 1,6: 2 - PORT_BIT(BIT_MASK(15) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') // 1,7: 1 - PORT_BIT(BIT_MASK(16) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') // 2,0: I - PORT_BIT(BIT_MASK(17) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') // 2,1: U - PORT_BIT(BIT_MASK(18) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') // 2,2: Y - PORT_BIT(BIT_MASK(19) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') // 2,3: T - PORT_BIT(BIT_MASK(20) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') // 2,4: R - PORT_BIT(BIT_MASK(21) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') // 2,5: E - PORT_BIT(BIT_MASK(22) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') // 2,6: W - PORT_BIT(BIT_MASK(23) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') // 2,7: Q - PORT_BIT(BIT_MASK(24) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') // 3,0: K - PORT_BIT(BIT_MASK(25) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') // 3,1: J - PORT_BIT(BIT_MASK(26) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') // 3,2: H - PORT_BIT(BIT_MASK(27) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') // 3,3: G - PORT_BIT(BIT_MASK(28) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') // 3,4: F - PORT_BIT(BIT_MASK(29) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') // 3,5: D - PORT_BIT(BIT_MASK(30) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') // 3,6: S - PORT_BIT(BIT_MASK(31) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') // 3,7: A + PORT_BIT(IOP_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) PORT_NAME("Down AUTO") // 0,0: Down / Auto + PORT_BIT(IOP_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) PORT_NAME("Up Home") // 0,1: Up / Home + PORT_BIT(IOP_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_CHAR(UCHAR_MAMEKEY(F4)) PORT_NAME("k4 k8") // 0,2: k4 / k8 + PORT_BIT(IOP_MASK(3) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_NAME("k3 k7") // 0,3: k3 / k7 + PORT_BIT(IOP_MASK(4) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_CHAR(UCHAR_MAMEKEY(F2)) PORT_NAME("k2 k6") // 0,4: k2 / k6 + PORT_BIT(IOP_MASK(5) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_CHAR(UCHAR_MAMEKEY(F1)) PORT_NAME("k1 k5") // 0,5: k1 / k5 + PORT_BIT(IOP_MASK(6) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("LABEL KEY") // 0,6: LABEL KEY + PORT_BIT(IOP_MASK(7) , IP_ACTIVE_HIGH , IPT_UNUSED) // 0,7: N/U + PORT_BIT(IOP_MASK(8) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') // 1,0: 8 + PORT_BIT(IOP_MASK(9) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') // 1,1: 7 + PORT_BIT(IOP_MASK(10) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') // 1,2: 6 + PORT_BIT(IOP_MASK(11) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') // 1,3: 5 + PORT_BIT(IOP_MASK(12) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') // 1,4: 4 + PORT_BIT(IOP_MASK(13) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') // 1,5: 3 + PORT_BIT(IOP_MASK(14) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') // 1,6: 2 + PORT_BIT(IOP_MASK(15) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') // 1,7: 1 + PORT_BIT(IOP_MASK(16) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') // 2,0: I + PORT_BIT(IOP_MASK(17) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') // 2,1: U + PORT_BIT(IOP_MASK(18) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') // 2,2: Y + PORT_BIT(IOP_MASK(19) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') // 2,3: T + PORT_BIT(IOP_MASK(20) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') // 2,4: R + PORT_BIT(IOP_MASK(21) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') // 2,5: E + PORT_BIT(IOP_MASK(22) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') // 2,6: W + PORT_BIT(IOP_MASK(23) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') // 2,7: Q + PORT_BIT(IOP_MASK(24) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') // 3,0: K + PORT_BIT(IOP_MASK(25) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') // 3,1: J + PORT_BIT(IOP_MASK(26) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') // 3,2: H + PORT_BIT(IOP_MASK(27) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') // 3,3: G + PORT_BIT(IOP_MASK(28) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') // 3,4: F + PORT_BIT(IOP_MASK(29) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') // 3,5: D + PORT_BIT(IOP_MASK(30) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') // 3,6: S + PORT_BIT(IOP_MASK(31) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') // 3,7: A PORT_START("KEY1") - PORT_BIT(BIT_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') // 4,0: M - PORT_BIT(BIT_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') // 4,1: N - PORT_BIT(BIT_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') // 4,2: B - PORT_BIT(BIT_MASK(3) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') // 4,3: V - PORT_BIT(BIT_MASK(4) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') // 4,4: C - PORT_BIT(BIT_MASK(5) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') // 4,5: X - PORT_BIT(BIT_MASK(6) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') // 4,6: Z - PORT_BIT(BIT_MASK(7) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') // 4,7: Space - PORT_BIT(BIT_MASK(8) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') // 5,0: , - PORT_BIT(BIT_MASK(9) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') // 5,1: . - PORT_BIT(BIT_MASK(10) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') // 5,2: / ? - PORT_BIT(BIT_MASK(11) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("PAUSE STEP") // 5,3: PAUSE / STEP - PORT_BIT(BIT_MASK(12) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("RUN") // 5,4: RUN - PORT_BIT(BIT_MASK(13) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) PORT_NAME("KP +") // 5,5: KP + - PORT_BIT(BIT_MASK(14) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_NAME("KP -") // 5,6: KP - - PORT_BIT(BIT_MASK(15) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) PORT_NAME("KP *") // 5,7: KP * (not sure) - PORT_BIT(BIT_MASK(16) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') // 6,0: L - PORT_BIT(BIT_MASK(17) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') // 6,1: ; - PORT_BIT(BIT_MASK(18) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') // 6,2: ' " - PORT_BIT(BIT_MASK(19) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_NAME("END LINE") // 6,3: END LINE - PORT_BIT(BIT_MASK(20) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("LIST P LST") // 6,4: LIST / P LST - PORT_BIT(BIT_MASK(21) , IP_ACTIVE_HIGH , IPT_UNUSED) // 6,5: N/U - PORT_BIT(BIT_MASK(22) , IP_ACTIVE_HIGH , IPT_UNUSED) // 6,6: N/U - PORT_BIT(BIT_MASK(23) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) PORT_NAME("KP /") // 6,7: KP / - PORT_BIT(BIT_MASK(24) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') // 7,0: O - PORT_BIT(BIT_MASK(25) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') // 7,1: P - PORT_BIT(BIT_MASK(26) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('(') PORT_CHAR('[') // 7,2: ( [ - PORT_BIT(BIT_MASK(27) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(')') PORT_CHAR(']') // 7,3: ) ] - PORT_BIT(BIT_MASK(28) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("CONT SCRATCH") // 7,4: CONT / SCRATCH - PORT_BIT(BIT_MASK(29) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("-LINE CLEAR") // 7,5: -LINE / CLEAR - PORT_BIT(BIT_MASK(30) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME(") INIT") // 7,6: ) INIT - PORT_BIT(BIT_MASK(31) , IP_ACTIVE_HIGH , IPT_UNUSED) // 7,7: N/U + PORT_BIT(IOP_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') // 4,0: M + PORT_BIT(IOP_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') // 4,1: N + PORT_BIT(IOP_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') // 4,2: B + PORT_BIT(IOP_MASK(3) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') // 4,3: V + PORT_BIT(IOP_MASK(4) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') // 4,4: C + PORT_BIT(IOP_MASK(5) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') // 4,5: X + PORT_BIT(IOP_MASK(6) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') // 4,6: Z + PORT_BIT(IOP_MASK(7) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') // 4,7: Space + PORT_BIT(IOP_MASK(8) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') // 5,0: , + PORT_BIT(IOP_MASK(9) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') // 5,1: . + PORT_BIT(IOP_MASK(10) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') // 5,2: / ? + PORT_BIT(IOP_MASK(11) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("PAUSE STEP") // 5,3: PAUSE / STEP + PORT_BIT(IOP_MASK(12) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("RUN") // 5,4: RUN + PORT_BIT(IOP_MASK(13) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(PLUS_PAD)) PORT_NAME("KP +") // 5,5: KP + + PORT_BIT(IOP_MASK(14) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD)) PORT_NAME("KP -") // 5,6: KP - + PORT_BIT(IOP_MASK(15) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_ASTERISK) PORT_CHAR(UCHAR_MAMEKEY(ASTERISK)) PORT_NAME("KP *") // 5,7: KP * (not sure) + PORT_BIT(IOP_MASK(16) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') // 6,0: L + PORT_BIT(IOP_MASK(17) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') // 6,1: ; + PORT_BIT(IOP_MASK(18) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"') // 6,2: ' " + PORT_BIT(IOP_MASK(19) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) PORT_NAME("END LINE") // 6,3: END LINE + PORT_BIT(IOP_MASK(20) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("LIST P LST") // 6,4: LIST / P LST + PORT_BIT(IOP_MASK(21) , IP_ACTIVE_HIGH , IPT_UNUSED) // 6,5: N/U + PORT_BIT(IOP_MASK(22) , IP_ACTIVE_HIGH , IPT_UNUSED) // 6,6: N/U + PORT_BIT(IOP_MASK(23) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHAR(UCHAR_MAMEKEY(SLASH_PAD)) PORT_NAME("KP /") // 6,7: KP / + PORT_BIT(IOP_MASK(24) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') // 7,0: O + PORT_BIT(IOP_MASK(25) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') // 7,1: P + PORT_BIT(IOP_MASK(26) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('(') PORT_CHAR('[') // 7,2: ( [ + PORT_BIT(IOP_MASK(27) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(')') PORT_CHAR(']') // 7,3: ) ] + PORT_BIT(IOP_MASK(28) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("CONT SCRATCH") // 7,4: CONT / SCRATCH + PORT_BIT(IOP_MASK(29) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("-LINE CLEAR") // 7,5: -LINE / CLEAR + PORT_BIT(IOP_MASK(30) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME(") INIT") // 7,6: ) INIT + PORT_BIT(IOP_MASK(31) , IP_ACTIVE_HIGH , IPT_UNUSED) // 7,7: N/U PORT_START("KEY2") - PORT_BIT(BIT_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') // 8,0: 9 - PORT_BIT(BIT_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') // 8,1: 0 - PORT_BIT(BIT_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') // 8,2: - _ - PORT_BIT(BIT_MASK(3) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') // 8,3: = + - PORT_BIT(BIT_MASK(4) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('\\') PORT_CHAR('|') // 8,4: \ | - PORT_BIT(BIT_MASK(5) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) // 8,5: BS - PORT_BIT(BIT_MASK(6) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("( RESET") // 8,6: ( RESET - PORT_BIT(BIT_MASK(7) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("^ RESLT") // 8,7: ^ / RESLT - PORT_BIT(BIT_MASK(8) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_NAME("Left GRAPH") // 9,0: LEFT / GRAPH - PORT_BIT(BIT_MASK(9) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_NAME("Right COPY") // 9,1: RIGHT / COPY - PORT_BIT(BIT_MASK(10) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_INSERT) PORT_NAME("RPL INS") // 9,2: RPL / INS - PORT_BIT(BIT_MASK(11) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_NAME("-CHAR DEL") // 9,3: -CHAR / DEL - PORT_BIT(BIT_MASK(12) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_PGDN) PORT_NAME("ROLL") // 9,4: ROLL - PORT_BIT(BIT_MASK(13) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("LOAD REW") // 9,5: LOAD / REW - PORT_BIT(BIT_MASK(14) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("STORE TEST") // 9,6: STORE / TEST - PORT_BIT(BIT_MASK(15) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("PAPER ADVANCE") // 9,7: PAPER ADVANCE + PORT_BIT(IOP_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') // 8,0: 9 + PORT_BIT(IOP_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') // 8,1: 0 + PORT_BIT(IOP_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') // 8,2: - _ + PORT_BIT(IOP_MASK(3) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') // 8,3: = + + PORT_BIT(IOP_MASK(4) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('\\') PORT_CHAR('|') // 8,4: \ | + PORT_BIT(IOP_MASK(5) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) // 8,5: BS + PORT_BIT(IOP_MASK(6) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("( RESET") // 8,6: ( RESET + PORT_BIT(IOP_MASK(7) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("^ RESLT") // 8,7: ^ / RESLT + PORT_BIT(IOP_MASK(8) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_NAME("Left GRAPH") // 9,0: LEFT / GRAPH + PORT_BIT(IOP_MASK(9) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) PORT_NAME("Right COPY") // 9,1: RIGHT / COPY + PORT_BIT(IOP_MASK(10) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_INSERT) PORT_NAME("RPL INS") // 9,2: RPL / INS + PORT_BIT(IOP_MASK(11) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_NAME("-CHAR DEL") // 9,3: -CHAR / DEL + PORT_BIT(IOP_MASK(12) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_PGDN) PORT_NAME("ROLL") // 9,4: ROLL + PORT_BIT(IOP_MASK(13) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("LOAD REW") // 9,5: LOAD / REW + PORT_BIT(IOP_MASK(14) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("STORE TEST") // 9,6: STORE / TEST + PORT_BIT(IOP_MASK(15) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_NAME("PAPER ADVANCE") // 9,7: PAPER ADVANCE PORT_START("MODKEYS") - PORT_BIT(BIT_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) // Shift - PORT_BIT(BIT_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE PORT_NAME("Shift lock") // Shift lock - PORT_BIT(BIT_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) // Control + PORT_BIT(IOP_MASK(0) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1) // Shift + PORT_BIT(IOP_MASK(1) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE PORT_NAME("Shift lock") // Shift lock + PORT_BIT(IOP_MASK(2) , IP_ACTIVE_HIGH , IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_SHIFT_2) // Control INPUT_PORTS_END @@ -1095,6 +1309,10 @@ static ADDRESS_MAP_START(cpu_mem_map , AS_PROGRAM , 8 , hp85_state) AM_RANGE(0xff08 , 0xff09) AM_DEVREADWRITE("tape" , hp_1ma6_device , reg_r , reg_w) AM_RANGE(0xff0a , 0xff0a) AM_READWRITE(clksts_r , clksts_w) AM_RANGE(0xff0b , 0xff0b) AM_READWRITE(clkdat_r , clkdat_w) + AM_RANGE(0xff0c , 0xff0c) AM_WRITE(prtlen_w) + AM_RANGE(0xff0d , 0xff0d) AM_READWRITE(prchar_r , prchar_w) + AM_RANGE(0xff0e , 0xff0e) AM_READWRITE(prtsts_r , prtctl_w) + AM_RANGE(0xff0f , 0xff0f) AM_WRITE(prtdat_w) AM_RANGE(0xff18 , 0xff18) AM_WRITE(rselec_w) AM_RANGE(0xff40 , 0xff40) AM_READWRITE(intrsc_r , intrsc_w) ADDRESS_MAP_END @@ -1113,8 +1331,8 @@ static MACHINE_CONFIG_START(hp85) MCFG_DEVICE_ADD("rombank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(rombank_mem_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(21) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(21) MCFG_ADDRESS_MAP_BANK_STRIDE(HP80_OPTROM_SIZE) MCFG_SCREEN_ADD("screen" , RASTER) @@ -1130,6 +1348,7 @@ static MACHINE_CONFIG_START(hp85) // Hw timers are updated at 1 kHz rate MCFG_TIMER_DRIVER_ADD_PERIODIC("hw_timer" , hp85_state , timer_update , attotime::from_hz(1000)) MCFG_TIMER_DRIVER_ADD("clk_busy_timer", hp85_state, clk_busy_timer) + MCFG_TIMER_DRIVER_ADD("prt_busy_timer", hp85_state, prt_busy_timer) // Beeper MCFG_SPEAKER_STANDARD_MONO("mono") @@ -1172,6 +1391,10 @@ static MACHINE_CONFIG_START(hp85) MCFG_HP80_IO_IRL_CB(WRITE8(hp85_state , irl_w)) MCFG_HP80_IO_HALT_CB(WRITE8(hp85_state , halt_w)) + // Printer output + MCFG_DEVICE_ADD("prt_graphic", BITBANGER, 0) + MCFG_DEVICE_ADD("prt_alpha", BITBANGER, 0) + MCFG_SOFTWARE_LIST_ADD("optrom_list" , "hp85_rom") MACHINE_CONFIG_END @@ -1186,6 +1409,9 @@ ROM_START(hp85) ROM_REGION(0x400 , "chargen" , 0) ROM_LOAD("chrgen.bin" , 0 , 0x400 , CRC(9c402544) SHA1(32634fc73c1544aeeefda62ebb10349c5b40729f)) + + ROM_REGION(0x400 , "prt_chargen" , 0) + ROM_LOAD("prt_chrgen.bin" , 0 , 0x400 , CRC(abeaba27) SHA1(fbf6bdd5d96df6aa5963f8cdfdeb180402b1cc85)) ROM_END COMP(1980 , hp85 , 0 , 0 , hp85 , hp85 , hp85_state , 0 , "HP" , "HP 85" , 0) diff --git a/src/mame/drivers/hp_ipc.cpp b/src/mame/drivers/hp_ipc.cpp index 455a1ff08ff..d3272864dce 100644 --- a/src/mame/drivers/hp_ipc.cpp +++ b/src/mame/drivers/hp_ipc.cpp @@ -716,8 +716,8 @@ static MACHINE_CONFIG_START(hp_ipc) MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(hp_ipc_mem_inner) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(25) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(25) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000) // horizontal time = 60 us (min) diff --git a/src/mame/drivers/hpz80unk.cpp b/src/mame/drivers/hpz80unk.cpp index 3fbfa6e2406..3f63642b353 100644 --- a/src/mame/drivers/hpz80unk.cpp +++ b/src/mame/drivers/hpz80unk.cpp @@ -12,17 +12,26 @@ Looks like roms are in 2 banks in range C000-FFFF. BASIC is included, if we can find out how to access it. Commands: -A disassemble -D +Axxxx Disassemble (. to quit) +DAxxxx,yyyy Ascii Dump of memory +DBxxxx,yyyy Binary Dump of memory +DHxxxx,yyyy Hex Dump of memory +DOxxxx,yyyy Octal dump of memory G H L -M -P Read Port -R -U -W Punch papertape -X choose Q,V,R,P (Q to quit; others ask for ram and prom ranges) +MMxxxx Modify Memory (. to quit) +Pxx Binary Display of Port +Pxx,xx Write to port +RC ??? +RF ??? +RM ??? +RT ??? +UC Displays 11111111 +US ??? +UZ Displays FFFF +W Punch papertape +X choose Q,V,R,P (Q to quit; others ask for ram and prom ranges) Y nothing Z nothing @@ -34,34 +43,61 @@ Z nothing #include "emu.h" #include "cpu/z80/z80.h" -#include "machine/terminal.h" +#include "machine/ay31015.h" +#include "bus/rs232/rs232.h" -#define TERMINAL_TAG "terminal" class hpz80unk_state : public driver_device { public: hpz80unk_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG), - m_p_rom(*this, "p_rom") - { - } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_p_rom(*this, "rom") + , m_uart1(*this, "uart1") + , m_uart2(*this, "uart2") + , m_uart3(*this, "uart3") + { } - required_device<cpu_device> m_maincpu; - required_device<generic_terminal_device> m_terminal; + DECLARE_READ8_MEMBER(port00_r); + DECLARE_READ8_MEMBER(port01_r); DECLARE_READ8_MEMBER(port02_r); DECLARE_READ8_MEMBER(port03_r); DECLARE_READ8_MEMBER(port04_r); + DECLARE_READ8_MEMBER(port0d_r); + DECLARE_WRITE8_MEMBER(port01_w); + DECLARE_WRITE8_MEMBER(port04_w); + DECLARE_WRITE8_MEMBER(port0e_w); DECLARE_READ8_MEMBER(portfc_r); - void kbd_put(u8 data); - required_shared_ptr<uint8_t> m_p_rom; - uint8_t m_term_data; + +private: uint8_t m_port02_data; virtual void machine_reset() override; + required_device<cpu_device> m_maincpu; + required_shared_ptr<uint8_t> m_p_rom; + required_device<ay31015_device> m_uart1; + required_device<ay31015_device> m_uart2; + required_device<ay31015_device> m_uart3; }; +READ8_MEMBER( hpz80unk_state::port00_r ) +{ + return (m_uart1->get_output_pin(AY31015_DAV) << 1) | (m_uart1->get_output_pin(AY31015_TBMT)) | 0xfc; +} + +READ8_MEMBER( hpz80unk_state::port01_r ) +{ + m_uart1->set_input_pin(AY31015_RDAV, 0); + uint8_t result = m_uart1->get_received_data(); + m_uart1->set_input_pin(AY31015_RDAV, 1); + return result; +} + +WRITE8_MEMBER( hpz80unk_state::port01_w ) +{ + m_uart1->set_transmit_data(data); +} + READ8_MEMBER( hpz80unk_state::port02_r ) { m_port02_data ^= 1; @@ -70,14 +106,30 @@ READ8_MEMBER( hpz80unk_state::port02_r ) READ8_MEMBER( hpz80unk_state::port03_r ) { - return (m_term_data) ? 0xff : 0xfd; + return (m_uart2->get_output_pin(AY31015_DAV) << 1) | (m_uart2->get_output_pin(AY31015_TBMT)) | 0xfc; } READ8_MEMBER( hpz80unk_state::port04_r ) { - uint8_t ret = m_term_data; - m_term_data = 0; - return ret; + m_uart2->set_input_pin(AY31015_RDAV, 0); + uint8_t result = m_uart2->get_received_data(); + m_uart2->set_input_pin(AY31015_RDAV, 1); + return result; +} + +WRITE8_MEMBER( hpz80unk_state::port04_w ) +{ + m_uart2->set_transmit_data(data); +} + +READ8_MEMBER( hpz80unk_state::port0d_r ) +{ + return (m_uart3->get_output_pin(AY31015_DAV) << 1) | (m_uart3->get_output_pin(AY31015_TBMT)) | 0xfc; +} + +WRITE8_MEMBER( hpz80unk_state::port0e_w ) +{ + m_uart3->set_transmit_data(data); } READ8_MEMBER( hpz80unk_state::portfc_r ) @@ -88,21 +140,33 @@ READ8_MEMBER( hpz80unk_state::portfc_r ) static ADDRESS_MAP_START( hpz80unk_mem, AS_PROGRAM, 8, hpz80unk_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0xbfff) AM_RAM - AM_RANGE(0xc000, 0xffff) AM_ROM AM_SHARE("p_rom") + AM_RANGE(0xc000, 0xffff) AM_ROM AM_SHARE("rom") ADDRESS_MAP_END static ADDRESS_MAP_START( hpz80unk_io, AS_IO, 8, hpz80unk_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0x01, 0x01) AM_DEVWRITE(TERMINAL_TAG, generic_terminal_device, write) + AM_RANGE(0x00, 0x00) AM_READ(port00_r) // uart1 status + AM_RANGE(0x01, 0x01) AM_READWRITE(port01_r,port01_w) // uart1 data AM_RANGE(0x02, 0x02) AM_READ(port02_r) - AM_RANGE(0x03, 0x03) AM_READ(port03_r) - AM_RANGE(0x04, 0x04) AM_READ(port04_r) + AM_RANGE(0x03, 0x03) AM_READ(port03_r) // uart2 status + AM_RANGE(0x04, 0x04) AM_READWRITE(port04_r,port04_w) // uart2 data + AM_RANGE(0x0d, 0x0d) AM_READ(port0d_r) // uart3 status + AM_RANGE(0x0e, 0x0e) AM_WRITE(port0e_w) // uart3 data + AM_RANGE(0x1d, 0x1e) // top of memory is written here, big-endian + AM_RANGE(0x1f, 0x1f) AM_READ_PORT("DSW") // select which uarts to use AM_RANGE(0xfc, 0xfc) AM_READ(portfc_r) ADDRESS_MAP_END /* Input ports */ static INPUT_PORTS_START( hpz80unk ) + // this is a theoretical switch + PORT_START("DSW") + PORT_DIPNAME( 0x03, 0x00, "UART selection") + PORT_DIPSETTING( 0x00, "In UART1, Out UART1") + PORT_DIPSETTING( 0x01, "In UART1, Out UART2") + PORT_DIPSETTING( 0x02, "In UART1, Out UART3") + PORT_DIPSETTING( 0x03, "In UART2, Out UART1") INPUT_PORTS_END @@ -110,14 +174,44 @@ void hpz80unk_state::machine_reset() { uint8_t* user1 = memregion("user1")->base(); memcpy((uint8_t*)m_p_rom, user1, 0x4000); + m_maincpu->set_pc(0xc000); + + // no idea if these are hard-coded, or programmable + m_uart1->set_input_pin(AY31015_XR, 0); + m_uart1->set_input_pin(AY31015_XR, 1); + m_uart1->set_input_pin(AY31015_SWE, 0); + m_uart1->set_input_pin(AY31015_NP, 1); + m_uart1->set_input_pin(AY31015_TSB, 0); + m_uart1->set_input_pin(AY31015_NB1, 1); + m_uart1->set_input_pin(AY31015_NB2, 1); + m_uart1->set_input_pin(AY31015_EPS, 1); + m_uart1->set_input_pin(AY31015_CS, 1); + m_uart1->set_input_pin(AY31015_CS, 0); + m_uart2->set_input_pin(AY31015_XR, 0); + m_uart2->set_input_pin(AY31015_XR, 1); + m_uart2->set_input_pin(AY31015_SWE, 0); + m_uart2->set_input_pin(AY31015_NP, 1); + m_uart2->set_input_pin(AY31015_TSB, 0); + m_uart2->set_input_pin(AY31015_NB1, 1); + m_uart2->set_input_pin(AY31015_NB2, 1); + m_uart2->set_input_pin(AY31015_EPS, 1); + m_uart2->set_input_pin(AY31015_CS, 1); + m_uart2->set_input_pin(AY31015_CS, 0); + + m_uart3->set_input_pin(AY31015_XR, 0); + m_uart3->set_input_pin(AY31015_XR, 1); + m_uart3->set_input_pin(AY31015_SWE, 0); + m_uart3->set_input_pin(AY31015_NP, 1); + m_uart3->set_input_pin(AY31015_TSB, 0); + m_uart3->set_input_pin(AY31015_NB1, 1); + m_uart3->set_input_pin(AY31015_NB2, 1); + m_uart3->set_input_pin(AY31015_EPS, 1); + m_uart3->set_input_pin(AY31015_CS, 1); + m_uart3->set_input_pin(AY31015_CS, 0); // this should be rom/ram banking } -void hpz80unk_state::kbd_put(u8 data) -{ - m_term_data = data; -} static MACHINE_CONFIG_START( hpz80unk ) /* basic machine hardware */ @@ -126,8 +220,26 @@ static MACHINE_CONFIG_START( hpz80unk ) MCFG_CPU_IO_MAP(hpz80unk_io) /* video hardware */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) - MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(hpz80unk_state, kbd_put)) + MCFG_DEVICE_ADD("uart1", AY51013, 0) // COM2502 + MCFG_AY51013_TX_CLOCK(153600) + MCFG_AY51013_RX_CLOCK(153600) + MCFG_AY51013_READ_SI_CB(DEVREADLINE("rs232a", rs232_port_device, rxd_r)) + MCFG_AY51013_WRITE_SO_CB(DEVWRITELINE("rs232a", rs232_port_device, write_txd)) + MCFG_RS232_PORT_ADD("rs232a", default_rs232_devices, "terminal") + + MCFG_DEVICE_ADD("uart2", AY51013, 0) // COM2502 + MCFG_AY51013_TX_CLOCK(153600) + MCFG_AY51013_RX_CLOCK(153600) + MCFG_AY51013_READ_SI_CB(DEVREADLINE("rs232b", rs232_port_device, rxd_r)) + MCFG_AY51013_WRITE_SO_CB(DEVWRITELINE("rs232b", rs232_port_device, write_txd)) + MCFG_RS232_PORT_ADD("rs232b", default_rs232_devices, nullptr) + + MCFG_DEVICE_ADD("uart3", AY51013, 0) // COM2502 + MCFG_AY51013_TX_CLOCK(153600) + MCFG_AY51013_RX_CLOCK(153600) + MCFG_AY51013_READ_SI_CB(DEVREADLINE("rs232c", rs232_port_device, rxd_r)) + MCFG_AY51013_WRITE_SO_CB(DEVWRITELINE("rs232c", rs232_port_device, write_txd)) + MCFG_RS232_PORT_ADD("rs232c", default_rs232_devices, nullptr) MACHINE_CONFIG_END /* ROM definition */ diff --git a/src/mame/drivers/ht68k.cpp b/src/mame/drivers/ht68k.cpp index 900c70bcc2b..b8a5445c1ff 100644 --- a/src/mame/drivers/ht68k.cpp +++ b/src/mame/drivers/ht68k.cpp @@ -129,7 +129,7 @@ static MACHINE_CONFIG_START( ht68k ) MCFG_CPU_PROGRAM_MAP(ht68k_mem) /* video hardware */ - MCFG_MC68681_ADD( "duart68681", XTAL_8MHz / 2 ) + MCFG_DEVICE_ADD( "duart68681", MC68681, XTAL_8MHz / 2 ) MCFG_MC68681_SET_EXTERNAL_CLOCKS(500000, 500000, 1000000, 1000000) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(ht68k_state, duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("rs232", rs232_port_device, write_txd)) diff --git a/src/mame/drivers/hunter2.cpp b/src/mame/drivers/hunter2.cpp index 5ea770d3db2..4d77977cf6a 100644 --- a/src/mame/drivers/hunter2.cpp +++ b/src/mame/drivers/hunter2.cpp @@ -413,19 +413,19 @@ static MACHINE_CONFIG_START( hunter2 ) MCFG_DEVICE_ADD("bank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(hunter2_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("bank2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(hunter2_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("bank3", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(hunter2_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MACHINE_CONFIG_END diff --git a/src/mame/drivers/hyprduel.cpp b/src/mame/drivers/hyprduel.cpp index e178b21a2b0..18ff03e7846 100644 --- a/src/mame/drivers/hyprduel.cpp +++ b/src/mame/drivers/hyprduel.cpp @@ -424,6 +424,7 @@ static ADDRESS_MAP_START( hyprduel_map, AS_PROGRAM, 16, hyprduel_state ) AM_RANGE(0x475000, 0x477fff) AM_RAM /* only used memory test */ AM_RANGE(0x478000, 0x4787ff) AM_RAM AM_SHARE("tiletable") /* Tiles Set */ AM_RANGE(0x478840, 0x47884d) AM_WRITE(blitter_w) AM_SHARE("blitter_regs") /* Tiles Blitter */ + AM_RANGE(0x478850, 0x478853) AM_RAM AM_SHARE("spriteregs") AM_RANGE(0x478860, 0x47886b) AM_WRITE(window_w) AM_SHARE("window") /* Tilemap Window */ AM_RANGE(0x478870, 0x47887b) AM_RAM_WRITE(scrollreg_w) AM_SHARE("scroll") /* Scroll Regs */ AM_RANGE(0x47887c, 0x47887d) AM_WRITE(scrollreg_init_w) @@ -471,6 +472,7 @@ static ADDRESS_MAP_START( magerror_map, AS_PROGRAM, 16, hyprduel_state ) AM_RANGE(0x875000, 0x877fff) AM_RAM /* only used memory test */ AM_RANGE(0x878000, 0x8787ff) AM_RAM AM_SHARE("tiletable") /* Tiles Set */ AM_RANGE(0x878840, 0x87884d) AM_WRITE(blitter_w) AM_SHARE("blitter_regs") /* Tiles Blitter */ + AM_RANGE(0x878850, 0x878853) AM_RAM AM_SHARE("spriteregs") AM_RANGE(0x878860, 0x87886b) AM_WRITE(window_w) AM_SHARE("window") /* Tilemap Window */ AM_RANGE(0x878870, 0x87887b) AM_RAM_WRITE(scrollreg_w) AM_SHARE("scroll") /* Scroll Regs */ AM_RANGE(0x87887c, 0x87887d) AM_WRITE(scrollreg_init_w) diff --git a/src/mame/drivers/ibm3153.cpp b/src/mame/drivers/ibm3153.cpp index 92d66ff8fea..19542cf5e7b 100644 --- a/src/mame/drivers/ibm3153.cpp +++ b/src/mame/drivers/ibm3153.cpp @@ -61,12 +61,12 @@ private: }; -static ADDRESS_MAP_START(ibm3153_mem, AS_PROGRAM, 8, ibm3153_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, ibm3153_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00000,0x0ffff) AM_ROM AM_REGION("user1", 0) ADDRESS_MAP_END -static ADDRESS_MAP_START(ibm3153_io, AS_IO, 8, ibm3153_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, ibm3153_state) AM_RANGE(0x0000,0xffff) AM_RAM //ADDRESS_MAP_UNMAP_HIGH //ADDRESS_MAP_GLOBAL_MASK(0xff) @@ -96,8 +96,8 @@ void ibm3153_state::machine_reset() static MACHINE_CONFIG_START( ibm3153 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", I80C32, XTAL_16MHz) // no idea of clock - MCFG_CPU_PROGRAM_MAP(ibm3153_mem) - MCFG_CPU_IO_MAP(ibm3153_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) diff --git a/src/mame/drivers/ibm6580.cpp b/src/mame/drivers/ibm6580.cpp index ad5785c4e95..58cdc215aca 100644 --- a/src/mame/drivers/ibm6580.cpp +++ b/src/mame/drivers/ibm6580.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Robbbert, Sergey Svishchev +// copyright-holders:Sergey Svishchev /*************************************************************************** IBM 6580 Displaywriter. diff --git a/src/mame/drivers/idsa.cpp b/src/mame/drivers/idsa.cpp index 60e4f61e149..024150bae00 100644 --- a/src/mame/drivers/idsa.cpp +++ b/src/mame/drivers/idsa.cpp @@ -9,10 +9,10 @@ Hardware: --------- CPU: Z80 @ 4 MHz INT: IRQ @ 977 Hz (4MHz/2048/2) or 488 Hz (4MHz/2048/4) -IO: DMA, AY8910 ports +DRIVERS: 2 x 8255 driving lamps and coils, used as demultiplexers only (no read access) DISPLAY: bsktball: 7-digit 7-segment panels with PROM-based 5-bit BCD data (allowing a simple alphabet) v1: 6-digit 7-segment panels with BCD decoding -SOUND: 2 x AY8910 @ 2 MHz plus SP0256 @ 3.12 MHz on board +SOUND: 2 x AY8910 @ 2 MHz (also used as output interface) plus SP0256 @ 3.12 MHz on board Schematic is terrible, lots of important info left out. Need the V1 manual & schematic. @@ -32,6 +32,7 @@ ToDO: #include "sound/ay8910.h" #include "sound/sp0256.h" #include "machine/clock.h" +#include "machine/i8255.h" #include "speaker.h" @@ -42,6 +43,7 @@ public: : genpin_class(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_speech(*this, "speech") + , m_ppi(*this, "ppi%u", 1) { } DECLARE_WRITE_LINE_MEMBER(clock_w); @@ -54,10 +56,13 @@ public: DECLARE_WRITE8_MEMBER(ay2_b_w); private: - uint16_t m_irqcnt; virtual void machine_reset() override; + + uint16_t m_irqcnt; + uint8_t m_ppi_data; required_device<cpu_device> m_maincpu; required_device<sp0256_device> m_speech; + required_device_array<i8255_device, 2> m_ppi; }; static ADDRESS_MAP_START( maincpu_map, AS_PROGRAM, 8, idsa_state ) @@ -228,18 +233,26 @@ WRITE8_MEMBER( idsa_state::port90_w ) // AY ports are for lamps and solenoids WRITE8_MEMBER( idsa_state::ay1_a_w ) { + //logerror("%s: AY1 port A = %02X\n", machine().describe_context(), data); + if (!BIT(data, 2)) + m_ppi[0]->write(space, data & 0x03, m_ppi_data); + if (!BIT(data, 3)) + m_ppi[1]->write(space, data & 0x03, m_ppi_data); } WRITE8_MEMBER( idsa_state::ay1_b_w ) { + m_ppi_data = data; } WRITE8_MEMBER( idsa_state::ay2_a_w ) { + //logerror("%s: AY2 port A = %02X\n", machine().describe_context(), data); } WRITE8_MEMBER( idsa_state::ay2_b_w ) { + //logerror("%s: AY2 port B = %02X\n", machine().describe_context(), data); } WRITE_LINE_MEMBER( idsa_state::clock_w ) @@ -280,14 +293,19 @@ static MACHINE_CONFIG_START( idsa ) MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_SOUND_ADD("speech", SP0256, 3120000) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.5) + MCFG_SOUND_ADD("aysnd1", AY8910, 2000000) // 2Mhz according to pinmame, schematic omits the clock line MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(idsa_state, ay1_a_w)) MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(idsa_state, ay1_b_w)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.75) + MCFG_SOUND_ADD("aysnd2", AY8910, 2000000) MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(idsa_state, ay2_a_w)) MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(idsa_state, ay2_b_w)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.75) + + MCFG_DEVICE_ADD("ppi1", I8255, 0) + MCFG_DEVICE_ADD("ppi2", I8255, 0) MACHINE_CONFIG_END diff --git a/src/mame/drivers/igs_m027.cpp b/src/mame/drivers/igs_m027.cpp index 7db33800f5c..a2389ee2a6a 100644 --- a/src/mame/drivers/igs_m027.cpp +++ b/src/mame/drivers/igs_m027.cpp @@ -329,7 +329,7 @@ INPUT_PORTS_END INTERRUPT_GEN_MEMBER(igs_m027_state::igs_majhong_interrupt) { - generic_pulse_irq_line(device.execute(), ARM7_FIRQ_LINE, 1); + device.execute().pulse_input_line(ARM7_FIRQ_LINE, device.execute().minimum_quantum_time()); } diff --git a/src/mame/drivers/imsai.cpp b/src/mame/drivers/imsai.cpp index dc87d6ae0c1..d3f21760f0f 100644 --- a/src/mame/drivers/imsai.cpp +++ b/src/mame/drivers/imsai.cpp @@ -18,6 +18,7 @@ #include "emu.h" #include "cpu/i8085/i8085.h" +//#include "bus/s100/s100.h" #include "machine/i8251.h" #include "machine/pit8253.h" #include "machine/terminal.h" diff --git a/src/mame/drivers/instruct.cpp b/src/mame/drivers/instruct.cpp index b59b2faab31..dee933173c9 100644 --- a/src/mame/drivers/instruct.cpp +++ b/src/mame/drivers/instruct.cpp @@ -214,7 +214,7 @@ INTERRUPT_GEN_MEMBER( instruct_state::t2l_int ) } } -static ADDRESS_MAP_START( instruct_mem, AS_PROGRAM, 8, instruct_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, instruct_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x0ffe) AM_RAM AM_SHARE("mainram") AM_RANGE(0x0fff, 0x0fff) AM_READWRITE(port_r,port_w) @@ -223,7 +223,7 @@ static ADDRESS_MAP_START( instruct_mem, AS_PROGRAM, 8, instruct_state ) AM_RANGE(0x2000, 0x7fff) AM_RAM AM_SHARE("extram") ADDRESS_MAP_END -static ADDRESS_MAP_START( instruct_io, AS_IO, 8, instruct_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, instruct_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x07, 0x07) AM_READWRITE(port_r,port_w) AM_RANGE(0xf8, 0xf8) AM_WRITE(portf8_w) @@ -234,7 +234,7 @@ static ADDRESS_MAP_START( instruct_io, AS_IO, 8, instruct_state ) AM_RANGE(0xfe, 0xfe) AM_READ(portfe_r) ADDRESS_MAP_END -static ADDRESS_MAP_START( instruct_data, AS_DATA, 8, instruct_state ) +static ADDRESS_MAP_START( data_map, AS_DATA, 8, instruct_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(S2650_DATA_PORT, S2650_DATA_PORT) AM_READWRITE(port_r,port_w) ADDRESS_MAP_END @@ -411,9 +411,9 @@ QUICKLOAD_LOAD_MEMBER( instruct_state, instruct ) static MACHINE_CONFIG_START( instruct ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",S2650, XTAL_3_579545MHz / 4) - MCFG_CPU_PROGRAM_MAP(instruct_mem) - MCFG_CPU_IO_MAP(instruct_io) - MCFG_CPU_DATA_MAP(instruct_data) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + MCFG_CPU_DATA_MAP(data_map) MCFG_CPU_PERIODIC_INT_DRIVER(instruct_state, t2l_int, 120) MCFG_S2650_SENSE_INPUT(READLINE(instruct_state, sense_r)) MCFG_S2650_FLAG_OUTPUT(WRITELINE(instruct_state, flag_w)) diff --git a/src/mame/drivers/intellec4.cpp b/src/mame/drivers/intellec4.cpp index 0790425401d..5e3bc8139f6 100644 --- a/src/mame/drivers/intellec4.cpp +++ b/src/mame/drivers/intellec4.cpp @@ -311,15 +311,15 @@ MACHINE_CONFIG_START(intellec4) MCFG_DEVICE_ADD("prgbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(intellec4_program_banks) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(14) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MCFG_DEVICE_ADD("rpbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(intellec4_rom_port_banks) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(14) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MCFG_DEVICE_ADD("promprg", INTEL_IMM6_76, 0) diff --git a/src/mame/drivers/interpro.cpp b/src/mame/drivers/interpro.cpp index 44bf7846b25..a1a80215321 100644 --- a/src/mame/drivers/interpro.cpp +++ b/src/mame/drivers/interpro.cpp @@ -104,8 +104,10 @@ * U35 128 kB EPROM (MPRGW510B) Boot ROM * U43? (MPRGM610P) Bitstream for XC3020? * U44 Intel 82596SX Ethernet controller (20MHz) + * U67 Intel N28F010-200 128Kx8 flash memory (200ns) * U68 CYID21603 TC150G89AF * U71 LSI L1A6104 CICD 95801 Intergraph I/O gate array + * U76 Intel N28F010-200 128Kx8 flash memory (200ns) * U81 NCR 53C94 SCSI controller * U86 24.0 MHz crystal Clock source for 53C94? * U87 4.9152 MHz crystal Clock source for 8530s? @@ -129,7 +131,9 @@ * U43? (MPRGM610P) Bitstream for XC3020? * U44 Intel 82596SX? Ethernet controller * U68 CYID21603 TC150G89AF + * U67 Intel N28F010 128Kx8 flash memory * U71 LSI L1A7374 CIDC094A3 Intergraph I/O gate array + * U76 Intel N28F010 128Kx8 flash memory * U81 NCR 53C94 SCSI controller * U86 24.0 MHz crystal Clock source for 53C94? * U87 4.9152 MHz crystal Clock source for 8530s? @@ -155,14 +159,6 @@ #define VERBOSE 0 #include "logmacro.h" -// FIXME: eeprom/flash device embedded here until real device is known -DEFINE_DEVICE_TYPE(INTERPRO_EEPROM, interpro_eeprom_device, "interpro_eeprom", "InterPro Flash EEPROM"); - -interpro_eeprom_device::interpro_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : eeprom_base_device(mconfig, INTERPRO_EEPROM, tag, owner) -{ -} - void interpro_state::machine_start() { // FIXME: disabled for now to avoid cold start diagnostic errors @@ -186,8 +182,14 @@ void interpro_state::machine_reset() m_sreg_ctrl1 = CTRL1_FLOPLOW; } -DRIVER_INIT_MEMBER(interpro_state, interpro) +DRIVER_INIT_MEMBER(interpro_state, common) +{ +} + +DRIVER_INIT_MEMBER(turquoise_state, turquoise) { + interpro_state::init_common(); + // FIXME: not all memory sizes are reported properly using fdm "5 inqhw" and // "optimum_memory" commands @@ -197,11 +199,26 @@ DRIVER_INIT_MEMBER(interpro_state, interpro) // 128 = reports 128M, 16x8 // 256 = reports 256M, 32x8 - // grab the main memory space from the mmu - address_space &space = m_mmu->space(0); + // map the configured ram + m_d_cammu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer()); + m_i_cammu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer()); +} + +DRIVER_INIT_MEMBER(sapphire_state, sapphire) +{ + interpro_state::init_common(); + + // FIXME: not all memory sizes are reported properly using fdm "5 inqhw" and + // "optimum_memory" commands + + // 16 = reports 16M, banks empty? + // 32 = reports 16M, banks empty? + // 64 = reports 128M, 16x8 + // 128 = reports 128M, 16x8 + // 256 = reports 256M, 32x8 // map the configured ram - space.install_ram(0, m_ram->mask(), m_ram->pointer()); + m_mmu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer()); } WRITE16_MEMBER(interpro_state::sreg_led_w) @@ -242,7 +259,9 @@ WRITE16_MEMBER(sapphire_state::sreg_ctrl2_w) { interpro_state::sreg_ctrl2_w(space, offset, data, mem_mask); - m_eeprom->write_enable(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE); + // enable/disable programming power on both flash devices + m_flash_lo->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE); + m_flash_hi->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE); } READ16_MEMBER(interpro_state::sreg_error_r) @@ -301,12 +320,20 @@ READ8_MEMBER(interpro_state::nodeid_r) } // these maps connect the cpu virtual addresses to the mmu -static ADDRESS_MAP_START(clipper_insn_map, AS_PROGRAM, 32, interpro_state) - AM_RANGE(0x00000000, 0xffffffff) AM_DEVREAD32(INTERPRO_MMU_TAG, cammu_device, insn_r, 0xffffffff) +static ADDRESS_MAP_START(c300_insn_map, AS_PROGRAM, 32, interpro_state) + AM_RANGE(0x00000000, 0xffffffff) AM_DEVREAD(INTERPRO_MMU_TAG "_i", cammu_device, read) ADDRESS_MAP_END -static ADDRESS_MAP_START(clipper_data_map, AS_DATA, 32, interpro_state) - AM_RANGE(0x00000000, 0xffffffff) AM_DEVREADWRITE32(INTERPRO_MMU_TAG, cammu_device, data_r, data_w, 0xffffffff) +static ADDRESS_MAP_START(c300_data_map, AS_DATA, 32, interpro_state) + AM_RANGE(0x00000000, 0xffffffff) AM_DEVREADWRITE(INTERPRO_MMU_TAG "_d", cammu_device, read, write) +ADDRESS_MAP_END + +static ADDRESS_MAP_START(c400_insn_map, AS_PROGRAM, 32, interpro_state) + AM_RANGE(0x00000000, 0xffffffff) AM_DEVREAD(INTERPRO_MMU_TAG, cammu_device, read) +ADDRESS_MAP_END + +static ADDRESS_MAP_START(c400_data_map, AS_DATA, 32, interpro_state) + AM_RANGE(0x00000000, 0xffffffff) AM_DEVREADWRITE(INTERPRO_MMU_TAG, cammu_device, read, write) ADDRESS_MAP_END static ADDRESS_MAP_START(interpro_common_map, 0, 32, interpro_state) @@ -376,19 +403,22 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(sapphire_main_map, 0, 32, sapphire_state) AM_RANGE(0x00000000, 0x00ffffff) AM_RAM AM_SHARE(RAM_TAG) AM_RANGE(0x7f100000, 0x7f11ffff) AM_ROM AM_REGION(INTERPRO_EPROM_TAG, 0) - AM_RANGE(0x7f180000, 0x7f1bffff) AM_DEVREADWRITE16(INTERPRO_EEPROM_TAG, interpro_eeprom_device, eeprom_r, eeprom_w, 0xffffffff) + AM_RANGE(0x7f180000, 0x7f1fffff) AM_DEVREADWRITE8(INTERPRO_FLASH_TAG "_lo", intel_28f010_device, read, write, 0x00ff00ff) AM_MASK(0x3ffff) + AM_RANGE(0x7f180000, 0x7f1fffff) AM_DEVREADWRITE8(INTERPRO_FLASH_TAG "_hi", intel_28f010_device, read, write, 0xff00ff00) AM_MASK(0x3ffff) AM_IMPORT_FROM(sapphire_base_map) ADDRESS_MAP_END static ADDRESS_MAP_START(turquoise_io_map, 1, 32, interpro_state) - AM_RANGE(0x00000000, 0x00001fff) AM_DEVICE(INTERPRO_MMU_TAG, cammu_device, map) + AM_RANGE(0x00000800, 0x000009ff) AM_DEVICE(INTERPRO_MMU_TAG "_d", cammu_c3_device, map) + AM_RANGE(0x00000a00, 0x00000bff) AM_DEVICE(INTERPRO_MMU_TAG "_i", cammu_c3_device, map) + AM_RANGE(0x00000c00, 0x00000dff) AM_DEVICE(INTERPRO_MMU_TAG "_d", cammu_c3_device, map_global) AM_IMPORT_FROM(turquoise_base_map) ADDRESS_MAP_END static ADDRESS_MAP_START(sapphire_io_map, 1, 32, interpro_state) - AM_RANGE(0x00000000, 0x00001fff) AM_DEVICE(INTERPRO_MMU_TAG, cammu_device, map) + AM_RANGE(0x00000000, 0x00001fff) AM_DEVICE(INTERPRO_MMU_TAG, cammu_c4_device, map) AM_IMPORT_FROM(sapphire_base_map) ADDRESS_MAP_END @@ -487,8 +517,6 @@ static MACHINE_CONFIG_START(ioga) // ioga floppy terminal count, ethernet channel attention MCFG_INTERPRO_IOGA_FDCTC_CB(DEVWRITELINE(INTERPRO_FDC_TAG, upd765_family_device, tc_line_w)) MCFG_INTERPRO_IOGA_ETH_CA_CB(DEVWRITELINE(INTERPRO_ETH_TAG, i82586_base_device, ca)) - - MCFG_INTERPRO_IOGA_DMA_BUS(INTERPRO_CAMMU_TAG, 0) MACHINE_CONFIG_END static INPUT_PORTS_START(interpro) @@ -542,15 +570,24 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED(turquoise, interpro) MCFG_CPU_ADD(INTERPRO_CPU_TAG, CLIPPER_C300, XTAL_12_5MHz) - MCFG_CPU_PROGRAM_MAP(clipper_insn_map) - MCFG_CPU_DATA_MAP(clipper_data_map) + MCFG_CPU_PROGRAM_MAP(c300_insn_map) + MCFG_CPU_DATA_MAP(c300_data_map) MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt) - MCFG_DEVICE_ADD(INTERPRO_MMU_TAG, CAMMU_C3, 0) + MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_i", CAMMU_C3, 0) + MCFG_DEVICE_ADDRESS_MAP(0, turquoise_main_map) + MCFG_DEVICE_ADDRESS_MAP(1, turquoise_io_map) + MCFG_DEVICE_ADDRESS_MAP(2, interpro_boot_map) + MCFG_CAMMU_SSW_CB(DEVREAD32(INTERPRO_CPU_TAG, clipper_device, get_ssw)) + MCFG_CAMMU_EXCEPTION_CB(DEVWRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception)) + + MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_d", CAMMU_C3, 0) MCFG_DEVICE_ADDRESS_MAP(0, turquoise_main_map) MCFG_DEVICE_ADDRESS_MAP(1, turquoise_io_map) MCFG_DEVICE_ADDRESS_MAP(2, interpro_boot_map) MCFG_CAMMU_SSW_CB(DEVREAD32(INTERPRO_CPU_TAG, clipper_device, get_ssw)) + MCFG_CAMMU_EXCEPTION_CB(DEVWRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception)) + MCFG_CAMMU_LINK(INTERPRO_MMU_TAG "_i") // boot fails memory test without this MCFG_DEVICE_MODIFY(RAM_TAG) @@ -588,13 +625,17 @@ static MACHINE_CONFIG_DERIVED(turquoise, interpro) // i/o gate array MCFG_DEVICE_ADD(INTERPRO_IOGA_TAG, TURQUOISE_IOGA, 0) + MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_MMU_TAG "_d", 0) MCFG_FRAGMENT_ADD(ioga) + + MCFG_DEVICE_MODIFY(INTERPRO_SRBUS_TAG) + MCFG_SR_MEMORY(INTERPRO_MMU_TAG "_d", 0, 1) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED(sapphire, interpro) MCFG_CPU_ADD(INTERPRO_CPU_TAG, CLIPPER_C400, XTAL_12_5MHz) - MCFG_CPU_PROGRAM_MAP(clipper_insn_map) - MCFG_CPU_DATA_MAP(clipper_data_map) + MCFG_CPU_PROGRAM_MAP(c400_insn_map) + MCFG_CPU_DATA_MAP(c400_data_map) MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt) MCFG_DEVICE_ADD(INTERPRO_MMU_TAG, CAMMU_C4T, 0) @@ -602,6 +643,7 @@ static MACHINE_CONFIG_DERIVED(sapphire, interpro) MCFG_DEVICE_ADDRESS_MAP(1, sapphire_io_map) MCFG_DEVICE_ADDRESS_MAP(2, interpro_boot_map) MCFG_CAMMU_SSW_CB(DEVREAD32(INTERPRO_CPU_TAG, clipper_device, get_ssw)) + MCFG_CAMMU_EXCEPTION_CB(DEVWRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception)) // memory control gate array MCFG_DEVICE_ADD(INTERPRO_MCGA_TAG, INTERPRO_FMCC, 0) @@ -633,12 +675,16 @@ static MACHINE_CONFIG_DERIVED(sapphire, interpro) // i/o gate array MCFG_DEVICE_ADD(INTERPRO_IOGA_TAG, SAPPHIRE_IOGA, 0) + MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_MMU_TAG, 0) MCFG_FRAGMENT_ADD(ioga) - // eeprom - MCFG_DEVICE_ADD(INTERPRO_EEPROM_TAG, INTERPRO_EEPROM, 0) - MCFG_EEPROM_SIZE(0x20000, 16) - MCFG_EEPROM_WRITE_TIME(attotime::from_usec(1000)) + // flash memory + MCFG_DEVICE_ADD(INTERPRO_FLASH_TAG "_lo", INTEL_28F010, 0) + MCFG_DEVICE_ADD(INTERPRO_FLASH_TAG "_hi", INTEL_28F010, 0) + + // sr bus address spaces + MCFG_DEVICE_MODIFY(INTERPRO_SRBUS_TAG) + MCFG_SR_MEMORY(INTERPRO_MMU_TAG, 0, 1) MACHINE_CONFIG_END MACHINE_CONFIG_DERIVED(ip2000, turquoise) @@ -684,8 +730,11 @@ ROM_START(ip2400) ROM_SYSTEM_BIOS(0, "ip2400", "InterPro 2400 EPROM") ROMX_LOAD("mprgw510b__05_16_92.u35", 0x00000, 0x20000, CRC(3b2c4545) SHA1(4e4c98d1cd1035a04be8527223f44d0b687ec3ef), ROM_BIOS(1)) - ROM_REGION16_LE(0x0040000, INTERPRO_EEPROM_TAG, 0) - ROM_LOAD_OPTIONAL("c4saph.bin", 0x00000, 0x40000, CRC(a0c0899f) SHA1(dda6fbca81f9885a1a76ca3c25e80463a83a0ef7)) + ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0) + ROM_LOAD_OPTIONAL("y225.u76", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218)) + + ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0) + ROM_LOAD_OPTIONAL("y226.u67", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c)) ROM_END ROM_START(ip2500) @@ -696,8 +745,11 @@ ROM_START(ip2500) ROM_SYSTEM_BIOS(0, "ip2500", "InterPro 2500 EPROM") ROMX_LOAD("ip2500_eprom.bin", 0x00000, 0x20000, NO_DUMP, ROM_BIOS(1)) - ROM_REGION16_LE(0x0040000, INTERPRO_EEPROM_TAG, 0) - ROM_LOAD_OPTIONAL("c4saph.bin", 0x00000, 0x40000, CRC(a0c0899f) SHA1(dda6fbca81f9885a1a76ca3c25e80463a83a0ef7)) + ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0) + ROM_LOAD_OPTIONAL("y225.u76", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218)) + + ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0) + ROM_LOAD_OPTIONAL("y226.u67", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c)) ROM_END ROM_START(ip2700) @@ -708,8 +760,11 @@ ROM_START(ip2700) ROM_SYSTEM_BIOS(0, "ip2700", "InterPro 2700 EPROM") ROMX_LOAD("mprgz530a__9405181.u35", 0x00000, 0x20000, CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(1)) - ROM_REGION16_LE(0x0040000, INTERPRO_EEPROM_TAG, 0) - ROM_LOAD_OPTIONAL("c4saph.bin", 0x00000, 0x40000, CRC(a0c0899f) SHA1(dda6fbca81f9885a1a76ca3c25e80463a83a0ef7)) + ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0) + ROM_LOAD_OPTIONAL("y225.u76", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218)) + + ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0) + ROM_LOAD_OPTIONAL("y226.u67", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c)) ROM_END ROM_START(ip2800) @@ -720,13 +775,16 @@ ROM_START(ip2800) ROM_SYSTEM_BIOS(0, "ip2800", "InterPro 2800 EPROM") ROMX_LOAD("ip2800_eprom.bin", 0x00000, 0x20000, CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(1)) - ROM_REGION16_LE(0x0040000, INTERPRO_EEPROM_TAG, 0) - ROM_LOAD_OPTIONAL("c4saph.bin", 0x00000, 0x40000, CRC(a0c0899f) SHA1(dda6fbca81f9885a1a76ca3c25e80463a83a0ef7)) + ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0) + ROM_LOAD_OPTIONAL("y225.u76", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218)) + + ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0) + ROM_LOAD_OPTIONAL("y226.u67", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c)) ROM_END -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP( 1989, ip2000, 0, 0, ip2000, interpro, turquoise_state, interpro, "Intergraph", "InterPro 2000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) -COMP( 1991?, ip2400, 0, 0, ip2400, interpro, sapphire_state, interpro, "Intergraph", "InterPro 2400", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) -COMP( 1993?, ip2500, 0, 0, ip2500, interpro, sapphire_state, interpro, "Intergraph", "InterPro 2500", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) -COMP( 1992, ip2700, 0, 0, ip2700, interpro, sapphire_state, interpro, "Intergraph", "InterPro 2700", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) -COMP( 1994, ip2800, 0, 0, ip2800, interpro, sapphire_state, interpro, "Intergraph", "InterPro 2800", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +COMP( 1989, ip2000, 0, 0, ip2000, interpro, turquoise_state, turquoise, "Intergraph", "InterPro 2000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) +COMP( 1991?, ip2400, 0, 0, ip2400, interpro, sapphire_state, sapphire, "Intergraph", "InterPro 2400", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) +COMP( 1993?, ip2500, 0, 0, ip2500, interpro, sapphire_state, sapphire, "Intergraph", "InterPro 2500", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) +COMP( 1992, ip2700, 0, 0, ip2700, interpro, sapphire_state, sapphire, "Intergraph", "InterPro 2700", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) +COMP( 1994, ip2800, 0, 0, ip2800, interpro, sapphire_state, sapphire, "Intergraph", "InterPro 2800", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) diff --git a/src/mame/drivers/ipds.cpp b/src/mame/drivers/ipds.cpp index c92b9eecaea..6e0974ebbf4 100644 --- a/src/mame/drivers/ipds.cpp +++ b/src/mame/drivers/ipds.cpp @@ -158,8 +158,12 @@ ROM_START( ipds ) ROM_REGION( 0x10000, "slavecpu", ROMREGION_ERASEFF ) ROM_LOAD( "164196.bin", 0x0000, 0x1000, CRC(d3e18bc6) SHA1(01bc233be154bdfea9e8015839c5885cdaa08f11) ) - ROM_REGION(0x0800, "chargen",0) + ROM_REGION(0x0800, "chargen", 0) ROM_LOAD( "163642.bin", 0x0000, 0x0800, CRC(3d81b2d1) SHA1(262a42920f15f1156ad0717c876cc0b2ed947ec5) ) + + ROM_REGION(0x1000, "user1", 0) + ROM_LOAD( "162806-001.u24", 0x0000, 0x0800, CRC(e6ba41ca) SHA1(a2d3438b728670b75c359ff49146ef57c08bf0f1) ) + ROM_LOAD( "163775-001.u8", 0x0800, 0x0800, CRC(0442163e) SHA1(737732adcfe22823db37112e28758464f5d9af7b) ) ROM_END /* Driver */ diff --git a/src/mame/drivers/iris3130.cpp b/src/mame/drivers/iris3130.cpp index 96c5ea9f1d7..fb6515b8ae2 100644 --- a/src/mame/drivers/iris3130.cpp +++ b/src/mame/drivers/iris3130.cpp @@ -423,11 +423,11 @@ static MACHINE_CONFIG_START( sgi_ip2 ) MCFG_CPU_ADD("maincpu", M68020, 16000000) MCFG_CPU_PROGRAM_MAP(sgi_ip2_map) - MCFG_MC68681_ADD( "duart68681a", XTAL_3_6864MHz ) /* Y3 3.6864MHz Xtal ??? copy-over from dectalk */ + MCFG_DEVICE_ADD( "duart68681a", MC68681, XTAL_3_6864MHz ) /* Y3 3.6864MHz Xtal ??? copy-over from dectalk */ MCFG_MC68681_IRQ_CALLBACK(WRITELINE(sgi_ip2_state, duarta_irq_handler)) MCFG_MC68681_B_TX_CALLBACK(DEVWRITELINE("rs232", rs232_port_device, write_txd)) - MCFG_MC68681_ADD( "duart68681b", XTAL_3_6864MHz ) /* Y3 3.6864MHz Xtal ??? copy-over from dectalk */ + MCFG_DEVICE_ADD( "duart68681b", MC68681, XTAL_3_6864MHz ) /* Y3 3.6864MHz Xtal ??? copy-over from dectalk */ MCFG_MC68681_IRQ_CALLBACK(WRITELINE(sgi_ip2_state, duartb_irq_handler)) MCFG_MC146818_ADD( "rtc", XTAL_4_194304Mhz ) diff --git a/src/mame/drivers/itech8.cpp b/src/mame/drivers/itech8.cpp index 73ec38b5d2b..646d3a34f63 100644 --- a/src/mame/drivers/itech8.cpp +++ b/src/mame/drivers/itech8.cpp @@ -2395,23 +2395,23 @@ ROM_START( hstennis10 ) ROM_END -ROM_START( arlingtn ) - /* banks are loaded in the opposite order from the others, */ - ROM_REGION( 0x1c000, "maincpu", 0 ) - ROM_LOAD( "ahrd121.bin", 0x10000, 0x4000, CRC(00aae02e) SHA1(3bcfbd256c34ae222dde24ba9544f19da70b698e) ) - ROM_CONTINUE( 0x04000, 0xc000 ) +ROM_START( arlingtn ) /* PCB p/n 1030 rev. 1A */ + ROM_REGION( 0x1c000, "maincpu", 0 ) /* banks are loaded in the opposite order from the others, */ + ROM_LOAD( "ahr-d_v_1.21.u5", 0x10000, 0x4000, CRC(00aae02e) SHA1(3bcfbd256c34ae222dde24ba9544f19da70b698e) ) /* Service menu reports version as 1.21-D */ + ROM_CONTINUE( 0x04000, 0xc000 ) ROM_COPY( "maincpu", 0x8000, 0x14000, 0x8000 ) ROM_REGION( 0x10000, "soundcpu", 0 ) - ROM_LOAD( "ahrsnd11.bin", 0x08000, 0x8000, CRC(dec57dca) SHA1(21a8ead10b0434629f41f6b067c49b6622569a6c) ) + ROM_LOAD( "ahr_snd_v1.1.u27", 0x08000, 0x8000, CRC(dec57dca) SHA1(21a8ead10b0434629f41f6b067c49b6622569a6c) ) ROM_REGION( 0xc0000, "grom", 0 ) - ROM_LOAD( "grom0.bin", 0x00000, 0x20000, CRC(5ef57fe5) SHA1(e877979e034a61968b432037501e25a302a17a9a) ) - ROM_LOAD( "grom1.bin", 0x20000, 0x20000, CRC(6aca95c0) SHA1(da7a899bf0812a7af178e48b5a626ce56a836579) ) - ROM_LOAD( "grom2.bin", 0x40000, 0x10000, CRC(6d6fde1b) SHA1(aaabc45d4b566be42e8d28d767e4771a96d9caae) ) + ROM_LOAD( "grom0.grom0", 0x00000, 0x20000, CRC(5ef57fe5) SHA1(e877979e034a61968b432037501e25a302a17a9a) ) + ROM_LOAD( "grom1.grom1", 0x20000, 0x20000, CRC(6aca95c0) SHA1(da7a899bf0812a7af178e48b5a626ce56a836579) ) + ROM_LOAD( "grom2.grom2", 0x40000, 0x10000, CRC(6d6fde1b) SHA1(aaabc45d4b566be42e8d28d767e4771a96d9caae) ) + /* GROM3, GROM4 & GROM5 are unpopulated */ ROM_REGION( 0x40000, "oki", 0 ) - ROM_LOAD( "srom0.bin", 0x00000, 0x40000, CRC(56087f81) SHA1(1d4a1f396ee9d8ed51d0417ea94b0b379312d72f) ) + ROM_LOAD( "srom0.srom0", 0x00000, 0x40000, CRC(56087f81) SHA1(1d4a1f396ee9d8ed51d0417ea94b0b379312d72f) ) ROM_END diff --git a/src/mame/drivers/itt3030.cpp b/src/mame/drivers/itt3030.cpp index ff6ee087728..0e6bc85a5b3 100644 --- a/src/mame/drivers/itt3030.cpp +++ b/src/mame/drivers/itt3030.cpp @@ -688,8 +688,8 @@ static MACHINE_CONFIG_START( itt3030 ) MCFG_DEVICE_ADD("lowerbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(lower48_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) MCFG_ADDRESS_MAP_BANK_STRIDE(0xc000) MCFG_DEVICE_ADD("crt5027", CRT5027, XTAL_6MHz) diff --git a/src/mame/drivers/jackpool.cpp b/src/mame/drivers/jackpool.cpp index c8fb44318e3..e6fe221f0b9 100644 --- a/src/mame/drivers/jackpool.cpp +++ b/src/mame/drivers/jackpool.cpp @@ -19,7 +19,9 @@ TODO: #include "emu.h" #include "cpu/m68000/m68000.h" +#include "machine/74259.h" #include "machine/eepromser.h" +#include "machine/ins8250.h" #include "sound/okim6295.h" #include "screen.h" #include "speaker.h" @@ -31,22 +33,20 @@ public: jackpool_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_vram(*this, "vram"), - m_io(*this, "io"), m_maincpu(*this, "maincpu"), m_eeprom(*this, "eeprom"), m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette") { } - required_shared_ptr<uint16_t> m_vram; - uint8_t m_map_vreg; - required_shared_ptr<uint16_t> m_io; - DECLARE_READ16_MEMBER(jackpool_ff_r); - DECLARE_READ16_MEMBER(jackpool_io_r); - DECLARE_WRITE16_MEMBER(jackpool_io_w); + DECLARE_READ8_MEMBER(jackpool_io_r); + DECLARE_WRITE_LINE_MEMBER(map_vreg_w); DECLARE_DRIVER_INIT(jackpool); virtual void video_start() override; uint32_t screen_update_jackpool(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(jackpool_interrupt); + + required_shared_ptr<uint16_t> m_vram; + uint8_t m_map_vreg; required_device<cpu_device> m_maincpu; required_device<eeprom_serial_93cxx_device> m_eeprom; required_device<gfxdecode_device> m_gfxdecode; @@ -102,13 +102,7 @@ uint32_t jackpool_state::screen_update_jackpool(screen_device &screen, bitmap_in return 0; } -/*Communication ram*/ -READ16_MEMBER(jackpool_state::jackpool_ff_r) -{ - return 0xffff; -} - -READ16_MEMBER(jackpool_state::jackpool_io_r) +READ8_MEMBER(jackpool_state::jackpool_io_r) { switch(offset*2) { @@ -134,54 +128,12 @@ READ16_MEMBER(jackpool_state::jackpool_io_r) } // printf("R %02x\n",offset*2); - return m_io[offset]; + return 0xff; } -WRITE16_MEMBER(jackpool_state::jackpool_io_w) +WRITE_LINE_MEMBER(jackpool_state::map_vreg_w) { - COMBINE_DATA(&m_io[offset]); - - switch(offset*2) - { - case 0x30: /* ---- ---x HOLD3 lamp */ break; - case 0x32: /* ---- ---x HOLD4 lamp */ break; - case 0x34: /* ---- ---x HOLD2 lamp */ break; - case 0x36: /* ---- ---x HOLD1 lamp */ break; - case 0x38: /* ---- ---x HOLD5 lamp */ break; - case 0x3a: /* ---- ---x START1 lamp */ break; - case 0x3c: /* ---- ---x BET lamp */ break; - case 0x3e: break; - case 0x40: /* ---- ---x PAYOUT lamp */ break; - case 0x46: /* ---- ---x coin counter */break; - case 0x4a: /* ---- ---x Ticket motor */break; - case 0x4c: /* ---- ---x Hopper motor */break; - case 0x4e: m_map_vreg = data & 1; break; - case 0x50: m_eeprom->cs_write((data & 1) ? ASSERT_LINE : CLEAR_LINE ); break; - case 0x52: m_eeprom->clk_write((data & 1) ? ASSERT_LINE : CLEAR_LINE ); break; - case 0x54: m_eeprom->di_write(data & 1); break; -// case 0x5a: m_eeprom->cs_write((data & 1) ? ASSERT_LINE : CLEAR_LINE ); break; -// case 0x5c: m_eeprom->cs_write((data & 1) ? ASSERT_LINE : CLEAR_LINE ); break; - case 0x60: break; -// default: printf("[%02x] <- %02x W\n",offset*2,data); break; - } - - #if 0 - if(offset*2 == 0x54) - { - printf("Write bit %02x\n",data); - m_eeprom->di_write(data & 1); - } - if(offset*2 == 0x52) - { - printf("Clock bit %02x\n",data); - m_eeprom->clk_write((data & 1) ? ASSERT_LINE : CLEAR_LINE ); - } - if(offset*2 == 0x50) - { - printf("chip select bit %02x\n",data); - m_eeprom->cs_write((data & 1) ? ASSERT_LINE : CLEAR_LINE ); - } - #endif + m_map_vreg = state; } static ADDRESS_MAP_START( jackpool_mem, AS_PROGRAM, 16, jackpool_state ) @@ -192,9 +144,13 @@ static ADDRESS_MAP_START( jackpool_mem, AS_PROGRAM, 16, jackpool_state ) AM_RANGE(0x348000, 0x34ffff) AM_RAM //<- vram banks 2 & 3? AM_RANGE(0x360000, 0x3603ff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") - AM_RANGE(0x380000, 0x380061) AM_READWRITE(jackpool_io_r,jackpool_io_w) AM_SHARE("io")//AM_READ(jackpool_io_r) + AM_RANGE(0x380000, 0x38002f) AM_READ8(jackpool_io_r, 0x00ff) + AM_RANGE(0x380030, 0x38003f) AM_DEVWRITE8("latch1", ls259_device, write_d0, 0x00ff) + AM_RANGE(0x380040, 0x38004f) AM_DEVWRITE8("latch2", ls259_device, write_d0, 0x00ff) + AM_RANGE(0x380050, 0x38005f) AM_DEVWRITE8("latch3", ls259_device, write_d0, 0x00ff) + AM_RANGE(0x380060, 0x380061) AM_WRITENOP // another single-bit output? - AM_RANGE(0x800000, 0x80000f) AM_READ(jackpool_ff_r) AM_WRITENOP //UART + AM_RANGE(0x800000, 0x80000f) AM_DEVREADWRITE8("uart", ns16550_device, ins8250_r, ins8250_w, 0x00ff) AM_RANGE(0xa00000, 0xa00001) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) ADDRESS_MAP_END @@ -282,8 +238,31 @@ static MACHINE_CONFIG_START( jackpool ) MCFG_SCREEN_UPDATE_DRIVER(jackpool_state, screen_update_jackpool) MCFG_SCREEN_PALETTE("palette") + MCFG_DEVICE_ADD("latch1", LS259, 0) + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(NOOP) // HOLD3 lamp + MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(NOOP) // HOLD4 lamp + MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(NOOP) // HOLD2 lamp + MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(NOOP) // HOLD1 lamp + MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(NOOP) // HOLD5 lamp + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(NOOP) // START1 lamp + MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(NOOP) // BET lamp + + MCFG_DEVICE_ADD("latch2", LS259, 0) + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(NOOP) // PAYOUT lamp + MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(NOOP) // Coin counter + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(NOOP) // Ticket motor + MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(NOOP) // Hopper motor + MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE(jackpool_state, map_vreg_w)) + + MCFG_DEVICE_ADD("latch3", LS259, 0) + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, cs_write)) + MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, clk_write)) + MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, di_write)) + MCFG_EEPROM_SERIAL_93C46_ADD("eeprom") + MCFG_DEVICE_ADD("uart", NS16550, 1843200) // exact type and clock unknown + MCFG_PALETTE_ADD("palette", 0x200) MCFG_PALETTE_FORMAT(xxxxBBBBGGGGRRRR) diff --git a/src/mame/drivers/jade.cpp b/src/mame/drivers/jade.cpp index e9bf5ee37f9..251679a3312 100644 --- a/src/mame/drivers/jade.cpp +++ b/src/mame/drivers/jade.cpp @@ -22,6 +22,7 @@ #include "machine/z80ctc.h" #include "machine/z80sio.h" #include "bus/rs232/rs232.h" +//#include "bus/s100/s100.h" class jade_state : public driver_device @@ -37,13 +38,13 @@ private: }; -static ADDRESS_MAP_START(jade_mem, AS_PROGRAM, 8, jade_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, jade_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x07ff) AM_ROM AM_REGION("roms", 0) AM_RANGE(0x0800, 0xffff) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START(jade_io, AS_IO, 8, jade_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, jade_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x28, 0x2b) AM_DEVREADWRITE("ctc2", z80ctc_device, read, write) @@ -55,17 +56,12 @@ ADDRESS_MAP_END static INPUT_PORTS_START( jade ) INPUT_PORTS_END -static DEVICE_INPUT_DEFAULTS_START( terminal ) - DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9615 ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9615 ) -DEVICE_INPUT_DEFAULTS_END - static MACHINE_CONFIG_START( jade ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) - MCFG_CPU_PROGRAM_MAP(jade_mem) - MCFG_CPU_IO_MAP(jade_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_DEVICE_ADD("ctc1", Z80CTC, XTAL_4MHz) @@ -86,16 +82,15 @@ static MACHINE_CONFIG_START( jade ) MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio_device, rxa_w)) MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio_device, ctsa_w)) - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) MACHINE_CONFIG_END /* ROM definition */ -ROM_START( jade ) +ROM_START( jgz80 ) ROM_REGION( 0x800, "roms", 0 ) ROM_LOAD( "jgz80.rom", 0x0000, 0x0800, CRC(90c4a1ef) SHA1(8a93a11051cc27f3edca24f0f4297ebe0099964e) ) ROM_END /* Driver */ -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1983, jade, 0, 0, jade, jade, jade_state, 0, "Jade Computer Products", "JGZ80", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1983, jgz80, 0, 0, jade, jade, jade_state, 0, "Jade Computer Products", "JGZ80", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) diff --git a/src/mame/drivers/jpmsys5.cpp b/src/mame/drivers/jpmsys5.cpp index 67105e2c9eb..68c98346d70 100644 --- a/src/mame/drivers/jpmsys5.cpp +++ b/src/mame/drivers/jpmsys5.cpp @@ -282,14 +282,11 @@ READ16_MEMBER(jpmsys5_state::jpm_upd7759_r) AM_RANGE(0x000000, 0x01ffff) AM_ROM \ AM_RANGE(0x040000, 0x043fff) AM_RAM AM_SHARE("nvram") \ AM_RANGE(0x046000, 0x046001) AM_WRITENOP \ - AM_RANGE(0x046020, 0x046021) AM_DEVREADWRITE8("acia6850_0", acia6850_device, status_r, control_w, 0xff) \ - AM_RANGE(0x046022, 0x046023) AM_DEVREADWRITE8("acia6850_0", acia6850_device, data_r, data_w, 0xff) \ + AM_RANGE(0x046020, 0x046023) AM_DEVREADWRITE8("acia6850_0", acia6850_device, read, write, 0xff) \ AM_RANGE(0x046040, 0x04604f) AM_DEVREADWRITE8("6840ptm", ptm6840_device, read, write, 0xff) \ AM_RANGE(0x046060, 0x046067) AM_DEVREADWRITE8("6821pia", pia6821_device, read, write,0xff) \ - AM_RANGE(0x046080, 0x046081) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0xff) \ - AM_RANGE(0x046082, 0x046083) AM_DEVREADWRITE8("acia6850_1", acia6850_device, data_r, data_w, 0xff) \ - AM_RANGE(0x04608c, 0x04608d) AM_DEVREADWRITE8("acia6850_2", acia6850_device, status_r, control_w, 0xff) \ - AM_RANGE(0x04608e, 0x04608f) AM_DEVREADWRITE8("acia6850_2", acia6850_device, data_r, data_w, 0xff) \ + AM_RANGE(0x046080, 0x046083) AM_DEVREADWRITE8("acia6850_1", acia6850_device, read, write, 0xff) \ + AM_RANGE(0x04608c, 0x04608f) AM_DEVREADWRITE8("acia6850_2", acia6850_device, read, write, 0xff) \ AM_RANGE(0x0460c0, 0x0460c1) AM_WRITENOP \ AM_RANGE(0x048000, 0x04801f) AM_READWRITE(coins_r, coins_w) \ AM_RANGE(0x04c000, 0x04c0ff) AM_READ(mux_r) AM_WRITE(mux_w) diff --git a/src/mame/drivers/jupiter.cpp b/src/mame/drivers/jupiter.cpp index e9b53971e4a..fb40dd79e20 100644 --- a/src/mame/drivers/jupiter.cpp +++ b/src/mame/drivers/jupiter.cpp @@ -110,10 +110,8 @@ static ADDRESS_MAP_START( jupiter2_mem, AS_PROGRAM, 8, jupiter2_state ) // AM_RANGE(0xff90, 0xff93) Hytype Parallel Printer PIA // AM_RANGE(0xffa0, 0xffa7) Persci Floppy Disk Controller // AM_RANGE(0xffb0, 0xffb3) Video PIA - AM_RANGE(0xffc0, 0xffc0) AM_DEVREADWRITE("acia0", acia6850_device, status_r, control_w) // Serial Port 0 ACIA - AM_RANGE(0xffc1, 0xffc1) AM_DEVREADWRITE("acia0", acia6850_device, data_r, data_w) - AM_RANGE(0xffc4, 0xffc4) AM_DEVREADWRITE("acia1", acia6850_device, status_r, control_w) // Serial Port 1 ACIA - AM_RANGE(0xffc5, 0xffc5) AM_DEVREADWRITE("acia1", acia6850_device, data_r, data_w) + AM_RANGE(0xffc0, 0xffc1) AM_DEVREADWRITE("acia0", acia6850_device, read, write) // Serial Port 0 ACIA + AM_RANGE(0xffc4, 0xffc5) AM_DEVREADWRITE("acia1", acia6850_device, read, write) // Serial Port 1 ACIA // AM_RANGE(0xffc8, 0xffc9) Serial Port 2 ACIA // AM_RANGE(0xffcc, 0xffcd) Serial Port 3 ACIA // AM_RANGE(0xffd0, 0xffd1) Serial Port 4 ACIA / Cassette diff --git a/src/mame/drivers/k8915.cpp b/src/mame/drivers/k8915.cpp index 4ef64f931d1..9603825faf0 100644 --- a/src/mame/drivers/k8915.cpp +++ b/src/mame/drivers/k8915.cpp @@ -2,17 +2,20 @@ // copyright-holders:Miodrag Milanovic, Robbbert /*************************************************************************** - Robotron K8915 +Robotron K8915 - 30/08/2010 Skeleton driver +2010-08-30 - When it says DIAGNOSTIC RAZ P, press enter. +When it says DIAGNOSTIC RAZ P, press enter. ****************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" -#include "machine/keyboard.h" +#include "machine/z80ctc.h" +#include "machine/z80sio.h" +#include "machine/clock.h" +#include "bus/rs232/rs232.h" #include "screen.h" class k8915_state : public driver_device @@ -23,38 +26,20 @@ public: , m_maincpu(*this, "maincpu") , m_p_videoram(*this, "videoram") , m_p_chargen(*this, "chargen") - { - } + { } - DECLARE_READ8_MEMBER(k8915_52_r); - DECLARE_READ8_MEMBER(k8915_53_r); DECLARE_WRITE8_MEMBER(k8915_a8_w); - void kbd_put(u8 data); DECLARE_DRIVER_INIT(k8915); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); private: uint8_t m_framecnt; - uint8_t m_term_data; virtual void machine_reset() override; required_device<cpu_device> m_maincpu; required_shared_ptr<uint8_t> m_p_videoram; required_region_ptr<u8> m_p_chargen; }; -READ8_MEMBER( k8915_state::k8915_52_r ) -{ -// get data from ascii keyboard - uint8_t ret = m_term_data; - m_term_data = 0; - return ret; -} - -READ8_MEMBER( k8915_state::k8915_53_r ) -{ -// keyboard status - return m_term_data ? 1 : 0; -} WRITE8_MEMBER( k8915_state::k8915_a8_w ) { @@ -65,17 +50,17 @@ WRITE8_MEMBER( k8915_state::k8915_a8_w ) membank("boot")->set_entry(1); // rom at 0000 } -static ADDRESS_MAP_START(k8915_mem, AS_PROGRAM, 8, k8915_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, k8915_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x0fff) AM_RAMBANK("boot") AM_RANGE(0x1000, 0x17ff) AM_RAM AM_SHARE("videoram") AM_RANGE(0x1800, 0xffff) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START(k8915_io, AS_IO, 8, k8915_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, k8915_state) ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0x52, 0x52) AM_READ(k8915_52_r) - AM_RANGE(0x53, 0x53) AM_READ(k8915_53_r) + AM_RANGE(0x50, 0x53) AM_DEVREADWRITE("sio", z80sio_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x58, 0x5b) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) AM_RANGE(0xa8, 0xa8) AM_WRITE(k8915_a8_w) ADDRESS_MAP_END @@ -140,16 +125,12 @@ uint32_t k8915_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, return 0; } -void k8915_state::kbd_put(u8 data) -{ - m_term_data = data; -} static MACHINE_CONFIG_START( k8915 ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", Z80, XTAL_16MHz / 4) - MCFG_CPU_PROGRAM_MAP(k8915_mem) - MCFG_CPU_IO_MAP(k8915_io) + MCFG_CPU_ADD("maincpu", Z80, XTAL_4_9152MHz / 2) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) @@ -162,8 +143,21 @@ static MACHINE_CONFIG_START( k8915 ) MCFG_PALETTE_ADD_MONOCHROME("palette") - MCFG_DEVICE_ADD("keyboard", GENERIC_KEYBOARD, 0) - MCFG_GENERIC_KEYBOARD_CB(PUT(k8915_state, kbd_put)) + MCFG_DEVICE_ADD("ctc_clock", CLOCK, XTAL_4_9152MHz / 2) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc", z80ctc_device, trg2)) + + MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_4_9152MHz / 2) + MCFG_Z80CTC_ZC2_CB(DEVWRITELINE("sio", z80sio_device, rxtxcb_w)) + + MCFG_DEVICE_ADD("sio", Z80SIO, XTAL_4_9152MHz / 2) + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "keyboard") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio_device, rxb_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio", z80sio_device, dcdb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio_device, ctsb_w)) MACHINE_CONFIG_END diff --git a/src/mame/drivers/kaypro.cpp b/src/mame/drivers/kaypro.cpp index af9252c05c9..50179c729c8 100644 --- a/src/mame/drivers/kaypro.cpp +++ b/src/mame/drivers/kaypro.cpp @@ -3,7 +3,7 @@ /************************************************************************************************* - Kaypro 2/83 computer - the very first Kaypro II - 2 full size floppy drives. + The Kaypro 2/83 computer - the very first Kaypro II - 2 full height floppy drives. Each disk was single sided, and could hold 191k. The computer had 2x pio and 1x sio. One of the sio ports communicated with the keyboard with a coiled telephone cord, complete with modular plug on each end. The keyboard carries @@ -23,17 +23,19 @@ C: floppy ToDo: - - - See about getting keyboard to work as a serial device. - - Need dump of 87C51 cpu in the keyboard. + - Find original Kaycomp ROMs + - Need dump of 87C51 cpu in a Kaypro II keyboard variant - Kaypro 2x, 4a: floppy not working "No operating system present on this disk" - Kaypro 10: Boots from floppy, but needs hard drive added. - - Kaypro 4p88: works as a normal Kaypro 4, extra hardware not done + - "Univeral"-ROM 81-478A: Boots, but fails with CP/M "BDOS Error on A:", was working until MAME v0190 + - fix Kayplus 84 ROM screen corruption + - Kaypro iip88, 484p88: works as a normal Kaypro 4, extra hardware not done - Kaypro Robie: has twin 2.6MB 5.25 floppy drives which we don't support, no software available + - Handyman ROM is really an add-on board with 16K proprietory RAM - Hard Disk not emulated. - The controller is a WD1002 (original version, for Winchester drives). + The controller is a WD1002-HD0 (original version, for Winchester drives), HD is 10MB, e.g. Shugart 712 - RTC type MM58167A to be added. Modem chips TMS99531, TMS99532 to be developed. @@ -49,13 +51,12 @@ #include "machine/clock.h" #include "machine/com8116.h" #include "machine/z80sio.h" -#include "formats/kaypro_dsk.h" #include "screen.h" #include "softlist.h" #include "speaker.h" -READ8_MEMBER( kaypro_state::kaypro2x_87_r ) { return 0x7f; } /* to bypass unemulated HD controller */ +READ8_MEMBER( kaypro_state::kaypro484_87_r ) { return 0x7f; } /* to bypass unemulated HD controller */ /*********************************************************** @@ -80,7 +81,7 @@ static ADDRESS_MAP_START( kayproii_io, AS_IO, 8, kaypro_state ) AM_RANGE(0x1c, 0x1f) AM_DEVREADWRITE("z80pio_s", z80pio_device, read_alt, write_alt) ADDRESS_MAP_END -static ADDRESS_MAP_START( kaypro2x_io, AS_IO, 8, kaypro_state ) +static ADDRESS_MAP_START( kaypro484_io, AS_IO, 8, kaypro_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00, 0x03) AM_DEVWRITE("brg", com8116_device, str_w) @@ -88,14 +89,14 @@ static ADDRESS_MAP_START( kaypro2x_io, AS_IO, 8, kaypro_state ) AM_RANGE(0x08, 0x0b) AM_DEVWRITE("brg", com8116_device, stt_w) AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("sio_2", z80sio_device, ba_cd_r, ba_cd_w) AM_RANGE(0x10, 0x13) AM_DEVREADWRITE("fdc", fd1793_device, read, write) - AM_RANGE(0x14, 0x17) AM_READWRITE(kaypro2x_system_port_r,kaypro2x_system_port_w) + AM_RANGE(0x14, 0x17) AM_READWRITE(kaypro484_system_port_r,kaypro484_system_port_w) AM_RANGE(0x18, 0x1b) AM_DEVWRITE("cent_data_out", output_latch_device, write) - AM_RANGE(0x1c, 0x1c) AM_READWRITE(kaypro2x_status_r,kaypro2x_index_w) - AM_RANGE(0x1d, 0x1d) AM_DEVREAD("crtc", mc6845_device, register_r) AM_WRITE(kaypro2x_register_w) - AM_RANGE(0x1f, 0x1f) AM_READWRITE(kaypro2x_videoram_r,kaypro2x_videoram_w) + AM_RANGE(0x1c, 0x1c) AM_READWRITE(kaypro484_status_r,kaypro484_index_w) + AM_RANGE(0x1d, 0x1d) AM_DEVREAD("crtc", mc6845_device, register_r) AM_WRITE(kaypro484_register_w) + AM_RANGE(0x1f, 0x1f) AM_READWRITE(kaypro484_videoram_r,kaypro484_videoram_w) /* The below are not emulated */ -/* AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("z80pio", kaypro2x_pio_r, kaypro2x_pio_w) - for RTC and Modem +/* AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("z80pio", kaypro484_pio_r, kaypro484_pio_w) - for RTC and Modem AM_RANGE(0x24, 0x27) communicate with MM58167A RTC. Modem uses TMS99531 and TMS99532 chips. AM_RANGE(0x80, 0x80) Hard drive controller card I/O port - 10MB hard drive only fitted to the Kaypro 10 AM_RANGE(0x81, 0x81) Hard Drive READ error register, WRITE precomp @@ -106,7 +107,7 @@ static ADDRESS_MAP_START( kaypro2x_io, AS_IO, 8, kaypro_state ) AM_RANGE(0x86, 0x86) Hard Drive Size / Drive / Head register I/O AM_RANGE(0x87, 0x87) Hard Drive READ status register, WRITE command register */ AM_RANGE(0x20, 0x86) AM_NOP - AM_RANGE(0x87, 0x87) AM_READ(kaypro2x_87_r) + AM_RANGE(0x87, 0x87) AM_READ(kaypro484_87_r) ADDRESS_MAP_END @@ -133,7 +134,7 @@ static const gfx_layout kayproii_charlayout = 8*8 /* every char takes 8 bytes */ }; -static const gfx_layout kaypro2x_charlayout = +static const gfx_layout kaypro484_charlayout = { 8, 16, /* 8 x 16 characters */ 256, /* 256 characters */ @@ -150,8 +151,8 @@ static GFXDECODE_START( kayproii ) GFXDECODE_ENTRY( "chargen", 0x0000, kayproii_charlayout, 0, 1 ) GFXDECODE_END -static GFXDECODE_START( kaypro2x ) - GFXDECODE_ENTRY( "chargen", 0x0000, kaypro2x_charlayout, 0, 1 ) +static GFXDECODE_START( kaypro484 ) + GFXDECODE_ENTRY( "chargen", 0x0000, kaypro484_charlayout, 0, 1 ) GFXDECODE_END /*************************************************************** @@ -168,7 +169,7 @@ static const z80_daisy_config kayproii_daisy_chain[] = { nullptr } }; -static const z80_daisy_config kaypro2x_daisy_chain[] = +static const z80_daisy_config kaypro484_daisy_chain[] = { { "sio_1" }, /* sio for RS232C and keyboard */ { "sio_2" }, /* sio for serial printer and inbuilt modem */ @@ -176,24 +177,17 @@ static const z80_daisy_config kaypro2x_daisy_chain[] = }; - - /*********************************************************** Machine Driver ************************************************************/ -FLOPPY_FORMATS_MEMBER( kaypro_state::kayproii_floppy_formats ) - FLOPPY_KAYPROII_FORMAT -FLOPPY_FORMATS_END - -FLOPPY_FORMATS_MEMBER( kaypro_state::kaypro2x_floppy_formats ) - FLOPPY_KAYPRO2X_FORMAT -FLOPPY_FORMATS_END static SLOT_INTERFACE_START( kaypro_floppies ) - SLOT_INTERFACE( "525qd", FLOPPY_525_DD ) + SLOT_INTERFACE( "525ssdd", FLOPPY_525_SSDD ) + SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) + SLOT_INTERFACE( "525qd", FLOPPY_525_QD ) SLOT_INTERFACE_END @@ -268,27 +262,32 @@ static MACHINE_CONFIG_START( kayproii ) MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(kaypro_state, fdc_intrq_w)) MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(kaypro_state, fdc_drq_w)) MCFG_WD_FDC_FORCE_READY - MCFG_FLOPPY_DRIVE_ADD("fdc:0", kaypro_floppies, "525qd", kaypro_state::kayproii_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD("fdc:0", kaypro_floppies, "525ssdd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_SOUND(true) - MCFG_FLOPPY_DRIVE_ADD("fdc:1", kaypro_floppies, "525qd", kaypro_state::kayproii_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD("fdc:1", kaypro_floppies, "525ssdd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_SOUND(true) MCFG_SOFTWARE_LIST_ADD("flop_list","kayproii") MACHINE_CONFIG_END -static MACHINE_CONFIG_DERIVED( kaypro4, kayproii ) +static MACHINE_CONFIG_DERIVED( kayproiv, kayproii ) MCFG_DEVICE_REMOVE("z80pio_s") MCFG_DEVICE_ADD("z80pio_s", Z80PIO, 2500000) MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_Z80PIO_IN_PA_CB(READ8(kaypro_state, pio_system_r)) - MCFG_Z80PIO_OUT_PA_CB(WRITE8(kaypro_state, kaypro4_pio_system_w)) + MCFG_Z80PIO_OUT_PA_CB(WRITE8(kaypro_state, kayproiv_pio_system_w)) + MCFG_DEVICE_REMOVE("fdc:0") + MCFG_DEVICE_REMOVE("fdc:1") + MCFG_FLOPPY_DRIVE_ADD("fdc:0", kaypro_floppies, "525dd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) + MCFG_FLOPPY_DRIVE_ADD("fdc:1", kaypro_floppies, "525dd", floppy_image_device::default_floppy_formats) MACHINE_CONFIG_END -static MACHINE_CONFIG_START( kaypro2x ) +static MACHINE_CONFIG_START( kaypro484 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, XTAL_16MHz / 4) MCFG_CPU_PROGRAM_MAP(kaypro_map) - MCFG_CPU_IO_MAP(kaypro2x_io) - MCFG_Z80_DAISY_CHAIN(kaypro2x_daisy_chain) + MCFG_CPU_IO_MAP(kaypro484_io) + MCFG_Z80_DAISY_CHAIN(kaypro484_daisy_chain) MCFG_MACHINE_RESET_OVERRIDE(kaypro_state, kaypro ) @@ -299,9 +298,9 @@ static MACHINE_CONFIG_START( kaypro2x ) MCFG_SCREEN_SIZE(80*8, 25*16) MCFG_SCREEN_VISIBLE_AREA(0,80*8-1,0,25*16-1) MCFG_VIDEO_START_OVERRIDE(kaypro_state, kaypro ) - MCFG_SCREEN_UPDATE_DRIVER(kaypro_state, screen_update_kaypro2x) + MCFG_SCREEN_UPDATE_DRIVER(kaypro_state, screen_update_kaypro484) - MCFG_GFXDECODE_ADD("gfxdecode", "palette", kaypro2x) + MCFG_GFXDECODE_ADD("gfxdecode", "palette", kaypro484) MCFG_PALETTE_ADD("palette", 3) MCFG_PALETTE_INIT_OWNER(kaypro_state, kaypro) @@ -314,7 +313,7 @@ static MACHINE_CONFIG_START( kaypro2x ) MCFG_MC6845_ADD("crtc", MC6845, "screen", 2000000) /* comes out of ULA - needs to be measured */ MCFG_MC6845_SHOW_BORDER_AREA(false) MCFG_MC6845_CHAR_WIDTH(7) - MCFG_MC6845_UPDATE_ROW_CB(kaypro_state, kaypro2x_update_row) + MCFG_MC6845_UPDATE_ROW_CB(kaypro_state, kaypro484_update_row) MCFG_QUICKLOAD_ADD("quickload", kaypro_state, kaypro, "com,cpm", 3) @@ -362,18 +361,31 @@ static MACHINE_CONFIG_START( kaypro2x ) MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(kaypro_state, fdc_intrq_w)) MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(kaypro_state, fdc_drq_w)) MCFG_WD_FDC_FORCE_READY - MCFG_FLOPPY_DRIVE_ADD("fdc:0", kaypro_floppies, "525qd", kaypro_state::kaypro2x_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD("fdc:0", kaypro_floppies, "525dd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_SOUND(true) - MCFG_FLOPPY_DRIVE_ADD("fdc:1", kaypro_floppies, "525qd", kaypro_state::kaypro2x_floppy_formats) + MCFG_FLOPPY_DRIVE_ADD("fdc:1", kaypro_floppies, "525dd", floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_SOUND(true) MACHINE_CONFIG_END -static MACHINE_CONFIG_DERIVED( kaypro10, kaypro2x ) +static MACHINE_CONFIG_DERIVED( kaypro10, kaypro484 ) MCFG_DEVICE_REMOVE("fdc:1") // only has 1 floppy drive // need to add hard drive & controller MACHINE_CONFIG_END -static MACHINE_CONFIG_DERIVED( omni2, kaypro4 ) +static MACHINE_CONFIG_DERIVED( kaypronew2, kaypro484 ) + MCFG_DEVICE_REMOVE("fdc:1") // only has 1 floppy drive +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( kaypro284, kaypro484 ) + MCFG_DEVICE_REMOVE("fdc:0") + MCFG_DEVICE_REMOVE("fdc:1") + MCFG_FLOPPY_DRIVE_ADD("fdc:0", kaypro_floppies, "525ssdd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) + MCFG_FLOPPY_DRIVE_ADD("fdc:1", kaypro_floppies, "525ssdd", floppy_image_device::default_floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( omni2, kayproiv ) MCFG_SCREEN_MODIFY("screen") MCFG_SCREEN_UPDATE_DRIVER(kaypro_state, screen_update_omni2) MACHINE_CONFIG_END @@ -399,71 +411,148 @@ DRIVER_INIT_MEMBER( kaypro_state, kaypro ) /* The detested bios "universal rom" is part number 81-478 */ +// Kaypro II ROM_START(kayproii) - /* The board could take a 2716 or 2732 */ + /* The original board could take a 2716 or 2732 */ ROM_REGION(0x4000, "roms",0) - ROM_SYSTEM_BIOS( 0, "149", "149") + ROM_SYSTEM_BIOS( 0, "149", "81-149 for Kaypro Bd. 81-110") ROMX_LOAD("81-149.u47", 0x0000, 0x0800, CRC(28264bc1) SHA1(a12afb11a538fc0217e569bc29633d5270dfa51b), ROM_BIOS(1) ) - ROM_SYSTEM_BIOS( 1, "149b", "149B") + ROM_SYSTEM_BIOS( 1, "149b", "81-149B for Kaypro Bd. 81-110") ROMX_LOAD("81-149b.u47", 0x0000, 0x0800, CRC(c008549e) SHA1(b9346a16f5f9ffb6bb0eb1766c348b74056485a8), ROM_BIOS(2) ) - ROM_SYSTEM_BIOS( 2, "149c", "149C") + ROM_SYSTEM_BIOS( 2, "149c", "81-149C for Kaypro Bd. 81-110") ROMX_LOAD("81-149c.u47", 0x0000, 0x0800, CRC(1272aa65) SHA1(027fee2f5f17ba71a4738f00188e132e326536ff), ROM_BIOS(3) ) - + ROM_SYSTEM_BIOS( 3, "232", "81-232 for Kaypro Bd. 81-240") + ROMX_LOAD("81-232.u47", 0x0000, 0x1000, CRC(4918fb91) SHA1(cd9f45cc3546bcaad7254b92c5d501c40e2ef0b2), ROM_BIOS(4) ) + ROM_SYSTEM_BIOS( 4, "roadrunner", "Highland Microkit Roadrunner 1.5") + ROMX_LOAD("kaypro_ii_roadrunner_1_5.bin", 0x0000, 0x1000, CRC(ca11357d) SHA1(8e8a6d6e0d31d1051db9a24601f12a3b4639b3bb), ROM_BIOS(5) ) // does not boot here but originally comes from a II + ROM_SYSTEM_BIOS( 5, "turbo", "Advent Turbo ROM") + ROMX_LOAD("trom34_3.rom", 0x0000, 0x1000, CRC(908a4c0e) SHA1(6e220479715a812d9116b0927a9ff2792f82b2a7), ROM_BIOS(6) ) + ROM_SYSTEM_BIOS( 6, "kplus83", "MICROCode Consulting KayPLUS 83") + ROMX_LOAD("kplus83.rom", 0x0000, 0x2000, CRC(5e9b817d) SHA1(26ea875ee3659a964cbded4ed0c82a3af42db64b), ROM_BIOS(7) ) + ROM_SYSTEM_BIOS( 7, "pro8v3", "MicroCornucopia_Pro8_V3.3") + ROMX_LOAD("pro8-3.rom", 0x0000, 0x1000, CRC(f2d4c598) SHA1(269b2fddeb98db3e5eba2056ff250dff72b0561e), ROM_BIOS(8) ) ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) ROM_REGION(0x0800, "chargen", ROMREGION_INVERT) ROM_LOAD("81-146.u43", 0x0000, 0x0800, CRC(4cc7d206) SHA1(5cb880083b94bd8220aac1f87d537db7cfeb9013) ) ROM_END -ROM_START(kaypro4) +// Kaypro IV (or 4'83) +ROM_START(kayproiv) ROM_REGION(0x4000, "roms",0) - ROM_LOAD("81-232.u47", 0x0000, 0x1000, CRC(4918fb91) SHA1(cd9f45cc3546bcaad7254b92c5d501c40e2ef0b2) ) - + ROM_SYSTEM_BIOS( 0, "232", "81-232 for Kaypro Bd. 81-240") + ROMX_LOAD("81-232.u47", 0x0000, 0x1000, CRC(4918fb91) SHA1(cd9f45cc3546bcaad7254b92c5d501c40e2ef0b2), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "roadrunner", "Highland Microkit Roadrunner 1.5") + ROMX_LOAD("kaypro_ii_roadrunner_1_5.bin", 0x0000, 0x1000, CRC(ca11357d) SHA1(8e8a6d6e0d31d1051db9a24601f12a3b4639b3bb), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 2, "turbo", "Advent Turbo ROM") + ROMX_LOAD("trom34_3.rom", 0x0000, 0x1000, CRC(908a4c0e) SHA1(6e220479715a812d9116b0927a9ff2792f82b2a7), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 3, "kplus83", "MICROCode Consulting KayPLUS 83") + ROMX_LOAD("kplus83.rom", 0x0000, 0x2000, CRC(5e9b817d) SHA1(26ea875ee3659a964cbded4ed0c82a3af42db64b), ROM_BIOS(4) ) + ROM_SYSTEM_BIOS( 4, "pro8v3", "MicroCornucopia_Pro8_V3.3") + ROMX_LOAD("pro8-3.rom", 0x0000, 0x1000, CRC(f2d4c598) SHA1(269b2fddeb98db3e5eba2056ff250dff72b0561e), ROM_BIOS(5) ) ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) ROM_REGION(0x0800, "chargen", ROMREGION_INVERT) ROM_LOAD("81-146.u43", 0x0000, 0x0800, CRC(4cc7d206) SHA1(5cb880083b94bd8220aac1f87d537db7cfeb9013) ) ROM_END -ROM_START(kaypro4p88) // "KAYPRO-88" board has 128k or 256k of its own ram on it +// Kaypro 10, '83 model, hard disk cable connector in the middle of the mainboard, no space for modem or RTC +ROM_START(kaypro10) ROM_REGION(0x4000, "roms",0) - ROM_LOAD("81-232.u47", 0x0000, 0x1000, CRC(4918fb91) SHA1(cd9f45cc3546bcaad7254b92c5d501c40e2ef0b2) ) - + ROM_SYSTEM_BIOS( 0, "188", "V1.9 for Kaypro Bd. 81-180") + ROMX_LOAD("81-188.u42", 0x0000, 0x1000, CRC(6cbd6aa0) SHA1(47004f8c6e17407e4f8d613c9520f9316716d9e2), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "x", "V1.7") + ROMX_LOAD("x.bin", 0x0000, 0x0fff, BAD_DUMP CRC(01e2e7b2) SHA1(fc2f8dc8a077d0c89a74463328efa1c444662d88), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 2, "turbo", "Advent Turbo ROM") + ROMX_LOAD("trom34.rom", 0x0000, 0x2000, CRC(0ec6d39a) SHA1(8c2a92b8642e144452c28300bf50a00a11a060cd), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 3, "kplus83", "MICROCode Consulting KayPLUS 83") + ROMX_LOAD("kplus83.rom", 0x0000, 0x2000, CRC(5e9b817d) SHA1(26ea875ee3659a964cbded4ed0c82a3af42db64b), ROM_BIOS(4) ) ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) - ROM_REGION(0x0800, "chargen", ROMREGION_INVERT) - ROM_LOAD("81-146.u43", 0x0000, 0x0800, CRC(4cc7d206) SHA1(5cb880083b94bd8220aac1f87d537db7cfeb9013) ) + ROM_REGION(0x1000, "chargen",0) + ROM_LOAD("81-187.u31", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) +ROM_END - ROM_REGION(0x1000, "8088cpu",0) - ROM_LOAD("81-356.u29", 0x0000, 0x1000, CRC(948556db) SHA1(6e779866d099cc0dc8c6369bdfb37a923ac448a4) ) +// Kaypro 10, '84 model, hard disk cable on the right hand side of the mainboard +ROM_START(kaypro1084) + ROM_REGION(0x4000, "roms",0) + ROM_SYSTEM_BIOS( 0, "302", "V1.9E for Kaypro Bd. 81-181") + ROMX_LOAD("81-302.u42", 0x0000, 0x1000, CRC(3f9bee20) SHA1(b29114a199e70afe46511119b77a662e97b093a0), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "1.9ee", "V1.9ee") + ROMX_LOAD("rom19ee.bin", 0x0000, 0x0fee, BAD_DUMP CRC(c3515bd0) SHA1(48a0a43c164e4d3e75e8e916498421ef616943cf), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 2, "277", "V1.9E(F)") + ROMX_LOAD("81-277.u42", 0x0000, 0x1000, CRC(e4e1831f) SHA1(1de31ed532a461ace7a4abad1f6647eeddceb3e7), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 3, "478", "V2.01 for Kaypro Bd. 81-582 (universal)") + ROMX_LOAD("81-478.u42", 0x0000, 0x2000, CRC(de618380) SHA1(c8d6312e6eeb62a53e741f1ff3b878bdcb7b5aaa), ROM_BIOS(4) ) + ROM_SYSTEM_BIOS( 4, "turbo", "Advent Turbo ROM") + ROMX_LOAD("trom34.rom", 0x0000, 0x2000, CRC(0ec6d39a) SHA1(8c2a92b8642e144452c28300bf50a00a11a060cd), ROM_BIOS(5) ) + ROM_SYSTEM_BIOS( 5, "kplus", "MICROCode Consulting KayPLUS 84") + ROMX_LOAD("kplus84.rom", 0x0000, 0x2000, CRC(4551905a) SHA1(48f0964edfad05b214810ae5595638245c30e5c0), ROM_BIOS(6) ) + + ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) + + ROM_REGION(0x1000, "chargen",0) + ROM_LOAD("81-187.u31", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) ROM_END -ROM_START(omni2) +ROM_START(kaypro484) // later renamed in 2X (or 2X MTC to signify the inclusion of Modem and RTC in comparison with the "old" 2X) ROM_REGION(0x4000, "roms",0) - ROM_LOAD("omni2.u47", 0x0000, 0x1000, CRC(2883f9e0) SHA1(d98c784e62853582d298bf7ca84c75872847ac9b) ) + ROM_SYSTEM_BIOS( 0, "292a", "81-292a for Kaypro Bd. 81-184") + ROMX_LOAD("81-292a.u34", 0x0000, 0x1000, CRC(241f27a5) SHA1(82711289d19e9b165e35324da010466d225e503a), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "turbo", "Advent Turbo ROM") + ROMX_LOAD("trom34.rom", 0x0000, 0x2000, CRC(0ec6d39a) SHA1(8c2a92b8642e144452c28300bf50a00a11a060cd), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 2, "kplus", "MICROCode Consulting KayPLUS 84") + ROMX_LOAD("kplus84.rom", 0x0000, 0x2000, CRC(4551905a) SHA1(48f0964edfad05b214810ae5595638245c30e5c0), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 3, "pro884", "MicroCornucopia pro884 SuperMax 2.7") + ROMX_LOAD("pro884mx.rom", 0x0000, 0x2000, CRC(febc6f51) SHA1(1f009aa9b7c9a3eddd0ee6ea7321a1c47c3e9807), ROM_BIOS(4) ) + ROM_SYSTEM_BIOS( 4, "pro8v5", "MicroCornucopia Pro8 V5") + ROMX_LOAD("pro884v5.rom", 0x0000, 0x2000, CRC(fe0051b1) SHA1(cac429154d40e21174ae05ceb0017b62473cdebd), ROM_BIOS(5) ) ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) - ROM_REGION(0x0800, "chargen", ROMREGION_INVERT) - ROM_LOAD("omni2.u43", 0x0000, 0x0800, CRC(049b3381) SHA1(46f1d4f038747ba9048b075dc617361be088f82a) ) + ROM_REGION(0x1000, "chargen",0) + ROM_LOAD("81-235.u9", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) ROM_END -ROM_START(omni4) + // Kaypro 2'84, like the 4'84, but two single sided drives, no RTC, no modem +ROM_START(kaypro284) ROM_REGION(0x4000, "roms",0) - ROM_LOAD("omni4.u34", 0x0000, 0x2000, CRC(f24e8521) SHA1(374f2e2b791a807f103744a22c9c8f3af55f1033) ) + ROM_SYSTEM_BIOS( 0, "292a", "81-292a for Kaypro Bd. 81-184") + ROMX_LOAD("81-292a.u34", 0x0000, 0x1000, CRC(241f27a5) SHA1(82711289d19e9b165e35324da010466d225e503a), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "turbo", "Advent Turbo ROM") + ROMX_LOAD("trom34.rom", 0x0000, 0x2000, CRC(0ec6d39a) SHA1(8c2a92b8642e144452c28300bf50a00a11a060cd), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 2, "kplus", "MICROCode Consulting KayPLUS 84") + ROMX_LOAD("kplus84.rom", 0x0000, 0x2000, CRC(4551905a) SHA1(48f0964edfad05b214810ae5595638245c30e5c0), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 3, "pro884", "MicroCornucopia pro884 SuperMax 2.7") + ROMX_LOAD("pro884mx.rom", 0x0000, 0x2000, CRC(febc6f51) SHA1(1f009aa9b7c9a3eddd0ee6ea7321a1c47c3e9807), ROM_BIOS(4) ) + ROM_SYSTEM_BIOS( 4, "pro8v5", "MicroCornucopia Pro8 V5") + ROMX_LOAD("pro884v5.rom", 0x0000, 0x2000, CRC(fe0051b1) SHA1(cac429154d40e21174ae05ceb0017b62473cdebd), ROM_BIOS(5) ) ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) - ROM_REGION(0x1000, "chargen", 0) - ROM_LOAD("omni4.u9", 0x0000, 0x1000, CRC(579665a6) SHA1(261fcdc5a44821de9484340cbe429110400140b4) ) + ROM_REGION(0x1000, "chargen",0) + ROM_LOAD("81-235.u9", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) ROM_END +// Kaypro 2X, a 4'84 without modem and RTC, later the 4'84 is renamed 2X, this fully decked out variant is called 2X MTC ROM_START(kaypro2x) - ROM_REGION(0x4000, "roms",0) - ROM_SYSTEM_BIOS( 0, "292", "292") - ROMX_LOAD("81-292.u34", 0x0000, 0x2000, CRC(5eb69aec) SHA1(525f955ca002976e2e30ac7ee37e4a54f279fe96), ROM_BIOS(1) ) - ROM_SYSTEM_BIOS( 1, "292a", "292A") - ROMX_LOAD("81-292a.u34", 0x0000, 0x1000, CRC(241f27a5) SHA1(82711289d19e9b165e35324da010466d225e503a), ROM_BIOS(2) ) + ROM_REGION(0x8000, "roms",0) + ROM_SYSTEM_BIOS( 0, "292a", "81-292a for Kaypro Bd. 81-184") + ROMX_LOAD("81-292a.u34", 0x0000, 0x1000, CRC(241f27a5) SHA1(82711289d19e9b165e35324da010466d225e503a), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "292", "V2.00 (early universal)" ) + ROMX_LOAD("81-292.u34", 0x0000, 0x2000, CRC(5eb69aec) SHA1(525f955ca002976e2e30ac7ee37e4a54f279fe96), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 2, "478", "V2.01 for Kaypro Bd. 81-580 (universal)") + ROMX_LOAD("81-478.u42", 0x0000, 0x2000, CRC(de618380) SHA1(c8d6312e6eeb62a53e741f1ff3b878bdcb7b5aaa), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 3, "turbo", "Advent Turbo ROM") + ROMX_LOAD("trom34.rom", 0x0000, 0x2000, CRC(0ec6d39a) SHA1(8c2a92b8642e144452c28300bf50a00a11a060cd), ROM_BIOS(4) ) + ROM_SYSTEM_BIOS( 4, "kplus", "MICROCode Consulting KayPLUS 84") + ROMX_LOAD("kplus84.rom", 0x0000, 0x2000, CRC(4551905a) SHA1(48f0964edfad05b214810ae5595638245c30e5c0), ROM_BIOS(5) ) + ROM_SYSTEM_BIOS( 5, "pro884", "MicroCornucopia pro884 SuperMax 2.7") + ROMX_LOAD("pro884mx.rom", 0x0000, 0x2000, CRC(febc6f51) SHA1(1f009aa9b7c9a3eddd0ee6ea7321a1c47c3e9807), ROM_BIOS(6) ) + ROM_SYSTEM_BIOS( 6, "pro8v5", "MicroCornucopia Pro8 V5") + ROMX_LOAD("pro884v5.rom", 0x0000, 0x2000, CRC(fe0051b1) SHA1(cac429154d40e21174ae05ceb0017b62473cdebd), ROM_BIOS(7) ) + ROM_SYSTEM_BIOS( 7, "handyman", "Hitech Research Handyman") // http://content.thetechnickel.com/misc/kaypro-handyman/kaypro-4-plus-88-06.jpg + ROMX_LOAD( "handyman.bin", 0x0000, 0x8000, CRC(f020d82c) SHA1(576a6608270d4ec7cf814c9de46ecf4e2869d30a), ROM_BIOS(8) ) // fits any classic Kaypro, needs its own 16K RAM ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) @@ -471,9 +560,29 @@ ROM_START(kaypro2x) ROM_LOAD("81-235.u9", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) ROM_END -ROM_START(kaypro4a) // same as kaypro2x ?? +// Kaypro II'84 plus 88, the "KAYPRO-88" board has 128k or 256k of its own ram on it, it's a factory installed SWP CoPower 88 +ROM_START(kayproiip88) + ROM_REGION(0x4000, "roms",0) + ROM_SYSTEM_BIOS( 0, "232", "81-232 for Kaypro Bd. 81-240") + ROMX_LOAD("81-232.u47", 0x0000, 0x1000, CRC(4918fb91) SHA1(cd9f45cc3546bcaad7254b92c5d501c40e2ef0b2), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "kplus83", "MICROCode Consulting KayPLUS 83") + ROMX_LOAD("kplus83.rom", 0x0000, 0x2000, CRC(5e9b817d) SHA1(26ea875ee3659a964cbded4ed0c82a3af42db64b), ROM_BIOS(2) ) + ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) + + ROM_REGION(0x0800, "chargen", ROMREGION_INVERT) + ROM_LOAD("81-146.u43", 0x0000, 0x0800, CRC(4cc7d206) SHA1(5cb880083b94bd8220aac1f87d537db7cfeb9013) ) + + ROM_REGION(0x1000, "8088cpu",0) + ROM_LOAD("81-356.u29", 0x0000, 0x1000, CRC(948556db) SHA1(6e779866d099cc0dc8c6369bdfb37a923ac448a4) ) +ROM_END + +// Kaypro 4'84 plus 88, the "KAYPRO-88" board has 128k or 256k of its own ram on it, it's a factory installed SWP CoPower 88 +ROM_START(kaypro484p88) ROM_REGION(0x4000, "roms",0) - ROM_LOAD("81-292.u34", 0x0000, 0x2000, CRC(5eb69aec) SHA1(525f955ca002976e2e30ac7ee37e4a54f279fe96) ) + ROM_SYSTEM_BIOS( 0, "292a", "292A") + ROMX_LOAD("81-292a.u34", 0x0000, 0x1000, CRC(241f27a5) SHA1(82711289d19e9b165e35324da010466d225e503a), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "kplus", "MICROCode Consulting KayPLUS 84") + ROMX_LOAD("kplus84.rom", 0x0000, 0x2000, CRC(4551905a) SHA1(48f0964edfad05b214810ae5595638245c30e5c0), ROM_BIOS(2) ) ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) @@ -481,23 +590,21 @@ ROM_START(kaypro4a) // same as kaypro2x ?? ROM_LOAD("81-235.u9", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) ROM_END -ROM_START(kaypro10) +// Kaypro New 2, no modem, no RTC, single DS/DD disk drive +ROM_START(kaypronew2) ROM_REGION(0x4000, "roms",0) - ROM_SYSTEM_BIOS( 0, "302", "V1.9E") - ROMX_LOAD("81-302.u42", 0x0000, 0x1000, CRC(3f9bee20) SHA1(b29114a199e70afe46511119b77a662e97b093a0), ROM_BIOS(1) ) - ROM_SYSTEM_BIOS( 1, "188", "V1.9") - ROMX_LOAD("81-188.u42", 0x0000, 0x1000, CRC(6cbd6aa0) SHA1(47004f8c6e17407e4f8d613c9520f9316716d9e2), ROM_BIOS(2) ) - ROM_SYSTEM_BIOS( 2, "277", "V1.9E(F)") - ROMX_LOAD("81-277.u42", 0x0000, 0x1000, CRC(e4e1831f) SHA1(1de31ed532a461ace7a4abad1f6647eeddceb3e7), ROM_BIOS(3) ) - ROM_SYSTEM_BIOS( 3, "478", "V2.01") - ROMX_LOAD("81-478.u42", 0x0000, 0x2000, CRC(de618380) SHA1(c8d6312e6eeb62a53e741f1ff3b878bdcb7b5aaa), ROM_BIOS(4) ) + ROM_SYSTEM_BIOS( 0, "478", "V2.01 for Kaypro Bd. 81-294 (universal") + ROMX_LOAD("81-478.u42", 0x0000, 0x2000, CRC(de618380) SHA1(c8d6312e6eeb62a53e741f1ff3b878bdcb7b5aaa), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "kplus", "MICROCode Consulting KayPLUS 84") + ROMX_LOAD("kplus84.rom", 0x0000, 0x2000, CRC(4551905a) SHA1(48f0964edfad05b214810ae5595638245c30e5c0), ROM_BIOS(2) ) ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) ROM_REGION(0x1000, "chargen",0) - ROM_LOAD("81-187.u31", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) + ROM_LOAD("81-235.u9", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) ROM_END +// "Desktop" PC with two high density, 2.8MB floppy disk drivers over the monitor ROM_START(robie) ROM_REGION(0x4000, "roms",0) ROM_SYSTEM_BIOS( 0, "326", "V1.7R") @@ -511,14 +618,69 @@ ROM_START(robie) ROM_LOAD("81-235.u9", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) ROM_END -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ -COMP( 1982, kayproii, 0, 0, kayproii, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro II - 2/83" , 0 ) -COMP( 1983, kaypro4, kayproii, 0, kaypro4, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 4 - 4/83" , 0 ) // model 81-004 -COMP( 1983, kaypro4p88, kayproii, 0, kaypro4, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 4 plus88 - 4/83" , MACHINE_NOT_WORKING ) // model 81-004 with an added 8088 daughterboard and rom -COMP( 198?, omni2, kayproii, 0, omni2, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Omni II Logic Analyzer" , 0 ) -COMP( 198?, omni4, kaypro2x, 0, kaypro2x, kaypro, kaypro_state, kaypro, "Omni Logic Inc.", "Omni 4 Logic Analyzer" , MACHINE_NOT_WORKING ) -COMP( 1984, kaypro2x, 0, 0, kaypro2x, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 2x" , MACHINE_NOT_WORKING ) // model 81-025 -COMP( 1984, kaypro4a, kaypro2x, 0, kaypro2x, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 4 - 4/84" , MACHINE_NOT_WORKING ) // model 81-015 -// Kaypro 4/84 plus 88 goes here, model 81-015 with an added 8088 daughterboard and rom -COMP( 1983, kaypro10, 0, 0, kaypro10, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 10" , MACHINE_NOT_WORKING ) // model 81-005 -COMP( 1984, robie, 0, 0, kaypro2x, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro Robie" , MACHINE_NOT_WORKING ) // model 81-005 +// Kaypro 4X, a Robie in the standard portable Kaypro enclosure +ROM_START(kaypro4x) + ROM_REGION(0x4000, "roms",0) + ROM_LOAD("81-326.u34", 0x0000, 0x2000, CRC(7f0c3f68) SHA1(54b088a1b2200f9df4b9b347bbefb0115f3a4976) ) + + ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) + + ROM_REGION(0x1000, "chargen",0) + ROM_LOAD("81-235.u9", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) +ROM_END + +// Kaypro 1, equivalent to "old" 2X, before 4'84 became 2X +ROM_START(kaypro1) + ROM_REGION(0x4000, "roms",0) + ROM_SYSTEM_BIOS( 0, "478", "V2.01 for Kaypro Bd. 81-294 (universal") + ROMX_LOAD("81-478.u42", 0x0000, 0x2000, CRC(de618380) SHA1(c8d6312e6eeb62a53e741f1ff3b878bdcb7b5aaa), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "turbo", "Advent Turbo ROM") + ROMX_LOAD("trom34.rom", 0x0000, 0x2000, CRC(0ec6d39a) SHA1(8c2a92b8642e144452c28300bf50a00a11a060cd), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 2, "kplus", "MICROCode Consulting KayPLUS 84") + ROMX_LOAD("kplus84.rom", 0x0000, 0x2000, CRC(4551905a) SHA1(48f0964edfad05b214810ae5595638245c30e5c0), ROM_BIOS(3) ) + + ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) + + ROM_REGION(0x1000, "chargen",0) + ROM_LOAD("81-235.u9", 0x0000, 0x1000, CRC(5f72da5b) SHA1(8a597000cce1a7e184abfb7bebcb564c6bf24fb7) ) +ROM_END + +// Omni II logic analyzer +ROM_START(omni2) + ROM_REGION(0x4000, "roms",0) + ROM_LOAD("omni2.u47", 0x0000, 0x1000, CRC(2883f9e0) SHA1(d98c784e62853582d298bf7ca84c75872847ac9b) ) + + ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) + + ROM_REGION(0x0800, "chargen", ROMREGION_INVERT) + ROM_LOAD("omni2.u43", 0x0000, 0x0800, CRC(049b3381) SHA1(46f1d4f038747ba9048b075dc617361be088f82a) ) +ROM_END + +// Omni 4 logic analyzer +ROM_START(omni4) + ROM_REGION(0x4000, "roms",0) + ROM_LOAD("omni4.u34", 0x0000, 0x2000, CRC(f24e8521) SHA1(374f2e2b791a807f103744a22c9c8f3af55f1033) ) + + ROM_REGION(0x10000, "rambank", ROMREGION_ERASEFF) + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD("omni4.u9", 0x0000, 0x1000, CRC(579665a6) SHA1(261fcdc5a44821de9484340cbe429110400140b4) ) +ROM_END + + +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ +COMP( 1982, kayproii, 0, 0, kayproii, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro II - 2/83" , 0 ) +COMP( 1983, kayproiv, kayproii, 0, kayproiv, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro IV - 4/83" , 0 ) // model 81-004 +COMP( 1983, kaypro10, 0, 0, kaypro10, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 10 - 1983", 0 ) +COMP( 1983, kayproiip88, kayproii, 0, kayproii, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 4 plus88 - 4/83" , MACHINE_NOT_WORKING ) // model 81-004 with an added 8088 daughterboard and rom +COMP( 1984, kaypro484, 0, 0, kaypro484, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 4/84" , MACHINE_NOT_WORKING ) // model 81-015 +COMP( 1984, kaypro284, kaypro484, 0, kaypro284, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 2/84" , MACHINE_NOT_WORKING ) // model 81-015 +COMP( 1984, kaypro484p88,kaypro484, 0, kaypro484, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 4/84 plus88", MACHINE_NOT_WORKING ) // model 81-015 with an added 8088 daughterboard and rom +COMP( 1984, kaypro1084, kaypro10, 0, kaypro10, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 10" , MACHINE_NOT_WORKING ) // model 81-005 +COMP( 1984, robie, 0, 0, kaypro484, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro Robie" , MACHINE_NOT_WORKING ) +COMP( 1985, kaypro2x, kaypro484, 0, kaypro484, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 2x" , MACHINE_NOT_WORKING ) // model 81-025 +COMP( 1985, kaypronew2, 0, 0, kaypronew2,kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro New 2", MACHINE_NOT_WORKING ) +COMP( 1985, kaypro4x, robie, 0, kaypro484, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 4x" , MACHINE_NOT_WORKING ) +COMP( 1986, kaypro1, kaypro484, 0, kaypro484, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Kaypro 1", MACHINE_NOT_WORKING ) +COMP( 198?, omni2, kayproii, 0, omni2, kaypro, kaypro_state, kaypro, "Non Linear Systems", "Omni II Logic Analyzer" , 0 ) +COMP( 198?, omni4, kaypro484, 0, kaypro484, kaypro, kaypro_state, kaypro, "Omni Logic Inc.", "Omni 4 Logic Analyzer" , MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/konamigv.cpp b/src/mame/drivers/konamigv.cpp index 19fd49297f3..4bcc0d7432e 100644 --- a/src/mame/drivers/konamigv.cpp +++ b/src/mame/drivers/konamigv.cpp @@ -85,6 +85,7 @@ Notes: Xilinx 1718DPC 74F244N (2 of these) LVT245SS (2 of theses) + On Simpsons Bowling, this also has one µPD4701AC and an empty space for a second. - 000180 is used for driving the RGB output. It's a very thin piece of very brittle ceramic containing a circuit, a LM1203 chip, some smt transistors/caps/resistors etc (let's just say @@ -129,6 +130,7 @@ Notes: #include "machine/eepromser.h" #include "machine/intelfsh.h" #include "machine/mb89371.h" +#include "machine/upd4701.h" #include "machine/ram.h" #include "sound/cdda.h" #include "sound/spu.h" @@ -143,15 +145,13 @@ public: konamigv_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_am53cf96(*this, "am53cf96"), + m_btc_trackball(*this, "upd%u", 1), m_maincpu(*this, "maincpu") { } DECLARE_READ16_MEMBER(flash_r); DECLARE_WRITE16_MEMBER(flash_w); - DECLARE_READ16_MEMBER(trackball_r); - DECLARE_READ16_MEMBER(unknown_r); - DECLARE_READ16_MEMBER(btc_trackball_r); DECLARE_WRITE16_MEMBER(btc_trackball_w); DECLARE_READ16_MEMBER(tokimeki_serial_r); DECLARE_WRITE16_MEMBER(tokimeki_serial_w); @@ -164,14 +164,10 @@ protected: private: required_device<am53cf96_device> m_am53cf96; + optional_device_array<upd4701_device, 2> m_btc_trackball; uint32_t m_flash_address; - uint16_t m_trackball_prev[ 2 ]; - uint16_t m_trackball_data[ 2 ]; - uint16_t m_btc_trackball_prev[ 4 ]; - uint16_t m_btc_trackball_data[ 4 ]; - fujitsu_29f016a_device *m_flash8[4]; uint8_t m_sector_buffer[ 4096 ]; @@ -192,16 +188,17 @@ static ADDRESS_MAP_START( simpbowl_map, AS_PROGRAM, 32, konamigv_state ) AM_IMPORT_FROM( konamigv_map ) AM_RANGE(0x1f680080, 0x1f68008f) AM_READWRITE16(flash_r, flash_w, 0xffffffff) - AM_RANGE(0x1f6800c0, 0x1f6800c7) AM_READ16(trackball_r, 0xffffffff) - AM_RANGE(0x1f6800c8, 0x1f6800cb) AM_READ16(unknown_r, 0x0000ffff) /* ?? */ + AM_RANGE(0x1f6800c0, 0x1f6800c7) AM_DEVREAD8("upd", upd4701_device, read_xy, 0xff00ff00) + AM_RANGE(0x1f6800c8, 0x1f6800cb) AM_DEVREAD8("upd", upd4701_device, reset_xy, 0x0000ff00) ADDRESS_MAP_END static ADDRESS_MAP_START( btchamp_map, AS_PROGRAM, 32, konamigv_state ) AM_IMPORT_FROM( konamigv_map ) AM_RANGE(0x1f380000, 0x1f3fffff) AM_DEVREADWRITE16("flash", intelfsh16_device, read, write, 0xffffffff) - AM_RANGE(0x1f680080, 0x1f680087) AM_READ16(btc_trackball_r, 0xffffffff) - AM_RANGE(0x1f680088, 0x1f68008b) AM_WRITE16(btc_trackball_w, 0xffffffff) + AM_RANGE(0x1f680080, 0x1f680087) AM_DEVREAD8("upd1", upd4701_device, read_xy, 0xff00ff00) + AM_RANGE(0x1f680080, 0x1f680087) AM_DEVREAD8("upd2", upd4701_device, read_xy, 0x00ff00ff) + AM_RANGE(0x1f680088, 0x1f68008b) AM_WRITE16(btc_trackball_w, 0x0000ffff) AM_RANGE(0x1f6800e0, 0x1f6800e3) AM_WRITENOP ADDRESS_MAP_END @@ -308,10 +305,6 @@ void konamigv_state::driver_start() { save_item(NAME(m_sector_buffer)); save_item(NAME(m_flash_address)); - save_item(NAME(m_trackball_prev)); - save_item(NAME(m_trackball_data)); - save_item(NAME(m_btc_trackball_prev)); - save_item(NAME(m_btc_trackball_data)); } static MACHINE_CONFIG_START( cdrom_config ) @@ -471,33 +464,6 @@ WRITE16_MEMBER(konamigv_state::flash_w) } } -READ16_MEMBER(konamigv_state::trackball_r) -{ - if( offset == 0 ) - { - static const char *const axisnames[] = { "TRACK0_X", "TRACK0_Y" }; - - for( int axis = 0; axis < 2; axis++ ) - { - uint16_t value = ioport(axisnames[axis])->read(); - m_trackball_data[ axis ] = value - m_trackball_prev[ axis ]; - m_trackball_prev[ axis ] = value; - } - } - - if( ( offset & 1 ) == 0 ) - { - return m_trackball_data[ offset >> 1 ] << 8; - } - - return m_trackball_data[ offset >> 1 ] & 0xf00; -} - -READ16_MEMBER(konamigv_state::unknown_r) -{ - return 0xffff; -} - DRIVER_INIT_MEMBER(konamigv_state,simpbowl) { m_flash8[0] = machine().device<fujitsu_29f016a_device>("flash0"); @@ -514,48 +480,35 @@ static MACHINE_CONFIG_DERIVED( simpbowl, konamigv ) MCFG_FUJITSU_29F016A_ADD("flash1") MCFG_FUJITSU_29F016A_ADD("flash2") MCFG_FUJITSU_29F016A_ADD("flash3") + + MCFG_DEVICE_ADD("upd", UPD4701A, 0) + MCFG_UPD4701_PORTX("TRACK0_X") + MCFG_UPD4701_PORTY("TRACK0_Y") MACHINE_CONFIG_END static INPUT_PORTS_START( simpbowl ) PORT_INCLUDE( konamigv ) PORT_START("TRACK0_X") - PORT_BIT( 0xfff, 0x0000, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_REVERSE PORT_PLAYER(1) + PORT_BIT( 0xfff, 0x000, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_REVERSE PORT_RESET PORT_PLAYER(1) PORT_START("TRACK0_Y") - PORT_BIT( 0xfff, 0x0000, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_PLAYER(1) + PORT_BIT( 0xfff, 0x000, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_RESET PORT_PLAYER(1) INPUT_PORTS_END /* Beat the Champ */ -READ16_MEMBER(konamigv_state::btc_trackball_r) +WRITE16_MEMBER(konamigv_state::btc_trackball_w) { -// osd_printf_debug( "r %08x %08x %08x\n", space.device().safe_pc(), offset, mem_mask ); - - if( offset == 3 ) - { - static const char *const axisnames[] = { "TRACK0_X", "TRACK0_Y", "TRACK1_X", "TRACK1_Y" }; - - for( int axis = 0; axis < 4; axis++ ) - { - uint16_t value = ioport(axisnames[axis])->read(); - m_btc_trackball_data[ axis ] = value - m_btc_trackball_prev[ axis ]; - m_btc_trackball_prev[ axis ] = value; - } - } +// osd_printf_debug( "w %08x %08x %08x %08x\n", space.device().safe_pc(), offset, data, mem_mask ); - if( ( offset & 1 ) == 0 ) + for (int i = 0; i < 2; i++) { - return ( m_btc_trackball_data[ offset >> 1 ] << 8 ) | ( m_btc_trackball_data[ ( offset >> 1 ) + 2 ] & 0xff ); + m_btc_trackball[i]->cs_w(BIT(data, 1)); + m_btc_trackball[i]->resetx_w(!BIT(data, 0)); + m_btc_trackball[i]->resety_w(!BIT(data, 0)); } - - return ( m_btc_trackball_data[ offset >> 1 ] & 0xf00 ) | ( m_btc_trackball_data[ ( offset >> 1 ) + 2 ] >> 8 ); -} - -WRITE16_MEMBER(konamigv_state::btc_trackball_w) -{ -// osd_printf_debug( "w %08x %08x %08x %08x\n", space.device().safe_pc(), offset, data, mem_mask ); } static MACHINE_CONFIG_DERIVED( btchamp, konamigv ) @@ -563,22 +516,30 @@ static MACHINE_CONFIG_DERIVED( btchamp, konamigv ) MCFG_CPU_PROGRAM_MAP( btchamp_map ) MCFG_SHARP_LH28F400_ADD("flash") + + MCFG_DEVICE_ADD("upd1", UPD4701A, 0) + MCFG_UPD4701_PORTX("TRACK0_X") + MCFG_UPD4701_PORTY("TRACK0_Y") + + MCFG_DEVICE_ADD("upd2", UPD4701A, 0) + MCFG_UPD4701_PORTX("TRACK1_X") + MCFG_UPD4701_PORTY("TRACK1_Y") MACHINE_CONFIG_END static INPUT_PORTS_START( btchamp ) PORT_INCLUDE( konamigv ) PORT_START("TRACK0_X") - PORT_BIT( 0x7ff, 0x0000, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_REVERSE PORT_PLAYER(1) + PORT_BIT( 0xfff, 0x000, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_RESET PORT_PLAYER(1) PORT_START("TRACK0_Y") - PORT_BIT( 0x7ff, 0x0000, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_PLAYER(1) + PORT_BIT( 0xfff, 0x000, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_RESET PORT_PLAYER(1) PORT_START("TRACK1_X") - PORT_BIT( 0x7ff, 0x0000, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_REVERSE PORT_PLAYER(2) + PORT_BIT( 0xfff, 0x000, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_RESET PORT_PLAYER(2) PORT_START("TRACK1_Y") - PORT_BIT( 0x7ff, 0x0000, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_PLAYER(2) + PORT_BIT( 0xfff, 0x000, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(63) PORT_RESET PORT_PLAYER(2) INPUT_PORTS_END /* Tokimeki Memorial games - have a mouse and printer and who knows what else */ diff --git a/src/mame/drivers/konamigx.cpp b/src/mame/drivers/konamigx.cpp index ffcc045a8b8..6c5ad59ba1c 100644 --- a/src/mame/drivers/konamigx.cpp +++ b/src/mame/drivers/konamigx.cpp @@ -3973,8 +3973,8 @@ GAME( 1995, tkmmpzdm, konamigx, konamigx_6bpp, puzldama, konamigx_state, konamig GAME( 1995, dragoona, konamigx, dragoonj, dragoonj, konamigx_state, posthack, ROT0, "Konami", "Dragoon Might (ver AAB)", MACHINE_IMPERFECT_GRAPHICS ) GAME( 1995, dragoonj, dragoona, dragoonj, dragoonj, konamigx_state, posthack, ROT0, "Konami", "Dragoon Might (ver JAA)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1996, sexyparo, konamigx, sexyparo, gokuparo, konamigx_state, konamigx, ROT0, "Konami", "Sexy Parodius (ver JAA)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1996, sexyparoa,sexyparo, sexyparo, gokuparo, konamigx_state, konamigx, ROT0, "Konami", "Sexy Parodius (ver AAA)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1996, sexyparo, konamigx, sexyparo, gokuparo, konamigx_state, konamigx, ROT0, "Konami", "Sexy Parodius (ver JAA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION ) +GAME( 1996, sexyparoa,sexyparo, sexyparo, gokuparo, konamigx_state, konamigx, ROT0, "Konami", "Sexy Parodius (ver AAA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_UNEMULATED_PROTECTION ) GAME( 1996, daiskiss, konamigx, konamigx, gokuparo, konamigx_state, konamigx, ROT0, "Konami", "Daisu-Kiss (ver JAA)", MACHINE_IMPERFECT_GRAPHICS ) diff --git a/src/mame/drivers/ksys573.cpp b/src/mame/drivers/ksys573.cpp index bd2bf50b7b1..928698f8a99 100644 --- a/src/mame/drivers/ksys573.cpp +++ b/src/mame/drivers/ksys573.cpp @@ -2040,7 +2040,7 @@ static MACHINE_CONFIG_START( konami573 ) MCFG_DEVICE_ADD( "flashbank", ADDRESS_MAP_BANK, 0 ) MCFG_DEVICE_PROGRAM_MAP( flashbank_map ) MCFG_ADDRESS_MAP_BANK_ENDIANNESS( ENDIANNESS_LITTLE ) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH( 16 ) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH( 16 ) MCFG_ADDRESS_MAP_BANK_STRIDE( 0x400000 ) /* video hardware */ diff --git a/src/mame/drivers/kyugo.cpp b/src/mame/drivers/kyugo.cpp index 30d3cbc50d4..2c5ef7b4162 100644 --- a/src/mame/drivers/kyugo.cpp +++ b/src/mame/drivers/kyugo.cpp @@ -42,14 +42,14 @@ static ADDRESS_MAP_START( kyugo_main_map, AS_PROGRAM, 8, kyugo_state ) AM_RANGE(0x0000, 0x7fff) AM_ROM - AM_RANGE(0x8000, 0x87ff) AM_RAM_WRITE(kyugo_bgvideoram_w) AM_SHARE("bgvideoram") - AM_RANGE(0x8800, 0x8fff) AM_RAM_WRITE(kyugo_bgattribram_w) AM_SHARE("bgattribram") - AM_RANGE(0x9000, 0x97ff) AM_RAM_WRITE(kyugo_fgvideoram_w) AM_SHARE("fgvideoram") - AM_RANGE(0x9800, 0x9fff) AM_RAM_READ(kyugo_spriteram_2_r) AM_SHARE("spriteram_2") + AM_RANGE(0x8000, 0x87ff) AM_RAM_WRITE(bgvideoram_w) AM_SHARE("bgvideoram") + AM_RANGE(0x8800, 0x8fff) AM_RAM_WRITE(bgattribram_w) AM_SHARE("bgattribram") + AM_RANGE(0x9000, 0x97ff) AM_RAM_WRITE(fgvideoram_w) AM_SHARE("fgvideoram") + AM_RANGE(0x9800, 0x9fff) AM_RAM_READ(spriteram_2_r) AM_SHARE("spriteram_2") AM_RANGE(0xa000, 0xa7ff) AM_RAM AM_SHARE("spriteram_1") - AM_RANGE(0xa800, 0xa800) AM_WRITE(kyugo_scroll_x_lo_w) - AM_RANGE(0xb000, 0xb000) AM_WRITE(kyugo_gfxctrl_w) - AM_RANGE(0xb800, 0xb800) AM_WRITE(kyugo_scroll_y_w) + AM_RANGE(0xa800, 0xa800) AM_WRITE(scroll_x_lo_w) + AM_RANGE(0xb000, 0xb000) AM_WRITE(gfxctrl_w) + AM_RANGE(0xb800, 0xb800) AM_WRITE(scroll_y_w) AM_RANGE(0xf000, 0xf7ff) AM_RAM AM_SHARE("shared_ram") ADDRESS_MAP_END @@ -137,7 +137,7 @@ ADDRESS_MAP_END * *************************************/ -WRITE8_MEMBER(kyugo_state::kyugo_coin_counter_w) +WRITE8_MEMBER(kyugo_state::coin_counter_w) { machine().bookkeeping().coin_counter_w(offset, data & 1); } @@ -155,7 +155,7 @@ static ADDRESS_MAP_START( repulse_sub_portmap, AS_IO, 8, kyugo_state ) AM_RANGE(0x00, 0x01) AM_DEVWRITE("ay1", ay8910_device, address_data_w) AM_RANGE(0x02, 0x02) AM_DEVREAD("ay1", ay8910_device, data_r) AM_RANGE(0x40, 0x41) AM_DEVWRITE("ay2", ay8910_device, address_data_w) - AM_RANGE(0xc0, 0xc1) AM_WRITE(kyugo_coin_counter_w) + AM_RANGE(0xc0, 0xc1) AM_WRITE(coin_counter_w) ADDRESS_MAP_END @@ -164,7 +164,7 @@ static ADDRESS_MAP_START( flashgala_sub_portmap, AS_IO, 8, kyugo_state ) AM_RANGE(0x40, 0x41) AM_DEVWRITE("ay1", ay8910_device, address_data_w) AM_RANGE(0x42, 0x42) AM_DEVREAD("ay1", ay8910_device, data_r) AM_RANGE(0x80, 0x81) AM_DEVWRITE("ay2", ay8910_device, address_data_w) - AM_RANGE(0xc0, 0xc1) AM_WRITE(kyugo_coin_counter_w) + AM_RANGE(0xc0, 0xc1) AM_WRITE(coin_counter_w) ADDRESS_MAP_END @@ -173,7 +173,7 @@ static ADDRESS_MAP_START( srdmissn_sub_portmap, AS_IO, 8, kyugo_state ) AM_RANGE(0x80, 0x81) AM_DEVWRITE("ay1", ay8910_device, address_data_w) AM_RANGE(0x82, 0x82) AM_DEVREAD("ay1", ay8910_device, data_r) AM_RANGE(0x84, 0x85) AM_DEVWRITE("ay2", ay8910_device, address_data_w) - AM_RANGE(0x90, 0x91) AM_WRITE(kyugo_coin_counter_w) + AM_RANGE(0x90, 0x91) AM_WRITE(coin_counter_w) ADDRESS_MAP_END @@ -533,7 +533,7 @@ static MACHINE_CONFIG_START( kyugo_base ) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) MCFG_SCREEN_SIZE(64*8, 32*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 36*8-1, 2*8, 30*8-1) - MCFG_SCREEN_UPDATE_DRIVER(kyugo_state, screen_update_kyugo) + MCFG_SCREEN_UPDATE_DRIVER(kyugo_state, screen_update) MCFG_SCREEN_PALETTE("palette") MCFG_GFXDECODE_ADD("gfxdecode", "palette", kyugo) @@ -864,6 +864,42 @@ ROM_START( 99lstwark ) ROM_LOAD( "1999-00.rom", 0x0000, 0x0800, CRC(0c0c449f) SHA1(efa4a8ac4c341ca5cdc3b5d2803eda43daf1bc93) ) /* unknown */ ROM_END +ROM_START( 99lstwarb ) // copyright blanked, seems based on 99lstwara, given it has a second shot type instead of the shields. + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "15.2764", 0x0000, 0x2000, CRC(f9367b9d) SHA1(08157add7a72208b273faec1dbb8cb2ef21f2438) ) + ROM_LOAD( "16.2764", 0x2000, 0x2000, CRC(04c3316a) SHA1(2db4ab98c8ac6c3eea1930c9dbbe6dd15b8e8a74) ) + ROM_LOAD( "17.2764", 0x4000, 0x2000, CRC(02aa4de5) SHA1(bab79e314764f4a1e05516e22bd1077476e53f5b) ) + + ROM_REGION( 0x10000, "sub", 0 ) + ROM_LOAD( "11.2764", 0x0000, 0x2000, CRC(aa3e0996) SHA1(8e92edfc933be0b9e23991dbad686fb0c0286321) ) + ROM_LOAD( "12.2764", 0x2000, 0x2000, CRC(a59d3d1b) SHA1(6f0eee9d89cbe667f02a787b0ce16563c3b48e3f) ) + ROM_LOAD( "13.2764", 0x4000, 0x2000, CRC(fe31975e) SHA1(904d3fb8bf3b31152c18095234b5f62589c5b18c) ) + ROM_LOAD( "14.2764", 0x6000, 0x2000, CRC(683481a5) SHA1(56d52194a4df3712fd9b16b2c0029d565e8c8bee) ) + + ROM_REGION( 0x01000, "gfx1", 0 ) + ROM_LOAD( "1.2732", 0x00000, 0x1000, CRC(8ed6855b) SHA1(9f3737162e63ba0e05e5b71b32802166ec39bf02) ) /* chars */ + + ROM_REGION( 0x06000, "gfx2", 0 ) + ROM_LOAD( "8.2764", 0x00000, 0x2000, CRC(b161c853) SHA1(26913524001415c7426c0d439e078335761d9e7a) ) /* tiles - plane 0 */ + ROM_LOAD( "9.2764", 0x02000, 0x2000, CRC(44fd4c31) SHA1(8f5da66eba4c8a1e3d00be201244b8039d8a5b76) ) /* tiles - plane 1 */ + ROM_LOAD( "10.2764", 0x04000, 0x2000, CRC(b3dbc16b) SHA1(df57836695aadf5c82df22ddeef65e60e025848a) ) /* tiles - plane 2 */ + + ROM_REGION( 0x18000, "gfx3", 0 ) + ROM_LOAD( "2.27128", 0x00000, 0x4000, CRC(34dba8f9) SHA1(7abd909856729f5dadcf8143505016a454ae6217) ) /* sprites - plane 0 */ + ROM_LOAD( "3.27128", 0x04000, 0x4000, CRC(8bd7d5b6) SHA1(73cf9828dbcb34e63c7cc70792f3dbab90bd7447) ) /* sprites - plane 0 */ + ROM_LOAD( "4.27128", 0x08000, 0x4000, CRC(64036ea0) SHA1(929794a0105fc5c064f95c75cfcc6ca25a3724ce) ) /* sprites - plane 1 */ + ROM_LOAD( "5.27128", 0x0c000, 0x4000, CRC(2f7352e4) SHA1(3e77c1a315fe082628cf69fede4063743a229055) ) /* sprites - plane 1 */ + ROM_LOAD( "6.27128", 0x10000, 0x4000, CRC(7d9e1e7e) SHA1(81dd8e933a1195e5f119a2b957828a4bf22bea35) ) /* sprites - plane 2 */ + ROM_LOAD( "7.27128", 0x14000, 0x4000, CRC(8b6fa1c4) SHA1(061ae1849e685dd838f61ea1d6e72a579f38ecc6) ) /* sprites - plane 2 */ + + ROM_REGION( 0x0340, "proms", 0 ) // not dumped for this PCB + ROM_LOAD( "b.1j", 0x0000, 0x0100, CRC(3ea35431) SHA1(b45318ce898f03a338435a3f6109483d246ff914) ) /* blue */ + ROM_LOAD( "g.1h", 0x0100, 0x0100, CRC(acd7a69e) SHA1(b18eab8f669f0a8105a4bbffa346c4b19491c451) ) /* green */ + ROM_LOAD( "r.1f", 0x0200, 0x0100, CRC(b7f48b41) SHA1(2d84dc29c0ab43729014129e6392207db0f56e9e) ) /* red */ + /* 0x0300-0x031f empty - looks like there isn't a lookup table PROM */ + ROM_LOAD( "m1.2c", 0x0320, 0x0020, CRC(83a39201) SHA1(4fdc722c9e20ee152c890342ef0dce18e35e2ef8) ) /* timing? (not used) */ +ROM_END + ROM_START( sonofphx ) ROM_REGION( 0x10000, "maincpu", 0 ) ROM_LOAD( "5.f4", 0x0000, 0x2000, CRC(e0d2c6cf) SHA1(87befaefa3e4f07523e9c4db19f13ff9309a7dcc) ) @@ -1414,6 +1450,7 @@ GAME( 1985, repulse, 0, repulse, repulse, kyugo_state, 0, ROT GAME( 1985, 99lstwar, repulse, repulse, repulse, kyugo_state, 0, ROT90, "Crux / Proma", "'99: The Last War (set 1)", MACHINE_SUPPORTS_SAVE ) // Crux went bankrupt during Repulse development, GAME( 1985, 99lstwara, repulse, repulse, repulse, kyugo_state, 0, ROT90, "Crux / Proma", "'99: The Last War (set 2)", MACHINE_SUPPORTS_SAVE ) // some of their staff later worked on the newer games on this hardware, GAME( 1985, 99lstwark, repulse, repulse, repulse, kyugo_state, 0, ROT90, "Crux / Kyugo", "'99: The Last War (Kyugo)", MACHINE_SUPPORTS_SAVE ) // directly for Kyugo? (Flashgal, Legend, SRD Mission, Airwolf, Planet Probe) +GAME( 1985, 99lstwarb, repulse, repulse, repulse, kyugo_state, 0, ROT90, "bootleg", "'99: The Last War (bootleg)", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS ) // bg_tilemap is wrong in some levels GAME( 1985, sonofphx, repulse, repulse, repulse, kyugo_state, 0, ROT90, "bootleg (Associated Overseas MFR, Inc.)", "Son of Phoenix (bootleg of Repulse)", MACHINE_SUPPORTS_SAVE ) GAME( 1985, flashgal, 0, repulse, flashgal, kyugo_state, 0, ROT0, "Kyugo / Sega", "Flashgal (set 1)", MACHINE_SUPPORTS_SAVE ) GAME( 1985, flashgalk, flashgal, repulse, flashgal, kyugo_state, 0, ROT0, "Kyugo / Sega", "Flashgal (set 1, Kyugo logo)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/laser3k.cpp b/src/mame/drivers/laser3k.cpp index 15c81db8508..147122baf07 100644 --- a/src/mame/drivers/laser3k.cpp +++ b/src/mame/drivers/laser3k.cpp @@ -980,22 +980,22 @@ static MACHINE_CONFIG_START( laser3k ) MCFG_DEVICE_ADD("bank0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(banks_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("bank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(banks_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("bank2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(banks_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("bank3", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(banks_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_RAM_ADD("mainram") diff --git a/src/mame/drivers/lb186.cpp b/src/mame/drivers/lb186.cpp index f64fe453e8e..bab75030513 100644 --- a/src/mame/drivers/lb186.cpp +++ b/src/mame/drivers/lb186.cpp @@ -92,7 +92,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( lb186_io, AS_IO, 16, lb186_state ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x1000, 0x101f) AM_DEVREADWRITE8("sc2681", mc68681_device, read, write, 0x00ff) + AM_RANGE(0x1000, 0x101f) AM_DEVREADWRITE8("duart", scn2681_device, read, write, 0x00ff) AM_RANGE(0x1080, 0x108f) AM_DEVREADWRITE8("scsibus:7:ncr5380", ncr5380n_device, read, write, 0x00ff) AM_RANGE(0x1100, 0x1107) AM_DEVREADWRITE8("fdc", wd1772_device, read, write, 0x00ff) AM_RANGE(0x1180, 0x1181) AM_READWRITE8(scsi_dack_r, scsi_dack_w, 0x00ff) @@ -124,16 +124,16 @@ static MACHINE_CONFIG_START( lb186 ) MCFG_CPU_PROGRAM_MAP(lb186_map) MCFG_CPU_IO_MAP(lb186_io) - MCFG_MC68681_ADD("sc2681", XTAL_3_6864MHz) + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) MCFG_MC68681_IRQ_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, int0_w)) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("rs232_1", rs232_port_device, write_txd)) MCFG_MC68681_B_TX_CALLBACK(DEVWRITELINE("rs232_2", rs232_port_device, write_txd)) MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(lb186_state, sio_out_w)) MCFG_RS232_PORT_ADD("rs232_1", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sc2681", mc68681_device, rx_a_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_a_w)) MCFG_RS232_PORT_ADD("rs232_2", default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sc2681", mc68681_device, rx_b_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_b_w)) MCFG_WD1772_ADD("fdc", XTAL_16MHz/2) MCFG_WD_FDC_INTRQ_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, int2_w)) diff --git a/src/mame/drivers/lethal.cpp b/src/mame/drivers/lethal.cpp index 08cbdccc65f..228a734aef6 100644 --- a/src/mame/drivers/lethal.cpp +++ b/src/mame/drivers/lethal.cpp @@ -499,8 +499,8 @@ static MACHINE_CONFIG_START( lethalen ) MCFG_DEVICE_ADD("bank4000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank4000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_EEPROM_SERIAL_ER5911_8BIT_ADD("eeprom") diff --git a/src/mame/drivers/lg-dvd.cpp b/src/mame/drivers/lg-dvd.cpp index e3aba7d3d0b..c393a4cdaa5 100644 --- a/src/mame/drivers/lg-dvd.cpp +++ b/src/mame/drivers/lg-dvd.cpp @@ -14,11 +14,11 @@ class lg_dvd_state : public driver_device public: lg_dvd_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) - , maincpu(*this, "maincpu") + , m_maincpu(*this, "maincpu") { } protected: - required_device<i80c52_device> maincpu; + required_device<i80c52_device> m_maincpu; }; static INPUT_PORTS_START( lg ) diff --git a/src/mame/drivers/lilith.cpp b/src/mame/drivers/lilith.cpp index 6d2ffd9e92e..6af40142897 100644 --- a/src/mame/drivers/lilith.cpp +++ b/src/mame/drivers/lilith.cpp @@ -9,26 +9,28 @@ CPU consists of various parts including AM2901 and AM2911. ************************************************************************************************************************************/ #include "emu.h" -//#include "cpu/mcs51/mcs51.h" class lilith_state : public driver_device { public: lilith_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) -// , maincpu(*this, "maincpu") +// , m_maincpu(*this, "maincpu") { } -protected: -// required_device<i80c52_device> maincpu; +private: +// required_device<cpu_device> m_maincpu; }; -static INPUT_PORTS_START( lilith ) -INPUT_PORTS_END +//static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, lilith_state ) +//ADDRESS_MAP_END -//static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, lilith_state ) +//static ADDRESS_MAP_START( io_map, AS_PROGRAM, 8, lilith_state ) //ADDRESS_MAP_END +static INPUT_PORTS_START( lilith ) +INPUT_PORTS_END + static MACHINE_CONFIG_START( lilith ) MACHINE_CONFIG_END diff --git a/src/mame/drivers/lola8a.cpp b/src/mame/drivers/lola8a.cpp index 7a22a1d7f13..5252dcd1066 100644 --- a/src/mame/drivers/lola8a.cpp +++ b/src/mame/drivers/lola8a.cpp @@ -17,6 +17,10 @@ DLOAD DSAVE DVERIFY MERGE CAT RUN NEW ON LIST DEF MON GWIND TWIND UNDER SPC OFF TAB THEN TO STEP AND OR XOR NOT ABS LEN SQR INT ASC CHR VAL STR MID ARG CALL RND LEFT RIGHT DOT SGN SIN FREE PI FN TAN COS POP PEEK INP LN EXP ATN + + COLOUR x (x = 0 to 3) there's no known colour ram, unable to determine + how colours can be displayed. Therefore we only show black and white. + ****************************************************************************/ #include "emu.h" @@ -39,28 +43,26 @@ public: lola8a_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") - , m_cass(*this, "cassette"), - m_palette(*this, "palette") + , m_cass(*this, "cassette") + , m_palette(*this, "palette") + , m_p_videoram(*this, "videoram") { } - required_device<cpu_device> m_maincpu; - - virtual void machine_reset() override { m_maincpu->set_pc(0x8000); } - DECLARE_READ8_MEMBER(lola8a_port_a_r); DECLARE_WRITE8_MEMBER(lola8a_port_b_w); DECLARE_WRITE_LINE_MEMBER(crtc_vsync); DECLARE_READ_LINE_MEMBER(cass_r); DECLARE_WRITE_LINE_MEMBER(cass_w); - DECLARE_READ8_MEMBER(keyboard_r); MC6845_UPDATE_ROW(crtc_update_row); private: uint8_t m_portb; + virtual void machine_reset() override { m_maincpu->set_pc(0x8000); } + required_device<cpu_device> m_maincpu; required_device<cassette_image_device> m_cass; -public: required_device<palette_device> m_palette; + required_shared_ptr<uint8_t> m_p_videoram; }; static ADDRESS_MAP_START(lola8a_mem, AS_PROGRAM, 8, lola8a_state) @@ -72,7 +74,7 @@ static ADDRESS_MAP_START(lola8a_mem, AS_PROGRAM, 8, lola8a_state) AM_RANGE( 0x8000, 0x9fff ) AM_ROM // 2764A at B45 AM_RANGE( 0xa000, 0xbfff ) AM_ROM // 2764A at C45 AM_RANGE( 0xc000, 0xdfff ) AM_ROM // 2764A at H67 - AM_RANGE( 0xe000, 0xffff ) AM_RAM // 6264 at G67 + AM_RANGE( 0xe000, 0xffff ) AM_RAM AM_SHARE("videoram") // 6264 at G67 ADDRESS_MAP_END static ADDRESS_MAP_START(lola8a_io, AS_IO, 8, lola8a_state) @@ -191,22 +193,29 @@ INPUT_PORTS_END MC6845_UPDATE_ROW( lola8a_state::crtc_update_row ) { - address_space &program = m_maincpu->space(AS_PROGRAM); + const rgb_t *palette = m_palette->palette()->entry_list_raw(); + u8 x,gfx; + u16 mem; + u32 *p = &bitmap.pix32(y); + ma &= 0x7ff; - for (int sx = 0; sx < x_count; sx++) + for (x = 0; x < x_count; x++) { - uint16_t addr = 0xa000 + sx*8 + ra + ma * 8; - uint8_t code = program.read_byte(addr); - - for (int x = 0; x <= 8; x++) - { - int color = BIT(code, 7-x) ? 7 : 0; - if (cursor_x==sx) color = 7; - bitmap.pix32(y, x + sx*8) = m_palette->pen_color(color); - } + mem = (x+ma)*8 + ra; + gfx = m_p_videoram[mem] ^ ((cursor_x == x) ? 0xff : 0); + + *p++ = palette[BIT(gfx, 7) ? 7 : 0]; + *p++ = palette[BIT(gfx, 6) ? 7 : 0]; + *p++ = palette[BIT(gfx, 5) ? 7 : 0]; + *p++ = palette[BIT(gfx, 4) ? 7 : 0]; + *p++ = palette[BIT(gfx, 3) ? 7 : 0]; + *p++ = palette[BIT(gfx, 2) ? 7 : 0]; + *p++ = palette[BIT(gfx, 1) ? 7 : 0]; + *p++ = palette[BIT(gfx, 0) ? 7 : 0]; } } + READ8_MEMBER(lola8a_state::lola8a_port_a_r) { logerror("lola8a_port_a_r\n"); diff --git a/src/mame/drivers/m10.cpp b/src/mame/drivers/m10.cpp index 1611df8ba6e..1910bfee2dd 100644 --- a/src/mame/drivers/m10.cpp +++ b/src/mame/drivers/m10.cpp @@ -131,18 +131,18 @@ Notes (couriersud) #define LOG(x) do { if (M10_DEBUG) printf x; } while (0) -WRITE8_MEMBER(m10_state::ic8j1_output_changed) +WRITE_LINE_MEMBER(m10_state::ic8j1_output_changed) { - LOG(("ic8j1: %d %d\n", data, m_screen->vpos())); - m_maincpu->set_input_line(0, !data ? CLEAR_LINE : ASSERT_LINE); + LOG(("ic8j1: %d %d\n", state, m_screen->vpos())); + m_maincpu->set_input_line(0, !state ? CLEAR_LINE : ASSERT_LINE); } -WRITE8_MEMBER(m10_state::ic8j2_output_changed) +WRITE_LINE_MEMBER(m10_state::ic8j2_output_changed) { /* written from /Q to A with slight delight */ - LOG(("ic8j2: %d\n", data)); - m_ic8j2->a_w(space, 0, data); - m_ic8j1->a_w(space, 0, data); + LOG(("ic8j2: %d\n", state)); + m_ic8j2->a_w(state); + m_ic8j1->a_w(state); } /************************************* @@ -444,8 +444,8 @@ READ8_MEMBER(m10_state::m10_a700_r) { //LOG(("rd:%d\n",m_screen->vpos())); LOG(("clear\n")); - m_ic8j1->clear_w(space, 0, 0); - m_ic8j1->clear_w(space, 0, 1); + m_ic8j1->clear_w(0); + m_ic8j1->clear_w(1); return 0x00; } @@ -454,8 +454,8 @@ READ8_MEMBER(m10_state::m11_a700_r) //LOG(("rd:%d\n",m_screen->vpos())); //m_maincpu->set_input_line(0, CLEAR_LINE); LOG(("clear\n")); - m_ic8j1->clear_w(space, 0, 0); - m_ic8j1->clear_w(space, 0, 1); + m_ic8j1->clear_w(0); + m_ic8j1->clear_w(1); return 0x00; } @@ -841,7 +841,7 @@ static MACHINE_CONFIG_START( m10 ) MCFG_TTL74123_A_PIN_VALUE(1) /* A pin - driven by the CRTC */ MCFG_TTL74123_B_PIN_VALUE(1) /* B pin - pulled high */ MCFG_TTL74123_CLEAR_PIN_VALUE(1) /* Clear pin - pulled high */ - MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITE8(m10_state, ic8j1_output_changed)) + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(m10_state, ic8j1_output_changed)) MCFG_DEVICE_ADD("ic8j2", TTL74123, 0) MCFG_TTL74123_CONNECTION_TYPE(TTL74123_NOT_GROUNDED_DIODE) /* the hook up type */ /* 10k + 20k variable resistor */ @@ -850,7 +850,7 @@ static MACHINE_CONFIG_START( m10 ) MCFG_TTL74123_A_PIN_VALUE(1) /* A pin - driven by the CRTC */ MCFG_TTL74123_B_PIN_VALUE(1) /* B pin - pulled high */ MCFG_TTL74123_CLEAR_PIN_VALUE(1) /* Clear pin - pulled high */ - MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITE8(m10_state, ic8j2_output_changed)) + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(m10_state, ic8j2_output_changed)) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mame/drivers/m24.cpp b/src/mame/drivers/m24.cpp index 52191dcd293..dd534c3d852 100644 --- a/src/mame/drivers/m24.cpp +++ b/src/mame/drivers/m24.cpp @@ -190,11 +190,6 @@ static ADDRESS_MAP_START(kbc_map, AS_PROGRAM, 8, m24_state) AM_RANGE(0xf800, 0xffff) AM_ROM AM_REGION("kbc", 0) ADDRESS_MAP_END -static ADDRESS_MAP_START(kbc_io, AS_IO, 8, m24_state) - AM_RANGE(TMS7000_PORTA, TMS7000_PORTA) AM_READ(pa_r) - AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_WRITE(pb_w) -ADDRESS_MAP_END - static INPUT_PORTS_START( m24 ) PORT_START("DSW0") PORT_DIPNAME( 0x8f, 0x89, "RAM banks") @@ -277,7 +272,8 @@ static MACHINE_CONFIG_START( olivetti ) MCFG_CPU_ADD("kbc", TMS7000, XTAL_4MHz) MCFG_CPU_PROGRAM_MAP(kbc_map) - MCFG_CPU_IO_MAP(kbc_io) + MCFG_TMS7000_IN_PORTA_CB(READ8(m24_state, pa_r)) + MCFG_TMS7000_OUT_PORTB_CB(WRITE8(m24_state, pb_w)) MCFG_DEVICE_ADD("keyboard", M24_KEYBOARD, 0) MCFG_M24_KEYBOARD_OUT_DATA_HANDLER(WRITELINE(m24_state, kbcin_w)) diff --git a/src/mame/drivers/m3.cpp b/src/mame/drivers/m3.cpp new file mode 100644 index 00000000000..72579e560cd --- /dev/null +++ b/src/mame/drivers/m3.cpp @@ -0,0 +1,144 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-20 Skeleton + +LSI M3 + +From disassembly: chips: Z80, 6845, 8251, 2x 8255, Z80CTC + + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "video/mc6845.h" +#include "screen.h" + +class m3_state : public driver_device +{ +public: + m3_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_p_chargen(*this, "chargen") + , m_p_videoram(*this, "videoram") + , m_palette(*this, "palette") + { } + + MC6845_UPDATE_ROW(crtc_update_row); + +private: + virtual void machine_reset() override; + required_device<cpu_device> m_maincpu; + required_region_ptr<u8> m_p_chargen; + required_shared_ptr<u8> m_p_videoram; + required_device<palette_device> m_palette; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, m3_state ) + AM_RANGE(0x0000, 0xe7ff) AM_RAM + AM_RANGE(0xe800, 0xefff) AM_RAM AM_SHARE("videoram") + AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION("roms", 0) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_PROGRAM, 8, m3_state ) + ADDRESS_MAP_GLOBAL_MASK (0xff) + AM_RANGE(0x84, 0x84) AM_DEVREADWRITE("crtc", mc6845_device, status_r, address_w) + AM_RANGE(0x85, 0x85) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w) +ADDRESS_MAP_END + +static INPUT_PORTS_START( m3 ) +INPUT_PORTS_END + +MC6845_UPDATE_ROW( m3_state::crtc_update_row ) +{ + const rgb_t *pens = m_palette->palette()->entry_list_raw(); + uint8_t chr,gfx,inv; + uint16_t mem,x; + uint32_t *p = &bitmap.pix32(y); + + for (x = 0; x < x_count; x++) + { + inv = (x == cursor_x) ? 0xff : 0; + mem = (ma + x) & 0x7ff; + chr = m_p_videoram[mem]; + if (BIT(chr, 7)) + { + inv ^= 0xff; + chr &= 0x7f; + } + + /* get pattern of pixels for that character scanline */ + gfx = m_p_chargen[(chr<<4) | ra] ^ inv; + + /* Display a scanline of a character (8 pixels) */ + *p++ = pens[BIT(gfx, 6)]; + *p++ = pens[BIT(gfx, 5)]; + *p++ = pens[BIT(gfx, 4)]; + *p++ = pens[BIT(gfx, 3)]; + *p++ = pens[BIT(gfx, 2)]; + *p++ = pens[BIT(gfx, 1)]; + *p++ = pens[BIT(gfx, 0)]; + } +} + +/* F4 Character Displayer */ +static const gfx_layout charlayout = +{ + 7, 16, /* 7 x 16 characters */ + 128, /* 128 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 0, 8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static GFXDECODE_START( f4disp ) + GFXDECODE_ENTRY( "chargen", 0x0000, charlayout, 0, 1 ) +GFXDECODE_END + +void m3_state::machine_reset() +{ + m_maincpu->set_pc(0xf000); +} + +static MACHINE_CONFIG_START( m3 ) + MCFG_CPU_ADD("maincpu", Z80, 2'000'000) // no idea of clock. + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + + /* video hardware */ + MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // not correct + MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update) + MCFG_SCREEN_SIZE(640, 480) + MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 479) + MCFG_GFXDECODE_ADD("gfxdecode", "palette", f4disp) + MCFG_PALETTE_ADD_MONOCHROME("palette") + + /* Devices */ + MCFG_MC6845_ADD("crtc", MC6845, "screen", 2'000'000) // clk unknown + MCFG_MC6845_SHOW_BORDER_AREA(false) + MCFG_MC6845_CHAR_WIDTH(7) + MCFG_MC6845_UPDATE_ROW_CB(m3_state, crtc_update_row) +MACHINE_CONFIG_END + +ROM_START( m3 ) + ROM_REGION( 0x3000, "roms", 0 ) + ROM_LOAD( "bootstrap_prom_(034).bin", 0x0000, 0x0800, CRC(7fdb051e) SHA1(7aa24d4f44b6a0c8f7f647667f4997432c186cac) ) + ROM_LOAD( "monitor_prom_v1.7_2015-12-09.bin", 0x0800, 0x0800, CRC(85b5c541) SHA1(92b4ec87a4d0d8c0f7b49eec0c5457f237de0a01) ) + + ROM_REGION( 0x0800, "chargen", 0 ) // bit 7 set on every byte - bad? + ROM_LOAD( "6845crt_font_prom_(033).bin", 0x0000, 0x0800, CRC(cc29f664) SHA1(4197530d9455d665fd4773f95bb6394f6b056dec) ) + + ROM_REGION( 0x0800, "keyboard", 0 ) + ROM_LOAD( "keyboard_prom_(032).bin", 0x0000, 0x0800, CRC(21548355) SHA1(ee4ce4af9c78474263dd58e0f19e79e5b00926fa) ) +ROM_END + +COMP( 19??, m3, 0, 0, m3, m3, m3_state, 0, "LSI", "M3", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/m6805evs.cpp b/src/mame/drivers/m6805evs.cpp index ca262cc0301..24cb5fb33d9 100644 --- a/src/mame/drivers/m6805evs.cpp +++ b/src/mame/drivers/m6805evs.cpp @@ -79,7 +79,7 @@ private: }; -static ADDRESS_MAP_START( m6805evs_mem, AS_PROGRAM, 8, m6805evs_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, m6805evs_state ) ADDRESS_MAP_GLOBAL_MASK(0x1fff) ADDRESS_MAP_UNMAP_HIGH @@ -101,7 +101,7 @@ void m6805evs_state::machine_reset() static MACHINE_CONFIG_START( m6805evs ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M6805, XTAL_4MHz) - MCFG_CPU_PROGRAM_MAP(m6805evs_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) MACHINE_CONFIG_END ROM_START(m6805evs) diff --git a/src/mame/drivers/m79152pc.cpp b/src/mame/drivers/m79152pc.cpp index 35c976fe304..bb1f109870a 100644 --- a/src/mame/drivers/m79152pc.cpp +++ b/src/mame/drivers/m79152pc.cpp @@ -12,6 +12,10 @@ #include "emu.h" #include "cpu/z80/z80.h" +#include "machine/z80ctc.h" +#include "machine/z80sio.h" +#include "machine/clock.h" +#include "bus/rs232/rs232.h" #include "screen.h" @@ -24,6 +28,7 @@ public: , m_p_attributes(*this, "attributes") , m_maincpu(*this, "maincpu") , m_p_chargen(*this, "chargen") + , m_uart(*this, "uart") { } uint32_t screen_update_m79152pc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); @@ -34,9 +39,10 @@ private: required_shared_ptr<uint8_t> m_p_attributes; required_device<cpu_device> m_maincpu; required_region_ptr<u8> m_p_chargen; + required_device<z80sio_device> m_uart; }; -static ADDRESS_MAP_START(m79152pc_mem, AS_PROGRAM, 8, m79152pc_state) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, m79152pc_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x3fff) AM_ROM AM_RANGE(0x4000, 0x47ff) AM_RAM @@ -44,9 +50,11 @@ static ADDRESS_MAP_START(m79152pc_mem, AS_PROGRAM, 8, m79152pc_state) AM_RANGE(0x9000, 0x9fff) AM_RAM AM_SHARE("attributes") ADDRESS_MAP_END -static ADDRESS_MAP_START( m79152pc_io, AS_IO, 8, m79152pc_state) +static ADDRESS_MAP_START( io_map, AS_IO, 8, m79152pc_state ) //ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x40, 0x43) AM_DEVREADWRITE("uart", z80sio_device, cd_ba_r, cd_ba_w) + AM_RANGE(0x44, 0x47) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) ADDRESS_MAP_END /* Input ports */ @@ -56,6 +64,7 @@ INPUT_PORTS_END void m79152pc_state::machine_reset() { + m_uart->ctsb_w(1); // this is checked before writing to port 47. } uint32_t m79152pc_state::screen_update_m79152pc(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) @@ -113,9 +122,8 @@ GFXDECODE_END static MACHINE_CONFIG_START( m79152pc ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) - MCFG_CPU_PROGRAM_MAP(m79152pc_mem) - MCFG_CPU_IO_MAP(m79152pc_io) - + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -127,6 +135,29 @@ static MACHINE_CONFIG_START( m79152pc ) MCFG_SCREEN_PALETTE("palette") MCFG_GFXDECODE_ADD("gfxdecode", "palette", m79152pc) MCFG_PALETTE_ADD_MONOCHROME("palette") + + MCFG_DEVICE_ADD("uart_clock", CLOCK, 153600) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("uart", z80sio_device, txca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart", z80sio_device, rxca_w)) + + MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_4MHz) + //MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + + MCFG_DEVICE_ADD("uart", Z80SIO, XTAL_4MHz) + //MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRA_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSA_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + //MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232a", rs232_port_device, write_txd)) + //MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232a", rs232_port_device, write_dtr)) + //MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232a", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "keyboard") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart", z80sio_device, rxa_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart", z80sio_device, ctsa_w)) + //MCFG_RS232_PORT_ADD("rs232a", default_rs232_devices, "terminal") + //MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart", z80sio_device, rxb_w)) + //MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart", z80sio_device, ctsb_w)) MACHINE_CONFIG_END /* ROM definition */ diff --git a/src/mame/drivers/m90.cpp b/src/mame/drivers/m90.cpp index 2899f17ee40..b121752189a 100644 --- a/src/mame/drivers/m90.cpp +++ b/src/mame/drivers/m90.cpp @@ -699,7 +699,7 @@ INTERRUPT_GEN_MEMBER(m90_state::bomblord_fake_nmi) INTERRUPT_GEN_MEMBER(m90_state::m90_interrupt) { - generic_pulse_irq_line(device.execute(), NEC_INPUT_LINE_INTP0, 1); + device.execute().pulse_input_line(NEC_INPUT_LINE_INTP0, device.execute().minimum_quantum_time()); } INTERRUPT_GEN_MEMBER(m90_state::dynablsb_interrupt) diff --git a/src/mame/drivers/macp.cpp b/src/mame/drivers/macp.cpp index 29896574351..eb8e8f786a5 100644 --- a/src/mame/drivers/macp.cpp +++ b/src/mame/drivers/macp.cpp @@ -141,7 +141,7 @@ GAME( 1986, macgalxy, 0, macp0, macp, macp_state, 0, ROT0, "MAC S.A.", "MAC's GAME( 1987, macjungl, 0, macp0, macp, macp_state, 0, ROT0, "MAC S.A.", "MAC Jungle", MACHINE_IS_SKELETON_MECHANICAL ) GAME( 1987, spctrain, 0, macp, macp, macp_state, 0, ROT0, "MAC S.A.", "Space Train (Pinball)", MACHINE_IS_SKELETON_MECHANICAL ) GAME( 1988, spcpnthr, 0, macpmsm, macp, macp_state, 0, ROT0, "MAC S.A.", "Space Panther", MACHINE_IS_SKELETON_MECHANICAL ) -GAME( 19??, mac_1808, 0, macpmsm, macp, macp_state, 0, ROT0, "MAC S.A.", "Unknown Game (MAC #1808)", MACHINE_IS_SKELETON_MECHANICAL ) +GAME( 19??, mac_1808, 0, macpmsm, macp, macp_state, 0, ROT0, "MAC S.A.", "unknown game (MAC #1808)", MACHINE_IS_SKELETON_MECHANICAL ) GAME( 1995, macjungn, 0, macpmsm, macp, macp_state, 0, ROT0, "MAC S.A.", "MAC Jungle (New version)", MACHINE_IS_SKELETON_MECHANICAL ) GAME( 1996, nbamac, 0, macpmsm, macp, macp_state, 0, ROT0, "MAC S.A.", "NBA MAC", MACHINE_IS_SKELETON_MECHANICAL ) diff --git a/src/mame/drivers/mainevt.cpp b/src/mame/drivers/mainevt.cpp index 03feedd4207..8df16552266 100644 --- a/src/mame/drivers/mainevt.cpp +++ b/src/mame/drivers/mainevt.cpp @@ -239,16 +239,16 @@ static INPUT_PORTS_START( mainevt ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE4 ) PORT_START("P1") - KONAMI8_B21_UNK(1) + KONAMI8_B12_UNK(1) PORT_START("P2") - KONAMI8_B21_UNK(2) + KONAMI8_B12_UNK(2) PORT_START("P3") - KONAMI8_B21_UNK(3) + KONAMI8_B12_UNK(3) PORT_START("P4") - KONAMI8_B21_UNK(4) + KONAMI8_B12_UNK(4) PORT_START("DSW1") PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:1,2,3,4") diff --git a/src/mame/drivers/majorpkr.cpp b/src/mame/drivers/majorpkr.cpp index 69c8bc63c0b..771a3dad155 100644 --- a/src/mame/drivers/majorpkr.cpp +++ b/src/mame/drivers/majorpkr.cpp @@ -995,15 +995,15 @@ static MACHINE_CONFIG_START( majorpkr ) MCFG_DEVICE_ADD("palette_bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(palettebanks) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x0800) MCFG_DEVICE_ADD("vram_bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vrambanks) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x0800) MCFG_NVRAM_ADD_0FILL("nvram") diff --git a/src/mame/drivers/mappy.cpp b/src/mame/drivers/mappy.cpp index 7f69dfeab4e..b5935bd983b 100644 --- a/src/mame/drivers/mappy.cpp +++ b/src/mame/drivers/mappy.cpp @@ -515,7 +515,7 @@ Notes: 99,99999,9999,9999,999999 it seems to be a counter decremented while the game is running. -- Mappy: similarly, if you enter service mode and press press +- Mappy: similarly, if you enter service mode and press P1 button + service coin the following is shown: 99.99.999.9999.9999.9999 99.99.999.9999.9999.0000 diff --git a/src/mame/drivers/marinedt.cpp b/src/mame/drivers/marinedt.cpp index b4b1518757c..198c71d990b 100644 --- a/src/mame/drivers/marinedt.cpp +++ b/src/mame/drivers/marinedt.cpp @@ -1,18 +1,28 @@ // license:BSD-3-Clause -// copyright-holders:David Haywood +// copyright-holders:Angelo Salese +/***************************************************************************************************************** -// **** SKELETON DRIVER **** original removed due to unresolved licensing. + Marine Date (c) 1981 Taito -/* + driver by Angelo Salese, + original "wiped off due of not anymore licenseable" driver by insideoutboy. + + TODO: + - discrete sound + - imperfect colors: unused bit 2 of color prom, guesswokred sea gradient, mg16 entirely unused. + also unused colors 0x10-0x1f (might be a flashing bank) + - collision detection isn't perfect, sometimes octopus gets stuck and dies even if moves are still available. + HW collision detection isn't perfect even from the reference, presumably needs a trojan run on the real HW. + - ROM writes (irq mask?) + - Merge devices with crbaloon/bking/grchamp drivers (PC3259). + +***************************************************************************************************************** Marine Date Taito 1981 - PCB Layout ---------- - Top board - MGO70001 MGN00001 |---------------------------------------------| @@ -39,10 +49,7 @@ Notes: (PCB contains lots of resistors/caps/transistors etc) 4030 - RCA CD4030 Quad Exclusive-Or Gate VR* - Volume pots for each sound VOL - Master Volume pot - - Middle board - MGO70002 MGN00002 |---------------------------------------------| @@ -63,10 +70,7 @@ Notes: MG12/13 - Hitachi HN462532 4kx8 EPROM MG14/15/16 - 82S123 bipolar PROM PC3259 - PC3259 8025 H08 unknown DIP24 IC. Package design indicates it was manufactured by Fujitsu - - Lower board - AA017779 sticker: MGN00003 sticker: CLN00002 @@ -91,32 +95,566 @@ Notes: Wire jumpers for ROM configuration - J1 open J2 1-2, 3-9, 4-8, 5-7 J4 1-2, 4-5, 7-8, 10-11 - Top and Middle PCBs are plugged in with the solder-sides together. Lower PCB is plugged in with components facing up. -------------------------------------------------------------------------- -*/ + +*****************************************************************************************************************/ #include "emu.h" +#include "cpu/z80/z80.h" +#include "screen.h" +#include "speaker.h" + +#define MAIN_CLOCK XTAL_9_987MHz class marinedt_state : public driver_device { public: marinedt_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) - { } + , m_maincpu(*this, "maincpu") + , m_screen(*this, "screen") + , m_vram(*this, "vram") + , m_gfxdecode(*this, "gfxdecode") + , m_in_track(*this, {"P1_TRACKX", "P2_TRACKX", "P1_TRACKY", "P2_TRACKY"}) + { + } + + // screen updates + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + DECLARE_PALETTE_INIT(marinedt); + DECLARE_READ8_MEMBER(trackball_r); + DECLARE_READ8_MEMBER(pc3259_r); + DECLARE_WRITE8_MEMBER(vram_w); + DECLARE_WRITE8_MEMBER(obj_0_w); + DECLARE_WRITE8_MEMBER(obj_1_w); + DECLARE_WRITE8_MEMBER(bgm_w); + DECLARE_WRITE8_MEMBER(sfx_w); + DECLARE_WRITE8_MEMBER(layer_enable_w); + DECLARE_WRITE8_MEMBER(output_w); + TILE_GET_INFO_MEMBER(get_tile_info); + +protected: + // driver_device overrides + virtual void machine_start() override; + virtual void machine_reset() override; + + virtual void video_start() override; + +private: + // devices + required_device<cpu_device> m_maincpu; + required_device<screen_device> m_screen; + required_shared_ptr<uint8_t> m_vram; + required_device<gfxdecode_device> m_gfxdecode; + required_ioport_array<4> m_in_track; + + tilemap_t *m_tilemap; + std::unique_ptr<bitmap_ind16> m_seabitmap[2]; + struct + { + uint8_t offs; + uint8_t x; + uint8_t y; + bitmap_ind16 bitmap; + }m_obj[2]; + + uint8_t m_layer_en; + uint8_t m_in_select; + bool m_screen_flip; + uint8_t m_sea_bank; + + void init_seabitmap(); + void obj_reg_w(uint8_t which,uint8_t reg, uint8_t data); + uint32_t obj_to_obj_collision(); + uint32_t obj_to_layer_collision(); }; +TILE_GET_INFO_MEMBER(marinedt_state::get_tile_info) +{ + int code = m_vram[tile_index]; + + SET_TILE_INFO_MEMBER(0, code, 0, 0); +} + +// initialize sea bitmap gradient +void marinedt_state::init_seabitmap() +{ + const rectangle clip(32, 256, 32, 256); + m_seabitmap[0] = std::make_unique<bitmap_ind16>(512, 512); + m_seabitmap[1] = std::make_unique<bitmap_ind16>(512, 512); + + m_seabitmap[0]->fill(64, clip); + m_seabitmap[1]->fill(64+32, clip); + + for (int y = clip.min_y; y <= clip.max_y; y++) + { + for (int x = clip.min_x; x <= clip.max_x; x++) + { + // TODO: exact formula (related to total h size?) + uint8_t blue_pen = 0x48 + ((x-32) / 8); + // clamp + if(blue_pen > 0x5f) + blue_pen = 0x5f; + + m_seabitmap[0]->pix16(y, x) = blue_pen; + m_seabitmap[1]->pix16(y, x) = blue_pen+0x20; + } + } +} + +void marinedt_state::video_start() +{ + m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(marinedt_state::get_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 32, 32); + + m_tilemap->set_transparent_pen(0); + + init_seabitmap(); + +// m_obj[0].bitmap = std::make_unique<bitmap_ind16>(512, 512); +// m_obj[1].bitmap = std::make_unique<bitmap_ind16>(512, 512); + +// m_screen->register_screen_bitmap(m_seabitmap); + m_screen->register_screen_bitmap(m_obj[0].bitmap); + m_screen->register_screen_bitmap(m_obj[1].bitmap); + + save_item(NAME(m_obj[0].x)); + save_item(NAME(m_obj[0].y)); + save_item(NAME(m_obj[0].offs)); + save_item(NAME(m_obj[1].x)); + save_item(NAME(m_obj[1].y)); + save_item(NAME(m_obj[1].offs)); + save_item(NAME(m_obj[0].bitmap)); + save_item(NAME(m_obj[1].bitmap)); + save_item(NAME(m_layer_en)); + save_item(NAME(m_sea_bank)); +} + +uint32_t marinedt_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) +{ + if(m_layer_en & 8) + copybitmap(bitmap, *m_seabitmap[m_sea_bank], m_screen_flip == false, m_screen_flip == false, m_screen_flip ? 0 : -256, m_screen_flip ? 0 : -224, cliprect); + else + bitmap.fill(0,cliprect); + + m_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + if(m_layer_en & 2) + copybitmap_trans(bitmap, m_obj[1].bitmap, 0, 0, 0, 0, cliprect, 0); + if(m_layer_en & 1) + copybitmap_trans(bitmap, m_obj[0].bitmap, 0, 0, 0, 0, cliprect, 0); + + return 0; +} + +WRITE8_MEMBER(marinedt_state::vram_w) +{ + m_vram[offset] = data; + m_tilemap->mark_tile_dirty(offset); +} + +inline void marinedt_state::obj_reg_w(uint8_t which, uint8_t reg,uint8_t data) +{ + rectangle visarea = m_screen->visible_area(); + //const uint8_t base_pen;// = which == 0 ? 0x30 : 0x20; + gfx_element *gfx = m_gfxdecode->gfx(which+1); + + switch(reg) + { + case 0: m_obj[which].offs = data; break; + // TODO: are offsets good? + case 1: m_obj[which].x = (data + 4) & 0xff; break; + case 2: m_obj[which].y = (data + 1) & 0xff; break; + } + + const uint8_t tilenum = ((m_obj[which].offs & 4) << 1) | ( (m_obj[which].offs & 0x38) >> 3); + const uint8_t color = (m_obj[which].offs & 3); + const bool fx = BIT(m_obj[which].offs,6); + const bool fy = BIT(m_obj[which].offs,7); + + //base_pen = (which == 0 ? 0x30 : 0x20) + color*4; + m_obj[which].bitmap.fill(0,visarea); + // redraw sprite in framebuffer using above + // bitmap,cliprect,tilenum,color,flipx,flipy,xpos,ypos,transpen + gfx->transpen(m_obj[which].bitmap,visarea,tilenum,color,fx,!fy,m_obj[which].x,m_obj[which].y,0); +} + +WRITE8_MEMBER(marinedt_state::obj_0_w) { obj_reg_w(0,offset,data); } +WRITE8_MEMBER(marinedt_state::obj_1_w) { obj_reg_w(1,offset,data); } + +READ8_MEMBER(marinedt_state::trackball_r) +{ + return (m_in_track[m_in_select & 3])->read(); +} + +// discrete sound +WRITE8_MEMBER(marinedt_state::bgm_w) +{ + // ... +} + +WRITE8_MEMBER(marinedt_state::sfx_w) +{ + /* + x--- ---- unknown, probably ties to PC3259 pin 16 like crbaloon + --x- ---- jet sound SFX + ---x ---- foam SFX + ---- x--- ink SFX + ---- -x-- collision SFX + ---- --x- dots hit SFX + ---- ---x irq mask in crbaloon, doesn't seem to apply here? + */ +// if(data & 0x7e) +// popmessage("%02x",data); +} + +WRITE8_MEMBER(marinedt_state::layer_enable_w) +{ + /* + ---x ---- enabled when shark appears (enables red gradient on sea bitmap apparently) + ---- x--- sea layer draw enable (disabled in test mode) + ---- --x- obj 2 draw enable + ---- ---x obj 1 draw enable + */ + m_layer_en = data & 0xf; + m_sea_bank = (data & 0x10) >> 4; +} + +WRITE8_MEMBER(marinedt_state::output_w) +{ + /* + ---- x--- trackball input select (x/y) + ---- -x-- trackball player select + ---- --x- flipscreen + ---- ---x global coin lockout (disabled in service mode) + */ + + m_in_select = (data & 0xc) >> 2; + m_screen_flip = BIT(data,1); + flip_screen_set(!m_screen_flip); + machine().bookkeeping().coin_lockout_global_w(!(data & 1)); +} + +// collision detection +// we return a value in the form of y<<5|x in case collision occurred +inline uint32_t marinedt_state::obj_to_obj_collision() +{ + // bail out if any obj is disabled + if((m_layer_en & 3) != 3) + return 0; + + for(int y=0;y<32;y++) + { + for(int x=0;x<32;x++) + { + int resx,resy; + + resx = m_obj[0].x + x; + resy = m_obj[0].y + y; + + if((m_obj[0].bitmap.pix16(resy,resx) & 3) == 0) + continue; + + // return value is never read most likely + if(m_obj[1].bitmap.pix16(resy,resx) != 0) + return ((resy / 8) * 32) | (((resx / 8) - 1) & 0x1f); + } + } + + return 0; +} + +inline uint32_t marinedt_state::obj_to_layer_collision() +{ + // bail out if obj target is disabled + if((m_layer_en & 1) == 0) + return 0; + + for(int y=0;y<32;y++) + { + for(int x=0;x<32;x++) + { + uint16_t resx,resy; + + resx = m_obj[0].x + x; + resy = m_obj[0].y + y; + + if((m_obj[0].bitmap.pix16(resy,resx) & 3) == 0) + continue; + + if(!m_screen_flip) + resy -= 32; + + // TODO: non screen flip path doesn't work properly + if(m_tilemap->pixmap().pix16(resy,resx) != 0) + { + if(m_screen_flip) + return ((resy / 8) * 32) | (((resx / 8) - 1) & 0x1f); + else + return (((resy / 8) * 32) | (((resx / 8) - 1) & 0x1f)) ^ 0x3ff; + } + } + } + + return 0; +} + +READ8_MEMBER(marinedt_state::pc3259_r) +{ + uint32_t rest,reso; + uint8_t reg = offset >> 2; + uint8_t xt,xo; + rest = obj_to_layer_collision(); + reso = obj_to_obj_collision(); + + switch(reg) + { + case 0: + xt = rest & 0xf; + xo = reso & 0xf; + return xt|(xo<<4); + case 1: + xt = (rest & 0xf0) >> 4; + xo = (reso & 0xf0) >> 4; + return xt|(xo<<4); + case 2: + xt = (rest & 0x300) >> 8; + xo = (reso & 0x300) >> 8; + return xt|(xo<<4); + case 3: + { + uint8_t res = 0; + res |= ((reso != 0)<<7); + res |= ((rest != 0)<<3); + return res; + } + } + + + return 0; +} + +static ADDRESS_MAP_START( marinedt_map, AS_PROGRAM, 8, marinedt_state ) + ADDRESS_MAP_GLOBAL_MASK(0x7fff) /* A15 is not decoded */ + AM_RANGE(0x0000, 0x3fff) AM_ROM AM_REGION("ipl",0) + AM_RANGE(0x4000, 0x43ff) AM_MIRROR(0x0400) AM_RAM + AM_RANGE(0x4800, 0x4bff) AM_MIRROR(0x0400) AM_RAM_WRITE(vram_w) AM_SHARE("vram") +ADDRESS_MAP_END + +static ADDRESS_MAP_START( marinedt_io, AS_IO, 8, marinedt_state ) + ADDRESS_MAP_GLOBAL_MASK(0x0f) + AM_RANGE(0x00, 0x00) AM_READ_PORT("DSW1") + AM_RANGE(0x01, 0x01) AM_READ(trackball_r) + AM_RANGE(0x02, 0x02) AM_SELECT(0xc) AM_READ(pc3259_r) + AM_RANGE(0x02, 0x04) AM_WRITE(obj_0_w) + AM_RANGE(0x03, 0x03) AM_READ_PORT("SYSTEM") + AM_RANGE(0x04, 0x04) AM_READ_PORT("DSW2") + AM_RANGE(0x05, 0x05) AM_WRITE(bgm_w) + AM_RANGE(0x06, 0x06) AM_WRITE(sfx_w) + AM_RANGE(0x08, 0x0b) AM_WRITE(obj_1_w) + AM_RANGE(0x0d, 0x0d) AM_WRITE(layer_enable_w) + AM_RANGE(0x0e, 0x0e) AM_WRITENOP // watchdog + AM_RANGE(0x0f, 0x0f) AM_WRITE(output_w) +ADDRESS_MAP_END static INPUT_PORTS_START( marinedt ) + PORT_START("SYSTEM") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SERVICE1 ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_TILT ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Ink Button") + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Ink Button") PORT_COCKTAIL + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_START2 ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_START1 ) + + // TODO: diplocations needs to be verified + PORT_START("DSW1") + PORT_DIPNAME( 0x0f, 0x00, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SWA:4,3,2,1") + PORT_DIPSETTING( 0x0f, DEF_STR( 9C_1C ) ) + PORT_DIPSETTING( 0x0e, DEF_STR( 8C_1C ) ) + PORT_DIPSETTING( 0x0d, DEF_STR( 7C_1C ) ) + PORT_DIPSETTING( 0x0c, DEF_STR( 6C_1C ) ) + PORT_DIPSETTING( 0x0b, DEF_STR( 5C_1C ) ) + PORT_DIPSETTING( 0x0a, DEF_STR( 4C_1C ) ) + PORT_DIPSETTING( 0x09, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x08, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x01, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x02, DEF_STR( 1C_3C ) ) + PORT_DIPSETTING( 0x03, DEF_STR( 1C_4C ) ) + PORT_DIPSETTING( 0x04, DEF_STR( 1C_5C ) ) + PORT_DIPSETTING( 0x05, DEF_STR( 1C_6C ) ) + PORT_DIPSETTING( 0x06, DEF_STR( 1C_7C ) ) + PORT_DIPSETTING( 0x07, DEF_STR( 1C_8C ) ) + PORT_DIPNAME( 0xf0, 0x00, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SWA:8,7,6,5") + PORT_DIPSETTING( 0xf0, DEF_STR( 9C_1C ) ) + PORT_DIPSETTING( 0xe0, DEF_STR( 8C_1C ) ) + PORT_DIPSETTING( 0xd0, DEF_STR( 7C_1C ) ) + PORT_DIPSETTING( 0xc0, DEF_STR( 6C_1C ) ) + PORT_DIPSETTING( 0xb0, DEF_STR( 5C_1C ) ) + PORT_DIPSETTING( 0xa0, DEF_STR( 4C_1C ) ) + PORT_DIPSETTING( 0x90, DEF_STR( 3C_1C ) ) + PORT_DIPSETTING( 0x80, DEF_STR( 2C_1C ) ) + PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) + PORT_DIPSETTING( 0x10, DEF_STR( 1C_2C ) ) + PORT_DIPSETTING( 0x20, DEF_STR( 1C_3C ) ) + PORT_DIPSETTING( 0x30, DEF_STR( 1C_4C ) ) + PORT_DIPSETTING( 0x40, DEF_STR( 1C_5C ) ) + PORT_DIPSETTING( 0x50, DEF_STR( 1C_6C ) ) + PORT_DIPSETTING( 0x60, DEF_STR( 1C_7C ) ) + PORT_DIPSETTING( 0x70, DEF_STR( 1C_8C ) ) + + PORT_START("DSW2") + PORT_DIPNAME( 0x01, 0x00, "DSWB" ) PORT_DIPLOCATION("SWB:1") + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x00, "Disable sprite-tile collision (Cheat)" ) PORT_DIPLOCATION("SWB:2") + PORT_DIPSETTING( 0x02, DEF_STR( Yes ) ) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_SERVICE_DIPLOC( 0x04, IP_ACTIVE_HIGH, "SWB:3") + PORT_DIPNAME( 0x08, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SWB:4") + PORT_DIPSETTING( 0x08, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) + PORT_DIPNAME( 0x10, 0x10, "Number of Coin Chutes") PORT_DIPLOCATION("SWB:5") + PORT_DIPSETTING( 0x10, "2" ) + PORT_DIPSETTING( 0x00, "1" ) + PORT_DIPNAME( 0x20, 0x00, "Year Display" ) PORT_DIPLOCATION("SWB:6") + PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) + PORT_DIPSETTING( 0x20, DEF_STR( No ) ) + PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SWB:8,7") + PORT_DIPSETTING( 0x00, "3" ) + PORT_DIPSETTING( 0x40, "4" ) + PORT_DIPSETTING( 0x80, "5" ) + PORT_DIPSETTING( 0xc0, "6" ) + + PORT_START("P1_TRACKX") + PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_REVERSE + + PORT_START("P1_TRACKY") + PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) + + PORT_START("P2_TRACKX") + PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_REVERSE PORT_COCKTAIL + + PORT_START("P2_TRACKY") + PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_COCKTAIL INPUT_PORTS_END +static const gfx_layout charlayout = +{ + 8,8, + RGN_FRAC(1,3), + 3, + { RGN_FRAC(0,3), RGN_FRAC(1,3), RGN_FRAC(2,3) }, + { STEP8(7,-1) }, + { STEP8(0,8) }, + 8*8 +}; + +static const gfx_layout objlayout = +{ + 32,32, + RGN_FRAC(1,1), + 2, + { 0, 4 }, + { STEP4(32*8*7,1), STEP4(32*8*6,1), STEP4(32*8*5,1), STEP4(32*8*4,1), STEP4(32*8*3,1), STEP4(32*8*2,1), STEP4(32*8*1,1), STEP4(32*8*0,1) }, + { STEP16(0,8), STEP16(16*8,8) }, + 32*32*2 +}; + +static GFXDECODE_START( marinedt ) + GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 4 ) + GFXDECODE_ENTRY( "gfx2", 0, objlayout, 48, 4 ) + GFXDECODE_ENTRY( "gfx3", 0, objlayout, 32, 4 ) +GFXDECODE_END + + +void marinedt_state::machine_start() +{ +} + +void marinedt_state::machine_reset() +{ + m_layer_en = 0; +} + + +PALETTE_INIT_MEMBER(marinedt_state, marinedt) +{ + const uint8_t *color_prom = memregion("proms")->base(); + int i; + int bit0, bit1, bit2; + int r, g, b; + + for (i = 0; i < 64; i++) + { + /* red component */ + bit0 = (color_prom[i] >> 0) & 0x01; + bit1 = (color_prom[i] >> 1) & 0x01; +// bit2 = (color_prom[i] >> 2) & 0x01; + r = (0x55 * bit0 + 0xaa * bit1); + + /* green component */ + bit0 = (color_prom[i] >> 3) & 0x01; + bit1 = (color_prom[i] >> 4) & 0x01; + g = (0x55 * bit0 + 0xaa * bit1); + + /* blue component */ + bit0 = (color_prom[i] >> 5) & 0x01; + bit1 = (color_prom[i] >> 6) & 0x01; + bit2 = (color_prom[i] >> 7) & 0x01; + b = (0x55 * bit0 + 0xaa * bit1); + // matches yellow haired siren + if(bit2 == 0) + b/=2; + + palette.set_pen_color(i, rgb_t(r, g, b)); + } + + + for (i = 0; i < 32; i++) + { + b = color_prom[i+0x60]; + palette.set_pen_color(64+31-i, rgb_t(0, 0, b)); + palette.set_pen_color(64+63-i, rgb_t(0xff, 0, b)); + } +} static MACHINE_CONFIG_START( marinedt ) + + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu",Z80,MAIN_CLOCK/4) + MCFG_CPU_PROGRAM_MAP(marinedt_map) + MCFG_CPU_IO_MAP(marinedt_io) + MCFG_CPU_VBLANK_INT_DRIVER("screen", marinedt_state, irq0_line_hold) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_UPDATE_DRIVER(marinedt_state, screen_update) + MCFG_SCREEN_RAW_PARAMS(MAIN_CLOCK/2, 328, 0, 256, 263, 32, 256) // template to get ~60 fps + MCFG_SCREEN_PALETTE("palette") + + MCFG_GFXDECODE_ADD("gfxdecode", "palette", marinedt) + + MCFG_PALETTE_ADD("palette", 64+64) + MCFG_PALETTE_INIT_OWNER(marinedt_state, marinedt) + + /* sound hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") +// MCFG_SOUND_ADD("aysnd", AY8910, MAIN_CLOCK/4) +// MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.30) MACHINE_CONFIG_END + +/*************************************************************************** + + Machine driver(s) + +***************************************************************************/ + ROM_START( marinedt ) - ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_REGION( 0x4000, "ipl", ROMREGION_ERASEFF ) ROM_LOAD( "mg01.3d", 0x0000, 0x0800, CRC(ad09f04d) SHA1(932fc973b4a2fbbebd7e6437ed30c8444e3d4afb)) ROM_LOAD( "mg02.4d", 0x0800, 0x0800, CRC(555a2b0f) SHA1(143a8953ce5070c31dc4c1f623833b2a5a2cf657)) ROM_LOAD( "mg03.5d", 0x1000, 0x0800, CRC(2abc79b3) SHA1(1afb331a2c0e320b6d026bc5cb47a53ac3356c2a)) @@ -126,9 +664,9 @@ ROM_START( marinedt ) ROM_LOAD( "mg07.10d", 0x3000, 0x0800, CRC(b85d1f9a) SHA1(4fd3e76b1816912df84477dba4655d395f5e7072) ) ROM_REGION( 0x1800, "gfx1", 0 ) - ROM_LOAD( "mg09.4f", 0x0000, 0x0800, CRC(f4c349ca) SHA1(077f65eeac616a778d6c42bb95677fa2892ab697) ) + ROM_LOAD( "mg11.1f", 0x0000, 0x0800, CRC(50d66dd7) SHA1(858d1d2a75e091b0e382d964c5e4ddcd8e6f07dd)) ROM_LOAD( "mg10.3f", 0x0800, 0x0800, CRC(b41251e3) SHA1(e125a971b401c78efeb4b03d0fab43e392d3fc14) ) - ROM_LOAD( "mg11.1f", 0x1000, 0x0800, CRC(50d66dd7) SHA1(858d1d2a75e091b0e382d964c5e4ddcd8e6f07dd)) + ROM_LOAD( "mg09.4f", 0x1000, 0x0800, CRC(f4c349ca) SHA1(077f65eeac616a778d6c42bb95677fa2892ab697) ) ROM_REGION( 0x1000, "gfx2", 0 ) ROM_LOAD( "mg12.6c", 0x0000, 0x1000, CRC(7c6486d5) SHA1(a7f17a803937937f05fc90621883a0fd44b297a0) ) @@ -136,11 +674,11 @@ ROM_START( marinedt ) ROM_REGION( 0x1000, "gfx3", 0 ) ROM_LOAD( "mg13.6h", 0x0000, 0x1000, CRC(17817044) SHA1(8c9b96620e3c414952e6d85c6e81b0df85c88e7a) ) - ROM_REGION( 0x0080, "proms", 0 ) - ROM_LOAD( "mg14.2a", 0x0000, 0x0020, CRC(f75f4e3a) SHA1(36e665987f475c57435fa8c224a2a3ce0c5e672b) ) - ROM_LOAD( "mg15.1a", 0x0020, 0x0020, CRC(cd3ab489) SHA1(a77478fb94d0cf8f4317f89cc9579def7c294b4f) ) - ROM_LOAD( "mg16.4e", 0x0040, 0x0020, CRC(92c868bc) SHA1(483ae6f47845ddacb701528e82bd388d7d66a0fb) ) - ROM_LOAD( "mg17.bpr", 0x0060, 0x0020, CRC(13261a02) SHA1(050edd18e4f79d19d5206f55f329340432fd4099) ) + ROM_REGION( 0x0080, "proms", ROMREGION_INVERT ) + ROM_LOAD( "mg14.2a", 0x0000, 0x0020, CRC(f75f4e3a) SHA1(36e665987f475c57435fa8c224a2a3ce0c5e672b) ) // tilemap colors + ROM_LOAD( "mg15.1a", 0x0020, 0x0020, CRC(cd3ab489) SHA1(a77478fb94d0cf8f4317f89cc9579def7c294b4f) ) // sprite colors + ROM_LOAD( "mg16.4e", 0x0040, 0x0020, CRC(92c868bc) SHA1(483ae6f47845ddacb701528e82bd388d7d66a0fb) ) // (related to sprites) + ROM_LOAD( "mg17.bpr", 0x0060, 0x0020, CRC(13261a02) SHA1(050edd18e4f79d19d5206f55f329340432fd4099) ) // sea bitmap colors ROM_END -GAME( 1981, marinedt, 0, marinedt, marinedt, marinedt_state, 0, ROT270, "Taito", "Marine Date", MACHINE_IS_SKELETON ) +GAME( 1981, marinedt, 0, marinedt, marinedt, marinedt_state, 0, ROT270, "Taito", "Marine Date", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION | MACHINE_IMPERFECT_COLORS | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/maygay1b.cpp b/src/mame/drivers/maygay1b.cpp index a236c2d786a..e8d95836dcf 100644 --- a/src/mame/drivers/maygay1b.cpp +++ b/src/mame/drivers/maygay1b.cpp @@ -776,7 +776,7 @@ MACHINE_CONFIG_START( maygay_m1 ) MCFG_CPU_IO_MAP(maygay_mcu_io) - MCFG_MC68681_ADD("duart68681", M1_DUART_CLOCK) + MCFG_DEVICE_ADD("duart68681", MC68681, M1_DUART_CLOCK) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(maygay1b_state, duart_irq_handler)) MCFG_MC68681_INPORT_CALLBACK(READ8(maygay1b_state, m1_duart_r)) diff --git a/src/mame/drivers/maygayv1.cpp b/src/mame/drivers/maygayv1.cpp index 2288214dd6d..7577957b9cc 100644 --- a/src/mame/drivers/maygayv1.cpp +++ b/src/mame/drivers/maygayv1.cpp @@ -897,7 +897,7 @@ static MACHINE_CONFIG_START( maygayv1 ) MCFG_PALETTE_ADD("palette", 16) - MCFG_MC68681_ADD("duart68681", DUART_CLOCK) + MCFG_DEVICE_ADD("duart68681", MC68681, DUART_CLOCK) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(maygayv1_state, duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(WRITELINE(maygayv1_state, duart_txa)) diff --git a/src/mame/drivers/mc1502.cpp b/src/mame/drivers/mc1502.cpp index dcb17a6c0cc..9c99c957128 100644 --- a/src/mame/drivers/mc1502.cpp +++ b/src/mame/drivers/mc1502.cpp @@ -6,6 +6,11 @@ Driver file for Elektronika MS 1502 + To do: + - fix video errors caused by 465caf8038a120b4c1ffad9df67a1dc7474e5bb1 + "cga: treat as fixed sync monitor (nw)" + - debug video init in BIOS 7.2 + ***************************************************************************/ #include "emu.h" @@ -374,6 +379,10 @@ ROM_START( mc1502 ) ROMX_LOAD( "msv5~2b0.pgm", 0xc000, 0x2000, CRC(f7f370e9) SHA1(e069a35005581a02856853b57dd511ab8e10054b),ROM_BIOS(10)) ROMX_LOAD( "msv5~2b1.pgm", 0xe000, 0x2000, CRC(d50e1c43) SHA1(22724dec0052ee9e52f44f5914f2f5f3fae14612),ROM_BIOS(10)) + // 7.2 + ROM_SYSTEM_BIOS(10, "v72", "v7.2 01/21/96") + ROMX_LOAD( "7.2_1.bin", 0xe000, 0x2000, CRC(80912ad4) SHA1(cc54b77b2db4cc5d614efafd04367d2f06400fc8),ROM_BIOS(11)) + ROM_REGION(0x2000,"gfx1", ROMREGION_ERASE00) ROM_LOAD( "symgen.rom", 0x0000, 0x2000, CRC(b2747a52) SHA1(6766d275467672436e91ac2997ac6b77700eba1e)) ROM_END diff --git a/src/mame/drivers/mc80.cpp b/src/mame/drivers/mc80.cpp deleted file mode 100644 index 9838d6b9390..00000000000 --- a/src/mame/drivers/mc80.cpp +++ /dev/null @@ -1,342 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Miodrag Milanovic -/*************************************************************************** - - MC-80.xx driver by Miodrag Milanovic - - 15/05/2009 Initial implementation - 12/05/2009 Skeleton driver. - 01/09/2011 Modernised, added a keyboard to mc8020 - -Real workings of mc8020 keyboard need to be understood and implemented. - -mc80.3x: http://www.ycdt.net/mc80.3x/ - -mc8030: very little info available. The area from FFD8-FFFF is meant for -interrupt vectors and so on, but most of it is zeroes. Appears the keyboard -is an ascii keyboard with built-in beeper. It communicates via the SIO, -which needs a rewrite to become useful. The asp ctc needs at least 2 -triggers. The purpose of the zve pio is unknown. The system uses interrupts -for various things, but none of that is working. - -****************************************************************************/ - -#include "emu.h" -#include "includes/mc80.h" -#include "screen.h" - -static ADDRESS_MAP_START(mc8020_mem, AS_PROGRAM, 8, mc80_state) - ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x0000, 0x0bff) AM_ROM - AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("videoram")// 1KB RAM ZRE - AM_RANGE(0x2000, 0x5fff) AM_ROM - AM_RANGE(0x6000, 0xffff) AM_RAM -ADDRESS_MAP_END - -static ADDRESS_MAP_START(mc8020_io, AS_IO, 8, mc80_state) - ADDRESS_MAP_UNMAP_HIGH - ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0xf0, 0xf3) AM_DEVREADWRITE("z80ctc", z80ctc_device, read, write) - AM_RANGE(0xf4, 0xf7) AM_DEVREADWRITE("z80pio", z80pio_device, read, write) -ADDRESS_MAP_END - -static ADDRESS_MAP_START(mc8030_mem, AS_PROGRAM, 8, mc80_state) - ADDRESS_MAP_UNMAP_HIGH - // ZRE 4 * 2KB - AM_RANGE(0x0000, 0x1fff) AM_ROM // ZRE ROM's 4 * 2716 - AM_RANGE(0x2000, 0x27ff) AM_ROM // SPE ROM's 2 * 2708 - AM_RANGE(0x2800, 0x3fff) AM_ROM // For extension - AM_RANGE(0x4000, 0xbfff) AM_RAM // SPE RAM - AM_RANGE(0xc000, 0xffff) AM_RAM // ZRE RAM -ADDRESS_MAP_END - -static ADDRESS_MAP_START(mc8030_io, AS_IO, 8, mc80_state) - ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x30, 0x3f) AM_MIRROR(0xff00) AM_NOP //"mass storage" - AM_RANGE(0x80, 0x83) AM_MIRROR(0xff00) AM_DEVREADWRITE("zve_ctc", z80ctc_device, read, write) // user CTC - AM_RANGE(0x84, 0x87) AM_MIRROR(0xff00) AM_DEVREADWRITE("zve_pio", z80pio_device, read, write) // PIO unknown usage - AM_RANGE(0x88, 0x8f) AM_MIRROR(0xff00) AM_WRITE(mc8030_zve_write_protect_w) - AM_RANGE(0xc0, 0xcf) AM_SELECT(0xff00) AM_WRITE(mc8030_vis_w) - AM_RANGE(0xd0, 0xd3) AM_MIRROR(0xff00) AM_DEVREADWRITE("asp_sio", z80sio0_device, cd_ba_r, cd_ba_w) // keyboard & IFSS? - AM_RANGE(0xd4, 0xd7) AM_MIRROR(0xff00) AM_DEVREADWRITE("asp_ctc", z80ctc_device, read, write) // sio bauds, KMBG? and kbd - AM_RANGE(0xd8, 0xdb) AM_MIRROR(0xff00) AM_DEVREADWRITE("asp_pio", z80pio_device, read, write) // external bus - AM_RANGE(0xe0, 0xef) AM_MIRROR(0xff00) AM_WRITE(mc8030_eprom_prog_w) -ADDRESS_MAP_END - -/* Input ports */ -static INPUT_PORTS_START( mc8020 ) - PORT_START("X1") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('!') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('@') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('#') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('$') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('%') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('&') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('\'') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('(') - - PORT_START("X2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('9') PORT_CHAR(')') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('0') PORT_CHAR('\"') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('+') PORT_CHAR('*') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('^') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('/') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - - PORT_START("X3") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') - - PORT_START("X4") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') - - PORT_START("X5") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') - - PORT_START("X6") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('?') - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR(']') - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - - PORT_START("X7") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) -INPUT_PORTS_END - -static INPUT_PORTS_START( mc8030 ) -INPUT_PORTS_END - - -TIMER_DEVICE_CALLBACK_MEMBER(mc80_state::mc8020_kbd) -{ - address_space &mem = m_maincpu->space(AS_PROGRAM); - char kbdrow[6]; - uint8_t i; - for (i = 1; i < 8; i++) - { - sprintf(kbdrow,"X%X", i); - mem.write_word(0xd20+i, ioport(kbdrow)->read()); - } -} - -// this is a guess there is no information available -static const z80_daisy_config mc8030_daisy_chain[] = -{ - { "asp_ctc" }, /* System ctc */ - { "asp_pio" }, /* System pio */ - { "asp_sio" }, /* sio */ - { "zve_pio" }, /* User pio */ - { "zve_ctc" }, /* User ctc */ - { nullptr } -}; - -static MACHINE_CONFIG_START( mc8020 ) - /* basic machine hardware */ - MCFG_CPU_ADD("maincpu",Z80, XTAL_2_4576MHz) - MCFG_CPU_PROGRAM_MAP(mc8020_mem) - MCFG_CPU_IO_MAP(mc8020_io) - MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(mc80_state,mc8020_irq_callback) - - MCFG_MACHINE_RESET_OVERRIDE(mc80_state,mc8020) - - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ - MCFG_SCREEN_SIZE(32*6, 16*8) - MCFG_SCREEN_VISIBLE_AREA(0, 32*6-1, 0, 16*8-1) - MCFG_VIDEO_START_OVERRIDE(mc80_state,mc8020) - MCFG_SCREEN_UPDATE_DRIVER(mc80_state, screen_update_mc8020) - MCFG_SCREEN_PALETTE("palette") - - MCFG_PALETTE_ADD_MONOCHROME("palette") - - /* devices */ - MCFG_DEVICE_ADD("z80pio", Z80PIO, XTAL_2_4576MHz) - MCFG_Z80PIO_IN_PA_CB(READ8(mc80_state, mc80_port_a_r)) - MCFG_Z80PIO_OUT_PA_CB(WRITE8(mc80_state, mc80_port_a_w)) - MCFG_Z80PIO_IN_PB_CB(READ8(mc80_state, mc80_port_b_r)) - MCFG_Z80PIO_OUT_PB_CB(WRITE8(mc80_state, mc80_port_b_w)) - - MCFG_DEVICE_ADD("z80ctc", Z80CTC, XTAL_2_4576MHz / 100) - MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_Z80CTC_ZC0_CB(WRITELINE(mc80_state, ctc_z0_w)) - MCFG_Z80CTC_ZC1_CB(WRITELINE(mc80_state, ctc_z1_w)) - MCFG_Z80CTC_ZC2_CB(WRITELINE(mc80_state, ctc_z2_w)) - - MCFG_TIMER_DRIVER_ADD_PERIODIC("mc8020_kbd", mc80_state, mc8020_kbd, attotime::from_hz(50)) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_START( mc8030 ) - /* basic machine hardware */ - MCFG_CPU_ADD("maincpu",Z80, XTAL_2_4576MHz) - MCFG_CPU_PROGRAM_MAP(mc8030_mem) - MCFG_CPU_IO_MAP(mc8030_io) - MCFG_Z80_DAISY_CHAIN(mc8030_daisy_chain) - MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(mc80_state,mc8030_irq_callback) - - MCFG_MACHINE_RESET_OVERRIDE(mc80_state,mc8030) - - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ - MCFG_SCREEN_SIZE(512, 256) - MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1) - MCFG_VIDEO_START_OVERRIDE(mc80_state,mc8030) - MCFG_SCREEN_UPDATE_DRIVER(mc80_state, screen_update_mc8030) - MCFG_SCREEN_PALETTE("palette") - - MCFG_PALETTE_ADD_MONOCHROME("palette") - - /* Devices */ - MCFG_DEVICE_ADD("zve_pio", Z80PIO, XTAL_2_4576MHz) - MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_Z80PIO_IN_PA_CB(READ8(mc80_state, zve_port_a_r)) - MCFG_Z80PIO_OUT_PA_CB(WRITE8(mc80_state, zve_port_a_w)) - MCFG_Z80PIO_IN_PB_CB(READ8(mc80_state, zve_port_b_r)) - MCFG_Z80PIO_OUT_PB_CB(WRITE8(mc80_state, zve_port_b_w)) - - MCFG_DEVICE_ADD("zve_ctc", Z80CTC, XTAL_2_4576MHz) - MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - // ZC0, ZC1, ZC2 for user - - MCFG_DEVICE_ADD("asp_pio", Z80PIO, XTAL_2_4576MHz) - MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_Z80PIO_IN_PA_CB(READ8(mc80_state, asp_port_a_r)) - MCFG_Z80PIO_OUT_PA_CB(WRITE8(mc80_state, asp_port_a_w)) - MCFG_Z80PIO_IN_PB_CB(READ8(mc80_state, asp_port_b_r)) - MCFG_Z80PIO_OUT_PB_CB(WRITE8(mc80_state, asp_port_b_w)) - - MCFG_DEVICE_ADD("asp_ctc", Z80CTC, XTAL_2_4576MHz) - MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - // ZC0: to SIO CLK CH A - // ZC1: to SIO CLK CH B - // ZC2: KMBG (??) - - MCFG_DEVICE_ADD("asp_sio", Z80SIO0, 4800) - // SIO CH A in = keyboard; out = beeper; CH B = IFSS (??) -MACHINE_CONFIG_END - -/* ROM definition */ -ROM_START( mc8020 ) - ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) - ROM_SYSTEM_BIOS(0, "ver1", "Version 1") - ROMX_LOAD( "s01.rom", 0x0000, 0x0400, CRC(0f1c1a62) SHA1(270c0a9e8e165658f3b09d40a3e8bb3dc1b88184), ROM_BIOS(1)) - ROMX_LOAD( "s02.rom", 0x0400, 0x0400, CRC(93b5811c) SHA1(8559d24072c9b5908a2627ff986d818308f51d59), ROM_BIOS(1)) - ROMX_LOAD( "s03.rom", 0x0800, 0x0400, CRC(3d32c334) SHA1(56d3012595540d03054ad3c6795ed5d929581a04), ROM_BIOS(1)) - ROMX_LOAD( "mo01_v2.rom", 0x2000, 0x0400, CRC(7e47201c) SHA1(db49afdc5c1fe4065a979c56cbdbd3c58f5d942f), ROM_BIOS(1)) - - ROM_SYSTEM_BIOS(1, "ver2", "Version 2") - ROMX_LOAD( "s01.rom", 0x0000, 0x0400, CRC(0f1c1a62) SHA1(270c0a9e8e165658f3b09d40a3e8bb3dc1b88184), ROM_BIOS(2)) - ROMX_LOAD( "s02_v2.rom", 0x0400, 0x0400, CRC(dd26c90a) SHA1(1108c11362fa63d21110a3b17868c1854a318c09), ROM_BIOS(2)) - ROMX_LOAD( "s03_v2.rom", 0x0800, 0x0400, CRC(5b64ee7b) SHA1(3b4cbfcb8e2dedcfd4a3680c81fe6ceb2211b275), ROM_BIOS(2)) - ROMX_LOAD( "mo01.rom", 0x2000, 0x0400, CRC(c65a470f) SHA1(71325fed1a342149b5efc2234ecfc8adfff0a42d), ROM_BIOS(2)) - - ROM_SYSTEM_BIOS(2, "ver3", "Version 3") - ROMX_LOAD( "s01.rom", 0x0000, 0x0400, CRC(0f1c1a62) SHA1(270c0a9e8e165658f3b09d40a3e8bb3dc1b88184), ROM_BIOS(3)) - ROMX_LOAD( "s02_v3.rom", 0x0400, 0x0400, CRC(40c7a694) SHA1(bcdf382e8dad9bb6e06d23ec018e9df55c8d8d0c), ROM_BIOS(3)) - ROMX_LOAD( "s03.rom", 0x0800, 0x0400, CRC(3d32c334) SHA1(56d3012595540d03054ad3c6795ed5d929581a04), ROM_BIOS(3)) - ROMX_LOAD( "mo01_v2.rom",0x2000, 0x0400, CRC(7e47201c) SHA1(db49afdc5c1fe4065a979c56cbdbd3c58f5d942f), ROM_BIOS(3)) - - // m02 doesn't exist on board - ROM_LOAD( "mo03.rom", 0x2800, 0x0400, CRC(29685056) SHA1(39e77658fb7af5a28112341f0893e007d73c1b7a)) - ROM_LOAD( "mo04.rom", 0x2c00, 0x0400, CRC(fd315b73) SHA1(cfb943ec8c884a9b92562d05f92faf06fe42ad68)) - ROM_LOAD( "mo05.rom", 0x3000, 0x0400, CRC(453d6370) SHA1(d96f0849a2da958d7e92a31667178ad140719477)) - ROM_LOAD( "mo06.rom", 0x3400, 0x0400, CRC(6357aba5) SHA1(a4867766f6e14e9fe66f22a6839f17c01058c8af)) - ROM_LOAD( "mo07.rom", 0x3800, 0x0400, CRC(a1eb6021) SHA1(b05b63f02de89f065f337bbe54c5b48244e3a4ba)) - ROM_LOAD( "mo08.rom", 0x3c00, 0x0400, CRC(8221cc32) SHA1(65e0ee4241d39d138205c88374b3bcd127e21511)) - ROM_LOAD( "mo09.rom", 0x4000, 0x0400, CRC(7ad5944d) SHA1(ef2781b114277a09ce0cf2e7decfdb7c48a693e3)) - ROM_LOAD( "mo10.rom", 0x4400, 0x0400, CRC(11de8c76) SHA1(b384d22506ff7e3e28bd2dcc33b7a69617eeb52a)) - ROM_LOAD( "mo11.rom", 0x4800, 0x0400, CRC(370cc672) SHA1(133f6e8bfd4e1ca2e9e0a8e2342084419f895e3c)) - ROM_LOAD( "mo12.rom", 0x4c00, 0x0400, CRC(a3838f2b) SHA1(e3602943700bf5068117946bf86f052f5c587169)) - ROM_LOAD( "mo13.rom", 0x5000, 0x0400, CRC(88b61d12) SHA1(00dd4452b4d4191e589ab58ba924ed21b10f323b)) - ROM_LOAD( "mo14.rom", 0x5400, 0x0400, CRC(2168da19) SHA1(c1ce1263167067d8be0a90604d9c29b7379a0545)) - ROM_LOAD( "mo15.rom", 0x5800, 0x0400, CRC(e32f54c4) SHA1(c3d9ca2204e7adbc625cf96031acb8c1df0447c7)) - ROM_LOAD( "mo16.rom", 0x5c00, 0x0400, CRC(403be935) SHA1(4e74355a78ab090ce180437156fed8e4a1d1c787)) -ROM_END - -ROM_START( mc8030 ) - ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "zve_1.rom", 0x0000, 0x0800, CRC(31ec0159) SHA1(a97ea9eb733c462e77d625a7942134e45d911c0a)) - ROM_LOAD( "zve_2.rom", 0x0800, 0x0800, CRC(5104983d) SHA1(7516274904042f4fc6813aa8b2a75c0a64f9b937)) - ROM_LOAD( "zve_3.rom", 0x1000, 0x0800, CRC(4bcfd727) SHA1(d296e587098e70270ad60db8edaa685af368b849)) - ROM_LOAD( "zve_4.rom", 0x1800, 0x0800, CRC(f949ae43) SHA1(68c324cf5578497db7ae65da5695fcb30493f612)) - ROM_LOAD( "spe_1.rom", 0x2000, 0x0400, CRC(826f609c) SHA1(e77ff6c180f5a6d7756d076173ae264a0e26f066)) - ROM_LOAD( "spe_2.rom", 0x2400, 0x0400, CRC(98320040) SHA1(6baf87e196f1ccdf44912deafa6042becbfb0679)) - - ROM_REGION( 0x4000, "vram", ROMREGION_ERASE00 ) - - ROM_REGION( 0x4000, "user1", 0 ) - // marked as "80.3x" - ROM_LOAD( "mc80.3-x-2c00-c63c.bin", 0x2c00, 0x0400, CRC(469be754) SHA1(a7fea257a1c0970349f75504c0870a2649b50303) ) - ROM_LOAD( "mc80.3-ccd-3000-f10a.bin", 0x3000, 0x0400, CRC(7d220128) SHA1(bb6070c9d460ec7ea1a1b46b19ca9520d55e127c) ) // 80.3x ccd test system - ROM_LOAD( "mc80.3-x-3800-7280.bin", 0x3800, 0x0400, CRC(09976efb) SHA1(1a708adbf1cd68d450a9bfccafe1f82e755e5885) ) - // marked as "80.3x rk" - ROM_LOAD( "mc80.3-rk-3000-5642.bin", 0x3000, 0x0400, CRC(280b2211) SHA1(d2c05ff7f7ea534776bf7e92263f1c10192e5385) ) - ROM_LOAD( "mc80.3-rk-3400-c6a7.bin", 0x3400, 0x0400, CRC(fc5656f3) SHA1(0ad5abb6536665719693063bf8da2993238c84dd) ) - ROM_LOAD( "mc80.3-rk-3800-1678.bin", 0x3800, 0x0400, CRC(34d7e1cf) SHA1(14d3e49f34e0c2a95967613538b33a671998e7a8) ) - // marked as "80.30e v1" - ROM_LOAD( "mc80.30e-0000.bin", 0x0000, 0x0800, CRC(ebdf766f) SHA1(d06f1e4467104f59554168d17cd15b98d107375e) ) - // marked as "80.30e v2" - ROM_LOAD( "mc80.30e-0000v2.bin", 0x0000, 0x0800, CRC(259b55e9) SHA1(6e8fd84f1b225f33bc0fd30ecc6e30b8063eaeed) ) - ROM_LOAD( "mc80.30e-0800v2.bin", 0x0800, 0x0800, CRC(fe7a01a7) SHA1(6531cde5b9dea2a15a813598937aa3d9540a8066) ) - // marked as "80.31e" - ROM_LOAD( "mc80.31e-2400-d0d7.bin", 0x2400, 0x0400, CRC(43c22046) SHA1(a179fe83b5cbbbc5f92a4b2ef1012099ccb333d9) ) - ROM_LOAD( "mc80.31e-3000-0d15.bin", 0x3000, 0x0400, CRC(cf6f090b) SHA1(0bc352ca42f41cfe7e28052c099dcd020b776dd5) ) - ROM_LOAD( "mc80.31e-3400-9993.bin", 0x3400, 0x0400, CRC(918d2b55) SHA1(b6dec17e996c464cf189a699d24d270494540b49) ) - ROM_LOAD( "mc80.31e-3800-7a4c.bin", 0x3800, 0x0400, CRC(62d9f989) SHA1(a20b731daed51270d86f486751302055eb93dd1c) ) - // marked as "80.31e?" - ROM_LOAD( "mc80.3s-2000.bin", 0x2000, 0x0400, CRC(28f1df56) SHA1(9752c9eab3d9f72c23b5f5618a5db1a038953e29) ) - ROM_LOAD( "mc80.3s-2400.bin", 0x2400, 0x0400, CRC(43c22046) SHA1(a179fe83b5cbbbc5f92a4b2ef1012099ccb333d9) ) - ROM_LOAD( "mc80.3s-2800.bin", 0x2800, 0x0400, CRC(4b52deb1) SHA1(f8a9ddb4363f8389990fd263985e882a73265c5d) ) - ROM_LOAD( "mc80.3s-2c00.bin", 0x2c00, 0x0400, CRC(a13d8302) SHA1(1fcdcd6b7af8ef4b18a0658a1a50d0db26b7f214) ) - ROM_LOAD( "mc80.3s-3000.bin", 0x3000, 0x0400, CRC(cf6f090b) SHA1(0bc352ca42f41cfe7e28052c099dcd020b776dd5) ) - ROM_LOAD( "mc80.3s-3400.bin", 0x3400, 0x0400, CRC(918d2b55) SHA1(b6dec17e996c464cf189a699d24d270494540b49) ) - ROM_LOAD( "mc80.3s-3800.bin", 0x3800, 0x0400, CRC(6104646b) SHA1(630f7c57e928db0eb4070139a66f2d313a6314b4) ) - ROM_LOAD( "mc80.3s-3c00.bin", 0x3c00, 0x0400, CRC(2f82d032) SHA1(fe8f642b94a0ba8852ec56d8cbb7a52bb7e5d55a) ) - // marked as "80.33 original" - ROM_LOAD( "mc80.33-1000.bin", 0x1000, 0x0800, CRC(c7e062b1) SHA1(81b999655b32d9b39287a08896a274278a2f739c) ) - // random set, zve_1 - 4 same as main set - ROM_LOAD( "spe_1a.rom", 0x2000, 0x000800, CRC(37c71c68) SHA1(951650698b00f65facf5ccfbd8dd13628a93425d) ) - ROM_LOAD( "spe_2a.rom", 0x2800, 0x000400, CRC(9ec8f287) SHA1(cdf5a9583d898814ba480ffbc8d906a642c6dc81) ) -ROM_END - -/* Driver */ - -// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -COMP( 198?, mc8020, 0, 0, mc8020, mc8020, mc80_state, 0, "VEB Elektronik Gera", "MC-80.21/22", MACHINE_NO_SOUND ) -COMP( 198?, mc8030, mc8020, 0, mc8030, mc8030, mc80_state, 0, "VEB Elektronik Gera", "MC-80.30/31", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | ORIENTATION_FLIP_X ) diff --git a/src/mame/drivers/mc8020.cpp b/src/mame/drivers/mc8020.cpp new file mode 100644 index 00000000000..a839d4b0a01 --- /dev/null +++ b/src/mame/drivers/mc8020.cpp @@ -0,0 +1,368 @@ +// license:BSD-3-Clause +// copyright-holders:Miodrag Milanovic, Robbbert +/*************************************************************************** + +MC-80.20 driver by Miodrag Milanovic + +2009-05-12 Skeleton driver. +2009-05-15 Initial implementation +2011-09-01 Modernised, added a keyboard + +ToDo: +- Find out if it has sound hardware, add if so +- What port B on PIO is for +- Find out the correct frequencies and connections for the CTC + +****************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "cpu/z80/z80daisy.h" +#include "machine/clock.h" +#include "machine/z80ctc.h" +#include "machine/z80pio.h" +#include "screen.h" + +class mc8020_state : public driver_device +{ +public: + mc8020_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_p_videoram(*this, "videoram") + , m_maincpu(*this, "maincpu") + , m_keyboard(*this, "X%u", 0) + { } + + DECLARE_READ8_MEMBER(port_b_r); + DECLARE_WRITE8_MEMBER(port_a_w); + DECLARE_WRITE8_MEMBER(port_b_w); + uint32_t screen_update_mc8020(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + +private: + u8 m_row; + required_shared_ptr<u8> m_p_videoram; + required_device<cpu_device> m_maincpu; + required_ioport_array<7> m_keyboard; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, mc8020_state ) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x0000, 0x0bff) AM_ROM + AM_RANGE(0x0c00, 0x0fff) AM_RAM AM_SHARE("videoram")// 1KB RAM ZRE + AM_RANGE(0x2000, 0x5fff) AM_ROM + AM_RANGE(0x6000, 0xffff) AM_RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_IO, 8, mc8020_state ) + ADDRESS_MAP_UNMAP_HIGH + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0xf0, 0xf3) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) + AM_RANGE(0xf4, 0xf7) AM_DEVREADWRITE("pio", z80pio_device, read_alt, write_alt) +ADDRESS_MAP_END + + +/* Input ports */ +static INPUT_PORTS_START( mc8020 ) + PORT_START("X0") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR('!') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('@') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('#') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('$') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('%') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('&') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('\'') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('(') + + PORT_START("X1") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('0') PORT_CHAR('\"') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('+') PORT_CHAR('*') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('^') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('/') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + + PORT_START("X2") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') + + PORT_START("X3") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') + + PORT_START("X4") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') + + PORT_START("X5") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('?') + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR(']') + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + + PORT_START("X6") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_UP) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_DOWN) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_RIGHT) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LEFT) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL) + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) +INPUT_PORTS_END + + +READ8_MEMBER( mc8020_state::port_b_r ) +{ + if (m_row == 0x40) + return m_keyboard[0]->read(); + else + if (m_row == 0x20) + return m_keyboard[1]->read(); + else + if (m_row == 0x10) + return m_keyboard[2]->read(); + else + if (m_row == 0x08) + return m_keyboard[3]->read(); + else + if (m_row == 0x04) + return m_keyboard[4]->read(); + else + if (m_row == 0x02) + return m_keyboard[5]->read(); + else + if (m_row == 0x01) + return m_keyboard[6]->read(); + else + return 0; +} + +WRITE8_MEMBER( mc8020_state::port_a_w ) +{ + m_row = data; +} + +WRITE8_MEMBER( mc8020_state::port_b_w ) +{ +} + + +// This is not a content of U402 510 +// but order is fine +static const uint8_t prom[] = { + 0x0c,0x11,0x13,0x15,0x17,0x10,0x0e,0x00, // @ + 0x04,0x0a,0x11,0x11,0x1f,0x11,0x11,0x00, // A + 0x1e,0x11,0x11,0x1e,0x11,0x11,0x1e,0x00, // B + 0x0e,0x11,0x10,0x10,0x10,0x11,0x0e,0x00, // C + 0x1e,0x09,0x09,0x09,0x09,0x09,0x1e,0x00, // D + 0x1f,0x10,0x10,0x1e,0x10,0x10,0x1f,0x00, // E + 0x1f,0x10,0x10,0x1e,0x10,0x10,0x10,0x00, // F + 0x0e,0x11,0x10,0x10,0x13,0x11,0x0f,0x00, // G + + 0x11,0x11,0x11,0x1f,0x11,0x11,0x11,0x00, // H + 0x0e,0x04,0x04,0x04,0x04,0x04,0x0e,0x00, // I + 0x01,0x01,0x01,0x01,0x11,0x11,0x0e,0x00, // J + 0x11,0x12,0x14,0x18,0x14,0x12,0x11,0x00, // K + 0x10,0x10,0x10,0x10,0x10,0x10,0x1f,0x00, // L + 0x11,0x1b,0x15,0x15,0x11,0x11,0x11,0x00, // M + 0x11,0x11,0x19,0x15,0x13,0x11,0x11,0x00, // N + 0x0e,0x11,0x11,0x11,0x11,0x11,0x0e,0x00, // O + + 0x1e,0x11,0x11,0x1e,0x10,0x10,0x10,0x00, // P + 0x0e,0x11,0x11,0x11,0x15,0x12,0x0d,0x00, // Q + 0x1e,0x11,0x11,0x1e,0x14,0x12,0x11,0x00, // R + 0x0e,0x11,0x10,0x0e,0x01,0x11,0x0e,0x00, // S + 0x1f,0x04,0x04,0x04,0x04,0x04,0x04,0x00, // T + 0x11,0x11,0x11,0x11,0x11,0x11,0x0e,0x00, // U + 0x11,0x11,0x11,0x0a,0x0a,0x04,0x04,0x00, // V + 0x11,0x11,0x11,0x15,0x15,0x15,0x0a,0x00, // W + + 0x11,0x11,0x0a,0x04,0x0a,0x11,0x11,0x00, // X + 0x11,0x11,0x0a,0x04,0x04,0x04,0x04,0x00, // Y + 0x1f,0x01,0x02,0x04,0x08,0x10,0x1f,0x00, // Z + 0x1c,0x10,0x10,0x10,0x10,0x10,0x1c,0x00, // [ + 0x00,0x10,0x08,0x04,0x02,0x01,0x00,0x00, // backslash + 0x07,0x01,0x01,0x01,0x01,0x01,0x07,0x00, // ] + 0x0e,0x11,0x00,0x00,0x00,0x00,0x00,0x00, // ^ + 0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00, // _ + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // + 0x04,0x04,0x04,0x04,0x04,0x00,0x04,0x00, // ! + 0x0a,0x0a,0x0a,0x00,0x00,0x00,0x00,0x00, // " + 0x0a,0x0a,0x1f,0x0a,0x1f,0x0a,0x0a,0x00, // # + 0x00,0x11,0x0e,0x0a,0x0e,0x11,0x00,0x00, // [] + 0x18,0x19,0x02,0x04,0x08,0x13,0x03,0x00, // % + 0x04,0x0a,0x0a,0x0c,0x15,0x12,0x0d,0x00, // & + 0x04,0x04,0x08,0x00,0x00,0x00,0x00,0x00, // ' + + 0x02,0x04,0x08,0x08,0x08,0x04,0x02,0x00, // ( + 0x08,0x04,0x02,0x02,0x02,0x04,0x08,0x00, // ) + 0x00,0x04,0x15,0x0e,0x15,0x04,0x00,0x00, // * + 0x00,0x04,0x04,0x1f,0x04,0x04,0x00,0x00, // + + 0x00,0x00,0x00,0x00,0x08,0x08,0x10,0x00, // , + 0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x00, // - + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00, // . + 0x00,0x01,0x02,0x04,0x08,0x10,0x00,0x00, // / + + 0x0e,0x11,0x13,0x15,0x19,0x11,0x0e,0x00, // 0 + 0x04,0x0c,0x04,0x04,0x04,0x04,0x0e,0x00, // 1 + 0x0e,0x11,0x01,0x06,0x08,0x10,0x1f,0x00, // 2 + 0x1f,0x01,0x02,0x06,0x01,0x11,0x0e,0x00, // 3 + 0x02,0x06,0x0a,0x12,0x1f,0x02,0x02,0x00, // 4 + 0x1f,0x10,0x1e,0x01,0x01,0x11,0x0e,0x00, // 5 + 0x07,0x08,0x10,0x1e,0x11,0x11,0x0e,0x00, // 6 + 0x1f,0x01,0x02,0x04,0x08,0x08,0x08,0x00, // 7 + + 0x0e,0x11,0x11,0x0e,0x11,0x11,0x0e,0x00, // 8 + 0x0e,0x11,0x11,0x0f,0x01,0x02,0x1c,0x00, // 9 + 0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00, // : + 0x00,0x00,0x04,0x00,0x04,0x04,0x08,0x00, // ; + 0x02,0x04,0x08,0x10,0x08,0x04,0x02,0x00, // < + 0x00,0x00,0x1f,0x00,0x1f,0x00,0x00,0x00, // = + 0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00, // > + 0x0e,0x11,0x01,0x02,0x04,0x00,0x04,0x00 // ? +}; + + +uint32_t mc8020_state::screen_update_mc8020(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + uint8_t y,ra,chr,gfx; + uint16_t sy=0,ma=0,x; + + for(y = 0; y < 8; y++ ) + { + for (ra = 0; ra < 16; ra++) + { + uint16_t *p = &bitmap.pix16(sy++); + + for (x = ma; x < ma + 32; x++) + { + if (ra > 3 && ra < 12) + { + chr = m_p_videoram[x]; + gfx = prom[(chr<<3) | (ra-4)]; + } + else + gfx = 0; + + /* Display a scanline of a character */ + *p++ = BIT(gfx, 5); + *p++ = BIT(gfx, 4); + *p++ = BIT(gfx, 3); + *p++ = BIT(gfx, 2); + *p++ = BIT(gfx, 1); + *p++ = BIT(gfx, 0); + } + } + ma+=32; + } + return 0; +} + +static const z80_daisy_config daisy_chain[] = +{ + { "ctc" }, + { nullptr } +}; + +static MACHINE_CONFIG_START( mc8020 ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu",Z80, XTAL_2_4576MHz) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + MCFG_Z80_DAISY_CHAIN(daisy_chain) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ + MCFG_SCREEN_SIZE(32*6, 16*8) + MCFG_SCREEN_VISIBLE_AREA(0, 32*6-1, 0, 16*8-1) + MCFG_SCREEN_UPDATE_DRIVER(mc8020_state, screen_update_mc8020) + MCFG_SCREEN_PALETTE("palette") + + MCFG_PALETTE_ADD_MONOCHROME("palette") + + /* devices */ + MCFG_DEVICE_ADD("pio", Z80PIO, XTAL_2_4576MHz) + MCFG_Z80PIO_OUT_PA_CB(WRITE8(mc8020_state, port_a_w)) + MCFG_Z80PIO_IN_PB_CB(READ8(mc8020_state, port_b_r)) + MCFG_Z80PIO_OUT_PB_CB(WRITE8(mc8020_state, port_b_w)) + + MCFG_DEVICE_ADD("ctc_clock", CLOCK, XTAL_2_4576MHz / 64) // guess + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc", z80ctc_device, trg2)) + + MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_2_4576MHz) + MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80CTC_ZC2_CB(DEVWRITELINE("ctc", z80ctc_device, trg1)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc", z80ctc_device, trg0)) +MACHINE_CONFIG_END + + +/* ROM definition */ +ROM_START( mc8020 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + ROM_SYSTEM_BIOS(0, "ver1", "Version 1") + ROMX_LOAD( "s01.rom", 0x0000, 0x0400, CRC(0f1c1a62) SHA1(270c0a9e8e165658f3b09d40a3e8bb3dc1b88184), ROM_BIOS(1)) + ROMX_LOAD( "s02.rom", 0x0400, 0x0400, CRC(93b5811c) SHA1(8559d24072c9b5908a2627ff986d818308f51d59), ROM_BIOS(1)) + ROMX_LOAD( "s03.rom", 0x0800, 0x0400, CRC(3d32c334) SHA1(56d3012595540d03054ad3c6795ed5d929581a04), ROM_BIOS(1)) + ROMX_LOAD( "mo01_v2.rom", 0x2000, 0x0400, CRC(7e47201c) SHA1(db49afdc5c1fe4065a979c56cbdbd3c58f5d942f), ROM_BIOS(1)) + + ROM_SYSTEM_BIOS(1, "ver2", "Version 2") + ROMX_LOAD( "s01.rom", 0x0000, 0x0400, CRC(0f1c1a62) SHA1(270c0a9e8e165658f3b09d40a3e8bb3dc1b88184), ROM_BIOS(2)) + ROMX_LOAD( "s02_v2.rom", 0x0400, 0x0400, CRC(dd26c90a) SHA1(1108c11362fa63d21110a3b17868c1854a318c09), ROM_BIOS(2)) + ROMX_LOAD( "s03_v2.rom", 0x0800, 0x0400, CRC(5b64ee7b) SHA1(3b4cbfcb8e2dedcfd4a3680c81fe6ceb2211b275), ROM_BIOS(2)) + ROMX_LOAD( "mo01.rom", 0x2000, 0x0400, CRC(c65a470f) SHA1(71325fed1a342149b5efc2234ecfc8adfff0a42d), ROM_BIOS(2)) + + ROM_SYSTEM_BIOS(2, "ver3", "Version 3") + ROMX_LOAD( "s01.rom", 0x0000, 0x0400, CRC(0f1c1a62) SHA1(270c0a9e8e165658f3b09d40a3e8bb3dc1b88184), ROM_BIOS(3)) + ROMX_LOAD( "s02_v3.rom", 0x0400, 0x0400, CRC(40c7a694) SHA1(bcdf382e8dad9bb6e06d23ec018e9df55c8d8d0c), ROM_BIOS(3)) + ROMX_LOAD( "s03.rom", 0x0800, 0x0400, CRC(3d32c334) SHA1(56d3012595540d03054ad3c6795ed5d929581a04), ROM_BIOS(3)) + ROMX_LOAD( "mo01_v2.rom",0x2000, 0x0400, CRC(7e47201c) SHA1(db49afdc5c1fe4065a979c56cbdbd3c58f5d942f), ROM_BIOS(3)) + + // m02 doesn't exist on board + ROM_LOAD( "mo03.rom", 0x2800, 0x0400, CRC(29685056) SHA1(39e77658fb7af5a28112341f0893e007d73c1b7a)) + ROM_LOAD( "mo04.rom", 0x2c00, 0x0400, CRC(fd315b73) SHA1(cfb943ec8c884a9b92562d05f92faf06fe42ad68)) + ROM_LOAD( "mo05.rom", 0x3000, 0x0400, CRC(453d6370) SHA1(d96f0849a2da958d7e92a31667178ad140719477)) + ROM_LOAD( "mo06.rom", 0x3400, 0x0400, CRC(6357aba5) SHA1(a4867766f6e14e9fe66f22a6839f17c01058c8af)) + ROM_LOAD( "mo07.rom", 0x3800, 0x0400, CRC(a1eb6021) SHA1(b05b63f02de89f065f337bbe54c5b48244e3a4ba)) + ROM_LOAD( "mo08.rom", 0x3c00, 0x0400, CRC(8221cc32) SHA1(65e0ee4241d39d138205c88374b3bcd127e21511)) + ROM_LOAD( "mo09.rom", 0x4000, 0x0400, CRC(7ad5944d) SHA1(ef2781b114277a09ce0cf2e7decfdb7c48a693e3)) + ROM_LOAD( "mo10.rom", 0x4400, 0x0400, CRC(11de8c76) SHA1(b384d22506ff7e3e28bd2dcc33b7a69617eeb52a)) + ROM_LOAD( "mo11.rom", 0x4800, 0x0400, CRC(370cc672) SHA1(133f6e8bfd4e1ca2e9e0a8e2342084419f895e3c)) + ROM_LOAD( "mo12.rom", 0x4c00, 0x0400, CRC(a3838f2b) SHA1(e3602943700bf5068117946bf86f052f5c587169)) + ROM_LOAD( "mo13.rom", 0x5000, 0x0400, CRC(88b61d12) SHA1(00dd4452b4d4191e589ab58ba924ed21b10f323b)) + ROM_LOAD( "mo14.rom", 0x5400, 0x0400, CRC(2168da19) SHA1(c1ce1263167067d8be0a90604d9c29b7379a0545)) + ROM_LOAD( "mo15.rom", 0x5800, 0x0400, CRC(e32f54c4) SHA1(c3d9ca2204e7adbc625cf96031acb8c1df0447c7)) + ROM_LOAD( "mo16.rom", 0x5c00, 0x0400, CRC(403be935) SHA1(4e74355a78ab090ce180437156fed8e4a1d1c787)) +ROM_END + + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS +COMP( 198?, mc8020, 0, 0, mc8020, mc8020, mc8020_state, 0, "VEB Elektronik Gera", "MC-80.21/22", MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/mc8030.cpp b/src/mame/drivers/mc8030.cpp new file mode 100644 index 00000000000..cee323f6b30 --- /dev/null +++ b/src/mame/drivers/mc8030.cpp @@ -0,0 +1,288 @@ +// license:BSD-3-Clause +// copyright-holders:Miodrag Milanovic +/*************************************************************************** + +MC-80.3x driver by Miodrag Milanovic + +2009-05-12 Skeleton driver. +2009-05-15 Initial implementation +2011-09-01 Modernised + +mc80.3x: http://www.ycdt.net/mc80.3x/ + +mc8030: very little info available. The area from FFD8-FFFF is meant for +interrupt vectors and so on, but most of it is zeroes. Appears the keyboard +is an ascii keyboard with built-in beeper. It communicates via the SIO. +The asp ctc needs at least 2 triggers. The purpose of the zve pio is unknown. + +****************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "cpu/z80/z80daisy.h" +#include "screen.h" +#include "machine/clock.h" +#include "bus/rs232/rs232.h" +#include "machine/z80ctc.h" +#include "machine/z80pio.h" +#include "machine/z80sio.h" + + +class mc8030_state : public driver_device +{ +public: + mc8030_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_p_videoram(*this, "vram") + , m_maincpu(*this, "maincpu") + { } + + DECLARE_WRITE8_MEMBER(zve_write_protect_w); + DECLARE_WRITE8_MEMBER(vis_w); + DECLARE_WRITE8_MEMBER(eprom_prog_w); + DECLARE_READ8_MEMBER(zve_port_a_r); + DECLARE_READ8_MEMBER(zve_port_b_r); + DECLARE_WRITE8_MEMBER(zve_port_a_w); + DECLARE_WRITE8_MEMBER(zve_port_b_w); + DECLARE_READ8_MEMBER(asp_port_a_r); + DECLARE_READ8_MEMBER(asp_port_b_r); + DECLARE_WRITE8_MEMBER(asp_port_a_w); + DECLARE_WRITE8_MEMBER(asp_port_b_w); + uint32_t screen_update_mc8030(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + +private: + required_region_ptr<u8> m_p_videoram; + required_device<cpu_device> m_maincpu; +}; + + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, mc8030_state ) + ADDRESS_MAP_UNMAP_HIGH + // ZRE 4 * 2KB + AM_RANGE(0x0000, 0x1fff) AM_ROM // ZRE ROM's 4 * 2716 + AM_RANGE(0x2000, 0x27ff) AM_ROM // SPE ROM's 2 * 2708 + AM_RANGE(0x2800, 0x3fff) AM_ROM // For extension + AM_RANGE(0x4000, 0xbfff) AM_RAM // SPE RAM + AM_RANGE(0xc000, 0xffff) AM_RAM // ZRE RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_IO, 8, mc8030_state ) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x30, 0x3f) AM_MIRROR(0xff00) AM_NOP //"mass storage" + AM_RANGE(0x80, 0x83) AM_MIRROR(0xff00) AM_DEVREADWRITE("zve_ctc", z80ctc_device, read, write) // user CTC + AM_RANGE(0x84, 0x87) AM_MIRROR(0xff00) AM_DEVREADWRITE("zve_pio", z80pio_device, read, write) // PIO unknown usage + AM_RANGE(0x88, 0x8f) AM_MIRROR(0xff00) AM_WRITE(zve_write_protect_w) + AM_RANGE(0xc0, 0xcf) AM_SELECT(0xff00) AM_WRITE(vis_w) + AM_RANGE(0xd0, 0xd3) AM_MIRROR(0xff00) AM_DEVREADWRITE("asp_sio", z80sio_device, ba_cd_r, ba_cd_w) // keyboard & IFSS? + AM_RANGE(0xd4, 0xd7) AM_MIRROR(0xff00) AM_DEVREADWRITE("asp_ctc", z80ctc_device, read, write) // sio bauds, KMBG? and kbd + AM_RANGE(0xd8, 0xdb) AM_MIRROR(0xff00) AM_DEVREADWRITE("asp_pio", z80pio_device, read, write) // external bus + AM_RANGE(0xe0, 0xef) AM_MIRROR(0xff00) AM_WRITE(eprom_prog_w) +ADDRESS_MAP_END + +/* Input ports */ +static INPUT_PORTS_START( mc8030 ) +INPUT_PORTS_END + + +WRITE8_MEMBER( mc8030_state::zve_write_protect_w ) +{ +} + +WRITE8_MEMBER( mc8030_state::vis_w ) +{ + // reg C + // 7 6 5 4 -- module + // 3 - 0 left half, 1 right half + // 2 1 0 + // ===== + // 0 0 0 - dark + // 0 0 1 - light + // 0 1 0 - in reg pixel + // 0 1 1 - negate in reg pixel + // 1 0 x - operation code in B reg + // reg B + // + uint16_t addr = ((offset & 0xff00) >> 2) | ((offset & 0x08) << 2) | (data >> 3); + u8 c = 1 << (data & 7); + if (BIT(offset, 0)) + m_p_videoram[addr] |= c; + else + m_p_videoram[addr] &= ~c; +} + +WRITE8_MEMBER( mc8030_state::eprom_prog_w ) +{ +} + +READ8_MEMBER( mc8030_state::zve_port_a_r ) +{ + return 0xff; +} + +READ8_MEMBER( mc8030_state::zve_port_b_r ) +{ + return 0xff; +} + +READ8_MEMBER( mc8030_state::asp_port_a_r ) +{ + return 0xff; +} + +READ8_MEMBER( mc8030_state::asp_port_b_r ) +{ + return 0xff; +} + + +uint32_t mc8030_state::screen_update_mc8030(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + uint8_t gfx; + uint16_t y=0,ma=0,x; + + for(y = 0; y < 256; y++ ) + { + uint16_t *p = &bitmap.pix16(y); + { + for (x = ma; x < ma + 64; x++) + { + gfx = m_p_videoram[x^0x3fff]; + + /* Display a scanline of a character */ + *p++ = BIT(gfx, 7); + *p++ = BIT(gfx, 6); + *p++ = BIT(gfx, 5); + *p++ = BIT(gfx, 4); + *p++ = BIT(gfx, 3); + *p++ = BIT(gfx, 2); + *p++ = BIT(gfx, 1); + *p++ = BIT(gfx, 0); + } + } + ma+=64; + } + return 0; +} + +// this is a guess there is no information available +static const z80_daisy_config daisy_chain[] = +{ + { "asp_ctc" }, /* System ctc */ + { "asp_pio" }, /* System pio */ + { "asp_sio" }, /* sio */ + { "zve_pio" }, /* User pio */ + { "zve_ctc" }, /* User ctc */ + { nullptr } +}; + + +static MACHINE_CONFIG_START( mc8030 ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu",Z80, XTAL_2_4576MHz) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + MCFG_Z80_DAISY_CHAIN(daisy_chain) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ + MCFG_SCREEN_SIZE(512, 256) + MCFG_SCREEN_VISIBLE_AREA(0, 512-1, 0, 256-1) + MCFG_SCREEN_UPDATE_DRIVER(mc8030_state, screen_update_mc8030) + MCFG_SCREEN_PALETTE("palette") + + MCFG_PALETTE_ADD_MONOCHROME("palette") + + /* Devices */ + MCFG_DEVICE_ADD("zve_pio", Z80PIO, XTAL_2_4576MHz) + MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80PIO_IN_PA_CB(READ8(mc8030_state, zve_port_a_r)) + //MCFG_Z80PIO_OUT_PA_CB(WRITE8(mc8030_state, zve_port_a_w)) + MCFG_Z80PIO_IN_PB_CB(READ8(mc8030_state, zve_port_b_r)) + //MCFG_Z80PIO_OUT_PB_CB(WRITE8(mc8030_state, zve_port_b_w)) + + MCFG_DEVICE_ADD("zve_ctc", Z80CTC, XTAL_2_4576MHz) + MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + // ZC0, ZC1, ZC2 for user + + MCFG_DEVICE_ADD("asp_pio", Z80PIO, XTAL_2_4576MHz) + MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80PIO_IN_PA_CB(READ8(mc8030_state, asp_port_a_r)) + //MCFG_Z80PIO_OUT_PA_CB(WRITE8(mc8030_state, asp_port_a_w)) + MCFG_Z80PIO_IN_PB_CB(READ8(mc8030_state, asp_port_b_r)) + //MCFG_Z80PIO_OUT_PB_CB(WRITE8(mc8030_state, asp_port_b_w)) + + MCFG_DEVICE_ADD("asp_ctc", Z80CTC, XTAL_2_4576MHz) + MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + // ZC0: to SIO CLK CH A + // ZC1: to SIO CLK CH B + // ZC2: KMBG (??) + + MCFG_DEVICE_ADD("uart_clock", CLOCK, 153600) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("asp_sio", z80sio_device, txca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("asp_sio", z80sio_device, rxca_w)) + + MCFG_DEVICE_ADD("asp_sio", Z80SIO, 4800) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + // SIO CH A in = keyboard; out = beeper; CH B = IFSS (??) + MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRA_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSA_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "keyboard") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("asp_sio", z80sio_device, rxa_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("asp_sio", z80sio_device, ctsa_w)) +MACHINE_CONFIG_END + +/* ROM definition */ +ROM_START( mc8030 ) + ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + ROM_LOAD( "zve_1.rom", 0x0000, 0x0800, CRC(31ec0159) SHA1(a97ea9eb733c462e77d625a7942134e45d911c0a)) + ROM_LOAD( "zve_2.rom", 0x0800, 0x0800, CRC(5104983d) SHA1(7516274904042f4fc6813aa8b2a75c0a64f9b937)) + ROM_LOAD( "zve_3.rom", 0x1000, 0x0800, CRC(4bcfd727) SHA1(d296e587098e70270ad60db8edaa685af368b849)) + ROM_LOAD( "zve_4.rom", 0x1800, 0x0800, CRC(f949ae43) SHA1(68c324cf5578497db7ae65da5695fcb30493f612)) + ROM_LOAD( "spe_1.rom", 0x2000, 0x0400, CRC(826f609c) SHA1(e77ff6c180f5a6d7756d076173ae264a0e26f066)) + ROM_LOAD( "spe_2.rom", 0x2400, 0x0400, CRC(98320040) SHA1(6baf87e196f1ccdf44912deafa6042becbfb0679)) + + ROM_REGION( 0x4000, "vram", ROMREGION_ERASE00 ) + + ROM_REGION( 0x4000, "user1", 0 ) + // marked as "80.3x" + ROM_LOAD( "mc80.3-x-2c00-c63c.bin", 0x2c00, 0x0400, CRC(469be754) SHA1(a7fea257a1c0970349f75504c0870a2649b50303) ) + ROM_LOAD( "mc80.3-ccd-3000-f10a.bin", 0x3000, 0x0400, CRC(7d220128) SHA1(bb6070c9d460ec7ea1a1b46b19ca9520d55e127c) ) // 80.3x ccd test system + ROM_LOAD( "mc80.3-x-3800-7280.bin", 0x3800, 0x0400, CRC(09976efb) SHA1(1a708adbf1cd68d450a9bfccafe1f82e755e5885) ) + // marked as "80.3x rk" + ROM_LOAD( "mc80.3-rk-3000-5642.bin", 0x3000, 0x0400, CRC(280b2211) SHA1(d2c05ff7f7ea534776bf7e92263f1c10192e5385) ) + ROM_LOAD( "mc80.3-rk-3400-c6a7.bin", 0x3400, 0x0400, CRC(fc5656f3) SHA1(0ad5abb6536665719693063bf8da2993238c84dd) ) + ROM_LOAD( "mc80.3-rk-3800-1678.bin", 0x3800, 0x0400, CRC(34d7e1cf) SHA1(14d3e49f34e0c2a95967613538b33a671998e7a8) ) + // marked as "80.30e v1" + ROM_LOAD( "mc80.30e-0000.bin", 0x0000, 0x0800, CRC(ebdf766f) SHA1(d06f1e4467104f59554168d17cd15b98d107375e) ) + // marked as "80.30e v2" + ROM_LOAD( "mc80.30e-0000v2.bin", 0x0000, 0x0800, CRC(259b55e9) SHA1(6e8fd84f1b225f33bc0fd30ecc6e30b8063eaeed) ) + ROM_LOAD( "mc80.30e-0800v2.bin", 0x0800, 0x0800, CRC(fe7a01a7) SHA1(6531cde5b9dea2a15a813598937aa3d9540a8066) ) + // marked as "80.31e" + ROM_LOAD( "mc80.31e-2400-d0d7.bin", 0x2400, 0x0400, CRC(43c22046) SHA1(a179fe83b5cbbbc5f92a4b2ef1012099ccb333d9) ) + ROM_LOAD( "mc80.31e-3000-0d15.bin", 0x3000, 0x0400, CRC(cf6f090b) SHA1(0bc352ca42f41cfe7e28052c099dcd020b776dd5) ) + ROM_LOAD( "mc80.31e-3400-9993.bin", 0x3400, 0x0400, CRC(918d2b55) SHA1(b6dec17e996c464cf189a699d24d270494540b49) ) + ROM_LOAD( "mc80.31e-3800-7a4c.bin", 0x3800, 0x0400, CRC(62d9f989) SHA1(a20b731daed51270d86f486751302055eb93dd1c) ) + // marked as "80.31e?" + ROM_LOAD( "mc80.3s-2000.bin", 0x2000, 0x0400, CRC(28f1df56) SHA1(9752c9eab3d9f72c23b5f5618a5db1a038953e29) ) + ROM_LOAD( "mc80.3s-2400.bin", 0x2400, 0x0400, CRC(43c22046) SHA1(a179fe83b5cbbbc5f92a4b2ef1012099ccb333d9) ) + ROM_LOAD( "mc80.3s-2800.bin", 0x2800, 0x0400, CRC(4b52deb1) SHA1(f8a9ddb4363f8389990fd263985e882a73265c5d) ) + ROM_LOAD( "mc80.3s-2c00.bin", 0x2c00, 0x0400, CRC(a13d8302) SHA1(1fcdcd6b7af8ef4b18a0658a1a50d0db26b7f214) ) + ROM_LOAD( "mc80.3s-3000.bin", 0x3000, 0x0400, CRC(cf6f090b) SHA1(0bc352ca42f41cfe7e28052c099dcd020b776dd5) ) + ROM_LOAD( "mc80.3s-3400.bin", 0x3400, 0x0400, CRC(918d2b55) SHA1(b6dec17e996c464cf189a699d24d270494540b49) ) + ROM_LOAD( "mc80.3s-3800.bin", 0x3800, 0x0400, CRC(6104646b) SHA1(630f7c57e928db0eb4070139a66f2d313a6314b4) ) + ROM_LOAD( "mc80.3s-3c00.bin", 0x3c00, 0x0400, CRC(2f82d032) SHA1(fe8f642b94a0ba8852ec56d8cbb7a52bb7e5d55a) ) + // marked as "80.33 original" + ROM_LOAD( "mc80.33-1000.bin", 0x1000, 0x0800, CRC(c7e062b1) SHA1(81b999655b32d9b39287a08896a274278a2f739c) ) + // random set, zve_1 - 4 same as main set + ROM_LOAD( "spe_1a.rom", 0x2000, 0x000800, CRC(37c71c68) SHA1(951650698b00f65facf5ccfbd8dd13628a93425d) ) + ROM_LOAD( "spe_2a.rom", 0x2800, 0x000400, CRC(9ec8f287) SHA1(cdf5a9583d898814ba480ffbc8d906a642c6dc81) ) +ROM_END + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS +COMP( 198?, mc8030, 0, 0, mc8030, mc8030, mc8030_state, 0, "VEB Elektronik Gera", "MC-80.30/31", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | ORIENTATION_FLIP_X ) diff --git a/src/mame/drivers/mcb216.cpp b/src/mame/drivers/mcb216.cpp index ded1dc04ba9..b8eac5475fe 100644 --- a/src/mame/drivers/mcb216.cpp +++ b/src/mame/drivers/mcb216.cpp @@ -2,39 +2,39 @@ // copyright-holders:Robbbert /*************************************************************************** - 2013-12-01 Driver for Cromemco MCB-216 SCC (Single Card Computer), - and also the earlier CB-308. +2013-12-01 Driver for Cromemco MCB-216 SCC (Single Card Computer), +and also the earlier CB-308. - The driver is working, just missing some hardware info (see ToDo). +TODO: +- Confirm cpu clock speed - TODO: - - Find out cpu clock speed - - Find out what UART type is used (init byte = 94) +Memory allocation +- 0000 to 0FFF - standard roms +- 1000 to 1FFF - optional roms or ram (expect roms) +- 2000 to 23FF - standard ram +- 2400 to FFFF - optional whatever the user wants (expect ram) - Memory allocation - - 0000 to 0FFF - standard roms - - 1000 to 1FFF - optional roms or ram (expect roms) - - 2000 to 23FF - standard ram - - 2400 to FFFF - optional whatever the user wants (expect ram) +All commands to be in uppercase. - MCB-216: - Press Enter twice. You will see the Basic OK prompt. To get into the - monitor, use the QUIT command, and to return use the B command. +MCB-216: +Press Enter twice. You will see the Basic OK prompt. To get into the +monitor, use the QUIT command, and to return use the B command. - The mcb216 can use an optional floppy-disk-drive unit. The only other - storage is paper-tape, which is expected to be attached to the terminal. +The mcb216 can use an optional floppy-disk-drive unit. The only other +storage is paper-tape, which is expected to be attached to the terminal. - CB-308: - Press Enter twice. You will see the Monitor logo. To get into the BASIC, - enter GE400. To return to the monitor, use the QUIT command followed by - pressing Enter twice. All monitor commands must be in uppercase. The - only storage is paper-tape. +CB-308: +Press Enter twice. You will see the Monitor logo. To get into the BASIC, +enter GE400. To return to the monitor, use the QUIT command followed by +pressing Enter twice. All monitor commands must be in uppercase. The +only storage is paper-tape. ****************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" -#include "machine/terminal.h" +#include "machine/ay31015.h" +#include "bus/rs232/rs232.h" class mcb216_state : public driver_device @@ -43,19 +43,18 @@ public: mcb216_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") - , m_terminal(*this, "terminal") + , m_uart(*this, "uart") { } - void kbd_put(u8 data); - DECLARE_READ8_MEMBER(keyin_r); - DECLARE_READ8_MEMBER(status_r); + DECLARE_READ8_MEMBER(port00_r); + DECLARE_READ8_MEMBER(port01_r); + DECLARE_WRITE8_MEMBER(port01_w); DECLARE_MACHINE_RESET(mcb216); DECLARE_MACHINE_RESET(cb308); private: - uint8_t m_term_data; required_device<cpu_device> m_maincpu; - required_device<generic_terminal_device> m_terminal; + required_device<ay31015_device> m_uart; }; static ADDRESS_MAP_START(mcb216_mem, AS_PROGRAM, 8, mcb216_state) @@ -67,8 +66,8 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(mcb216_io, AS_IO, 8, mcb216_state) ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0x00, 0x00) AM_READ(status_r) - AM_RANGE(0x01, 0x01) AM_READ(keyin_r) AM_DEVWRITE("terminal", generic_terminal_device, write) + AM_RANGE(0x00, 0x00) AM_READ(port00_r) + AM_RANGE(0x01, 0x01) AM_READWRITE(port01_r,port01_w) ADDRESS_MAP_END static ADDRESS_MAP_START(cb308_mem, AS_PROGRAM, 8, mcb216_state) @@ -83,33 +82,52 @@ static INPUT_PORTS_START( mcb216 ) INPUT_PORTS_END -READ8_MEMBER( mcb216_state::keyin_r ) +READ8_MEMBER( mcb216_state::port01_r ) { - uint8_t ret = m_term_data; - m_term_data = 0; - return ret; + m_uart->set_input_pin(AY31015_RDAV, 0); + u8 result = m_uart->get_received_data(); + m_uart->set_input_pin(AY31015_RDAV, 1); + return result; } // 0x40 - a keystroke is available // 0x80 - ok to send to terminal -READ8_MEMBER( mcb216_state::status_r ) +READ8_MEMBER( mcb216_state::port00_r ) { - return (m_term_data) ? 0xc0 : 0x80; + return (m_uart->get_output_pin(AY31015_DAV) << 6) | (m_uart->get_output_pin(AY31015_TBMT) << 7); } -void mcb216_state::kbd_put(u8 data) +WRITE8_MEMBER( mcb216_state::port01_w ) { - m_term_data = data; + m_uart->set_transmit_data(data); } MACHINE_RESET_MEMBER( mcb216_state, mcb216 ) { - m_term_data = 0; + m_uart->set_input_pin(AY31015_XR, 0); + m_uart->set_input_pin(AY31015_XR, 1); + m_uart->set_input_pin(AY31015_SWE, 0); + m_uart->set_input_pin(AY31015_NP, 1); + m_uart->set_input_pin(AY31015_TSB, 0); + m_uart->set_input_pin(AY31015_NB1, 1); + m_uart->set_input_pin(AY31015_NB2, 1); + m_uart->set_input_pin(AY31015_EPS, 1); + m_uart->set_input_pin(AY31015_CS, 1); + m_uart->set_input_pin(AY31015_CS, 0); } MACHINE_RESET_MEMBER( mcb216_state, cb308 ) { - m_term_data = 0; + m_uart->set_input_pin(AY31015_XR, 0); + m_uart->set_input_pin(AY31015_XR, 1); + m_uart->set_input_pin(AY31015_SWE, 0); + m_uart->set_input_pin(AY31015_NP, 1); + m_uart->set_input_pin(AY31015_TSB, 0); + m_uart->set_input_pin(AY31015_NB1, 1); + m_uart->set_input_pin(AY31015_NB2, 1); + m_uart->set_input_pin(AY31015_EPS, 1); + m_uart->set_input_pin(AY31015_CS, 1); + m_uart->set_input_pin(AY31015_CS, 0); m_maincpu->set_state_int(Z80_PC, 0xe000); } @@ -121,8 +139,12 @@ static MACHINE_CONFIG_START( mcb216 ) MCFG_MACHINE_RESET_OVERRIDE(mcb216_state, mcb216) /* video hardware */ - MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) - MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(mcb216_state, kbd_put)) + MCFG_DEVICE_ADD("uart", AY51013, 0) // exact uart type is unknown + MCFG_AY51013_TX_CLOCK(153600) + MCFG_AY51013_RX_CLOCK(153600) + MCFG_AY51013_READ_SI_CB(DEVREADLINE("rs232", rs232_port_device, rxd_r)) + MCFG_AY51013_WRITE_SO_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") MACHINE_CONFIG_END static MACHINE_CONFIG_START( cb308 ) @@ -133,8 +155,12 @@ static MACHINE_CONFIG_START( cb308 ) MCFG_MACHINE_RESET_OVERRIDE(mcb216_state, cb308) /* video hardware */ - MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) - MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(mcb216_state, kbd_put)) + MCFG_DEVICE_ADD("uart", AY51013, 0) // exact uart type is unknown + MCFG_AY51013_TX_CLOCK(153600) + MCFG_AY51013_RX_CLOCK(153600) + MCFG_AY51013_READ_SI_CB(DEVREADLINE("rs232", rs232_port_device, rxd_r)) + MCFG_AY51013_WRITE_SO_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") MACHINE_CONFIG_END /* ROM definition */ @@ -155,5 +181,5 @@ ROM_END /* Driver */ /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -COMP( 1979, mcb216, 0, 0, mcb216, mcb216, mcb216_state, 0, "Cromemco", "MCB-216", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) -COMP( 1977, cb308, mcb216, 0, cb308, mcb216, mcb216_state, 0, "Cromemco", "CB-308", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) +COMP( 1979, mcb216, 0, 0, mcb216, mcb216, mcb216_state, 0, "Cromemco", "MCB-216", MACHINE_NO_SOUND_HW ) +COMP( 1977, cb308, mcb216, 0, cb308, mcb216, mcb216_state, 0, "Cromemco", "CB-308", MACHINE_NO_SOUND_HW ) diff --git a/src/mame/drivers/mcr3.cpp b/src/mame/drivers/mcr3.cpp index 86e679b00a8..f77425c9bf5 100644 --- a/src/mame/drivers/mcr3.cpp +++ b/src/mame/drivers/mcr3.cpp @@ -233,8 +233,8 @@ READ8_MEMBER(mcr3_state::maxrpm_ip2_r) WRITE8_MEMBER(mcr3_state::maxrpm_op5_w) { - /* latch the low 4 bits as input to the ADC0844 */ - m_maxrpm_adc_control = data & 0x0f; + /* latch bits 1-4 as input to the ADC0844 */ + m_maxrpm_adc_control = (data >> 1) & 0x0f; /* remaining bits go to standard connections */ mcrmono_control_port_w(space, offset, data); @@ -243,12 +243,12 @@ WRITE8_MEMBER(mcr3_state::maxrpm_op5_w) WRITE8_MEMBER(mcr3_state::maxrpm_op6_w) { - static const char *const inputs[] = { "MONO.IP1", "MONO.IP1.ALT1", "MONO.IP1.ALT2", "MONO.IP1.ALT3" }; /* Reflective Sensor Control: 4 bits of input from OP5 are routed to a transceiver at U2, and ultimately on to the low 4 I/O pins of the ADC0844. The /EN on - the transceiver is directly connected to J2-2. + the transceiver is directly connected to J2-2. Note that two bits + get swapped in the process: OP53 = MA3 and OP54 = MA2. In order to perform a read or a write to the ADC0844, the /RD and /WR signals are directly controlled via J2-8 and J2-7 respectively. @@ -264,13 +264,11 @@ WRITE8_MEMBER(mcr3_state::maxrpm_op6_w) /* when the read is toggled is when the ADC value is latched */ if (!(data & 0x80)) - m_latched_input = ioport(inputs[m_maxrpm_adc_select])->read(); + m_latched_input = m_maxrpm_adc->read(space, 0); /* when both the write and the enable are low, it's a write to the ADC0844 */ - /* unfortunately the behavior below doesn't match up with the inputs on the */ - /* schematics and wiring diagrams, so they must be wrong */ if (!(data & 0x40) && !(data & 0x20)) - m_maxrpm_adc_select = (m_maxrpm_adc_control >> 1) & 3; + m_maxrpm_adc->write(space, 0, BITSWAP8(m_maxrpm_adc_control, 7, 6, 5, 4, 2, 3, 1, 0)); /* low 5 bits control the turbo CS */ m_turbo_cheap_squeak->write(space, offset, data); @@ -1136,6 +1134,14 @@ static MACHINE_CONFIG_DERIVED( mono_tcs, mcrmono ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( maxrpm, mono_tcs ) + MCFG_ADC0844_ADD("adc") + MCFG_ADC0844_CH1_CB(IOPORT("MONO.IP1")) + MCFG_ADC0844_CH2_CB(IOPORT("MONO.IP1.ALT1")) + MCFG_ADC0844_CH3_CB(IOPORT("MONO.IP1.ALT2")) + MCFG_ADC0844_CH4_CB(IOPORT("MONO.IP1.ALT3")) +MACHINE_CONFIG_END + /* Rampage/Power Drive/Star Guards = MCR monoboard with Sounds Good */ static MACHINE_CONFIG_DERIVED( mono_sg, mcrmono ) @@ -1581,7 +1587,6 @@ DRIVER_INIT_MEMBER(mcr3_state,maxrpm) m_maincpu->space(AS_IO).install_write_handler(0x06, 0x06, write8_delegate(FUNC(mcr3_state::maxrpm_op6_w),this)); save_item(NAME(m_maxrpm_adc_control)); - save_item(NAME(m_maxrpm_adc_select)); save_item(NAME(m_maxrpm_last_shift)); save_item(NAME(m_maxrpm_p1_shift)); save_item(NAME(m_maxrpm_p2_shift)); @@ -1664,7 +1669,7 @@ DRIVER_INIT_MEMBER(mcr3_state,turbotag) /* MCR monoboard games */ GAME( 1984, demoderm, demoderb, mono_tcs, demoderm, mcr3_state, demoderm, ROT0, "Bally Midway", "Demolition Derby (MCR-3 Mono Board Version)", MACHINE_SUPPORTS_SAVE ) GAME( 1985, sarge, 0, mono_tcs, sarge, mcr3_state, sarge, ROT0, "Bally Midway", "Sarge", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, maxrpm, 0, mono_tcs, maxrpm, mcr3_state, maxrpm, ROT0, "Bally Midway", "Max RPM (ver 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, maxrpm, 0, maxrpm, maxrpm, mcr3_state, maxrpm, ROT0, "Bally Midway", "Max RPM (ver 2)", MACHINE_SUPPORTS_SAVE ) GAME( 1986, rampage, 0, mono_sg, rampage, mcr3_state, rampage, ROT0, "Bally Midway", "Rampage (Rev 3, 8/27/86)", MACHINE_SUPPORTS_SAVE ) GAME( 1986, rampage2, rampage, mono_sg, rampage, mcr3_state, rampage, ROT0, "Bally Midway", "Rampage (Rev 2, 8/4/86)", MACHINE_SUPPORTS_SAVE ) GAME( 1986, powerdrv, 0, mono_sg, powerdrv, mcr3_state, powerdrv, ROT0, "Bally Midway", "Power Drive", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/mcr68.cpp b/src/mame/drivers/mcr68.cpp index dc51a33f966..7124aa43509 100644 --- a/src/mame/drivers/mcr68.cpp +++ b/src/mame/drivers/mcr68.cpp @@ -22,6 +22,9 @@ - CPU/Video Board: XTAL 16.000MHz at 1D, XTAL 20.000MHz at 1F - Sound Board: XTAL 16.000MHz + Spy Hunter II reads its extra analog inputs through the "Reflective + Sensor Control" board (A084-91854-B000), which is also used by Max RPM. + **************************************************************************** Memory map @@ -102,10 +105,8 @@ WRITE16_MEMBER(mcr68_state::blasted_control_w) READ16_MEMBER(mcr68_state::spyhunt2_port_0_r) { - static const char *const portnames[] = { "AN1", "AN2", "AN3", "AN4" }; int result = ioport("IN0")->read(); - int which = (m_control_word >> 3) & 3; - int analog = ioport(portnames[which])->read(); + int analog = m_adc->read(space, 0); return result | ((m_sounds_good->read(space, 0) & 1) << 5) | (analog << 8); } @@ -127,6 +128,8 @@ WRITE16_MEMBER(mcr68_state::spyhunt2_control_w) m_sounds_good->reset_write(~m_control_word & 0x2000); m_sounds_good->write(space, offset, (m_control_word >> 8) & 0x001f); + + m_adc->write(space, 0, (m_control_word >> 3) & 0x0f); } @@ -950,6 +953,12 @@ static MACHINE_CONFIG_DERIVED( spyhunt2, mcr68 ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 1.0) MCFG_SOUND_ADD("tcs", MIDWAY_TURBO_CHEAP_SQUEAK, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 1.0) + + MCFG_ADC0844_ADD("adc") + MCFG_ADC0844_CH1_CB(IOPORT("AN1")) + MCFG_ADC0844_CH2_CB(IOPORT("AN2")) + MCFG_ADC0844_CH3_CB(IOPORT("AN3")) + MCFG_ADC0844_CH4_CB(IOPORT("AN4")) MACHINE_CONFIG_END diff --git a/src/mame/drivers/mekd2.cpp b/src/mame/drivers/mekd2.cpp index 0ac11d44017..39400bce047 100644 --- a/src/mame/drivers/mekd2.cpp +++ b/src/mame/drivers/mekd2.cpp @@ -140,8 +140,7 @@ private: static ADDRESS_MAP_START( mekd2_mem , AS_PROGRAM, 8, mekd2_state) AM_RANGE(0x0000, 0x00ff) AM_RAM // user ram AM_RANGE(0x8004, 0x8007) AM_DEVREADWRITE("pia_u", pia6821_device, read, write) - AM_RANGE(0x8008, 0x8008) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0x8009, 0x8009) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0x8008, 0x8009) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0x8020, 0x8023) AM_DEVREADWRITE("pia_s", pia6821_device, read, write) AM_RANGE(0xa000, 0xa07f) AM_RAM // system ram AM_RANGE(0xe000, 0xe3ff) AM_ROM AM_MIRROR(0x1c00) /* JBUG ROM */ diff --git a/src/mame/drivers/meritm.cpp b/src/mame/drivers/meritm.cpp index 83ac0ab720f..c603e03e1a7 100644 --- a/src/mame/drivers/meritm.cpp +++ b/src/mame/drivers/meritm.cpp @@ -258,7 +258,7 @@ public: DECLARE_MACHINE_START(meritm_crt250_crt252_crt258); DECLARE_MACHINE_START(meritm_crt260); DECLARE_MACHINE_START(merit_common); - uint32_t screen_update_meritm(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update_meritm(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); TIMER_DEVICE_CALLBACK_MEMBER(vblank_start_tick); TIMER_DEVICE_CALLBACK_MEMBER(vblank_end_tick); void meritm_crt250_switch_banks( ); @@ -334,7 +334,7 @@ void meritm_state::video_start() save_item(NAME(m_interrupt_vdp1_state)); } -uint32_t meritm_state::screen_update_meritm(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t meritm_state::screen_update_meritm(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { if(machine().input().code_pressed_once(KEYCODE_Q)) { @@ -347,7 +347,7 @@ uint32_t meritm_state::screen_update_meritm(screen_device &screen, bitmap_ind16 popmessage("Layer 1 %sabled",m_layer1_enabled ? "en" : "dis"); } - bitmap.fill(m_v9938_0->black_pen(), cliprect); + bitmap.fill(rgb_t::black(), cliprect); if ( m_layer0_enabled ) { @@ -356,7 +356,7 @@ uint32_t meritm_state::screen_update_meritm(screen_device &screen, bitmap_ind16 if ( m_layer1_enabled ) { - copybitmap_trans(bitmap, m_v9938_1->get_bitmap(), 0, 0, -6, -12, cliprect, m_v9938_1->get_transpen()); + copybitmap_transalpha(bitmap, m_v9938_1->get_bitmap(), 0, 0, -6, -12, cliprect); } return 0; } diff --git a/src/mame/drivers/mes.cpp b/src/mame/drivers/mes.cpp index fcbff5f8f06..c7046f0a6f7 100644 --- a/src/mame/drivers/mes.cpp +++ b/src/mame/drivers/mes.cpp @@ -2,14 +2,18 @@ // copyright-holders:Robbbert /*************************************************************************** - Schleicher MES +Schleicher MES - 30/08/2010 Skeleton driver +2010-08-30 Skeleton driver ****************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" +#include "machine/z80ctc.h" +#include "machine/z80pio.h" +#include "machine/z80sio.h" +#include "machine/keyboard.h" #include "screen.h" @@ -24,8 +28,13 @@ public: { } uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + void kbd_put(u8 data); + DECLARE_READ8_MEMBER(port00_r); + DECLARE_READ8_MEMBER(port08_r); private: + u8 m_term_data; + u8 m_port08; virtual void machine_reset() override; required_device<cpu_device> m_maincpu; required_shared_ptr<uint8_t> m_p_videoram; @@ -33,16 +42,32 @@ private: }; +READ8_MEMBER( mes_state::port00_r ) +{ + u8 ret = m_term_data; + m_term_data = 0; + return ret; +} -static ADDRESS_MAP_START(mes_mem, AS_PROGRAM, 8, mes_state) +READ8_MEMBER( mes_state::port08_r ) +{ + return m_port08 | (m_term_data ? 0x80 : 0); +} + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, mes_state ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x0000, 0x0fff) AM_ROM + AM_RANGE(0x0000, 0x0fff) AM_ROM AM_REGION("roms", 0) AM_RANGE(0x1000, 0xefff) AM_RAM AM_RANGE(0xf000, 0xffff) AM_RAM AM_SHARE("videoram") ADDRESS_MAP_END -static ADDRESS_MAP_START( mes_io, AS_IO, 8, mes_state) +static ADDRESS_MAP_START( io_map, AS_IO, 8, mes_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x00, 0x00) AM_READ(port00_r) + AM_RANGE(0x08, 0x08) AM_READ(port08_r) + AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) + AM_RANGE(0x10, 0x13) AM_DEVREADWRITE("sio", z80sio_device, cd_ba_r, cd_ba_w) + AM_RANGE(0x18, 0x1b) AM_DEVREADWRITE("pio", z80pio_device, read, write) ADDRESS_MAP_END /* Input ports */ @@ -51,17 +76,16 @@ INPUT_PORTS_END void mes_state::machine_reset() { + m_port08 = 0; + m_term_data = 0; } /* This system appears to have 2 screens. Not implemented. Also the screen dimensions are a guess. */ uint32_t mes_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - //static uint8_t framecnt=0; uint8_t y,ra,chr,gfx; - uint16_t sy=0,ma=0,x,xx; - - //framecnt++; + uint16_t sy=0,ma=0,x; for (y = 0; y < 25; y++) { @@ -69,23 +93,15 @@ uint32_t mes_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c { uint16_t *p = &bitmap.pix16(sy++); - xx = ma; for (x = ma; x < ma + 80; x++) { gfx = 0; if (ra < 9) { - chr = m_p_videoram[xx++]; - - // /* Take care of flashing characters */ - // if ((chr < 0x80) && (framecnt & 0x08)) - // chr |= 0x80; - - if (chr & 0x80) // ignore attribute bytes - x--; - else - gfx = m_p_chargen[(chr<<4) | ra ]; + chr = m_p_videoram[x]; + gfx = m_p_chargen[(chr<<4) | ra ]; } + /* Display a scanline of a character */ *p++ = BIT(gfx, 7); *p++ = BIT(gfx, 6); @@ -102,11 +118,16 @@ uint32_t mes_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c return 0; } +void mes_state::kbd_put(u8 data) +{ + m_term_data = data; +} + static MACHINE_CONFIG_START( mes ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, XTAL_16MHz / 4) - MCFG_CPU_PROGRAM_MAP(mes_mem) - MCFG_CPU_IO_MAP(mes_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -118,15 +139,22 @@ static MACHINE_CONFIG_START( mes ) MCFG_SCREEN_PALETTE("palette") MCFG_PALETTE_ADD_MONOCHROME("palette") + + MCFG_DEVICE_ADD("ctc", Z80CTC, 0) + MCFG_DEVICE_ADD("pio", Z80PIO, 0) + MCFG_DEVICE_ADD("sio", Z80SIO, 0) + + MCFG_DEVICE_ADD("keybd", GENERIC_KEYBOARD, 0) + MCFG_GENERIC_KEYBOARD_CB(PUT(mes_state, kbd_put)) MACHINE_CONFIG_END /* ROM definition */ ROM_START( mes ) - ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) + ROM_REGION( 0x1000, "roms", ROMREGION_ERASEFF ) ROM_LOAD( "mescpu.bin", 0x0000, 0x1000, CRC(b6d90cf4) SHA1(19e608af5bdaabb00a134e1106b151b00e2a0b04)) - ROM_REGION( 0x10000, "xebec", ROMREGION_ERASEFF ) + ROM_REGION( 0x2000, "xebec", ROMREGION_ERASEFF ) ROM_LOAD( "mesxebec.bin", 0x0000, 0x2000, CRC(061b7212) SHA1(c5d600116fb7563c69ebd909eb9613269b2ada0f)) /* character generator not dumped, using the one from 'c10' for now */ diff --git a/src/mame/drivers/metro.cpp b/src/mame/drivers/metro.cpp index f7009880e05..87a6edb0c77 100644 --- a/src/mame/drivers/metro.cpp +++ b/src/mame/drivers/metro.cpp @@ -67,23 +67,14 @@ no PCB number but all look identical to each other. To Do: -- Tilemaps/sprites offsets may be emulated understanding what appear to be CRT registers - at c78880 (sequence of 4 values), c78890 (sequence of 5 values) and c788a0 (start sequence). -- Wrong color bars in service mode (e.g. balcube, toride2g). - They use solid color tiles (80xx), but the right palette is not at 00-ff. - Related to the unknown table in the RAM mapped just before the palette? +- For video related issues @see devices/video/imagetek_i4100.cpp - Most games, in service mode, seem to require that you press start1&2 *exactly at once* in order to advance to the next screen (e.g. holding 1 then pressing 2 doesn't work). - Coin lockout -- Some gfx problems in ladykill, 3kokushi, puzzli, gakusai, - seem related to how we handle windows and wrapping - Interrupt timing needs figuring out properly, having it incorrect causes scrolling glitches in some games. Test cases Mouse Go Go title screen, GunMaster title screen. Changing it can cause excessive slowdown in said games however. -- Bang Bang Ball / Bubble Buster slow to a crawl when you press a - button between levels, on a real PCB it speeds up instead (related - to above?) - vmetal: ES8712 actually controls a M6585 and an unknown logic selector chip. Notes: @@ -108,7 +99,6 @@ driver modified by Hau #include "sound/ym2413.h" #include "sound/2610intf.h" #include "sound/ymf278b.h" - #include "speaker.h" @@ -125,7 +115,11 @@ READ16_MEMBER(metro_state::metro_irq_cause_r) /* interrupt cause, used by int[0] vblank - int[1] ? DAITORIDE, BALCUBE, KARATOUR, MOUJA + int[1] hblank (bangball for faster intermission skip, + puzzli for gameplay water effect, + blzntrnd title screen scroll (enabled all the time then?), + unused/empty in balcube, daitoride, karatour, + unchecked mouja & other i4300 games ) int[2] blitter int[3] ? KARATOUR int[4] ? @@ -209,9 +203,6 @@ void metro_state::device_timer(emu_timer &timer, device_timer_id id, int param, m_requested_int[0] = 1; update_irq_state(); break; - case TIMER_METRO_BLIT_DONE: - metro_blit_done(ptr, param); - break; default: assert_always(false, "Unknown id in metro_state::device_timer"); } @@ -229,6 +220,25 @@ INTERRUPT_GEN_MEMBER(metro_state::metro_periodic_interrupt) update_irq_state(); } +TIMER_DEVICE_CALLBACK_MEMBER(metro_state::bangball_scanline) +{ + int scanline = param; + + // vblank irq + if(scanline == 224) + { + m_requested_int[m_vblank_bit] = 1; + m_requested_int[4] = 1; // ??? + update_irq_state(); + } + else if(scanline < 224 && (*m_irq_enable & 2) == 0) + { + // pretty likely hblank irq (pressing a button when clearing a stage) + m_requested_int[1] = 1; + update_irq_state(); + } +} + /* lev 2-7 (lev 1 seems sound related) */ INTERRUPT_GEN_MEMBER(metro_state::karatour_interrupt) { @@ -443,250 +453,32 @@ WRITE8_MEMBER(metro_state::daitorid_portb_w) ***************************************************************************/ -/* IT DOESN'T WORK PROPERLY */ - WRITE16_MEMBER(metro_state::metro_coin_lockout_1word_w) { if (ACCESSING_BITS_0_7) { -// machine().bookkeeping().coin_lockout_w(0, data & 1); -// machine().bookkeeping().coin_lockout_w(1, data & 2); + machine().bookkeeping().coin_counter_w(0, data & 1); + machine().bookkeeping().coin_counter_w(1, data & 2); } if (data & ~3) logerror("CPU #0 PC %06X : unknown bits of coin lockout written: %04X\n", space.device().safe_pc(), data); } - +// value written doesn't matter, also each counted coin gets reported after one full second. +// TODO: maybe the counter also controls lockout? WRITE16_MEMBER(metro_state::metro_coin_lockout_4words_w) { + machine().bookkeeping().coin_counter_w((offset >> 1) & 1, offset & 1); // machine().bookkeeping().coin_lockout_w((offset >> 1) & 1, offset & 1); - if (data & ~1) logerror("CPU #0 PC %06X : unknown bits of coin lockout written: %04X\n", space.device().safe_pc(), data); -} - - - -/*************************************************************************** - - - Banked ROM access - - -***************************************************************************/ - -/* - The main CPU has access to the ROMs that hold the graphics through - a banked window of 64k. Those ROMs also usually store the tables for - the virtual tiles set. The tile codes to be written to the tilemap - memory to render the backgrounds are also stored here, in a format - that the blitter can readily use (which is a form of compression) -*/ - -READ16_MEMBER(metro_state::metro_bankedrom_r) -{ - uint8_t *ROM = memregion("gfx1")->base(); - size_t len = memregion("gfx1")->bytes(); - - offset = offset * 2 + 0x10000 * (*m_rombank); - - if (offset < len) - return ((ROM[offset + 0] << 8) + ROM[offset + 1]); - else - return 0xffff; + if (data & ~1) logerror("CPU #0 PC %06X : unknown bits of coin lockout written: %04X\n", space.device().safe_pc(), data); } - - - -/*************************************************************************** - - - Blitter - - [ Registers ] - - Offset: Value: - - 0.l Destination Tilemap (1,2,3) - 4.l Blitter Data Address (byte offset into the gfx ROMs) - 8.l Destination Address << 7 (byte offset into the tilemap) - - The Blitter reads a byte and looks at the most significative - bits for the opcode, while the remaining bits define a value - (usually how many bytes to write). The opcode byte may be - followed by a number of other bytes: - - 76------ Opcode - --543210 N - (at most N+1 bytes follow) - - - The blitter is designed to write every other byte (e.g. it - writes a byte and skips the next). Hence 2 blits are needed - to fill a tilemap (first even, then odd addresses) - - [ Opcodes ] - - 0 Copy the following N+1 bytes. If the whole byte - is $00: stop and generate an IRQ - - 1 Fill N+1 bytes with a sequence, starting with - the value in the following byte - - 2 Fill N+1 bytes with the value in the following - byte - - 3 Skip N+1 bytes. If the whole byte is $C0: - skip to the next row of the tilemap (+0x200 bytes) - but preserve the column passed at the start of the - blit (destination address % 0x200) - - -***************************************************************************/ - -TIMER_CALLBACK_MEMBER(metro_state::metro_blit_done) +WRITE_LINE_MEMBER(metro_state::vdp_blit_end_w) { m_requested_int[m_blitter_bit] = 1; update_irq_state(); } -inline int metro_state::blt_read( const uint8_t *ROM, const int offs ) -{ - return ROM[offs]; -} - -void metro_state::blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask ) -{ - switch(tmap) - { - case 1: metro_vram_0_w(space, offs, data, mask); break; - case 2: metro_vram_1_w(space, offs, data, mask); break; - case 3: metro_vram_2_w(space, offs, data, mask); break; - } -// logerror("%s : Blitter %X] %04X <- %04X & %04X\n", space.machine().describe_context(), tmap, offs, data, mask); -} - - -WRITE16_MEMBER(metro_state::metro_blitter_w) -{ - COMBINE_DATA(&m_blitter_regs[offset]); - - if (offset == 0x0c / 2) - { - uint8_t *src = memregion("gfx1")->base(); - size_t src_len = memregion("gfx1")->bytes(); - - uint32_t tmap = (m_blitter_regs[0x00 / 2] << 16) + m_blitter_regs[0x02 / 2]; - uint32_t src_offs = (m_blitter_regs[0x04 / 2] << 16) + m_blitter_regs[0x06 / 2]; - uint32_t dst_offs = (m_blitter_regs[0x08 / 2] << 16) + m_blitter_regs[0x0a / 2]; - - int shift = (dst_offs & 0x80) ? 0 : 8; - uint16_t mask = (dst_offs & 0x80) ? 0x00ff : 0xff00; - -// logerror("CPU #0 PC %06X : Blitter regs %08X, %08X, %08X\n", space.device().safe_pc(), tmap, src_offs, dst_offs); - - dst_offs >>= 7 + 1; - switch (tmap) - { - case 1: - case 2: - case 3: - break; - default: - logerror("CPU #0 PC %06X : Blitter unknown destination: %08X\n", space.device().safe_pc(), tmap); - return; - } - - while (1) - { - uint16_t b1, b2, count; - - src_offs %= src_len; - b1 = blt_read(src, src_offs); -// logerror("CPU #0 PC %06X : Blitter opcode %02X at %06X\n", space.device().safe_pc(), b1, src_offs); - src_offs++; - - count = ((~b1) & 0x3f) + 1; - - switch ((b1 & 0xc0) >> 6) - { - case 0: - /* Stop and Generate an IRQ. We can't generate it now - both because it's unlikely that the blitter is so - fast and because some games (e.g. lastfort) need to - complete the blitter irq service routine before doing - another blit. */ - if (b1 == 0) - { - m_blit_done_timer->adjust(attotime::from_usec(500)); - return; - } - - /* Copy */ - while (count--) - { - src_offs %= src_len; - b2 = blt_read(src, src_offs) << shift; - src_offs++; - - dst_offs &= 0xffff; - blt_write(space, tmap, dst_offs, b2, mask); - dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1))); - } - break; - - case 1: - /* Fill with an increasing value */ - src_offs %= src_len; - b2 = blt_read(src, src_offs); - src_offs++; - - while (count--) - { - dst_offs &= 0xffff; - blt_write(space, tmap, dst_offs, b2 << shift, mask); - dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1))); - b2++; - } - break; - - case 2: - /* Fill with a fixed value */ - src_offs %= src_len; - b2 = blt_read(src, src_offs) << shift; - src_offs++; - - while (count--) - { - dst_offs &= 0xffff; - blt_write(space, tmap, dst_offs, b2, mask); - dst_offs = ((dst_offs + 1) & (0x100 - 1)) | (dst_offs & (~(0x100 - 1))); - } - break; - - case 3: - /* Skip to the next line ?? */ - if (b1 == 0xc0) - { - dst_offs += 0x100; - dst_offs &= ~(0x100 - 1); - dst_offs |= (0x100 - 1) & (m_blitter_regs[0x0a / 2] >> (7 + 1)); - } - else - { - dst_offs += count; - } - break; - - default: - logerror("CPU #0 PC %06X : Blitter unknown opcode %02X at %06X\n",space.device().safe_pc(),b1,src_offs-1); - return; - } - - } - } -} - - /*************************************************************************** @@ -761,24 +553,9 @@ static ADDRESS_MAP_START( balcube_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x500002, 0x500003) AM_READ_PORT("IN1") // AM_RANGE(0x500006, 0x500007) AM_READNOP // AM_RANGE(0x500002, 0x500009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout - AM_RANGE(0x600000, 0x61ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x620000, 0x63ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x640000, 0x65ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x660000, 0x66ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x670000, 0x671fff) AM_RAM // ??? - AM_RANGE(0x672000, 0x673fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x674000, 0x674fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x678000, 0x6787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x678840, 0x67884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x678860, 0x67886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x678870, 0x67887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x678880, 0x678881) AM_WRITENOP // ? CRT - AM_RANGE(0x678890, 0x678891) AM_WRITENOP // ? CRT + AM_RANGE(0x600000, 0x67ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0x6788a2, 0x6788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x6788a4, 0x6788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable - AM_RANGE(0x6788aa, 0x6788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x6788ac, 0x6788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0x679700, 0x679713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) ADDRESS_MAP_END @@ -790,24 +567,9 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( daitoa_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM - AM_RANGE(0x100000, 0x11ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x120000, 0x13ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x140000, 0x15ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x160000, 0x16ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x170000, 0x171fff) AM_RAM // ??? - AM_RANGE(0x172000, 0x173fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x174000, 0x174fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x178000, 0x1787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x178840, 0x17884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x178860, 0x17886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x178870, 0x17887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x178880, 0x178881) AM_WRITENOP // ? CRT - AM_RANGE(0x178890, 0x178891) AM_WRITENOP // ? CRT + AM_RANGE(0x100000, 0x17ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map ) AM_RANGE(0x1788a2, 0x1788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x1788a4, 0x1788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable - AM_RANGE(0x1788aa, 0x1788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x1788ac, 0x1788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0x179700, 0x179713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0x200000, 0x200001) AM_READ_PORT("IN0") // Inputs AM_RANGE(0x200002, 0x200003) AM_READ_PORT("IN1") // AM_RANGE(0x200006, 0x200007) AM_READNOP // @@ -832,24 +594,9 @@ static ADDRESS_MAP_START( bangball_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0xd00002, 0xd00003) AM_READ_PORT("IN1") // AM_RANGE(0xd00006, 0xd00007) AM_READNOP // AM_RANGE(0xd00002, 0xd00009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout - AM_RANGE(0xe00000, 0xe1ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0xe20000, 0xe3ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0xe40000, 0xe5ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0xe60000, 0xe6ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0xe70000, 0xe71fff) AM_RAM // ??? - AM_RANGE(0xe72000, 0xe73fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0xe74000, 0xe74fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0xe78000, 0xe787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0xe78840, 0xe7884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0xe78860, 0xe7886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0xe78870, 0xe7887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0xe78880, 0xe78881) AM_WRITENOP // ? CRT - AM_RANGE(0xe78890, 0xe78891) AM_WRITENOP // ? CRT + AM_RANGE(0xe00000, 0xe7ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0xe788a2, 0xe788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0xe788a4, 0xe788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable - AM_RANGE(0xe788aa, 0xe788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0xe788ac, 0xe788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0xe79700, 0xe79713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) ADDRESS_MAP_END @@ -860,24 +607,9 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( batlbubl_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x0fffff) AM_ROM // ROM - AM_RANGE(0x100000, 0x11ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x120000, 0x13ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x140000, 0x15ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x160000, 0x16ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x170000, 0x171fff) AM_RAM // ??? - AM_RANGE(0x172000, 0x173fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x174000, 0x174fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x178000, 0x1787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x178840, 0x17884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x178860, 0x17886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x178870, 0x17887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x178880, 0x178881) AM_WRITENOP // ? CRT - AM_RANGE(0x178890, 0x178891) AM_WRITENOP // ? CRT + AM_RANGE(0x100000, 0x17ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0x1788a2, 0x1788a3) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x1788a4, 0x1788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable - AM_RANGE(0x1788aa, 0x1788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x1788ac, 0x1788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0x179700, 0x179713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0x200000, 0x200001) AM_READ_PORT("IN1") // Inputs AM_RANGE(0x200002, 0x200003) AM_READ_PORT("DSW0") // AM_RANGE(0x200004, 0x200005) AM_READ_PORT("IN0") // @@ -896,24 +628,9 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( msgogo_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM - AM_RANGE(0x100000, 0x11ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x120000, 0x13ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x140000, 0x15ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x160000, 0x16ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x170000, 0x171fff) AM_RAM // ??? - AM_RANGE(0x172000, 0x173fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x174000, 0x174fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x178000, 0x1787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x178840, 0x17884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x178860, 0x17886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x178870, 0x17887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x178880, 0x178881) AM_WRITENOP // ? CRT - AM_RANGE(0x178890, 0x178891) AM_WRITENOP // ? CRT - AM_RANGE(0x1788a2, 0x1788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge + AM_RANGE(0x100000, 0x17ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) + AM_RANGE(0x1788a2, 0x1788a3) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x1788a4, 0x1788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable - AM_RANGE(0x1788aa, 0x1788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x1788ac, 0x1788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0x179700, 0x179713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0x200000, 0x200001) AM_READ_PORT("COINS") // Inputs AM_RANGE(0x200002, 0x200003) AM_READ_PORT("JOYS") // AM_RANGE(0x200006, 0x200007) AM_READNOP // @@ -930,25 +647,10 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( daitorid_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x03ffff) AM_ROM // ROM - AM_RANGE(0x400000, 0x41ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x420000, 0x43ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x440000, 0x45ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x460000, 0x46ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x470000, 0x471fff) AM_RAM // ??? - AM_RANGE(0x472000, 0x473fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x474000, 0x474fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x478000, 0x4787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x478840, 0x47884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x478860, 0x47886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x478870, 0x47887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x478880, 0x478881) AM_WRITENOP // ? CRT - AM_RANGE(0x478890, 0x478891) AM_WRITENOP // ? CRT + AM_RANGE(0x400000, 0x47ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0x4788a2, 0x4788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x4788a4, 0x4788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x4788a8, 0x4788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0x4788aa, 0x4788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x4788ac, 0x4788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0x479700, 0x479713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0x800000, 0x80ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) AM_RANGE(0xc00000, 0xc00001) AM_READ_PORT("IN0") AM_WRITE(metro_soundstatus_w) // To Sound CPU AM_RANGE(0xc00002, 0xc00003) AM_READ_PORT("IN1") // @@ -965,25 +667,10 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( dharma_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x03ffff) AM_ROM // ROM AM_RANGE(0x400000, 0x40ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) - AM_RANGE(0x800000, 0x81ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x820000, 0x83ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x840000, 0x85ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x870000, 0x871fff) AM_RAM // ??? - AM_RANGE(0x872000, 0x873fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x874000, 0x874fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x878000, 0x8787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x878870, 0x87887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0x878880, 0x878881) AM_WRITENOP // ? CRT - AM_RANGE(0x878890, 0x878891) AM_WRITENOP // ? CRT + AM_RANGE(0x800000, 0x87ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0x8788a2, 0x8788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x8788a4, 0x8788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0x8788aa, 0x8788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x8788ac, 0x8788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0x879700, 0x879713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0xc00000, 0xc00001) AM_READ_PORT("IN0") AM_WRITE(metro_soundstatus_w) // To Sound CPU AM_RANGE(0xc00002, 0xc00003) AM_READ_PORT("IN1") // AM_RANGE(0xc00004, 0xc00005) AM_READ_PORT("DSW0") // @@ -996,20 +683,6 @@ ADDRESS_MAP_END Karate Tournament ***************************************************************************/ -/* This game uses almost only the blitter to write to the tilemaps. - The CPU can only access a "window" of 512x256 pixels in the upper - left corner of the big tilemap */ - -#define KARATOUR_OFFS( _x_ ) ((_x_) & (0x3f)) + (((_x_) & ~(0x3f)) * (0x100 / 0x40)) - -READ16_MEMBER(metro_state::karatour_vram_0_r){ return m_vram_0[KARATOUR_OFFS(offset)]; } -READ16_MEMBER(metro_state::karatour_vram_1_r){ return m_vram_1[KARATOUR_OFFS(offset)]; } -READ16_MEMBER(metro_state::karatour_vram_2_r){ return m_vram_2[KARATOUR_OFFS(offset)]; } - -WRITE16_MEMBER(metro_state::karatour_vram_0_w){ metro_vram_0_w(space, KARATOUR_OFFS(offset), data, mem_mask); } -WRITE16_MEMBER(metro_state::karatour_vram_1_w){ metro_vram_1_w(space, KARATOUR_OFFS(offset), data, mem_mask); } -WRITE16_MEMBER(metro_state::karatour_vram_2_w){ metro_vram_2_w(space, KARATOUR_OFFS(offset), data, mem_mask); } - static ADDRESS_MAP_START( karatour_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM AM_RANGE(0x400000, 0x400001) AM_READWRITE(metro_soundstatus_r, metro_soundstatus_w) // From Sound CPU @@ -1019,25 +692,10 @@ static ADDRESS_MAP_START( karatour_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x400006, 0x400007) AM_READ_PORT("DSW0") // AM_RANGE(0x40000a, 0x40000b) AM_READ_PORT("DSW1") // AM_RANGE(0x40000c, 0x40000d) AM_READ_PORT("IN2") // - AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x870000, 0x871fff) AM_RAM // ??? - AM_RANGE(0x872000, 0x873fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x874000, 0x874fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x875000, 0x875fff) AM_READWRITE(karatour_vram_0_r, karatour_vram_0_w) // Layer 0 (Part of) - AM_RANGE(0x876000, 0x876fff) AM_READWRITE(karatour_vram_1_r, karatour_vram_1_w) // Layer 1 (Part of) - AM_RANGE(0x877000, 0x877fff) AM_READWRITE(karatour_vram_2_r, karatour_vram_2_w) // Layer 2 (Part of) - AM_RANGE(0x878000, 0x8787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x878800, 0x878813) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers - AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x878870, 0x87887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x878880, 0x878881) AM_WRITENOP // ? CRT - AM_RANGE(0x878890, 0x878891) AM_WRITENOP // ? CRT + AM_RANGE(0x800000, 0x87ffff) AM_DEVICE("vdp", imagetek_i4100_device, map) AM_RANGE(0x8788a2, 0x8788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x8788a4, 0x8788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0x8788aa, 0x8788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x8788ac, 0x8788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) ADDRESS_MAP_END @@ -1051,29 +709,14 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( kokushi_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM AM_RANGE(0x700000, 0x70ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) - AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x870000, 0x871fff) AM_RAM // ??? - AM_RANGE(0x872000, 0x873fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x874000, 0x874fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x875000, 0x875fff) AM_READWRITE(karatour_vram_0_r, karatour_vram_0_w) // Layer 0 (Part of) - AM_RANGE(0x876000, 0x876fff) AM_READWRITE(karatour_vram_1_r, karatour_vram_1_w) // Layer 1 (Part of) - AM_RANGE(0x877000, 0x877fff) AM_READWRITE(karatour_vram_2_r, karatour_vram_2_w) // Layer 2 (Part of) - AM_RANGE(0x878000, 0x8787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x878870, 0x87887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - WRONG -// AM_RANGE(0x878880, 0x878881) AM_WRITENOP // ? CRT - AM_RANGE(0x878890, 0x878891) AM_WRITENOP // ? CRT + AM_RANGE(0x800000, 0x87ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0x8788a2, 0x8788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x8788a4, 0x8788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0x8788aa, 0x8788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x8788ac, 0x8788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0x879700, 0x879713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0xc00000, 0xc00001) AM_READ_PORT("IN0") AM_WRITE(metro_soundstatus_w) // To Sound CPU AM_RANGE(0xc00002, 0xc00003) AM_READ_PORT("IN1") // Inputs AM_RANGE(0xc00004, 0xc00005) AM_READ_PORT("DSW0") // - AM_RANGE(0xc00002, 0xc00009) AM_WRITE(metro_coin_lockout_4words_w ) // Coin Lockout + AM_RANGE(0xc00002, 0xc00009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout ADDRESS_MAP_END @@ -1084,25 +727,10 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( lastfort_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x03ffff) AM_ROM // ROM AM_RANGE(0x400000, 0x40ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) - AM_RANGE(0x800000, 0x81ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x820000, 0x83ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x840000, 0x85ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x870000, 0x871fff) AM_RAM // ??? - AM_RANGE(0x872000, 0x873fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x874000, 0x874fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x878000, 0x8787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x878800, 0x878813) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers - AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x878870, 0x87887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x878880, 0x878881) AM_WRITENOP // ? CRT - AM_RANGE(0x878890, 0x878891) AM_WRITENOP // ? CRT + AM_RANGE(0x800000, 0x87ffff) AM_DEVICE("vdp", imagetek_i4100_device, map) AM_RANGE(0x8788a2, 0x8788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x8788a4, 0x8788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0x8788aa, 0x8788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x8788ac, 0x8788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control AM_RANGE(0xc00000, 0xc00001) AM_READWRITE(metro_soundstatus_r, metro_soundstatus_w) // From / To Sound CPU AM_RANGE(0xc00002, 0xc00003) AM_WRITE(metro_coin_lockout_1word_w) // Coin Lockout AM_RANGE(0xc00004, 0xc00005) AM_READ_PORT("IN0") // Inputs @@ -1125,25 +753,10 @@ static ADDRESS_MAP_START( lastforg_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x400006, 0x400007) AM_READ_PORT("DSW0") // AM_RANGE(0x40000a, 0x40000b) AM_READ_PORT("DSW1") // AM_RANGE(0x40000c, 0x40000d) AM_READ_PORT("IN2") // - AM_RANGE(0x880000, 0x89ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x8a0000, 0x8bffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x8c0000, 0x8dffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x8e0000, 0x8effff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x8f0000, 0x8f1fff) AM_RAM // ??? - AM_RANGE(0x8f2000, 0x8f3fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x8f4000, 0x8f4fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x8f8000, 0x8f87ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x8f8800, 0x8f8813) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers - AM_RANGE(0x8f8840, 0x8f884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x8f8860, 0x8f886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x8f8870, 0x8f887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x8f8880, 0x8f8881) AM_WRITENOP // ? CRT - AM_RANGE(0x8f8890, 0x8f8891) AM_WRITENOP // ? CRT + AM_RANGE(0x880000, 0x8fffff) AM_DEVICE("vdp", imagetek_i4100_device, map) AM_RANGE(0x8f88a2, 0x8f88a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x8f88a4, 0x8f88a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x8f88a8, 0x8f88a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0x8f88aa, 0x8f88ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x8f88ac, 0x8f88ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control AM_RANGE(0xc00000, 0xc0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) ADDRESS_MAP_END @@ -1158,22 +771,16 @@ void metro_state::gakusai_oki_bank_set() m_oki->set_rom_bank(bank); } -WRITE16_MEMBER(metro_state::gakusai_oki_bank_hi_w) +WRITE8_MEMBER(metro_state::gakusai_oki_bank_hi_w) { - if (ACCESSING_BITS_0_7) - { - m_gakusai_oki_bank_hi = data & 0xff; - gakusai_oki_bank_set(); - } + m_gakusai_oki_bank_hi = data; + gakusai_oki_bank_set(); } -WRITE16_MEMBER(metro_state::gakusai_oki_bank_lo_w) +WRITE8_MEMBER(metro_state::gakusai_oki_bank_lo_w) { - if (ACCESSING_BITS_0_7) - { - m_gakusai_oki_bank_lo = data & 0xff; - gakusai_oki_bank_set(); - } + m_gakusai_oki_bank_lo = data; + gakusai_oki_bank_set(); } @@ -1189,56 +796,40 @@ READ16_MEMBER(metro_state::gakusai_input_r) return 0xffff; } -READ16_MEMBER(metro_state::gakusai_eeprom_r) +READ8_MEMBER(metro_state::gakusai_eeprom_r) { return m_eeprom->do_read() & 1; } -WRITE16_MEMBER(metro_state::gakusai_eeprom_w) +WRITE8_MEMBER(metro_state::gakusai_eeprom_w) { - if (ACCESSING_BITS_0_7) - { - // latch the bit - m_eeprom->di_write(BIT(data, 0)); + // latch the bit + m_eeprom->di_write(BIT(data, 0)); - // reset line asserted: reset. - m_eeprom->cs_write(BIT(data, 2) ? ASSERT_LINE : CLEAR_LINE ); + // reset line asserted: reset. + m_eeprom->cs_write(BIT(data, 2) ? ASSERT_LINE : CLEAR_LINE ); - // clock line asserted: write latch or select next bit to read - m_eeprom->clk_write(BIT(data, 1) ? ASSERT_LINE : CLEAR_LINE ); - } + // clock line asserted: write latch or select next bit to read + m_eeprom->clk_write(BIT(data, 1) ? ASSERT_LINE : CLEAR_LINE ); } static ADDRESS_MAP_START( gakusai_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM - AM_RANGE(0x200000, 0x21ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x220000, 0x23ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x240000, 0x25ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x260000, 0x26ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x270000, 0x271fff) AM_RAM // ??? - AM_RANGE(0x272000, 0x273fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x274000, 0x274fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x278000, 0x2787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x27880e, 0x27880f) AM_RAM AM_SHARE("screenctrl") // Screen Control + AM_RANGE(0x200000, 0x27ffff) AM_DEVICE("vdp3", imagetek_i4300_device, v3_map ) AM_RANGE(0x278810, 0x27881f) AM_WRITEONLY AM_SHARE("irq_levels") // IRQ Levels AM_RANGE(0x278820, 0x27882f) AM_WRITEONLY AM_SHARE("irq_vectors") // IRQ Vectors AM_RANGE(0x278830, 0x278831) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x278832, 0x278833) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge - AM_RANGE(0x278836, 0x278837) AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w) - AM_RANGE(0x278840, 0x27884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x278850, 0x27885b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0x278860, 0x27886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x278870, 0x278871) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank + AM_RANGE(0x278836, 0x278837) AM_READNOP AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w) AM_RANGE(0x278880, 0x278881) AM_READ(gakusai_input_r) // Inputs AM_RANGE(0x278882, 0x278883) AM_READ_PORT("IN0") // AM_RANGE(0x278888, 0x278889) AM_WRITEONLY AM_SHARE("input_sel") // Inputs - AM_RANGE(0x279700, 0x279713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0x400000, 0x400001) AM_WRITENOP // ? 5 - AM_RANGE(0x500000, 0x500001) AM_WRITE(gakusai_oki_bank_lo_w) // Sound + AM_RANGE(0x500000, 0x500001) AM_WRITE8(gakusai_oki_bank_lo_w, 0x00ff) // Sound AM_RANGE(0x600000, 0x600003) AM_DEVWRITE8("ymsnd", ym2413_device, write, 0x00ff) AM_RANGE(0x700000, 0x700001) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) // Sound - AM_RANGE(0xc00000, 0xc00001) AM_READWRITE(gakusai_eeprom_r, gakusai_eeprom_w) // EEPROM - AM_RANGE(0xd00000, 0xd00001) AM_WRITE(gakusai_oki_bank_hi_w) + AM_RANGE(0xc00000, 0xc00001) AM_READWRITE8(gakusai_eeprom_r, gakusai_eeprom_w, 0x00ff) // EEPROM + AM_RANGE(0xd00000, 0xd00001) AM_WRITE8(gakusai_oki_bank_hi_w, 0x00ff) AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) ADDRESS_MAP_END @@ -1249,35 +840,21 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( gakusai2_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM - AM_RANGE(0x600000, 0x61ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x620000, 0x63ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x640000, 0x65ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x660000, 0x66ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x670000, 0x671fff) AM_RAM // ??? - AM_RANGE(0x672000, 0x673fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x674000, 0x674fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x675000, 0x675fff) AM_RAM // Sprites? - AM_RANGE(0x678000, 0x6787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x67880e, 0x67880f) AM_RAM AM_SHARE("screenctrl") // Screen Control + AM_RANGE(0x600000, 0x67ffff) AM_DEVICE("vdp3", imagetek_i4300_device, v3_map) AM_RANGE(0x678810, 0x67881f) AM_WRITEONLY AM_SHARE("irq_levels") // IRQ Levels AM_RANGE(0x678820, 0x67882f) AM_WRITEONLY AM_SHARE("irq_vectors") // IRQ Vectors AM_RANGE(0x678830, 0x678831) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x678832, 0x678833) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge - AM_RANGE(0x678836, 0x678837) AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w) - AM_RANGE(0x678840, 0x67884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x678850, 0x67885b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0x678860, 0x67886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x678870, 0x678871) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank + AM_RANGE(0x678836, 0x678837) AM_READNOP AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w) AM_RANGE(0x678880, 0x678881) AM_READ(gakusai_input_r) // Inputs AM_RANGE(0x678882, 0x678883) AM_READ_PORT("IN0") // AM_RANGE(0x678888, 0x678889) AM_WRITEONLY AM_SHARE("input_sel") // Inputs - AM_RANGE(0x679700, 0x679713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0x800000, 0x800001) AM_WRITENOP // ? 5 - AM_RANGE(0x900000, 0x900001) AM_WRITE(gakusai_oki_bank_lo_w) // Sound bank - AM_RANGE(0xa00000, 0xa00001) AM_WRITE(gakusai_oki_bank_hi_w) // + AM_RANGE(0x900000, 0x900001) AM_WRITE8(gakusai_oki_bank_lo_w, 0x00ff) // Sound bank + AM_RANGE(0xa00000, 0xa00001) AM_WRITE8(gakusai_oki_bank_hi_w, 0x00ff) // AM_RANGE(0xb00000, 0xb00001) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) // Sound AM_RANGE(0xc00000, 0xc00003) AM_DEVWRITE8("ymsnd", ym2413_device, write, 0x00ff) - AM_RANGE(0xe00000, 0xe00001) AM_READWRITE(gakusai_eeprom_r,gakusai_eeprom_w) // EEPROM + AM_RANGE(0xe00000, 0xe00001) AM_READWRITE8(gakusai_eeprom_r, gakusai_eeprom_w, 0x00ff) // EEPROM AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) ADDRESS_MAP_END @@ -1286,7 +863,7 @@ ADDRESS_MAP_END Mahjong Doukyuusei Special ***************************************************************************/ -READ16_MEMBER(metro_state::dokyusp_eeprom_r) +READ8_MEMBER(metro_state::dokyusp_eeprom_r) { // clock line asserted: write latch or select next bit to read m_eeprom->clk_write(CLEAR_LINE); @@ -1295,58 +872,39 @@ READ16_MEMBER(metro_state::dokyusp_eeprom_r) return m_eeprom->do_read() & 1; } -WRITE16_MEMBER(metro_state::dokyusp_eeprom_bit_w) +WRITE8_MEMBER(metro_state::dokyusp_eeprom_bit_w) { - if (ACCESSING_BITS_0_7) - { - // latch the bit - m_eeprom->di_write(BIT(data, 0)); + // latch the bit + m_eeprom->di_write(BIT(data, 0)); - // clock line asserted: write latch or select next bit to read - m_eeprom->clk_write(CLEAR_LINE); - m_eeprom->clk_write(ASSERT_LINE); - } + // clock line asserted: write latch or select next bit to read + m_eeprom->clk_write(CLEAR_LINE); + m_eeprom->clk_write(ASSERT_LINE); } -WRITE16_MEMBER(metro_state::dokyusp_eeprom_reset_w) +WRITE8_MEMBER(metro_state::dokyusp_eeprom_reset_w) { - if (ACCESSING_BITS_0_7) - { - // reset line asserted: reset. - m_eeprom->cs_write(BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE); - } + // reset line asserted: reset. + m_eeprom->cs_write(BIT(data, 0) ? ASSERT_LINE : CLEAR_LINE); } static ADDRESS_MAP_START( dokyusp_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x03ffff) AM_ROM // ROM - AM_RANGE(0x200000, 0x21ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x220000, 0x23ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x240000, 0x25ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x260000, 0x26ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x270000, 0x271fff) AM_RAM // ??? - AM_RANGE(0x272000, 0x273fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x274000, 0x274fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x278000, 0x2787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x27880e, 0x27880f) AM_RAM AM_SHARE("screenctrl") // Screen Control + AM_RANGE(0x200000, 0x27ffff) AM_DEVICE("vdp3", imagetek_i4300_device, v3_map) AM_RANGE(0x278810, 0x27881f) AM_WRITEONLY AM_SHARE("irq_levels") // IRQ Levels AM_RANGE(0x278820, 0x27882f) AM_WRITEONLY AM_SHARE("irq_vectors") // IRQ Vectors AM_RANGE(0x278830, 0x278831) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x278832, 0x278833) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x278836, 0x278837) AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w) - AM_RANGE(0x278840, 0x27884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x278850, 0x27885b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0x278860, 0x27886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x278870, 0x278871) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank AM_RANGE(0x278880, 0x278881) AM_READ(gakusai_input_r) // Inputs AM_RANGE(0x278882, 0x278883) AM_READ_PORT("IN0") // AM_RANGE(0x278888, 0x278889) AM_WRITEONLY AM_SHARE("input_sel") // - AM_RANGE(0x279700, 0x279713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0x400000, 0x400001) AM_WRITENOP // ? 5 - AM_RANGE(0x500000, 0x500001) AM_WRITE(gakusai_oki_bank_lo_w) // Sound + AM_RANGE(0x500000, 0x500001) AM_WRITE8(gakusai_oki_bank_lo_w, 0x00ff) // Sound AM_RANGE(0x600000, 0x600003) AM_DEVWRITE8("ymsnd", ym2413_device, write, 0x00ff) AM_RANGE(0x700000, 0x700001) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) // Sound - AM_RANGE(0xc00000, 0xc00001) AM_WRITE(dokyusp_eeprom_reset_w) // EEPROM - AM_RANGE(0xd00000, 0xd00001) AM_READWRITE(dokyusp_eeprom_r, dokyusp_eeprom_bit_w) // EEPROM + AM_RANGE(0xc00000, 0xc00001) AM_WRITE8(dokyusp_eeprom_reset_w, 0x00ff) // EEPROM + AM_RANGE(0xd00000, 0xd00001) AM_READWRITE8(dokyusp_eeprom_r, dokyusp_eeprom_bit_w, 0x00ff) // EEPROM AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) ADDRESS_MAP_END @@ -1357,35 +915,21 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( dokyusei_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x03ffff) AM_ROM // ROM - AM_RANGE(0x400000, 0x41ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x420000, 0x43ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x440000, 0x45ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x460000, 0x46ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x460000, 0x46ffff) AM_WRITENOP // DSW Selection - AM_RANGE(0x470000, 0x471fff) AM_RAM // ??? - AM_RANGE(0x472000, 0x473fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x474000, 0x474fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x478000, 0x4787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x47880e, 0x47880f) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control + AM_RANGE(0x400000, 0x47ffff) AM_DEVICE("vdp3", imagetek_i4300_device, v3_map) AM_RANGE(0x478810, 0x47881f) AM_WRITEONLY AM_SHARE("irq_levels") // IRQ Levels AM_RANGE(0x478820, 0x47882f) AM_WRITEONLY AM_SHARE("irq_vectors") // IRQ Vectors AM_RANGE(0x478830, 0x478831) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable // AM_RANGE(0x478832, 0x478833) AM_READ(metro_irq_cause_r) // IRQ Cause AM_RANGE(0x478832, 0x478833) AM_WRITE(metro_irq_cause_w) // IRQ Acknowledge AM_RANGE(0x478836, 0x478837) AM_WRITENOP // ? watchdog ? - AM_RANGE(0x478840, 0x47884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x478850, 0x47885b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0x478860, 0x47886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x478870, 0x478871) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank AM_RANGE(0x478880, 0x478881) AM_READ(gakusai_input_r) // Inputs AM_RANGE(0x478882, 0x478883) AM_READ_PORT("IN0") // AM_RANGE(0x478884, 0x478885) AM_READ_PORT("DSW0") // 2 x DSW AM_RANGE(0x478886, 0x478887) AM_READ_PORT("DSW1") // AM_RANGE(0x478888, 0x478889) AM_WRITEONLY AM_SHARE("input_sel") // Inputs - AM_RANGE(0x479700, 0x479713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers - AM_RANGE(0x800000, 0x800001) AM_WRITE(gakusai_oki_bank_hi_w) // Samples Bank? + AM_RANGE(0x800000, 0x800001) AM_WRITE8(gakusai_oki_bank_hi_w, 0x00ff) // Samples Bank? AM_RANGE(0x900000, 0x900001) AM_WRITENOP // ? 4 - AM_RANGE(0xa00000, 0xa00001) AM_WRITE(gakusai_oki_bank_lo_w) // Samples Bank + AM_RANGE(0xa00000, 0xa00001) AM_WRITE8(gakusai_oki_bank_lo_w, 0x00ff) // Samples Bank AM_RANGE(0xc00000, 0xc00003) AM_DEVWRITE8("ymsnd", ym2413_device, write, 0x00ff) // AM_RANGE(0xd00000, 0xd00001) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0x00ff) // Sound AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) @@ -1398,25 +942,10 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( pangpoms_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x03ffff) AM_ROM // ROM - AM_RANGE(0x400000, 0x41ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x420000, 0x43ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x440000, 0x45ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x460000, 0x46ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x470000, 0x471fff) AM_RAM // ??? - AM_RANGE(0x472000, 0x473fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x474000, 0x474fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x478000, 0x4787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x478800, 0x478813) AM_RAM AM_SHARE("videoregs") // Video Registers - AM_RANGE(0x478840, 0x47884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x478860, 0x47886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x478870, 0x47887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0x478880, 0x478881) AM_WRITENOP // ? CRT - AM_RANGE(0x478890, 0x478891) AM_WRITENOP // ? CRT + AM_RANGE(0x400000, 0x47ffff) AM_DEVICE("vdp", imagetek_i4100_device, map) AM_RANGE(0x4788a2, 0x4788a3) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x4788a4, 0x4788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x4788a8, 0x4788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0x4788aa, 0x4788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x4788ac, 0x4788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control AM_RANGE(0x800000, 0x800001) AM_READWRITE(metro_soundstatus_r,metro_soundstatus_w) // From / To Sound CPU AM_RANGE(0x800002, 0x800003) AM_READNOP AM_WRITE(metro_coin_lockout_1word_w) // Coin Lockout AM_RANGE(0x800004, 0x800005) AM_READ_PORT("IN0") // Inputs @@ -1441,25 +970,10 @@ static ADDRESS_MAP_START( poitto_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x800004, 0x800005) AM_READ_PORT("DSW0") // AM_RANGE(0x800006, 0x800007) AM_READ_PORT("IN2") // AM_RANGE(0x800002, 0x800009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout - AM_RANGE(0xc00000, 0xc1ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0xc20000, 0xc3ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0xc40000, 0xc5ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0xc60000, 0xc6ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0xc70000, 0xc71fff) AM_RAM // ??? - AM_RANGE(0xc72000, 0xc73fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0xc74000, 0xc74fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0xc78000, 0xc787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0xc78800, 0xc78813) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers - AM_RANGE(0xc78840, 0xc7884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0xc78860, 0xc7886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0xc78870, 0xc7887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0xc78880, 0xc78881) AM_WRITENOP // ? CRT - AM_RANGE(0xc78890, 0xc78891) AM_WRITENOP // ? CRT + AM_RANGE(0xc00000, 0xc7ffff) AM_DEVICE("vdp", imagetek_i4100_device, map) AM_RANGE(0xc788a2, 0xc788a3) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0xc788a4, 0xc788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0xc788a8, 0xc788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0xc788aa, 0xc788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0xc788ac, 0xc788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control ADDRESS_MAP_END @@ -1477,25 +991,10 @@ static ADDRESS_MAP_START( skyalert_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x40000a, 0x40000b) AM_READ_PORT("DSW0") // AM_RANGE(0x40000c, 0x40000d) AM_READ_PORT("DSW1") // AM_RANGE(0x40000e, 0x40000f) AM_READ_PORT("IN3") // - AM_RANGE(0x800000, 0x81ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x820000, 0x83ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x840000, 0x85ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x860000, 0x86ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x870000, 0x871fff) AM_RAM // ??? - AM_RANGE(0x872000, 0x873fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x874000, 0x874fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x878000, 0x8787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x878800, 0x878813) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers - AM_RANGE(0x878840, 0x87884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x878860, 0x87886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x878870, 0x87887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x878880, 0x878881) AM_WRITENOP // ? CRT - AM_RANGE(0x878890, 0x878891) AM_WRITENOP // ? CRT + AM_RANGE(0x800000, 0x87ffff) AM_DEVICE("vdp", imagetek_i4100_device, map) AM_RANGE(0x8788a2, 0x8788a3) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x8788a4, 0x8788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x8788a8, 0x8788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0x8788aa, 0x8788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x8788ac, 0x8788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control AM_RANGE(0xc00000, 0xc0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) ADDRESS_MAP_END @@ -1512,25 +1011,10 @@ static ADDRESS_MAP_START( pururun_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x400006, 0x400007) AM_READ_PORT("IN2") // AM_RANGE(0x400002, 0x400009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout AM_RANGE(0x800000, 0x80ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) - AM_RANGE(0xc00000, 0xc1ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0xc20000, 0xc3ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0xc40000, 0xc5ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0xc60000, 0xc6ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0xc70000, 0xc71fff) AM_RAM // ??? - AM_RANGE(0xc72000, 0xc73fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0xc74000, 0xc74fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0xc78000, 0xc787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0xc78840, 0xc7884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0xc78860, 0xc7886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0xc78870, 0xc7887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0xc78880, 0xc78881) AM_WRITENOP // ? CRT - AM_RANGE(0xc78890, 0xc78891) AM_WRITENOP // ? CRT + AM_RANGE(0xc00000, 0xc7ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0xc788a2, 0xc788a3) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0xc788a4, 0xc788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0xc788a8, 0xc788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0xc788aa, 0xc788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0xc788ac, 0xc788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0xc79700, 0xc79713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers ADDRESS_MAP_END @@ -1546,25 +1030,10 @@ static ADDRESS_MAP_START( toride2g_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x800004, 0x800005) AM_READ_PORT("DSW0") // AM_RANGE(0x800006, 0x800007) AM_READ_PORT("IN2") // AM_RANGE(0x800002, 0x800009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout - AM_RANGE(0xc00000, 0xc1ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0xc20000, 0xc3ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0xc40000, 0xc5ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0xc60000, 0xc6ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0xc70000, 0xc71fff) AM_RAM // ??? - AM_RANGE(0xc72000, 0xc73fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0xc74000, 0xc74fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0xc78000, 0xc787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0xc78840, 0xc7884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0xc78860, 0xc7886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0xc78870, 0xc7887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0xc78880, 0xc78881) AM_WRITENOP // ? CRT - AM_RANGE(0xc78890, 0xc78891) AM_WRITENOP // ? CRT + AM_RANGE(0xc00000, 0xc7ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map ) AM_RANGE(0xc788a2, 0xc788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0xc788a4, 0xc788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0xc788a8, 0xc788a9) AM_WRITE(metro_soundlatch_w) // To Sound CPU - AM_RANGE(0xc788aa, 0xc788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0xc788ac, 0xc788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0xc79700, 0xc79713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers ADDRESS_MAP_END @@ -1602,24 +1071,9 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( blzntrnd_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x1fffff) AM_ROM // ROM - AM_RANGE(0x200000, 0x21ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x220000, 0x23ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x240000, 0x25ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x260000, 0x26ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x260000, 0x26ffff) AM_WRITENOP // ?????? - AM_RANGE(0x270000, 0x271fff) AM_RAM // ??? - AM_RANGE(0x272000, 0x273fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x274000, 0x274fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x278000, 0x2787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x278860, 0x27886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x278870, 0x27887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x278890, 0x278891) AM_WRITENOP // ? CRT + AM_RANGE(0x200000, 0x27ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0x2788a2, 0x2788a3) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x2788a4, 0x2788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable - AM_RANGE(0x2788aa, 0x2788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x2788ac, 0x2788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0x279700, 0x279713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers -// AM_RANGE(0x300000, 0x300001) AM_READNOP // Sound AM_RANGE(0x400000, 0x43ffff) AM_RAM_WRITE(metro_k053936_w) AM_SHARE("k053936_ram") // 053936 AM_RANGE(0x500000, 0x500fff) AM_DEVWRITE("k053936", k053936_device, linectrl_w) // 053936 line control @@ -1645,38 +1099,21 @@ WRITE8_MEMBER(metro_state::mouja_sound_rombank_w) static ADDRESS_MAP_START( mouja_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM // ROM - AM_RANGE(0x400000, 0x41ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x420000, 0x43ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x440000, 0x45ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x470000, 0x471fff) AM_RAM // ??? - AM_RANGE(0x472000, 0x473fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x474000, 0x474fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x478000, 0x4787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x47880e, 0x47880f) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control + AM_RANGE(0x400000, 0x47ffff) AM_DEVICE("vdp3", imagetek_i4300_device, v3_map) AM_RANGE(0x478810, 0x47881f) AM_WRITEONLY AM_SHARE("irq_levels") // IRQ Levels AM_RANGE(0x478820, 0x47882f) AM_WRITEONLY AM_SHARE("irq_vectors") // IRQ Vectors AM_RANGE(0x478830, 0x478831) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable AM_RANGE(0x478832, 0x478833) AM_READWRITE(metro_irq_cause_r,metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x478834, 0x478835) AM_WRITE(mouja_irq_timer_ctrl_w) // IRQ set timer count AM_RANGE(0x478836, 0x478837) AM_DEVWRITE("watchdog", watchdog_timer_device, reset16_w) - AM_RANGE(0x478850, 0x47885b) AM_WRITEONLY AM_SHARE("scroll") // Scroll Regs - AM_RANGE(0x478860, 0x47886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window AM_RANGE(0x478880, 0x478881) AM_READ_PORT("IN0") // Inputs AM_RANGE(0x478882, 0x478883) AM_READ_PORT("IN1") // AM_RANGE(0x478884, 0x478885) AM_READ_PORT("DSW0") // AM_RANGE(0x478886, 0x478887) AM_READ_PORT("IN2") // - AM_RANGE(0x478888, 0x478889) AM_WRITENOP // ?? - AM_RANGE(0x479700, 0x479713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0x800000, 0x800001) AM_WRITE8(mouja_sound_rombank_w, 0x00ff) AM_RANGE(0xc00000, 0xc00003) AM_DEVWRITE8("ymsnd", ym2413_device, write, 0x00ff) AM_RANGE(0xd00000, 0xd00001) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0xffff) AM_RANGE(0xf00000, 0xf0ffff) AM_RAM AM_MIRROR(0x0f0000) // RAM (mirrored) -#if 0 - AM_RANGE(0x460000, 0x46ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x478840, 0x47884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x47883a, 0x47883b) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x800002, 0x800009) AM_WRITE(metro_coin_lockout_4words_w) // Coin Lockout -#endif ADDRESS_MAP_END static ADDRESS_MAP_START( mouja_okimap, 0, 8, metro_state ) @@ -1774,34 +1211,6 @@ WRITE16_MEMBER(metro_state::puzzlet_irq_enable_w) *m_irq_enable = data ^ 0xffff; } -/* FIXME: algorithm not yet understood. */ -WRITE16_MEMBER(metro_state::vram_0_clr_w) -{ - static int i; - -// printf("0 %04x %04x\n",offset,data); - for(i=0;i<0x20/2;i++) - m_vram_0[(offset*0x10+i)/2] = 0xffff; -} - -WRITE16_MEMBER(metro_state::vram_1_clr_w) -{ - static int i; - -// printf("0 %04x %04x\n",offset,data); - for(i=0;i<0x20/2;i++) - m_vram_1[(offset*0x10+i)/2] = 0xffff; -} - -WRITE16_MEMBER(metro_state::vram_2_clr_w) -{ - static int i; - -// printf("0 %04x %04x\n",offset,data); - for(i=0;i<0x20/2;i++) - m_vram_2[(offset*0x10+i)/2] = 0xffff; -} - // H8/3007 CPU static ADDRESS_MAP_START( puzzlet_map, AS_PROGRAM, 16, metro_state ) @@ -1812,26 +1221,10 @@ static ADDRESS_MAP_START( puzzlet_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x500000, 0x500001) AM_DEVREADWRITE8("oki", okim6295_device, read, write, 0xff00) AM_RANGE(0x580000, 0x580003) AM_DEVWRITE8("ymsnd", ym2413_device, write, 0xff00) - AM_RANGE(0x700000, 0x71ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x720000, 0x73ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x740000, 0x75ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x760000, 0x76ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x770000, 0x771fff) AM_RAM // ??? - AM_RANGE(0x772000, 0x773fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x774000, 0x774fff) AM_RAM AM_SHARE("spriteram") - AM_RANGE(0x775000, 0x775fff) AM_RAM_WRITE(vram_0_clr_w) - AM_RANGE(0x776000, 0x776fff) AM_RAM_WRITE(vram_1_clr_w) - AM_RANGE(0x777000, 0x777fff) AM_RAM_WRITE(vram_2_clr_w) - AM_RANGE(0x778000, 0x7787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x778800, 0x778813) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers - AM_RANGE(0x778840, 0x77884f) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x778860, 0x77886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x778870, 0x77887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x778890, 0x778891) AM_WRITENOP // ? CRT + // TODO: !!! i4300 !!! AM_RANGE(0x7788a2, 0x7788a3) AM_WRITE(metro_irq_cause_w) // IRQ Cause AM_RANGE(0x7788a4, 0x7788a5) AM_WRITE(puzzlet_irq_enable_w) AM_SHARE("irq_enable") // IRQ Enable - AM_RANGE(0x7788aa, 0x7788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x7788ac, 0x7788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control + AM_RANGE(0x700000, 0x77ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0x7f2000, 0x7f3fff) AM_RAM @@ -1893,24 +1286,9 @@ WRITE_LINE_MEMBER(metro_state::vmetal_es8712_irq) static ADDRESS_MAP_START( vmetal_map, AS_PROGRAM, 16, metro_state ) AM_RANGE(0x000000, 0x0fffff) AM_ROM // ROM - AM_RANGE(0x100000, 0x11ffff) AM_RAM_WRITE(metro_vram_0_w) AM_SHARE("vram_0") // Layer 0 - AM_RANGE(0x120000, 0x13ffff) AM_RAM_WRITE(metro_vram_1_w) AM_SHARE("vram_1") // Layer 1 - AM_RANGE(0x140000, 0x15ffff) AM_RAM_WRITE(metro_vram_2_w) AM_SHARE("vram_2") // Layer 2 - AM_RANGE(0x160000, 0x16ffff) AM_READ(metro_bankedrom_r) // Banked ROM - AM_RANGE(0x170000, 0x171fff) AM_RAM // ??? - AM_RANGE(0x172000, 0x173fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // Palette - AM_RANGE(0x174000, 0x174fff) AM_RAM AM_SHARE("spriteram") // Sprites - AM_RANGE(0x178000, 0x1787ff) AM_RAM AM_SHARE("tiletable") // Tiles Set - AM_RANGE(0x178840, 0x17884d) AM_WRITE(metro_blitter_w) AM_SHARE("blitter_regs") // Tiles Blitter - AM_RANGE(0x178860, 0x17886b) AM_WRITE(metro_window_w) AM_SHARE("window") // Tilemap Window - AM_RANGE(0x178870, 0x17887b) AM_WRITEONLY AM_SHARE("scroll") // Scroll - AM_RANGE(0x178880, 0x178881) AM_WRITENOP // ? CRT - AM_RANGE(0x178890, 0x178891) AM_WRITENOP // ? CRT + AM_RANGE(0x100000, 0x17ffff) AM_DEVICE("vdp2", imagetek_i4220_device, v2_map) AM_RANGE(0x1788a2, 0x1788a3) AM_READWRITE(metro_irq_cause_r, metro_irq_cause_w) // IRQ Cause / IRQ Acknowledge AM_RANGE(0x1788a4, 0x1788a5) AM_WRITEONLY AM_SHARE("irq_enable") // IRQ Enable - AM_RANGE(0x1788aa, 0x1788ab) AM_WRITEONLY AM_SHARE("rombank") // Rom Bank - AM_RANGE(0x1788ac, 0x1788ad) AM_WRITEONLY AM_SHARE("screenctrl") // Screen Control - AM_RANGE(0x179700, 0x179713) AM_WRITEONLY AM_SHARE("videoregs") // Video Registers AM_RANGE(0x200000, 0x200001) AM_READ_PORT("P1_P2") AM_WRITE8(vmetal_control_w, 0x00ff) AM_RANGE(0x200002, 0x200003) AM_READ_PORT("SYSTEM") AM_RANGE(0x300000, 0x31ffff) AM_READ(balcube_dsw_r) // DSW x 3 @@ -2769,9 +2147,10 @@ static INPUT_PORTS_START( lastfort ) PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:7") PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0040, DEF_STR( On ) ) - PORT_DIPNAME( 0x0080, 0x0080, "Tiles" ) PORT_DIPLOCATION("SW2:8") - PORT_DIPSETTING( 0x0080, "Mahjong" ) +// PORT_DIPNAME( 0x0080, 0x0080, "Tiles" ) PORT_DIPLOCATION("SW2:8") +// PORT_DIPSETTING( 0x0080, "Mahjong" ) // PORT_DIPSETTING( 0x0000, "Cards" ) // Not working - See notes + PORT_DIPUNUSED_DIPLOC( 0x0080, 0x0080, "SW2:8" ) PORT_START("IN3") // $c0000e PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) @@ -3656,10 +3035,96 @@ void metro_state::machine_start() save_item(NAME(m_busy_sndcpu)); save_item(NAME(m_gakusai_oki_bank_lo)); save_item(NAME(m_gakusai_oki_bank_hi)); - save_item(NAME(m_sprite_xoffs)); - save_item(NAME(m_sprite_yoffs)); } +static MACHINE_CONFIG_START( i4100_config ) + MCFG_DEVICE_ADD("vdp", I4100, XTAL_26_666MHz) + MCFG_I4100_GFXDECODE("gfxdecode") + MCFG_I4100_BLITTER_END_CALLBACK(WRITELINE(metro_state,vdp_blit_end_w)) + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(58.2328) // VSync 58.2328Hz, HSync 15.32kHz + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) + MCFG_SCREEN_SIZE(320, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) + MCFG_SCREEN_UPDATE_DEVICE("vdp", imagetek_i4100_device, screen_update) + MCFG_SCREEN_PALETTE(":vdp:palette") + + MCFG_GFXDECODE_ADD("gfxdecode", ":vdp:palette", i4100) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( i4220_config ) + MCFG_DEVICE_ADD("vdp2", I4220, XTAL_26_666MHz) + MCFG_I4100_GFXDECODE("gfxdecode") + MCFG_I4100_BLITTER_END_CALLBACK(WRITELINE(metro_state,vdp_blit_end_w)) + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(58.2328) // VSync 58.2328Hz, HSync 15.32kHz + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) + MCFG_SCREEN_SIZE(320, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) + MCFG_SCREEN_UPDATE_DEVICE("vdp2", imagetek_i4100_device, screen_update) + MCFG_SCREEN_PALETTE(":vdp2:palette") + + MCFG_GFXDECODE_ADD("gfxdecode", ":vdp2:palette", i4220) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( i4300_config ) + MCFG_DEVICE_ADD("vdp3", I4300, XTAL_26_666MHz) + MCFG_I4100_GFXDECODE("gfxdecode") + MCFG_I4100_BLITTER_END_CALLBACK(WRITELINE(metro_state,vdp_blit_end_w)) + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(58.2328) // VSync 58.2328Hz, HSync 15.32kHz + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) + MCFG_SCREEN_SIZE(320, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) + MCFG_SCREEN_UPDATE_DEVICE("vdp3", imagetek_i4100_device, screen_update) + MCFG_SCREEN_PALETTE(":vdp3:palette") + + MCFG_GFXDECODE_ADD("gfxdecode", ":vdp3:palette", i4300) +MACHINE_CONFIG_END + +// TODO: these comes from the CRTC inside the i4100 +static MACHINE_CONFIG_START( i4100_config_360x224 ) + MCFG_FRAGMENT_ADD( i4100_config ) + + MCFG_DEVICE_MODIFY("screen") + MCFG_SCREEN_SIZE(360, 224) + MCFG_SCREEN_VISIBLE_AREA(0, 360-1, 0, 224-1) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( i4220_config_320x240 ) + MCFG_FRAGMENT_ADD( i4220_config ) + + MCFG_DEVICE_MODIFY("screen") + MCFG_SCREEN_SIZE(320, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( i4220_config_304x224 ) + MCFG_FRAGMENT_ADD( i4220_config ) + + MCFG_DEVICE_MODIFY("screen") + MCFG_SCREEN_SIZE(320, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 304-1, 0, 224-1) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( i4300_config_384x224 ) + MCFG_FRAGMENT_ADD( i4300_config ) + + MCFG_DEVICE_MODIFY("screen") + MCFG_SCREEN_SIZE(384, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 384-1, 0, 224-1) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( i4300_config_320x240 ) + MCFG_FRAGMENT_ADD( i4300_config ) + + MCFG_DEVICE_MODIFY("screen") + MCFG_SCREEN_SIZE(384, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) +MACHINE_CONFIG_END static MACHINE_CONFIG_START( msgogo ) @@ -3671,18 +3136,9 @@ static MACHINE_CONFIG_START( msgogo ) MCFG_CPU_PERIODIC_INT_DRIVER(metro_state, metro_periodic_interrupt, 60) // ? /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4220) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4220_dx_tmap) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4220_config ) + MCFG_DEVICE_MODIFY("vdp2") + MCFG_I4100_TILEMAP_XOFFSETS(-2,-2,-2) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -3710,15 +3166,25 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( bangball, msgogo ) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_PROGRAM_MAP(bangball_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", metro_state, metro_vblank_interrupt) - MCFG_CPU_PERIODIC_INT_DRIVER(metro_state, metro_periodic_interrupt, 60) // ? + MCFG_CPU_VBLANK_INT_REMOVE() + MCFG_CPU_PERIODIC_INT_REMOVE() + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", metro_state, bangball_scanline, "screen", 0, 1) + + // doesn't like 58.2 Hz + MCFG_DEVICE_MODIFY("screen") + MCFG_SCREEN_REFRESH_RATE(60) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( batlbubl, msgogo ) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_PROGRAM_MAP(batlbubl_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", metro_state, metro_vblank_interrupt) - MCFG_CPU_PERIODIC_INT_DRIVER(metro_state, metro_periodic_interrupt, 60) // ? + MCFG_CPU_VBLANK_INT_REMOVE() + MCFG_CPU_PERIODIC_INT_REMOVE() + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", metro_state, bangball_scanline, "screen", 0, 1) + + // doesn't like 58.2 Hz + MCFG_DEVICE_MODIFY("screen") + MCFG_SCREEN_REFRESH_RATE(60) MACHINE_CONFIG_END @@ -3754,18 +3220,9 @@ static MACHINE_CONFIG_START( daitorid ) MCFG_FRAGMENT_ADD(daitorid_upd7810_sound) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(58) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4220) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4220_dx_tmap) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4220_config ) + MCFG_DEVICE_MODIFY("vdp2") + MCFG_I4100_TILEMAP_XOFFSETS(-2,-2,-2) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -3792,18 +3249,7 @@ static MACHINE_CONFIG_START( dharma ) MCFG_FRAGMENT_ADD(metro_upd7810_sound) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4220) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4220) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD(i4220_config) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -3817,7 +3263,6 @@ static MACHINE_CONFIG_START( dharma ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.90) MACHINE_CONFIG_END - static MACHINE_CONFIG_START( karatour ) /* basic machine hardware */ @@ -3829,18 +3274,7 @@ static MACHINE_CONFIG_START( karatour ) MCFG_FRAGMENT_ADD(metro_upd7810_sound) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 240) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4100) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4100) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD(i4100_config) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -3866,18 +3300,7 @@ static MACHINE_CONFIG_START( 3kokushi ) MCFG_FRAGMENT_ADD(metro_upd7810_sound) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 240) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4220) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4220) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4220_config_320x240 ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -3903,18 +3326,7 @@ static MACHINE_CONFIG_START( lastfort ) MCFG_FRAGMENT_ADD(metro_upd7810_sound) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(58) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(360, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 360-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4100) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4100) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4100_config_360x224 ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -3938,19 +3350,7 @@ static MACHINE_CONFIG_START( lastforg ) MCFG_FRAGMENT_ADD(metro_upd7810_sound) - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(58) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(360, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 360-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4100) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4100) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4100_config_360x224 ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -3973,18 +3373,7 @@ static MACHINE_CONFIG_START( dokyusei ) MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(metro_state,metro_irq_callback) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4300) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4300) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4300_config ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4009,18 +3398,7 @@ static MACHINE_CONFIG_START( dokyusp ) MCFG_WATCHDOG_ADD("watchdog") /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(384, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 384-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4300) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4300) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4300_config_384x224 ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4046,18 +3424,7 @@ static MACHINE_CONFIG_START( gakusai ) MCFG_WATCHDOG_ADD("watchdog") /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 240) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4300) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4300) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4300_config_320x240 ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4083,18 +3450,7 @@ static MACHINE_CONFIG_START( gakusai2 ) MCFG_WATCHDOG_ADD("watchdog") /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 240) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 240-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4300) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4300) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4300_config_320x240 ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4118,18 +3474,7 @@ static MACHINE_CONFIG_START( pangpoms ) MCFG_FRAGMENT_ADD(metro_upd7810_sound) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(360, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 360-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4100) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4100) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4100_config_360x224 ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4155,18 +3500,7 @@ static MACHINE_CONFIG_START( poitto ) MCFG_FRAGMENT_ADD(metro_upd7810_sound) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(360, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 360-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4100) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4100) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4100_config_360x224 ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4192,18 +3526,7 @@ static MACHINE_CONFIG_START( pururun ) MCFG_FRAGMENT_ADD(daitorid_upd7810_sound) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4220) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4220) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4220_config ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4229,19 +3552,8 @@ static MACHINE_CONFIG_START( skyalert ) MCFG_FRAGMENT_ADD(metro_upd7810_sound) - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(360, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 360-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") + MCFG_FRAGMENT_ADD(i4100_config_360x224) - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4100) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4100) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4267,18 +3579,7 @@ static MACHINE_CONFIG_START( toride2g ) MCFG_FRAGMENT_ADD(metro_upd7810_sound) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4220) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4220) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4220_config ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4304,18 +3605,7 @@ static MACHINE_CONFIG_START( mouja ) MCFG_WATCHDOG_ADD("watchdog") /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(58) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(512, 256) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4300) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4300) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_FRAGMENT_ADD( i4300_config ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4337,18 +3627,11 @@ static MACHINE_CONFIG_START( vmetal ) MCFG_CPU_PERIODIC_INT_DRIVER(metro_state, metro_periodic_interrupt, 8*60) // ? /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(58.2328) // VSync 58.2328Hz, HSync 15.32kHz - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") + MCFG_FRAGMENT_ADD( i4220_config_304x224 ) - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4220) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4220_dx_sprite) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + MCFG_DEVICE_MODIFY("vdp2") + MCFG_I4100_TILEMAP_XOFFSETS(-16,-16,-16) + MCFG_I4100_TILEMAP_YOFFSETS(-16,-16,-16) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4377,21 +3660,24 @@ static MACHINE_CONFIG_START( blzntrnd ) MCFG_CPU_IO_MAP(blzntrnd_sound_io_map) /* video hardware */ + MCFG_DEVICE_ADD("vdp2", I4220, XTAL_26_666MHz) + MCFG_I4100_GFXDECODE("gfxdecode") + MCFG_I4100_BLITTER_END_CALLBACK(WRITELINE(metro_state,vdp_blit_end_w)) + MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(58) + MCFG_SCREEN_REFRESH_RATE(58.2328) // VSync 58.2328Hz, HSync 15.32kHz MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(8, 320-8-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", blzntrnd) + MCFG_SCREEN_SIZE(320, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 304-1, 0, 224-1) + MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_psac_vdp2_mix) + MCFG_SCREEN_PALETTE(":vdp2:palette") MCFG_VIDEO_START_OVERRIDE(metro_state,blzntrnd) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + + MCFG_GFXDECODE_ADD("gfxdecode", ":vdp2:palette", blzntrnd) + MCFG_DEVICE_ADD("k053936", K053936, 0) - MCFG_K053936_OFFSETS(-69, -21) + MCFG_K053936_OFFSETS(-77, -21) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4410,7 +3696,10 @@ static MACHINE_CONFIG_DERIVED( gstrik2, blzntrnd ) MCFG_VIDEO_START_OVERRIDE(metro_state,gstrik2) MCFG_DEVICE_MODIFY("k053936") - MCFG_K053936_OFFSETS(-69, -19) + MCFG_K053936_OFFSETS(-77, -19) + + MCFG_DEVICE_MODIFY("vdp2") + MCFG_I4100_TILEMAP_XOFFSETS(0,-8,0) MACHINE_CONFIG_END @@ -4430,18 +3719,8 @@ static MACHINE_CONFIG_START( puzzlet ) MCFG_H8_SCI_CLK_CALLBACK(DEVWRITELINE(":coins", puzzlet_io_device, clk_w)) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(58) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(320, 224) - MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 224-1) - MCFG_SCREEN_UPDATE_DRIVER(metro_state, screen_update_metro) - MCFG_SCREEN_PALETTE("palette") - - MCFG_GFXDECODE_ADD("gfxdecode", "palette", i4300) - MCFG_VIDEO_START_OVERRIDE(metro_state,metro_i4300) - MCFG_PALETTE_ADD("palette", 0x1000) - MCFG_PALETTE_FORMAT(GGGGGRRRRRBBBBBx) + // TODO: looks like game is running in i4220 compatibilty mode, $778000 seems to be an id for the chip? + MCFG_FRAGMENT_ADD( i4220_config ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") @@ -4494,7 +3773,7 @@ ROM_START( balcube ) ROM_LOAD16_BYTE( "bal-cube_06.6", 0x000000, 0x040000, CRC(c400f84d) SHA1(416eb82ec1201d24d9d964191a5a1792c9445923) ) /* Silkscreened 6 and U18 */ ROM_LOAD16_BYTE( "bal-cube_05.5", 0x000001, 0x040000, CRC(15313e3f) SHA1(10a8702016f223194dc91875b4736253fd47dbb8) ) /* Silkscreened 5 and U19 */ - ROM_REGION( 0x200000, "gfx1", 0 ) /* Gfx + Data (Addressable by CPU & Blitter) */ + ROM_REGION( 0x400000, "gfx1", 0 ) /* Gfx + Data (Addressable by CPU & Blitter) */ ROMX_LOAD( "bal-cube_02.2", 0x000000, 0x080000, CRC(492ca8f0) SHA1(478336a462a2bfc288cf91262314f5767f8c707d) , ROM_GROUPWORD | ROM_SKIP(6)) /* Silkscreened 2 and U30 */ ROMX_LOAD( "bal-cube_04.4", 0x000002, 0x080000, CRC(d1acda2c) SHA1(f58015302af6c864523d48bdf8f8a4383b69fa9d) , ROM_GROUPWORD | ROM_SKIP(6)) /* Silkscreened 4 and U29 */ ROMX_LOAD( "bal-cube_01.1", 0x000004, 0x080000, CRC(0ea3d161) SHA1(63ae430a19e777ce82b41ab02baef3bb224c7557) , ROM_GROUPWORD | ROM_SKIP(6)) /* Silkscreened 1 and U28 */ @@ -6213,8 +5492,6 @@ void metro_state::metro_common( ) m_irq_line = 2; *m_irq_enable = 0; - - m_blit_done_timer = timer_alloc(TIMER_METRO_BLIT_DONE); } @@ -6232,16 +5509,6 @@ DRIVER_INIT_MEMBER(metro_state,metro) DRIVER_INIT_MEMBER(metro_state,karatour) { - m_vram_0.allocate(0x20000/2); - m_vram_1.allocate(0x20000/2); - m_vram_2.allocate(0x20000/2); - for (int i = 0; i < 0x20000 / 2; i++) - { - m_vram_0[i] = machine().rand(); - m_vram_1[i] = machine().rand(); - m_vram_2[i] = machine().rand(); - } - m_karatour_irq_timer = timer_alloc(TIMER_KARATOUR_IRQ); DRIVER_INIT_CALL(metro); @@ -6359,15 +5626,15 @@ GAME( 1992, skyalert, 0, skyalert, skyalert, metro_state, metro, ROT2 GAME( 1993, ladykill, 0, karatour, ladykill, metro_state, karatour, ROT90, "Yanyaka (Mitchell license)", "Lady Killer", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1993, moegonta, ladykill, karatour, moegonta, metro_state, karatour, ROT90, "Yanyaka", "Moeyo Gonta!! (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1993, poitto, 0, poitto, poitto, metro_state, metro, ROT0, "Metro / Able Corp.", "Poitto!", MACHINE_SUPPORTS_SAVE ) -GAME( 1994, blzntrnd, 0, blzntrnd, blzntrnd, metro_state, blzntrnd, ROT0, "Human Amusement", "Blazing Tornado", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1994, blzntrnd, 0, blzntrnd, blzntrnd, metro_state, blzntrnd, ROT0, "Human Amusement", "Blazing Tornado", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL ) GAME( 1994, dharma, 0, dharma, dharma, metro_state, dharmak, ROT0, "Metro", "Dharma Doujou", MACHINE_SUPPORTS_SAVE ) GAME( 1994, dharmaj, dharma, dharma, dharma, metro_state, metro, ROT0, "Metro", "Dharma Doujou (Japan)", MACHINE_SUPPORTS_SAVE ) GAME( 1994, dharmak, dharma, dharma, dharma, metro_state, dharmak, ROT0, "Metro", "Dharma Doujou (Korea)", MACHINE_SUPPORTS_SAVE ) -GAME( 1994, lastfort, 0, lastfort, lastfort, metro_state, metro, ROT0, "Metro", "Last Fortress - Toride", MACHINE_SUPPORTS_SAVE ) -GAME( 1994, lastforte, lastfort, lastfort, lastfero, metro_state, metro, ROT0, "Metro", "Last Fortress - Toride (Erotic, Rev C)", MACHINE_SUPPORTS_SAVE ) -GAME( 1994, lastfortea,lastfort, lastfort, lastfero, metro_state, metro, ROT0, "Metro", "Last Fortress - Toride (Erotic, Rev A)", MACHINE_SUPPORTS_SAVE ) +GAME( 1994, lastfort, 0, lastfort, lastfort, metro_state, metro, ROT0, "Metro", "Last Fortress - Toride (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1994, lastforte, lastfort, lastfort, lastfero, metro_state, metro, ROT0, "Metro", "Last Fortress - Toride (China, Rev C)", MACHINE_SUPPORTS_SAVE ) +GAME( 1994, lastfortea,lastfort, lastfort, lastfero, metro_state, metro, ROT0, "Metro", "Last Fortress - Toride (China, Rev A)", MACHINE_SUPPORTS_SAVE ) GAME( 1994, lastfortk, lastfort, lastfort, lastfero, metro_state, metro, ROT0, "Metro", "Last Fortress - Toride (Korea)", MACHINE_SUPPORTS_SAVE ) -GAME( 1994, lastfortg, lastfort, lastforg, ladykill, metro_state, lastfortg,ROT0, "Metro", "Last Fortress - Toride (German)", MACHINE_SUPPORTS_SAVE ) +GAME( 1994, lastfortg, lastfort, lastforg, ladykill, metro_state, lastfortg,ROT0, "Metro", "Last Fortress - Toride (Germany)", MACHINE_SUPPORTS_SAVE ) GAME( 1994, toride2g, 0, toride2g, toride2g, metro_state, metro, ROT0, "Metro", "Toride II Adauchi Gaiden", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1994, toride2gg, toride2g, toride2g, toride2g, metro_state, metro, ROT0, "Metro", "Toride II Adauchi Gaiden (German)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1994, toride2gk, toride2g, toride2g, toride2g, metro_state, metro, ROT0, "Metro", "Toride II Bok Su Oi Jeon Adauchi Gaiden (Korea)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) @@ -6383,8 +5650,8 @@ GAME( 1995, puzzli, 0, daitorid, puzzli, metro_state, daitorid, ROT0 GAME( 1996, 3kokushi, 0, 3kokushi, 3kokushi, metro_state, karatour, ROT0, "Mitchell", "Sankokushi (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1996, balcube, 0, balcube, balcube, metro_state, balcube, ROT0, "Metro", "Bal Cube", MACHINE_SUPPORTS_SAVE ) GAME( 1996, bangball, 0, bangball, bangball, metro_state, balcube, ROT0, "Banpresto / Kunihiko Tashiro+Goodhouse", "Bang Bang Ball (v1.05)", MACHINE_SUPPORTS_SAVE ) -GAME( 1996, gstrik2, 0, gstrik2, gstrik2, metro_state, blzntrnd, ROT0, "Human Amusement", "Grand Striker 2 (Europe and Oceania)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAME( 1996, gstrik2j, gstrik2, gstrik2, gstrik2, metro_state, blzntrnd, ROT0, "Human Amusement", "Grand Striker 2 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) // priority between rounds +GAME( 1996, gstrik2, 0, gstrik2, gstrik2, metro_state, blzntrnd, ROT0, "Human Amusement", "Grand Striker 2 (Europe and Oceania)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL ) +GAME( 1996, gstrik2j, gstrik2, gstrik2, gstrik2, metro_state, blzntrnd, ROT0, "Human Amusement", "Grand Striker 2 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE | MACHINE_NO_COCKTAIL ) // priority between rounds GAME( 1999, batlbubl, bangball, batlbubl, batlbubl, metro_state, balcube, ROT0, "Banpresto (Limenko license?)", "Battle Bubble (v2.00)", MACHINE_SUPPORTS_SAVE ) // or bootleg? GAME( 1996, mouja, 0, mouja, mouja, metro_state, mouja, ROT0, "Etona", "Mouja (Japan)", MACHINE_SUPPORTS_SAVE ) GAME( 1997, gakusai, 0, gakusai, gakusai, metro_state, gakusai, ROT0, "MakeSoft", "Mahjong Gakuensai (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/meyc8088.cpp b/src/mame/drivers/meyc8088.cpp index 09bdd393e4b..af77a96f749 100644 --- a/src/mame/drivers/meyc8088.cpp +++ b/src/mame/drivers/meyc8088.cpp @@ -1,5 +1,6 @@ // license:BSD-3-Clause // copyright-holders:hap, Roberto Fresca +// thanks-to:Darrell Hal Smith, Kevin Mullins /**************************************************************** Meyco 8088 based hardware @@ -8,10 +9,6 @@ 3 x 8KB EPROM (max 4), 3 x 8KB RAM (max 4), 2KB battery RAM, 2 x i8155, optional i8251A + RS232 for factory debug - driver by MAME team - also thanks to Darrell Hal Smith, Kevin Mullins - - To initialize battery RAM, go into Meter Read mode (F1 -> 9), and then press the Meter Read + Reset buttons (9 + 0). @@ -19,9 +16,9 @@ in mid-game, it may run faulty on the next boot. Enable the Night Switch to prevent this. - TODO: - coincounters/hopper + - correct CPU speed (currently underclocked) ****************************************************************/ @@ -163,8 +160,9 @@ uint32_t meyc8088_state::screen_update_meyc8088(screen_device &screen, bitmap_in WRITE_LINE_MEMBER(meyc8088_state::screen_vblank_meyc8088) { - // INTR on LC255 (pulses at start and end of vblank), INTA hardwired to $20 - generic_pulse_irq_line_and_vector(*m_maincpu, 0, 0x20, 1); + // LC255(200ns pulse) rising edge asserts INTR at start and end of vblank + // INTA wired back to INTR to clear it, vector is hardwired to $20 + m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0x20); } diff --git a/src/mame/drivers/mgolf.cpp b/src/mame/drivers/mgolf.cpp index 7b93183085f..d27ffbb548d 100644 --- a/src/mame/drivers/mgolf.cpp +++ b/src/mame/drivers/mgolf.cpp @@ -159,7 +159,7 @@ TIMER_CALLBACK_MEMBER(mgolf_state::interrupt_callback) update_plunger(); - generic_pulse_irq_line(*m_maincpu, 0, 1); + m_maincpu->pulse_input_line(0, m_maincpu->minimum_quantum_time()); scanline = scanline + 32; diff --git a/src/mame/drivers/mice.cpp b/src/mame/drivers/mice.cpp index 85b317b71c8..907ae395520 100644 --- a/src/mame/drivers/mice.cpp +++ b/src/mame/drivers/mice.cpp @@ -8,12 +8,20 @@ Microtek International Inc MICE (Micro-In-Circuit Emulator) This is a CPU emulator for development work. -Each CPU has a plugin card with various chips. The usual complement is - the selected CPU, a 8085, 8255/8251/8155/6116, eproms and crystals. +Each emulated CPU has its own plugin "personality" card, containing the CPU +itself, an XTAL clock and enough latches, buffers and gates to allow total +control to be exercised over its bus activity. -The connection to the outside world is via RS232 to a terminal. +In the original MICE system, the MCP-85 main control card could be reused +with different CPU cards after replacing the EPROMs. The more spaciously +designed MICE-II eliminated this as a separate board and moved its primary +components (8085/8255/8251/8155/6116/ROMs/6.144 XTAL) onto the CEP (Control +Emulation Processor) card for each CPU; however, the RTT (Real-time Trace) +board (providing extra I/O ports) and UEM (Universal Emulation Memory) +boards could be shared between CEP cards. -No schematic available. This driver is guesswork. +The connection to the outside world is via a RS-232C port to a terminal. +The serial protocol is configurable through a 6-position DIP switch. There's a mistake in the boot rom: if the test of the 8155 or 8255 fail, it attempts to write a suitable message to the screen, but as the 8251 hasn't @@ -44,7 +52,7 @@ private: static ADDRESS_MAP_START(mice_mem, AS_PROGRAM, 8, mice_state) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x0000, 0x3fff) AM_ROM AM_REGION("mice_6502", 0) + AM_RANGE(0x0000, 0x3fff) AM_ROM AM_REGION("mcp", 0) AM_RANGE(0x4400, 0x47ff) AM_RAM //(U13) AM_RANGE(0x6000, 0x60ff) AM_DEVREADWRITE("rpt", i8155_device, memory_r, memory_w) ADDRESS_MAP_END @@ -58,6 +66,29 @@ static ADDRESS_MAP_START(mice_io, AS_IO, 8, mice_state) AM_RANGE(0x70, 0x73) AM_DEVREADWRITE("ppi", i8255_device, read, write) ADDRESS_MAP_END +static ADDRESS_MAP_START(mice2_mem, AS_PROGRAM, 8, mice_state) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x0000, 0x7fff) AM_ROM AM_REGION("cep", 0) + AM_RANGE(0x9000, 0x90ff) AM_DEVREADWRITE("rpt", i8155_device, memory_r, memory_w) + AM_RANGE(0xb000, 0xb7ff) AM_RAM + AM_RANGE(0xe800, 0xe8ff) AM_DEVREADWRITE("rtt8155", i8155_device, memory_r, memory_w) +ADDRESS_MAP_END + +static ADDRESS_MAP_START(mice2_io, AS_IO, 8, mice_state) + ADDRESS_MAP_UNMAP_HIGH + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x80, 0x80) AM_DEVREADWRITE("uart", i8251_device, data_r, data_w) + AM_RANGE(0x81, 0x81) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w) + AM_RANGE(0x90, 0x97) AM_DEVREADWRITE("rpt", i8155_device, io_r, io_w) + AM_RANGE(0xa0, 0xa3) AM_DEVREADWRITE("ppi", i8255_device, read, write) + AM_RANGE(0xc0, 0xc3) AM_DEVREADWRITE("rttppi1", i8255_device, read, write) + AM_RANGE(0xc8, 0xcb) AM_DEVREADWRITE("rttppi2", i8255_device, read, write) + AM_RANGE(0xd0, 0xd3) AM_DEVREADWRITE("rttppi3", i8255_device, read, write) + AM_RANGE(0xd8, 0xdb) AM_DEVREADWRITE("rttppi4", i8255_device, read, write) + AM_RANGE(0xe0, 0xe3) AM_DEVREADWRITE("rttppi5", i8255_device, read, write) + AM_RANGE(0xe8, 0xed) AM_DEVREADWRITE("rtt8155", i8155_device, io_r, io_w) +ADDRESS_MAP_END + /* Input ports */ static INPUT_PORTS_START( mice ) PORT_START("BAUD") @@ -80,7 +111,28 @@ static INPUT_PORTS_START( mice ) // "The number of stop bits is permanently set to one; and the communication is full duplex." (manual, p. 6) INPUT_PORTS_END -static DEVICE_INPUT_DEFAULTS_START( terminal ) +static INPUT_PORTS_START( micev3 ) + PORT_START("BAUD") + PORT_DIPNAME(0x07, 0x02, "Baud Rate") PORT_DIPLOCATION("U17:1,2,3") + PORT_DIPSETTING(0x06, "150") + PORT_DIPSETTING(0x05, "300") + PORT_DIPSETTING(0x04, "600") + PORT_DIPSETTING(0x03, "1200") + PORT_DIPSETTING(0x02, "2400") + PORT_DIPSETTING(0x01, "4800") + PORT_DIPSETTING(0x00, "9600") + PORT_DIPSETTING(0x07, "19200") // 110 baud on older firmware versions + PORT_DIPNAME(0x08, 0x00, "Data Bits") PORT_DIPLOCATION("U17:4") + PORT_DIPSETTING(0x00, "7") + PORT_DIPSETTING(0x08, "8") + PORT_DIPNAME(0x30, 0x30, "Parity") PORT_DIPLOCATION("U17:5,6") + PORT_DIPSETTING(0x00, DEF_STR(None)) + PORT_DIPSETTING(0x30, "Even") + PORT_DIPSETTING(0x10, "Odd") + // "The number of stop bits is permanently set at two; and the communication is full duplex." (manual, p. 2-7) +INPUT_PORTS_END + +static DEVICE_INPUT_DEFAULTS_START( mice_terminal ) DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_2400 ) DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_2400 ) DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) @@ -89,6 +141,15 @@ static DEVICE_INPUT_DEFAULTS_START( terminal ) DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) DEVICE_INPUT_DEFAULTS_END +static DEVICE_INPUT_DEFAULTS_START( mice2_terminal ) + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_2400 ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_2400 ) + DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_2 ) +DEVICE_INPUT_DEFAULTS_END + static MACHINE_CONFIG_START( mice ) /* basic machine hardware */ @@ -107,7 +168,7 @@ static MACHINE_CONFIG_START( mice ) MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart", i8251_device, write_rxd)) MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart", i8251_device, write_dsr)) MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart", i8251_device, write_cts)) - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) + MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", mice_terminal) MCFG_DEVICE_ADD("rpt", I8155, XTAL_6_144MHz / 2) MCFG_I8155_IN_PORTC_CB(IOPORT("BAUD")) @@ -117,30 +178,62 @@ static MACHINE_CONFIG_START( mice ) MCFG_DEVICE_ADD("ppi", I8255, 0) MACHINE_CONFIG_END -/* ROM definition */ -ROM_START( mice ) - ROM_REGION( 0x10000, "mice2_z80b", 0 ) +static MACHINE_CONFIG_DERIVED( mice2, mice ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(mice2_mem) + MCFG_CPU_IO_MAP(mice2_io) + + MCFG_DEVICE_MODIFY("rs232") + MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", mice2_terminal) + + MCFG_DEVICE_ADD("rttppi1", I8255, 0) + MCFG_DEVICE_ADD("rttppi2", I8255, 0) + MCFG_DEVICE_ADD("rttppi3", I8255, 0) + MCFG_DEVICE_ADD("rttppi4", I8255, 0) + MCFG_DEVICE_ADD("rttppi5", I8255, 0) + MCFG_DEVICE_ADD("rtt8155", I8155, 0) +MACHINE_CONFIG_END + +/* ROM definitions */ +ROM_START( mice_6502 ) + ROM_REGION( 0x4000, "mcp", 0 ) + ROM_LOAD( "6502_u10_v.2.0", 0x2000, 0x1000, CRC(496c53a7) SHA1(f28cddef18ab3e0eca1fea125dd678a54817c9df) ) + ROM_LOAD( "6502_u11_v.2.0", 0x1000, 0x1000, CRC(8d655bd2) SHA1(94936553f1692ede0934e3c7b599f3ad6adb6aec) ) + ROM_LOAD( "6502_u12_v.2.0", 0x0000, 0x1000, CRC(cee810ee) SHA1(ab642cda73f4b3f715ddc2909ba2b48cbd474d4d) ) +ROM_END + +ROM_START( mice2_z80 ) + ROM_REGION( 0x8000, "cep", 0 ) ROM_LOAD( "z80_u2_v.3.0", 0x4000, 0x2000, CRC(992b1b53) SHA1(f7b66c49ab26a9f97b2e6ebe45d162daa66d8a67) ) ROM_LOAD( "z80_u3_v.3.0", 0x2000, 0x2000, CRC(48d0be9b) SHA1(602af21868b1b5e6d488706a831259d78fefad6f) ) ROM_LOAD( "z80_u4_v.3.0", 0x0000, 0x2000, CRC(4fe2d08d) SHA1(902b98357b8f2e61f68dd171478368a3ac47af6e) ) - ROM_REGION( 0x10000, "mice2_6502", 0 ) +ROM_END + +ROM_START( mice2_6502 ) + ROM_REGION( 0x8000, "cep", 0 ) ROM_LOAD( "6502_u1_v.3.2", 0x6000, 0x2000, CRC(0ba10943) SHA1(e7590e2c1d9d2b1ff8cca0f5da366650ea4d50e3) ) ROM_LOAD( "6502_u2_v.3.2", 0x4000, 0x2000, CRC(f3169423) SHA1(a588a2e1894f523cf11c34d036beadbfe5b10538) ) ROM_LOAD( "6502_u3_v.3.2", 0x2000, 0x2000, CRC(d5c77c3f) SHA1(71439735ed62db07bee713775ee2189120d1a1e7) ) ROM_LOAD( "6502_u4_v.3.2", 0x0000, 0x2000, CRC(6acfc3a1) SHA1(3572a4798873c21a247a43da8419e7b9a181c67d) ) - ROM_REGION( 0x10000, "mice2_8085", 0 ) +ROM_END + +ROM_START( mice2_8085 ) + ROM_REGION( 0x8000, "cep", 0 ) ROM_LOAD( "8085_u2_v.3.1", 0x4000, 0x2000, CRC(2fce00a5) SHA1(0611f928be663a9279781d9f496fc950fd4ee7e2) ) ROM_LOAD( "8085_u3_v.3.1", 0x2000, 0x2000, CRC(16ee3018) SHA1(9e215504bcea2c5ebfb7578ecf371eec45cbe5d7) ) ROM_LOAD( "8085_u4_v.3.1", 0x0000, 0x2000, CRC(5798f2b5) SHA1(e0fe9411394bded8a77bc6a0f71519aad7800125) ) - ROM_REGION( 0x10000, "mice2_6809", 0 ) +ROM_END + +ROM_START( mice2_6809 ) + ROM_REGION( 0x8000, "cep", 0 ) ROM_LOAD( "6809_u1_v.3.4", 0x0000, 0x8000, CRC(b94d043d) SHA1(822697485f064286155f2a66cdbdcb0bd66ddb8c) ) - ROM_REGION( 0x10000, "mice_6502", 0 ) - ROM_LOAD( "6502_u10_v.2.0", 0x2000, 0x1000, CRC(496c53a7) SHA1(f28cddef18ab3e0eca1fea125dd678a54817c9df) ) - ROM_LOAD( "6502_u11_v.2.0", 0x1000, 0x1000, CRC(8d655bd2) SHA1(94936553f1692ede0934e3c7b599f3ad6adb6aec) ) - ROM_LOAD( "6502_u12_v.2.0", 0x0000, 0x1000, CRC(cee810ee) SHA1(ab642cda73f4b3f715ddc2909ba2b48cbd474d4d) ) ROM_END /* Driver */ -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1981, mice, 0, 0, mice, mice, mice_state, 0, "Microtek International Inc", "Mice", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1981, mice_6502, 0, 0, mice, mice, mice_state, 0, "Microtek International", "MICE 6502 (Rev-A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) +COMP( 1984, mice2_z80, 0, 0, mice2, micev3, mice_state, 0, "Microtek International", "MICE-II Z80 (Rev-F)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) +COMP( 1987, mice2_6502, mice2_z80, 0, mice2, micev3, mice_state, 0, "Microtek International", "MICE-II 6502 (Rev-F)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) +COMP( 1987, mice2_8085, mice2_z80, 0, mice2, micev3, mice_state, 0, "Microtek International", "MICE-II 8085 (Rev-M)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) +COMP( 1987, mice2_6809, mice2_z80, 0, mice2, micev3, mice_state, 0, "Microtek International", "MICE-II 6809(E) (Rev-L)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) diff --git a/src/mame/drivers/micral.cpp b/src/mame/drivers/micral.cpp index c681b8b7bd4..8d7f448c906 100644 --- a/src/mame/drivers/micral.cpp +++ b/src/mame/drivers/micral.cpp @@ -2,31 +2,61 @@ // copyright-holders:Robbbert /******************************************************************************** - Bull (Originally R2E) Micral 80-22G - - 2015-10-01 Skeleton [Robbbert] - - http://www.ti99.com/exelvision/website/index.php?page=r2e-micral-8022-g - - This expensive, futuristic-looking design featured a motherboard and slots, - much like an ancient pc. The known chip complement is: - Z80A, 4MHz; 64KB RAM, 2KB BIOS ROM, 256x4 prom (7611); - CRT8002, TMS9937 (=CRT5037), 4KB video RAM, 256x4 prom (7611); - 2x 5.25 inch floppy drives, one ST506 5MB hard drive; - CDP6402 UART. Sound is a beeper. - The keyboard has a uPD780C (=Z80) and 1KB of ROM. - - The FDC and HDC are unknown. - No manuals, schematic or circuit description have been found. +Bull (Originally R2E) Micral 80-22G + +2015-10-01 Skeleton [Robbbert] + +http://www.ti99.com/exelvision/website/index.php?page=r2e-micral-8022-g + +This expensive, futuristic-looking design featured a motherboard and slots, +much like an ancient pc. The known chip complement is: +Z80A, 4MHz; 64KB RAM, 2KB BIOS ROM, 256x4 prom (7611); +CRT8002, TMS9937 (=CRT5037), 4KB video RAM, 256x4 prom (7611); +2x 5.25 inch floppy drives, one ST506 5MB hard drive; +CDP6402 UART. Sound is a beeper. +The keyboard has a uPD780C (=Z80) and 1KB of ROM. + +The FDC and HDC are unknown. +No manuals, schematic or circuit description have been found. + +Commands must be in uppercase. Reboot to exit each command. +Bx[,x]: ?? +Gxxxx : go (writes a jump @FFED then jumps to FFEB) +T : test +* : echo keystrokes +enter : ?? + +Using generic keyboard via the uart for now. It's unknown how the real keyboard +communicates with the main cpu. + +FFF8/9 are used for sending instructions to the screen. FFF9 is command/status, +and FFF8 is data. The codes 0-D seem to be for the CRT5037, but the results don't +make much sense. Code A0 is to write a byte to the current cursor position, and +B0 is to get the status. + +Screen needs: +- Scrolling +- Proper character generator +- To be properly understood +- According to the web, graphics are possible. A screenshot shows reverse video + exists. + +Other things... +- Beeper +- 2 floppy drives +- keyboard +- unknown ports *********************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" #include "video/tms9927.h" -#include "sound/beep.h" +//#include "sound/beep.h" #include "screen.h" #include "speaker.h" +#include "machine/ay31015.h" +#include "bus/rs232/rs232.h" class micral_state : public driver_device @@ -35,27 +65,98 @@ public: micral_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") - , m_beep(*this, "beeper") + //, m_beep(*this, "beeper") + , m_p_videoram(*this, "vram") + , m_p_chargen(*this, "chargen") + , m_uart(*this, "uart") + , m_crtc(*this, "crtc") { } DECLARE_DRIVER_INIT(micral); DECLARE_MACHINE_RESET(micral); - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + DECLARE_READ8_MEMBER(keyin_r); + DECLARE_READ8_MEMBER(status_r); + DECLARE_READ8_MEMBER(unk_r); + DECLARE_READ8_MEMBER(video_r); + DECLARE_WRITE8_MEMBER(video_w); + u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); private: + u16 s_curpos; + u8 s_command; + u8 s_data; required_device<cpu_device> m_maincpu; - required_device<beep_device> m_beep; + //required_device<beep_device> m_beep; + required_region_ptr<u8> m_p_videoram; + required_region_ptr<u8> m_p_chargen; + required_device<ay31015_device> m_uart; + required_device<crt5037_device> m_crtc; }; +READ8_MEMBER( micral_state::status_r ) +{ + return m_uart->get_output_pin(AY31015_DAV) | 4; +} + +READ8_MEMBER( micral_state::unk_r ) +{ + return 0x96; +} + +READ8_MEMBER( micral_state::keyin_r ) +{ + m_uart->set_input_pin(AY31015_RDAV, 0); + u8 result = m_uart->get_received_data(); + m_uart->set_input_pin(AY31015_RDAV, 1); + return result; +} + +READ8_MEMBER( micral_state::video_r ) +{ + if (offset) + return 0x07; + else + return m_p_videoram[s_curpos]; +} -static ADDRESS_MAP_START( micral_mem, AS_PROGRAM, 8, micral_state ) +WRITE8_MEMBER( micral_state::video_w ) +{ + if (offset) + { + s_command = data; + if (s_command == 0x0c) + s_curpos = (s_curpos & 0xff00) | s_data; + else + if (s_command == 0x0d) + s_curpos = (s_curpos & 0xff) | ((s_data & 0x1f) << 8); + else + if (s_command == 0xa0) + m_p_videoram[s_curpos] = s_data; + + //if (s_command < 0x10) + //m_crtc->write(space, s_command, s_data); + } + else + { + s_data = data; + } +} + + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, micral_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0xf7ff) AM_RAM AM_RANGE(0xf800, 0xfeff) AM_ROM - AM_RANGE(0xff00, 0xffff) AM_RAM // FFF0-F seems to be devices + AM_RANGE(0xff00, 0xffef) AM_RAM + AM_RANGE(0xfff6, 0xfff7) // AM_WRITENOP // unknown ports + AM_RANGE(0xfff8, 0xfff9) AM_READWRITE(video_r, video_w) + AM_RANGE(0xfffa, 0xfffa) AM_READ(keyin_r) + AM_RANGE(0xfffb, 0xfffb) AM_READ(unk_r) + AM_RANGE(0xfffc, 0xfffc) AM_READ(status_r) + AM_RANGE(0xfffd, 0xffff) // more unknown ports ADDRESS_MAP_END -static ADDRESS_MAP_START( micral_kbd_mem, AS_PROGRAM, 8, micral_state ) +static ADDRESS_MAP_START( mem_kbd, AS_PROGRAM, 8, micral_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x03ff) AM_ROM AM_RANGE(0x8000, 0x8000) AM_RAM // byte returned to main cpu after receiving irq @@ -75,7 +176,7 @@ static ADDRESS_MAP_START( micral_kbd_mem, AS_PROGRAM, 8, micral_state ) AM_RANGE(0xa000, 0xa000) AM_READ_PORT("X13") ADDRESS_MAP_END -static ADDRESS_MAP_START( micral_kbd_io, AS_IO, 8, micral_state ) +static ADDRESS_MAP_START( io_kbd, AS_IO, 8, micral_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x00) AM_READ_PORT("X14") ADDRESS_MAP_END @@ -200,34 +301,40 @@ static INPUT_PORTS_START( micral ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_CODE(KEYCODE_LCONTROL) // ?? INPUT_PORTS_END -uint32_t micral_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +uint32_t micral_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { -// for (int y = 0; y < 32*8; y++) -// { -// offs_t offset = (y / 8) * 128; - -// for (int sx = 0; sx < 64; sx++) -// { -// uint8_t code = m_video_ram[offset++]; -// uint8_t attr = m_video_ram[offset++]; - -// offs_t char_offs = ((code & 0x7f) << 3) | (y & 0x07); -// if (BIT(code, 7)) char_offs = ((code & 0x7f) << 3) | ((y >> 1) & 0x07); - -// uint8_t data = m_char_rom->base()[char_offs]; - -// rgb_t fg = m_palette->pen_color(attr & 0x07); -// rgb_t bg = m_palette->pen_color((attr >> 3) & 0x07); - -// for (int x = 0; x < 6; x++) -// { -// bitmap.pix32(y, (sx * 6) + x) = BIT(data, 7) ? fg : bg; - -// data <<= 1; -// } -// } -// } - + uint8_t y,ra,chr,gfx; + uint16_t sy=0,ma=0,x; + + for (y = 0; y < 24; y++) + { + for (ra = 0; ra < 10; ra++) + { + uint16_t *p = &bitmap.pix16(sy++); + + for (x = 0; x < 80; x++) + { + gfx = 0; + if (ra < 9) + { + chr = m_p_videoram[x+ma]; + gfx = m_p_chargen[(chr<<4) | ra ]; + if (((s_curpos & 0xff)==x) && ((s_curpos >> 8)==y)) + gfx ^= 0xff; + } + /* Display a scanline of a character */ + *p++ = BIT(gfx, 7); + *p++ = BIT(gfx, 6); + *p++ = BIT(gfx, 5); + *p++ = BIT(gfx, 4); + *p++ = BIT(gfx, 3); + *p++ = BIT(gfx, 2); + *p++ = BIT(gfx, 1); + *p++ = BIT(gfx, 0); + } + } + ma+=256; + } return 0; } @@ -245,16 +352,28 @@ MACHINE_RESET_MEMBER( micral_state, micral ) //membank("bankr0")->set_entry(0); // point at rom //membank("bankw0")->set_entry(0); // always write to ram m_maincpu->set_state_int(Z80_PC, 0xf800); + + // no idea if these are hard-coded, or programmable + m_uart->set_input_pin(AY31015_XR, 0); + m_uart->set_input_pin(AY31015_XR, 1); + m_uart->set_input_pin(AY31015_SWE, 0); + m_uart->set_input_pin(AY31015_NP, 1); + m_uart->set_input_pin(AY31015_TSB, 0); + m_uart->set_input_pin(AY31015_NB1, 1); + m_uart->set_input_pin(AY31015_NB2, 1); + m_uart->set_input_pin(AY31015_EPS, 1); + m_uart->set_input_pin(AY31015_CS, 1); + m_uart->set_input_pin(AY31015_CS, 0); } static MACHINE_CONFIG_START( micral ) // basic machine hardware MCFG_CPU_ADD( "maincpu", Z80, XTAL_4MHz ) - MCFG_CPU_PROGRAM_MAP(micral_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) // no i/o ports on main cpu MCFG_CPU_ADD( "keyboard", Z80, XTAL_1MHz ) // freq unknown - MCFG_CPU_PROGRAM_MAP(micral_kbd_mem) - MCFG_CPU_IO_MAP(micral_kbd_io) + MCFG_CPU_PROGRAM_MAP(mem_kbd) + MCFG_CPU_IO_MAP(io_kbd) MCFG_MACHINE_RESET_OVERRIDE(micral_state, micral) @@ -263,20 +382,28 @@ static MACHINE_CONFIG_START( micral ) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(250)) MCFG_SCREEN_UPDATE_DRIVER(micral_state, screen_update) - MCFG_SCREEN_SIZE(64*6, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0, 64*6-1, 0, 32*8-1) + MCFG_SCREEN_SIZE(640, 240) + MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 239) + MCFG_SCREEN_PALETTE("palette") MCFG_PALETTE_ADD_MONOCHROME("palette") //MCFG_GFXDECODE_ADD("gfxdecode", "palette", micral) - MCFG_DEVICE_ADD("crtc", CRT5037, XTAL_17_9712MHz/2) // xtal freq unknown - MCFG_TMS9927_CHAR_WIDTH(6) // unknown + MCFG_DEVICE_ADD("crtc", CRT5037, 4000000) // xtal freq unknown + MCFG_TMS9927_CHAR_WIDTH(8) // unknown //MCFG_TMS9927_VSYN_CALLBACK(DEVWRITELINE(TMS5501_TAG, tms5501_device, sens_w)) MCFG_VIDEO_SET_SCREEN("screen") /* sound hardware */ - MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("beeper", BEEP, 2000) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + //MCFG_SPEAKER_STANDARD_MONO("mono") + //MCFG_SOUND_ADD("beeper", BEEP, 2000) + //MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + + MCFG_DEVICE_ADD("uart", AY51013, 0) // CDP6402 + MCFG_AY51013_TX_CLOCK(153600) + MCFG_AY51013_RX_CLOCK(153600) + MCFG_AY51013_READ_SI_CB(DEVREADLINE("rs232", rs232_port_device, rxd_r)) + MCFG_AY51013_WRITE_SO_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "keyboard") MACHINE_CONFIG_END ROM_START( micral ) @@ -285,6 +412,12 @@ ROM_START( micral ) ROM_REGION( 0x400, "keyboard", 0 ) ROM_LOAD( "2010221.rom", 0x000, 0x400, CRC(65123378) SHA1(401f0a648b78bf1662a1cd2546e83ba8e3cb7a42) ) + + ROM_REGION( 0x2000, "vram", ROMREGION_ERASEFF ) + + // Using the chargen from 'c10' for now. + ROM_REGION( 0x2000, "chargen", 0 ) + ROM_LOAD( "c10_char.bin", 0x0000, 0x2000, BAD_DUMP CRC(cb530b6f) SHA1(95590bbb433db9c4317f535723b29516b9b9fcbf)) ROM_END /* Driver */ diff --git a/src/mame/drivers/micro20.cpp b/src/mame/drivers/micro20.cpp index 131ea4e5ec6..1b69cc61587 100644 --- a/src/mame/drivers/micro20.cpp +++ b/src/mame/drivers/micro20.cpp @@ -156,13 +156,13 @@ static MACHINE_CONFIG_START( micro20 ) MCFG_CPU_ADD(MAINCPU_TAG, M68020, XTAL_16_67MHz) MCFG_CPU_PROGRAM_MAP(micro20_map) - MCFG_MC68681_ADD(DUART_A_TAG, XTAL_3_6864MHz) + MCFG_DEVICE_ADD(DUART_A_TAG, MC68681, XTAL_3_6864MHz) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("rs232", rs232_port_device, write_txd)) MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") MCFG_RS232_RXD_HANDLER(DEVWRITELINE(DUART_A_TAG, mc68681_device, rx_a_w)) - MCFG_MC68681_ADD(DUART_B_TAG, XTAL_3_6864MHz) + MCFG_DEVICE_ADD(DUART_B_TAG, MC68681, XTAL_3_6864MHz) MCFG_WD1772_ADD(FDC_TAG, XTAL_16_67MHz / 2) diff --git a/src/mame/drivers/micro3d.cpp b/src/mame/drivers/micro3d.cpp index b2dc7d7ba21..1969a1b1b70 100644 --- a/src/mame/drivers/micro3d.cpp +++ b/src/mame/drivers/micro3d.cpp @@ -26,13 +26,15 @@ #include "emu.h" #include "includes/micro3d.h" #include "audio/micro3d.h" - #include "cpu/am29000/am29000.h" #include "cpu/m68000/m68000.h" #include "cpu/mcs51/mcs51.h" +#include "bus/rs232/rs232.h" +#include "machine/adc0844.h" #include "machine/mc68681.h" #include "machine/mc68901.h" #include "machine/nvram.h" +#include "machine/z80scc.h" #include "sound/ym2151.h" #include "screen.h" @@ -210,11 +212,11 @@ static ADDRESS_MAP_START( hostmem, AS_PROGRAM, 16, micro3d_state ) AM_RANGE(0x920000, 0x920001) AM_READ_PORT("INPUTS_C_D") AM_RANGE(0x940000, 0x940001) AM_READ_PORT("INPUTS_A_B") AM_RANGE(0x960000, 0x960001) AM_WRITE(micro3d_reset_w) - AM_RANGE(0x980000, 0x980001) AM_READWRITE(micro3d_adc_r, micro3d_adc_w) + AM_RANGE(0x980000, 0x980001) AM_DEVREADWRITE8("adc", adc0844_device, read, write, 0x00ff) AM_RANGE(0x9a0000, 0x9a0007) AM_DEVREADWRITE("vgb", tms34010_device, host_r, host_w) AM_RANGE(0x9c0000, 0x9c0001) AM_NOP /* Lamps */ - AM_RANGE(0x9e0000, 0x9e002f) AM_DEVREADWRITE8("mc68901", mc68901_device, read, write, 0xff00) - AM_RANGE(0xa00000, 0xa0003f) AM_DEVREADWRITE8("duart68681", mc68681_device, read, write, 0xff00) + AM_RANGE(0x9e0000, 0x9e002f) AM_DEVREADWRITE8("mfp", mc68901_device, read, write, 0xff00) + AM_RANGE(0xa00000, 0xa0003f) AM_DEVREADWRITE8("duart", mc68681_device, read, write, 0xff00) AM_RANGE(0xa20000, 0xa20001) AM_READ(micro3d_encoder_h_r) AM_RANGE(0xa40002, 0xa40003) AM_READ(micro3d_encoder_l_r) ADDRESS_MAP_END @@ -233,8 +235,8 @@ static ADDRESS_MAP_START( vgbmem, AS_PROGRAM, 16, micro3d_state ) AM_RANGE(0x00e00000, 0x00e0000f) AM_WRITE(micro3d_xfer3dk_w) AM_RANGE(0x02000000, 0x0200ffff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // clut AM_RANGE(0x02600000, 0x0260000f) AM_WRITE(micro3d_creg_w) - AM_RANGE(0x02c00000, 0x02c0003f) AM_READ(micro3d_ti_uart_r) - AM_RANGE(0x02e00000, 0x02e0003f) AM_WRITE(micro3d_ti_uart_w) + AM_RANGE(0x02c00000, 0x02c0003f) AM_READ8(vgb_uart_r, 0x00ff) + AM_RANGE(0x02e00000, 0x02e0003f) AM_WRITE8(vgb_uart_w, 0x00ff) AM_RANGE(0x03800000, 0x03dfffff) AM_ROM AM_REGION("tms_gfx", 0) AM_RANGE(0x03e00000, 0x03ffffff) AM_ROM AM_REGION("tms34010", 0) AM_RANGE(0xc0000000, 0xc00001ff) AM_DEVREADWRITE("vgb", tms34010_device, io_register_r, io_register_w) @@ -264,7 +266,7 @@ static ADDRESS_MAP_START( drmath_data, AS_DATA, 32, micro3d_state ) AM_RANGE(0x01400000, 0x01400003) AM_READWRITE(micro3d_pipe_r, micro3d_fifo_w) AM_RANGE(0x01600000, 0x01600003) AM_WRITE(drmath_intr2_ack) AM_RANGE(0x01800000, 0x01800003) AM_WRITE(micro3d_alt_fifo_w) - AM_RANGE(0x03fffff0, 0x03fffff7) AM_READWRITE(micro3d_scc_r, micro3d_scc_w) + AM_RANGE(0x03fffff0, 0x03fffff7) AM_DEVREADWRITE8("scc", z80scc_device, ba_cd_inv_r, ba_cd_inv_w, 0x000000ff) ADDRESS_MAP_END /************************************* @@ -301,6 +303,7 @@ static MACHINE_CONFIG_START( micro3d ) MCFG_CPU_ADD("vgb", TMS34010, XTAL_40MHz) MCFG_CPU_PROGRAM_MAP(vgbmem) + MCFG_VIDEO_SET_SCREEN("screen") MCFG_TMS340X0_HALT_ON_RESET(false) /* halt on reset */ MCFG_TMS340X0_PIXEL_CLOCK(XTAL_40MHz / 8) /* pixel clock */ MCFG_TMS340X0_PIXELS_PER_CLOCK(4) /* pixels per clock */ @@ -311,23 +314,34 @@ static MACHINE_CONFIG_START( micro3d ) MCFG_CPU_PROGRAM_MAP(drmath_prg) MCFG_CPU_DATA_MAP(drmath_data) + MCFG_SCC8530_ADD("scc", XTAL_32MHz / 2 / 2, 0, 0, 0, 0) + MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE("monitor_drmath", rs232_port_device, write_txd)) + + MCFG_RS232_PORT_ADD("monitor_drmath", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("scc", z80scc_device, rxb_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("scc", z80scc_device, dcdb_w)) MCFG_DEVCB_XOR(1) + MCFG_CPU_ADD("audiocpu", I8051, XTAL_11_0592MHz) MCFG_CPU_PROGRAM_MAP(soundmem_prg) MCFG_CPU_IO_MAP(soundmem_io) MCFG_MCS51_SERIAL_TX_CB(WRITE8(micro3d_state, data_from_i8031)) MCFG_MCS51_SERIAL_RX_CB(READ8(micro3d_state, data_to_i8031)) - MCFG_MC68681_ADD("duart68681", XTAL_3_6864MHz) + MCFG_DEVICE_ADD("duart", MC68681, XTAL_3_6864MHz) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(micro3d_state, duart_irq_handler)) + MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("monitor_host", rs232_port_device, write_txd)) MCFG_MC68681_B_TX_CALLBACK(WRITELINE(micro3d_state, duart_txb)) MCFG_MC68681_INPORT_CALLBACK(READ8(micro3d_state, duart_input_r)) MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(micro3d_state, duart_output_w)) - MCFG_DEVICE_ADD("mc68901", MC68901, 4000000) + MCFG_DEVICE_ADD("mfp", MC68901, 4000000) MCFG_MC68901_TIMER_CLOCK(4000000) MCFG_MC68901_RX_CLOCK(0) MCFG_MC68901_TX_CLOCK(0) MCFG_MC68901_OUT_IRQ_CB(INPUTLINE("maincpu", M68K_IRQ_4)) + //MCFG_MC68901_OUT_TAO_CB(DEVWRITELINE("mfp", mc68901_device, rc_w)) + //MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("mfp", mc68901_device, tc_w)) + MCFG_MC68901_OUT_TCO_CB(DEVWRITELINE("mfp", mc68901_device, tbi_w)) MCFG_NVRAM_ADD_0FILL("nvram") MCFG_QUANTUM_TIME(attotime::from_hz(3000)) @@ -340,6 +354,20 @@ static MACHINE_CONFIG_START( micro3d ) MCFG_SCREEN_UPDATE_DEVICE("vgb", tms34010_device, tms340x0_ind16) MCFG_SCREEN_PALETTE("palette") + MCFG_DEVICE_ADD("uart", MC2661, XTAL_40MHz / 8) // actually SCN2651 + MCFG_MC2661_TXD_HANDLER(DEVWRITELINE("monitor_vgb", rs232_port_device, write_txd)) + + MCFG_RS232_PORT_ADD("monitor_vgb", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart", mc2661_device, rx_w)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart", mc2661_device, dsr_w)) + + MCFG_RS232_PORT_ADD("monitor_host", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", mc68681_device, rx_a_w)) + + MCFG_ADC0844_ADD("adc") + MCFG_ADC0844_INTR_CB(DEVWRITELINE("mfp", mc68901_device, i3_w)) + MCFG_ADC0844_CH1_CB(IOPORT("THROTTLE")) + MCFG_ADC0844_CH2_CB(READ8(micro3d_state, adc_volume_r)) MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") @@ -360,6 +388,11 @@ static MACHINE_CONFIG_START( micro3d ) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MACHINE_CONFIG_END +MACHINE_CONFIG_DERIVED( botss11, micro3d ) + MCFG_DEVICE_MODIFY("adc") + MCFG_ADC0844_CH1_CB(NOOP) +MACHINE_CONFIG_END + /************************************* * @@ -648,5 +681,5 @@ ROM_END GAME( 1991, f15se, 0, micro3d, f15se, micro3d_state, micro3d, ROT0, "Microprose Games Inc.", "F-15 Strike Eagle (rev. 2.2 02/25/91)", MACHINE_IMPERFECT_SOUND ) GAME( 1991, f15se21, f15se, micro3d, f15se, micro3d_state, micro3d, ROT0, "Microprose Games Inc.", "F-15 Strike Eagle (rev. 2.1 02/04/91)", MACHINE_IMPERFECT_SOUND ) GAME( 1992, botss, 0, micro3d, botss, micro3d_state, botss, ROT0, "Microprose Games Inc.", "Battle of the Solar System (rev. 1.1a 7/23/92)", MACHINE_IMPERFECT_SOUND ) -GAME( 1992, botss11, botss, micro3d, botss11, micro3d_state, micro3d, ROT0, "Microprose Games Inc.", "Battle of the Solar System (rev. 1.1 3/24/92)", MACHINE_IMPERFECT_SOUND ) -GAME( 1992, tankbatl, 0, micro3d, tankbatl, micro3d_state, micro3d, ROT0, "Microprose Games Inc.", "Tank Battle (prototype rev. 4/21/92)", MACHINE_IMPERFECT_SOUND ) +GAME( 1992, botss11, botss, botss11, botss11, micro3d_state, micro3d, ROT0, "Microprose Games Inc.", "Battle of the Solar System (rev. 1.1 3/24/92)", MACHINE_IMPERFECT_SOUND ) +GAME( 1992, tankbatl, 0, botss11, tankbatl, micro3d_state, micro3d, ROT0, "Microprose Games Inc.", "Tank Battle (prototype rev. 4/21/92)", MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/drivers/microterm.cpp b/src/mame/drivers/microterm.cpp new file mode 100644 index 00000000000..12a3027600d --- /dev/null +++ b/src/mame/drivers/microterm.cpp @@ -0,0 +1,139 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +Skeleton driver for Micro-Term terminals. + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" +#include "machine/eepromser.h" +#include "machine/mc2661.h" +#include "machine/mc68681.h" +//#include "video/scn2674.h" +//#include "screen.h" + +class microterm_state : public driver_device +{ +public: + microterm_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + //, m_p_chargen(*this, "chargen") + { } + + DECLARE_READ8_MEMBER(c000_r); + +private: + required_device<cpu_device> m_maincpu; + //required_region_ptr<u8> m_p_chargen; +}; + +READ8_MEMBER(microterm_state::c000_r) +{ + return machine().rand() & 0x80; +} + +static ADDRESS_MAP_START( mt420_mem_map, AS_PROGRAM, 8, microterm_state ) + AM_RANGE(0x0000, 0x7fff) AM_ROM AM_REGION("maincpu", 0) + AM_RANGE(0xc000, 0xc000) AM_READ(c000_r) AM_WRITENOP + AM_RANGE(0xe000, 0xefff) AM_RAM + AM_RANGE(0xf000, 0xf7ff) AM_RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( mt420_io_map, AS_IO, 8, microterm_state ) + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0xe0, 0xef) AM_DEVREADWRITE("duart", scn2681_device, read, write) + AM_RANGE(0xf0, 0xf3) AM_DEVREADWRITE("asci", mc2661_device, read, write) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( mt5510_mem_map, AS_PROGRAM, 8, microterm_state ) + AM_RANGE(0x0000, 0x7fff) AM_ROM AM_REGION("maincpu", 0) AM_WRITENOP + AM_RANGE(0x8000, 0xbfff) AM_RAM + AM_RANGE(0xc000, 0xffff) AM_RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( mt5510_io_map, AS_IO, 8, microterm_state ) + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x60, 0x6f) AM_DEVREADWRITE("duart", scn2681_device, read, write) +ADDRESS_MAP_END + +static INPUT_PORTS_START( microterm ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( mt420 ) + MCFG_CPU_ADD("maincpu", Z80, 4'000'000) + MCFG_CPU_PROGRAM_MAP(mt420_mem_map) + MCFG_CPU_IO_MAP(mt420_io_map) + + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) // MC2681 + MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", 0)) + MCFG_MC68681_OUTPORT_CALLBACK(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, di_write)) MCFG_DEVCB_BIT(5) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, cs_write)) MCFG_DEVCB_BIT(4) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, clk_write)) MCFG_DEVCB_BIT(3) + + MCFG_DEVICE_ADD("asci", MC2661, XTAL_3_6864MHz) // SCN2641 + + MCFG_EEPROM_SERIAL_93C46_ADD("eeprom") + MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("duart", scn2681_device, ip6_w)) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_START( mt5510 ) + MCFG_CPU_ADD("maincpu", Z80, XTAL_6MHz) + MCFG_CPU_PROGRAM_MAP(mt5510_mem_map) + MCFG_CPU_IO_MAP(mt5510_io_map) + + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) + MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", 0)) + MCFG_MC68681_OUTPORT_CALLBACK(DEVWRITELINE("eeprom1", eeprom_serial_93cxx_device, di_write)) MCFG_DEVCB_BIT(6) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom2", eeprom_serial_93cxx_device, di_write)) MCFG_DEVCB_BIT(5) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom1", eeprom_serial_93cxx_device, cs_write)) MCFG_DEVCB_BIT(4) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom2", eeprom_serial_93cxx_device, cs_write)) MCFG_DEVCB_BIT(4) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom1", eeprom_serial_93cxx_device, clk_write)) MCFG_DEVCB_BIT(3) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom2", eeprom_serial_93cxx_device, clk_write)) MCFG_DEVCB_BIT(3) + + MCFG_EEPROM_SERIAL_93C46_ADD("eeprom1") + MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("duart", scn2681_device, ip6_w)) + + MCFG_EEPROM_SERIAL_93C46_ADD("eeprom2") + MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("duart", scn2681_device, ip5_w)) +MACHINE_CONFIG_END + + +/************************************************************************************************************** + +Micro-Term Model 420. +Chips: Z80, MC2681P, SCN2674, 2x CDM6264E3, TMM2016BP-12, SCN2641, NMC9345N. Undumped PAL10L8NC at U18 and PROM (N82S129N) at U41. +Crystals: 3.6864, 15.30072 (hard to read), 9.87768 + +***************************************************************************************************************/ + +ROM_START( mt420 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "1910_M.P._R1.9.u8", 0x0000, 0x8000, CRC(e79154e9) SHA1(7c3f22097b931986c921bf731de98a1d0536aec9) ) + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "mt420cg_rev2.1.u44", 0x0000, 0x0fe0, CRC(7950e485) SHA1(1f03525958464bbe861d2e78f07cc5264e17c0e8) ) // incomplete? +ROM_END + + + +/************************************************************************************************************** + +Micro-Term 5510. +Chips: Z80, SCN2681, S8842C4/SCX6244UNT, 4x CXK5864BP-70L, 2x NMC9346N +Crystals: 6.000, 3.68640, 45.8304 + +***************************************************************************************************************/ + +ROM_START( mt5510 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "2500_M.P._R1.9.u11", 0x00000, 0x10000, CRC(71f19a53) SHA1(91df26d46a93359cd033d7137f1676bcfa58223b) ) +ROM_END + + + + +COMP( 1986, mt420, 0, 0, mt420, microterm, microterm_state, 0, "Micro-Term", "Micro-Term 420", MACHINE_IS_SKELETON ) +COMP( 1988, mt5510, 0, 0, mt5510, microterm, microterm_state, 0, "Micro-Term", "Micro-Term 5510", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/midvunit.cpp b/src/mame/drivers/midvunit.cpp index aad1f2edb98..320530bb9c1 100644 --- a/src/mame/drivers/midvunit.cpp +++ b/src/mame/drivers/midvunit.cpp @@ -48,11 +48,8 @@ Known to exist but not dumped: void midvunit_state::machine_start() { - m_adc_ready_timer = timer_alloc(TIMER_ADC_READY); - save_item(NAME(m_cmos_protected)); save_item(NAME(m_control_data)); - save_item(NAME(m_adc_data)); save_item(NAME(m_adc_shift)); save_item(NAME(m_last_port0)); save_item(NAME(m_shifter_state)); @@ -126,30 +123,20 @@ READ32_MEMBER(midvunit_state::port0_r) * *************************************/ -READ32_MEMBER(midvunit_state::midvunit_adc_r) +READ32_MEMBER( midvunit_state::adc_r ) { if (!(m_control_data & 0x40)) - { - m_maincpu->set_input_line(3, CLEAR_LINE); - return m_adc_data << m_adc_shift; - } + return m_adc->read(space, 0) << m_adc_shift; else logerror("adc_r without enabling reads!\n"); + return 0xffffffff; } - -WRITE32_MEMBER(midvunit_state::midvunit_adc_w) +WRITE32_MEMBER( midvunit_state::adc_w ) { if (!(m_control_data & 0x20)) - { - int which = (data >> m_adc_shift) - 4; - if (which < 0 || which > 2) - logerror("adc_w: unexpected which = %02X\n", which + 4); - else - m_adc_data = m_adc_ports[which].read_safe(0); - m_adc_ready_timer->adjust(attotime::from_msec(1)); - } + m_adc->write(space, 0, data >> m_adc_shift); else logerror("adc_w without enabling writes!\n"); } @@ -608,7 +595,7 @@ static ADDRESS_MAP_START( midvunit_map, AS_PROGRAM, 32, midvunit_state ) // AM_RANGE(0x991050, 0x991050) AM_READONLY // seems to be another port AM_RANGE(0x991060, 0x991060) AM_READ(port0_r) AM_RANGE(0x992000, 0x992000) AM_READ_PORT("992000") - AM_RANGE(0x993000, 0x993000) AM_READWRITE(midvunit_adc_r, midvunit_adc_w) + AM_RANGE(0x993000, 0x993000) AM_READWRITE(adc_r, adc_w) AM_RANGE(0x994000, 0x994000) AM_WRITE(midvunit_control_w) AM_RANGE(0x995000, 0x995000) AM_READWRITE(midvunit_wheel_board_r, midvunit_wheel_board_w) AM_RANGE(0x995020, 0x995020) AM_WRITE(midvunit_cmos_protect_w) @@ -1161,6 +1148,11 @@ static MACHINE_CONFIG_START( midvcommon ) MCFG_SCREEN_UPDATE_DRIVER(midvunit_state, screen_update_midvunit) MCFG_SCREEN_PALETTE("palette") + MCFG_ADC0844_ADD("adc") + MCFG_ADC0844_INTR_CB(INPUTLINE("maincpu", 3)) + MCFG_ADC0844_CH1_CB(IOPORT("WHEEL")) + MCFG_ADC0844_CH2_CB(IOPORT("ACCEL")) + MCFG_ADC0844_CH3_CB(IOPORT("BRAKE")) MACHINE_CONFIG_END @@ -1201,6 +1193,8 @@ static MACHINE_CONFIG_DERIVED( midvplus, midvcommon ) MCFG_MIDWAY_IOASIC_UPPER(452) /* no alternates */ MCFG_MIDWAY_IOASIC_YEAR_OFFS(94) + MCFG_DEVICE_REMOVE("adc") + /* sound hardware */ MCFG_DEVICE_ADD("dcs", DCS2_AUDIO_2115, 0) MCFG_DCS2_AUDIO_DRAM_IN_MB(2) @@ -1927,9 +1921,6 @@ DRIVER_INIT_MEMBER(midvunit_state,wargods) { uint8_t default_nvram[256]; - /* initialize the subsystems */ - m_adc_shift = 16; - /* we need proper VRAM */ memset(default_nvram, 0xff, sizeof(default_nvram)); default_nvram[0x0e] = default_nvram[0x2e] = 0x67; diff --git a/src/mame/drivers/midxunit.cpp b/src/mame/drivers/midxunit.cpp index f63e779554c..9c914ad7469 100644 --- a/src/mame/drivers/midxunit.cpp +++ b/src/mame/drivers/midxunit.cpp @@ -88,6 +88,7 @@ There's a separate sound board also, but it wasn't available so is not documente #include "cpu/adsp2100/adsp2100.h" #include "cpu/tms34010/tms34010.h" +#include "machine/adc0844.h" #include "machine/nvram.h" #include "screen.h" @@ -109,10 +110,14 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 16, midxunit_state ) AM_RANGE(0x20000000, 0x20ffffff) AM_RAM AM_RANGE(0x40800000, 0x4fffffff) AM_WRITE(midxunit_unknown_w) AM_RANGE(0x60400000, 0x6040001f) AM_READWRITE(midxunit_status_r, midxunit_security_clock_w) - AM_RANGE(0x60c00000, 0x60c0007f) AM_READ(midxunit_io_r) + AM_RANGE(0x60c00000, 0x60c0001f) AM_READ_PORT("IN0") + AM_RANGE(0x60c00020, 0x60c0003f) AM_READ_PORT("IN1") + AM_RANGE(0x60c00040, 0x60c0005f) AM_READ_PORT("IN2") + AM_RANGE(0x60c00060, 0x60c0007f) AM_READ_PORT("DSW") AM_RANGE(0x60c00080, 0x60c000df) AM_WRITE(midxunit_io_w) AM_RANGE(0x60c000e0, 0x60c000ff) AM_READWRITE(midxunit_security_r, midxunit_security_w) - AM_RANGE(0x80800000, 0x8080001f) AM_READWRITE(midxunit_analog_r, midxunit_analog_select_w) + AM_RANGE(0x80800000, 0x8080000f) AM_DEVREADWRITE8("adc", adc0848_device, read, write, 0x00ff) + AM_RANGE(0x80800010, 0x8080001f) AM_NOP AM_RANGE(0x80c00000, 0x80c000ff) AM_READWRITE(midxunit_uart_r, midxunit_uart_w) AM_RANGE(0xa0440000, 0xa047ffff) AM_READWRITE(midxunit_cmos_r, midxunit_cmos_w) AM_SHARE("nvram") AM_RANGE(0xa0800000, 0xa08fffff) AM_READWRITE(midxunit_paletteram_r, midxunit_paletteram_w) AM_SHARE("palette") @@ -210,28 +215,22 @@ static INPUT_PORTS_START( revx ) PORT_DIPSETTING( 0x0000, DEF_STR( On )) PORT_START("AN0") - PORT_BIT( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(1) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(1) PORT_START("AN1") - PORT_BIT( 0x00ff, 0x0080, IPT_AD_STICK_Y ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_PLAYER(1) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_START("AN2") - PORT_BIT( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(2) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(2) PORT_START("AN3") - PORT_BIT( 0x00ff, 0x0080, IPT_AD_STICK_Y ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_PLAYER(2) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_PLAYER(2) PORT_START("AN4") - PORT_BIT( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(3) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_REVERSE PORT_PLAYER(3) PORT_START("AN5") - PORT_BIT( 0x00ff, 0x0080, IPT_AD_STICK_Y ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_PLAYER(3) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_PLAYER(3) INPUT_PORTS_END @@ -270,6 +269,15 @@ static MACHINE_CONFIG_START( midxunit ) /* serial prefixes 419, 420 */ MCFG_MIDWAY_SERIAL_PIC_UPPER(419); + MCFG_ADC0848_ADD("adc") + MCFG_ADC0848_INTR_CB(WRITELINE(midxunit_state, adc_int_w)) // ADC INT passed through PLSI1032 + MCFG_ADC0848_CH1_CB(IOPORT("AN0")) + MCFG_ADC0848_CH2_CB(IOPORT("AN1")) + MCFG_ADC0848_CH3_CB(IOPORT("AN2")) + MCFG_ADC0848_CH4_CB(IOPORT("AN3")) + MCFG_ADC0848_CH5_CB(IOPORT("AN4")) + MCFG_ADC0848_CH6_CB(IOPORT("AN5")) + /* sound hardware */ MCFG_DEVICE_ADD("dcs", DCS_AUDIO_2K_UART, 0) MACHINE_CONFIG_END diff --git a/src/mame/drivers/midyunit.cpp b/src/mame/drivers/midyunit.cpp index 2d3c1ab7560..54cf88821c5 100644 --- a/src/mame/drivers/midyunit.cpp +++ b/src/mame/drivers/midyunit.cpp @@ -964,20 +964,16 @@ static INPUT_PORTS_START( term2 ) PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("STICK0_X") - PORT_BIT( 0x00ff, 0x0080, IPT_AD_STICK_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_REVERSE PORT_PLAYER(1) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_REVERSE PORT_PLAYER(1) PORT_START("STICK0_Y") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_PLAYER(1) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("STICK1_X") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_REVERSE PORT_PLAYER(2) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("STICK1_Y") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(20) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_PLAYER(2) - PORT_BIT( 0xff00, IP_ACTIVE_LOW, IPT_UNUSED ) INPUT_PORTS_END @@ -1248,6 +1244,15 @@ static MACHINE_CONFIG_DERIVED( yunit_adpcm_6bit_faster, yunit_core ) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( term2, yunit_adpcm_6bit_faster ) + MCFG_ADC0844_ADD("adc") // U2 on Coil Lamp Driver Board (A-14915) + MCFG_ADC0844_CH1_CB(IOPORT("STICK0_X")) + MCFG_ADC0844_CH2_CB(IOPORT("STICK0_Y")) + MCFG_ADC0844_CH3_CB(IOPORT("STICK1_X")) + MCFG_ADC0844_CH4_CB(IOPORT("STICK1_Y")) +MACHINE_CONFIG_END + + static MACHINE_CONFIG_DERIVED( mkyawdim, yunit_core ) /* basic machine hardware */ @@ -3077,12 +3082,12 @@ GAME( 1991, shimpactp4, shimpact, yunit_cvsd_6bit_slow, shimpact, midyunit_stat GAME( 1991, strkforc, 0, yunit_cvsd_4bit_fast, strkforc, midyunit_state, strkforc, ROT0, "Midway", "Strike Force (rev 1 02/25/91)", MACHINE_SUPPORTS_SAVE ) -GAME( 1991, term2, 0, yunit_adpcm_6bit_faster, term2, midyunit_state, term2, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LA4 08/03/92)", MACHINE_SUPPORTS_SAVE ) -GAME( 1991, term2la3, term2, yunit_adpcm_6bit_faster, term2, midyunit_state, term2la3, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LA3 03/27/92)", MACHINE_SUPPORTS_SAVE ) -GAME( 1991, term2la2, term2, yunit_adpcm_6bit_faster, term2, midyunit_state, term2la2, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LA2 12/09/91)", MACHINE_SUPPORTS_SAVE ) -GAME( 1991, term2la1, term2, yunit_adpcm_6bit_faster, term2, midyunit_state, term2la1, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LA1 11/01/91)", MACHINE_SUPPORTS_SAVE ) -GAME( 1991, term2pa2, term2, yunit_adpcm_6bit_faster, term2, midyunit_state, term2la1, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (prototype, rev PA2 10/18/91)", MACHINE_SUPPORTS_SAVE ) -GAME( 1991, term2lg1, term2, yunit_adpcm_6bit_faster, term2, midyunit_state, term2la1, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LG1 11/04/91)", MACHINE_SUPPORTS_SAVE ) +GAME( 1991, term2, 0, term2, term2, midyunit_state, term2, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LA4 08/03/92)", MACHINE_SUPPORTS_SAVE ) +GAME( 1991, term2la3, term2, term2, term2, midyunit_state, term2la3, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LA3 03/27/92)", MACHINE_SUPPORTS_SAVE ) +GAME( 1991, term2la2, term2, term2, term2, midyunit_state, term2la2, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LA2 12/09/91)", MACHINE_SUPPORTS_SAVE ) +GAME( 1991, term2la1, term2, term2, term2, midyunit_state, term2la1, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LA1 11/01/91)", MACHINE_SUPPORTS_SAVE ) +GAME( 1991, term2pa2, term2, term2, term2, midyunit_state, term2la1, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (prototype, rev PA2 10/18/91)", MACHINE_SUPPORTS_SAVE ) +GAME( 1991, term2lg1, term2, term2, term2, midyunit_state, term2la1, ORIENTATION_FLIP_X, "Midway", "Terminator 2 - Judgment Day (rev LG1 11/04/91)", MACHINE_SUPPORTS_SAVE ) GAME( 1992, mkla4, mk, yunit_adpcm_6bit_fast, mkla4, midyunit_state, mkyunit, ROT0, "Midway", "Mortal Kombat (rev 4.0 09/28/92)", MACHINE_SUPPORTS_SAVE ) GAME( 1992, mkla3, mk, yunit_adpcm_6bit_fast, mkla4, midyunit_state, mkyunit, ROT0, "Midway", "Mortal Kombat (rev 3.0 08/31/92)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/mightyframe.cpp b/src/mame/drivers/mightyframe.cpp new file mode 100644 index 00000000000..3ade15fa65a --- /dev/null +++ b/src/mame/drivers/mightyframe.cpp @@ -0,0 +1,48 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-03 Skeleton + +Convergent Technologies 68k Mightyframe S80 + +Chips: CPU is a square MC68020RC12B. Also, 3x Z80SCC and 2 undumped proms labelled "7201087B"(@15D) and "7201089B"(@15F) + The only photo shows just a part of the board, the only crystal is a tiny tubular one next to a OKI M58321 chip. + +Manuals: http://mightyframe.blogspot.com.au/p/manuals.html + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/m68000/m68000.h" + +class mightyframe_state : public driver_device +{ +public: + mightyframe_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) +// , m_maincpu(*this, "maincpu") + { } + +private: +// required_device<cpu_device> m_maincpu; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 16, mightyframe_state ) + AM_RANGE(0x000000, 0x007fff) AM_ROM +ADDRESS_MAP_END + +static INPUT_PORTS_START( mightyframe ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( mightyframe ) + MCFG_CPU_ADD("maincpu", M68000, XTAL_16MHz) // no idea of clock + MCFG_CPU_PROGRAM_MAP(mem_map) +MACHINE_CONFIG_END + +ROM_START( mightyframe ) + ROM_REGION( 0x8000, "maincpu", 0 ) + ROM_LOAD( "72-01231.26c", 0x0000, 0x8000, CRC(41faf884) SHA1(d0c6f35394b4006bbe9a3f81b658ded37f41d86f) ) +ROM_END + +COMP( 1985?, mightyframe, 0, 0, mightyframe, mightyframe, mightyframe_state, 0, "Convergent Technologies", "Mightyframe", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/milwaukee.cpp b/src/mame/drivers/milwaukee.cpp new file mode 100644 index 00000000000..457e500f4ce --- /dev/null +++ b/src/mame/drivers/milwaukee.cpp @@ -0,0 +1,86 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-20 Skeleton + +Milwaukee Computer MC-1000 series (MC-1000/1100/1200/1300/1400) all the same except for disk options. + +Chips: SY6502, 2x 6821, 2x MC6850P, 6852, INS8253 +Other: 2x 7-position rotary "dips" to select baud rates on each 6850 (19.2K, 9600, 4800, 2400, 1200, 600, 300). + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/m6502/m6502.h" +#include "machine/6821pia.h" +#include "machine/6850acia.h" +#include "machine/pit8253.h" +#include "machine/mc6852.h" +#include "machine/clock.h" +#include "bus/rs232/rs232.h" + +class milwaukee_state : public driver_device +{ +public: + milwaukee_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + //, m_p_chargen(*this, "chargen") + { } + +private: + required_device<cpu_device> m_maincpu; + //required_region_ptr<u8> m_p_chargen; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, milwaukee_state ) + AM_RANGE(0x0000, 0xf7ff) AM_RAM + //AM_RANGE(0xf800, 0xf87f) expansion i/o + AM_RANGE(0xf880, 0xf881) AM_DEVREADWRITE("acia1", acia6850_device, read, write) // terminal + AM_RANGE(0xf882, 0xf883) AM_DEVREADWRITE("acia2", acia6850_device, read, write) // remote + AM_RANGE(0xf884, 0xf887) AM_DEVREADWRITE("pia1", pia6821_device, read, write) // centronics + AM_RANGE(0xf888, 0xf88b) AM_DEVREADWRITE("pit", pit8253_device, read, write) + AM_RANGE(0xf88c, 0xf88f) AM_DEVREADWRITE("pia2", pia6821_device, read, write) // disk controller + AM_RANGE(0xf890, 0xf891) AM_DEVREADWRITE("ssda", mc6852_device, read, write) + AM_RANGE(0xf898, 0xffff) AM_ROM AM_REGION("roms", 0x0098) +ADDRESS_MAP_END + +static INPUT_PORTS_START( milwaukee ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( milwaukee ) + MCFG_CPU_ADD("maincpu", M6502, XTAL_16MHz / 16) + MCFG_CPU_PROGRAM_MAP(mem_map) + + MCFG_DEVICE_ADD("pit", PIT8253, 0) + MCFG_PIT8253_CLK0(XTAL_16MHz / 16 / 4) // 250 kHz + MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pit", pit8253_device, write_gate0)) MCFG_DEVCB_INVERT + MCFG_PIT8253_CLK1(double(XTAL_16MHz) / 2 / 13 / 2048 / 5) // 60.09 Hz? + MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("pit", pit8253_device, write_clk2)) MCFG_DEVCB_INVERT + + MCFG_DEVICE_ADD("pia1", PIA6821, 0) + MCFG_DEVICE_ADD("pia2", PIA6821, 0) + MCFG_DEVICE_ADD("acia2", ACIA6850, 0) + MCFG_DEVICE_ADD("ssda", MC6852, 0) + + MCFG_DEVICE_ADD("acia_clock", CLOCK, XTAL_16MHz / 2 / 13 / 4) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("acia1", acia6850_device, write_txc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("acia1", acia6850_device, write_rxc)) + + MCFG_DEVICE_ADD("acia1", ACIA6850, 0) + MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia1", acia6850_device, write_rxd)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia1", acia6850_device, write_cts)) +MACHINE_CONFIG_END + +ROM_START( mc1200 ) + ROM_REGION( 0x0c00, "roms", 0 ) + ROM_LOAD( "mfm_6-29-82_10_sector.u15", 0x0000, 0x0800, CRC(40b0af66) SHA1(c988e1f90c9abb93171c4e40a6585ce9cc3fd495) ) + ROM_LOAD( "2758.u14", 0x0800, 0x0400, CRC(b20e2345) SHA1(da498cc0c746897a85d6f2d1a5bd70a726c1e4ef) ) // big white sticker, but nothing on it +ROM_END + +COMP( 1980, mc1200, 0, 0, milwaukee, milwaukee, milwaukee_state, 0, "Milwaukee Computers", "MC-1200", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/miniframe.cpp b/src/mame/drivers/miniframe.cpp index 965cddbcfad..93d39d9195d 100644 --- a/src/mame/drivers/miniframe.cpp +++ b/src/mame/drivers/miniframe.cpp @@ -230,7 +230,7 @@ static MACHINE_CONFIG_START( miniframe ) MCFG_DEVICE_ADD("ramrombank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(ramrombank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400000) // floppy diff --git a/src/mame/drivers/mits680b.cpp b/src/mame/drivers/mits680b.cpp index a05ed4fdd42..5799b966d92 100644 --- a/src/mame/drivers/mits680b.cpp +++ b/src/mame/drivers/mits680b.cpp @@ -47,11 +47,10 @@ READ8_MEMBER( mits680b_state::status_check_r ) } -static ADDRESS_MAP_START(mits680b_mem, AS_PROGRAM, 8, mits680b_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, mits680b_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x03ff) AM_RAM // 1024 bytes RAM - AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0xf001, 0xf001) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0xf000, 0xf001) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0xf002, 0xf002) AM_READ(status_check_r) AM_RANGE(0xff00, 0xffff) AM_ROM AM_REGION("roms", 0) ADDRESS_MAP_END @@ -64,7 +63,7 @@ INPUT_PORTS_END static MACHINE_CONFIG_START( mits680b ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M6800, XTAL_1MHz / 2) - MCFG_CPU_PROGRAM_MAP(mits680b_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) MCFG_DEVICE_ADD("uart_clock", CLOCK, 153600) MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("acia", acia6850_device, write_txc)) diff --git a/src/mame/drivers/mk14.cpp b/src/mame/drivers/mk14.cpp index bf7e7692b27..66b9d32920f 100644 --- a/src/mame/drivers/mk14.cpp +++ b/src/mame/drivers/mk14.cpp @@ -105,7 +105,7 @@ WRITE8_MEMBER( mk14_state::display_w ) } } -static ADDRESS_MAP_START(mk14_mem, AS_PROGRAM, 8, mk14_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, mk14_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0x0fff) AM_RANGE(0x000, 0x1ff) AM_MIRROR(0x600) AM_ROM // ROM @@ -193,7 +193,7 @@ static MACHINE_CONFIG_START( mk14 ) // IC1 1SP-8A/600 (8060) SC/MP Microprocessor MCFG_CPU_ADD("maincpu", INS8060, XTAL_4_433619MHz) MCFG_SCMP_CONFIG(WRITELINE(mk14_state, cass_w), NOOP, READLINE(mk14_state, cass_r), NOOP, READLINE(mk14_state, cass_r), NOOP) - MCFG_CPU_PROGRAM_MAP(mk14_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) /* video hardware */ MCFG_DEFAULT_LAYOUT(layout_mk14) diff --git a/src/mame/drivers/mmagic.cpp b/src/mame/drivers/mmagic.cpp index ccb0d8be365..b9830e4e728 100644 --- a/src/mame/drivers/mmagic.cpp +++ b/src/mame/drivers/mmagic.cpp @@ -49,6 +49,8 @@ #include "emu.h" #include "cpu/i8085/i8085.h" +#include "sound/samples.h" +#include "speaker.h" #include "screen.h" @@ -71,12 +73,14 @@ public: m_maincpu(*this, "maincpu"), m_screen(*this, "screen"), m_palette(*this, "palette"), + m_samples(*this,"samples"), m_vram(*this, "vram"), m_tiles(*this, "tiles"), m_colors(*this, "colors"), m_ball_x(0x00), m_ball_y(0x00), - m_color(0x00) + m_color(0x00), + m_audio(0x00) {} DECLARE_READ8_MEMBER(vblank_r); @@ -94,6 +98,7 @@ private: required_device<cpu_device> m_maincpu; required_device<screen_device> m_screen; required_device<palette_device> m_palette; + required_device<samples_device> m_samples; required_shared_ptr<uint8_t> m_vram; required_region_ptr<uint8_t> m_tiles; required_region_ptr<uint8_t> m_colors; @@ -101,6 +106,7 @@ private: uint8_t m_ball_x; uint8_t m_ball_y; uint8_t m_color; + uint8_t m_audio; }; @@ -245,10 +251,33 @@ uint32_t mmagic_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap // AUDIO EMULATION //************************************************************************** +static const char *const mmagic_sample_names[] = +{ + "*mmagic", + "4", + "3", + "5", + "2", + "2-2", + "6", + "6-2", + "1", + nullptr +}; + WRITE8_MEMBER( mmagic_state::audio_w ) { if (LOG_AUDIO) logerror("audio_w: %02x\n", data); + + data ^= 0xff; + if (data != m_audio) + { + if (BIT(data, 7)) + m_samples->start(0, m_audio & 7); + + m_audio = data; + } } @@ -262,6 +291,7 @@ void mmagic_state::machine_start() save_item(NAME(m_ball_x)); save_item(NAME(m_ball_y)); save_item(NAME(m_color)); + save_item(NAME(m_audio)); } @@ -271,7 +301,7 @@ void mmagic_state::machine_start() static MACHINE_CONFIG_START( mmagic ) // basic machine hardware - MCFG_CPU_ADD("maincpu", I8085A, XTAL_6_144MHz) // NEC D8085A + MCFG_CPU_ADD("maincpu", I8085A, XTAL_6_144MHz) // NEC D8085A MCFG_CPU_PROGRAM_MAP(mmagic_mem) MCFG_CPU_IO_MAP(mmagic_io) @@ -283,7 +313,12 @@ static MACHINE_CONFIG_START( mmagic ) MCFG_PALETTE_ADD_3BIT_RGB("palette") // sound hardware - // TODO: SN76477 + discrete sound + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("samples", SAMPLES, 0) + MCFG_SAMPLES_CHANNELS(1) + MCFG_SAMPLES_NAMES(mmagic_sample_names) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.5) + // TODO: replace samples with SN76477 + discrete sound MACHINE_CONFIG_END @@ -315,4 +350,4 @@ ROM_END //************************************************************************** // YEAR NAME PARENT MACHINE INPUT CLASS INIT ROT COMPANY FULLNAME FLAGS -GAME( 1979, mmagic, 0, mmagic, mmagic, mmagic_state, 0, ROT270, "Nintendo", "Monkey Magic", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND ) +GAME( 1979, mmagic, 0, mmagic, mmagic, mmagic_state, 0, ROT270, "Nintendo", "Monkey Magic", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/drivers/model2.cpp b/src/mame/drivers/model2.cpp index 924c5fea26a..87168015871 100644 --- a/src/mame/drivers/model2.cpp +++ b/src/mame/drivers/model2.cpp @@ -380,6 +380,24 @@ MACHINE_START_MEMBER(model2_state,model2) { m_copro_fifoin_data = make_unique_clear<uint32_t[]>(COPRO_FIFOIN_SIZE); m_copro_fifoout_data = make_unique_clear<uint32_t[]>(COPRO_FIFOOUT_SIZE); + + m_port_1c00004 = 1; + m_port_1c00006 = 2; + m_port_1c00010 = 0; + m_port_1c00012 = 1; + m_port_1c00014 = 2; +} + +MACHINE_START_MEMBER(model2_state,srallyc) +{ + m_copro_fifoin_data = make_unique_clear<uint32_t[]>(COPRO_FIFOIN_SIZE); + m_copro_fifoout_data = make_unique_clear<uint32_t[]>(COPRO_FIFOOUT_SIZE); + + m_port_1c00004 = 2; + m_port_1c00006 = 3; + m_port_1c00010 = 0; + m_port_1c00012 = 1; + m_port_1c00014 = 4; } MACHINE_RESET_MEMBER(model2_state,model2_common) @@ -526,30 +544,54 @@ WRITE32_MEMBER(model2_state::videoctl_w) COMBINE_DATA(&m_videocontrol); } -CUSTOM_INPUT_MEMBER(model2_state::_1c00000_r) +READ8_MEMBER(model2_state::model2_crx_in_r) { - uint32_t ret = m_in0->read(); + uint8_t input = 0xff; - if(m_ctrlmode == 0) + switch (offset) { - return ret; - } - else - { - ret &= ~0x0030; - return ret | 0x00d0 | (m_eeprom->do_read() << 5); + case 0x01: + input = m_in[0]->read(); + if (m_ctrlmode != 0) + input = (input & ~0x0030) | 0x00d0 | (m_eeprom->do_read() << 5); + break; + case 0x02: + input = m_in[m_port_1c00004]->read(); + break; + case 0x03: + input = m_in[m_port_1c00006]->read(); + break; + case 0x06: + // 2A-CRX only? + input = (m_screen->vblank() << 3) | 0xf7; + break; + case 0x08: + input = m_in[m_port_1c00010]->read(); + break; + case 0x09: + input = m_in[m_port_1c00012]->read(); + break; + case 0x0a: + input = m_in[m_port_1c00014]->read(); + break; + case 0x0c: + case 0x0d: + input = hotd_lightgun_r(space, offset - 0x0c); + break; + case 0x0e: + // these must be high + input &= ~0x1a; + break; + case 0x0f: + if (m_analog_channel < 4) + { + input = m_analog_ports[m_analog_channel].read_safe(0); + ++m_analog_channel; + } + break; } -} -CUSTOM_INPUT_MEMBER(model2_state::_1c0001c_r) -{ - uint32_t iptval = 0x00ff; - if(m_analog_channel < 4) - { - iptval = m_analog_ports[m_analog_channel].read_safe(0); - ++m_analog_channel; - } - return iptval; + return input; } /* PORT_DIPSETTING( 0x00, "0" ) // 0: neutral @@ -652,7 +694,7 @@ CUSTOM_INPUT_MEMBER(model2_state::srallyc_gearbox_r) CUSTOM_INPUT_MEMBER(model2_state::rchase2_devices_r) { - return 0xffff; + return 0xff; } WRITE32_MEMBER(model2_state::rchase2_devices_w) @@ -1116,9 +1158,9 @@ WRITE32_MEMBER(model2_state::geo_w) /*****************************************************************************/ -READ32_MEMBER(model2_state::hotd_lightgun_r) +READ8_MEMBER(model2_state::hotd_lightgun_r) { - uint16_t res = 0xffff; + uint8_t res = 0xff; if(m_lightgun_mux < 8) res = (m_lightgun_ports[m_lightgun_mux >> 1].read_safe(0) >> ((m_lightgun_mux & 1)*8)) & 0xff; @@ -1126,7 +1168,7 @@ READ32_MEMBER(model2_state::hotd_lightgun_r) { uint16_t p1x,p1y,p2x,p2y; - res = 0xfffc; + res = 0xfc; p1x = m_lightgun_ports[1].read_safe(0); p1y = m_lightgun_ports[0].read_safe(0); @@ -1142,7 +1184,10 @@ READ32_MEMBER(model2_state::hotd_lightgun_r) } /* upper bits are presumably related to lightgun latches */ - return 0x000c0000 | res; + if (offset == 1) + return 0x0c; + else + return res; } WRITE32_MEMBER(model2_state::hotd_lightgun_w) @@ -1547,6 +1592,22 @@ READ32_MEMBER(model2_state::model2o_fifoctrl_r) return 0xffffffff; } +READ8_MEMBER(model2_state::model2o_in_r) +{ + // TODO: original model 2 actually uses a separate board for inputs, which transmits them to dual-port RAM + switch (offset) + { + case 0x00: return m_steer.read_safe(0xff); + case 0x01: return m_accel.read_safe(0xff); + case 0x02: return m_brake.read_safe(0xff); + case 0x08: return m_in[0]->read(); + case 0x09: return m_in[1]->read(); + case 0x0a: return m_in[2]->read(); + case 0x0f: return (m_screen->vblank() << 3) | 0xf7; + default: return 0xff; + } +} + /* original Model 2 overrides */ static ADDRESS_MAP_START( model2o_mem, AS_PROGRAM, 32, model2_state ) AM_RANGE(0x00200000, 0x0021ffff) AM_RAM @@ -1565,14 +1626,10 @@ static ADDRESS_MAP_START( model2o_mem, AS_PROGRAM, 32, model2_state ) AM_RANGE(0x12400000, 0x125fffff) AM_RAM_WRITE(model2o_tex_w1) AM_MIRROR(0x200000) AM_SHARE("textureram1") // texture RAM 1 AM_RANGE(0x12800000, 0x1281ffff) AM_RAM_WRITE(model2o_luma_w) AM_SHARE("lumaram") // polygon "luma" RAM - AM_RANGE(0x01c00000, 0x01c00003) AM_READ_PORT("1c00000") - AM_RANGE(0x01c00004, 0x01c00007) AM_READ_PORT("1c00004") - AM_RANGE(0x01c00010, 0x01c00013) AM_READ_PORT("1c00010") - AM_RANGE(0x01c00014, 0x01c00017) AM_READ_PORT("1c00014") - AM_RANGE(0x01c0001c, 0x01c0001f) AM_READ_PORT("1c0001c") - AM_RANGE(0x01c00040, 0x01c00043) AM_READ(daytona_unk_r ) - AM_RANGE(0x01c00100, 0x01c0010f) AM_READ8(virtuacop_lightgun_r,0x00ff00ff) - AM_RANGE(0x01c00110, 0x01c00113) AM_READ8(virtuacop_lightgun_offscreen_r,0x00ff00ff) + AM_RANGE(0x01c00000, 0x01c0001f) AM_READ8(model2o_in_r, 0x00ff00ff) + AM_RANGE(0x01c00040, 0x01c00043) AM_READ(daytona_unk_r) + AM_RANGE(0x01c00100, 0x01c0010f) AM_READ8(virtuacop_lightgun_r, 0x00ff00ff) + AM_RANGE(0x01c00110, 0x01c00113) AM_READ8(virtuacop_lightgun_offscreen_r, 0x00ff00ff) AM_RANGE(0x01c00200, 0x01c002ff) AM_RAM AM_SHARE("backup2") AM_RANGE(0x01c80000, 0x01c80003) AM_READWRITE(model2_serial_r, model2_serial_w) @@ -1605,14 +1662,12 @@ static ADDRESS_MAP_START( model2a_crx_mem, AS_PROGRAM, 32, model2_state ) AM_RANGE(0x12400000, 0x125fffff) AM_RAM_WRITE(model2o_tex_w1) AM_MIRROR(0x200000) AM_SHARE("textureram1") // texture RAM 1 AM_RANGE(0x12800000, 0x1281ffff) AM_RAM_WRITE(model2o_luma_w) AM_SHARE("lumaram") // polygon "luma" RAM - AM_RANGE(0x01c00000, 0x01c00003) AM_READ_PORT("1c00000") AM_WRITE(ctrl0_w ) - AM_RANGE(0x01c00004, 0x01c00007) AM_READ_PORT("1c00004") - AM_RANGE(0x01c00008, 0x01c0000f) AM_READNOP AM_WRITENOP - AM_RANGE(0x01c0000c, 0x01c0000f) AM_READ_PORT("1c0000c") - AM_RANGE(0x01c00010, 0x01c00013) AM_READ_PORT("1c00010") AM_WRITENOP - AM_RANGE(0x01c00014, 0x01c00017) AM_READ_PORT("1c00014") AM_WRITE(hotd_lightgun_w) - AM_RANGE(0x01c00018, 0x01c0001b) AM_READ(hotd_lightgun_r) - AM_RANGE(0x01c0001c, 0x01c0001f) AM_READ_PORT("1c0001c") AM_WRITE(analog_2b_w ) + AM_RANGE(0x01c00000, 0x01c0001f) AM_READ8(model2_crx_in_r, 0x00ff00ff) + AM_RANGE(0x01c00000, 0x01c00003) AM_WRITE(ctrl0_w) + AM_RANGE(0x01c00008, 0x01c0000f) AM_WRITENOP + AM_RANGE(0x01c00010, 0x01c00013) AM_WRITENOP + AM_RANGE(0x01c00014, 0x01c00017) AM_WRITE(hotd_lightgun_w) + AM_RANGE(0x01c0001c, 0x01c0001f) AM_WRITE(analog_2b_w) AM_RANGE(0x01c00040, 0x01c00043) AM_WRITENOP AM_RANGE(0x01c80000, 0x01c80003) AM_READWRITE(model2_serial_r, model2_serial_w) @@ -1645,15 +1700,11 @@ static ADDRESS_MAP_START( model2b_crx_mem, AS_PROGRAM, 32, model2_state ) AM_RANGE(0x11400000, 0x1140ffff) AM_RAM AM_SHARE("lumaram") // polygon "luma" RAM (2b/2c) AM_RANGE(0x12800000, 0x1281ffff) AM_RAM AM_SHARE("lumaram") // polygon "luma" RAM - - AM_RANGE(0x01c00000, 0x01c00003) AM_READ_PORT("1c00000") AM_WRITE(ctrl0_w ) - AM_RANGE(0x01c00004, 0x01c00007) AM_READ_PORT("1c00004") - AM_RANGE(0x01c00008, 0x01c0000b) AM_READNOP AM_WRITENOP - AM_RANGE(0x01c0000c, 0x01c0000f) AM_READNOP - AM_RANGE(0x01c00010, 0x01c00013) AM_READ_PORT("1c00010") - AM_RANGE(0x01c00014, 0x01c00017) AM_READ_PORT("1c00014") AM_WRITE(hotd_lightgun_w) - AM_RANGE(0x01c00018, 0x01c0001b) AM_READ(hotd_lightgun_r) - AM_RANGE(0x01c0001c, 0x01c0001f) AM_READ_PORT("1c0001c") AM_WRITE(analog_2b_w ) + AM_RANGE(0x01c00000, 0x01c0001f) AM_READ8(model2_crx_in_r, 0x00ff00ff) + AM_RANGE(0x01c00000, 0x01c00003) AM_WRITE(ctrl0_w) + AM_RANGE(0x01c00008, 0x01c0000b) AM_WRITENOP + AM_RANGE(0x01c00014, 0x01c00017) AM_WRITE(hotd_lightgun_w) + AM_RANGE(0x01c0001c, 0x01c0001f) AM_WRITE(analog_2b_w) AM_RANGE(0x01c00040, 0x01c00043) AM_WRITENOP AM_RANGE(0x01c80000, 0x01c80003) AM_READWRITE(model2_serial_r, model2_serial_w) @@ -1677,12 +1728,10 @@ static ADDRESS_MAP_START( model2c_crx_mem, AS_PROGRAM, 32, model2_state ) AM_RANGE(0x11200000, 0x113fffff) AM_RAM AM_SHARE("textureram1") // texture RAM 1 (2b/2c) AM_RANGE(0x11400000, 0x1140ffff) AM_RAM AM_SHARE("lumaram") // polygon "luma" RAM (2b/2c) - AM_RANGE(0x01c00000, 0x01c00003) AM_READ_PORT("1c00000") AM_WRITE(ctrl0_w ) - AM_RANGE(0x01c00004, 0x01c00007) AM_READ_PORT("1c00004") - AM_RANGE(0x01c00010, 0x01c00013) AM_READ_PORT("1c00010") - AM_RANGE(0x01c00014, 0x01c00017) AM_READ_PORT("1c00014") AM_WRITE(hotd_lightgun_w) - AM_RANGE(0x01c00018, 0x01c0001b) AM_READ(hotd_lightgun_r) - AM_RANGE(0x01c0001c, 0x01c0001f) AM_READ_PORT("1c0001c") AM_WRITE(analog_2b_w ) + AM_RANGE(0x01c00000, 0x01c0001f) AM_READ8(model2_crx_in_r, 0x00ff00ff) + AM_RANGE(0x01c00000, 0x01c00003) AM_WRITE(ctrl0_w) + AM_RANGE(0x01c00014, 0x01c00017) AM_WRITE(hotd_lightgun_w) + AM_RANGE(0x01c0001c, 0x01c0001f) AM_WRITE(analog_2b_w) AM_RANGE(0x01c80000, 0x01c80003) AM_READWRITE(model2_serial_r, model2_serial_w ) AM_IMPORT_FROM(model2_base_mem) @@ -1691,521 +1740,306 @@ ADDRESS_MAP_END /* Input definitions */ #define MODEL2_PLAYER_INPUTS(_n_, _b1_, _b2_, _b3_, _b4_) \ - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_##_b1_ ) PORT_PLAYER(_n_) \ - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_##_b2_ ) PORT_PLAYER(_n_) \ - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_##_b3_ ) PORT_PLAYER(_n_) \ - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_##_b4_ ) PORT_PLAYER(_n_) \ - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(_n_) \ - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(_n_) \ - PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(_n_) \ - PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(_n_) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_##_b1_ ) PORT_PLAYER(_n_) \ + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_##_b2_ ) PORT_PLAYER(_n_) \ + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_##_b3_ ) PORT_PLAYER(_n_) \ + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_##_b4_ ) PORT_PLAYER(_n_) \ + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(_n_) \ + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(_n_) \ + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(_n_) \ + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(_n_) static INPUT_PORTS_START( model2 ) - PORT_START("1c00000") - PORT_BIT( 0x0000ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c00000_r, nullptr) - - PORT_START("1c00004") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - - PORT_START("1c0000c") - PORT_BIT( 0xfffffff7, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x00000008, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") - - PORT_START("1c00010") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN0") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - - PORT_START("1c00014") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c0001c") - PORT_BIT( 0x0000001a, IP_ACTIVE_HIGH, IPT_SPECIAL ) // these must be high - PORT_BIT( 0x0000ffe5, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c0001c_r, nullptr) - PORT_START("IN0") - PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_SERVICE_NO_TOGGLE( 0x0004, IP_ACTIVE_LOW ) - PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("1P Push Switch") PORT_CODE(KEYCODE_7) - PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("2P Push Switch") PORT_CODE(KEYCODE_8) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_START2) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_SERVICE) PORT_NAME("1P Push Switch") PORT_CODE(KEYCODE_7) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_SERVICE) PORT_NAME("2P Push Switch") PORT_CODE(KEYCODE_8) PORT_START("IN1") MODEL2_PLAYER_INPUTS(1, BUTTON1, BUTTON2, BUTTON3, BUTTON4) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("IN2") MODEL2_PLAYER_INPUTS(2, BUTTON1, BUTTON2, BUTTON3, BUTTON4) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) INPUT_PORTS_END static INPUT_PORTS_START( desert ) - PORT_START("1c00000") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "STEER") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "ACCEL") - - PORT_START("1c00004") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "BRAKE") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c00010") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN0") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - - PORT_START("1c00014") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c0001c") - PORT_BIT( 0xfff7ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x00080000, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") - PORT_START("IN0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) // VR 1 (Blue) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1) // VR 2 (Green) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1) // VR 3 (Red) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_PLAYER(1) // VR 1 (Blue) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_PLAYER(1) // VR 2 (Green) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_PLAYER(1) // VR 3 (Red) PORT_START("IN1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) // shift - PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) // machine gun - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) // cannon - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_PLAYER(1) // shift + PORT_BIT(0x0e, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) // machine gun + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(1) // cannon + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("IN2") MODEL2_PLAYER_INPUTS(2, BUTTON1, BUTTON2, BUTTON3, BUTTON4) PORT_START("STEER") - PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_START("ACCEL") - PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_PEDAL) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_START("BRAKE") - PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_PEDAL2) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) INPUT_PORTS_END static INPUT_PORTS_START( vcop ) - PORT_START("1c00000") - PORT_BIT( 0x0000ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c00004") - PORT_BIT( 0x0000ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c00010") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN0") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - - PORT_START("1c00014") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c0001c") - PORT_BIT( 0xfff7ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x00080000, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") - PORT_START("IN0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_START2) + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("IN1") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Trigger") - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Trigger") - PORT_BIT( 0xfffc, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) PORT_NAME("P1 Trigger") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) PORT_NAME("P2 Trigger") + PORT_BIT(0xfc, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("IN2") - PORT_BIT( 0xffff, IP_ACTIVE_LOW, IPT_UNUSED ) // <- one bit here enables "debug mode" + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNUSED) // <- one bit here enables "debug mode" PORT_START("P1_X") - PORT_BIT( 0x3ff, 0x200, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(1) + PORT_BIT(0x3ff, 0x200, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(1) PORT_START("P1_Y") - PORT_BIT( 0x3ff, 0x200, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(1) + PORT_BIT(0x3ff, 0x200, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(1) PORT_START("P2_X") - PORT_BIT( 0x3ff, 0x200, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(2) + PORT_BIT(0x3ff, 0x200, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(2) PORT_START("P2_Y") - PORT_BIT( 0x3ff, 0x200, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(2) + PORT_BIT(0x3ff, 0x200, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(2) INPUT_PORTS_END static INPUT_PORTS_START( daytona ) - PORT_START("1c00000") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "STEER") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "ACCEL") - - PORT_START("1c00004") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "BRAKE") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c00010") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN0") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - - PORT_START("1c00014") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c0001c") - PORT_BIT( 0xfff7ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x00080000, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") - - PORT_START("IN0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) // VR 1 (Red) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1) // VR 2 (Blue) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1) // VR 3 (Yellow) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_PLAYER(1) // VR 1 (Red) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_PLAYER(1) // VR 2 (Blue) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_PLAYER(1) // VR 3 (Yellow) PORT_START("IN1") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER(1) // VR 4 (Green) - PORT_BIT(0x0e, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) // shift 3 - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) // shift 4 - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON7) PORT_PLAYER(1) // VR 4 (Green) + PORT_BIT(0x0e, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) // shift 3 + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_PLAYER(1) // shift 4 + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_PLAYER(1) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_PLAYER(1) PORT_START("IN2") MODEL2_PLAYER_INPUTS(2, BUTTON1, BUTTON2, BUTTON3, BUTTON4) PORT_START("STEER") - PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_START("ACCEL") - PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_PEDAL) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_START("BRAKE") - PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_PEDAL2) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) INPUT_PORTS_END -static INPUT_PORTS_START( manxtt ) - PORT_START("1c00000") - PORT_BIT( 0x0000ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c00000_r, nullptr) - - PORT_START("1c00004") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN3") - - PORT_START("1c0000c") - PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c00010") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN0") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - - PORT_START("1c00014") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN4") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c0001c") - PORT_BIT( 0x0000001a, IP_ACTIVE_HIGH, IPT_SPECIAL ) // these must be high - PORT_BIT( 0x0000ffe5, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c0001c_r, nullptr) +static INPUT_PORTS_START( manxtt ) PORT_START("IN0") - PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_SERVICE_NO_TOGGLE( 0x0004, IP_ACTIVE_LOW ) - PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("P1 Start / VR") - PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_START1) PORT_NAME("P1 Start / VR") + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x00, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN1") - PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN2") - PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) // shift up in Manx TT, Punch in Motoraid - PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) // shift down in Manx TT, Kick in Motoraid - PORT_BIT(0xffcf, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) // shift up in Manx TT, Punch in Motoraid + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2) // shift down in Manx TT, Kick in Motoraid + PORT_BIT(0xcf, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN3") - PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN4") - PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("ANA0") // throttle - PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_PEDAL) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_START("ANA1") // brake - PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_PEDAL2) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_START("ANA2") // bank - PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_REVERSE + PORT_BIT(0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_REVERSE INPUT_PORTS_END static INPUT_PORTS_START( srallyc ) - PORT_START("1c00000") - PORT_BIT( 0x0000ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c00000_r, nullptr) - - PORT_START("1c00004") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN3") - - PORT_START("1c0000c") - PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c00010") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN0") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - - PORT_START("1c00014") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN4") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c0001c") - PORT_BIT( 0x0000001a, IP_ACTIVE_HIGH, IPT_SPECIAL ) // these must be high - PORT_BIT( 0x0000ffe5, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c0001c_r, nullptr) - PORT_START("IN0") - PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_SERVICE_NO_TOGGLE( 0x0004, IP_ACTIVE_LOW ) - PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1) PORT_NAME("VR") // VR - PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT(0x0090, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_PLAYER(1) PORT_NAME("VR") // VR + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x90, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("IN1") - PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN2") - PORT_BIT(0x0070, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,srallyc_gearbox_r, nullptr) - PORT_BIT(0x008f, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x70, IP_ACTIVE_HIGH, IPT_SPECIAL) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,srallyc_gearbox_r, nullptr) + PORT_BIT(0x8f, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("GEARS") // fake to handle gear bits - PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("GEAR N") - PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("GEAR 1") - PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("GEAR 2") - PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("GEAR 3") - PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_PLAYER(1) PORT_NAME("GEAR 4") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_PLAYER(1) PORT_NAME("GEAR N") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_PLAYER(1) PORT_NAME("GEAR 1") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_PLAYER(1) PORT_NAME("GEAR 2") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_PLAYER(1) PORT_NAME("GEAR 3") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_PLAYER(1) PORT_NAME("GEAR 4") PORT_START("IN3") - //PORT_BIT(0x00ff, 0x00, IPT_AD_STICK_Y ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_REVERSE PORT_NAME("Handle (Drive)") - PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + //PORT_BIT(0xff, 0x00, IPT_AD_STICK_Y) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_REVERSE PORT_NAME("Handle (Drive)") + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN4") - PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("ANA0") // steer - PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_START("ANA1") // accel - PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_PEDAL) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) PORT_START("ANA2") // brake - PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_PEDAL2) PORT_SENSITIVITY(30) PORT_KEYDELTA(10) PORT_PLAYER(1) INPUT_PORTS_END static INPUT_PORTS_START( vcop2 ) - PORT_START("1c00000") - PORT_BIT( 0x0000ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c00000_r, nullptr) - - PORT_START("1c00004") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN3") - - PORT_START("1c0000c") - PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c00010") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN0") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - - PORT_START("1c00014") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN4") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c0001c") - PORT_BIT( 0x0000001a, IP_ACTIVE_HIGH, IPT_SPECIAL ) // these must be high - PORT_BIT( 0x0000ffe5, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c0001c_r, nullptr) - PORT_START("IN0") - PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_SERVICE_NO_TOGGLE( 0x0004, IP_ACTIVE_LOW ) - PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT(0x00c0, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_START2) + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("IN1") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Trigger") - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Trigger") - PORT_BIT( 0xfffc, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) PORT_NAME("P1 Trigger") + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) PORT_NAME("P2 Trigger") + PORT_BIT(0xfc, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("IN2") - PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN3") - PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN4") - PORT_BIT(0xffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0xff, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("P1_X") - PORT_BIT( 0x3ff, 0x200, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(1) + PORT_BIT(0x3ff, 0x200, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(1) PORT_START("P1_Y") - PORT_BIT( 0x3ff, 0x200, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(1) + PORT_BIT(0x3ff, 0x200, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(1) PORT_START("P2_X") - PORT_BIT( 0x3ff, 0x200, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(2) + PORT_BIT(0x3ff, 0x200, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(2) PORT_START("P2_Y") - PORT_BIT( 0x3ff, 0x200, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(2) + PORT_BIT(0x3ff, 0x200, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX( 0, 0x3ff ) PORT_SENSITIVITY( 50 ) PORT_KEYDELTA( 15 ) PORT_PLAYER(2) INPUT_PORTS_END static INPUT_PORTS_START( bel ) - PORT_START("1c00000") - PORT_BIT( 0x0000ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c00000_r, nullptr) - - PORT_START("1c00004") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - - PORT_START("1c00010") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN0") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - - PORT_START("1c00014") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c0001c") - PORT_BIT( 0x0000001a, IP_ACTIVE_HIGH, IPT_SPECIAL ) // these must be high - PORT_BIT( 0x0000ffe5, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c0001c_r, nullptr) - PORT_START("IN0") - PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_SERVICE_NO_TOGGLE( 0x0008, IP_ACTIVE_LOW ) - PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("1P Push Switch") PORT_CODE(KEYCODE_7) - PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("2P Push Switch") PORT_CODE(KEYCODE_8) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_SERVICE1) + PORT_SERVICE_NO_TOGGLE(0x08, IP_ACTIVE_LOW) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_START2) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_SERVICE) PORT_NAME("1P Push Switch") PORT_CODE(KEYCODE_7) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_SERVICE) PORT_NAME("2P Push Switch") PORT_CODE(KEYCODE_8) PORT_START("IN1") MODEL2_PLAYER_INPUTS(1, BUTTON1, BUTTON2, BUTTON3, BUTTON4) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("IN2") MODEL2_PLAYER_INPUTS(2, BUTTON1, BUTTON2, BUTTON3, BUTTON4) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) INPUT_PORTS_END static INPUT_PORTS_START( rchase2 ) - PORT_INCLUDE( model2 ) + PORT_INCLUDE(model2) PORT_MODIFY("IN1") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) // 1p shot - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) // 2p shot - PORT_BIT( 0xfffc, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(1) // 1p shot + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_PLAYER(2) // 2p shot + PORT_BIT(0xfc, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_MODIFY("IN2") - PORT_BIT( 0xffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,rchase2_devices_r, nullptr) + PORT_BIT(0xff, IP_ACTIVE_HIGH, IPT_SPECIAL) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,rchase2_devices_r, nullptr) /* FIXME: don't know yet if min max values are really correct, we'll see ... */ PORT_START("ANA0") - PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0x80,0x7f) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(2) + PORT_BIT(0xff, 0x00, IPT_AD_STICK_X) PORT_MINMAX(0x80,0x7f) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(2) PORT_START("ANA1") - PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_X ) PORT_MINMAX(0x80,0x7f) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_AD_STICK_X) PORT_MINMAX(0x80,0x7f) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(1) PORT_START("ANA2") - PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(2) + PORT_BIT(0xff, 0x00, IPT_AD_STICK_Y) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(2) PORT_START("ANA3") - PORT_BIT( 0x00ff, 0x0000, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(1) + PORT_BIT(0xff, 0x00, IPT_AD_STICK_Y) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_PLAYER(1) INPUT_PORTS_END static INPUT_PORTS_START( skytargt ) - PORT_START("1c00000") - PORT_BIT( 0x0000ffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c00000_r, nullptr) - - PORT_START("1c00004") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - - PORT_START("1c0000c") - PORT_BIT( 0xfffffff7, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x00000008, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") - - PORT_START("1c00010") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN0") - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN1") - - PORT_START("1c00014") - PORT_BIT( 0x0000ffff, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, driver_device,custom_port_read, "IN2") - PORT_BIT( 0xffff0000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("1c0001c") - PORT_BIT( 0x0000001a, IP_ACTIVE_HIGH, IPT_SPECIAL ) // these must be high - PORT_BIT( 0x0000ffe5, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0xffff0000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, model2_state,_1c0001c_r, nullptr) - PORT_START("IN0") - PORT_BIT(0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_SERVICE_NO_TOGGLE( 0x0004, IP_ACTIVE_LOW ) - PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_SERVICE1 ) - PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_COIN1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_COIN2) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_SERVICE1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNKNOWN) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNKNOWN) + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN1") - PORT_BIT(0x000f, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 Machine Gun") - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 Missile") - PORT_BIT(0x00c0, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT(0x0f, IP_ACTIVE_LOW, IPT_UNKNOWN) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("P1 Machine Gun") + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("P1 Missile") + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNKNOWN) PORT_START("IN2") MODEL2_PLAYER_INPUTS(2, BUTTON1, BUTTON2, BUTTON3, BUTTON4) - PORT_BIT(0xff00, IP_ACTIVE_LOW, IPT_UNKNOWN ) INPUT_PORTS_END @@ -2533,7 +2367,11 @@ static MACHINE_CONFIG_START( model2a ) MCFG_M2COMM_ADD("m2comm") MACHINE_CONFIG_END -static MACHINE_CONFIG_DERIVED( manxttdx, model2a ) /* Includes a Model 1 Sound board for additional sounds - Deluxe version only */ +static MACHINE_CONFIG_DERIVED( manxtt, model2a ) + MCFG_MACHINE_START_OVERRIDE(model2_state,srallyc) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( manxttdx, manxtt ) /* Includes a Model 1 Sound board for additional sounds - Deluxe version only */ MCFG_SEGAM1AUDIO_ADD("m1audio") MCFG_SEGAM1AUDIO_RXD_HANDLER(DEVWRITELINE("uart", i8251_device, write_rxd)) @@ -2558,6 +2396,7 @@ static MACHINE_CONFIG_DERIVED( model2a_0229, model2a ) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( srallyc, model2a ) + MCFG_MACHINE_START_OVERRIDE(model2_state,srallyc) MCFG_FRAGMENT_ADD(sj25_0207_01) MACHINE_CONFIG_END @@ -2634,6 +2473,10 @@ static MACHINE_CONFIG_DERIVED( model2b_0229, model2b ) // MCFG_SET_5838_READ_CALLBACK(model2_state, crypt_read_callback) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( indy500, model2b ) + MCFG_MACHINE_START_OVERRIDE(model2_state,srallyc) +MACHINE_CONFIG_END + static ADDRESS_MAP_START( rchase2_iocpu_map, AS_PROGRAM, 8, model2_state ) AM_RANGE(0x0000, 0x7fff) AM_ROM @@ -2727,6 +2570,10 @@ static MACHINE_CONFIG_DERIVED( model2c_5881, model2c ) MCFG_SET_READ_CALLBACK(model2_state, crypt_read_callback) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( overrev2c, model2c ) + MCFG_MACHINE_START_OVERRIDE(model2_state,srallyc) +MACHINE_CONFIG_END + /* ROM definitions */ @@ -5753,7 +5600,7 @@ ROM_START( daytonase ) /* Daytona USA (Japan, Revision A), Original Model 2 w/Mo ROM_LOAD("epr-16488a.ic12", 0x000000, 0x010000, CRC(546c5d1a) SHA1(5533301fe7e3b499e6cee12230d2c656c3c667da) ) ROM_END -ROM_START( daytona93 ) /* Daytona USA Deluxe '93 version (There is said to be a Deluxe '94 edition) */ +ROM_START( daytona93 ) /* Daytona USA (Deluxe cabinet, '93 version. There is said to be a Deluxe '94 edition) */ ROM_REGION( 0x200000, "maincpu", 0 ) // i960 program ROM_LOAD32_WORD("epr-16530a.12", 0x000000, 0x020000, CRC(39e962b5) SHA1(b98a1faabb4f1eff707a94c32224c7820f259874) ) ROM_LOAD32_WORD("epr-16531a.13", 0x000002, 0x020000, CRC(693126eb) SHA1(779734ba536db67e14760d52e8d8d7db07816481) ) @@ -6276,20 +6123,20 @@ DRIVER_INIT_MEMBER(model2_state,srallyc) // Model 2 (TGPs, Model 1 sound board) -GAME( 1993, daytona, 0, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1993, daytonase, daytona, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA Special Edition (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1993, daytona93, daytona, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA Deluxe '93", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1993, daytonas, daytona, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA (With Saturn Adverts)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1993, daytonat, daytona, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA (Japan, Turbo hack, set 1)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1993, daytonata, daytona, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA (Japan, Turbo hack, set 2)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1993, daytonam, daytona, daytona, daytona, model2_state, daytonam, ROT0, "Sega", "Daytona USA (Japan, To The MAXX)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1994, daytona, 0, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1994, daytonase, daytona, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA Special Edition (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1993, daytona93, daytona, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA (Japan)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1994, daytonas, daytona, daytona, daytona, model2_state, srallyc, ROT0, "Sega", "Daytona USA (With Saturn Adverts)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1994, daytonat, daytona, daytona, daytona, model2_state, srallyc, ROT0, "hack (Kyle Hodgetts)", "Daytona USA (Japan, Turbo hack, set 1)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1994, daytonata, daytona, daytona, daytona, model2_state, srallyc, ROT0, "hack (Kyle Hodgetts)", "Daytona USA (Japan, Turbo hack, set 2)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 2001, daytonam, daytona, daytona, daytona, model2_state, daytonam, ROT0, "hack (Kyle Hodgetts)", "Daytona USA (Japan, To The MAXX)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1994, desert, 0, model2o, desert, model2_state, 0, ROT0, "Sega / Martin Marietta", "Desert Tank", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1994, vcop, 0, model2o, vcop, model2_state, 0, ROT0, "Sega", "Virtua Cop (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1994, vcopa, vcop, model2o, vcop, model2_state, 0, ROT0, "Sega", "Virtua Cop (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) // Model 2A-CRX (TGPs, SCSP sound board) GAME( 1995, manxtt, 0, manxttdx, manxtt, model2_state, 0, ROT0, "Sega", "Manx TT Superbike - DX (Revision D)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1995, manxttc, 0, model2a, manxtt, model2_state, 0, ROT0, "Sega", "Manx TT Superbike - Twin (Revision C)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1995, manxttc, 0, manxtt, manxtt, model2_state, 0, ROT0, "Sega", "Manx TT Superbike - Twin (Revision C)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1995, srallyc, 0, srallyc, srallyc, model2_state, srallyc, ROT0, "Sega", "Sega Rally Championship - Twin/DX (Revision C)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1995, srallycb, srallyc, srallyc, srallyc, model2_state, srallyc, ROT0, "Sega", "Sega Rally Championship - Twin/DX (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1995, srallycdx, srallyc, srallyc, srallyc, model2_state, srallyc, ROT0, "Sega", "Sega Rally Championship - DX (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) @@ -6303,8 +6150,8 @@ GAME( 1995, skytargt, 0, model2a, skytargt, model2_state, 0, GAME( 1996, doaa, doa, model2a_0229, model2, model2_state, doa, ROT0, "Sega", "Dead or Alive (Model 2A, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1997, zeroguna, zerogun, model2a_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Export, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1997, zerogunaj, zerogun, model2a_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Japan, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1997, motoraid, 0, model2a, manxtt, model2_state, 0, ROT0, "Sega", "Motor Raid - Twin", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1997, motoraiddx,motoraid, model2a, manxtt, model2_state, 0, ROT0, "Sega", "Motor Raid - Twin/DX", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1997, motoraid, 0, manxtt, manxtt, model2_state, 0, ROT0, "Sega", "Motor Raid - Twin", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1997, motoraiddx,motoraid, manxtt, manxtt, model2_state, 0, ROT0, "Sega", "Motor Raid - Twin/DX", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1998, dynamcop, 0, model2a_5881, model2, model2_state, genprot, ROT0, "Sega", "Dynamite Cop (Export, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1998, dyndeka2, dynamcop, model2a_5881, model2, model2_state, genprot, ROT0, "Sega", "Dynamite Deka 2 (Japan, Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1998, pltkidsa, pltkids, model2a_5881, model2, model2_state, pltkids, ROT0, "Psikyo", "Pilot Kids (Model 2A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) @@ -6315,21 +6162,21 @@ GAME( 1994, vstrikero, vstriker, model2b, model2, model2_state, 0, GAME( 1995, fvipers, 0, model2b, model2, model2_state, 0, ROT0, "Sega", "Fighting Vipers (Revision D)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1995, fvipersb, fvipers, model2b, model2, model2_state, 0, ROT0, "Sega", "Fighting Vipers (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1995, gunblade, 0, model2b, model2, model2_state, 0, ROT0, "Sega", "Gunblade NY (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1995, indy500, 0, model2b, srallyc, model2_state, 0, ROT0, "Sega", "INDY 500 Twin (Revision A, Newer)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1995, indy500d, indy500, model2b, srallyc, model2_state, 0, ROT0, "Sega", "INDY 500 Deluxe (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1995, indy500to, indy500, model2b, srallyc, model2_state, 0, ROT0, "Sega", "INDY 500 Twin (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1995, indy500, 0, indy500, srallyc, model2_state, 0, ROT0, "Sega", "INDY 500 Twin (Revision A, Newer)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1995, indy500d, indy500, indy500, srallyc, model2_state, 0, ROT0, "Sega", "INDY 500 Deluxe (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1995, indy500to, indy500, indy500, srallyc, model2_state, 0, ROT0, "Sega", "INDY 500 Twin (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, schamp, 0, model2b, model2, model2_state, 0, ROT0, "Sega", "Sonic Championship (USA)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, sfight, schamp, model2b, model2, model2_state, 0, ROT0, "Sega", "Sonic the Fighters (Japan)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, lastbrnx, 0, model2b, model2, model2_state, 0, ROT0, "Sega", "Last Bronx (Export, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, lastbrnxu, lastbrnx, model2b, model2, model2_state, 0, ROT0, "Sega", "Last Bronx (USA, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, lastbrnxj, lastbrnx, model2b, model2, model2_state, 0, ROT0, "Sega", "Last Bronx (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, doa, 0, model2b_0229, model2, model2_state, doa, ROT0, "Sega", "Dead or Alive (Model 2B, Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1996, sgt24h, 0, model2b, srallyc, model2_state, sgt24h, ROT0, "Jaleco", "Super GT 24h", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1996, sgt24h, 0, indy500, srallyc, model2_state, sgt24h, ROT0, "Jaleco", "Super GT 24h", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, von, 0, model2b, model2, model2_state, 0, ROT0, "Sega", "Cyber Troopers Virtual-On (USA, Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, vonj, von, model2b, model2, model2_state, 0, ROT0, "Sega", "Cyber Troopers Virtual-On (Japan, Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, dynabb, 0, model2b, model2, model2_state, 0, ROT0, "Sega", "Dynamite Baseball", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1997, dynabb97, 0, model2b, model2, model2_state, 0, ROT0, "Sega", "Dynamite Baseball 97 (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1997, overrevb, overrev, model2b, srallyc, model2_state, 0, ROT0, "Jaleco", "Over Rev (Model 2B, Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1997, overrevb, overrev, indy500, srallyc, model2_state, 0, ROT0, "Jaleco", "Over Rev (Model 2B, Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1997, zerogun, 0, model2b_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Export, Model 2B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1997, zerogunj, zerogun, model2b_5881, model2, model2_state, zerogun, ROT0, "Psikyo", "Zero Gunner (Japan, Model 2B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1998, dynamcopb, dynamcop, model2b_5881, model2, model2_state, genprot, ROT0, "Sega", "Dynamite Cop (Export, Model 2B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) @@ -6343,8 +6190,8 @@ GAME( 1996, stcc, 0, stcc, model2, model2_state, 0, GAME( 1996, stccb, stcc, stcc, model2, model2_state, 0, ROT0, "Sega", "Sega Touring Car Championship (Revision B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, stcca, stcc, stcc, model2, model2_state, 0, ROT0, "Sega", "Sega Touring Car Championship (Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, waverunr, 0, model2c, model2, model2_state, 0, ROT0, "Sega", "Wave Runner (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1997, hotd, 0, model2c, model2, model2_state, 0, ROT0, "Sega", "The House of the Dead", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1997, overrev, 0, model2c, srallyc, model2_state, 0, ROT0, "Jaleco", "Over Rev (Model 2C, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1997, hotd, 0, model2c, vcop2, model2_state, 0, ROT0, "Sega", "The House of the Dead", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1997, overrev, 0, overrev2c, srallyc, model2_state, 0, ROT0, "Jaleco", "Over Rev (Model 2C, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1997, rascot2, 0, model2c, model2, model2_state, 0, ROT0, "Sega", "Royal Ascot II", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1997, segawski, 0, model2c, model2, model2_state, 0, ROT0, "Sega", "Sega Water Ski (Japan, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) GAME( 1997, topskatr, 0, model2c, model2, model2_state, 0, ROT0, "Sega", "Top Skater (Export, Revision A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_GRAPHICS ) diff --git a/src/mame/drivers/model3.cpp b/src/mame/drivers/model3.cpp index 48a1ad4007e..a8ab703beb1 100644 --- a/src/mame/drivers/model3.cpp +++ b/src/mame/drivers/model3.cpp @@ -1884,8 +1884,43 @@ static INPUT_PORTS_START( model3 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) PORT_START("IN3") - PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) + + PORT_START("DSW") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) /* Dip switches */ +INPUT_PORTS_END +static INPUT_PORTS_START( von2 ) + PORT_INCLUDE( common ) + + PORT_START("IN2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Left Lever Shot Trigger") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Left Lever Turbo Button") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_DOWN ) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_UP ) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_RIGHT ) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_LEFT ) PORT_8WAY + + PORT_START("IN3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Right Lever Shot Trigger") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Right Lever Turbo Button") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_DOWN ) PORT_8WAY + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_UP ) PORT_8WAY + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_RIGHT ) PORT_8WAY + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_LEFT ) PORT_8WAY + + // TODO: not here PORT_START("DSW") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) /* Dip switches */ INPUT_PORTS_END @@ -6404,9 +6439,9 @@ GAME( 1998, oceanhun, 0, model3_20_5881, model3, model3_state, oceanhun, GAME( 1998, skichamp, 0, model3_20, skichamp, model3_state, skichamp, ROT0, "Sega", "Ski Champ (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1998, srally2, 0, model3_20, scud, model3_state, srally2, ROT0, "Sega", "Sega Rally 2", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1998, srally2x, 0, model3_20, scud, model3_state, srally2, ROT0, "Sega", "Sega Rally 2 DX", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1998, von2, 0, model3_20_5881, model3, model3_state, von2, ROT0, "Sega", "Virtual On 2: Oratorio Tangram (Revision B)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1998, von2a, von2, model3_20_5881, model3, model3_state, von2, ROT0, "Sega", "Virtual On 2: Oratorio Tangram (Revision A)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1998, von254g, von2, model3_20_5881, model3, model3_state, von2, ROT0, "Sega", "Virtual On 2: Oratorio Tangram (ver 5.4g)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +GAME( 1998, von2, 0, model3_20_5881, von2, model3_state, von2, ROT0, "Sega", "Virtual On 2: Oratorio Tangram (Revision B)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +GAME( 1998, von2a, von2, model3_20_5881, von2, model3_state, von2, ROT0, "Sega", "Virtual On 2: Oratorio Tangram (Revision A)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +GAME( 1998, von254g, von2, model3_20_5881, von2, model3_state, von2, ROT0, "Sega", "Virtual On 2: Oratorio Tangram (ver 5.4g)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1998, fvipers2, 0, model3_20_5881, model3, model3_state, vs299, ROT0, "Sega", "Fighting Vipers 2 (Japan, Revision A)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1998, vs298, 0, model3_20_5881, model3, model3_state, vs298, ROT0, "Sega", "Virtua Striker 2 '98 (Step 2.0)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1999, vs2v991, 0, model3_20_5881, model3, model3_state, vs299, ROT0, "Sega", "Virtua Striker 2 '99.1 (Revision B)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) @@ -6423,7 +6458,7 @@ GAME( 1998, dirtdvlsj, dirtdvls, model3_21_5881, scud, model3_state, dirtdvl GAME( 1998, swtrilgy, 0, model3_21_5881, swtrilgy, model3_state, swtrilgy, ROT0, "Sega / LucasArts", "Star Wars Trilogy Arcade (Revision A)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1998, swtrilgya, swtrilgy, model3_21_5881, swtrilgy, model3_state, swtrilga, ROT0, "Sega / LucasArts", "Star Wars Trilogy Arcade", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1998, spikeout, 0, model3_21_5881, model3, model3_state, spikeout, ROT0, "Sega", "Spikeout (Revision C)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) -GAME( 1998, spikeofe, 0, model3_21_5881, model3, model3_state, spikeofe, ROT0, "Sega", "Spikeout Final Edition", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) +GAME( 1999, spikeofe, 0, model3_21_5881, model3, model3_state, spikeofe, ROT0, "Sega", "Spikeout Final Edition", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1998, magtruck, 0, model3_21_5881, eca, model3_state, magtruck, ROT0, "Sega", "Magical Truck Adventure (Japan)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1999, eca, 0, model3_21_5881, eca, model3_state, eca, ROT0, "Sega", "Emergency Call Ambulance (Export)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) GAME( 1999, ecau, eca, model3_21_5881, eca, model3_state, eca, ROT0, "Sega", "Emergency Call Ambulance (USA)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/drivers/modellot.cpp b/src/mame/drivers/modellot.cpp index c7f08e01522..be748b84b32 100644 --- a/src/mame/drivers/modellot.cpp +++ b/src/mame/drivers/modellot.cpp @@ -2,17 +2,39 @@ // copyright-holders:Miodrag Milanovic, Robbbert /********************************************************************************** - General Processor Modello T +General Processor Modello T - 2012-12-10 Skeleton driver. - 2013-09-27 Added keyboard and cursor. +2012-12-10 Skeleton driver. +2013-09-27 Added keyboard and cursor. - Made in Italy, a single board with numerous small daughter boards. - The 3 units (keyboard, disk drives, main unit) had wooden cabinets. - It had an inbuilt small green-screen CRT, like a Kaypro, and the RAM could - be 16, 32, or 48k. The FDC is a FD1791. +Made in Italy, a single board with numerous small daughter boards. +The 3 units (keyboard, disk drives, main unit) had wooden cabinets. +It had an inbuilt small green-screen CRT, like a Kaypro, and the RAM could +be 16, 32, or 48k. The FDC is a FD1791. - All the articles and doco (what there is of it) is all in Italian. +All the articles and doco (what there is of it) is all in Italian. + +Doco found... + +Port 77 out (cassette control): +- d0 = recording signal #1 +- d1 = relay #1 (0 = open) +- d2 = recording signal #2 +- d3 = relay #2 (0 = open) + +Port 77 in: +- d0 = free +- d1 = playback signal +- d2 = signal from the anti-glare circuit +- d3 = same as d2 + +Optional ports: +- 3c to 3f (FDC) +- 5c to 5f (PRT) +- 6c to 6f (US2) +- 78 to 7b (US1) +It's not clear if these are meant to be 3881 PIOs connected to the devices, or for +the devices themselves. An example shows a i8251 used as the US1 device. ***********************************************************************************/ @@ -30,8 +52,7 @@ public: , m_p_videoram(*this, "videoram") , m_maincpu(*this, "maincpu") , m_p_chargen(*this, "chargen") - { - } + { } DECLARE_READ8_MEMBER(port77_r); DECLARE_READ8_MEMBER(portff_r); @@ -46,14 +67,14 @@ private: required_region_ptr<u8> m_p_chargen; }; -static ADDRESS_MAP_START(modellot_mem, AS_PROGRAM, 8, modellot_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, modellot_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0xbfff) AM_RAM // 48k ram AM_RANGE(0xc000, 0xc3ff) AM_RAM AM_SHARE("videoram") AM_RANGE(0xe000, 0xffff) AM_ROM ADDRESS_MAP_END -static ADDRESS_MAP_START(modellot_io, AS_IO, 8, modellot_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, modellot_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x77, 0x77) AM_READ(port77_r) @@ -152,8 +173,8 @@ uint32_t modellot_state::screen_update_modellot(screen_device &screen, bitmap_in static MACHINE_CONFIG_START( modellot ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) - MCFG_CPU_PROGRAM_MAP(modellot_mem) - MCFG_CPU_IO_MAP(modellot_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) diff --git a/src/mame/drivers/moo.cpp b/src/mame/drivers/moo.cpp index 6e02c558fc1..a6e18d0b203 100644 --- a/src/mame/drivers/moo.cpp +++ b/src/mame/drivers/moo.cpp @@ -802,8 +802,8 @@ ROM_END ROM_START( buckyea ) /* Version EA */ ROM_REGION( 0x240000, "maincpu", 0 ) /* main program */ - ROM_LOAD16_BYTE( "2.d5", 0x000000, 0x40000, CRC(e18518a6) SHA1(6b0bac8080032b7528b47e802c2f6a5264da5f55) ) /* 27C2001 EA prototype? */ - ROM_LOAD16_BYTE( "3.d6", 0x000001, 0x40000, CRC(45ef9545) SHA1(370862e916410e7052e094033cc18ac727c75d8e) ) /* 27C2001 EA prototype? */ + ROM_LOAD16_BYTE( "2.d5", 0x000000, 0x40000, CRC(e18518a6) SHA1(6b0bac8080032b7528b47e802c2f6a5264da5f55) ) /* EA */ + ROM_LOAD16_BYTE( "3.d6", 0x000001, 0x40000, CRC(45ef9545) SHA1(370862e916410e7052e094033cc18ac727c75d8e) ) /* EA */ /* data */ ROM_LOAD16_BYTE( "173a03.t5", 0x200000, 0x20000, CRC(cd724026) SHA1(525445499604b713da4d8bc0a88e428654ceab95) ) @@ -838,8 +838,8 @@ ROM_END ROM_START( buckyjaa ) /* Version JA */ ROM_REGION( 0x240000, "maincpu", 0 ) /* main program */ - ROM_LOAD16_BYTE( "173_ja_a01.05", 0x000000, 0x040000, CRC(0a32bde7) SHA1(17b7654fd69eb1b82e2949ef324ce599113360aa) ) /* JAA */ - ROM_LOAD16_BYTE( "173_ja_a02.06", 0x000001, 0x040000, CRC(3e6f3955) SHA1(09ca39da8bdb37cb5517fe59cff5467c0623c380) ) /* JAA */ + ROM_LOAD16_BYTE( "173jaa01.05", 0x000000, 0x040000, CRC(0a32bde7) SHA1(17b7654fd69eb1b82e2949ef324ce599113360aa) ) /* JAA */ + ROM_LOAD16_BYTE( "173jaa02.06", 0x000001, 0x040000, CRC(3e6f3955) SHA1(09ca39da8bdb37cb5517fe59cff5467c0623c380) ) /* JAA */ /* data */ ROM_LOAD16_BYTE( "173a03.t5", 0x200000, 0x20000, CRC(cd724026) SHA1(525445499604b713da4d8bc0a88e428654ceab95) ) @@ -943,6 +943,42 @@ ROM_START( buckyaab ) /* Version AA */ ROM_LOAD( "buckyaab.nv", 0x0000, 0x080, CRC(6a5986f3) SHA1(3efddeed261b09031c582e12318f00c2cbb214ea) ) ROM_END +ROM_START( buckyaa ) /* Version AA */ + ROM_REGION( 0x240000, "maincpu", 0 ) + /* main program */ + ROM_LOAD16_BYTE( "173aa01.q4", 0x000000, 0x40000, CRC(e18518a6) SHA1(6b0bac8080032b7528b47e802c2f6a5264da5f55) ) /* AA */ + ROM_LOAD16_BYTE( "173aa02.q5", 0x000001, 0x40000, CRC(c888d0c7) SHA1(e11d270049ea8e2d9673224c990c8beecf7942be) ) /* AA */ + + /* data */ + ROM_LOAD16_BYTE( "173a03.t5", 0x200000, 0x20000, CRC(cd724026) SHA1(525445499604b713da4d8bc0a88e428654ceab95) ) + ROM_LOAD16_BYTE( "173a04.t6", 0x200001, 0x20000, CRC(7dd54d6f) SHA1(b0ee8ec445b92254bca881eefd4449972fed506a) ) + + ROM_REGION( 0x050000, "soundcpu", 0 ) + /* Z80 sound program */ + ROM_LOAD( "173a07.f5", 0x000000, 0x040000, CRC(4cdaee71) SHA1(bdc05d4475415f6fac65d7cdbc48df398e57845e) ) + ROM_RELOAD( 0x010000, 0x040000 ) + + ROM_REGION( 0x200000, "gfx1", 0 ) + /* tilemaps */ + ROM_LOAD32_WORD( "173a05.t8", 0x000000, 0x100000, CRC(d14333b4) SHA1(d1a15ead2d156e1fceca0bf202ab3962411caf11) ) + ROM_LOAD32_WORD( "173a06.t10", 0x000002, 0x100000, CRC(6541a34f) SHA1(15cf481498e3b7e0b2f7bfe5434121cc3bd65662) ) + + ROM_REGION( 0x800000, "gfx2", 0 ) + /* sprites */ + ROM_LOAD64_WORD( "173a10.b8", 0x000000, 0x200000, CRC(42fb0a0c) SHA1(d68c932cfabdec7896698b433525fe47ef4698d0) ) + ROM_LOAD64_WORD( "173a11.a8", 0x000002, 0x200000, CRC(b0d747c4) SHA1(0cf1ee1b9a35ded31a81c321df2a076f7b588971) ) + ROM_LOAD64_WORD( "173a12.b10", 0x000004, 0x200000, CRC(0fc2ad24) SHA1(6eda1043ee1266b8ba938a03a90bc7787210a936) ) + ROM_LOAD64_WORD( "173a13.a10", 0x000006, 0x200000, CRC(4cf85439) SHA1(8c298bf0e659a830a1830a1180f4ce71215ade45) ) + + ROM_REGION( 0x400000, "k054539", 0 ) + /* K054539 samples */ + ROM_LOAD( "173a08.b6", 0x000000, 0x200000, CRC(dcdded95) SHA1(8eeb546a0b60a35a6dce36c5ee872e6c93c577c9) ) + ROM_LOAD( "173a09.a6", 0x200000, 0x200000, CRC(c93697c4) SHA1(0528a604868267a30d281b822c187df118566691) ) + + ROM_REGION( 0x80, "eeprom", 0 ) // default eeprom to prevent game booting upside down with error + ROM_LOAD( "bucky.nv", 0x0000, 0x080, CRC(6a5986f3) SHA1(3efddeed261b09031c582e12318f00c2cbb214ea) ) +ROM_END + ROM_START( moomesabl ) ROM_REGION( 0x180000, "maincpu", 0 ) @@ -1009,3 +1045,4 @@ GAME( 1992, buckyea, bucky, bucky, bucky, moo_state, 0, ROT0, "Konami", GAME( 1992, buckyjaa, bucky, bucky, bucky, moo_state, 0, ROT0, "Konami", "Bucky O'Hare (ver JAA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1992, buckyuab, bucky, bucky, bucky, moo_state, 0, ROT0, "Konami", "Bucky O'Hare (ver UAB)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) GAME( 1992, buckyaab, bucky, bucky, bucky, moo_state, 0, ROT0, "Konami", "Bucky O'Hare (ver AAB)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +GAME( 1992, buckyaa, bucky, bucky, bucky, moo_state, 0, ROT0, "Konami", "Bucky O'Hare (ver AA)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/mpu4vid.cpp b/src/mame/drivers/mpu4vid.cpp index 0217f6ee6e8..81a3b3c14bf 100644 --- a/src/mame/drivers/mpu4vid.cpp +++ b/src/mame/drivers/mpu4vid.cpp @@ -1180,8 +1180,7 @@ static ADDRESS_MAP_START( mpu4_68k_map, AS_PROGRAM, 16, mpu4vid_state ) /* AM_RANGE(0xa00004, 0xa0000f) AM_READWRITE(mpu4_vid_unmap_r, mpu4_vid_unmap_w) */ AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, read, write,0x00ff) AM_RANGE(0xc00000, 0xc1ffff) AM_READWRITE(mpu4_vid_vidram_r, mpu4_vid_vidram_w) AM_SHARE("vid_vidram") - AM_RANGE(0xff8000, 0xff8001) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0xff8002, 0xff8003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0xff8000, 0xff8003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, read, write, 0x00ff) AM_RANGE(0xff9000, 0xff900f) AM_DEVREADWRITE8("6840ptm_68k", ptm6840_device, read, write, 0x00ff) AM_RANGE(0xffd000, 0xffd00f) AM_READWRITE8(vidcharacteriser_r, vidcharacteriser_w,0x00ff) ADDRESS_MAP_END @@ -1196,8 +1195,7 @@ static ADDRESS_MAP_START( mpu4oki_68k_map, AS_PROGRAM, 16, mpu4vid_state ) AM_RANGE(0xa00002, 0xa00003) AM_DEVWRITE8("ef9369", ef9369_device, address_w, 0x00ff) AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, read, write,0x00ff) AM_RANGE(0xc00000, 0xc1ffff) AM_READWRITE(mpu4_vid_vidram_r, mpu4_vid_vidram_w) AM_SHARE("vid_vidram") - AM_RANGE(0xff8000, 0xff8001) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0xff8002, 0xff8003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0xff8000, 0xff8003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, read, write, 0x00ff) AM_RANGE(0xff9000, 0xff900f) AM_DEVREADWRITE8("6840ptm_68k", ptm6840_device, read, write, 0x00ff) AM_RANGE(0xffa040, 0xffa04f) AM_DEVREAD8("ptm_ic3ss", ptm6840_device, read,0x00ff) // 6840PTM on sampled sound board AM_RANGE(0xffa040, 0xffa04f) AM_WRITE8(ic3ss_w,0x00ff) // 6840PTM on sampled sound board @@ -1217,8 +1215,7 @@ static ADDRESS_MAP_START( bwbvid_68k_map, AS_PROGRAM, 16, mpu4vid_state ) /* AM_RANGE(0xa00004, 0xa0000f) AM_READWRITE(mpu4_vid_unmap_r, mpu4_vid_unmap_w) */ AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, read, write,0x00ff) AM_RANGE(0xc00000, 0xc1ffff) AM_READWRITE(mpu4_vid_vidram_r, mpu4_vid_vidram_w) AM_SHARE("vid_vidram") - AM_RANGE(0xe00000, 0xe00001) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0xe00002, 0xe00003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0xe00000, 0xe00003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, read, write, 0x00ff) AM_RANGE(0xe01000, 0xe0100f) AM_DEVREADWRITE8("6840ptm_68k", ptm6840_device, read, write, 0x00ff) //AM_RANGE(0xa00004, 0xa0000f) AM_READWRITE(bwb_characteriser16_r, bwb_characteriser16_w)//AM_READWRITE(adpcm_r, adpcm_w) CHR ? ADDRESS_MAP_END @@ -1234,8 +1231,7 @@ static ADDRESS_MAP_START( bwbvid5_68k_map, AS_PROGRAM, 16, mpu4vid_state ) /* AM_RANGE(0xa00004, 0xa0000f) AM_READWRITE(mpu4_vid_unmap_r, mpu4_vid_unmap_w) */ AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, read, write,0x00ff) AM_RANGE(0xc00000, 0xc1ffff) AM_READWRITE(mpu4_vid_vidram_r, mpu4_vid_vidram_w) AM_SHARE("vid_vidram") - AM_RANGE(0xe00000, 0xe00001) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0xe00002, 0xe00003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0xe00000, 0xe00003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, read, write, 0x00ff) AM_RANGE(0xe01000, 0xe0100f) AM_DEVREADWRITE8("6840ptm_68k", ptm6840_device, read, write, 0x00ff) AM_RANGE(0xe02000, 0xe02007) AM_DEVREADWRITE8("pia_ic4ss", pia6821_device, read, write, 0xff00) //Seems odd... AM_RANGE(0xe03000, 0xe0300f) AM_DEVREAD8("ptm_ic3ss", ptm6840_device, read,0xff00) // 6840PTM on sampled sound board @@ -1246,8 +1242,7 @@ ADDRESS_MAP_END /* TODO: Fix up MPU4 map*/ static ADDRESS_MAP_START( mpu4_6809_map, AS_PROGRAM, 8, mpu4_state ) AM_RANGE(0x0000, 0x07ff) AM_RAM AM_SHARE("nvram") - AM_RANGE(0x0800, 0x0800) AM_DEVREADWRITE("acia6850_0", acia6850_device, status_r, control_w) - AM_RANGE(0x0801, 0x0801) AM_DEVREADWRITE("acia6850_0", acia6850_device, data_r, data_w) + AM_RANGE(0x0800, 0x0801) AM_DEVREADWRITE("acia6850_0", acia6850_device, read, write) AM_RANGE(0x0880, 0x0881) AM_NOP //Read/write here AM_RANGE(0x0900, 0x0907) AM_DEVREADWRITE("ptm_ic2", ptm6840_device, read, write) AM_RANGE(0x0a00, 0x0a03) AM_DEVREADWRITE("pia_ic3", pia6821_device, read, write) @@ -1281,7 +1276,8 @@ static MACHINE_CONFIG_START( mpu4_vid ) MCFG_GFXDECODE_ADD("gfxdecode", "palette", empty) - MCFG_SCN2674_VIDEO_ADD("scn2674_vid", 0, INPUTLINE("video", 3)) + MCFG_DEVICE_ADD("scn2674_vid", SCN2674, 0) + MCFG_SCN2674_INTR_CALLBACK(INPUTLINE("video", M68K_IRQ_3)) MCFG_SCN2674_TEXT_CHARACTER_WIDTH(8) MCFG_SCN2674_GFX_CHARACTER_WIDTH(8) MCFG_SCN2674_DRAW_CHARACTER_CALLBACK_OWNER(mpu4vid_state, display_pixels) diff --git a/src/mame/drivers/mquake.cpp b/src/mame/drivers/mquake.cpp index 4f9c087577b..c58c420aa0e 100644 --- a/src/mame/drivers/mquake.cpp +++ b/src/mame/drivers/mquake.cpp @@ -311,8 +311,8 @@ static MACHINE_CONFIG_START( mquake ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_512kb_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_NVRAM_ADD_0FILL("nvram") diff --git a/src/mame/drivers/ms9540.cpp b/src/mame/drivers/ms9540.cpp index 1f15b290f81..c9cf9871bf0 100644 --- a/src/mame/drivers/ms9540.cpp +++ b/src/mame/drivers/ms9540.cpp @@ -27,18 +27,16 @@ Chips: #include "cpu/m68000/m68000.h" #include "machine/terminal.h" -#define TERMINAL_TAG "terminal" class ms9540_state : public driver_device { public: ms9540_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_p_base(*this, "rambase"), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG) - { - } + : driver_device(mconfig, type, tag) + , m_p_base(*this, "rambase") + , m_maincpu(*this, "maincpu") + , m_terminal(*this, "terminal") + { } void kbd_put(u8 data); @@ -51,7 +49,7 @@ private: }; -static ADDRESS_MAP_START(ms9540_mem, AS_PROGRAM, 16, ms9540_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 16, ms9540_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xffffff) AM_RANGE(0x000000, 0x00ffff) AM_RAM AM_SHARE("rambase") @@ -80,10 +78,10 @@ void ms9540_state::kbd_put(u8 data) static MACHINE_CONFIG_START( ms9540 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M68000, 8000000) // unknown clock - MCFG_CPU_PROGRAM_MAP(ms9540_mem) + MCFG_CPU_PROGRAM_MAP(mem_map) /* video hardware */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) + MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(ms9540_state, kbd_put)) MACHINE_CONFIG_END diff --git a/src/mame/drivers/mstation.cpp b/src/mame/drivers/mstation.cpp index e0e4f67eb3f..c91fb7fefa4 100644 --- a/src/mame/drivers/mstation.cpp +++ b/src/mame/drivers/mstation.cpp @@ -470,13 +470,13 @@ static MACHINE_CONFIG_START( mstation ) MCFG_DEVICE_ADD("bank0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(mstation_banked_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("bank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(mstation_banked_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) /* internal ram */ diff --git a/src/mame/drivers/mtouchxl.cpp b/src/mame/drivers/mtouchxl.cpp index 42f22bd931c..e1fe37ad47e 100644 --- a/src/mame/drivers/mtouchxl.cpp +++ b/src/mame/drivers/mtouchxl.cpp @@ -242,7 +242,7 @@ static MACHINE_CONFIG_START( at486 ) MCFG_DEVICE_ADD("dbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(dbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) /* Flash ROM */ diff --git a/src/mame/drivers/mtx.cpp b/src/mame/drivers/mtx.cpp index 9b2c1870a63..7665567c963 100644 --- a/src/mame/drivers/mtx.cpp +++ b/src/mame/drivers/mtx.cpp @@ -15,7 +15,6 @@ - SDX/FDX floppy - HDX hard disk - HRX high resolution graphics - - CBM (all RAM) mode - "Silicon" disks - Multi Effect Video Wall @@ -48,11 +47,6 @@ -------------------------------------------------*/ static ADDRESS_MAP_START( mtx_mem, AS_PROGRAM, 8, mtx_state ) - AM_RANGE(0x0000, 0x1fff) AM_ROMBANK("bank1") - AM_RANGE(0x2000, 0x3fff) AM_ROMBANK("bank2") - AM_RANGE(0x4000, 0x7fff) AM_RAMBANK("bank3") - AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank4") - AM_RANGE(0xc000, 0xffff) AM_RAM ADDRESS_MAP_END /*------------------------------------------------- @@ -70,6 +64,7 @@ static ADDRESS_MAP_START( mtx_io, AS_IO, 8, mtx_state ) AM_RANGE(0x06, 0x06) AM_READWRITE(mtx_key_hi_r, mtx_sound_latch_w) // AM_RANGE(0x07, 0x07) PIO AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE(Z80CTC_TAG, z80ctc_device, read, write) + AM_RANGE(0x1f, 0x1f) AM_WRITE(mtx_cst_motor_w) AM_RANGE(0x30, 0x31) AM_WRITE(hrx_address_w) AM_RANGE(0x32, 0x32) AM_READWRITE(hrx_data_r, hrx_data_w) AM_RANGE(0x33, 0x33) AM_READWRITE(hrx_attr_r, hrx_attr_w) @@ -326,7 +321,7 @@ static MACHINE_CONFIG_START( mtx512 ) MCFG_SNAPSHOT_ADD("snapshot", mtx_state, mtx, "mtx", 1) MCFG_CASSETTE_ADD("cassette") - MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED) + MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED) MCFG_CASSETTE_INTERFACE("mtx_cass") MCFG_TIMER_DRIVER_ADD_PERIODIC("cassette_timer", mtx_state, cassette_tick, attotime::from_hz(44100)) @@ -334,9 +329,22 @@ static MACHINE_CONFIG_START( mtx512 ) /* internal ram */ MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("64K") - MCFG_RAM_EXTRA_OPTIONS("96K,128K,160K,192K,224K,256K,288K,320K,352K,384K,416K,448K,480K,512K") + MCFG_RAM_EXTRA_OPTIONS("96K,128K,192K,320K,448K,512K") + /* rom extension board */ + MCFG_GENERIC_SOCKET_ADD("extrom", generic_plain_slot, "mtx_rom") + MCFG_GENERIC_EXTENSIONS("bin,rom") + MCFG_GENERIC_LOAD(mtx_state, extrom_load) + + /* cartridge slot */ + MCFG_GENERIC_SOCKET_ADD("rompak", generic_plain_slot, "mtx_cart") + MCFG_GENERIC_EXTENSIONS("bin,rom") + MCFG_GENERIC_LOAD(mtx_state, rompak_load) + + /* software lists */ MCFG_SOFTWARE_LIST_ADD("cass_list", "mtx_cass") + MCFG_SOFTWARE_LIST_ADD("cart_list", "mtx_cart") + MCFG_SOFTWARE_LIST_ADD("rom_list", "mtx_rom") MACHINE_CONFIG_END /*------------------------------------------------- @@ -348,7 +356,7 @@ static MACHINE_CONFIG_DERIVED( mtx500, mtx512 ) /* internal ram */ MCFG_RAM_MODIFY(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("32K") - MCFG_RAM_EXTRA_OPTIONS("64K,96K,128K,160K,192K,224K,256K,288K,320K,352K,384K,416K,448K,480K,512K") + MCFG_RAM_EXTRA_OPTIONS("64K,96K,128K,160K,288K,416K") MACHINE_CONFIG_END /*------------------------------------------------- @@ -369,7 +377,7 @@ static MACHINE_CONFIG_DERIVED( rs128, mtx512 ) /* internal ram */ MCFG_RAM_MODIFY(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("128K") - MCFG_RAM_EXTRA_OPTIONS("160K,192K,224K,256K,288K,320K,352K,384K,416K,448K,480K,512K") + MCFG_RAM_EXTRA_OPTIONS("192K,320K,448K,512K") MACHINE_CONFIG_END /*************************************************************************** @@ -380,13 +388,19 @@ ROM_START( mtx512 ) ROM_REGION( 0x02000, "user1", 0 ) ROM_LOAD( "osrom", 0x0000, 0x2000, CRC(9ca858cc) SHA1(3804503a58f0bcdea96bb6488833782ebd03976d) ) - ROM_REGION( 0x10000, "user2", 0 ) + ROM_REGION( 0x10000, "user2", ROMREGION_ERASEFF ) ROM_LOAD( "basicrom", 0x0000, 0x2000, CRC(87b4e59c) SHA1(c49782a82a7f068c1195cd967882ba9edd546eaf) ) ROM_LOAD( "assemrom", 0x2000, 0x2000, CRC(9d7538c3) SHA1(d1882c4ea61a68b1715bd634ded5603e18a99c5f) ) - ROM_LOAD( "newword0", 0x4000, 0x2000, CRC(5433bd01) SHA1(56897f385476864337b7b994c1b46f50eaa57128) ) - ROM_LOAD( "newword1", 0x6000, 0x2000, CRC(10980c03) SHA1(8245c42fb1eda43b67fa483e50e4ee3bc5f3f29f) ) - ROM_LOAD( "newword2", 0x8000, 0x2000, CRC(cbff7130) SHA1(b4ab27def6020ba8e32959a1b988fce77bcc1d7f) ) - ROM_LOAD( "newword3", 0xa000, 0x2000, CRC(e6bbc33b) SHA1(26faa4a8d952c4659f610e94608b630456ab89aa) ) + + /* Keyboard ROMs are piggy-backed on top of the OS ROM, wired to be selected as ROM 7 */ + /* Country character sets documented in the Operators Manual are: + U.S.A, France, Germany, England, Denmark, Sweden, Italy, Spain */ + ROM_DEFAULT_BIOS("us") + ROM_SYSTEM_BIOS( 0, "us", "U.S.A." ) + ROM_SYSTEM_BIOS( 1, "dk", "Denmark" ) + ROMX_LOAD( "danish.rom", 0xe000, 0x2000, CRC(9c1b3fae) SHA1(82bc021660d88eebcf0c4d3856558ee9acc1c348), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 2, "fi", "Finland" ) + ROMX_LOAD( "finnish.rom", 0xe000, 0x2000, CRC(9b96cf72) SHA1(b46d1a733e0e635ccdaf4752cc370d793c3b5c55), ROM_BIOS(3) ) ROM_REGION( 0x2000, "sdx", 0 ) ROM_LOAD( "sdx", 0x0000, 0x2000, NO_DUMP ) diff --git a/src/mame/drivers/mvme147.cpp b/src/mame/drivers/mvme147.cpp index 2bdebc079b1..8421f2a169b 100644 --- a/src/mame/drivers/mvme147.cpp +++ b/src/mame/drivers/mvme147.cpp @@ -289,7 +289,7 @@ READ32_MEMBER (mvme147_state::bootvect_r){ WRITE32_MEMBER (mvme147_state::bootvect_w){ m_sysram[offset % sizeof(m_sysram)] &= ~mem_mask; m_sysram[offset % sizeof(m_sysram)] |= (data & mem_mask); - m_sysrom = &m_sysram[0]; // redirect all upcomming accesses to masking RAM until reset. + m_sysrom = &m_sysram[0]; // redirect all upcoming accesses to masking RAM until reset. } /**** diff --git a/src/mame/drivers/mx2178.cpp b/src/mame/drivers/mx2178.cpp index 5841311762e..29d4f11fdcb 100644 --- a/src/mame/drivers/mx2178.cpp +++ b/src/mame/drivers/mx2178.cpp @@ -23,9 +23,10 @@ TODO: ***************************************************************************************************/ #include "emu.h" -#include "bus/rs232/rs232.h" #include "cpu/z80/z80.h" +//#include "cpu/8x300/8x300.h" // device = N8X300 #include "machine/6850acia.h" +#include "bus/rs232/rs232.h" #include "machine/clock.h" #include "video/mc6845.h" #include "screen.h" @@ -47,7 +48,7 @@ public: private: virtual void machine_reset() override; required_device<palette_device> m_palette; - required_shared_ptr<uint8_t> m_p_videoram; + required_shared_ptr<u8> m_p_videoram; required_device<z80_device> m_maincpu; required_region_ptr<u8> m_p_chargen; }; @@ -64,10 +65,8 @@ static ADDRESS_MAP_START(mx2178_io, AS_IO, 8, mx2178_state) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x00) AM_DEVREADWRITE("crtc", mc6845_device, status_r, address_w) AM_RANGE(0x01, 0x01) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w) - AM_RANGE(0x80, 0x80) AM_DEVREADWRITE("acia1", acia6850_device, status_r, control_w) - AM_RANGE(0x81, 0x81) AM_DEVREADWRITE("acia1", acia6850_device, data_r, data_w) - AM_RANGE(0xa0, 0xa0) AM_DEVREADWRITE("acia2", acia6850_device, status_r, control_w) - AM_RANGE(0xa1, 0xa1) AM_DEVREADWRITE("acia2", acia6850_device, data_r, data_w) + AM_RANGE(0x80, 0x81) AM_DEVREADWRITE("acia1", acia6850_device, read, write) + AM_RANGE(0xa0, 0xa1) AM_DEVREADWRITE("acia2", acia6850_device, read, write) ADDRESS_MAP_END diff --git a/src/mame/drivers/mz2500.cpp b/src/mame/drivers/mz2500.cpp index 4f87e4ad09f..f3a3c8ce3ef 100644 --- a/src/mame/drivers/mz2500.cpp +++ b/src/mame/drivers/mz2500.cpp @@ -50,7 +50,7 @@ #include "machine/pit8253.h" #include "machine/rp5c15.h" #include "machine/wd_fdc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80pio.h" #include "sound/2203intf.h" #include "sound/beep.h" @@ -1511,7 +1511,7 @@ static ADDRESS_MAP_START(mz2500_io, AS_IO, 8, mz2500_state ) // AM_RANGE(0x60, 0x63) AM_WRITE(w3100a_w) // AM_RANGE(0x63, 0x63) AM_READ(w3100a_r) // AM_RANGE(0x98, 0x99) ADPCM, unknown type, custom? - AM_RANGE(0xa0, 0xa3) AM_DEVREADWRITE("z80sio",z80sio0_device, ba_cd_r, ba_cd_w) + AM_RANGE(0xa0, 0xa3) AM_DEVREADWRITE("z80sio", z80sio_device, ba_cd_r, ba_cd_w) // AM_RANGE(0xa4, 0xa5) AM_READWRITE(sasi_r, sasi_w) AM_RANGE(0xa8, 0xa8) AM_WRITE(mz2500_rom_w) AM_RANGE(0xa9, 0xa9) AM_READ(mz2500_rom_r) @@ -2097,7 +2097,7 @@ static MACHINE_CONFIG_START( mz2500 ) MCFG_Z80PIO_OUT_PA_CB(WRITE8(mz2500_state, mz2500_pio1_porta_w)) MCFG_Z80PIO_IN_PB_CB(READ8(mz2500_state, mz2500_pio1_porta_r)) - MCFG_DEVICE_ADD("z80sio", Z80SIO0, 6000000) + MCFG_DEVICE_ADD("z80sio", Z80SIO, 6000000) MCFG_DEVICE_ADD(RP5C15_TAG, RP5C15, XTAL_32_768kHz) MCFG_RP5C15_OUT_ALARM_CB(WRITELINE(mz2500_state, mz2500_rtc_alarm_irq)) diff --git a/src/mame/drivers/mz700.cpp b/src/mame/drivers/mz700.cpp index 197543a235f..70781085a1e 100644 --- a/src/mame/drivers/mz700.cpp +++ b/src/mame/drivers/mz700.cpp @@ -376,8 +376,8 @@ static MACHINE_CONFIG_START( mz700 ) MCFG_DEVICE_ADD("banke", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(mz700_banke) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_MACHINE_RESET_OVERRIDE(mz_state, mz700) @@ -442,8 +442,8 @@ static MACHINE_CONFIG_DERIVED( mz800, mz700 ) MCFG_DEVICE_ADD("bankf", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(mz800_bankf) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_MACHINE_RESET_OVERRIDE(mz_state, mz800) diff --git a/src/mame/drivers/namcofl.cpp b/src/mame/drivers/namcofl.cpp index 38fd137d8fd..a9a55657cca 100644 --- a/src/mame/drivers/namcofl.cpp +++ b/src/mame/drivers/namcofl.cpp @@ -809,7 +809,7 @@ DRIVER_INIT_MEMBER(namcofl_state,finalapr) m_gametype = NAMCOFL_FINAL_LAP_R; } -GAME ( 1995, speedrcr, 0, namcofl, speedrcr, namcofl_state, speedrcr, ROT0, "Namco", "Speed Racer", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -GAMEL( 1995, finalapr, 0, namcofl, finalapr, namcofl_state, finalapr, ROT0, "Namco", "Final Lap R (Rev. B)", MACHINE_SUPPORTS_SAVE, layout_namcofl ) -GAMEL( 1995, finalapro, finalapr, namcofl, finalapr, namcofl_state, finalapr, ROT0, "Namco", "Final Lap R", MACHINE_SUPPORTS_SAVE, layout_namcofl ) -GAMEL( 1995, finalaprj, finalapr, namcofl, finalapr, namcofl_state, finalapr, ROT0, "Namco", "Final Lap R (Japan Rev. C)", MACHINE_SUPPORTS_SAVE, layout_namcofl ) +GAME ( 1995, speedrcr, 0, namcofl, speedrcr, namcofl_state, speedrcr, ROT0, "Namco", "Speed Racer", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE ) +GAMEL( 1995, finalapr, 0, namcofl, finalapr, namcofl_state, finalapr, ROT0, "Namco", "Final Lap R (Rev. B)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_namcofl ) +GAMEL( 1995, finalapro, finalapr, namcofl, finalapr, namcofl_state, finalapr, ROT0, "Namco", "Final Lap R", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_namcofl ) +GAMEL( 1995, finalaprj, finalapr, namcofl, finalapr, namcofl_state, finalapr, ROT0, "Namco", "Final Lap R (Japan Rev. C)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE, layout_namcofl ) diff --git a/src/mame/drivers/namcond1.cpp b/src/mame/drivers/namcond1.cpp index b5b92a2a9f9..4931866af33 100644 --- a/src/mame/drivers/namcond1.cpp +++ b/src/mame/drivers/namcond1.cpp @@ -322,7 +322,7 @@ INTERRUPT_GEN_MEMBER(namcond1_state::mcu_interrupt) { if( m_h8_irq5_enabled ) { - generic_pulse_irq_line(device.execute(), 5, 1); + device.execute().pulse_input_line(5, device.execute().minimum_quantum_time()); } } diff --git a/src/mame/drivers/namcops2.cpp b/src/mame/drivers/namcops2.cpp index 7ef801edf75..2254dd4fc31 100644 --- a/src/mame/drivers/namcops2.cpp +++ b/src/mame/drivers/namcops2.cpp @@ -1312,6 +1312,9 @@ ROM_START( timecrs3 ) DISK_REGION("dvd") DISK_IMAGE_READONLY( "tst1dvd0", 0, SHA1(f8a447d9a4224282516bea590f5217c751bdc4ae) ) + + ROM_REGION(0x40000, "iocpu", 0) // NAMCO V291 I/O PCB, HD643334 H8/3334 MCU code + ROM_LOAD("tss-iopc.ic3", 0x000000, 0x040000, CRC(bb112fe0) SHA1(6fa5dc81d258137c1b1ad427d49d136d0bbf53fa) ) ROM_END ROM_START( timecrs3e ) @@ -1324,6 +1327,9 @@ ROM_START( timecrs3e ) DISK_REGION("dvd") DISK_IMAGE_READONLY( "tst1dvd0", 0, SHA1(f8a447d9a4224282516bea590f5217c751bdc4ae) ) + + ROM_REGION(0x40000, "iocpu", 0) // NAMCO V291 I/O PCB, HD643334 H8/3334 MCU code + ROM_LOAD("tss-iopc.ic3", 0x000000, 0x040000, CRC(bb112fe0) SHA1(6fa5dc81d258137c1b1ad427d49d136d0bbf53fa) ) ROM_END ROM_START( zgundmdx ) diff --git a/src/mame/drivers/namcos10.cpp b/src/mame/drivers/namcos10.cpp index cc8aea3fdf0..be218dfd3be 100644 --- a/src/mame/drivers/namcos10.cpp +++ b/src/mame/drivers/namcos10.cpp @@ -2,53 +2,56 @@ // copyright-holders:smf /*************************************************************************** - Namco System 10 - Arcade PSX Hardware - ===================================== - Driver by smf +Namco System 10 - Arcade PSX Hardware +===================================== +Driver by smf. Board notes by Guru -Namco System 10 Hardware Overview ---------------------------------- + +---------------------------------------- +Guru Readme for Namco System 10 Hardware +---------------------------------------- Note! This document is a Work-In-Progress and will be updated from time to time when more dumps are available. This document covers all the known Namco System 10 games, including.... -*Drum Master (C) Namco, 2001 -*Drum Master 2 (C) Namco, 2001 -*Drum Master 3 (C) Namco, 2002 -*Drum Master 4 (C) Namco, 2003 -*Drum Master 5 (C) Namco, 2003 -*Drum Master 6 (C) Namco, 2004 -*Drum Master 7 (C) Namco, 2005 -*GAHAHA Ippatsu-dou (C) Namco/Metro, 2000 -*GAHAHA Ippatsu-dou 2 (C) Namco/Metro, 2001 -Gamshara (10021 Ver.A) (C) Mitchell, 2003 -Gekitoride-Jong Space (10011 Ver.A) (C) Namco/Metro, 2001 -*Golgo-13 3 : Juusei no Chinkonka (C) Namco/8ing/Raizing, 2001 -*Hard Puncher Hajime no Ippo 2 Ouja e no Chousen (C) Namco/Taito, 2002 -*Honne Hakkenki (C) Namco, 2001 -Kotoba no Puzzle Mojipittan (KPM1 Ver.A) (C) Namco, 2001 -*Kurukuru Food (C) Namco, 2002 -Mr Driller 2 (DR21 Ver.A) (C) Namco, 2000 -Mr Driller 2 (DR22 Ver.A) (C) Namco, 2000 -Mr Driller G (DRG1 Ver.A) (C) Namco, 2001 -NFL Classic Football (NCF3 Ver.A) (C) Namco, 2003 - Has a noticeable red dot on the right of the version printed on PCB. Something to determine region? -Panicuru Panekuru (PPA1 Ver.A) (C) Namco, 2001 -*Photo Battole (C) Namco, 2001 -Point Blank 3 / Gunbalina (GNN2 Ver. A) (C) Namco, 2000 -*Ren-ai Quiz High School Angel (C) Namco, 2002 -*Seishun Quiz Colorful High School (C) Namco, 2002 -Star Trigon (STT1 Ver.A) (C) Namco, 2002 -*Taiko No Tatsujin (C) Namco, 2001 -*Taiko No Tatsujin 2 (C) Namco, 2001 -*Taiko No Tatsujin 3 (C) Namco, 2002 -*Taiko No Tatsujin 4 (C) Namco, 2003 -*Taiko No Tatsujin 5 (C) Namco, 2003 -*Taiko No Tatsujin 6 (C) Namco, 2004 -*Tsukkomi Yousei Gips Nice Tsukkomi (C) Namco/Metro, 2002 -Uchuu Daisakusen : Chocovader Contactee (CVC1 Ver.A) (C) Namco, 2002 +*Drum Master (C) Namco, 2001 +*Drum Master 2 (C) Namco, 2001 +*Drum Master 3 (C) Namco, 2002 +*Drum Master 4 (C) Namco, 2003 +*Drum Master 5 (C) Namco, 2003 +*Drum Master 6 (C) Namco, 2004 +*Drum Master 7 (C) Namco, 2005 +GAHAHA Ippatsu-dou (GID2 Ver.A) (C) Namco/Metro, 2000 +GAHAHA Ippatsu-dou 2 (GIS1 Ver.A) (C) Namco/Metro, 2001 +Gamshara (10021 Ver.A) (C) Mitchell, 2003 +Gekitoride-Jong Space (10011 Ver.A) (C) Namco/Metro, 2001 +Golgo 13 Juusei no Chinkonka (GLT1 Ver.A) (C) Namco/8ing/Raizing, 2001 +Gunbalina (GNN1 Ver. A) (C) Namco, 2000 +*Hard Puncher Hajime no Ippo 2 Ouja e no Chousen (C) Namco/Taito, 2002 +*Honne Hakkenki (C) Namco, 2001 +Kotoba no Puzzle Mojipittan (KPM1 Ver.A) (C) Namco, 2001 +*Kurukuru Food (C) Namco, 2002 +Mr Driller 2 (DR21 Ver.A) (C) Namco, 2000 +Mr Driller 2 (DR22 Ver.A) (C) Namco, 2000 +Mr Driller G (DRG1 Ver.A) (C) Namco, 2001 +NFL Classic Football (NCF3 Ver.A) (C) Namco, 2003 +Panicuru Panekuru (PPA1 Ver.A) (C) Namco, 2001 +*Photo Battle (C) Namco, 2001 +Point Blank 3 (GNN2 Ver. A) (C) Namco, 2000 +*Ren-ai Quiz High School Angel (C) Namco, 2002 +Seishun Quiz Colorful High School (CHS1 Ver.A) (C) Namco, 2002 +Star Trigon (STT1 Ver.A) (C) Namco, 2002 +*Taiko No Tatsujin (C) Namco, 2001 +Taiko No Tatsujin 2 (TK21 Ver.C) (C) Namco, 2001 +Taiko No Tatsujin 3 (TK31 Ver.A) (C) Namco, 2002 +Taiko No Tatsujin 4 (TK41 Ver.A) (C) Namco, 2003 +Taiko No Tatsujin 5 (TK51 Ver.A) (C) Namco, 2003 +Taiko No Tatsujin 6 (TK61 Ver.A) (C) Namco, 2004 +Tsukkomi Yousei Gips Nice Tsukkomi (NTK1 Ver.A) (C) Namco/Metro, 2002 +Uchuu Daisakusen Chocovader Contactee (CVC1 Ver.A) (C) Namco, 2002 * - denotes not dumped yet. -The Namco System 10 system comprises 2 PCB's.... +The Namco System 10 system comprises 2 or 3 PCB's.... MAIN PCB - This is the mother board PCB. It holds the main CPU/GPU & SPU and all sound circuitry, program & video RAM, controller/input logic and video output circuitry. Basically everything except the ROMs. There are three known revisions of this PCB so far. The differences seem very minor. The 2nd and 3rd revision @@ -59,8 +62,9 @@ MAIN PCB - This is the mother board PCB. It holds the main CPU/GPU & SPU and all Note there are no ROMs on the Main PCB and also no custom Namco chips on System10, which seem to have been phased out. Instead, they have been replaced by (custom programmed) CPLDs, probably due to cost-cutting measures within the company, or to reduce the cost of System10 to an entry-level no-frills development platform. -MEM PCB - There are two known revisions of this PCB (so far). They're mostly identical except for the type/number of ROMs - used and the contents of the CPLD. The 2nd revision also has a RAM chip on it. +MEM PCB - There are three known revisions of this PCB (so far). They're mostly identical except for the type/number of ROMs + used and the contents of the CPLD. The 2nd revision also has a RAM chip on it. The 3rd revision has some extra + hardware present to decode MP3 data. Each game has a multi-letter code assigned to it which is printed on a small sticker and placed on the top side of the MEM PCB. This code is then proceeded by a number (only '1' & '2' seen so far), then 'Ver.' then A/B/C/D/E (only 'A' seen so far) @@ -68,11 +72,18 @@ MEM PCB - There are two known revisions of this PCB (so far). They're mostly id test mode). The first 1 denotes a Japanese version. Other numbers denote a World version. For World versions, only the main program changes, the rest of the (graphics) ROMs use the Japanese version ROMs. + If the version sticker has a red dot it means nothing as several identical versions of the same games exist with and + without the red dot. A similar red dot has also been seen on Namco System 246 security carts and means nothing. + Speculation about a red dot on a sticker is pointless and has no impact on the dumps or the emulation. Any System 10 MEM PCB can be swapped to run on any System 10 Main PCB regardless of the main board revision. - The high scores are stored on the MEM PCB (probably inside the main program EEPROMs/FlashROMs or maybe the CPLD?). + The high scores are stored on the MEM PCB (probably inside the main program EEPROMs/FlashROMs). + There are no "alt" versions with the same code, this simply means the game was dumped without first resetting the + high score records and coinage/play statistics info to factory defaults. Also, on all System 10 games, there is a sticker with a serial number on it and the program ROMs also contain that same serial number. I'm not sure why, they're not exactly _easily_ tracable and no one cares either way ;-) - See the Main PCB and ROM Daughterboard PCB texts below for more details. +EXIO PCB - Optional I/O & Extra Controls PCB + + See the Main PCB, ROM Daughterboard PCB and Expansion PCB below for more details. Main PCB Layout @@ -90,7 +101,7 @@ SYSTEM10 MAIN PCB 8906962400 (8906972400) | LA4705 VR1 J201 | | |----------------------| | | NJM3414 |----------------------| | -|-| | +|-| J10 | | BA3121 | | NJM3414 54V25632 54V25632 J1| | CXD1178Q | @@ -122,7 +133,7 @@ Notes: ------ CXD8606BQ : SONY CXD8606BQ Central Processing Unit / GTE (QFP208) - replaced by CXD8606CQ on Revision 3 Main PCB - CXD8561CQ : SONY CXD8561CQ Graphics Processsor Unit (QFP208) + CXD8561CQ : SONY CXD8561CQ Graphics Processor Unit (QFP208) CXD2938Q : SONY CXD2938Q Sound Processor Unit (QFP208) CXD1178Q : SONY CXD1178Q 8-bit RGB 3-channel D/A converter (QFP48) CXA2067AS : SONY CXA2067AS TV/Video circuit RGB Pre-Driver (SDIP30) @@ -136,22 +147,18 @@ Notes: PQ30RV31 : Sharp PQ30RV31 5 Volt to 3.3 Volt Voltage Regulator LA4705 : LA4705 15W 2-channel Power Amplifier (SIP18) MAX734 : MAX734 +12V 120mA Flash Memory Programming Supply Switching Regulator (SOIC8) - PST592 : PST592J System Reset IC with 2.7V detection circuit (SOIC4) - BA3121 : Ground Isolation Amplifier/ Noise Eliminator (SOIC8) - NJM3414 : 70mA Dual Op Amp (x2, SOIC8) - DSW1 : 8 position dip switch - JP4 : 2 position jumper, set to NC, alt. position labelled SYNC (Note: changing the jumper position has - no visual effect) - J1 : 40 Pin IDC connector for plugging of a flat 40-wire cable (not used, purpose unknown, possible - CDROM/DVD) - J4 : 10 pin header for extra controls etc / (note: custom Namco 48 pin edge connector is not on - System10 PCBs) - J5 : 4 pin header for stereo sound out \ - J201 : 100 pin custom Namco connector for mounting of MEM PCB. This connector is surface-mounted, not a - thru-hole type. - J202 : 80 pin custom Namco connector for mounting of another board. This connector is surface-mounted, - not a thru-hole type. - (not used, purpose unknown) + PST592 : PST592J System Reset IC with 2.7V detection circuit (MMP-4A) + BA3121 : Rohm BA3121 Dual Channel Ground Isolation Amplifier & Noise Eliminator (SOIC8) + JRC3414 : New Japan Radio Co. Ltd. JRC3414 Single-Supply Dual High Current Operational Amplifier (x2, SOIC8) + DSW1 : 8 position DIP switch + JP4 : 2 position jumper, set to NC, alt. position labelled SYNC (Note: changing the jumper position has no visual effect) + J1 : 40 Pin IDC connector for a flat 40-wire cable, used for games that have a DVDROM Drive + J4 : 10 pin header for extra controls etc \ (note: custom Namco 48 pin edge connector is not on System10 PCBs) + J5 : 4 pin header for stereo sound out / + J10 : 4 pin header for audio input from ROM board type 3. This audio is mixed with the other main board audio. + J201 : 100 pin custom Namco connector for mounting of MEM PCB. This connector is surface-mounted, not a thru-hole type. + J202 : 80 pin custom Namco connector for mounting of another board. This connector is surface-mounted, not a thru-hole type. + There are additional boards that plug in here and provide extra functionality. See below for the details. J103 : 6-pin JAMMA2 power plug (Note none of the other JAMMA2 standard connectors are present) VR1 : Volume potentiometer * : Unpopulated position for IS41LV16100 1M x16 EDO DRAM @@ -160,16 +167,16 @@ Additional Notes: 1. In test mode (Display Test) the screen can be set to interlace or non-interlace mode. The graphics in interlace mode are visually much smoother with noticeable screen flickering. Non-interlace modes gives a much blockier graphic display (i.e. lower resolution) but without screen flickering. - 2. There is no dedicated highscore/options EEPROM present on the PCB, the game stores its settings on the - game board (probably in the program EEPROMs/FlashROMs or maybe the CPLD?). + 2. There is no dedicated highscore/options EEPROM present on the PCB, the game stores it's settings on the + game board (probably in the program EEPROMs/FlashROMs). -ROM Daughterboard PCB ---------------------- +ROM Daughterboard PCBs +---------------------- This PCB holds all the ROMs. -There are two known types of ROM daughterboards used on S10 games (so far). +There are three known types of ROM daughterboards used on S10 games (so far). All of the PCBs are the same size (approx 5" x 5") containing one custom connector surface-mounted to the underside of -the PCB, some MASKROMs/FlashROMs, a CPLD (which seems to be the customary 'KEYCUS' chip, and on the 2nd type a RAM -chip also. +the PCB, some MASKROMs/FlashROMs, a CPLD (which seems to be the customary 'KEYCUS' chip. On the 2nd type a RAM +chip is also present. The 3rd type has additional hardware to decode MP3 audio and a ROMless Microcontroller. ******** *Type 1* @@ -179,7 +186,7 @@ System10 MEM(M) PCB 8906961000 (8906970700) | | | |-------| +- | | | +- -| |CY37128| +- +| |CY37128| J1+- | |VP160 | +- | | | +- | 7E 7D |-------| +- @@ -201,7 +208,7 @@ Notes: CY37128VP160: CY37128VP160 Cypress Complex Programmable Logic Device (TQFP160) 1A - 5A : Intel Flash DA28F640J5 64MBit Flash EEPROM (SSOP56) 1D - 7E : Samsung Electronics K3N9V1000A-YC 128MBit MASK ROM (TSOP48) (see note 3) - 6 pin header: (purpose unknown, probably for programming the CPLD) + J1 : 6 pin header for programming the CPLD via JTAG This PCB is used on: @@ -224,7 +231,7 @@ System10 MEM(N) PCB 8906961402 (8906971402) | | | |---------| +- | | | +- -| |CY37256 | +- +| |CY37256 | J1+- | 8E 8D |VP208 | +- | | | +- | 7E 7D |---------| +- @@ -246,24 +253,140 @@ Notes: CY37256VP208: Cypress CY37256VP208 Complex Programmable Logic Device (TQFP208) CY7C1019 : Cypress CY7C1019BV33-15VC or Samsung Electronics K6R1008V1C-JC15 128k x8 bit 3.3V High Speed CMOS Static Ram (SOJ32) 1D - 8E : Samsung Electronics K9F2808U0B-YCBO 128MBit NAND Flash EEPROM (TSOP48) - 6 pin header: (purpose unknown, probably for programming the CPLD) + J1 : 6 pin header for programming the CPLD via JTAG This PCB is used on: MEM PCB -Game Sticker KEYCUS ROMs Populated ---------------------------------------------------------------------------- -Gekitoride-Jong Space 10011 Ver.A KC003A 8E, 8D, 7E, 7D -Mr.Driller G DRG1 Ver.A KC007A 8E, 8D, 7E -Kotoba no Puzzle Mojipittan KPM1 Ver.A KC012A 8E, 8D, 7E -Panicuru Panekuru PPA1 Ver.A KC017A 8E, 8D, 7E -Star Trigon STT1 Ver.A KC019A 8E, 8D -Gamshara 10021 Ver.A KC020A 8E, 8D -Utyuu Daisakusen Chocovader Contactee CVC1 Ver.A KC022A 8E, 8D, 7E, 7D, 6E -Kono Tako 10021 Ver.A KC034A 8E, 8D +Game Sticker KEYCUS ROMs Populated CD Notes +---------------------------------------------------------------------------------------------------------------------------------------------- +Gamshara 10021 Ver.A KC020A 8E, 8D N/A +Gekitoride-Jong Space 10011 Ver.A KC003A 8E, 8D, 7E, 7D N/A +Gunbalina GNN1 Ver.A KC002A 8E, 8D N/A see note 3 +Kono Tako 10021 Ver.A KC034A 8E, 8D N/A +Kotoba no Puzzle Mojipittan KPM1 Ver.A KC012A 8E, 8D, 7E N/A +Mr Driller G DRG1 Ver.A KC007A 8E, 8D, 7E N/A +NFL Classic Football NCF3 Ver.A KC027A 8E, 8D, 7E, 7D N/A +Panicuru Panekuru PPA1 Ver.A KC017A 8E, 8D, 7E N/A +Point Blank 3 GNN2 Ver.A KC002A 8E, 8D N/A see note 3 +Star Trigon STT1 Ver.A KC019A 8E, 8D N/A +Taiko No Tatsujin 2 TK21 Ver.C KC010A 8E, 8D, 7E TK21-A KEYCUS is marked KC007A, KC010A is a sticker +Taiko No Tatsujin 3 TK31 Ver.A KC016A 8E, 8D, 7E not dumped For all TK* games see note 2 +Taiko No Tatsujin 4 TK41 Ver.A KC024A 8E, 8D, 7E TK-4 +Taiko No Tatsujin 5 TK51 Ver.A KC031A 8E, 8D, 7E not dumped +Taiko No Tatsujin 6 TK61 Ver.A KC036A 8E, 8D, 7E TK-6 +Utyuu Daisakusen Chocovader Contactee CVC1 Ver.A KC022A 8E, 8D, 7E, 7D, 6E N/A + + Notes: + 1. The ROM PCB has locations for 16x 128MBit FlashROMs (Total capacity = 2048MBits) but usually only a few are populated. + 2. All of the Taiko no Tatsujin games require a CDROM disc. The game will not show anything on screen + if the CD drive & disc is not present and working. The disc contains binary data. + 3. Some kind of block locking or protection issues in the NAND FlashROM prevents the last NAND block being dumped. + +******** +*Type 3* +******** +System10 MEM(P3) PCB 8906962201 (8906972201) +|-------------------------------------| +|TMP95C061 J101 L K6R1008 | +| PST575D +- +| LLLL |-------| +- +|VHCT245 | | |-------| +- +| LCX245 |CY37256| | |J1+- +| 07VZ5M |VP208 | |CY37256| +- +| 07VZ5M |(2) | |VP208 | +- +| |-------| |(1) | | +|J3 |-------| | +| HY57V641620 DSW(4) | +| LCX245 LCX245| +| LC82310 LCX245 LCX245| +| 3414 16.9344MHz | +| VHC14 L | +| L | +| L | +| L | +| 0 2 4 6 8 10 12 14 | +|J2 | +| 1 3 5 7 9 11 13 15 | +|-------------------------------------| +Notes: + TMP95C061 : Toshiba TMP95C061 TLCS-900 Series CMOS 16-bit Microcontroller; No internal ROM or RAM (QFP100) + CY37256VP208(1): Cypress CY37256VP208 Complex Programmable Logic Device, marked with code 'KC' and a number. + This is the Namco KEYCUS chip which is unique to each game (TQFP208) + CY37256VP208(2): Cypress CY37256VP208 Complex Programmable Logic Device, marked 'S10MEP2A' (TQFP208) + K6R1008 : Samsung Electronics K6R1008V1C-JC15 128k x8-bit 3.3V High Speed CMOS Static Ram (SOJ32) + HY57V641620 : Hyundai HY57V641620 4 Banks x1M x16-bit Synchronous DRAM (TSOP54 Type II) + 0-15 : Samsung Electronics K9F2808U0A-YCBO 16Mx8-bit (128M-bit) NAND Flash ROM (TSOP48) + Note! These ROMs also hold data for high scores and play time and coin history. + They must be reset to factory defaults before dumping so the dump is clean. + LC82310 : Sanyo LC82310 MP3 decoder IC (QFP64) + 3414 : New Japan Radio Co. Ltd. JRC3414 Single-Supply Dual High Current Operational Amplifier (SOIC8) + 07VZ5M : Sharp 07VZ5M Variable Voltage Regulator + PST575D : Mitsumi PST575D System Reset IC. Available in voltage detection C through L with voltages 4.5V-2.3V + This D version triggers a reset at 4.2V (MMP-4A) + J1 : 6 pin header for programming the CPLDs via JTAG + J2 : 4 pin connector joined to main board for MP3 audio output from ROM board + J3 : 6 pin connector joined to V278 EMI PCB (filter board on outside of metal box) via 16-pin IDC connector + This connector is probably for extra controls + L : LED (SMD 0603) Note - 1. The ROM PCB has locations for 16x 128MBit FlashROMs (Total capacity = 2048MBits) but usually only a few are populated. + 1. The ROM PCB has locations for 16x Flash ROMs (Total capacity = 2048M-bits) but usually only a few are populated. + +This PCB is used on: + + MEM PCB +Game Sticker KEYCUS ROMs Populated +----------------------------------------------------------------------------------------------------- +Golgo 13 Juusei no Chinkonka GLT1 Ver.A KC009A 0, 1, 2, 3, 4, 5 +Seishun Quiz Colorful High School CHS1 Ver.A KC025A 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 +Tsukkomi Yousei Gips Nice Tsukkomi NTK1 Ver.A KC018A 0, 1, 2, 3, 4, 5, 6, 7 + + +Expansion Daughterboard PCB +--------------------------- +This PCB provides input/output capabilities for JVS hook-ups and allows extra controls to be connected. +There is actually only one PCB design but there are several variations where some of the connectors and +ICs are not populated if the game does not need that capability. However the PCB contains all the +locations/pads/holes etc to mount those parts. In most cases seen so far this PCB is optional but on some +games (e.g. Point Blank 3) it is required for proper game play. + +System10 EXIO PCB 8906960602 (8906970602) +|--------------------------------------------------------| +| J4 J5 J3 J2 | +| ADM485 MC14052 |-| +| LT1181A | +| VHCT245 | +| CY37128VP100 VHCT245 | +|J6 VHCT245 VHCT245 J1| +| VHCT245 | +| VHCT245 | +| VHC14 61C256 | +| TMP95C061 | +| 22.1184MHz VHCT244 |-| +| LLLL J7 VHCT574 J8| +|--------------------------------------------------------| +Notes: + TMP95C061 : Toshiba TMP95C061 TLCS-900 Series CMOS 16-bit Microcontroller; No internal ROM or RAM (QFP100) + CY37128VP160 : CY37128VP100 Cypress Complex Programmable Logic Device, marked 'S10XIO1A' or 'S10XIO1B' or 'S10XIO1C' (TQFP100) + VHC* : Common 3.3v logic chips + ADM485 : Analog Devices ADM485 Low Power EIA RS485 transceiver (SOIC8) + 61C256 : ISSI IS61C256AH-15J 32k x8-bit SRAM (SOJ28) + LT1181A : Linear Technology LT1181A or Analog Devices ADM202EARW Low Power 5V RS232 Dual Driver/Receiver (SOIC16W) + MC14052 : OnSemi MC14052 Analog DP4T Multiplexers/Demultiplexer (SOIC16) + L : LED (SMD 0603) + J1 : 48-Way Card Edge Connector + J2 : USB Connector for JVS External I/O board + J3 : Dual RCA Jacks marked 'AUDIO', for audio output + J4/J5 : HD15F DSUB Connector marked 'CRT1/CRT2', for video output + J6 : DB9 DSUB Connector marked 'RS232C'. Possibly for networking several PCBs together + J7 : 6 pin header for programming the CPLDs via JTAG + J8 : 2 pin header for connection of gun. Pin 1:Player 1 Gun Opto. Pin2:Player 2 Gun Opto + +This PCB is required by Point Blank 3 since it controls the gun opto signal. Only the CPLD and J8 and some minor +logic and other small support parts are populated. +This PCB has been found almost fully populated (minus J6) on some Taiko no Tatsujin games (TK51/TK61) but not +earlier TK games, so it appears to be optional or is only used by the later TK51 and TK61 games. */ #include "emu.h" @@ -945,6 +1068,20 @@ ROM_START( gjspace ) ROM_LOAD( "10011a_3.bin", 0x3180000, 0x1080000, CRC(fb0de5ca) SHA1(50a462a52ff4a0bc112b9d89f2b2d032c60cf59c) ) ROM_END + +ROM_START( g13jnc ) + ROM_REGION32_LE( 0x400000, "maincpu:rom", 0 ) /* bios */ + ROM_FILL( 0x0000000, 0x400000, 0x55 ) + + ROM_REGION16_LE( 0x6300000, "user2", 0 ) /* main prg */ + ROM_LOAD( "GLT1_Ver.A.0", 0x0000000, 0x1080000, CRC(e60f78d3) SHA1(5c876ac7366b5c46b5229a6b6f694ad222f36195) ) + ROM_LOAD( "GLT1_Ver.A.1", 0x1080000, 0x1080000, CRC(c3f31dd9) SHA1(05e6d39f33191979bcc00a585b64904a077000dc) ) + ROM_LOAD( "GLT1_Ver.A.2", 0x2100000, 0x1080000, CRC(e464e03a) SHA1(751f6bd753dacbb881fb47bc1b146ef59245bd10) ) + ROM_LOAD( "GLT1_Ver.A.3", 0x3180000, 0x1080000, CRC(f7486979) SHA1(a44c33ae7004e79fe66c6d2cba3d11671ce2582c) ) + ROM_LOAD( "GLT1_Ver.A.4", 0x4200000, 0x1080000, CRC(e39969b4) SHA1(3348839c0cc4a4bcaa7803ef22981420c527e1a4) ) + ROM_LOAD( "GLT1_Ver.A.5", 0x5280000, 0x1080000, CRC(a82800b4) SHA1(ce4cc479acdf7ac5a7237d07422ea3ee580d899a) ) +ROM_END + ROM_START( mrdrilrg ) ROM_REGION32_LE( 0x400000, "maincpu:rom", 0 ) /* bios */ ROM_FILL( 0x0000000, 0x400000, 0x55 ) @@ -1070,6 +1207,7 @@ GAME( 2000, mrdrlr2a, mrdrilr2, ns10_mrdrilr2, namcos10, namcos10_state, mrdril GAME( 2000, ptblank3, 0, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Point Blank 3 (Asia, GNN2 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) GAME( 2000, gunbalina, ptblank3, namcos10_memn, namcos10, namcos10_state, gunbalna, ROT0, "Namco", "Gunbalina (Japan, GNN1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) GAME( 2001, gjspace, 0, ns10_gjspace , namcos10, namcos10_state, gjspace, ROT0, "Namco / Metro", "Gekitoride-Jong Space (10011 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +GAME( 2001, g13jnc, 0, namcos10_memn, namcos10, namcos10_state, 0, ROT0, "Eighting / Raizing / Namco", "Golgo 13: Juusei no Chinkonka (Japan, GLT1 VER.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) GAME( 2001, mrdrilrg, 0, namcos10_memn, namcos10, namcos10_state, mrdrilrg, ROT0, "Namco", "Mr. Driller G (Japan, DRG1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks GAME( 2001, mrdrilrga, mrdrilrg, namcos10_memn, namcos10, namcos10_state, mrdrilrg, ROT0, "Namco", "Mr. Driller G ALT (Japan, DRG1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // PORT_4WAY joysticks GAME( 2001, knpuzzle, 0, ns10_knpuzzle, namcos10, namcos10_state, knpuzzle, ROT0, "Namco", "Kotoba no Puzzle Mojipittan (Japan, KPM1 Ver.A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/namcos11.cpp b/src/mame/drivers/namcos11.cpp index 0522834aa2f..86784874484 100644 --- a/src/mame/drivers/namcos11.cpp +++ b/src/mame/drivers/namcos11.cpp @@ -1676,7 +1676,7 @@ GAME( 1995, xevi3dgj, xevi3dg, xevi3dg, namcos11, namcos11_state, 0, ROT GAME( 1996, primglex, 0, primglex, tekken, namcos11_state, 0, ROT0, "Namco", "Prime Goal EX (Japan, PG1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, danceyes, 0, danceyes, namcos11, namcos11_state, 0, ROT0, "Namco", "Dancing Eyes (US, DC3/VER.C)", MACHINE_IMPERFECT_GRAPHICS ) GAME( 1996, danceyesj, danceyes, danceyes, namcos11, namcos11_state, 0, ROT0, "Namco", "Dancing Eyes (Japan, DC1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1996, pocketrc, 0, pocketrc, pocketrc, namcos11_state, 0, ROT0, "Namco", "Pocket Racer (Japan, PKR1/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1996, pocketrc, 0, pocketrc, pocketrc, namcos11_state, 0, ROT0, "Namco", "Pocket Racer (Japan, PKR1/VER.B)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) GAME( 1997, starswep, 0, starswep, namcos11, namcos11_state, 0, ROT0, "Axela / Namco", "Star Sweep (World, STP2/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) GAME( 1997, starswepj, starswep, starswep, namcos11, namcos11_state, 0, ROT0, "Axela / Namco", "Star Sweep (Japan, STP1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) GAME( 1998, myangel3, 0, myangel3, myangel3, namcos11_state, 0, ROT0, "MOSS / Namco", "Kosodate Quiz My Angel 3 (Japan, KQT1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) diff --git a/src/mame/drivers/namcos12.cpp b/src/mame/drivers/namcos12.cpp index 7e430b88225..198bb9e6f64 100644 --- a/src/mame/drivers/namcos12.cpp +++ b/src/mame/drivers/namcos12.cpp @@ -1173,6 +1173,16 @@ protected: }; +class namcos12_boothack_state : public namcos12_state +{ +public: + using namcos12_state::namcos12_state; + +protected: + virtual void machine_reset() override; +}; + + inline void ATTR_PRINTF(3,4) namcos12_state::verboselog( int n_level, const char *s_fmt, ... ) { if( VERBOSE_LEVEL >= n_level ) @@ -1487,41 +1497,17 @@ void namcos12_state::machine_reset() m_tssio_port_4 = 0; m_has_tektagt_dma = 0; +} - if( strcmp( machine().system().name, "tektagt" ) == 0 || - strcmp( machine().system().name, "tektagtac" ) == 0 || - strcmp( machine().system().name, "tektagtac1" ) == 0 || - strcmp( machine().system().name, "tektagtub" ) == 0 || - strcmp( machine().system().name, "tektagtjc1" ) == 0 || - strcmp( machine().system().name, "tektagtjb" ) == 0 || - strcmp( machine().system().name, "tektagtja" ) == 0 || - strcmp( machine().system().name, "fgtlayer" ) == 0 || - strcmp( machine().system().name, "golgo13" ) == 0 || - strcmp( machine().system().name, "g13knd" ) == 0 || - strcmp( machine().system().name, "mrdrillr" ) == 0 || - strcmp( machine().system().name, "mrdrillrj" ) == 0 || - strcmp( machine().system().name, "pacapp" ) == 0 || - strcmp( machine().system().name, "pacappsp" ) == 0 || - strcmp( machine().system().name, "pacapp2" ) == 0 || - strcmp( machine().system().name, "tenkomor" ) == 0 || - strcmp( machine().system().name, "tenkomorja" ) == 0 || - strcmp( machine().system().name, "ptblank2" ) == 0 || - strcmp( machine().system().name, "gunbarl" ) == 0 || - strcmp( machine().system().name, "sws2000" ) == 0 || - strcmp( machine().system().name, "sws2001" ) == 0 || - strcmp( machine().system().name, "truckk" ) == 0 || - strcmp( machine().system().name, "technodr" ) == 0 || - strcmp( machine().system().name, "aplarail" ) == 0 || - strcmp( machine().system().name, "kartduel" ) == 0 || - strcmp( machine().system().name, "ohbakyuun" ) == 0 || - strcmp( machine().system().name, "ghlpanic" ) == 0 ) - { - /* HACK: this is based on guesswork, it might not even be keycus. */ - uint8_t *rom = memregion( "maincpu:rom" )->base() + 0x20280; - uint8_t *ram = m_ram->pointer() + 0x10000; +void namcos12_boothack_state::machine_reset() +{ + namcos12_state::machine_reset(); - memcpy( ram, rom, 12 ); - } + /* HACK: this is based on guesswork, it might not even be keycus. */ + uint8_t *rom = memregion( "maincpu:rom" )->base() + 0x20280; + uint8_t *ram = m_ram->pointer() + 0x10000; + + memcpy( ram, rom, 12 ); } /* H8/3002 MCU stuff */ @@ -3182,55 +3168,55 @@ ROM_START( aplarail ) ROM_LOAD( "at28c16", 0x000000, 0x000800, CRC(db1b63c5) SHA1(01fc3386a2d1cb1bed1b7fd9bd2fd59e503832d3) ) ROM_END -GAME( 1996, tekken3, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (World, TET2/VER.E1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ -GAME( 1996, tekken3b, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (World, TET2/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ -GAME( 1996, tekken3a, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (World, TET2/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ -GAME( 1996, tekken3ud, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (US, TET3/VER.D)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ -GAME( 1996, tekken3ua, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (US, TET3/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ -GAME( 1996, tekken3je1,tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (Japan, TET1/VER.E1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ -GAME( 1996, tekken3ja, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (Japan, TET1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC014 */ -GAME( 1997, lbgrande, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Libero Grande (World, LG2/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC014 */ -GAME( 1997, lbgrandeja,lbgrande, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Libero Grande (Japan, LG1/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC014 */ -GAME( 1997, toukon3, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco / Tomy", "Shin Nihon Pro Wrestling Toukon Retsuden 3 Arcade Edition (Japan, TR1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC019 */ -GAME( 1998, soulclbr, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (World, SOC14/VER.C)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1998, soulclbrwb,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (World, SOC14/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1998, soulclbruc,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (US, SOC13/VER.C)", MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1998, soulclbrub,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (US, SOC13/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) /* KC020 */ -GAME( 1998, soulclbrjc,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (Japan, SOC11/VER.C)", MACHINE_IMPERFECT_GRAPHICS ) /* KC020 */ -GAME( 1998, soulclbrjb,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (Japan, SOC11/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) /* KC020 */ -GAME( 1998, soulclbrja,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (Japan, SOC11/VER.A2)", MACHINE_IMPERFECT_GRAPHICS ) /* KC020 */ -GAME( 1998, ehrgeiz, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Square / Namco", "Ehrgeiz (World, EG2/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC021 */ -GAME( 1998, ehrgeizua, ehrgeiz, coh700, namcos12, namcos12_state, namcos12, ROT0, "Square / Namco", "Ehrgeiz (US, EG3/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC021 */ -GAME( 1998, ehrgeizja, ehrgeiz, coh700, namcos12, namcos12_state, namcos12, ROT0, "Square / Namco", "Ehrgeiz (Japan, EG1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC021 */ -GAME( 1998, mdhorse, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "MOSS / Namco", "Derby Quiz My Dream Horse (Japan, MDH1/VER.A2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC035 */ -GAME( 1998, aplarail, 0, aplarail, aplarail, namcos12_state, namcos12, ROT0, "Namco / Tomy", "Attack Pla Rail (Japan, AP1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC032 */ -GAME( 1998, sws98, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Super World Stadium '98 (Japan, SS81/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC0?? */ -GAME( 1998, technodr, 0, technodr, technodr, namcos12_state, technodr, ROT0, "Namco", "Techno Drive (Japan, TD2/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) /* KC056 */ -GAME( 1998, tenkomor, 0, coh700, namcos12, namcos12_state, namcos12, ROT90,"Namco", "Tenkomori Shooting (World, TKM2/VER.A1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC036 */ -GAME( 1998, tenkomorja,tenkomor, coh700, namcos12, namcos12_state, namcos12, ROT90,"Namco", "Tenkomori Shooting (Japan, TKM1/VER.A1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC036 */ -GAME( 1998, fgtlayer, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Arika / Namco", "Fighting Layer (Japan, FTL1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC037 */ -GAME( 1999, pacapp, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Produce / Namco", "Paca Paca Passion (Japan, PPP1/VER.A2)", MACHINE_IMPERFECT_GRAPHICS ) /* KC038 */ -GAME( 1999, ptblank2, 0, ptblank2, ptblank2, namcos12_state, ptblank2, ROT0, "Namco", "Point Blank 2 (GNB5/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC042 */ -GAME( 1999, gunbarl, ptblank2, ptblank2, ptblank2, namcos12_state, ptblank2, ROT0, "Namco", "Gunbarl (Japan, GNB4/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC042 */ -GAME( 1999, sws99, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Super World Stadium '99 (Japan, SS91/VER.A3)", MACHINE_IMPERFECT_GRAPHICS ) /* KC043 */ -GAME( 1999, tektagt, 0, tektagt, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (World, TEG2/VER.C1, set 1)", 0 ) /* KC044 */ -GAME( 1999, tektagtc1, tektagt, tektagt, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (World, TEG2/VER.C1, set 2)", 0 ) /* KC044 */ -GAME( 1999, tektagtuc1,tektagt, tektagt, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (US, TEG3/VER.C1)", 0 ) /* KC044 */ -GAME( 1999, tektagtub, tektagt, tektagt, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (US, TEG3/VER.B)", 0 ) /* KC044 */ -GAME( 1999, tektagtjc1,tektagt, tektagt, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (Japan, TEG1/VER.C1)", MACHINE_NOT_WORKING ) /* KC044 */ -GAME( 1999, tektagtjb, tektagt, tektagt, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (Japan, TEG1/VER.B)", MACHINE_NOT_WORKING ) /* KC044 */ -GAME( 1999, tektagtja, tektagt, tektagt, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (Japan, TEG1/VER.A3)", MACHINE_NOT_WORKING ) /* KC044 */ -GAME( 1999, ghlpanic, 0, ptblank2, ghlpanic, namcos12_state, namcos12, ROT0, "Eighting / Raizing / Namco", "Ghoul Panic (World, OB2/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC045 */ -GAME( 1999, ohbakyuun, ghlpanic, ptblank2, ghlpanic, namcos12_state, namcos12, ROT0, "Eighting / Raizing / Namco", "Oh! Bakyuuun (Japan, OB1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC045 */ -GAME( 1999, pacapp2, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Produce / Namco", "Paca Paca Passion 2 (Japan, PKS1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC046 */ -GAME( 1999, mrdrillr, 0, coh700, namcos124w,namcos12_state,namcos12, ROT0, "Namco", "Mr. Driller (US, DRI3/VER.A2)", MACHINE_IMPERFECT_GRAPHICS ) /* KC048 */ -GAME( 1999, mrdrillrj, mrdrillr, coh700, namcos124w,namcos12_state,namcos12, ROT0, "Namco", "Mr. Driller (Japan, DRI1/VER.A2)", MACHINE_IMPERFECT_GRAPHICS ) /* KC048 */ -GAME( 1999, kaiunqz, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Kaiun Quiz (Japan, KW1/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC050 */ -GAME( 1999, pacappsp, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Produce / Namco", "Paca Paca Passion Special (Japan, PSP1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC052 */ -GAME( 1999, aquarush, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Aqua Rush (Japan, AQ1/VER.A1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC053 */ -GAME( 1999, golgo13, 0, golgo13, golgo13, namcos12_state, namcos12, ROT0, "Eighting / Raizing / Namco", "Golgo 13 (Japan, GLG1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC054 */ -GAME( 1999, g13knd, 0, golgo13, golgo13, namcos12_state, namcos12, ROT0, "Eighting / Raizing / Namco", "Golgo 13 Kiseki no Dandou (Japan, GLS1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC059 */ -GAME( 2000, sws2000, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Super World Stadium 2000 (Japan, SS01/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC055 */ -GAME( 2000, truckk, 0, truckk, namcos12, namcos12_state, namcos12, ROT0, "Metro / Namco", "Truck Kyosokyoku (Japan, TKK2/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING ) /* KC056 */ -GAME( 2000, kartduel, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Kart Duel (Japan, KTD1/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC057 */ -GAME( 2001, sws2001, sws2000, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Super World Stadium 2001 (Japan, SS11/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC061 */ +GAME( 1996, tekken3, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (World, TET2/VER.E1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ +GAME( 1996, tekken3b, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (World, TET2/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ +GAME( 1996, tekken3a, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (World, TET2/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ +GAME( 1996, tekken3ud, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (US, TET3/VER.D)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ +GAME( 1996, tekken3ua, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (US, TET3/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ +GAME( 1996, tekken3je1,tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (Japan, TET1/VER.E1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC006 */ +GAME( 1996, tekken3ja, tekken3, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Tekken 3 (Japan, TET1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC014 */ +GAME( 1997, lbgrande, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Libero Grande (World, LG2/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC014 */ +GAME( 1997, lbgrandeja,lbgrande, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Libero Grande (Japan, LG1/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC014 */ +GAME( 1997, toukon3, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco / Tomy", "Shin Nihon Pro Wrestling Toukon Retsuden 3 Arcade Edition (Japan, TR1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC019 */ +GAME( 1998, soulclbr, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (World, SOC14/VER.C)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1998, soulclbrwb,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (World, SOC14/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1998, soulclbruc,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (US, SOC13/VER.C)", MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1998, soulclbrub,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (US, SOC13/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) /* KC020 */ +GAME( 1998, soulclbrjc,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (Japan, SOC11/VER.C)", MACHINE_IMPERFECT_GRAPHICS ) /* KC020 */ +GAME( 1998, soulclbrjb,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (Japan, SOC11/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) /* KC020 */ +GAME( 1998, soulclbrja,soulclbr, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Soul Calibur (Japan, SOC11/VER.A2)", MACHINE_IMPERFECT_GRAPHICS ) /* KC020 */ +GAME( 1998, ehrgeiz, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Square / Namco", "Ehrgeiz (World, EG2/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC021 */ +GAME( 1998, ehrgeizua, ehrgeiz, coh700, namcos12, namcos12_state, namcos12, ROT0, "Square / Namco", "Ehrgeiz (US, EG3/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC021 */ +GAME( 1998, ehrgeizja, ehrgeiz, coh700, namcos12, namcos12_state, namcos12, ROT0, "Square / Namco", "Ehrgeiz (Japan, EG1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC021 */ +GAME( 1998, mdhorse, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "MOSS / Namco", "Derby Quiz My Dream Horse (Japan, MDH1/VER.A2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC035 */ +GAME( 1998, aplarail, 0, aplarail, aplarail, namcos12_boothack_state, namcos12, ROT0, "Namco / Tomy", "Attack Pla Rail (Japan, AP1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC032 */ +GAME( 1998, sws98, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Super World Stadium '98 (Japan, SS81/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC0?? */ +GAME( 1998, technodr, 0, technodr, technodr, namcos12_boothack_state, technodr, ROT0, "Namco", "Techno Drive (Japan, TD2/VER.B)", MACHINE_IMPERFECT_GRAPHICS ) /* KC056 */ +GAME( 1998, tenkomor, 0, coh700, namcos12, namcos12_boothack_state, namcos12, ROT90,"Namco", "Tenkomori Shooting (World, TKM2/VER.A1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC036 */ +GAME( 1998, tenkomorja,tenkomor, coh700, namcos12, namcos12_boothack_state, namcos12, ROT90,"Namco", "Tenkomori Shooting (Japan, TKM1/VER.A1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC036 */ +GAME( 1998, fgtlayer, 0, coh700, namcos12, namcos12_boothack_state, namcos12, ROT0, "Arika / Namco", "Fighting Layer (Japan, FTL1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC037 */ +GAME( 1999, pacapp, 0, coh700, namcos12, namcos12_boothack_state, namcos12, ROT0, "Produce / Namco", "Paca Paca Passion (Japan, PPP1/VER.A2)", MACHINE_IMPERFECT_GRAPHICS ) /* KC038 */ +GAME( 1999, ptblank2, 0, ptblank2, ptblank2, namcos12_boothack_state, ptblank2, ROT0, "Namco", "Point Blank 2 (GNB5/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC042 */ +GAME( 1999, gunbarl, ptblank2, ptblank2, ptblank2, namcos12_boothack_state, ptblank2, ROT0, "Namco", "Gunbarl (Japan, GNB4/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC042 */ +GAME( 1999, sws99, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Super World Stadium '99 (Japan, SS91/VER.A3)", MACHINE_IMPERFECT_GRAPHICS ) /* KC043 */ +GAME( 1999, tektagt, 0, tektagt, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (World, TEG2/VER.C1, set 1)", 0 ) /* KC044 */ +GAME( 1999, tektagtc1, tektagt, tektagt, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (World, TEG2/VER.C1, set 2)", 0 ) /* KC044 */ +GAME( 1999, tektagtuc1,tektagt, tektagt, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (US, TEG3/VER.C1)", 0 ) /* KC044 */ +GAME( 1999, tektagtub, tektagt, tektagt, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (US, TEG3/VER.B)", 0 ) /* KC044 */ +GAME( 1999, tektagtjc1,tektagt, tektagt, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (Japan, TEG1/VER.C1)", MACHINE_NOT_WORKING ) /* KC044 */ +GAME( 1999, tektagtjb, tektagt, tektagt, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (Japan, TEG1/VER.B)", MACHINE_NOT_WORKING ) /* KC044 */ +GAME( 1999, tektagtja, tektagt, tektagt, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Tekken Tag Tournament (Japan, TEG1/VER.A3)", MACHINE_NOT_WORKING ) /* KC044 */ +GAME( 1999, ghlpanic, 0, ptblank2, ghlpanic, namcos12_boothack_state, namcos12, ROT0, "Eighting / Raizing / Namco", "Ghoul Panic (World, OB2/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC045 */ +GAME( 1999, ohbakyuun, ghlpanic, ptblank2, ghlpanic, namcos12_boothack_state, namcos12, ROT0, "Eighting / Raizing / Namco", "Oh! Bakyuuun (Japan, OB1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC045 */ +GAME( 1999, pacapp2, 0, coh700, namcos12, namcos12_boothack_state, namcos12, ROT0, "Produce / Namco", "Paca Paca Passion 2 (Japan, PKS1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC046 */ +GAME( 1999, mrdrillr, 0, coh700, namcos124w,namcos12_boothack_state, namcos12, ROT0, "Namco", "Mr. Driller (US, DRI3/VER.A2)", MACHINE_IMPERFECT_GRAPHICS ) /* KC048 */ +GAME( 1999, mrdrillrj, mrdrillr, coh700, namcos124w,namcos12_boothack_state, namcos12, ROT0, "Namco", "Mr. Driller (Japan, DRI1/VER.A2)", MACHINE_IMPERFECT_GRAPHICS ) /* KC048 */ +GAME( 1999, kaiunqz, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Kaiun Quiz (Japan, KW1/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC050 */ +GAME( 1999, pacappsp, 0, coh700, namcos12, namcos12_boothack_state, namcos12, ROT0, "Produce / Namco", "Paca Paca Passion Special (Japan, PSP1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC052 */ +GAME( 1999, aquarush, 0, coh700, namcos12, namcos12_state, namcos12, ROT0, "Namco", "Aqua Rush (Japan, AQ1/VER.A1)", MACHINE_IMPERFECT_GRAPHICS ) /* KC053 */ +GAME( 1999, golgo13, 0, golgo13, golgo13, namcos12_boothack_state, namcos12, ROT0, "Eighting / Raizing / Namco", "Golgo 13 (Japan, GLG1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC054 */ +GAME( 2000, g13knd, 0, golgo13, golgo13, namcos12_boothack_state, namcos12, ROT0, "Eighting / Raizing / Namco", "Golgo 13 Kiseki no Dandou (Japan, GLS1/VER.A)", MACHINE_IMPERFECT_GRAPHICS ) /* KC059 */ +GAME( 2000, sws2000, 0, coh700, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Super World Stadium 2000 (Japan, SS01/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC055 */ +GAME( 2000, truckk, 0, truckk, namcos12, namcos12_boothack_state, namcos12, ROT0, "Metro / Namco", "Truck Kyosokyoku (Japan, TKK2/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND | MACHINE_NOT_WORKING ) /* KC056 */ +GAME( 2000, kartduel, 0, coh700, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Kart Duel (Japan, KTD1/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC057 */ +GAME( 2001, sws2001, sws2000, coh700, namcos12, namcos12_boothack_state, namcos12, ROT0, "Namco", "Super World Stadium 2001 (Japan, SS11/VER.A)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) /* KC061 */ diff --git a/src/mame/drivers/namcos22.cpp b/src/mame/drivers/namcos22.cpp index e79cfcf0514..5929f68d546 100644 --- a/src/mame/drivers/namcos22.cpp +++ b/src/mame/drivers/namcos22.cpp @@ -2978,7 +2978,7 @@ ADDRESS_MAP_END TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::propcycl_pedal_interrupt) { - generic_pulse_irq_line(*m_mcu, M37710_LINE_TIMERA3TICK, 1); + m_mcu->pulse_input_line(M37710_LINE_TIMERA3TICK, m_mcu->minimum_quantum_time()); } TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::propcycl_pedal_update) @@ -3013,7 +3013,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::propcycl_pedal_update) TIMER_CALLBACK_MEMBER(namcos22_state::adillor_trackball_interrupt) { - generic_pulse_irq_line(*m_mcu, param ? M37710_LINE_TIMERA2TICK : M37710_LINE_TIMERA3TICK, 1); + m_mcu->pulse_input_line(param ? M37710_LINE_TIMERA2TICK : M37710_LINE_TIMERA3TICK, m_mcu->minimum_quantum_time()); } TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::adillor_trackball_update) @@ -5653,27 +5653,27 @@ GAME( 1993, ridgerac3, ridgerac, namcos22, ridgera, namcos22_state, ridgeraj, GAME( 1993, ridgeracb, ridgerac, namcos22, ridgera, namcos22_state, ridgeraj, ROT0, "Namco", "Ridge Racer (Rev. RR2, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 1993-10-07 GAME( 1993, ridgeracj, ridgerac, namcos22, ridgera, namcos22_state, ridgeraj, ROT0, "Namco", "Ridge Racer (Rev. RR1, Japan)" , MACHINE_IMPERFECT_GRAPHICS ) // 1993-10-07 GAME( 1993, ridgeracf, ridgerac, namcos22, ridgeracf, namcos22_state, ridgeraj, ROT0, "Namco", "Ridge Racer Full Scale (World)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) // 1993-12-13, very different version, incomplete dump. -GAME( 1994, ridgera2, 0, namcos22, ridgera2, namcos22_state, ridger2j, ROT0, "Namco", "Ridge Racer 2 (Rev. RRS2, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 1994-06-21 -GAME( 1994, ridgera2j, ridgera2, namcos22, ridgera2, namcos22_state, ridger2j, ROT0, "Namco", "Ridge Racer 2 (Rev. RRS1 Ver.B, Japan)" , MACHINE_IMPERFECT_GRAPHICS ) // 1994-06-21 -GAME( 1994, ridgera2ja,ridgera2, namcos22, ridgera2, namcos22_state, ridger2j, ROT0, "Namco", "Ridge Racer 2 (Rev. RRS1, Japan)" , MACHINE_IMPERFECT_GRAPHICS ) // 1994-06-13 +GAME( 1994, ridgera2, 0, namcos22, ridgera2, namcos22_state, ridger2j, ROT0, "Namco", "Ridge Racer 2 (Rev. RRS2, World)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) // 1994-06-21 +GAME( 1994, ridgera2j, ridgera2, namcos22, ridgera2, namcos22_state, ridger2j, ROT0, "Namco", "Ridge Racer 2 (Rev. RRS1 Ver.B, Japan)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) // 1994-06-21 +GAME( 1994, ridgera2ja,ridgera2, namcos22, ridgera2, namcos22_state, ridger2j, ROT0, "Namco", "Ridge Racer 2 (Rev. RRS1, Japan)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) // 1994-06-13 GAME( 1994, cybrcomm, 0, cybrcomm, cybrcomm, namcos22_state, cybrcomm, ROT0, "Namco", "Cyber Commando (Rev. CY1, Japan)" , MACHINE_IMPERFECT_GRAPHICS ) // 10/14/94 -GAME( 1995, raveracw, 0, namcos22, raveracw, namcos22_state, raveracw, ROT0, "Namco", "Rave Racer (Rev. RV2, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 07/16/95 -GAME( 1995, raveracj, raveracw, namcos22, raveracw, namcos22_state, raveracw, ROT0, "Namco", "Rave Racer (Rev. RV1 Ver.B, Japan)" , MACHINE_IMPERFECT_GRAPHICS ) // 07/16/95 -GAME( 1995, raveracja, raveracw, namcos22, raveracw, namcos22_state, raveracw, ROT0, "Namco", "Rave Racer (Rev. RV1, Japan)" , MACHINE_IMPERFECT_GRAPHICS ) // 06/29/95 -GAME( 1994, acedrvrw, 0, namcos22, acedrvr, namcos22_state, acedrvr, ROT0, "Namco", "Ace Driver: Racing Evolution (Rev. AD2, World)", MACHINE_IMPERFECT_GRAPHICS ) // 94/10/20 16:22:25 -GAME( 1996, victlapw, 0, namcos22, victlap, namcos22_state, victlap, ROT0, "Namco", "Ace Driver: Victory Lap (Rev. ADV2, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 96/02/13 17:50:06 +GAME( 1995, raveracw, 0, namcos22, raveracw, namcos22_state, raveracw, ROT0, "Namco", "Rave Racer (Rev. RV2, World)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) // 07/16/95 +GAME( 1995, raveracj, raveracw, namcos22, raveracw, namcos22_state, raveracw, ROT0, "Namco", "Rave Racer (Rev. RV1 Ver.B, Japan)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) // 07/16/95 +GAME( 1995, raveracja, raveracw, namcos22, raveracw, namcos22_state, raveracw, ROT0, "Namco", "Rave Racer (Rev. RV1, Japan)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) // 06/29/95 +GAME( 1994, acedrvrw, 0, namcos22, acedrvr, namcos22_state, acedrvr, ROT0, "Namco", "Ace Driver: Racing Evolution (Rev. AD2, World)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) // 94/10/20 16:22:25 +GAME( 1996, victlapw, 0, namcos22, victlap, namcos22_state, victlap, ROT0, "Namco", "Ace Driver: Victory Lap (Rev. ADV2, World)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) // 96/02/13 17:50:06 /* Super System22 games */ GAME( 1994, alpinerd, 0, alpine, alpiner, namcos22_state, alpiner, ROT0, "Namco", "Alpine Racer (Rev. AR2 Ver.D, World)" , MACHINE_IMPERFECT_GRAPHICS ) GAME( 1994, alpinerc, alpinerd, alpine, alpiner, namcos22_state, alpiner, ROT0, "Namco", "Alpine Racer (Rev. AR2 Ver.C, World)" , MACHINE_IMPERFECT_GRAPHICS ) GAME( 1995, airco22b, 0, airco22b, airco22, namcos22_state, airco22, ROT0, "Namco", "Air Combat 22 (Rev. ACS1 Ver.B, Japan)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) // various problems -GAME( 1995, cybrcycc, 0, cybrcycc, cybrcycc, namcos22_state, cybrcyc, ROT0, "Namco", "Cyber Cycles (Rev. CB2 Ver.C, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 95/04/04 +GAME( 1995, cybrcycc, 0, cybrcycc, cybrcycc, namcos22_state, cybrcyc, ROT0, "Namco", "Cyber Cycles (Rev. CB2 Ver.C, World)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN ) // 95/04/04 GAME( 1995, dirtdash, 0, dirtdash, dirtdash, namcos22_state, dirtdash, ROT0, "Namco", "Dirt Dash (Rev. DT2, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 95/12/20 20:01:56 GAME( 1995, timecris, 0, timecris, timecris, namcos22_state, timecris, ROT0, "Namco", "Time Crisis (Rev. TS2 Ver.B, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 96/04/02 18:48:00 GAME( 1995, timecrisa,timecris, timecris, timecris, namcos22_state, timecris, ROT0, "Namco", "Time Crisis (Rev. TS2 Ver.A, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 96/01/08 18:56:09 GAME( 1996, propcycl, 0, propcycl, propcycl, namcos22_state, propcycl, ROT0, "Namco", "Prop Cycle (Rev. PR2 Ver.A, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 96/06/18 21:22:13 GAME( 1996, alpinesa, 0, alpinesa, alpiner, namcos22_state, alpinesa, ROT0, "Namco", "Alpine Surfer (Rev. AF2 Ver.A, World)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) // 96/07/01 15:19:23. major gfx problems, slave dsp? -GAME( 1996, tokyowar, 0, tokyowar, tokyowar, namcos22_state, tokyowar, ROT0, "Namco", "Tokyo Wars (Rev. TW2 Ver.A, World)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) // 96/09/03 14:08:47. near-invincible tanks, maybe related to timecris helicopter bug? +GAME( 1996, tokyowar, 0, tokyowar, tokyowar, namcos22_state, tokyowar, ROT0, "Namco", "Tokyo Wars (Rev. TW2 Ver.A, World)" , MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_NOT_WORKING ) // 96/09/03 14:08:47. near-invincible tanks, maybe related to timecris helicopter bug? GAME( 1996, aquajet, 0, cybrcycc, aquajet, namcos22_state, aquajet, ROT0, "Namco", "Aqua Jet (Rev. AJ2 Ver.B, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 96/09/20 14:28:30 GAME( 1996, alpinr2b, 0, alpine, alpiner, namcos22_state, alpiner2, ROT0, "Namco", "Alpine Racer 2 (Rev. ARS2 Ver.B, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 97/01/10 17:10:59 GAME( 1996, alpinr2a, alpinr2b, alpine, alpiner, namcos22_state, alpiner2, ROT0, "Namco", "Alpine Racer 2 (Rev. ARS2 Ver.A, World)" , MACHINE_IMPERFECT_GRAPHICS ) // 96/12/06 13:45:05 diff --git a/src/mame/drivers/nanos.cpp b/src/mame/drivers/nanos.cpp index 605993d13c8..99e10a1c303 100644 --- a/src/mame/drivers/nanos.cpp +++ b/src/mame/drivers/nanos.cpp @@ -16,7 +16,7 @@ #include "machine/timer.h" #include "machine/upd765.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80pio.h" #include "formats/nanos_dsk.h" @@ -72,8 +72,8 @@ private: required_device<z80pio_device> m_pio; required_device<z80pio_device> m_pio_0; required_device<z80pio_device> m_pio_1; - required_device<z80sio0_device> m_sio_0; - required_device<z80sio0_device> m_sio_1; + required_device<z80sio_device> m_sio_0; + required_device<z80sio_device> m_sio_1; required_device<z80ctc_device> m_ctc_0; required_device<z80ctc_device> m_ctc_1; required_device<upd765a_device> m_fdc; @@ -144,7 +144,7 @@ static ADDRESS_MAP_START( nanos_io , AS_IO, 8, nanos_state) /* I/O card */ AM_RANGE(0x80, 0x83) AM_DEVREADWRITE("z80pio_0", z80pio_device, read, write) - AM_RANGE(0x84, 0x87) AM_DEVREADWRITE("z80sio_0", z80sio0_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x84, 0x87) AM_DEVREADWRITE("z80sio_0", z80sio_device, ba_cd_r, ba_cd_w) AM_RANGE(0x88, 0x8B) AM_DEVREADWRITE("z80pio_1", z80pio_device, read, write) AM_RANGE(0x8C, 0x8F) AM_DEVREADWRITE("z80ctc_0", z80ctc_device, read, write) @@ -152,7 +152,7 @@ static ADDRESS_MAP_START( nanos_io , AS_IO, 8, nanos_state) AM_RANGE(0x92, 0x92) AM_WRITE(nanos_tc_w) AM_RANGE(0x94, 0x95) AM_DEVICE("upd765", upd765a_device, map) /* V24+IFSS card */ - AM_RANGE(0xA0, 0xA3) AM_DEVREADWRITE("z80sio_0", z80sio0_device, ba_cd_r, ba_cd_w) + AM_RANGE(0xA0, 0xA3) AM_DEVREADWRITE("z80sio_0", z80sio_device, ba_cd_r, ba_cd_w) AM_RANGE(0xA4, 0xA7) AM_DEVREADWRITE("z80ctc_1", z80ctc_device, read, write) /* 256-k RAM card I - 64k OS-Memory + 192k-RAM-Floppy */ @@ -492,11 +492,11 @@ static MACHINE_CONFIG_START( nanos ) MCFG_DEVICE_ADD("z80pio_1", Z80PIO, XTAL_4MHz) MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("z80sio_0", Z80SIO0, XTAL_4MHz) - MCFG_Z80DART_OUT_INT_CB(WRITELINE(nanos_state, z80daisy_interrupt)) + MCFG_DEVICE_ADD("z80sio_0", Z80SIO, XTAL_4MHz) + MCFG_Z80SIO_OUT_INT_CB(WRITELINE(nanos_state, z80daisy_interrupt)) - MCFG_DEVICE_ADD("z80sio_1", Z80SIO0, XTAL_4MHz) - MCFG_Z80DART_OUT_INT_CB(WRITELINE(nanos_state, z80daisy_interrupt)) + MCFG_DEVICE_ADD("z80sio_1", Z80SIO, XTAL_4MHz) + MCFG_Z80SIO_OUT_INT_CB(WRITELINE(nanos_state, z80daisy_interrupt)) MCFG_DEVICE_ADD("z80pio", Z80PIO, XTAL_4MHz) MCFG_Z80PIO_IN_PA_CB(READ8(nanos_state, nanos_port_a_r)) diff --git a/src/mame/drivers/naomi.cpp b/src/mame/drivers/naomi.cpp index 3bd95652e08..75dbbca1870 100644 --- a/src/mame/drivers/naomi.cpp +++ b/src/mame/drivers/naomi.cpp @@ -665,6 +665,7 @@ Melty Blood Actress Again 841-0061C not present 6 Melty Blood Actress Again Version A (Rev A) 841-0061C 24455 6 (512Mb) present 317-5133-JPN present IC2# is labeled "REV.A" - IC4# is marked "5A" Mushiking - The King Of Beetles II ENG (Ver. 1.001) 840-0164C not present 2 (512Mb) present 317-0437-COM present requires 610-0669 barcode reader, 838-14245-92 "MAPLE/232C CONVERT BD" (MIE-based), 838-14243 "RFID CHIP R/W BD" and RFID chip Mushiking - The King Of Beetles II ENG (Ver. 2.001) 840-0164C 24357 2 (512Mb) present 317-0437-COM present IC4# is marked "18" +Mushiking - The King Of Beetles IV ENG 840-0180C not present 2 (512Mb) present 317-0437-COM present IC2# is labeled "VER.1", IC4# is marked "8A", requires 610-0669 barcode reader, 838-14245-92 "MAPLE/232C CONVERT BD" (MIE-based), 838-14243 "RFID CHIP R/W BD" and RFID chip Pokasuka Ghost! 840-0170C not present 5 (512Mb) present 317-0461-COM present requires 837-14672 sensor board (SH4 based) Radirgy Noa 841-0062C not present 4 (512Mb) present 317-5138-JPN present IC2# is labeled "VER.2" - IC4# is marked "8A" Rhythm Tengoku 841-0177C not present 4 (512Mb) present 317-0503-JPN present IC2# is labeled "VER.2" - IC4# is marked "8A" @@ -4412,7 +4413,7 @@ ROM_START( tduno2 ) ROM_PARAMETER( ":rom_board:key", "2f6f0f8d" ) ROM_END -ROM_START( mtkob2 ) +ROM_START( mushike ) NAOMI_BIOS NAOMI_DEFAULT_EEPROM @@ -6081,7 +6082,7 @@ ROM_START( mushi2eo ) ROM_LOAD( "fpr-24334.ic9", 0x4000000, 0x4000000, CRC(13d2d1dc) SHA1(6a47cfaddf006e6ff46837fac956fbcc20619d79) ) ROM_REGION( 0x800, "pic_readout", 0 ) - ROM_LOAD( "317-0437-com.ic3", 0, 0x800, BAD_DUMP CRC(b6e4f61a) SHA1(b5cae574170afa3889e01517f1c4429e207042b9) ) + ROM_LOAD( "317-0437-com.ic3", 0, 0x800, CRC(3b6fcee8) SHA1(65fbdd3b8c61a4b5ccb6389b25483a7ecdc0794d) ) ROM_PARAMETER( ":rom_board:id", "5502" ) ROM_END @@ -6096,11 +6097,26 @@ ROM_START( mushik2e ) ROM_LOAD( "fpr-24334.ic9", 0x4000000, 0x4000000, CRC(13d2d1dc) SHA1(6a47cfaddf006e6ff46837fac956fbcc20619d79) ) ROM_REGION( 0x800, "pic_readout", 0 ) - ROM_LOAD( "317-0437-com.ic3", 0, 0x800, BAD_DUMP CRC(b6e4f61a) SHA1(b5cae574170afa3889e01517f1c4429e207042b9) ) + ROM_LOAD( "317-0437-com.ic3", 0, 0x800, CRC(3b6fcee8) SHA1(65fbdd3b8c61a4b5ccb6389b25483a7ecdc0794d) ) ROM_PARAMETER( ":rom_board:id", "5582" ) ROM_END +// change game version (4/5/6): in BACKUP DATA CLEAR menu hold P1 and P2 buttons 1 for 3 seconds, then change version number in appeared menu and select YES(CLEAR) +ROM_START( mushik4e ) + NAOMI_BIOS + NAOMI_DEFAULT_EEPROM + + ROM_REGION( 0x8000000, "rom_board", ROMREGION_ERASEFF) + ROM_LOAD( "fpr-24417.ic8", 0x0000000, 0x4000000, CRC(01278cbb) SHA1(98da275314f0aedf60c3de0c128b4a48a1ede483) ) + ROM_LOAD( "fpr-24418.ic9", 0x4000000, 0x4000000, CRC(7c8d7687) SHA1(ef2c9da286b73428e5b51260b764aa78a40d6fd5) ) + + ROM_REGION( 0x800, "pic_readout", 0 ) + ROM_LOAD( "317-0437-com.ic3", 0, 0x800, CRC(3b6fcee8) SHA1(65fbdd3b8c61a4b5ccb6389b25483a7ecdc0794d) ) + + ROM_PARAMETER( ":rom_board:id", "5502" ) +ROM_END + ROM_START( zunou ) NAOMI_BIOS NAOMI_DEFAULT_EEPROM @@ -6828,7 +6844,7 @@ ROM_START( wrungpo ) // 838-12801 DRIVE BD WAVERUNNER ROM_REGION( 0x10000, "motorio", ROMREGION_ERASEFF) - ROM_LOAD( "epr-19250.ic8", 0x000000, 0x010000, NO_DUMP ) + ROM_LOAD( "epr-19250.ic8", 0x000000, 0x010000, CRC(542d3836) SHA1(128cb0bfaf05791d219437653002f6bb948a4ad5) ) // 840-0064-01 2001 317-0306-COM Naomi ROM_PARAMETER( ":rom_board:segam2crypt:key", "284ae7c3") @@ -6849,7 +6865,7 @@ ROM_START( wrungp ) // 838-12801 DRIVE BD WAVERUNNER ROM_REGION( 0x10000, "motorio", ROMREGION_ERASEFF) - ROM_LOAD( "epr-19250.ic8", 0x000000, 0x010000, NO_DUMP ) + ROM_LOAD( "epr-19250.ic8", 0x000000, 0x010000, CRC(542d3836) SHA1(128cb0bfaf05791d219437653002f6bb948a4ad5) ) ROM_PARAMETER( ":rom_board:segam2crypt:key", "-1") // 315-5881 not populated ROM_END @@ -10210,21 +10226,21 @@ ROM_END /* 0136 */ GAME( 2004, shootplm, naomi, naomim1, naomi, naomi_state, naomi, ROT0, "Sega", "Shootout Pool Prize (Export) / Shootout Pool The Medal (Japan) Version B", GAME_FLAGS ) // Build: 23 Jan 2004 /* 0136 */ GAME( 2004, shootplmp, shootplm, naomim2, naomi, naomi_state, naomi, ROT0, "Sega", "Shootout Pool Prize (Export) / Shootout Pool The Medal (Japan) Version B (prototype)", GAME_FLAGS ) // Build: 15 Dec 2003 /* 0140 */ GAME( 2004, kick4csh, naomi, naomim1, naomi, naomi_state, naomi, ROT0, "Sega", "Kick '4' Cash (Export)", GAME_FLAGS ) -/* 0150 */ GAME( 2003, mtkob2, naomi, naomim1, naomi, naomi_state, naomi, ROT0, "Sega", "Mushiking The King Of Beetle (2K3 2ND, World)", GAME_FLAGS ) // not for Japan +/* 0150 */ GAME( 2004, mushike, naomi, naomim1, naomi, naomi_state, naomi, ROT0, "Sega", "Mushiking The King Of Beetle (2K3 2ND, World)", GAME_FLAGS ) // not for Japan /* 0152 */ GAME( 2004, mushi2k4, naomi, naomim2, naomi, naomi_state, naomi, ROT0, "Sega", "Mushiking The King Of Beetles 2004 Second (Japan)", GAME_FLAGS ) /* 0158 */ GAME( 2005, mushi2k5, naomi, naomim2, naomi, naomi_state, naomi, ROT0, "Sega", "Mushiking The King Of Beetles 2005 First (Japan)", GAME_FLAGS ) -/* 0164 */ GAME( 2005, mushi2eo, mushik2e, naomim4, naomi, naomi_state, naomi, ROT0, "Sega", "Mushiking The King Of Beetles - Mushiking II / III / III+ (Ver. 1.001) (World)", GAME_FLAGS ) // not for Japan, version can be changed in secret menu -/* 0164 */ GAME( 2005, mushik2e, naomi, naomim4, naomi, naomi_state, naomi, ROT0, "Sega", "Mushiking The King Of Beetles - Mushiking II / III / III+ (Ver. 2.001) (World)", GAME_FLAGS ) // not for Japan, version can be changed in secret menu +/* 0164 */ GAME( 2005, mushi2eo, mushik2e, naomim4, naomi, naomi_state, naomi, ROT0, "Sega", "Mushiking The King Of Beetles - Mushiking II / III / III+ (Ver. 1.001) (World)", GAME_FLAGS ) // not for Japan or Korea, version can be changed in secret menu, ~equivalent of Japanese 2K5 versions. +/* 0164 */ GAME( 2005, mushik2e, naomi, naomim4, naomi, naomi_state, naomi, ROT0, "Sega", "Mushiking The King Of Beetles - Mushiking II / III / III+ (Ver. 2.001) (World)", GAME_FLAGS ) // not for Japan or Korea, version can be changed in secret menu, ~equivalent of Japanese 2K5 versions. /* 0166 */ GAME( 2006, zunou, naomi, naomim4, naomi, naomi_state, naomi, ROT0, "Sega", "Touch De Zunou (Japan, Rev A)", GAME_FLAGS ) /* 0170-01 */ GAME( 2007, manicpnc, naomi, naomim4, naomi, naomi_state, naomi, ROT0, "Sega", "Manic Panic Ghosts! (USA, Export)", GAME_FLAGS ) /* 0170 */ GAME( 2007, pokasuka, manicpnc, naomim4, naomi, naomi_state, naomi, ROT0, "Sega", "Pokasuka Ghost! (Japan)", GAME_FLAGS ) /* 0175 */ GAME( 2007, asndynmt, naomi, naomim4, naomi, naomi_state, naomi, ROT0, "Sega", "Asian Dynamite / Dynamite Deka EX", GAME_FLAGS ) /* 0177 */ GAME( 2007, rhytngk, naomi, naomim4, naomi, naomi_state, naomi, ROT0, "Sega / Nintendo - J.P ROOM", "Rhythm Tengoku (Japan)", GAME_FLAGS ) -// 0180 Mushiking IV (World) +/* 0180 */ GAME( 2007, mushik4e, naomi, naomim4, naomi, naomi_state, naomi, ROT0, "Sega", "Mushiking The King Of Beetles - Mushiking IV / V / VI (World)", GAME_FLAGS ) // not for Japan or Korea, version can be changed in secret menu, ~equivalent of Japanese 2K6 versions. /* 0186 */ GAME( 2009, shorsepr, naomi, naomim4, naomi, naomi_state, naomi, ROT270,"Sega", "Star Horse Progress Returns (satellite)", GAME_FLAGS ) // 0xxx Mushiking 2K3 1ST (Japan) // 0xxx Mushiking 2K4 1ST (Japan) -// 0xxx Mushiking 2K5 2ND (Japan) note: starting from ver 2K6 was moved to SystemSP platform and later to PC-based hardware +// 0xxx Mushiking 2K5 2ND (Japan) note: starting from ver 2K6 2ND was moved to SystemSP platform and later to PC-based hardware // 0xxx Star Horse 2001 (main screens, server) // 0xxx Star Horse 2002 (whole set) // 0xxx Star Horse Progress Returns (main screens, server) diff --git a/src/mame/drivers/nbmj9195.cpp b/src/mame/drivers/nbmj9195.cpp index f71ca4c4c80..d446b6f9194 100644 --- a/src/mame/drivers/nbmj9195.cpp +++ b/src/mame/drivers/nbmj9195.cpp @@ -3467,4 +3467,4 @@ GAME( 1994, mscoutm, 0, mscoutm, mscoutm, nbmj9195_state, nbmj9195, RO GAME( 1994, imekura, 0, imekura, imekura, nbmj9195_state, nbmj9195, ROT0, "Sphinx / AV Japan", "Imekura Mahjong (Japan)", MACHINE_SUPPORTS_SAVE ) GAME( 1994, mjegolf, 0, mjegolf, mjegolf, nbmj9195_state, nbmj9195, ROT0, "Fujic / AV Japan", "Mahjong Erotica Golf (Japan)", MACHINE_SUPPORTS_SAVE ) -GAME( 199?, shabdama, 0, shabdama, mjuraden, nbmj9195_state, nbmj9195, ROT0, "Nichibutsu", "LD Mahjong #4 Shabon-Dama", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1991, shabdama, 0, shabdama, mjuraden, nbmj9195_state, nbmj9195, ROT0, "Nichibutsu", "LD Mahjong #4 Shabon-Dama", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/nds.cpp b/src/mame/drivers/nds.cpp index 485d7c45a42..1effc73ba92 100644 --- a/src/mame/drivers/nds.cpp +++ b/src/mame/drivers/nds.cpp @@ -1,10 +1,16 @@ // license:BSD-3-Clause -// copyright-holders:Ryan Holtz +// copyright-holders:Ryan Holtz, R. Belmont /*************************************************************************** - ds.cpp + nds.cpp - Skeleton driver for first-generation Nintendo DS. + Preliminary driver for first-generation Nintendo DS. + + Tech info: http://problemkaputt.de/gbatek.htm + + Notes: + Timers and DMAs 0-3 are ARM9's, 4-7 are ARM7's. + Interrupt registers [0] is ARM9, [1] is ARM7. ***************************************************************************/ @@ -13,6 +19,44 @@ #define VERBOSE_LEVEL (0) +// Measured value from GBATEK. Actual crystal unknown. +#define MASTER_CLOCK (33513982) + +#define INT_VBL 0x00000001 +#define INT_HBL 0x00000002 +#define INT_VCNT 0x00000004 +#define INT_TM0_OVERFLOW 0x00000008 +#define INT_TM1_OVERFLOW 0x00000010 +#define INT_TM2_OVERFLOW 0x00000020 +#define INT_TM3_OVERFLOW 0x00000040 +#define INT_SIO 0x00000080 // also RCNT/RTC (arm7 only) +#define INT_DMA0 0x00000100 +#define INT_DMA1 0x00000200 +#define INT_DMA2 0x00000400 +#define INT_DMA3 0x00000800 +#define INT_KEYPAD 0x00001000 +#define INT_GAMEPAK 0x00002000 // GBA slot IRQ line (never used?) +#define INT_NA1 0x00004000 // unused +#define INT_NA2 0x00008000 // unused +#define INT_IPCSYNC 0x00010000 +#define INT_IPCSENDEMPTY 0x00020000 +#define INT_IPCRECVNOTEMPTY 0x00040000 +#define INT_CARDXFERCOMPLETE 0x00080000 +#define INT_CARDIREQ 0x00100000 +#define INT_GEOCMDFIFO 0x00200000 // arm9 only +#define INT_SCREENUNFOLD 0x00400000 // arm7 only +#define INT_SPIBUS 0x00800000 // arm7 only +#define INT_WIFI 0x01000000 // arm7 only - also DSP on DSi +#define INT_CAMERA 0x02000000 // DSi only +#define INT_NA3 0x04000000 +#define INT_NA4 0x08000000 +#define INT_NEWDMA0 0x10000000 // DSi only +#define INT_NEWDMA1 0x20000000 // DSi only +#define INT_NEWDMA2 0x40000000 // DSi only +#define INT_NEWDMA3 0x80000000 // DSi only + +static const uint32_t timer_clks[4] = { MASTER_CLOCK, MASTER_CLOCK / 64, MASTER_CLOCK / 256, MASTER_CLOCK / 1024 }; + static inline void ATTR_PRINTF(3,4) verboselog(device_t &device, int n_level, const char *s_fmt, ...) { if( VERBOSE_LEVEL >= n_level ) @@ -28,13 +72,121 @@ static inline void ATTR_PRINTF(3,4) verboselog(device_t &device, int n_level, co READ32_MEMBER(nds_state::arm7_io_r) { + uint8_t temp1, temp2; switch(offset) { + case TIMER_OFFSET: + case TIMER_OFFSET+1: + case TIMER_OFFSET+2: + case TIMER_OFFSET+3: + { + uint32_t elapsed; + double time, ticks; + int timer = (offset - TIMER_OFFSET) + 4; + + printf("Read timer reg %x (PC=%x)\n", timer, space.device().safe_pc()); + + // update times for + if (m_timer_regs[timer] & 0x800000) + { + if (m_timer_regs[timer] & 0x00040000) + { + elapsed = m_timer_regs[timer] & 0xffff; + } + else + { + time = 0.1; //m_tmr_timer[timer]->elapsed().as_double(); + + ticks = (double)(0x10000 - (m_timer_regs[timer] & 0xffff)); + + // printf("time %f ticks %f 1/hz %f\n", time, ticks, 1.0 / m_timer_hz[timer]); + + time *= ticks; + time /= (1.0 / m_timer_hz[timer]); + + elapsed = (uint32_t)time; + } + +// printf("elapsed = %x\n", elapsed); + } + else + { +// printf("Reading inactive timer!\n"); + elapsed = 0; + } + + return (m_timer_regs[timer] & 0xffff0000) | (elapsed & 0xffff); + } + break; + + case IME_OFFSET: + return m_ime[1]; + + case IE_OFFSET: + return m_ie[1]; + + case IF_OFFSET: + return m_if[1]; + + case IPCSYNC_OFFSET: + return m_arm7_ipcsync; + + case AUX_SPI_CNT_OFFSET: + printf("arm7: read AUX_SPI_CNT mask %08x\n", mem_mask); + return 0; + break; + + case GAMECARD_BUS_CTRL_OFFSET: + //printf("arm7: read GAMECARD_BUS_CTRL (%08x) mask %08x\n", m_gamecard_ctrl, mem_mask); + return m_gamecard_ctrl; + break; + + case GAMECARD_DATA_OFFSET: + printf("arm7: read to GAMECARD_DATA mask %08x\n", mem_mask); + return 0xffffffff; + break; + + case GAMECARD_DATA_2_OFFSET: + printf("arm7: read to GAMECARD_DATA2 mask %08x\n", mem_mask); + return 0xffffffff; + break; + + case GAMECARD_DATA_IN_OFFSET: + //printf("arm7: read to GAMECARD_DATA_IN mask %08x (len = %x)\n", mem_mask, m_cartdata_len); + if (m_cartdata_len >= 4) + { + m_cartdata_len -= 4; + } + else + { + m_cartdata_len = 0; + } + + if (m_cartdata_len == 0) + { + printf("NDS: xfer over\n"); + m_gamecard_ctrl &= ~GAMECARD_DATA_READY; + m_gamecard_ctrl &= ~GAMECARD_BLOCK_BUSY; + } + return 0xffffffff; + break; + + case SPI_CTRL_OFFSET: + //printf("arm7: read SPI_CTRL mask %08x\n", mem_mask); + return 0; + break; + case POSTFLG_OFFSET: /* Bit Use * 0 0=Booting, 1=Booted (set by BIOS/firmware) */ return m_arm7_postflg; + + case WRAMSTAT_OFFSET: + temp1 = (((m_vramcntc & 3) == 2) && (m_vramcntc & 0x80)) ? 1 : 0; + temp2 = (((m_vramcntd & 3) == 2) && (m_vramcntd & 0x80)) ? 2 : 0; + return (m_wramcnt << 8) | temp1 | temp2; + default: verboselog(*this, 0, "[ARM7] [IO] Unknown read: %08x (%08x)\n", offset*4, mem_mask); break; @@ -47,6 +199,139 @@ WRITE32_MEMBER(nds_state::arm7_io_w) { switch(offset) { + case TIMER_OFFSET: + case TIMER_OFFSET+1: + case TIMER_OFFSET+2: + case TIMER_OFFSET+3: + { + double rate, clocksel; + uint32_t old_timer_regs; + + int timer = (offset - TIMER_OFFSET)+4; + + old_timer_regs = m_timer_regs[timer]; + + m_timer_regs[timer] = (m_timer_regs[timer] & ~(mem_mask & 0xFFFF0000)) | (data & (mem_mask & 0xFFFF0000)); + + printf("%08x to timer %d (mask %08x PC %x)\n", data, timer, ~mem_mask, space.device().safe_pc()); + + if (ACCESSING_BITS_0_15) + { + m_timer_reload[timer] = ((m_timer_reload[timer] & ~mem_mask) | (data & mem_mask)) & 0x0000FFFF; + m_timer_recalc[timer] = 1; + } + + // enabling this timer? + if ((ACCESSING_BITS_16_31) && (data & 0x800000)) + { + double final; + + if ((old_timer_regs & 0x00800000) == 0) // start bit 0 -> 1 + { + m_timer_regs[timer] = (m_timer_regs[timer] & 0xFFFF0000) | (m_timer_reload[timer] & 0x0000FFFF); + } + + rate = 0x10000 - (m_timer_regs[timer] & 0xffff); + + clocksel = timer_clks[(m_timer_regs[timer] >> 16) & 3]; + + final = clocksel / rate; + + m_timer_hz[timer] = final; + + m_timer_recalc[timer] = 0; + + printf("Enabling timer %d @ %f Hz regs %08x\n", timer, final, m_timer_regs[timer]); + + // enable the timer + if( !(data & 0x40000) ) // if we're not in Count-Up mode + { + attotime time = attotime::from_hz(final); + m_tmr_timer[timer]->adjust(time, timer, time); + } + } + } + break; + + case IME_OFFSET: + printf("ARM7: %08x to IME\n", data); + COMBINE_DATA(&m_ime[1]); + break; + + case IE_OFFSET: + printf("ARM7: %08x to IE\n", data); + COMBINE_DATA(&m_ie[1]); + break; + + case IF_OFFSET: + COMBINE_DATA(&m_if[1]); + break; + + case IPCSYNC_OFFSET: + //printf("ARM7: %x to IPCSYNC\n", data); + m_arm9_ipcsync &= ~0xf; + m_arm9_ipcsync |= ((data >> 8) & 0xf); + m_arm7_ipcsync &= 0xf; + m_arm7_ipcsync |= (data & ~0xf); + break; + + case AUX_SPI_CNT_OFFSET: + //printf("arm7: %08x to AUX_SPI_CNT mask %08x\n", data, mem_mask); + m_spicnt &= 0x0080; + m_spicnt |= (data & 0xe043); + + break; + + case GAMECARD_BUS_CTRL_OFFSET: + //printf("arm7: %08x to GAMECARD_BUS_CTRL mask %08x\n", data, mem_mask); + m_gamecard_ctrl &= GAMECARD_DATA_READY; + m_gamecard_ctrl |= (data & ~GAMECARD_DATA_READY); + + if (!(m_spicnt & (1<<15))) + { + return; + } + + if (!(m_gamecard_ctrl & GAMECARD_BLOCK_BUSY)) + { + return; + } + + m_cartdata_len = (m_gamecard_ctrl >> 24) & 7; + if (m_cartdata_len == 7) + { + m_cartdata_len = 4; + } + else if (m_cartdata_len != 0) + { + m_cartdata_len = 256 << m_cartdata_len; + } + printf("nds: cartdata for transfer = %x\n", m_cartdata_len); + + if (m_cartdata_len > 0) + { + m_gamecard_ctrl |= GAMECARD_DATA_READY; + } + else + { + printf("NDS: xfer over\n"); + m_gamecard_ctrl &= ~GAMECARD_DATA_READY; + m_gamecard_ctrl &= ~GAMECARD_BLOCK_BUSY; + } + break; + + case GAMECARD_DATA_OFFSET: + //printf("arm7: %08x to GAMECARD_DATA mask %08x\n", data, mem_mask); + break; + + case GAMECARD_DATA_2_OFFSET: + //printf("arm7: %08x to GAMECARD_DATA2 mask %08x\n", data, mem_mask); + break; + + case SPI_CTRL_OFFSET: + //printf("arm7: %08x to SPI_CTRL mask %08x\n", data, mem_mask); + break; + case POSTFLG_OFFSET: /* Bit Use * 0 0=Booting, 1=Booted (set by BIOS/firmware) @@ -56,6 +341,16 @@ WRITE32_MEMBER(nds_state::arm7_io_w) m_arm7_postflg &= ~POSTFLG_PBF_MASK; m_arm7_postflg |= data & POSTFLG_PBF_MASK; } + + if (ACCESSING_BITS_8_15) + { + if ((data>>8) & 0x80) + { + printf("arm7: HALT\n"); // halts the arm7 until an interrupt occurs + m_arm7->suspend(SUSPEND_REASON_HALT, 1); + m_arm7halted = true; + } + } break; default: verboselog(*this, 0, "[ARM7] [IO] Unknown write: %08x = %08x (%08x)\n", offset*4, data, mem_mask); @@ -67,6 +362,62 @@ READ32_MEMBER(nds_state::arm9_io_r) { switch(offset) { + case TIMER_OFFSET: + case TIMER_OFFSET+1: + case TIMER_OFFSET+2: + case TIMER_OFFSET+3: + { + uint32_t elapsed; + double time, ticks; + int timer = (offset - TIMER_OFFSET); + + //printf("Read timer reg %x (PC=%x)\n", timer, space.device().safe_pc()); + + // update times for + if (m_timer_regs[timer] & 0x800000) + { + if (m_timer_regs[timer] & 0x00040000) + { + elapsed = m_timer_regs[timer] & 0xffff; + } + else + { + time = 0.1; //m_tmr_timer[timer]->elapsed().as_double(); + + ticks = (double)(0x10000 - (m_timer_regs[timer] & 0xffff)); + + // printf("time %f ticks %f 1/hz %f\n", time, ticks, 1.0 / m_timer_hz[timer]); + + time *= ticks; + time /= (1.0 / m_timer_hz[timer]); + + elapsed = (uint32_t)time; + } + +// printf("elapsed = %x\n", elapsed); + } + else + { +// printf("Reading inactive timer!\n"); + elapsed = 0; + } + + return (m_timer_regs[timer] & 0xffff0000) | (elapsed & 0xffff); + } + break; + + case IME_OFFSET: + return m_ime[0]; + + case IE_OFFSET: + return m_ie[0]; + + case IF_OFFSET: + return m_if[0]; + + case IPCSYNC_OFFSET: + return m_arm9_ipcsync; + case POSTFLG_OFFSET: /* Bit Use * 0 0=Booting, 1=Booted (set by BIOS/firmware) @@ -85,6 +436,133 @@ WRITE32_MEMBER(nds_state::arm9_io_w) { switch(offset) { + case TIMER_OFFSET: + case TIMER_OFFSET+1: + case TIMER_OFFSET+2: + case TIMER_OFFSET+3: + { + double rate, clocksel; + uint32_t old_timer_regs; + + int timer = (offset - TIMER_OFFSET)+4; + + old_timer_regs = m_timer_regs[timer]; + + m_timer_regs[timer] = (m_timer_regs[timer] & ~(mem_mask & 0xFFFF0000)) | (data & (mem_mask & 0xFFFF0000)); + + printf("%x to timer %d (mask %x PC %x)\n", data, timer, ~mem_mask, space.device().safe_pc()); + + if (ACCESSING_BITS_0_15) + { + m_timer_reload[timer] = ((m_timer_reload[timer] & ~mem_mask) | (data & mem_mask)) & 0x0000FFFF; + m_timer_recalc[timer] = 1; + } + + // enabling this timer? + if ((ACCESSING_BITS_16_31) && (data & 0x800000)) + { + double final; + + if ((old_timer_regs & 0x00800000) == 0) // start bit 0 -> 1 + { + m_timer_regs[timer] = (m_timer_regs[timer] & 0xFFFF0000) | (m_timer_reload[timer] & 0x0000FFFF); + } + + rate = 0x10000 - (m_timer_regs[timer] & 0xffff); + + clocksel = timer_clks[(m_timer_regs[timer] >> 16) & 3]; + + final = clocksel / rate; + + m_timer_hz[timer] = final; + + m_timer_recalc[timer] = 0; + + printf("Enabling timer %d @ %f Hz\n", timer, final); + + // enable the timer + if( !(data & 0x40000) ) // if we're not in Count-Up mode + { + attotime time = attotime::from_hz(final); + m_tmr_timer[timer]->adjust(time, timer, time); + } + } + } + break; + + case IME_OFFSET: + printf("ARM9: %08x to IME\n", data); + COMBINE_DATA(&m_ime[0]); + break; + + case IE_OFFSET: + printf("ARM9: %08x to IE\n", data); + COMBINE_DATA(&m_ie[0]); + break; + + case IF_OFFSET: + COMBINE_DATA(&m_if[0]); + break; + + case IPCSYNC_OFFSET: + printf("ARM9: %x to IPCSYNC\n", data); + m_arm7_ipcsync &= ~0xf; + m_arm7_ipcsync |= ((data >> 8) & 0xf); + m_arm9_ipcsync &= 0xf; + m_arm9_ipcsync |= (data & ~0xf); + break; + + case VRAMCNT_A_OFFSET: + if (ACCESSING_BITS_0_7) // VRAMCNT_A + { + m_vramcnta = data & 0xff; + } + if (ACCESSING_BITS_8_15) // VRAMCNT_B + { + m_vramcntb = (data >> 8) & 0xff; + } + if (ACCESSING_BITS_16_23) // VRAMCNT_C + { + m_vramcntc = (data >> 16) & 0xff; + } + if (ACCESSING_BITS_24_31) // VRAMCNT_D + { + m_vramcntd = (data >> 24) & 0xff; + } + break; + + case WRAMCNT_OFFSET: + if (ACCESSING_BITS_0_7) // VRAMCNT_E + { + m_vramcnte = data & 0xff; + } + if (ACCESSING_BITS_8_15) // VRAMCNT_F + { + m_vramcntf = (data >> 8) & 0xff; + } + if (ACCESSING_BITS_16_23) // VRAMCNT_G + { + m_vramcntg = (data >> 16) & 0xff; + } + if (ACCESSING_BITS_24_31) // WRAMCNT + { + m_wramcnt = (data>>24) & 0x3; + m_arm7wrambnk->set_bank(m_wramcnt); + m_arm9wrambnk->set_bank(m_wramcnt); + } + break; + + case VRAMCNT_H_OFFSET: + if (ACCESSING_BITS_0_7) // VRAMCNT_H + { + m_vramcnth = data & 0xff; + } + if (ACCESSING_BITS_8_15) // VRAMCNT_I + { + m_vramcnti = (data >> 8) & 0xff; + } + break; + case POSTFLG_OFFSET: /* Bit Use * 0 0=Booting, 1=Booted (set by BIOS/firmware) @@ -105,38 +583,409 @@ WRITE32_MEMBER(nds_state::arm9_io_w) } static ADDRESS_MAP_START( nds_arm7_map, AS_PROGRAM, 32, nds_state ) - AM_RANGE(0x00000000, 0x00003fff) AM_ROM - AM_RANGE(0x02000000, 0x023fffff) AM_RAM AM_SHARE("mainram") - AM_RANGE(0x03800000, 0x0380ffff) AM_RAM - AM_RANGE(0x04000000, 0x0400ffff) AM_READWRITE(arm7_io_r, arm7_io_w) + AM_RANGE(0x00000000, 0x00003fff) AM_ROM AM_REGION("arm7", 0) + AM_RANGE(0x02000000, 0x023fffff) AM_RAM AM_MIRROR(0x00400000) AM_SHARE("mainram") + AM_RANGE(0x03000000, 0x03007fff) AM_MIRROR(0x007f8000) AM_DEVICE("nds7wram", address_map_bank_device, amap32) + AM_RANGE(0x03800000, 0x0380ffff) AM_RAM AM_MIRROR(0x007f0000) AM_SHARE("arm7ram") + AM_RANGE(0x04000000, 0x0410ffff) AM_READWRITE(arm7_io_r, arm7_io_w) ADDRESS_MAP_END static ADDRESS_MAP_START( nds_arm9_map, AS_PROGRAM, 32, nds_state ) - AM_RANGE(0x00000000, 0x00000fff) AM_ROM - AM_RANGE(0x02000000, 0x023fffff) AM_RAM AM_SHARE("mainram") - AM_RANGE(0x04000000, 0x0400ffff) AM_READWRITE(arm9_io_r, arm9_io_w) + AM_RANGE(0x02000000, 0x023fffff) AM_RAM AM_MIRROR(0x00400000) AM_SHARE("mainram") + AM_RANGE(0x03000000, 0x03007fff) AM_MIRROR(0x00ff8000) AM_DEVICE("nds9wram", address_map_bank_device, amap32) + AM_RANGE(0x04000000, 0x0410ffff) AM_READWRITE(arm9_io_r, arm9_io_w) + AM_RANGE(0xffff0000, 0xffff0fff) AM_ROM AM_MIRROR(0x1000) AM_REGION("arm9", 0) +ADDRESS_MAP_END + +// ARM7 views of WRAM +static ADDRESS_MAP_START( nds7_wram_map, AS_PROGRAM, 32, nds_state ) + AM_RANGE(0x00000, 0x07fff) AM_READWRITE(wram_arm7mirror_r, wram_arm7mirror_w) + AM_RANGE(0x08000, 0x0bfff) AM_READWRITE(wram_first_half_r, wram_first_half_w) + AM_RANGE(0x0c000, 0x0ffff) AM_READWRITE(wram_first_half_r, wram_first_half_w) + AM_RANGE(0x10000, 0x13fff) AM_READWRITE(wram_second_half_r, wram_second_half_w) + AM_RANGE(0x14000, 0x17fff) AM_READWRITE(wram_second_half_r, wram_second_half_w) + AM_RANGE(0x18000, 0x1ffff) AM_READWRITE(wram_first_half_r, wram_first_half_w) +ADDRESS_MAP_END + +// ARM9 views of WRAM +static ADDRESS_MAP_START( nds9_wram_map, AS_PROGRAM, 32, nds_state ) + AM_RANGE(0x00000, 0x07fff) AM_READWRITE(wram_first_half_r, wram_first_half_w) + AM_RANGE(0x08000, 0x0bfff) AM_READWRITE(wram_second_half_r, wram_second_half_w) + AM_RANGE(0x0c000, 0x0ffff) AM_READWRITE(wram_second_half_r, wram_second_half_w) + AM_RANGE(0x10000, 0x13fff) AM_READWRITE(wram_first_half_r, wram_first_half_w) + AM_RANGE(0x14000, 0x17fff) AM_READWRITE(wram_first_half_r, wram_first_half_w) + AM_RANGE(0x18000, 0x1ffff) AM_NOP AM_WRITENOP // probably actually open bus? GBATEK describes as "random" ADDRESS_MAP_END +READ32_MEMBER(nds_state::wram_first_half_r) { return m_WRAM[offset]; } +READ32_MEMBER(nds_state::wram_second_half_r) { return m_WRAM[offset+0x4000]; } +WRITE32_MEMBER(nds_state::wram_first_half_w) { COMBINE_DATA(&m_WRAM[offset]); } +WRITE32_MEMBER(nds_state::wram_second_half_w) { COMBINE_DATA(&m_WRAM[offset+0x4000]); } +READ32_MEMBER(nds_state::wram_arm7mirror_r) { return m_arm7ram[offset]; } +WRITE32_MEMBER(nds_state::wram_arm7mirror_w) { COMBINE_DATA(&m_arm7ram[offset]); } + static INPUT_PORTS_START( nds ) INPUT_PORTS_END - void nds_state::machine_reset() { m_arm7_postflg = 0; m_arm9_postflg = 0; + m_wramcnt = 0; + m_arm7wrambnk->set_bank(0); + m_arm9wrambnk->set_bank(0); + m_arm7halted = false; } void nds_state::machine_start() { + int i; + + for (i = 0; i < 8; i++) + { + m_dma_timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nds_state::dma_complete),this)); + m_dma_timer[i]->adjust(attotime::never, i); + + m_tmr_timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nds_state::timer_expire),this)); + m_tmr_timer[i]->adjust(attotime::never, i); + } + + m_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nds_state::handle_irq),this)); + m_irq_timer->adjust(attotime::never); +} + +TIMER_CALLBACK_MEMBER(nds_state::dma_complete) +{ + #if 0 + static const uint32_t ch_int[8] = { INT_DMA0, INT_DMA1, INT_DMA2, INT_DMA3, INT_DMA0, INT_DMA1, INT_DMA2, INT_DMA3 }; + + uintptr_t ch = param; + +// printf("dma complete: ch %d\n", ch); + + m_dma_timer[ch]->adjust(attotime::never); + + int ctrl = DMACNT_H(ch); + + // IRQ + if (ctrl & 0x4000) + { + request_irq(ch_int[ch]); + } + + // if we're supposed to repeat, don't clear "active" and then the next vbl/hbl will retrigger us + // always clear active for immediate DMAs though + if (!((ctrl>>9) & 1) || ((ctrl & 0x3000) == 0)) + { + DMACNT_H_RESET(ch, 0x8000); // clear "active" bit + } + else + { + // if repeat, reload the count + if ((ctrl>>9) & 1) + { + m_dma_cnt[ch] = DMACNT_L(ch); + + // if increment & reload mode, reload the destination + if (((ctrl>>5)&3) == 3) + { + m_dma_dst[ch] = DMADAD(ch); + } + } + } + #endif +} + +void nds_state::dma_exec(int ch) +{ + #if 0 + address_space &space; + uint32_t src = m_dma_src[ch]; + uint32_t dst = m_dma_dst[ch]; + uint16_t ctrl = DMACNT_H(ch); + int srcadd = (ctrl >> 7) & 3; + int dstadd = (ctrl >> 5) & 3; + + if (ch > 4) + { + space = m_arm7->space(AS_PROGRAM); + } + else + { + space = m_arm9->space(AS_PROGRAM); + } + + int cnt = m_dma_cnt[ch]; + if (cnt == 0) + { + if (ch == 3) + cnt = 0x10000; + else + cnt = 0x4000; + } + +// if (dst >= 0x6000000 && dst <= 0x6017fff) +// printf("DMA exec: ch %d from %08x to %08x, mode %04x, count %04x (%s)\n", (int)ch, src, dst, ctrl, cnt, ((ctrl>>10) & 1) ? "32" : "16"); + + for (int i = 0; i < cnt; i++) + { + if ((ctrl>>10) & 1) + { + src &= 0xfffffffc; + dst &= 0xfffffffc; + + // 32-bit + space.write_dword(dst, space.read_dword(src)); + switch (dstadd) + { + case 0: // increment + dst += 4; + break; + case 1: // decrement + dst -= 4; + break; + case 2: // don't move + break; + case 3: // increment and reload + dst += 4; + break; + } + switch (srcadd) + { + case 0: // increment + src += 4; + break; + case 1: // decrement + src -= 4; + break; + case 2: // don't move + break; + case 3: // not used ("Metal Max 2 Kai" expects no increment/decrement) + break; + } + } + else + { + src &= 0xfffffffe; + dst &= 0xfffffffe; + + // 16-bit + space.write_word(dst, space.read_word(src)); + switch (dstadd) + { + case 0: // increment + dst += 2; + break; + case 1: // decrement + dst -= 2; + break; + case 2: // don't move + break; + case 3: // increment and reload + dst += 2; + break; + } + switch (srcadd) + { + case 0: // increment + src += 2; + break; + case 1: // decrement + src -= 2; + break; + case 2: // don't move + break; + case 3: // not used (see note in 32-bit version above) + break; + } + } + } + + m_dma_src[ch] = src; + m_dma_dst[ch] = dst; +#endif +// printf("settng DMA timer %d for %d cycs (tmr %x)\n", ch, cnt, (uint32_t)m_dma_timer[ch]); +// m_dma_timer[ch]->adjust(ATTOTIME_IN_CYCLES(0, cnt), ch); + dma_complete(nullptr, ch); +} + +TIMER_CALLBACK_MEMBER(nds_state::handle_irq) +{ + request_irq(0, m_if[0]); + request_irq(1, m_if[1]); + + m_irq_timer->adjust(attotime::never); +} + +void nds_state::request_irq(int cpu, uint32_t int_type) +{ + // set flag for later recovery + m_if[cpu] |= int_type; + + printf("request IRQ %08x on CPU %d\n", int_type, cpu); + + // is this specific interrupt enabled? + int_type &= m_ie[cpu]; + if (int_type != 0) + { + // master enable? + if (m_ime[cpu] & 1) + { + if (cpu == 0) + { + m_arm9->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); + m_arm9->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE); + } + else + { + if (m_arm7halted) + { + printf("ARM7 unhalting\n"); + m_arm7->resume(SUSPEND_REASON_HALT); + m_arm7halted = false; + } + + m_arm7->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); + m_arm7->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE); + } + } + } +} + +TIMER_CALLBACK_MEMBER(nds_state::timer_expire) +{ + static const uint32_t tmr_ints[8] = { INT_TM0_OVERFLOW, INT_TM1_OVERFLOW, INT_TM2_OVERFLOW, INT_TM3_OVERFLOW }; + uintptr_t tmr = (uintptr_t) param; + int cpu = (tmr > 4) ? 1 : 0; + + verboselog(*this, 1, "Timer %d expired\n", (int)tmr); + + // "The reload value is copied into the counter only upon following two situations: Automatically upon timer overflows," + // "or when the timer start bit becomes changed from 0 to 1." + if (m_timer_recalc[tmr] != 0) + { + double rate, clocksel, final; + attotime time; + m_timer_recalc[tmr] = 0; + m_timer_regs[tmr] = (m_timer_regs[tmr] & 0xFFFF0000) | (m_timer_reload[tmr] & 0x0000FFFF); + rate = 0x10000 - (m_timer_regs[tmr] & 0xffff); + clocksel = timer_clks[(m_timer_regs[tmr] >> 16) & 3]; + final = clocksel / rate; + m_timer_hz[tmr] = final; + time = attotime::from_hz(final); + m_tmr_timer[tmr]->adjust(time, tmr, time); + } + + // Handle count-up timing + switch (tmr) + { + case 0: + if (m_timer_regs[1] & 0x40000) + { + m_timer_regs[1] = (( ( m_timer_regs[1] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[1] & 0xffff0000); + if( ( m_timer_regs[1] & 0x0000ffff ) == 0 ) + { + m_timer_regs[1] |= m_timer_reload[1]; + if( ( m_timer_regs[1] & 0x400000 ) && ( m_ime[cpu] != 0 ) ) + { + request_irq(cpu, tmr_ints[1]); + } + if( ( m_timer_regs[2] & 0x40000 ) ) + { + m_timer_regs[2] = (( ( m_timer_regs[2] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[2] & 0xffff0000); + if( ( m_timer_regs[2] & 0x0000ffff ) == 0 ) + { + m_timer_regs[2] |= m_timer_reload[2]; + if( ( m_timer_regs[2] & 0x400000 ) && ( m_ime[cpu] != 0 ) ) + { + request_irq(cpu, tmr_ints[2]); + } + if( ( m_timer_regs[3] & 0x40000 ) ) + { + m_timer_regs[3] = (( ( m_timer_regs[3] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[3] & 0xffff0000); + if( ( m_timer_regs[3] & 0x0000ffff ) == 0 ) + { + m_timer_regs[3] |= m_timer_reload[3]; + if( ( m_timer_regs[3] & 0x400000 ) && ( m_ime[cpu] != 0 ) ) + { + request_irq(cpu, tmr_ints[3]); + } + } + } + } + } + } + } + break; + case 1: + if (m_timer_regs[2] & 0x40000) + { + m_timer_regs[2] = (( ( m_timer_regs[2] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[2] & 0xffff0000); + if( ( m_timer_regs[2] & 0x0000ffff ) == 0 ) + { + m_timer_regs[2] |= m_timer_reload[2]; + if( ( m_timer_regs[2] & 0x400000 ) && ( m_ime[cpu] != 0 ) ) + { + request_irq(cpu, tmr_ints[2]); + } + if( ( m_timer_regs[3] & 0x40000 ) ) + { + m_timer_regs[3] = (( ( m_timer_regs[3] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[3] & 0xffff0000); + if( ( m_timer_regs[3] & 0x0000ffff ) == 0 ) + { + m_timer_regs[3] |= m_timer_reload[3]; + if( ( m_timer_regs[3] & 0x400000 ) && ( m_ime[cpu] != 0 ) ) + { + request_irq(cpu, tmr_ints[3]); + } + } + } + } + } + break; + case 2: + if (m_timer_regs[3] & 0x40000) + { + m_timer_regs[3] = (( ( m_timer_regs[3] & 0x0000ffff ) + 1 ) & 0x0000ffff) | (m_timer_regs[3] & 0xffff0000); + if( ( m_timer_regs[3] & 0x0000ffff ) == 0 ) + { + m_timer_regs[3] |= m_timer_reload[3]; + if( ( m_timer_regs[3] & 0x400000 ) && ( m_ime[cpu] != 0 ) ) + { + request_irq(cpu, tmr_ints[3]); + } + } + } + break; + } + + // are we supposed to IRQ? + if ((m_timer_regs[tmr] & 0x400000) && (m_ime[cpu] != 0)) + { + request_irq(cpu, tmr_ints[tmr & 3]); + } } static MACHINE_CONFIG_START( nds ) - MCFG_CPU_ADD("arm7", ARM7, XTAL_33_333MHz) + MCFG_CPU_ADD("arm7", ARM7, MASTER_CLOCK) MCFG_CPU_PROGRAM_MAP(nds_arm7_map) - MCFG_CPU_ADD("arm9", ARM946ES, XTAL_66_6667MHz) + MCFG_CPU_ADD("arm9", ARM946ES, MASTER_CLOCK*2) + MCFG_ARM_HIGH_VECTORS() MCFG_CPU_PROGRAM_MAP(nds_arm9_map) + + // WRAM + MCFG_DEVICE_ADD("nds7wram", ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(nds7_wram_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) + + MCFG_DEVICE_ADD("nds9wram", ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(nds9_wram_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MACHINE_CONFIG_END /* Help identifying the region and revisions of the set would be greatly appreciated! */ @@ -151,5 +1000,5 @@ ROM_START( nds ) ROM_LOAD( "firmware.bin", 0x0000, 0x40000, CRC(945f9dc9) SHA1(cfe072921ee3fb93f688743f8beef89043c3e9ad) ) ROM_END -// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -CONS(2004, nds, 0, 0, nds, nds, nds_state, 0, "Nintendo", "DS", MACHINE_IS_SKELETON) +// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS +CONS(2004, nds, 0, 0, nds, nds, nds_state, 0, "Nintendo", "DS", MACHINE_NOT_WORKING | MACHINE_NO_SOUND) diff --git a/src/mame/drivers/neogeo.cpp b/src/mame/drivers/neogeo.cpp index b38bb656c90..7ff8212317e 100644 --- a/src/mame/drivers/neogeo.cpp +++ b/src/mame/drivers/neogeo.cpp @@ -10791,8 +10791,8 @@ GAME( 1990, bstars, neogeo, neobase, neogeo, neogeo_state, neogeo, R GAME( 1990, bstarsh, bstars, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Baseball Stars Professional (NGH-002)", MACHINE_SUPPORTS_SAVE ) GAME( 1990, tpgolf, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Top Player's Golf (NGM-003 ~ NGH-003)", MACHINE_SUPPORTS_SAVE ) GAME( 1990, mahretsu, neogeo, neogeo_mj, mjneogeo, neogeo_state, neogeo, ROT0, "SNK", "Mahjong Kyo Retsuden (NGM-004 ~ NGH-004)", MACHINE_SUPPORTS_SAVE ) // does not support mahjong panel in MVS mode <- it actually works fine??? -GAME( 1990, ridhero, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Riding Hero (NGM-006 ~ NGH-006)", MACHINE_SUPPORTS_SAVE ) -GAME( 1990, ridheroh, ridhero, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Riding Hero (set 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1990, ridhero, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Riding Hero (NGM-006 ~ NGH-006)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, ridheroh, ridhero, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Riding Hero (set 2)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE ) GAME( 1991, alpham2, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Alpha Mission II / ASO II - Last Guardian (NGM-007 ~ NGH-007)", MACHINE_SUPPORTS_SAVE ) GAME( 1991, alpham2p, alpham2, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Alpha Mission II / ASO II - Last Guardian (prototype)", MACHINE_SUPPORTS_SAVE ) GAME( 1990, cyberlip, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Cyber-Lip (NGM-010)", MACHINE_SUPPORTS_SAVE ) @@ -10806,7 +10806,7 @@ GAME( 1991, burningf, neogeo, neobase, neogeo, neogeo_state, neogeo, R GAME( 1991, burningfh, burningf, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Burning Fight (NGH-018, US)", MACHINE_SUPPORTS_SAVE ) GAME( 1991, burningfpa, burningf, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Burning Fight (prototype, ver 23.3, 910326)", MACHINE_SUPPORTS_SAVE ) GAME( 1991, burningfp, burningf, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Burning Fight (prototype, older)", MACHINE_SUPPORTS_SAVE ) -GAME( 1990, lbowling, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "League Bowling (NGM-019 ~ NGH-019)", MACHINE_SUPPORTS_SAVE ) +GAME( 1990, lbowling, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "League Bowling (NGM-019 ~ NGH-019)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE ) GAME( 1991, gpilots, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Ghost Pilots (NGM-020 ~ NGH-020)", MACHINE_SUPPORTS_SAVE ) GAME( 1991, gpilotsh, gpilots, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Ghost Pilots (NGH-020, US)", MACHINE_SUPPORTS_SAVE ) GAME( 1990, joyjoy, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "SNK", "Puzzled / Joy Joy Kid (NGM-021 ~ NGH-021)", MACHINE_SUPPORTS_SAVE ) @@ -10954,7 +10954,7 @@ GAME( 1990, ncombat, neogeo, neobase, neogeo, neogeo_state, neogeo, R GAME( 1990, ncombath, ncombat, neobase, neogeo, neogeo_state, neogeo, ROT0, "Alpha Denshi Co.", "Ninja Combat (NGH-009)", MACHINE_SUPPORTS_SAVE ) GAME( 1990, bjourney, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "Alpha Denshi Co.", "Blue's Journey / Raguy (ALM-001 ~ ALH-001)", MACHINE_SUPPORTS_SAVE ) GAME( 1991, crsword, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "Alpha Denshi Co.", "Crossed Swords (ALM-002 ~ ALH-002)", MACHINE_SUPPORTS_SAVE ) -GAME( 1991, trally, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "Alpha Denshi Co.", "Thrash Rally (ALM-003 ~ ALH-003)", MACHINE_SUPPORTS_SAVE ) +GAME( 1991, trally, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "Alpha Denshi Co.", "Thrash Rally (ALM-003 ~ ALH-003)", MACHINE_NODEVICE_LAN | MACHINE_SUPPORTS_SAVE ) GAME( 1992, ncommand, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "Alpha Denshi Co.", "Ninja Commando", MACHINE_SUPPORTS_SAVE ) GAME( 1992, wh1, neogeo, neobase, neogeo, neogeo_state, neogeo, ROT0, "Alpha Denshi Co.", "World Heroes (ALM-005)", MACHINE_SUPPORTS_SAVE ) GAME( 1992, wh1h, wh1, neobase, neogeo, neogeo_state, neogeo, ROT0, "Alpha Denshi Co.", "World Heroes (ALH-005)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/neogeocd.cpp b/src/mame/drivers/neogeocd.cpp index 0953db35f10..1a5cb72ceaf 100644 --- a/src/mame/drivers/neogeocd.cpp +++ b/src/mame/drivers/neogeocd.cpp @@ -1083,10 +1083,12 @@ MACHINE_CONFIG_END ROM_START( neocd ) ROM_REGION16_BE( 0x80000, "mainbios", 0 ) - ROM_SYSTEM_BIOS( 0, "top", "Top loading NeoGeo CD" ) + ROM_SYSTEM_BIOS( 0, "top", "Top loading Neo-Geo CD" ) ROMX_LOAD( "top-sp1.bin", 0x00000, 0x80000, CRC(c36a47c0) SHA1(235f4d1d74364415910f73c10ae5482d90b4274f), ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(1)) - ROM_SYSTEM_BIOS( 1, "front", "Front loading NeoGeo CD" ) + ROM_SYSTEM_BIOS( 1, "front", "Front loading Neo-Geo CD" ) ROMX_LOAD( "front-sp1.bin", 0x00000, 0x80000, CRC(cac62307) SHA1(53bc1f283cdf00fa2efbb79f2e36d4c8038d743a), ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(2)) + ROM_SYSTEM_BIOS( 2, "unibios32", "Universe Bios (Hack, Ver. 3.2)" ) + ROMX_LOAD( "uni-bioscd.rom", 0x00000, 0x80000, CRC(0ffb3127) SHA1(5158b728e62b391fb69493743dcf7abbc62abc82), ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(3)) ROM_REGION( 0x100000, "ymsnd", ROMREGION_ERASEFF ) /* 1MB of Sound RAM */ @@ -1109,7 +1111,10 @@ ROM_END ROM_START( neocdz ) ROM_REGION16_BE( 0x80000, "mainbios", 0 ) - ROM_LOAD16_WORD_SWAP( "neocd.bin", 0x00000, 0x80000, CRC(df9de490) SHA1(7bb26d1e5d1e930515219cb18bcde5b7b23e2eda) ) + ROM_SYSTEM_BIOS( 0, "official", "Official BIOS" ) + ROMX_LOAD( "neocd.bin", 0x00000, 0x80000, CRC(df9de490) SHA1(7bb26d1e5d1e930515219cb18bcde5b7b23e2eda), ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(1)) + ROM_SYSTEM_BIOS( 1, "unibios32", "Universe Bios (Hack, Ver. 3.2)" ) + ROMX_LOAD( "uni-bioscd.rom", 0x00000, 0x80000, CRC(0ffb3127) SHA1(5158b728e62b391fb69493743dcf7abbc62abc82), ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(2)) ROM_REGION( 0x100000, "ymsnd", ROMREGION_ERASEFF ) /* 1MB of Sound RAM */ diff --git a/src/mame/drivers/neoprint.cpp b/src/mame/drivers/neoprint.cpp index 51fa4151b53..b86e8efb169 100644 --- a/src/mame/drivers/neoprint.cpp +++ b/src/mame/drivers/neoprint.cpp @@ -48,20 +48,8 @@ public: m_generic_paletteram_16(*this, "paletteram") { } - required_shared_ptr<uint16_t> m_npvidram; - required_shared_ptr<uint16_t> m_npvidregs; - required_device<cpu_device> m_maincpu; - required_device<cpu_device> m_audiocpu; - required_device<upd4990a_device> m_upd4990a; - required_device<gfxdecode_device> m_gfxdecode; - required_device<screen_device> m_screen; - required_device<palette_device> m_palette; - required_device<generic_latch_8_device> m_soundlatch; - optional_shared_ptr<uint16_t> m_generic_paletteram_16; + static constexpr feature_type unemulated_features() { return feature::CAMERA | feature::PRINTER; } - uint8_t m_audio_result; - uint8_t m_bank_val; - uint8_t m_vblank; DECLARE_READ8_MEMBER(neoprint_calendar_r); DECLARE_WRITE8_MEMBER(neoprint_calendar_w); DECLARE_READ8_MEMBER(neoprint_unk_r); @@ -77,11 +65,29 @@ public: DECLARE_DRIVER_INIT(npcartv1); DECLARE_DRIVER_INIT(nprsp); DECLARE_DRIVER_INIT(unkneo); - virtual void machine_start() override; - virtual void video_start() override; DECLARE_MACHINE_RESET(nprsp); uint32_t screen_update_neoprint(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_nprsp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + +protected: + virtual void machine_start() override; + virtual void video_start() override; + +private: + required_shared_ptr<uint16_t> m_npvidram; + required_shared_ptr<uint16_t> m_npvidregs; + required_device<cpu_device> m_maincpu; + required_device<cpu_device> m_audiocpu; + required_device<upd4990a_device> m_upd4990a; + required_device<gfxdecode_device> m_gfxdecode; + required_device<screen_device> m_screen; + required_device<palette_device> m_palette; + required_device<generic_latch_8_device> m_soundlatch; + optional_shared_ptr<uint16_t> m_generic_paletteram_16; + + uint8_t m_audio_result; + uint8_t m_bank_val; + uint8_t m_vblank; void draw_layer(bitmap_ind16 &bitmap,const rectangle &cliprect,int layer,int data_shift); void audio_cpu_assert_nmi(); }; diff --git a/src/mame/drivers/nes_vt.cpp b/src/mame/drivers/nes_vt.cpp index c3607c47ede..b54b89cd866 100644 --- a/src/mame/drivers/nes_vt.cpp +++ b/src/mame/drivers/nes_vt.cpp @@ -840,8 +840,8 @@ static MACHINE_CONFIG_START( nes_vt ) MCFG_DEVICE_ADD("prg", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(prg_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(15) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(15) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MCFG_NES_CONTROL_PORT_ADD("ctrl1", nes_control_port1_devices, "joypad") diff --git a/src/mame/drivers/nmk16.cpp b/src/mame/drivers/nmk16.cpp index 69aa897e230..21e6786440f 100644 --- a/src/mame/drivers/nmk16.cpp +++ b/src/mame/drivers/nmk16.cpp @@ -1053,6 +1053,12 @@ static ADDRESS_MAP_START( macross2_map, AS_PROGRAM, 16, nmk16_state ) AM_RANGE(0x1f0000, 0x1fffff) AM_RAM AM_SHARE("mainram") ADDRESS_MAP_END +static ADDRESS_MAP_START( tdragon3h_map, AS_PROGRAM, 16, nmk16_state ) // bootleg has these 2 swapped + AM_RANGE(0x10000e, 0x10000f) AM_READ_PORT("DSW2") + AM_RANGE(0x10000a, 0x10000b) AM_DEVREAD8("soundlatch2", generic_latch_8_device, read, 0x00ff) /* from Z80 */ + AM_IMPORT_FROM(macross2_map) +ADDRESS_MAP_END + static ADDRESS_MAP_START( raphero_map, AS_PROGRAM, 16, nmk16_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM AM_RANGE(0x100000, 0x100001) AM_READ_PORT("IN0") @@ -4552,6 +4558,12 @@ static MACHINE_CONFIG_START( tdragon2 ) MCFG_NMK112_ROM1("oki2") MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( tdragon3h, tdragon2 ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(tdragon3h_map) +MACHINE_CONFIG_END + + static MACHINE_CONFIG_START( raphero ) /* basic machine hardware */ @@ -6438,6 +6450,37 @@ ROM_START( tdragon2 ) ROM_LOAD( "10.bpr", 0x0100, 0x0100, CRC(e6ead349) SHA1(6d81b1c0233580aa48f9718bade42d640e5ef3dd) ) /* unknown */ ROM_END +ROM_START( tdragon3h ) + ROM_REGION( 0x80000, "maincpu", 0 ) /* 68000 code */ + ROM_LOAD16_BYTE( "H.27C2001", 0x00000, 0x40000, CRC(0091f4a3) SHA1(025e5f7ff12eaa90c5cfe757c71d58ba7040cba7) ) + ROM_LOAD16_BYTE( "L.27C020", 0x00001, 0x40000, CRC(4699c313) SHA1(1851a4b5ad9c2bac230126d195e239a5ebe827f9) ) + + ROM_REGION( 0x20000, "audiocpu", 0 ) /* Z80 code */ + ROM_LOAD( "1.27C1000", 0x00000, 0x20000, CRC(b870be61) SHA1(ea5d45c3a3ab805e55806967f00167cf6366212e) ) /* banked */ + + ROM_REGION( 0x020000, "fgtile", 0 ) + ROM_LOAD( "12.27C1000", 0x000000, 0x020000, CRC(f809d616) SHA1(c6a4d776fee770ec197204b855b85bcc719469a5) ) /* 8x8 tiles */ + + // all other roms are MASK parts marked 'CONNY' but weren't dumped from this PCB so content is only assumed to be the same + + ROM_REGION( 0x200000, "bgtile", 0 ) + ROM_LOAD( "ww930914.2", 0x000000, 0x200000, CRC(f968c65d) SHA1(fd6d21bba53f945b1597d7d0735bc62dd44d5498) ) /* 16x16 tiles */ + + ROM_REGION( 0x400000, "sprites", 0 ) + ROM_LOAD16_WORD_SWAP( "ww930917.7", 0x000000, 0x200000, CRC(b98873cb) SHA1(cc19200865176e940ff68e12de81f029b51c2084) ) /* Sprites */ + ROM_LOAD16_WORD_SWAP( "ww930918.8", 0x200000, 0x200000, CRC(baee84b2) SHA1(b325b00e6147266dbdc840e03556004531dc2038) ) + + ROM_REGION( 0x240000, "oki1", 0 ) /* OKIM6295 samples */ + ROM_LOAD( "ww930916.4", 0x040000, 0x200000, CRC(07c35fe6) SHA1(33547bd88764704310f2ef8cf3bfe21ceb56d5b7) ) /* all banked */ + + ROM_REGION( 0x240000, "oki2", 0 ) /* OKIM6295 samples */ + ROM_LOAD( "ww930915.3", 0x040000, 0x200000, CRC(82025bab) SHA1(ac6053700326ea730d00ec08193e2c8a2a019f0b) ) /* all banked */ + + ROM_REGION( 0x0200, "proms", 0 ) + ROM_LOAD( "9.bpr", 0x0000, 0x0100, CRC(435653a2) SHA1(575b4a46ea65179de3042614da438d2f6d8b572e) ) /* unknown */ + ROM_LOAD( "10.bpr", 0x0100, 0x0100, CRC(e6ead349) SHA1(6d81b1c0233580aa48f9718bade42d640e5ef3dd) ) /* unknown */ +ROM_END + ROM_START( tdragon2a ) ROM_REGION( 0x80000, "maincpu", 0 ) /* 68000 code */ ROM_LOAD16_WORD_SWAP( "6.bin", 0x00000, 0x80000, CRC(310d6bca) SHA1(f46ad1d13cf5014aef1f0e8862b369ab31c22866) ) @@ -8006,6 +8049,7 @@ GAME( 1993, macross2k, macross2, macross2, macross2, nmk16_state, bank GAME( 1993, tdragon2, 0, tdragon2, tdragon2, nmk16_state, banked_audiocpu, ROT270, "NMK", "Thunder Dragon 2 (9th Nov. 1993)", MACHINE_NO_COCKTAIL ) GAME( 1993, tdragon2a, tdragon2, tdragon2, tdragon2, nmk16_state, banked_audiocpu, ROT270, "NMK", "Thunder Dragon 2 (1st Oct. 1993)", MACHINE_NO_COCKTAIL ) GAME( 1993, bigbang, tdragon2, tdragon2, tdragon2, nmk16_state, banked_audiocpu, ROT270, "NMK", "Big Bang (9th Nov. 1993)", MACHINE_NO_COCKTAIL ) +GAME( 1996, tdragon3h, tdragon2, tdragon3h, tdragon2, nmk16_state, banked_audiocpu, ROT270, "bootleg (Conny Co Ltd.)", "Thunder Dragon 3 (bootleg of Thunder Dragon 2)", MACHINE_NO_COCKTAIL ) // based on 1st Oct. 1993 set /* arcadia was a name conflict to the Emerson Arcadia 2001 in mess */ GAME( 1994, arcadian, 0, raphero, raphero, nmk16_state, banked_audiocpu, ROT270, "NMK", "Arcadia (NMK)", 0 ) // 23rd July 1993 in test mode, (c)1994 on title screen diff --git a/src/mame/drivers/norautp.cpp b/src/mame/drivers/norautp.cpp index e344dc4b404..034581a036d 100644 --- a/src/mame/drivers/norautp.cpp +++ b/src/mame/drivers/norautp.cpp @@ -3658,4 +3658,4 @@ GAME( 1993, tpoker2, 0, dphltest, norautp, norautp_state, 0, ROT0, "M GAME( 198?, fastdrwp, 0, dphl, norautp, norautp_state, 0, ROT0, "Stern Electronics?", "Fast Draw (poker conversion kit)?", MACHINE_NOT_WORKING ) GAME( 198?, dphlunka, 0, dphl, norautp, norautp_state, 0, ROT0, "SMS Manufacturing Corp.", "Draw Poker HI-LO (unknown, rev 1)", MACHINE_NOT_WORKING ) GAME( 198?, dphlunkb, 0, dphl, norautp, norautp_state, 0, ROT0, "SMS Manufacturing Corp.", "Draw Poker HI-LO (unknown, rev 2)", MACHINE_NOT_WORKING ) -GAME( 198?, pkii_dm, 0, nortest1, norautp, norautp_state, 0, ROT0, "<unknown>", "Unknown Poker PKII/DM", MACHINE_NOT_WORKING ) +GAME( 198?, pkii_dm, 0, nortest1, norautp, norautp_state, 0, ROT0, "<unknown>", "unknown poker game PKII/DM", MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/nyny.cpp b/src/mame/drivers/nyny.cpp index 11c38f09a09..e6040373eee 100644 --- a/src/mame/drivers/nyny.cpp +++ b/src/mame/drivers/nyny.cpp @@ -148,12 +148,11 @@ public: DECLARE_WRITE8_MEMBER(pia_2_port_a_w); DECLARE_WRITE8_MEMBER(pia_2_port_b_w); DECLARE_WRITE_LINE_MEMBER(flipscreen_w); - DECLARE_WRITE_LINE_MEMBER(display_enable_changed); DECLARE_WRITE8_MEMBER(nyny_ay8910_37_port_a_w); virtual void machine_start() override; virtual void machine_reset() override; INTERRUPT_GEN_MEMBER(update_pia_1); - DECLARE_WRITE8_MEMBER(ic48_1_74123_output_changed); + DECLARE_WRITE_LINE_MEMBER(ic48_1_74123_output_changed); inline void shift_star_generator( ); MC6845_UPDATE_ROW(crtc_update_row); @@ -242,9 +241,9 @@ WRITE8_MEMBER(nyny_state::pia_2_port_b_w) * *************************************/ -WRITE8_MEMBER(nyny_state::ic48_1_74123_output_changed) +WRITE_LINE_MEMBER(nyny_state::ic48_1_74123_output_changed) { - m_pia2->ca1_w(data); + m_pia2->ca1_w(state); } /************************************* @@ -355,11 +354,6 @@ MC6845_END_UPDATE( nyny_state::crtc_end_update ) } -WRITE_LINE_MEMBER(nyny_state::display_enable_changed) -{ - m_ic48_1->a_w(generic_space(), 0, state); -} - /************************************* * @@ -618,7 +612,7 @@ static MACHINE_CONFIG_START( nyny ) MCFG_MC6845_CHAR_WIDTH(8) MCFG_MC6845_UPDATE_ROW_CB(nyny_state, crtc_update_row) MCFG_MC6845_END_UPDATE_CB(nyny_state, crtc_end_update) - MCFG_MC6845_OUT_DE_CB(WRITELINE(nyny_state, display_enable_changed)) + MCFG_MC6845_OUT_DE_CB(DEVWRITELINE("ic48_1", ttl74123_device, a_w)) /* 74LS123 */ MCFG_DEVICE_ADD("ic48_1", TTL74123, 0) @@ -628,7 +622,7 @@ static MACHINE_CONFIG_START( nyny ) MCFG_TTL74123_A_PIN_VALUE(1) /* A pin - driven by the CRTC */ MCFG_TTL74123_B_PIN_VALUE(1) /* B pin - pulled high */ MCFG_TTL74123_CLEAR_PIN_VALUE(1) /* Clear pin - pulled high */ - MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITE8(nyny_state, ic48_1_74123_output_changed)) + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(nyny_state, ic48_1_74123_output_changed)) MCFG_DEVICE_ADD("pia1", PIA6821, 0) MCFG_PIA_READPA_HANDLER(IOPORT("IN0")) diff --git a/src/mame/drivers/ob68k1a.cpp b/src/mame/drivers/ob68k1a.cpp index a16adabb45a..e8cb1a9ccbd 100644 --- a/src/mame/drivers/ob68k1a.cpp +++ b/src/mame/drivers/ob68k1a.cpp @@ -121,11 +121,9 @@ static ADDRESS_MAP_START( ob68k1a_mem, AS_PROGRAM, 16, ob68k1a_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x000000, 0x01ffff) AM_RAM AM_RANGE(0xfe0000, 0xfeffff) AM_ROM AM_REGION(MC68000L10_TAG, 0) - AM_RANGE(0xffff00, 0xffff01) AM_DEVREADWRITE8(MC6850_0_TAG, acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0xffff02, 0xffff03) AM_DEVREADWRITE8(MC6850_0_TAG, acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0xffff00, 0xffff03) AM_DEVREADWRITE8(MC6850_0_TAG, acia6850_device, read, write, 0x00ff) AM_RANGE(0xffff10, 0xffff11) AM_WRITE8(com8116_w, 0xff00) - AM_RANGE(0xffff20, 0xffff21) AM_DEVREADWRITE8(MC6850_1_TAG, acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0xffff22, 0xffff23) AM_DEVREADWRITE8(MC6850_1_TAG, acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0xffff20, 0xffff23) AM_DEVREADWRITE8(MC6850_1_TAG, acia6850_device, read, write, 0x00ff) // AM_RANGE(0xffff40, 0xffff47) AM_DEVREADWRITE8(MC6821_0_TAG, pia6821_device, read, write, 0x00ff) // AM_RANGE(0xffff40, 0xffff47) AM_DEVREADWRITE8(MC6821_1_TAG, pia6821_device, read, write, 0xff00) AM_RANGE(0xffff40, 0xffff47) AM_READWRITE8(pia_r, pia_w, 0xffff) diff --git a/src/mame/drivers/octopus.cpp b/src/mame/drivers/octopus.cpp index 3f2bac7797e..23340b81a80 100644 --- a/src/mame/drivers/octopus.cpp +++ b/src/mame/drivers/octopus.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Barry Rodewald, Robbbert +// copyright-holders:Barry Rodewald /*************************************************************************** Hilger Analytical AB6089 Mk. 1 (LSI Octopus) @@ -121,7 +121,7 @@ It's a very rare computer. It has 2 processors, Z80 and 8088, so it can run both #include "machine/pit8253.h" #include "machine/ram.h" #include "machine/wd_fdc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "sound/spkrdev.h" #include "video/scn2674.h" @@ -245,7 +245,7 @@ private: required_device<pit8253_device> m_pit; required_device<i8255_device> m_ppi; required_device<speaker_sound_device> m_speaker; - required_device<z80sio2_device> m_serial; + required_device<z80sio_device> m_serial; required_device<centronics_device> m_parallel; required_device<address_map_bank_device> m_z80_bankdev; required_device<ram_device> m_ram; @@ -300,10 +300,10 @@ static ADDRESS_MAP_START( octopus_io, AS_IO, 8, octopus_state ) AM_RANGE(0x51, 0x51) AM_DEVREADWRITE("keyboard", i8251_device, status_r, control_w) // 0x70-73: HD controller AM_RANGE(0x80, 0x83) AM_DEVREADWRITE("pit", pit8253_device, read, write) - AM_RANGE(0xa0, 0xa0) AM_DEVREADWRITE("serial", z80sio2_device, da_r, da_w) - AM_RANGE(0xa1, 0xa1) AM_DEVREADWRITE("serial", z80sio2_device, ca_r, ca_w) - AM_RANGE(0xa2, 0xa2) AM_DEVREADWRITE("serial", z80sio2_device, db_r, db_w) - AM_RANGE(0xa3, 0xa3) AM_DEVREADWRITE("serial", z80sio2_device, cb_r, cb_w) + AM_RANGE(0xa0, 0xa0) AM_DEVREADWRITE("serial", z80sio_device, da_r, da_w) + AM_RANGE(0xa1, 0xa1) AM_DEVREADWRITE("serial", z80sio_device, ca_r, ca_w) + AM_RANGE(0xa2, 0xa2) AM_DEVREADWRITE("serial", z80sio_device, db_r, db_w) + AM_RANGE(0xa3, 0xa3) AM_DEVREADWRITE("serial", z80sio_device, cb_r, cb_w) AM_RANGE(0xb0, 0xb1) AM_DEVREADWRITE("pic_master", pic8259_device, read, write) AM_RANGE(0xb4, 0xb5) AM_DEVREADWRITE("pic_slave", pic8259_device, read, write) AM_RANGE(0xc0, 0xc7) AM_DEVREADWRITE("crtc", scn2674_device, read, write) @@ -952,7 +952,7 @@ static MACHINE_CONFIG_START( octopus ) MCFG_PIT8253_CLK0(2457500) // DART channel A MCFG_PIT8253_OUT0_HANDLER(WRITELINE(octopus_state,serial_clock_w)) // being able to write both Rx and Tx clocks at one time would be nice MCFG_PIT8253_CLK1(2457500) // DART channel B - MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("serial",z80sio2_device,rxtxcb_w)) + MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("serial",z80sio_device,rxtxcb_w)) MCFG_PIT8253_CLK2(2457500) // speaker frequency MCFG_PIT8253_OUT2_HANDLER(WRITELINE(octopus_state,spk_freq_w)) @@ -960,21 +960,21 @@ static MACHINE_CONFIG_START( octopus ) MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) - MCFG_DEVICE_ADD("serial", Z80SIO2, XTAL_16MHz / 4) // clock rate not mentioned in tech manual - MCFG_Z80DART_OUT_INT_CB(DEVWRITELINE("pic_master",pic8259_device, ir1_w)) - MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE("serial_a",rs232_port_device, write_txd)) - MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE("serial_b",rs232_port_device, write_txd)) - MCFG_Z80DART_OUT_RTSA_CB(DEVWRITELINE("serial_a",rs232_port_device, write_rts)) - MCFG_Z80DART_OUT_RTSB_CB(DEVWRITELINE("serial_b",rs232_port_device, write_rts)) + MCFG_DEVICE_ADD("serial", Z80SIO, XTAL_16MHz / 4) // clock rate not mentioned in tech manual + MCFG_Z80SIO_OUT_INT_CB(DEVWRITELINE("pic_master",pic8259_device, ir1_w)) + MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("serial_a",rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("serial_b",rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_RTSA_CB(DEVWRITELINE("serial_a",rs232_port_device, write_rts)) + MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("serial_b",rs232_port_device, write_rts)) MCFG_RS232_PORT_ADD("serial_a", default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("serial",z80sio2_device, rxa_w)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("serial",z80sio2_device, ctsa_w)) MCFG_DEVCB_INVERT - MCFG_RS232_RI_HANDLER(DEVWRITELINE("serial",z80sio2_device, ria_w)) MCFG_DEVCB_INVERT + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("serial",z80sio_device, rxa_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("serial",z80sio_device, ctsa_w)) MCFG_DEVCB_INVERT + //MCFG_RS232_RI_HANDLER(DEVWRITELINE("serial",z80sio_device, ria_w)) MCFG_DEVCB_INVERT MCFG_RS232_PORT_ADD("serial_b", default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("serial",z80sio2_device, rxb_w)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("serial",z80sio2_device, ctsb_w)) MCFG_DEVCB_INVERT - MCFG_RS232_RI_HANDLER(DEVWRITELINE("serial",z80sio2_device, rib_w)) MCFG_DEVCB_INVERT + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("serial",z80sio_device, rxb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("serial",z80sio_device, ctsb_w)) MCFG_DEVCB_INVERT + //MCFG_RS232_RI_HANDLER(DEVWRITELINE("serial",z80sio_device, rib_w)) MCFG_DEVCB_INVERT MCFG_CENTRONICS_ADD("parallel", octopus_centronics_devices, "printer") MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(octopus_state, parallel_busy_w)) @@ -991,7 +991,8 @@ static MACHINE_CONFIG_START( octopus ) // MCFG_SCREEN_PALETTE("palette") // MCFG_PALETTE_ADD_MONOCHROME("palette") - MCFG_SCN2674_VIDEO_ADD("crtc", 0, DEVWRITELINE("pic_slave",pic8259_device,ir0_w)) // character clock can be selectable, either 16MHz or 17.6MHz + MCFG_DEVICE_ADD("crtc", SCN2674, 0) // character clock can be selectable, either 16MHz or 17.6MHz + MCFG_SCN2674_INTR_CALLBACK(DEVWRITELINE("pic_slave", pic8259_device, ir0_w)) MCFG_SCN2674_TEXT_CHARACTER_WIDTH(8) MCFG_SCN2674_GFX_CHARACTER_WIDTH(8) MCFG_SCN2674_DRAW_CHARACTER_CALLBACK_OWNER(octopus_state, display_pixels) @@ -1001,7 +1002,7 @@ static MACHINE_CONFIG_START( octopus ) MCFG_DEVICE_ADD("z80_bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(octopus_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_RAM_ADD("ram") diff --git a/src/mame/drivers/onyx.cpp b/src/mame/drivers/onyx.cpp index 6e68c7ff76c..3faabd8603a 100644 --- a/src/mame/drivers/onyx.cpp +++ b/src/mame/drivers/onyx.cpp @@ -6,8 +6,6 @@ Onyx C8002 2013-08-18 Skeleton Driver -Copied from p8k.c - The C8002 is one of the earliest minicomputers to use Unix as an operating system. The system consists of a main CPU (Z8002), and a slave CPU for Mass Storage control (Z80) @@ -21,54 +19,47 @@ The Z8002 board contains a 16 MHz crystal; 3x Z80CTC; 5x Z80SIO/0; 3x Z80PIO; 2 The system can handle 8 RS232 terminals, 7 hard drives, a tape cartridge drive, parallel i/o, and be connected to a RS422 network. +Status: +- Main screen prints an error with CTC (because there's no clock into it atm) +- Subcpu screen (after a while) prints various statuses then waits for the fdc to respond + +To Do: +- Hook up daisy chains (see p8k.cpp for how to hook up a 16-bit chain) + (keyboard input depends on interrupts) +- Remaining devices +- Whatever hooks up to the devices +- Eventually we'll need software +- Manuals / schematics would be nice + *************************************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" #include "cpu/z8000/z8000.h" +#include "machine/clock.h" +#include "bus/rs232/rs232.h" //#include "cpu/z80/z80daisy.h" -//#include "machine/z80ctc.h" -//#include "machine/z80pio.h" -//#include "machine/z80dart.h" +#include "machine/z80ctc.h" +#include "machine/z80pio.h" +#include "machine/z80sio.h" //#include "machine/z80dma.h" #include "machine/terminal.h" -#define TERMINAL_TAG "terminal" - class onyx_state : public driver_device { public: onyx_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG) - { - } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { } DECLARE_MACHINE_RESET(c8002); - void kbd_put(u8 data); - DECLARE_READ8_MEMBER(portff05_r); private: - uint8_t m_term_data; required_device<cpu_device> m_maincpu; - required_device<generic_terminal_device> m_terminal; }; -READ8_MEMBER( onyx_state::portff05_r ) -{ - //return m_term_data; - - return 4; -} - -void onyx_state::kbd_put(u8 data) -{ - m_term_data = data; -} - - /* Input ports */ static INPUT_PORTS_START( c8002 ) INPUT_PORTS_END @@ -91,8 +82,16 @@ ADDRESS_MAP_END //ADDRESS_MAP_END static ADDRESS_MAP_START(c8002_io, AS_IO, 8, onyx_state) - AM_RANGE(0xff00, 0xff01) AM_DEVWRITE(TERMINAL_TAG, generic_terminal_device, write) - AM_RANGE(0xff04, 0xff05) AM_READ(portff05_r) + AM_RANGE(0xff00, 0xff07) AM_DEVREADWRITE_MOD("sio1", z80sio_device, cd_ba_r, cd_ba_w, rshift<1>) + AM_RANGE(0xff08, 0xff0f) AM_DEVREADWRITE_MOD("sio2", z80sio_device, cd_ba_r, cd_ba_w, rshift<1>) + AM_RANGE(0xff10, 0xff17) AM_DEVREADWRITE_MOD("sio3", z80sio_device, cd_ba_r, cd_ba_w, rshift<1>) + AM_RANGE(0xff18, 0xff1f) AM_DEVREADWRITE_MOD("sio4", z80sio_device, cd_ba_r, cd_ba_w, rshift<1>) + AM_RANGE(0xff20, 0xff27) AM_DEVREADWRITE_MOD("sio5", z80sio_device, cd_ba_r, cd_ba_w, rshift<1>) + AM_RANGE(0xff30, 0xff37) AM_DEVREADWRITE_MOD("ctc1", z80ctc_device, read, write, rshift<1>) + AM_RANGE(0xff38, 0xff3f) AM_DEVREADWRITE_MOD("ctc2", z80ctc_device, read, write, rshift<1>) + AM_RANGE(0xff40, 0xff47) AM_DEVREADWRITE_MOD("ctc3", z80ctc_device, read, write, rshift<1>) + AM_RANGE(0xff50, 0xff57) AM_DEVREADWRITE_MOD("pio1", z80pio_device, read, write, rshift<1>) + AM_RANGE(0xff58, 0xff5f) AM_DEVREADWRITE_MOD("pio2", z80pio_device, read, write, rshift<1>) ADDRESS_MAP_END static ADDRESS_MAP_START(submem, AS_PROGRAM, 8, onyx_state) @@ -102,9 +101,11 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(subio, AS_IO, 8, onyx_state) ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("pio1s", z80pio_device, read, write) + AM_RANGE(0x04, 0x04) AM_READNOP // disk status? + AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("sio1s", z80sio_device, cd_ba_r, cd_ba_w ) ADDRESS_MAP_END - /*************************************************************************** Machine Drivers @@ -125,18 +126,48 @@ static MACHINE_CONFIG_START( c8002 ) MCFG_CPU_IO_MAP(subio) MCFG_MACHINE_RESET_OVERRIDE(onyx_state, c8002) + MCFG_DEVICE_ADD("sio1_clock", CLOCK, 307200) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("sio1", z80sio_device, rxca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio1" ,z80sio_device, txca_w)) + /* peripheral hardware */ - //MCFG_DEVICE_ADD("z80ctc_0", Z80CTC, XTAL_4MHz) - //MCFG_DEVICE_ADD("z80ctc_1", Z80CTC, XTAL_4MHz) - //MCFG_DEVICE_ADD("z80sio_0", Z80SIO0, 9600) - //MCFG_DEVICE_ADD("z80sio_1", Z80SIO0, 9600) - //MCFG_DEVICE_ADD("z80pio_0", Z80CTC, XTAL_4MHz) - //MCFG_DEVICE_ADD("z80pio_1", Z80CTC, XTAL_4MHz) - //MCFG_DEVICE_ADD("z80pio_2", Z80CTC, XTAL_4MHz) - - /* video hardware */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) - MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(onyx_state, kbd_put)) + MCFG_DEVICE_ADD("pio1", Z80PIO, XTAL_16MHz/4) + //MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("pio2", Z80PIO, XTAL_16MHz/4) + //MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("ctc1", Z80CTC, XTAL_16MHz /4) + MCFG_DEVICE_ADD("ctc2", Z80CTC, XTAL_16MHz /4) + MCFG_DEVICE_ADD("ctc3", Z80CTC, XTAL_16MHz /4) + MCFG_DEVICE_ADD("sio1", Z80SIO, XTAL_16MHz /4) + MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRA_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSA_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_DEVICE_ADD("sio2", Z80SIO, XTAL_16MHz /4) + MCFG_DEVICE_ADD("sio3", Z80SIO, XTAL_16MHz /4) + MCFG_DEVICE_ADD("sio4", Z80SIO, XTAL_16MHz /4) + MCFG_DEVICE_ADD("sio5", Z80SIO, XTAL_16MHz /4) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio1", z80sio_device, rxa_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio1", z80sio_device, dcda_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio1", z80sio_device, ctsa_w)) + + MCFG_DEVICE_ADD("pio1s", Z80PIO, XTAL_16MHz/4) + //MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("subcpu", INPUT_LINE_IRQ0)) + + MCFG_DEVICE_ADD("sio1s_clock", CLOCK, 614400) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("sio1s", z80sio_device, rxtxcb_w)) + //MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio1s" ,z80sio_device, txca_w)) + + MCFG_DEVICE_ADD("sio1s", Z80SIO, XTAL_16MHz /4) + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232s", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232s", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232s", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232s", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio1s", z80sio_device, rxb_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio1s", z80sio_device, dcdb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio1s", z80sio_device, ctsb_w)) MACHINE_CONFIG_END /* ROM definition */ @@ -165,5 +196,73 @@ ROM_END /* Driver */ -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1982, c8002, 0, 0, c8002, c8002, onyx_state, 0, "Onyx", "C8002", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1982, c8002, 0, 0, c8002, c8002, onyx_state, 0, "Onyx Systems", "C8002", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) + + + +/******************************************************************************************************************************** + +Onyx Systems C5000. +(says C8000 on the backplate) + +Chips: 256k dynamic RAM, Z80A, Z80DMA, 5x Z80PIO, 2x Z80SIO/0, 2x Z80CTC, 5? undumped proms, 3 red leds, 1x 4-sw DIP +Crystals: 16.000000, 19.660800 +Labels of proms: 339, 153, XMN4, 2_1, 1_2 + +*********************************************************************************************************************************/ + +static ADDRESS_MAP_START(c5000_mem, AS_PROGRAM, 8, onyx_state) + AM_RANGE(0x0000, 0x1fff) AM_ROM + AM_RANGE(0x2000, 0xffff) AM_RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START(c5000_io, AS_IO, 8, onyx_state) + ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x10, 0x13) AM_DEVREADWRITE("sio1", z80sio_device, cd_ba_r, cd_ba_w ) +ADDRESS_MAP_END + +static MACHINE_CONFIG_START( c5000 ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", Z80, XTAL_16MHz / 4 ) + //MCFG_Z80_DAISY_CHAIN(sub_daisy_chain) + MCFG_CPU_PROGRAM_MAP(c5000_mem) + MCFG_CPU_IO_MAP(c5000_io) + //MCFG_MACHINE_RESET_OVERRIDE(onyx_state, c8002) + + MCFG_DEVICE_ADD("sio1_clock", CLOCK, 614400) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("sio1", z80sio_device, rxtxcb_w)) + //MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio1" ,z80sio_device, txca_w)) + + /* peripheral hardware */ + //MCFG_DEVICE_ADD("pio1", Z80PIO, XTAL_16MHz/4) + //MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + //MCFG_DEVICE_ADD("pio2", Z80PIO, XTAL_16MHz/4) + //MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + //MCFG_DEVICE_ADD("ctc1", Z80CTC, XTAL_16MHz /4) + //MCFG_DEVICE_ADD("ctc2", Z80CTC, XTAL_16MHz /4) + //MCFG_DEVICE_ADD("ctc3", Z80CTC, XTAL_16MHz /4) + MCFG_DEVICE_ADD("sio1", Z80SIO, XTAL_16MHz /4) + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio1", z80sio_device, rxb_w)) + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio1", z80sio_device, dcdb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio1", z80sio_device, ctsb_w)) + + //MCFG_DEVICE_ADD("sio2", Z80SIO, XTAL_16MHz /4) +MACHINE_CONFIG_END + + +ROM_START( c5000 ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "860-3.prom1", 0x0000, 0x1000, CRC(31b52df3) SHA1(e221c7829b4805805cde1bde763bd5a936e7db1a) ) + ROM_LOAD( "861-3.prom2", 0x1000, 0x1000, CRC(d1eba182) SHA1(850035497975b821fc1e51fbb73642cba3ff9784) ) +ROM_END + +/* Driver */ + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1981, c5000, 0, 0, c5000, c8002, onyx_state, 0, "Onyx Systems", "C5000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) diff --git a/src/mame/drivers/osbexec.cpp b/src/mame/drivers/osbexec.cpp index e3e775dd0e3..d48da4ba9a9 100644 --- a/src/mame/drivers/osbexec.cpp +++ b/src/mame/drivers/osbexec.cpp @@ -16,7 +16,7 @@ #include "machine/pit8253.h" #include "machine/ram.h" #include "machine/wd_fdc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "sound/spkrdev.h" #include "screen.h" @@ -51,7 +51,7 @@ public: required_device<ram_device> m_messram; required_device<pia6821_device> m_pia_0; required_device<pia6821_device> m_pia_1; - required_device<z80dart_device> m_sio; + required_device<z80sio_device> m_sio; required_device<speaker_sound_device> m_speaker; required_device<floppy_image_device> m_floppy0; required_device<floppy_image_device> m_floppy1; @@ -221,7 +221,7 @@ static ADDRESS_MAP_START( osbexec_io, AS_IO, 8, osbexec_state ) AM_RANGE( 0x00, 0x03 ) AM_MIRROR( 0xff00 ) AM_DEVREADWRITE( "pia_0", pia6821_device, read, write) /* 6821 PIA @ UD12 */ AM_RANGE( 0x04, 0x07 ) AM_MIRROR( 0xff00 ) AM_DEVREADWRITE("ctc", pit8253_device, read, write) /* 8253 @UD1 */ AM_RANGE( 0x08, 0x0B ) AM_MIRROR( 0xff00 ) AM_DEVREADWRITE("mb8877", wd_fdc_device_base, read, write ) /* MB8877 @ UB17 input clock = 1MHz */ - AM_RANGE( 0x0C, 0x0F ) AM_MIRROR( 0xff00 ) AM_DEVREADWRITE("sio", z80sio2_device, ba_cd_r, ba_cd_w ) /* SIO @ UD4 */ + AM_RANGE( 0x0C, 0x0F ) AM_MIRROR( 0xff00 ) AM_DEVREADWRITE("sio", z80sio_device, ba_cd_r, ba_cd_w ) /* SIO @ UD4 */ AM_RANGE( 0x10, 0x13 ) AM_MIRROR( 0xff00 ) AM_DEVREADWRITE( "pia_1", pia6821_device, read, write) /* 6821 PIA @ UD8 */ AM_RANGE( 0x14, 0x17 ) AM_SELECT( 0xff00 ) AM_READ(osbexec_kbd_r ) /* KBD */ AM_RANGE( 0x18, 0x1b ) AM_MIRROR( 0xff00 ) AM_READ(osbexec_rtc_r ) /* "RTC" @ UE13/UF13 */ @@ -590,34 +590,34 @@ static MACHINE_CONFIG_START( osbexec ) MCFG_INPUT_MERGER_ANY_HIGH("mainirq") MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", 0)) - MCFG_DEVICE_ADD("sio", Z80SIO2, MAIN_CLOCK/6) - MCFG_Z80DART_OUT_TXDA_CB(DEVWRITELINE(MODEM_PORT_TAG, rs232_port_device, write_txd)) MCFG_DEVCB_INVERT - MCFG_Z80DART_OUT_DTRA_CB(DEVWRITELINE(MODEM_PORT_TAG, rs232_port_device, write_dtr)) MCFG_DEVCB_INVERT - MCFG_Z80DART_OUT_RTSA_CB(DEVWRITELINE(MODEM_PORT_TAG, rs232_port_device, write_rts)) MCFG_DEVCB_INVERT - MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE(PRINTER_PORT_TAG, rs232_port_device, write_txd)) MCFG_DEVCB_INVERT - MCFG_Z80DART_OUT_DTRB_CB(DEVWRITELINE(PRINTER_PORT_TAG, rs232_port_device, write_dtr)) MCFG_DEVCB_INVERT - MCFG_Z80DART_OUT_RTSB_CB(DEVWRITELINE(PRINTER_PORT_TAG, rs232_port_device, write_rts)) MCFG_DEVCB_INVERT - MCFG_Z80DART_OUT_INT_CB(DEVWRITELINE("mainirq", input_merger_device, in_w<4>)) + MCFG_DEVICE_ADD("sio", Z80SIO, MAIN_CLOCK/6) + MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE(MODEM_PORT_TAG, rs232_port_device, write_txd)) MCFG_DEVCB_INVERT + MCFG_Z80SIO_OUT_DTRA_CB(DEVWRITELINE(MODEM_PORT_TAG, rs232_port_device, write_dtr)) MCFG_DEVCB_INVERT + MCFG_Z80SIO_OUT_RTSA_CB(DEVWRITELINE(MODEM_PORT_TAG, rs232_port_device, write_rts)) MCFG_DEVCB_INVERT + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE(PRINTER_PORT_TAG, rs232_port_device, write_txd)) MCFG_DEVCB_INVERT + MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE(PRINTER_PORT_TAG, rs232_port_device, write_dtr)) MCFG_DEVCB_INVERT + MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE(PRINTER_PORT_TAG, rs232_port_device, write_rts)) MCFG_DEVCB_INVERT + MCFG_Z80SIO_OUT_INT_CB(DEVWRITELINE("mainirq", input_merger_device, in_w<4>)) MCFG_DEVICE_ADD("ctc", PIT8253, 0) MCFG_PIT8253_CLK0(MAIN_CLOCK / 13) // divided by 74S161 @ UC25 MCFG_PIT8253_CLK1(MAIN_CLOCK / 13) // divided by 74S161 @ UC25 MCFG_PIT8253_CLK2(MAIN_CLOCK / 12) MCFG_PIT8253_OUT0_HANDLER(WRITELINE(osbexec_state, comm_clk_a_w)) - MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("sio", z80sio2_device, rxtxcb_w)) + MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("sio", z80sio_device, rxtxcb_w)) //MCFG_PIT8253_OUT2_HANDLER(WRITELINE(osbexec_state, spindle_clk_w)) MCFG_RS232_PORT_ADD(MODEM_PORT_TAG, default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio2_device, rxa_w)) MCFG_DEVCB_INVERT - MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio", z80sio2_device, dcda_w)) MCFG_DEVCB_INVERT + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio_device, rxa_w)) MCFG_DEVCB_INVERT + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio", z80sio_device, dcda_w)) MCFG_DEVCB_INVERT MCFG_RS232_DSR_HANDLER(WRITELINE(osbexec_state, modem_dsr_w)) MCFG_RS232_RI_HANDLER(WRITELINE(osbexec_state, modem_ri_w)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio2_device, ctsa_w)) MCFG_DEVCB_INVERT + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio_device, ctsa_w)) MCFG_DEVCB_INVERT MCFG_RS232_PORT_ADD(PRINTER_PORT_TAG, default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio2_device, rxb_w)) MCFG_DEVCB_INVERT - MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio", z80sio2_device, dcdb_w)) MCFG_DEVCB_INVERT - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio2_device, ctsb_w)) MCFG_DEVCB_INVERT + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio_device, rxb_w)) MCFG_DEVCB_INVERT + MCFG_RS232_DCD_HANDLER(DEVWRITELINE("sio", z80sio_device, dcdb_w)) MCFG_DEVCB_INVERT + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio_device, ctsb_w)) MCFG_DEVCB_INVERT MCFG_DEVICE_ADD("mb8877", MB8877, MAIN_CLOCK/24) MCFG_WD_FDC_INTRQ_CALLBACK(DEVWRITELINE("pia_1", pia6821_device, cb1_w)) diff --git a/src/mame/drivers/osi.cpp b/src/mame/drivers/osi.cpp index 08ca2ec45db..c05dddff594 100644 --- a/src/mame/drivers/osi.cpp +++ b/src/mame/drivers/osi.cpp @@ -453,8 +453,7 @@ static ADDRESS_MAP_START( osi600_mem, AS_PROGRAM, 8, sb2m600_state ) AM_RANGE(0xa000, 0xbfff) AM_ROM AM_RANGE(0xd000, 0xd3ff) AM_RAM AM_SHARE("video_ram") AM_RANGE(0xdf00, 0xdf00) AM_READWRITE(keyboard_r, keyboard_w) - AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("acia_0", acia6850_device, status_r, control_w) - AM_RANGE(0xf001, 0xf001) AM_DEVREADWRITE("acia_0", acia6850_device, data_r, data_w) + AM_RANGE(0xf000, 0xf001) AM_DEVREADWRITE("acia_0", acia6850_device, read, write) AM_RANGE(0xf800, 0xffff) AM_ROM ADDRESS_MAP_END @@ -464,8 +463,7 @@ static ADDRESS_MAP_START( uk101_mem, AS_PROGRAM, 8, uk101_state ) AM_RANGE(0xd000, 0xd3ff) AM_RAM AM_SHARE("video_ram") AM_RANGE(0xd400, 0xd7ff) AM_NOP // bios sets this to spaces at boot AM_RANGE(0xdc00, 0xdfff) AM_READ(keyboard_r) AM_WRITE(keyboard_w) - AM_RANGE(0xf000, 0xf000) AM_MIRROR(0x00fe) AM_DEVREADWRITE("acia_0", acia6850_device, status_r, control_w) - AM_RANGE(0xf001, 0xf001) AM_MIRROR(0x00fe) AM_DEVREADWRITE("acia_0", acia6850_device, data_r, data_w) + AM_RANGE(0xf000, 0xf001) AM_MIRROR(0x00fe) AM_DEVREADWRITE("acia_0", acia6850_device, read, write) AM_RANGE(0xf800, 0xffff) AM_ROM ADDRESS_MAP_END @@ -479,8 +477,7 @@ static ADDRESS_MAP_START( c1p_mem, AS_PROGRAM, 8, c1p_state ) AM_RANGE(0xd400, 0xd7ff) AM_RAM AM_SHARE("color_ram") AM_RANGE(0xd800, 0xd800) AM_WRITE(ctrl_w) AM_RANGE(0xdf00, 0xdf00) AM_READWRITE(keyboard_r, keyboard_w) - AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("acia_0", acia6850_device, status_r, control_w) - AM_RANGE(0xf001, 0xf001) AM_DEVREADWRITE("acia_0", acia6850_device, data_r, data_w) + AM_RANGE(0xf000, 0xf001) AM_DEVREADWRITE("acia_0", acia6850_device, read, write) AM_RANGE(0xf7c0, 0xf7c0) AM_WRITE(osi630_sound_w) AM_RANGE(0xf7e0, 0xf7e0) AM_WRITE(osi630_ctrl_w) AM_RANGE(0xf800, 0xffff) AM_ROM @@ -490,8 +487,7 @@ static ADDRESS_MAP_START( c1pmf_mem, AS_PROGRAM, 8, c1pmf_state ) AM_RANGE(0x0000, 0x4fff) AM_RAMBANK("bank1") AM_RANGE(0xa000, 0xbfff) AM_ROM AM_RANGE(0xc000, 0xc003) AM_DEVREADWRITE("pia_0", pia6821_device, read, write) // FDC - AM_RANGE(0xc010, 0xc010) AM_DEVREADWRITE("acia_1", acia6850_device, status_r, control_w) - AM_RANGE(0xc011, 0xc011) AM_DEVREADWRITE("acia_1", acia6850_device, data_r, data_w) + AM_RANGE(0xc010, 0xc011) AM_DEVREADWRITE("acia_1", acia6850_device, read, write) AM_RANGE(0xc704, 0xc707) AM_DEVREADWRITE("pia_1", pia6821_device, read, write) AM_RANGE(0xc708, 0xc70b) AM_DEVREADWRITE("pia_2", pia6821_device, read, write) AM_RANGE(0xc70c, 0xc70f) AM_DEVREADWRITE("pia_3", pia6821_device, read, write) @@ -499,8 +495,7 @@ static ADDRESS_MAP_START( c1pmf_mem, AS_PROGRAM, 8, c1pmf_state ) AM_RANGE(0xd400, 0xd7ff) AM_RAM AM_SHARE("color_ram") AM_RANGE(0xd800, 0xd800) AM_WRITE(ctrl_w) AM_RANGE(0xdf00, 0xdf00) AM_READWRITE(keyboard_r, keyboard_w) - AM_RANGE(0xf000, 0xf000) AM_DEVREADWRITE("acia_0", acia6850_device, status_r, control_w) - AM_RANGE(0xf001, 0xf001) AM_DEVREADWRITE("acia_0", acia6850_device, data_r, data_w) + AM_RANGE(0xf000, 0xf001) AM_DEVREADWRITE("acia_0", acia6850_device, read, write) AM_RANGE(0xf7c0, 0xf7c0) AM_WRITE(osi630_sound_w) AM_RANGE(0xf7e0, 0xf7e0) AM_WRITE(osi630_ctrl_w) AM_RANGE(0xf800, 0xffff) AM_ROM diff --git a/src/mame/drivers/p8k.cpp b/src/mame/drivers/p8k.cpp index 6d2d78b2c4f..e17148291ce 100644 --- a/src/mame/drivers/p8k.cpp +++ b/src/mame/drivers/p8k.cpp @@ -51,7 +51,7 @@ #include "cpu/z8000/z8000.h" #include "machine/upd765.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80dma.h" #include "machine/z80pio.h" #include "sound/beep.h" @@ -87,6 +87,8 @@ public: : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_daisy(*this, "p8k_16_daisy") + , m_pio2(*this, "pio2") + , m_i8272(*this, "i8272") { } DECLARE_READ8_MEMBER(p8k_port0_r); @@ -106,6 +108,8 @@ public: private: required_device<cpu_device> m_maincpu; optional_device<p8k_16_daisy_device> m_daisy; + optional_device<z80pio_device> m_pio2; + optional_device<i8272a_device> m_i8272; }; /*************************************************************************** @@ -141,8 +145,8 @@ static ADDRESS_MAP_START(p8k_iomap, AS_IO, 8, p8k_state) AM_RANGE(0x18, 0x1b) AM_DEVREADWRITE("pio1", z80pio_device, read_alt, write_alt) AM_RANGE(0x1c, 0x1f) AM_DEVREADWRITE("pio2", z80pio_device, read_alt, write_alt) AM_RANGE(0x20, 0x21) AM_DEVICE("i8272", i8272a_device, map) - AM_RANGE(0x24, 0x27) AM_DEVREADWRITE("sio0", z80sio0_device, ba_cd_r, ba_cd_w) - AM_RANGE(0x28, 0x2b) AM_DEVREADWRITE("sio1", z80sio0_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x24, 0x27) AM_DEVREADWRITE("sio", z80sio_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x28, 0x2b) AM_DEVREADWRITE("sio1", z80sio_device, ba_cd_r, ba_cd_w) AM_RANGE(0x2c, 0x2f) AM_DEVREADWRITE("ctc1", z80ctc_device, read, write) AM_RANGE(0x3c, 0x3c) AM_DEVREADWRITE("dma", z80dma_device, read, write) ADDRESS_MAP_END @@ -195,9 +199,7 @@ WRITE_LINE_MEMBER( p8k_state::p8k_daisy_interrupt ) WRITE_LINE_MEMBER( p8k_state::p8k_dma_irq_w ) { - i8272a_device *i8272 = machine().device<i8272a_device>("i8272"); - i8272->tc_w(state); - + m_i8272->tc_w(state); p8k_daisy_interrupt(state); } @@ -233,7 +235,7 @@ static const z80_daisy_config p8k_daisy_chain[] = { "dma" }, /* FDC related */ { "pio2" }, { "ctc0" }, - { "sio0" }, + { "sio" }, { "sio1" }, { "pio0" }, { "pio1" }, @@ -245,8 +247,7 @@ static const z80_daisy_config p8k_daisy_chain[] = DECLARE_WRITE_LINE_MEMBER( p8k_state::fdc_irq ) { - z80pio_device *z80pio = machine().device<z80pio_device>("pio2"); - z80pio->port_b_write(state ? 0x10 : 0x00); + m_pio2->port_b_write(state ? 0x10 : 0x00); } static SLOT_INTERFACE_START( p8k_floppies ) @@ -326,8 +327,8 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(p8k_16_iomap, AS_IO, 16, p8k_state) // AM_RANGE(0x0fef0, 0x0feff) // clock - AM_RANGE(0x0ff80, 0x0ff87) AM_DEVREADWRITE8("sio0", z80sio0_device, cd_ba_r, cd_ba_w, 0xff) - AM_RANGE(0x0ff88, 0x0ff8f) AM_DEVREADWRITE8("sio1", z80sio0_device, cd_ba_r, cd_ba_w, 0xff) + AM_RANGE(0x0ff80, 0x0ff87) AM_DEVREADWRITE8("sio", z80sio_device, cd_ba_r, cd_ba_w, 0xff) + AM_RANGE(0x0ff88, 0x0ff8f) AM_DEVREADWRITE8("sio1", z80sio_device, cd_ba_r, cd_ba_w, 0xff) AM_RANGE(0x0ff90, 0x0ff97) AM_DEVREADWRITE8("pio0", z80pio_device, read_alt, write_alt, 0xff) AM_RANGE(0x0ff98, 0x0ff9f) AM_DEVREADWRITE8("pio1", z80pio_device, read_alt, write_alt, 0xff) AM_RANGE(0x0ffa0, 0x0ffa7) AM_DEVREADWRITE8("pio2", z80pio_device, read_alt, write_alt, 0xff) @@ -361,7 +362,7 @@ static const z80_daisy_config p8k_16_daisy_chain[] = { { "ctc0" }, { "ctc1" }, - { "sio0" }, + { "sio" }, { "sio1" }, { "pio0" }, { "pio1" }, @@ -416,8 +417,8 @@ static MACHINE_CONFIG_START( p8k ) MCFG_Z80DMA_OUT_IORQ_CB(WRITE8(p8k_state, io_write_byte)) MCFG_DEVICE_ADD("uart_clock", CLOCK, 307200) - MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("sio0", z80sio0_device, txcb_w)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio0", z80sio0_device, rxcb_w)) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("sio", z80sio_device, txcb_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio", z80sio_device, rxcb_w)) MCFG_DEVICE_ADD("ctc0", Z80CTC, 1229000) /* 1.22MHz clock */ // to implement: callbacks! @@ -431,18 +432,18 @@ static MACHINE_CONFIG_START( p8k ) // Baud Gen 0, Baud Gen 1, Baud Gen 2, MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio0", Z80SIO0, XTAL_4MHz) - MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) - MCFG_Z80DART_OUT_DTRB_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) - MCFG_Z80DART_OUT_RTSB_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio", Z80SIO, XTAL_4MHz) + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio0", z80sio0_device, rxb_w)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio0", z80sio0_device, ctsb_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio_device, rxb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio_device, ctsb_w)) - MCFG_DEVICE_ADD("sio1", Z80SIO0, XTAL_4MHz) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio1", Z80SIO, XTAL_4MHz) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_DEVICE_ADD("pio0", Z80PIO, 1229000) MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) @@ -478,8 +479,8 @@ static MACHINE_CONFIG_START( p8k_16 ) MCFG_Z80_DAISY_CHAIN(p8k_16_daisy_chain) MCFG_DEVICE_ADD("uart_clock", CLOCK, 307200) - MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("sio0", z80sio0_device, txcb_w)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio0", z80sio0_device, rxcb_w)) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("sio", z80sio_device, txcb_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio", z80sio_device, rxcb_w)) /* peripheral hardware */ MCFG_DEVICE_ADD("ctc0", Z80CTC, XTAL_4MHz) @@ -488,18 +489,18 @@ static MACHINE_CONFIG_START( p8k_16 ) MCFG_DEVICE_ADD("ctc1", Z80CTC, XTAL_4MHz) MCFG_Z80CTC_INTR_CB(WRITELINE(p8k_state, p8k_16_daisy_interrupt)) - MCFG_DEVICE_ADD("sio0", Z80SIO0, XTAL_4MHz) - MCFG_Z80DART_OUT_TXDB_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) - MCFG_Z80DART_OUT_DTRB_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) - MCFG_Z80DART_OUT_RTSB_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) - MCFG_Z80DART_OUT_INT_CB(WRITELINE(p8k_state, p8k_16_daisy_interrupt)) + MCFG_DEVICE_ADD("sio", Z80SIO, XTAL_4MHz) + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_Z80SIO_OUT_DTRB_CB(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_Z80SIO_OUT_RTSB_CB(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + MCFG_Z80SIO_OUT_INT_CB(WRITELINE(p8k_state, p8k_16_daisy_interrupt)) MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio0", z80sio0_device, rxb_w)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio0", z80sio0_device, ctsb_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio_device, rxb_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio_device, ctsb_w)) - MCFG_DEVICE_ADD("sio1", Z80SIO0, XTAL_4MHz) - MCFG_Z80DART_OUT_INT_CB(WRITELINE(p8k_state, p8k_16_daisy_interrupt)) + MCFG_DEVICE_ADD("sio1", Z80SIO, XTAL_4MHz) + MCFG_Z80SIO_OUT_INT_CB(WRITELINE(p8k_state, p8k_16_daisy_interrupt)) MCFG_DEVICE_ADD("pio0", Z80PIO, XTAL_4MHz) MCFG_Z80PIO_OUT_INT_CB(WRITELINE(p8k_state, p8k_16_daisy_interrupt)) diff --git a/src/mame/drivers/pacman.cpp b/src/mame/drivers/pacman.cpp index 7addb73f540..4475c90fecd 100644 --- a/src/mame/drivers/pacman.cpp +++ b/src/mame/drivers/pacman.cpp @@ -5973,18 +5973,19 @@ ROM_START( lizwiz ) ROM_END -ROM_START( theglobp ) - ROM_REGION( 0x20000, "maincpu", 0 ) - ROM_LOAD( "glob.u2", 0x0000, 0x2000, CRC(829d0bea) SHA1(89f52b459a03fb40b9bbd97ac8a292f7ead6faba) ) - ROM_LOAD( "glob.u3", 0x2000, 0x2000, CRC(31de6628) SHA1(35a47dcf34efd74b5b2fda137e06a3dcabd74854) ) +// Distributed by: Eagle Conversions, 25 Eagle St., Bldg #5, Providence, RI 02908 +ROM_START( theglobp ) // Pac-Man PCB conversion kit. Includes a small daughtercard (2 roms + 4 PLDs, plugs in through the Z80 socket), 2 roms + 2 BPROMs + ROM_REGION( 0x20000, "maincpu", 0 ) // these 2 ROMs are encrypted & located on daughtercard + ROM_LOAD( "u_2_the_glob_pg02284_eagle.u2", 0x0000, 0x2000, CRC(829d0bea) SHA1(89f52b459a03fb40b9bbd97ac8a292f7ead6faba) ) /* actual label: U 2 THE GLOB PG02284 EAGLE */ + ROM_LOAD( "u_3_the_glob_pg02284_eagle.u3", 0x2000, 0x2000, CRC(31de6628) SHA1(35a47dcf34efd74b5b2fda137e06a3dcabd74854) ) /* actual label: U 3 THE GLOB PG02284 EAGLE */ ROM_REGION( 0x2000, "gfx1", 0 ) - ROM_LOAD( "glob.5e", 0x0000, 0x1000, CRC(53688260) SHA1(9ce0d1d67d12743b69e8190bf7506b00b2f02955) ) - ROM_LOAD( "glob.5f", 0x1000, 0x1000, CRC(051f59c7) SHA1(e1e1322686997e5bcdac164704b328cce352ae42) ) + ROM_LOAD( "5_e_the_glob_pg02284_eagle.5e", 0x0000, 0x1000, CRC(53688260) SHA1(9ce0d1d67d12743b69e8190bf7506b00b2f02955) ) /* actual label: 5 E THE GLOB PG02284 EAGLE */ + ROM_LOAD( "5_f_the_glob_pg02284_eagle.5f", 0x1000, 0x1000, CRC(051f59c7) SHA1(e1e1322686997e5bcdac164704b328cce352ae42) ) /* actual label: 5 F THE GLOB PG02284 EAGLE */ ROM_REGION( 0x0120, "proms", 0 ) - ROM_LOAD( "glob.7f", 0x0000, 0x0020, CRC(1f617527) SHA1(448845cab63800a05fcb106897503d994377f78f) ) - ROM_LOAD( "glob.4a", 0x0020, 0x0100, CRC(28faa769) SHA1(7588889f3102d4e0ca7918f536556209b2490ea1) ) + ROM_LOAD( "7_f_the_glob.7f", 0x0000, 0x0020, CRC(1f617527) SHA1(448845cab63800a05fcb106897503d994377f78f) ) /* actual label: 7 F THE GLOB (black dot preceeds "THE") */ + ROM_LOAD( "4_a_the_glob.4a", 0x0020, 0x0100, CRC(28faa769) SHA1(7588889f3102d4e0ca7918f536556209b2490ea1) ) /* actual label: 7 F THE GLOB (black dot preceeds "THE") */ ROM_REGION( 0x0200, "namco", 0 ) /* sound PROMs */ ROM_LOAD( "82s126.1m", 0x0000, 0x0100, CRC(a9cc86bf) SHA1(bbcec0570aeceb582ff8238a4bc8546a23430081) ) @@ -5995,16 +5996,16 @@ ROM_END //Program roms same as the globp ROM_START( sprglobp ) ROM_REGION( 0x20000, "maincpu", 0 ) - ROM_LOAD( "glob.u2", 0x0000, 0x2000, CRC(829d0bea) SHA1(89f52b459a03fb40b9bbd97ac8a292f7ead6faba) ) - ROM_LOAD( "glob.u3", 0x2000, 0x2000, CRC(31de6628) SHA1(35a47dcf34efd74b5b2fda137e06a3dcabd74854) ) + ROM_LOAD( "u_2_the_glob_pg02284_eagle.u2", 0x0000, 0x2000, CRC(829d0bea) SHA1(89f52b459a03fb40b9bbd97ac8a292f7ead6faba) ) + ROM_LOAD( "u_3_the_glob_pg02284_eagle.u3", 0x2000, 0x2000, CRC(31de6628) SHA1(35a47dcf34efd74b5b2fda137e06a3dcabd74854) ) ROM_REGION( 0x2000, "gfx1", 0 ) ROM_LOAD( "5e_2532.dat", 0x0000, 0x1000, CRC(1aa16109) SHA1(ddc8606512d7ab7555b84146b9d793f65ad0a75f) ) ROM_LOAD( "5f_2532.dat", 0x1000, 0x1000, CRC(afe72a89) SHA1(fb17632e2665c3cebc1865ef25fa310cc52725c4) ) ROM_REGION( 0x0120, "proms", 0 ) - ROM_LOAD( "glob.7f", 0x0000, 0x0020, CRC(1f617527) SHA1(448845cab63800a05fcb106897503d994377f78f) ) - ROM_LOAD( "glob.4a", 0x0020, 0x0100, CRC(28faa769) SHA1(7588889f3102d4e0ca7918f536556209b2490ea1) ) + ROM_LOAD( "7_f_the_glob.7f", 0x0000, 0x0020, CRC(1f617527) SHA1(448845cab63800a05fcb106897503d994377f78f) ) + ROM_LOAD( "4_a_the_glob.4a", 0x0020, 0x0100, CRC(28faa769) SHA1(7588889f3102d4e0ca7918f536556209b2490ea1) ) ROM_REGION( 0x0200, "namco", 0 ) /* sound PROMs */ ROM_LOAD( "82s126.1m", 0x0000, 0x0100, CRC(a9cc86bf) SHA1(bbcec0570aeceb582ff8238a4bc8546a23430081) ) @@ -6046,8 +6047,8 @@ ROM_START( beastfp ) ROM_LOAD( "beastf.ic4", 0x0000, 0x002c, CRC(a6ab926d) SHA1(a8c2ddce2d595cecf057b37916f2f897de8a0e4e) ) // pal10h8 ROM_REGION( 0x0120, "proms", 0 ) - ROM_LOAD( "glob.7f", 0x0000, 0x0020, CRC(1f617527) SHA1(448845cab63800a05fcb106897503d994377f78f) ) - ROM_LOAD( "glob.4a", 0x0020, 0x0100, CRC(28faa769) SHA1(7588889f3102d4e0ca7918f536556209b2490ea1) ) + ROM_LOAD( "7_f_the_glob.7f", 0x0000, 0x0020, CRC(1f617527) SHA1(448845cab63800a05fcb106897503d994377f78f) ) + ROM_LOAD( "4_a_the_glob.4a", 0x0020, 0x0100, CRC(28faa769) SHA1(7588889f3102d4e0ca7918f536556209b2490ea1) ) ROM_REGION( 0x0200, "namco", 0 ) /* sound PROMs */ ROM_LOAD( "82s126.1m", 0x0000, 0x0100, CRC(a9cc86bf) SHA1(bbcec0570aeceb582ff8238a4bc8546a23430081) ) diff --git a/src/mame/drivers/palm.cpp b/src/mame/drivers/palm.cpp index 2e9ffa1d340..f37ac1c9d37 100644 --- a/src/mame/drivers/palm.cpp +++ b/src/mame/drivers/palm.cpp @@ -58,7 +58,7 @@ public: required_ioport m_io_penb; required_ioport m_io_portd; - offs_t palm_dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options); + 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); }; diff --git a/src/mame/drivers/palm_dbg.hxx b/src/mame/drivers/palm_dbg.hxx index 44b952b2260..13d4a18e0ac 100644 --- a/src/mame/drivers/palm_dbg.hxx +++ b/src/mame/drivers/palm_dbg.hxx @@ -1162,18 +1162,16 @@ static const char *lookup_trap(uint16_t opcode) return nullptr; } -offs_t palm_state::palm_dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options) +offs_t palm_state::palm_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms) { - uint16_t opcode; unsigned result = 0; const char *trap; - opcode = *((uint16_t *) oprom); - opcode = ((opcode >> 8) & 0x00ff) | ((opcode << 8) & 0xff00); + uint16_t opcode = opcodes.r16(pc); + if (opcode == 0x4E4F) { - uint16_t callnum = *((uint16_t *) (oprom + 2)); - callnum = ((callnum >> 8) & 0x00ff) | ((callnum << 8) & 0xff00); + uint16_t callnum = opcodes.r16(pc+2); trap = lookup_trap(callnum); result = 2; stream << (trap ? trap : "trap #$f"); diff --git a/src/mame/drivers/parodius.cpp b/src/mame/drivers/parodius.cpp index c61f742a184..63c6c778fca 100644 --- a/src/mame/drivers/parodius.cpp +++ b/src/mame/drivers/parodius.cpp @@ -238,15 +238,15 @@ static MACHINE_CONFIG_START( parodius ) MCFG_DEVICE_ADD("bank0000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank0000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x0800) MCFG_DEVICE_ADD("bank2000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank2000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(12) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(12) MCFG_ADDRESS_MAP_BANK_STRIDE(0x0800) MCFG_WATCHDOG_ADD("watchdog") diff --git a/src/mame/drivers/pasogo.cpp b/src/mame/drivers/pasogo.cpp index baa205f86be..f9eb18c9e66 100644 --- a/src/mame/drivers/pasogo.cpp +++ b/src/mame/drivers/pasogo.cpp @@ -544,7 +544,7 @@ static MACHINE_CONFIG_START( pasogo ) MCFG_DEVICE_ADD("ems", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(emsbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_IBM5160_MOTHERBOARD_ADD("mb", "maincpu") diff --git a/src/mame/drivers/pc.cpp b/src/mame/drivers/pc.cpp index fc0a5d30df5..b04cf4e2539 100644 --- a/src/mame/drivers/pc.cpp +++ b/src/mame/drivers/pc.cpp @@ -346,6 +346,7 @@ Misc: A Kaypro 16/2 is a configuration without harddisk but with two floppy disk #include "emu.h" #include "machine/genpc.h" +#include "machine/i8251.h" #include "cpu/i86/i86.h" #include "cpu/nec/nec.h" #include "bus/isa/isa.h" @@ -410,6 +411,13 @@ static ADDRESS_MAP_START(ibm5550_io, AS_IO, 16, pc_state ) AM_RANGE(0x0000, 0x00ff) AM_DEVICE8("mb", ibm5160_mb_device, map, 0xffff) ADDRESS_MAP_END +static ADDRESS_MAP_START(epc_io, AS_IO, 8, pc_state) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x0070, 0x0070) AM_DEVREADWRITE("i8251", i8251_device, data_r, data_w) + AM_RANGE(0x0071, 0x0071) AM_DEVREADWRITE("i8251", i8251_device, status_r, control_w) + AM_RANGE(0x0000, 0x00ff) AM_DEVICE("mb", ibm5160_mb_device, map) +ADDRESS_MAP_END + INPUT_CHANGED_MEMBER(pc_state::pc_turbo_callback) { m_maincpu->set_clock_scale((newval & 2) ? 1 : m_turbo_off_speed); @@ -525,6 +533,11 @@ MACHINE_CONFIG_END // Ericsson Information System static MACHINE_CONFIG_DERIVED( epc, pccga ) + MCFG_DEVICE_REMOVE("maincpu") + MCFG_CPU_PC(pc8, epc, I8088, 4772720) + MCFG_DEVICE_MODIFY("isa1") + MCFG_SLOT_DEFAULT_OPTION("ega") + MCFG_DEVICE_ADD("i8251", I8251, 0) // clock? MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( eppc, pccga ) @@ -823,9 +836,13 @@ ROM_END ROM_START( epc ) ROM_REGION(0x10000,"bios", 0) - ROM_LOAD( "epcbios1.bin", 0xe000, 0x02000, CRC(79a83706) SHA1(33528c46a24d7f65ef5a860fbed05afcf797fc55)) - ROM_LOAD( "epcbios2.bin", 0xc000, 0x02000, CRC(3ca764ca) SHA1(02232fedef22d31a641f4b65933b9e269afce19e)) - ROM_LOAD( "epcbios3.bin", 0xa000, 0x02000, CRC(70483280) SHA1(b44b09da94d77b0269fc48f07d130b2d74c4bb8f)) + ROM_DEFAULT_BIOS("p860110") + ROM_SYSTEM_BIOS(0, "p840705", "P840705") + ROMX_LOAD("ericsson_8088.bin", 0xe000, 0x2000, CRC(3953c38d) SHA1(2bfc1f1d11d0da5664c3114994fc7aa3d6dd010d), ROM_BIOS(1)) + ROM_SYSTEM_BIOS(1, "p860110", "P860110") + ROMX_LOAD( "epcbios1.bin", 0xe000, 0x02000, CRC(79a83706) SHA1(33528c46a24d7f65ef5a860fbed05afcf797fc55), ROM_BIOS(2)) + ROMX_LOAD( "epcbios2.bin", 0xa000, 0x02000, CRC(3ca764ca) SHA1(02232fedef22d31a641f4b65933b9e269afce19e), ROM_BIOS(2)) + ROMX_LOAD( "epcbios3.bin", 0xc000, 0x02000, CRC(70483280) SHA1(b44b09da94d77b0269fc48f07d130b2d74c4bb8f), ROM_BIOS(2)) ROM_END ROM_START( eppc ) @@ -997,6 +1014,7 @@ ROM_START( kaypro16 ) ROM_LOAD("pc102782.bin", 0xe000, 0x2000, CRC(ade4ed14) SHA1(de6d87ae83a71728d60df6a5964e680487ea8400)) ROM_END + /*************************************************************************** Game driver(s) diff --git a/src/mame/drivers/pc9801.cpp b/src/mame/drivers/pc9801.cpp index be1e38219af..036cccbd006 100644 --- a/src/mame/drivers/pc9801.cpp +++ b/src/mame/drivers/pc9801.cpp @@ -2396,8 +2396,8 @@ static MACHINE_CONFIG_START( pc9801rs ) MCFG_DEVICE_ADD("ipl_bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(ipl_bank) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x18000) MCFG_MACHINE_START_OVERRIDE(pc9801_state,pc9801rs) diff --git a/src/mame/drivers/pcm.cpp b/src/mame/drivers/pcm.cpp index 2183928883e..7b6cce016b9 100644 --- a/src/mame/drivers/pcm.cpp +++ b/src/mame/drivers/pcm.cpp @@ -58,7 +58,7 @@ #include "imagedev/cassette.h" #include "machine/k7659kb.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80pio.h" #include "sound/spkrdev.h" #include "sound/wave.h" @@ -72,11 +72,10 @@ public: pcm_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") - , m_pio_s(*this, "z80pio_s") - , m_pio_u(*this, "z80pio_u") - , m_sio(*this, "z80sio") - , m_ctc_s(*this, "z80ctc_s") - , m_ctc_u(*this, "z80ctc_u") + , m_pio_s(*this, "pio_s") + , m_pio_u(*this, "pio_u") + , m_ctc_s(*this, "ctc_s") + , m_ctc_u(*this, "ctc_u") , m_speaker(*this, "speaker") , m_cass(*this, "cassette") , m_p_videoram(*this, "videoram") @@ -96,7 +95,6 @@ private: required_device<cpu_device> m_maincpu; required_device<z80pio_device> m_pio_s; required_device<z80pio_device> m_pio_u; - required_device<z80sio0_device> m_sio; required_device<z80ctc_device> m_ctc_s; required_device<z80ctc_device> m_ctc_u; required_device<speaker_sound_device> m_speaker; @@ -169,11 +167,11 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(pcm_io, AS_IO, 8, pcm_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0x80, 0x83) AM_DEVREADWRITE("z80ctc_s", z80ctc_device, read, write) // system CTC - AM_RANGE(0x84, 0x87) AM_DEVREADWRITE("z80pio_s", z80pio_device, read, write) // system PIO - AM_RANGE(0x88, 0x8B) AM_DEVREADWRITE("z80sio", z80sio0_device, cd_ba_r, cd_ba_w) // SIO - AM_RANGE(0x8C, 0x8F) AM_DEVREADWRITE("z80ctc_u", z80ctc_device, read, write) // user CTC - AM_RANGE(0x90, 0x93) AM_DEVREADWRITE("z80pio_u", z80pio_device, read, write) // user PIO + AM_RANGE(0x80, 0x83) AM_DEVREADWRITE("ctc_s", z80ctc_device, read, write) // system CTC + AM_RANGE(0x84, 0x87) AM_DEVREADWRITE("pio_s", z80pio_device, read, write) // system PIO + AM_RANGE(0x88, 0x8B) AM_DEVREADWRITE("sio", z80sio_device, cd_ba_r, cd_ba_w) // SIO + AM_RANGE(0x8C, 0x8F) AM_DEVREADWRITE("ctc_u", z80ctc_device, read, write) // user CTC + AM_RANGE(0x90, 0x93) AM_DEVREADWRITE("pio_u", z80pio_device, read, write) // user PIO //AM_RANGE(0x94, 0x97) // bank select //AM_RANGE(0x98, 0x9B) // NMI generator //AM_RANGE(0x9C, 0x9F) // io ports available to the user @@ -223,11 +221,11 @@ uint32_t pcm_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c static const z80_daisy_config pcm_daisy_chain[] = { - { "z80ctc_s" }, /* System ctc */ - { "z80pio_s" }, /* System pio */ - { "z80sio" }, /* sio */ - { "z80pio_u" }, /* User pio */ - { "z80ctc_u" }, /* User ctc */ + { "ctc_s" }, /* System ctc */ + { "pio_s" }, /* System pio */ + { "sio" }, /* sio */ + { "pio_u" }, /* User pio */ + { "ctc_u" }, /* User ctc */ { nullptr } }; @@ -280,24 +278,25 @@ static MACHINE_CONFIG_START( pcm ) MCFG_K7659_KEYBOARD_ADD() MCFG_CASSETTE_ADD("cassette") - MCFG_DEVICE_ADD("z80pio_u", Z80PIO, XTAL_10MHz/4) + MCFG_DEVICE_ADD("pio_u", Z80PIO, XTAL_10MHz/4) MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("z80pio_s", Z80PIO, XTAL_10MHz/4) + MCFG_DEVICE_ADD("pio_s", Z80PIO, XTAL_10MHz/4) MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_Z80PIO_IN_PA_CB(DEVREAD8(K7659_KEYBOARD_TAG, k7659_keyboard_device, read)) MCFG_Z80PIO_IN_PB_CB(READ8(pcm_state, pcm_85_r)) MCFG_Z80PIO_OUT_PB_CB(WRITE8(pcm_state, pcm_85_w)) - MCFG_DEVICE_ADD("z80sio", Z80SIO0, 4800) // clocks come from the system ctc + MCFG_DEVICE_ADD("sio", Z80SIO, XTAL_10MHz /4) - MCFG_DEVICE_ADD("z80ctc_u", Z80CTC, XTAL_10MHz /4) + MCFG_DEVICE_ADD("ctc_u", Z80CTC, XTAL_10MHz /4) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("z80ctc_s", Z80CTC, XTAL_10MHz /4) + MCFG_DEVICE_ADD("ctc_s", Z80CTC, XTAL_10MHz /4) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - // ZC0 : SIO channel A clock - // ZC1 : SIO channel B clock + MCFG_Z80CTC_ZC0_CB(DEVWRITELINE("sio", z80sio_device, rxca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("sio", z80sio_device, rxca_w)) + MCFG_Z80CTC_ZC1_CB(DEVWRITELINE("sio", z80sio_device, rxtxcb_w)) MCFG_Z80CTC_ZC2_CB(WRITELINE(pcm_state, pcm_82_w)) // speaker MACHINE_CONFIG_END diff --git a/src/mame/drivers/pcxt.cpp b/src/mame/drivers/pcxt.cpp index 42bfd095cbf..0f766aa0473 100644 --- a/src/mame/drivers/pcxt.cpp +++ b/src/mame/drivers/pcxt.cpp @@ -496,8 +496,8 @@ static MACHINE_CONFIG_START( filetto ) MCFG_DEVICE_ADD("bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MACHINE_CONFIG_END diff --git a/src/mame/drivers/pencil2.cpp b/src/mame/drivers/pencil2.cpp index 27ec9d2f41a..a189f8ef50a 100644 --- a/src/mame/drivers/pencil2.cpp +++ b/src/mame/drivers/pencil2.cpp @@ -126,7 +126,7 @@ private: required_device<generic_slot_device> m_cart; }; -static ADDRESS_MAP_START(pencil2_mem, AS_PROGRAM, 8, pencil2_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, pencil2_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x1fff) AM_ROM AM_RANGE(0x2000, 0x5fff) AM_WRITENOP // stop error log filling up @@ -134,7 +134,7 @@ static ADDRESS_MAP_START(pencil2_mem, AS_PROGRAM, 8, pencil2_state) //AM_RANGE(0x8000, 0xffff) // mapped by the cartslot ADDRESS_MAP_END -static ADDRESS_MAP_START(pencil2_io, AS_IO, 8, pencil2_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, pencil2_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x0f) AM_DEVWRITE("cent_data_out", output_latch_device, write) @@ -306,8 +306,8 @@ void pencil2_state::machine_start() static MACHINE_CONFIG_START( pencil2 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, XTAL_10_738635MHz/3) - MCFG_CPU_PROGRAM_MAP(pencil2_mem) - MCFG_CPU_IO_MAP(pencil2_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_DEVICE_ADD( "tms9928a", TMS9929A, XTAL_10_738635MHz / 2 ) diff --git a/src/mame/drivers/pengadvb.cpp b/src/mame/drivers/pengadvb.cpp index 60ccb7c1505..f10f8c72359 100644 --- a/src/mame/drivers/pengadvb.cpp +++ b/src/mame/drivers/pengadvb.cpp @@ -214,29 +214,29 @@ static MACHINE_CONFIG_START( pengadvb ) MCFG_DEVICE_ADD("page0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_DEVICE_ADD("page1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_DEVICE_ADD("page2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_DEVICE_ADD("page3", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_DEVICE_ADD("ppi8255", I8255, 0) diff --git a/src/mame/drivers/peplus.cpp b/src/mame/drivers/peplus.cpp index 8051b314791..fadf787cca3 100644 --- a/src/mame/drivers/peplus.cpp +++ b/src/mame/drivers/peplus.cpp @@ -8306,6 +8306,21 @@ ROM_START( peps0207 ) /* Normal board : Red White & Blue Slots (PS0207) - Payout ROM_LOAD( "cap960.u50", 0x0000, 0x0100, CRC(00dd8d0a) SHA1(542763b12aeb0aec2b410f7c075c52907f45d171) ) ROM_END +ROM_START( peps0239 ) /* Normal board : Jackpot Jewels Slots (PS0239) - Payout 92.65% */ + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "ps0239_545-871.u68", 0x00000, 0x08000, CRC(4a5106b4) SHA1(f84b574e371b2c9b1c0eaee1f7ca7e74a63e5984) ) /* 2 Coins Max / 1 Line */ + ROM_RELOAD( 0x08000, 0x08000) /* 32K version built using earlier gaming libraries */ + + ROM_REGION( 0x020000, "gfx1", 0 ) + ROM_LOAD( "mro-cg1151.u72", 0x00000, 0x8000, BAD_DUMP CRC(596f1207) SHA1(d66acfa509e33e9fe2dce89ef4c19909a578b3bf) ) /* 08/24/92 @ IGT MN */ + ROM_LOAD( "mgo-cg1151.u73", 0x08000, 0x8000, BAD_DUMP CRC(aa4984ca) SHA1(2bbf2eba739b6cac7459a8021535967520c198ba) ) + ROM_LOAD( "mbo-cg1151.u74", 0x10000, 0x8000, BAD_DUMP CRC(cf13bf00) SHA1(beaaa9acf660bb2c59d68f9f971b1e8f11bd81e9) ) /* one of these four roms are bad as there are 7 rogue */ + ROM_LOAD( "mxo-cg1151.u75", 0x18000, 0x8000, BAD_DUMP CRC(659d72db) SHA1(973ccd71a7993d1885f1dbd0f877f18133650616) ) /* "green" dots in the single BAR with Diamond graphic */ + + ROM_REGION( 0x100, "proms", 0 ) + ROM_LOAD( "cap1151.u50", 0x0000, 0x0100, CRC(f8079ea2) SHA1(92dc104a76b3e5fa272f2f769a328b238c1702ed) ) +ROM_END + ROM_START( peps0296 ) /* Normal board : Haywire Slots (PS0296) - Payout 90.00% */ ROM_REGION( 0x10000, "maincpu", 0 ) ROM_LOAD( "ps0296_561-959.u68", 0x00000, 0x10000, CRC(da871550) SHA1(99e7a4fc77731b185751622ba2e08a44ad8eb7f9) ) /* 3 Coins Max / 1 Line */ @@ -13771,14 +13786,10 @@ Double Aces & Faces ????? 99.20% ROM_LOAD( "xm00009p.u66", 0x00000, 0x10000, CRC(e133d0bb) SHA1(7ed4fa335e230c28e6fc66f0c990bc7ead2b279d) ) ROM_REGION( 0x020000, "gfx1", 0 ) - ROM_LOAD( "mro-cg2xxx.u77", 0x00000, 0x8000, NO_DUMP ) /* This set requires an unknown CG graphics set for the correct banners on the MENU page */ - ROM_LOAD( "mgo-cg2xxx.u78", 0x08000, 0x8000, NO_DUMP ) /* Most likely CG2227, CG2229 or CG2239 */ - ROM_LOAD( "mbo-cg2xxx.u79", 0x10000, 0x8000, NO_DUMP ) - ROM_LOAD( "mxo-cg2xxx.u80", 0x18000, 0x8000, NO_DUMP ) - ROM_LOAD( "mro-cg2174.u77", 0x00000, 0x8000, CRC(bb666733) SHA1(dcaa1980b051a554cb0f443b1183a680edc9ad3f) ) /* 07/26/95 @ IGT L95-1616 */ - ROM_LOAD( "mgo-cg2174.u78", 0x08000, 0x8000, CRC(cc46adb0) SHA1(6065aa5dcb9091ad80e499c7ee6dc629e79c865a) ) /* Close but banners on MEMU WRONG!! */ - ROM_LOAD( "mbo-cg2174.u79", 0x10000, 0x8000, CRC(7291a0c8) SHA1(1068f35e6ef5fd88c584922860231840a90fb623) ) - ROM_LOAD( "mxo-cg2174.u80", 0x18000, 0x8000, CRC(14f9480c) SHA1(59323f9fc5995277aea86d088893b6eb95b4e89b) ) + ROM_LOAD( "mro-cg2xxx.u77", 0x00000, 0x8000, BAD_DUMP CRC(26abb9df) SHA1(0721accc3cb65f00dc979231497edfff0b1faf80) ) /* This set requires an unknown CG graphics set for the correct banners on the MENU page */ + ROM_LOAD( "mgo-cg2xxx.u78", 0x08000, 0x8000, BAD_DUMP CRC(409fd5f6) SHA1(fc4d5627fcc8b891939d6237851c585739d5e0b0) ) /* Most likely CG2227, CG2229 or CG2239 */ + ROM_LOAD( "mbo-cg2xxx.u79", 0x10000, 0x8000, BAD_DUMP CRC(fe48d88e) SHA1(d9a3057a6af087e6d6014a2f80b3f022090970f4) ) + ROM_LOAD( "mxo-cg2xxx.u80", 0x18000, 0x8000, BAD_DUMP CRC(e14bb037) SHA1(5b9c3627e9d29f2140c4bc02c29b319d251abb9f) ) /* Use these modified CG2174 set until correct graphics roms are dumped */ ROM_REGION( 0x200, "proms", 0 ) ROM_LOAD( "capx2174.u43", 0x0000, 0x0200, CRC(50bdad55) SHA1(958d463c7effb3457c1f9c44c9b7822339c04e8b) ) @@ -14427,6 +14438,7 @@ GAMEL(1996, peps0090, 0, peplus, peplus_slots, peplus_state, peplus, GAMEL(1996, peps0092, peps0047, peplus, peplus_slots, peplus_state, peplus, ROT0, "IGT - International Game Technology", "Player's Edge Plus (PS0092) Wild Cherry Slots", 0, layout_pe_slots ) GAMEL(1996, peps0206, peps0021, peplus, peplus_slots, peplus_state, peplus, ROT0, "IGT - International Game Technology", "Player's Edge Plus (PS0206) Red White & Blue Slots", 0, layout_pe_slots ) GAMEL(1996, peps0207, peps0021, peplus, peplus_slots, peplus_state, peplus, ROT0, "IGT - International Game Technology", "Player's Edge Plus (PS0207) Red White & Blue Slots", 0, layout_pe_slots ) +GAMEL(1996, peps0239, 0, peplus, peplus_slots, peplus_state, peplus, ROT0, "IGT - International Game Technology", "Player's Edge Plus (PS0239) Jackpot Jewels Slots", 0, layout_pe_slots ) GAMEL(1996, peps0296, 0, peplus, peplus_slots, peplus_state, peplus, ROT0, "IGT - International Game Technology", "Player's Edge Plus (PS0296) Haywire Slots", 0, layout_pe_slots ) GAMEL(1996, peps0298, peps0042, peplus, peplus_slots, peplus_state, peplus, ROT0, "IGT - International Game Technology", "Player's Edge Plus (PS0298) Double Diamond Slots", 0, layout_pe_slots ) GAMEL(1996, peps0308, 0, peplus, peplus_slots, peplus_state, peplus, ROT0, "IGT - International Game Technology", "Player's Edge Plus (PS0308) Double Jackpot Slots", 0, layout_pe_slots ) diff --git a/src/mame/drivers/perq.cpp b/src/mame/drivers/perq.cpp index 2ba2d57a9c6..650b4990410 100644 --- a/src/mame/drivers/perq.cpp +++ b/src/mame/drivers/perq.cpp @@ -12,26 +12,25 @@ ROMS came from PERQemu by Josh Dersch. ************************************************************************************************************************************/ #include "emu.h" -//#include "cpu/mcs51/mcs51.h" class perq_state : public driver_device { public: perq_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) -// , maincpu(*this, "maincpu") +// , m_maincpu(*this, "maincpu") { } -protected: -// required_device<i80c52_device> maincpu; +private: +// required_device<cpu_device> m_maincpu; }; +//static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, perq_state ) +//ADDRESS_MAP_END + static INPUT_PORTS_START( perq ) INPUT_PORTS_END -//static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, perq_state ) -//ADDRESS_MAP_END - static MACHINE_CONFIG_START( perq ) MACHINE_CONFIG_END diff --git a/src/mame/drivers/pgm.cpp b/src/mame/drivers/pgm.cpp index e44ee17d4ee..c6b8cd018c1 100644 --- a/src/mame/drivers/pgm.cpp +++ b/src/mame/drivers/pgm.cpp @@ -67,29 +67,29 @@ game region code.. ASIC 3: state based device? see - machine/pgmprot.c + machine/pgmprot_orlegend.cpp ASIC 25 + ASIC 12 state based device + rom overlays see - machine/pgmprot5.c + machine/pgmprot_igs025_igs012.cpp ASIC 25 + ASIC 22 state based device + encrypted DMA device see - machine/pgmprot4.c + machine/pgmprot_igs025_igs022.cpp ASIC 25 + ASIC 28 state based device + encrypted DMA device? see - machine/pgmprot6.c + machine/pgmprot_igs025_igs028.cpp ASIC 027A(55857F/55857G): ARM based CPUs with internal ROM see - machine/pgmprot1.c - machine/pgmprot2.c - machine/pgmprot3.c + machine/pgmprot_igs027a_type1.cpp + machine/pgmprot_igs027a_type2.cpp + machine/pgmprot_igs027a_type3.cpp there are probably more... @@ -3224,6 +3224,43 @@ ROM_START( martmastc102 ) ROM_LOAD( "m1001.u7", 0xc00000, 0x400000, CRC(662d2d48) SHA1(2fcc3099d9c04456cae3b13035fb28eaf709e7d8) ) ROM_END +/* +Only the ROMs at U9 and U10 were dumped. + +U9 and U10 are not standard EPROMs, instead they are 27C322 adapter boards with an SMD OKI 27C3202 TSOP. +*/ + +ROM_START( martmasttw ) + ROM_REGION( 0x600000, "maincpu", 0 ) /* 68000 Code */ + PGM_68K_BIOS + ROM_LOAD16_WORD_SWAP( "mm_v102_u9.bin", 0x100000, 0x400000, CRC(7eb41ed4) SHA1(7df7789db8f9110fe747f41e193b4a28096018e7) ) + + ROM_REGION( 0x4000, "prot", 0 ) /* ARM protection ASIC - internal rom */ + ROM_LOAD( "martial_masters_v101_tw.asic", 0x000000, 0x04000, NO_DUMP ) + + ROM_REGION32_LE( 0x400000, "user1", 0 ) /* Protection Data (encrypted external ARM data) */ + ROM_LOAD( "mm_v101_u10.bin", 0x000000, 0x400000, CRC(917beb91) SHA1(0d867d8382518197ac98522bfc69063042db9890) ) // double size wrt to other sets + + ROM_REGION( 0xc00000, "tiles", 0 ) /* 8x8 Text Tiles + 32x32 BG Tiles */ + PGM_VIDEO_BIOS + ROM_LOAD( "t1000.u3", 0x180000, 0x800000, CRC(bbf879b5) SHA1(bd9a6aea34ad4001e89e62ff4b7a2292eb833c00) ) + + ROM_REGION( 0x2800000, "sprcol", 0 ) /* Sprite Colour Data */ + ROM_LOAD( "a1000.u3", 0x0000000, 0x0800000, CRC(43577ac8) SHA1(6eea8b455985d5bac74dcc9943cdc3c0902de6cc) ) + ROM_LOAD( "a1001.u4", 0x0800000, 0x0800000, CRC(fe7a476f) SHA1(a8c7f1f0dd3e53141aed6d927eb88a3ceebb81e4) ) + ROM_LOAD( "a1002.u6", 0x1000000, 0x0800000, CRC(62e33d38) SHA1(96163d583e25073594f8413ce263e56b66bd69a1) ) + ROM_LOAD( "a1003.u8", 0x1800000, 0x0800000, CRC(b2c4945a) SHA1(7b18287a2db56db3651cfd4deb607af53522fefd) ) + ROM_LOAD( "a1004.u10", 0x2000000, 0x0400000, CRC(9fd3f5fd) SHA1(057531f91062be51589c6cf8f4170089b9be6380) ) + + ROM_REGION( 0x1000000, "sprmask", 0 ) /* Sprite Masks + Colour Indexes */ + ROM_LOAD( "b1000.u9", 0x0000000, 0x0800000, CRC(c5961f6f) SHA1(a68060b10edbd084cbde79d2ed1c9084777beb10) ) + ROM_LOAD( "b1001.u11", 0x0800000, 0x0800000, CRC(0b7e1c06) SHA1(545e15e0087f8621d593fecd8b4013f7ca311686) ) + + ROM_REGION( 0x1000000, "ics", 0 ) /* Samples - (8 bit mono 11025Hz) - */ + PGM_AUDIO_BIOS + ROM_LOAD( "m1000.u5", 0x400000, 0x800000, CRC(ed407ae8) SHA1(a6e9c09b39c13e8fb7fbc89fa9f823cbeb66e901) ) + ROM_LOAD( "m1001.u7", 0xc00000, 0x400000, CRC(662d2d48) SHA1(2fcc3099d9c04456cae3b13035fb28eaf709e7d8) ) +ROM_END /* @@ -4660,11 +4697,6 @@ GAME( 1999, kovsh100, kovsh, pgm_arm_type1, kovsh, pgm_arm_type1_sta // nasty modern asian bootleg of Knights of Valour Super Heroes with characters ripped from SNK's The King of Fighters series! GAME( 1999, kovqhsgs, kovsh, pgm_arm_type1, kovsh, pgm_arm_type1_state, kovqhsgs, ROT0, "bootleg", "Knights of Valour: Quan Huang San Guo Special / Sangoku Senki: Quan Huang San Guo Special (ver. 303CN)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) - - - - - // region provided by internal ARM rom GAME( 2000, kov2, pgm, pgm_arm_type2, kov2, pgm_arm_type2_state, kov2, ROT0, "IGS", "Knights of Valour 2 / Sangoku Senki 2 (ver. 107, 102, 100HK)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // 05/10/01 14:24:08 V107 (Ext. Arm V102, Int. Arm V100HK) GAME( 2000, kov2106, kov2, pgm_arm_type2, kov2, pgm_arm_type2_state, kov2, ROT0, "IGS", "Knights of Valour 2 / Sangoku Senki 2 (ver. 106, 102, 100HK)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // 02/27/01 13:26:46 V106 (Ext. Arm V102, Int. Arm V100HK) @@ -4683,6 +4715,7 @@ GAME( 2001, martmast, pgm, pgm_arm_type2, martmast, pgm_arm_type2_s GAME( 2001, martmastc, martmast, pgm_arm_type2, martmast, pgm_arm_type2_state, martmast, ROT0, "IGS", "Martial Masters (ver. 104, 102, 101CN)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // 68k V104, Ext Arm 102, Int Arm 101CN GAME( 2001, martmastc103, martmast, pgm_arm_type2, martmast, pgm_arm_type2_state, martmast, ROT0, "IGS", "Martial Masters (ver. 103, 102, 101CN)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // 68k V103, Ext Arm 102, Int Arm 101CN (actually 102 CN on the PCB, needs to be dumped) GAME( 2001, martmastc102, martmast, pgm_arm_type2, martmast, pgm_arm_type2_state, martmast, ROT0, "IGS", "Martial Masters (ver. 102, 101, 101CN)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // 68k V102, Ext Arm 101, Int Arm 101CN +GAME( 2001, martmasttw, martmast, pgm_arm_type2, martmast, pgm_arm_type2_state, martmast, ROT0, "IGS", "Martial Masters (ver. 102, 101, 101TW)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) // 68k V102, Ext Arm 101, Int Arm 101TW // region provided by internal ARM rom GAME( 2001, ddp2, pgm, pgm_arm_type2, pgm, pgm_arm_type2_state, ddp2, ROT270, "IGS", "DoDonPachi II - Bee Storm (World, ver. 102)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/pgm2.cpp b/src/mame/drivers/pgm2.cpp index fc6b8011e3a..d28f0fac442 100644 --- a/src/mame/drivers/pgm2.cpp +++ b/src/mame/drivers/pgm2.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:David Haywood, ??? +// copyright-holders:David Haywood, Xing Xing, Andreas Naive /* PGM 2 hardware. Motherboard is bare bones stuff, and does not contain any ROMs. @@ -7,13 +7,6 @@ Decryption should be correct in most cases. The ARM appears to be ARMv5T, probably an ARM9. - We need to determine where VRAM etc. map in order to attempt tests on the PCBs. - - We will also need to try to attack the internal ROM, as there are many many calls made into it. - Chances are it'll be possible to get it to copy itself out, or black-box the behavior. - All calls to the IROM are done through small shims, so it should also be possible to hack around - the IROM if we can't get the dump out. - PGM2 Motherboard Components: IS61LV25616AL(SRAM) @@ -33,10 +26,10 @@ Single PCB versions of some of the titles were also available Only 5 Games were released for this platform, 3 of which are just updates / re-releases of older titles! - The platform has since been superseded by PGM3 (HD system uses flash cards etc.) + The platform has since been superseded by PGM3, see pgm3.cpp Oriental Legend 2 - The King of Fighters '98 - Ultimate Match - Hero (NOT DUMPED) + The King of Fighters '98 - Ultimate Match - Hero Knights of Valour 2 New Legend Dodonpachi Daioujou Tamashii Knights of Valour 3 @@ -46,66 +39,210 @@ Jigsaw World Arena Puzzle of Ocha / Ochainu No Pazuru + + ToDo (emulation issues): + + Support remaining games (need IGS036 dumps) + Identify which regions each game was released in and either dump alt. internal ROMs for each region, or + create them until that can be done. + RTC (integrated into the CPU with the SRAM?) + Memory Card system (there's an MCU on the motherboard that will need simulating or dumping somehow) + Verify Sprite Zoom (check exactly which pixels are doubled / missed on hardware for flipped , non-flipped cases etc.) + Simplify IGS036 encryption based on tables in internal roms + Fix ARM? bug that means Oriental Legend 2 needs a patch (might also be that it needs the card reader, and is running a + codepath that would not exist in a real environment at the moment) + Fix Save States (is this a driver problem or an ARM core problem, they don't work unless you get through the startup tests) + */ -#include "emu.h" -#include "cpu/arm7/arm7.h" -#include "cpu/arm7/arm7core.h" -#include "sound/ymz770.h" -#include "machine/igs036crypt.h" -#include "screen.h" -#include "speaker.h" +#include "includes/pgm2.h" -class pgm2_state : public driver_device +// checked on startup, or doesn't boot +READ32_MEMBER(pgm2_state::unk_startup_r) { -public: - pgm2_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu") { } - - DECLARE_DRIVER_INIT(kov2nl); - DECLARE_DRIVER_INIT(orleg2); - DECLARE_DRIVER_INIT(ddpdojh); - DECLARE_DRIVER_INIT(kov3); - DECLARE_DRIVER_INIT(kov3_104); - DECLARE_DRIVER_INIT(kov3_102); - DECLARE_DRIVER_INIT(kov3_100); - - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - uint32_t screen_update_pgm2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - DECLARE_WRITE_LINE_MEMBER(screen_vblank_pgm2); - required_device<cpu_device> m_maincpu; -private: - void pgm_create_dummy_internal_arm_region(); - void decrypt_kov3_module(uint32_t addrxor, uint16_t dataxor); -}; + logerror("%s: unk_startup_r\n", machine().describe_context().c_str()); + return 0x00000180; +} + +READ32_MEMBER(pgm2_state::rtc_r) +{ + // write to FFFFFD20 if bit 18 set (0x40000) probably reset this RTC timer + // TODO: somehow hook here current time/date, which is a bit complicated because value is relative, later to it added "base time" stored in SRAM + return machine().time().seconds(); +} + +INTERRUPT_GEN_MEMBER(pgm2_state::igs_interrupt) +{ + m_arm_aic->set_irq(0x47); +} + +TIMER_DEVICE_CALLBACK_MEMBER(pgm2_state::igs_interrupt2) +{ + int scanline = param; + + if(scanline == 0) + m_arm_aic->set_irq(0x46); +} static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state ) AM_RANGE(0x00000000, 0x00003fff) AM_ROM //AM_REGION("user1", 0x00000) // internal ROM - // these might be swapped - AM_RANGE(0x10000000, 0x107fffff) AM_ROM AM_MIRROR(0x0f800000) AM_REGION("user1", 0) // external ROM - AM_RANGE(0x20000000, 0x2007ffff) AM_RAM // main SRAM? - // This doesn't exist, it's just necessary because our stub IPL doesn't set SP - AM_RANGE(0xfff00000, 0xffffffff) AM_RAM + AM_RANGE(0x02000000, 0x0200ffff) AM_RAM AM_SHARE("sram") // 'battery ram' (in CPU?) + + // could be the card reader, looks a bit like a standard IGS MCU comms protocol going on here + AM_RANGE(0x03600000, 0x03600003) AM_WRITENOP + AM_RANGE(0x03620000, 0x03620003) AM_WRITENOP + AM_RANGE(0x03640000, 0x03640003) AM_WRITENOP + AM_RANGE(0x03660000, 0x03660003) AM_READ_PORT("UNK1") + AM_RANGE(0x03680000, 0x03680003) AM_READ_PORT("UNK2") + AM_RANGE(0x036a0000, 0x036a0003) AM_WRITENOP + + AM_RANGE(0x03900000, 0x03900003) AM_READ_PORT("INPUTS0") + AM_RANGE(0x03a00000, 0x03a00003) AM_READ_PORT("INPUTS1") + + AM_RANGE(0x10000000, 0x10ffffff) AM_ROM AM_REGION("user1", 0) // external ROM + AM_RANGE(0x20000000, 0x2007ffff) AM_RAM AM_SHARE("mainram") + + AM_RANGE(0x30000000, 0x30001fff) AM_RAM AM_SHARE("sp_videoram") // spriteram ('move' ram in test mode) + + AM_RANGE(0x30020000, 0x30021fff) AM_RAM_WRITE(bg_videoram_w) AM_SHARE("bg_videoram") + AM_RANGE(0x30040000, 0x30045fff) AM_RAM_WRITE(fg_videoram_w) AM_SHARE("fg_videoram") + + AM_RANGE(0x30060000, 0x30063fff) AM_RAM_DEVWRITE("sp_palette", palette_device, write) AM_SHARE("sp_palette") + + AM_RANGE(0x30080000, 0x30081fff) AM_RAM_DEVWRITE("bg_palette", palette_device, write) AM_SHARE("bg_palette") + + AM_RANGE(0x300a0000, 0x300a07ff) AM_RAM_DEVWRITE("tx_palette", palette_device, write) AM_SHARE("tx_palette") + + AM_RANGE(0x300c0000, 0x300c01ff) AM_RAM AM_SHARE("sp_zoom") // sprite zoom table - it uploads the same data 4x, maybe xshrink,xgrow,yshrink,ygrow or just redundant mirrors + + /* linescroll ram - it clears to 0x3bf on startup which is enough bytes for 240 lines if each rowscroll value was 8 bytes, but each row is 4, + so only half of this is used? or tx can do it too (unlikely, as orl2 writes 256 lines of data) maybe just bad mem check bounds on orleg2. + It reports pass even if it fails the first byte but if the first byte passes it attempts to test 0x10000 bytes, which is far too big so + what is the real size? */ + AM_RANGE(0x300e0000, 0x300e03ff) AM_RAM AM_SHARE("lineram") AM_MIRROR(0x000fc00) + + AM_RANGE(0x30100000, 0x301000ff) AM_RAM // unknown mask 00ff00ff, seems to be banked with 0x30120030 too? + + AM_RANGE(0x30120000, 0x30120003) AM_RAM AM_SHARE("bgscroll") // scroll + // there are other 0x301200xx regs + + AM_RANGE(0x40000000, 0x40000003) AM_DEVREADWRITE8("ymz774", ymz774_device, read, write, 0xffffffff) + + // internal to IGS036? - various other writes down here on startup too - could be other standard ATMEL peripherals like the ARM_AIC mixed with custom bits + AM_RANGE(0xffffec00, 0xffffec5f) AM_RAM + AM_RANGE(0xfffffc00, 0xfffffcff) AM_RAM // confirmed as encryption table for main program rom (see code at 3950) + + AM_RANGE(0xfffff000, 0xfffff14b) AM_DEVICE("arm_aic", arm_aic_device, regs_map) + + AM_RANGE(0xfffff430, 0xfffff433) AM_WRITENOP // often + AM_RANGE(0xfffff434, 0xfffff437) AM_WRITENOP // often + + AM_RANGE(0xfffffd28, 0xfffffd2b) AM_READ(rtc_r) + +// AM_RANGE(0xfffffa08, 0xfffffa0b) AM_WRITE(table_done_w) // after uploading encryption? table might actually send it or enable external ROM? + AM_RANGE(0xfffffa0c, 0xfffffa0f) AM_READ(unk_startup_r) ADDRESS_MAP_END static INPUT_PORTS_START( pgm2 ) +// probably not inputs + PORT_START("UNK1") + PORT_BIT( 0xffffffff, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + +// probably not inputs + PORT_START("UNK2") + PORT_BIT( 0xffffffff, IP_ACTIVE_HIGH, IPT_UNKNOWN ) + + PORT_START("INPUTS0") + PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) + PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) + PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) + PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) + PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) + PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) + PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) + PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) + PORT_BIT( 0x00000100, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x00000200, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x00000400, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) + PORT_BIT( 0x00000800, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) + PORT_BIT( 0x00001000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) + PORT_BIT( 0x00002000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) + PORT_BIT( 0x00004000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x00008000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) + PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) + PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(3) + PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(3) + PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3) + PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3) + PORT_BIT( 0x01000000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) + PORT_BIT( 0x02000000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) + PORT_BIT( 0x04000000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) + PORT_BIT( 0x08000000, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(3) + PORT_BIT( 0x10000000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x20000000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x40000000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80000000, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("INPUTS1") + PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(4) + PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(4) + PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(4) + PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(4) + PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4) + PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4) + PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4) + PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(4) + PORT_BIT( 0x00000100, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x00000200, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x00000400, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x00000800, IP_ACTIVE_LOW, IPT_START2 ) + PORT_BIT( 0x00001000, IP_ACTIVE_LOW, IPT_START3 ) + PORT_BIT( 0x00002000, IP_ACTIVE_LOW, IPT_START4 ) + PORT_BIT( 0x00004000, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x00008000, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_COIN3 ) + PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_COIN4 ) + PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_SERVICE1 ) // test key p1+p2 + PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_SERVICE2 ) // test key p3+p4 + PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_SERVICE3 ) // service key p1+p2 + PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_SERVICE4 ) // service key p3+p4 + PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_SERVICE( 0x01000000, IP_ACTIVE_LOW ) PORT_DIPLOCATION("SW1:1") + PORT_DIPNAME( 0x02000000, 0x02000000, "Music" ) PORT_DIPLOCATION("SW1:2") + PORT_DIPSETTING( 0x00000000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x02000000, DEF_STR( On ) ) + PORT_DIPNAME( 0x04000000, 0x04000000, "Voice" ) PORT_DIPLOCATION("SW1:3") + PORT_DIPSETTING( 0x00000000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x04000000, DEF_STR( On ) ) + PORT_DIPNAME( 0x08000000, 0x08000000, "Free" ) PORT_DIPLOCATION("SW1:4") + PORT_DIPSETTING( 0x08000000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00000000, DEF_STR( On ) ) + PORT_DIPNAME( 0x10000000, 0x10000000, "Stop" ) PORT_DIPLOCATION("SW1:5") + PORT_DIPSETTING( 0x10000000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00000000, DEF_STR( On ) ) + PORT_DIPNAME( 0x20000000, 0x20000000, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW1:6") + PORT_DIPSETTING( 0x20000000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00000000, DEF_STR( On ) ) + PORT_DIPNAME( 0x40000000, 0x40000000, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW1:7") + PORT_DIPSETTING( 0x40000000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00000000, DEF_STR( On ) ) + PORT_DIPNAME( 0x80000000, 0x80000000, DEF_STR( Unused ) ) PORT_DIPLOCATION("SW1:8") + PORT_DIPSETTING( 0x80000000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00000000, DEF_STR( On ) ) INPUT_PORTS_END -uint32_t pgm2_state::screen_update_pgm2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - return 0; -} - -WRITE_LINE_MEMBER(pgm2_state::screen_vblank_pgm2) -{ -} -void pgm2_state::video_start() +WRITE_LINE_MEMBER(pgm2_state::irq) { +// printf("irq\n"); + if (state == ASSERT_LINE) m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); + else m_maincpu->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE); } void pgm2_state::machine_start() @@ -127,343 +264,224 @@ static const gfx_layout tiles8x8_layout = 32*8 }; -/* slightly odd decode, and ends up with multiple letters in a single 32x32 tile, can probably specify corners, or needs an address line swap before decode */ -/* actually 7bpp? roms report fixed bits, but should be good dumps */ static const gfx_layout tiles32x32x8_layout = { 32,32, RGN_FRAC(1,1), - 8, - { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 0*8, 2*8, 1*8, 3*8, 4*8, 6*8, 5*8, 7*8, 8*8, 10*8, 9*8, 11*8, 12*8, 14*8, 13*8, 15*8, - 16*8, 18*8, 17*8, 19*8, 20*8, 22*8, 21*8, 23*8, 24*8, 26*8, 25*8, 27*8, 28*8, 30*8, 29*8, 31*8 }, + 7, + { 1, 2, 3, 4, 5, 6, 7 }, + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8, + 16*8, 17*8, 18*8, 19*8, 20*8, 21*8, 22*8, 23*8, 24*8, 25*8, 26*8, 27*8, 28*8, 29*8, 30*8, 31*8 }, { 0*256, 1*256, 2*256, 3*256, 4*256, 5*256, 6*256, 7*256, 8*256, 9*256, 10*256, 11*256, 12*256, 13*256, 14*256, 15*256, 16*256, 17*256, 18*256, 19*256, 20*256, 21*256, 22*256, 23*256, 24*256, 25*256, 26*256, 27*256, 28*256, 29*256, 30*256, 31*256 }, 256*32 }; -#if 0 -/* sprites aren't tile based, this is variable width 1bpp data, colour data is almost certainly in sprites b */ -/* there don't seem to be any indexes into the colour data, probably provided by the program, or the colour data references the bitmaps (reverse of PGM) */ -static const gfx_layout tiles32x8x1_layout = -{ - 32,8, - RGN_FRAC(1,1), - 1, - { 0 }, - { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 }, - { 0*32,1*32,2*32,3*32,4*32,5*32,6*32,7*32 }, - 8*32 -}; -#endif - - - -static GFXDECODE_START( pgm2 ) - GFXDECODE_ENTRY( "tiles", 0, tiles8x8_layout, 0, 16 ) - GFXDECODE_ENTRY( "bgtile", 0, tiles32x32x8_layout, 0, 16 ) -#if 0 - // not tile based - GFXDECODE_ENTRY( "spritesa", 0, tiles32x8x1_layout, 0, 16 ) - GFXDECODE_ENTRY( "spritesb", 0, tiles32x8x1_layout, 0, 16 ) -#endif +static GFXDECODE_START( pgm2_tx ) + GFXDECODE_ENTRY( "tiles", 0, tiles8x8_layout, 0, 0x800/4/0x10 ) GFXDECODE_END - - -void pgm2_state::pgm_create_dummy_internal_arm_region() -{ - uint16_t *temp16 = (uint16_t *)memregion("maincpu")->base(); - int i; - for (i = 0;i < 0x4000 / 2;i += 2) - { - temp16[i] = 0xFFFE; - temp16[i + 1] = 0xEAFF; - - } - int base = 0; - int addr = 0x10000000; - - // just do a jump to 0x10000000 because that looks possibly correct. - // we probably should be setting up stack and other things too, but we - // don't really know that info yet. - - temp16[(base) / 2] = 0x0004; base += 2; - temp16[(base) / 2] = 0xe59f; base += 2; - temp16[(base) / 2] = 0x0000; base += 2; - temp16[(base) / 2] = 0xe590; base += 2; - temp16[(base) / 2] = 0xff10; base += 2; - temp16[(base) / 2] = 0xe12f; base += 2; - temp16[(base) / 2] = 0x0010; base += 2; - temp16[(base) / 2] = 0x0000; base += 2; - - temp16[(base) / 2] = addr & 0xffff; base += 2; - temp16[(base) / 2] = (addr >> 16) & 0xffff; base += 2; - - /* debug code to find jumps to the internal ROM and put jumps back to where we came from in the internal ROM space */ - - uint16_t *gamerom = (uint16_t *)memregion("user1")->base(); - int gameromlen = memregion("user1")->bytes() / 2; - - for (int i = 0;i < gameromlen - 3;i++) - { - uint16_t val1 = gamerom[i]; - uint16_t val2 = gamerom[i + 1]; - - if ((val1 == 0xF004) && (val2 == 0xe51f)) - { - uint16_t val3 = gamerom[i + 2]; - uint16_t val4 = gamerom[i + 3]; - uint32_t jump = (val4 << 16) | val3; - - if (jump < 0x10000000) // jumps to internal ROM - { - logerror("internal ROM jump found at %08x (jump is %08x)", i * 2, jump); - if (jump & 1) - { - logerror(" (To THUMB)"); - jump &= ~1; - // put a BX R14 there - temp16[(jump / 2)] = 0x4770; - } - else - { - // put a BX R14 there - temp16[(jump / 2)] = 0xFF1E; - temp16[(jump / 2) + 1] = 0xE12F; - } - logerror("\n"); - } - else if (jump < 0x20000000) // jumps to RAM - { - logerror("RAM jump found at %08x (jump is %08x)", i * 2, jump); - if (jump & 1) logerror(" (To THUMB)"); - logerror("\n"); - } - else // anything else is to ROM - { - logerror("ROM jump found at %08x (jump is %08x)", i * 2, jump); - if (jump & 1) logerror(" (To THUMB)"); - logerror("\n"); - } - - } - } -} - - +static GFXDECODE_START( pgm2_bg ) + GFXDECODE_ENTRY( "bgtile", 0, tiles32x32x8_layout, 0, 0x2000/4/0x80 ) +GFXDECODE_END static MACHINE_CONFIG_START( pgm2 ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", ARM9, 20000000) // ?? ARM baesd CPU, has internal ROM. + MCFG_CPU_ADD("maincpu", IGS036, 100000000) // ?? ARM based CPU, has internal ROM. MCFG_CPU_PROGRAM_MAP(pgm2_map) + MCFG_CPU_VBLANK_INT_DRIVER("screen", pgm2_state, igs_interrupt) + MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", pgm2_state, igs_interrupt2, "screen", 0, 1) + MCFG_ARM_AIC_ADD("arm_aic") + MCFG_IRQ_LINE_CB(WRITELINE(pgm2_state, irq)) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MCFG_SCREEN_SIZE(64*8, 64*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 56*8-1, 0*8, 28*8-1) + MCFG_SCREEN_SIZE(64*8, 32*8) + MCFG_SCREEN_VISIBLE_AREA(0, 448-1, 0, 224-1) MCFG_SCREEN_UPDATE_DRIVER(pgm2_state, screen_update_pgm2) MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(pgm2_state, screen_vblank_pgm2)) - MCFG_SCREEN_PALETTE("palette") - MCFG_GFXDECODE_ADD("gfxdecode", "palette", pgm2) - MCFG_PALETTE_ADD("palette", 0x1000) + MCFG_GFXDECODE_ADD("gfxdecode2", "tx_palette", pgm2_tx) + + MCFG_GFXDECODE_ADD("gfxdecode3", "bg_palette", pgm2_bg) + + MCFG_PALETTE_ADD("sp_palette", 0x4000/4) // sprites + MCFG_PALETTE_FORMAT(XRGB) + + MCFG_PALETTE_ADD("tx_palette", 0x800/4) // text + MCFG_PALETTE_FORMAT(XRGB) + + MCFG_PALETTE_ADD("bg_palette", 0x2000/4) // bg + MCFG_PALETTE_FORMAT(XRGB) + MCFG_NVRAM_ADD_0FILL("sram") MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MCFG_YMZ770_ADD("ymz770", 16384000) // Actually a YMZ774 on-board + MCFG_YMZ774_ADD("ymz774", 16384000) // is clock correct ? MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MACHINE_CONFIG_END -ROM_START( orleg2 ) - ROM_REGION( 0x04000, "maincpu", 0 ) - ROM_LOAD( "xyj2_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) - - ROM_REGION( 0x800000, "user1", 0 ) +/* using macros for the video / sound roms because the locations never change between sets, and + we're going to have a LOT of clones to cover all the internal rom regions and external rom revision + combinations, so it keeps things readable */ + +// Oriental Legend 2 + +#define ORLEG2_VIDEO_SOUND_ROMS \ + ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ + ROM_LOAD( "ig-a_text.u4", 0x00000000, 0x0200000, CRC(fa444c32) SHA1(31e5e3efa92d52bf9ab97a0ece51e3b77f52ce8a) ) \ + \ + ROM_REGION( 0x1000000, "bgtile", 0 ) \ + ROM_LOAD32_WORD( "ig-a_bgl.u35", 0x00000000, 0x0800000, CRC(083a8315) SHA1(0dba25e132fbb12faa59ced648c27b881dc73478) ) \ + ROM_LOAD32_WORD( "ig-a_bgh.u36", 0x00000002, 0x0800000, CRC(e197221d) SHA1(5574b1e3da4b202db725be906dd868edc2fd4634) ) \ + \ + ROM_REGION( 0x2000000, "sprites_mask", 0 ) /* 1bpp sprite mask data (packed) */ \ + ROM_LOAD32_WORD( "ig-a_bml.u12", 0x00000000, 0x1000000, CRC(113a331c) SHA1(ee6b31bb2b052cc8799573de0d2f0a83f0ab4f6a) ) \ + ROM_LOAD32_WORD( "ig-a_bmh.u16", 0x00000002, 0x1000000, CRC(fbf411c8) SHA1(5089b5cc9bbf6496ef1367c6255e63e9ab895117) ) \ + \ + ROM_REGION( 0x4000000, "sprites_colour", 0 ) /* sprite colour data (6bpp data, 2 bits unused except for 4 bytes that are randomly 0xff - check dump?) */ \ + ROM_LOAD32_WORD( "ig-a_cgl.u18", 0x00000000, 0x2000000, BAD_DUMP CRC(43501fa6) SHA1(58ccce6d393964b771fec3f5c583e3ede57482a3) ) \ + ROM_LOAD32_WORD( "ig-a_cgh.u26", 0x00000002, 0x2000000, BAD_DUMP CRC(7051d020) SHA1(3d9b24c6fda4c9699bb9f00742e0888059b623e1) ) \ + \ + ROM_REGION( 0x1000000, "ymz774", ROMREGION_ERASEFF ) /* ymz770 */ \ + ROM_LOAD16_WORD_SWAP( "ig-a_sp.u2", 0x00000000, 0x1000000, CRC(8250688c) SHA1(d2488477afc528aeee96826065deba2bce4f0a7d) ) \ + \ + ROM_REGION( 0x10000, "sram", 0 ) \ + ROM_LOAD( "xyj2_nvram", 0x00000000, 0x10000, CRC(ccccc71c) SHA1(585b5ccbf89dd28d8532da785d7c8af12f31c6d6) ) + +#define ORLEG2_PROGRAM_104 \ + ROM_REGION( 0x1000000, "user1", 0 ) \ ROM_LOAD( "xyj2_v104cn.u7", 0x00000000, 0x0800000, CRC(7c24a4f5) SHA1(3cd9f9264ef2aad0869afdf096e88eb8d74b2570) ) - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "ig-a_text.u4", 0x00000000, 0x0200000, CRC(fa444c32) SHA1(31e5e3efa92d52bf9ab97a0ece51e3b77f52ce8a) ) - - ROM_REGION( 0x1000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "ig-a_bgl.u35", 0x00000000, 0x0800000, CRC(083a8315) SHA1(0dba25e132fbb12faa59ced648c27b881dc73478) ) - ROM_LOAD32_WORD( "ig-a_bgh.u36", 0x00000002, 0x0800000, CRC(e197221d) SHA1(5574b1e3da4b202db725be906dd868edc2fd4634) ) - - ROM_REGION( 0x2000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "ig-a_bml.u12", 0x00000000, 0x1000000, CRC(113a331c) SHA1(ee6b31bb2b052cc8799573de0d2f0a83f0ab4f6a) ) - ROM_LOAD32_WORD( "ig-a_bmh.u16", 0x00000002, 0x1000000, CRC(fbf411c8) SHA1(5089b5cc9bbf6496ef1367c6255e63e9ab895117) ) - - ROM_REGION( 0x4000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "ig-a_cgl.u18", 0x00000000, 0x2000000, CRC(43501fa6) SHA1(58ccce6d393964b771fec3f5c583e3ede57482a3) ) - ROM_LOAD32_WORD( "ig-a_cgh.u26", 0x00000002, 0x2000000, CRC(7051d020) SHA1(3d9b24c6fda4c9699bb9f00742e0888059b623e1) ) - - ROM_REGION( 0x1000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "ig-a_sp.u2", 0x00000000, 0x1000000, CRC(8250688c) SHA1(d2488477afc528aeee96826065deba2bce4f0a7d) ) -ROM_END - -ROM_START( orleg2o ) - ROM_REGION( 0x04000, "maincpu", 0 ) - ROM_LOAD( "xyj2_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) - - ROM_REGION( 0x800000, "user1", 0 ) +#define ORLEG2_PROGRAM_103 \ + ROM_REGION( 0x1000000, "user1", 0 ) \ ROM_LOAD( "xyj2_v103cn.u7", 0x000000, 0x800000, CRC(21c1fae8) SHA1(36eeb7a5e8dc8ee7c834f3ff1173c28cf6c2f1a3) ) - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "ig-a_text.u4", 0x00000000, 0x0200000, CRC(fa444c32) SHA1(31e5e3efa92d52bf9ab97a0ece51e3b77f52ce8a) ) - - ROM_REGION( 0x1000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "ig-a_bgl.u35", 0x00000000, 0x0800000, CRC(083a8315) SHA1(0dba25e132fbb12faa59ced648c27b881dc73478) ) - ROM_LOAD32_WORD( "ig-a_bgh.u36", 0x00000002, 0x0800000, CRC(e197221d) SHA1(5574b1e3da4b202db725be906dd868edc2fd4634) ) +#define ORLEG2_PROGRAM_101 \ + ROM_REGION( 0x1000000, "user1", 0 ) \ + ROM_LOAD( "xyj2_v101cn.u7", 0x000000, 0x800000, CRC(45805b53) SHA1(f2a8399c821b75fadc53e914f6f318707e70787c) ) - ROM_REGION( 0x2000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "ig-a_bml.u12", 0x00000000, 0x1000000, CRC(113a331c) SHA1(ee6b31bb2b052cc8799573de0d2f0a83f0ab4f6a) ) - ROM_LOAD32_WORD( "ig-a_bmh.u16", 0x00000002, 0x1000000, CRC(fbf411c8) SHA1(5089b5cc9bbf6496ef1367c6255e63e9ab895117) ) +#define ORLEG2_INTERNAL_CHINA \ + ROM_REGION( 0x04000, "maincpu", 0 ) \ + /* Offset 3cb8 of the internal rom controls the region, however only China is dumped at the moment. Overseas (English) external ROM is confirmed to match (with FA rom label extensions) but th Internal rom might differ by more than the region byte so needs dumping */ \ + ROM_LOAD( "xyj2_igs036_china.rom", 0x00000000, 0x0004000, CRC(bcce7641) SHA1(c3b5cf6e9f6eae09b6785314777a52b34c3c7657) ) - ROM_REGION( 0x4000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "ig-a_cgl.u18", 0x00000000, 0x2000000, CRC(43501fa6) SHA1(58ccce6d393964b771fec3f5c583e3ede57482a3) ) - ROM_LOAD32_WORD( "ig-a_cgh.u26", 0x00000002, 0x2000000, CRC(7051d020) SHA1(3d9b24c6fda4c9699bb9f00742e0888059b623e1) ) - - ROM_REGION( 0x1000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "ig-a_sp.u2", 0x00000000, 0x1000000, CRC(8250688c) SHA1(d2488477afc528aeee96826065deba2bce4f0a7d) ) +ROM_START( orleg2 ) + ORLEG2_INTERNAL_CHINA + ORLEG2_PROGRAM_104 + ORLEG2_VIDEO_SOUND_ROMS ROM_END -ROM_START( orleg2oa ) - ROM_REGION( 0x04000, "maincpu", 0 ) - ROM_LOAD( "xyj2_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) - - ROM_REGION( 0x800000, "user1", 0 ) - ROM_LOAD( "orleg2_xyj2_v101cn.u7", 0x000000, 0x800000, CRC(45805b53) SHA1(f2a8399c821b75fadc53e914f6f318707e70787c) ) - - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "ig-a_text.u4", 0x00000000, 0x0200000, CRC(fa444c32) SHA1(31e5e3efa92d52bf9ab97a0ece51e3b77f52ce8a) ) - - ROM_REGION( 0x1000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "ig-a_bgl.u35", 0x00000000, 0x0800000, CRC(083a8315) SHA1(0dba25e132fbb12faa59ced648c27b881dc73478) ) - ROM_LOAD32_WORD( "ig-a_bgh.u36", 0x00000002, 0x0800000, CRC(e197221d) SHA1(5574b1e3da4b202db725be906dd868edc2fd4634) ) - - ROM_REGION( 0x2000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "ig-a_bml.u12", 0x00000000, 0x1000000, CRC(113a331c) SHA1(ee6b31bb2b052cc8799573de0d2f0a83f0ab4f6a) ) - ROM_LOAD32_WORD( "ig-a_bmh.u16", 0x00000002, 0x1000000, CRC(fbf411c8) SHA1(5089b5cc9bbf6496ef1367c6255e63e9ab895117) ) - - ROM_REGION( 0x4000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "ig-a_cgl.u18", 0x00000000, 0x2000000, CRC(43501fa6) SHA1(58ccce6d393964b771fec3f5c583e3ede57482a3) ) - ROM_LOAD32_WORD( "ig-a_cgh.u26", 0x00000002, 0x2000000, CRC(7051d020) SHA1(3d9b24c6fda4c9699bb9f00742e0888059b623e1) ) - - ROM_REGION( 0x1000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "ig-a_sp.u2", 0x00000000, 0x1000000, CRC(8250688c) SHA1(d2488477afc528aeee96826065deba2bce4f0a7d) ) +ROM_START( orleg2_103 ) + ORLEG2_INTERNAL_CHINA + ORLEG2_PROGRAM_103 + ORLEG2_VIDEO_SOUND_ROMS ROM_END -ROM_START( kov2nl ) - ROM_REGION( 0x04000, "maincpu", 0 ) - ROM_LOAD( "gsyx_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) - - ROM_REGION( 0x800000, "user1", 0 ) - ROM_LOAD( "gsyx_v302cn.u7", 0x00000000, 0x0800000, CRC(b19cf540) SHA1(25da5804bbfd7ef2cdf5cc5aabaa803d18b98929) ) - - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "ig-a3_text.u4", 0x00000000, 0x0200000, CRC(214530ff) SHA1(4231a02054b0345392a077042b95779fd45d6c22) ) - - ROM_REGION( 0x1000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "ig-a3_bgl.u35", 0x00000000, 0x0800000, CRC(2d46b1f6) SHA1(ea8c805eda6292e86a642e9633d8fee7054d10b1) ) - ROM_LOAD32_WORD( "ig-a3_bgh.u36", 0x00000002, 0x0800000, CRC(df710c36) SHA1(f826c3f496c4f17b46d18af1d8e02cac7b7027ac) ) - - ROM_REGION( 0x2000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "ig-a3_bml.u12", 0x00000000, 0x1000000, CRC(0bf63836) SHA1(b8e4f1951f8074b475b795bd7840c5a375b6f5ef) ) - ROM_LOAD32_WORD( "ig-a3_bmh.u16", 0x00000002, 0x1000000, CRC(4a378542) SHA1(5d06a8a8796285a786ebb690c34610f923ef5570) ) - - ROM_REGION( 0x4000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "ig-a3_cgl.u18", 0x00000000, 0x2000000, CRC(8d923e1f) SHA1(14371cf385dd8857017d3111cd4710f4291b1ae2) ) - ROM_LOAD32_WORD( "ig-a3_cgh.u26", 0x00000002, 0x2000000, CRC(5b6fbf3f) SHA1(d1f52e230b91ee6cde939d7c2b74da7fd6527e73) ) - - ROM_REGION( 0x2000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "ig-a3_sp.u37", 0x00000000, 0x2000000, CRC(45cdf422) SHA1(8005d284bcee73cff37a147fcd1c3e9f039a7203) ) +ROM_START( orleg2_101 ) + ORLEG2_INTERNAL_CHINA + ORLEG2_PROGRAM_101 + ORLEG2_VIDEO_SOUND_ROMS ROM_END -ROM_START( kov2nlo ) - ROM_REGION( 0x04000, "maincpu", 0 ) - ROM_LOAD( "gsyx_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) - - ROM_REGION( 0x800000, "user1", 0 ) - ROM_LOAD( "gsyx_v301cn.u7", 0x000000, 0x800000, CRC(c4595c2c) SHA1(09e379556ef76f81a63664f46d3f1415b315f384) ) - - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "ig-a3_text.u4", 0x00000000, 0x0200000, CRC(214530ff) SHA1(4231a02054b0345392a077042b95779fd45d6c22) ) - - ROM_REGION( 0x1000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "ig-a3_bgl.u35", 0x00000000, 0x0800000, CRC(2d46b1f6) SHA1(ea8c805eda6292e86a642e9633d8fee7054d10b1) ) - ROM_LOAD32_WORD( "ig-a3_bgh.u36", 0x00000002, 0x0800000, CRC(df710c36) SHA1(f826c3f496c4f17b46d18af1d8e02cac7b7027ac) ) - - ROM_REGION( 0x2000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "ig-a3_bml.u12", 0x00000000, 0x1000000, CRC(0bf63836) SHA1(b8e4f1951f8074b475b795bd7840c5a375b6f5ef) ) - ROM_LOAD32_WORD( "ig-a3_bmh.u16", 0x00000002, 0x1000000, CRC(4a378542) SHA1(5d06a8a8796285a786ebb690c34610f923ef5570) ) - - ROM_REGION( 0x4000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "ig-a3_cgl.u18", 0x00000000, 0x2000000, CRC(8d923e1f) SHA1(14371cf385dd8857017d3111cd4710f4291b1ae2) ) - ROM_LOAD32_WORD( "ig-a3_cgh.u26", 0x00000002, 0x2000000, CRC(5b6fbf3f) SHA1(d1f52e230b91ee6cde939d7c2b74da7fd6527e73) ) +// Knights of Valour 2 New Legend + +#define KOV2NL_VIDEO_SOUND_ROMS \ + ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ + ROM_LOAD( "ig-a3_text.u4", 0x00000000, 0x0200000, CRC(214530ff) SHA1(4231a02054b0345392a077042b95779fd45d6c22) ) \ + \ + ROM_REGION( 0x1000000, "bgtile", 0 ) \ + ROM_LOAD32_WORD( "ig-a3_bgl.u35", 0x00000000, 0x0800000, CRC(2d46b1f6) SHA1(ea8c805eda6292e86a642e9633d8fee7054d10b1) ) \ + ROM_LOAD32_WORD( "ig-a3_bgh.u36", 0x00000002, 0x0800000, CRC(df710c36) SHA1(f826c3f496c4f17b46d18af1d8e02cac7b7027ac) ) \ + \ + ROM_REGION( 0x2000000, "sprites_mask", 0 ) /* 1bpp sprite mask data */ \ + ROM_LOAD32_WORD( "ig-a3_bml.u12", 0x00000000, 0x1000000, CRC(0bf63836) SHA1(b8e4f1951f8074b475b795bd7840c5a375b6f5ef) ) \ + ROM_LOAD32_WORD( "ig-a3_bmh.u16", 0x00000002, 0x1000000, CRC(4a378542) SHA1(5d06a8a8796285a786ebb690c34610f923ef5570) ) \ + \ + ROM_REGION( 0x4000000, "sprites_colour", 0 ) /* sprite colour data */ \ + ROM_LOAD32_WORD( "ig-a3_cgl.u18", 0x00000000, 0x2000000, CRC(8d923e1f) SHA1(14371cf385dd8857017d3111cd4710f4291b1ae2) ) \ + ROM_LOAD32_WORD( "ig-a3_cgh.u26", 0x00000002, 0x2000000, CRC(5b6fbf3f) SHA1(d1f52e230b91ee6cde939d7c2b74da7fd6527e73) ) \ + \ + ROM_REGION( 0x2000000, "ymz774", ROMREGION_ERASEFF ) /* ymz770 */ \ + ROM_LOAD16_WORD_SWAP( "ig-a3_sp.u37", 0x00000000, 0x2000000, CRC(45cdf422) SHA1(8005d284bcee73cff37a147fcd1c3e9f039a7203) ) \ + \ + ROM_REGION(0x10000, "sram", 0) \ + ROM_LOAD("gsyx_nvram", 0x00000000, 0x10000, CRC(22400c16) SHA1(f775a16299c30f2ce23d683161b910e06eff37c1) ) + +#define KOV2NL_PROGRAM_302 \ + ROM_REGION( 0x1000000, "user1", 0 ) \ + ROM_LOAD("gsyx_v302cn.u7", 0x00000000, 0x0800000, CRC(b19cf540) SHA1(25da5804bbfd7ef2cdf5cc5aabaa803d18b98929) ) + +#define KOV2NL_PROGRAM_301 \ + ROM_REGION( 0x1000000, "user1", 0 ) \ + ROM_LOAD("gsyx_v301cn.u7", 0x000000, 0x800000, CRC(c4595c2c) SHA1(09e379556ef76f81a63664f46d3f1415b315f384) ) + +#define KOV2NL_PROGRAM_300 \ + ROM_REGION( 0x1000000, "user1", 0 ) \ + ROM_LOAD("gsyx_v300tw.u7", 0x000000, 0x800000, CRC(08da7552) SHA1(303b97d7694405474c8133a259303ccb49db48b1) ) + +#define KOV2NL_INTERNAL_CHINA \ + ROM_REGION( 0x04000, "maincpu", 0 ) \ + ROM_LOAD( "gsyx_igs036_china.rom", 0x00000000, 0x0004000, CRC(e09fe4ce) SHA1(c0cac64ef8727cbe79d503ec4df66ddb6f2c925e) ) - ROM_REGION( 0x2000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "ig-a3_sp.u37", 0x00000000, 0x2000000, CRC(45cdf422) SHA1(8005d284bcee73cff37a147fcd1c3e9f039a7203) ) +ROM_START( kov2nl ) + KOV2NL_INTERNAL_CHINA + KOV2NL_PROGRAM_302 + KOV2NL_VIDEO_SOUND_ROMS ROM_END -ROM_START( kov2nloa ) - ROM_REGION( 0x04000, "maincpu", 0 ) - ROM_LOAD( "gsyx_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) - - ROM_REGION( 0x800000, "user1", 0 ) - ROM_LOAD( "kov2nl_gsyx_v300tw.u7", 0x000000, 0x800000, CRC(08da7552) SHA1(303b97d7694405474c8133a259303ccb49db48b1) ) - - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "ig-a3_text.u4", 0x00000000, 0x0200000, CRC(214530ff) SHA1(4231a02054b0345392a077042b95779fd45d6c22) ) - - ROM_REGION( 0x1000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "ig-a3_bgl.u35", 0x00000000, 0x0800000, CRC(2d46b1f6) SHA1(ea8c805eda6292e86a642e9633d8fee7054d10b1) ) - ROM_LOAD32_WORD( "ig-a3_bgh.u36", 0x00000002, 0x0800000, CRC(df710c36) SHA1(f826c3f496c4f17b46d18af1d8e02cac7b7027ac) ) - - ROM_REGION( 0x2000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "ig-a3_bml.u12", 0x00000000, 0x1000000, CRC(0bf63836) SHA1(b8e4f1951f8074b475b795bd7840c5a375b6f5ef) ) - ROM_LOAD32_WORD( "ig-a3_bmh.u16", 0x00000002, 0x1000000, CRC(4a378542) SHA1(5d06a8a8796285a786ebb690c34610f923ef5570) ) - - ROM_REGION( 0x4000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "ig-a3_cgl.u18", 0x00000000, 0x2000000, CRC(8d923e1f) SHA1(14371cf385dd8857017d3111cd4710f4291b1ae2) ) - ROM_LOAD32_WORD( "ig-a3_cgh.u26", 0x00000002, 0x2000000, CRC(5b6fbf3f) SHA1(d1f52e230b91ee6cde939d7c2b74da7fd6527e73) ) +ROM_START( kov2nl_301 ) + KOV2NL_INTERNAL_CHINA + KOV2NL_PROGRAM_301 + KOV2NL_VIDEO_SOUND_ROMS +ROM_END - ROM_REGION( 0x2000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "ig-a3_sp.u37", 0x00000000, 0x2000000, CRC(45cdf422) SHA1(8005d284bcee73cff37a147fcd1c3e9f039a7203) ) +ROM_START( kov2nl_300 ) + KOV2NL_INTERNAL_CHINA + KOV2NL_PROGRAM_300 + KOV2NL_VIDEO_SOUND_ROMS ROM_END +// Dodonpachi Daioujou Tamashii + +#define DDPDOJH_VIDEO_SOUND_ROMS \ + ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ + ROM_LOAD( "ddpdoj_text.u1", 0x00000000, 0x0200000, CRC(f18141d1) SHA1(a16e0a76bc926a158bb92dfd35aca749c569ef50) ) \ + \ + ROM_REGION( 0x2000000, "bgtile", 0 ) \ + ROM_LOAD32_WORD( "ddpdoj_bgl.u23", 0x00000000, 0x1000000, CRC(ff65fdab) SHA1(abdd5ca43599a2daa722547a999119123dd9bb28) ) \ + ROM_LOAD32_WORD( "ddpdoj_bgh.u24", 0x00000002, 0x1000000, CRC(bb84d2a6) SHA1(a576a729831b5946287fa8f0d923016f43a9bedb) ) \ + \ + ROM_REGION( 0x1000000, "sprites_mask", 0 ) /* 1bpp sprite mask data */ \ + ROM_LOAD32_WORD( "ddpdoj_mapl0.u13", 0x00000000, 0x800000, CRC(bcfbb0fc) SHA1(9ec478eba9905913cf997bd9b46c70c1ad383630) ) \ + ROM_LOAD32_WORD( "ddpdoj_maph0.u15", 0x00000002, 0x800000, CRC(0cc75d4e) SHA1(6d1b5ef0fdebf1e84fa199b939ffa07b810b12c9) ) \ + \ + ROM_REGION( 0x2000000, "sprites_colour", 0 ) /* sprite colour data */ \ + ROM_LOAD32_WORD( "ddpdoj_spa0.u9", 0x00000000, 0x1000000, CRC(1232c1b4) SHA1(ecc1c549ae19d2f052a85fe4a993608aedf49a25) ) \ + ROM_LOAD32_WORD( "ddpdoj_spb0.u18", 0x00000002, 0x1000000, CRC(6a9e2cbf) SHA1(8e0a4ea90f5ef534820303d62f0873f8ac9f080e) ) \ + \ + ROM_REGION( 0x1000000, "ymz774", ROMREGION_ERASEFF ) /* ymz770 */ \ + ROM_LOAD16_WORD_SWAP( "ddpdoj_wave0.u12", 0x00000000, 0x1000000, CRC(2b71a324) SHA1(f69076cc561f40ca564d804bc7bd455066f8d77c) ) + ROM_START( ddpdojh ) ROM_REGION( 0x04000, "maincpu", 0 ) - ROM_LOAD( "ddpdoj_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) + ROM_LOAD( "ddpdoj_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) // CRC(5db91464) SHA1(723d8086285805bd815e62120dfa9a4269bcd932) - ROM_REGION( 0x800000, "user1", 0 ) + ROM_REGION( 0x1000000, "user1", 0 ) ROM_LOAD( "ddpdoj_v201cn.u4", 0x00000000, 0x0200000, CRC(89e4b760) SHA1(9fad1309da31d12a413731b416a8bbfdb304ed9e) ) - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "ddpdoj_text.u1", 0x00000000, 0x0200000, CRC(f18141d1) SHA1(a16e0a76bc926a158bb92dfd35aca749c569ef50) ) - - ROM_REGION( 0x2000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "ddpdoj_bgl.u23", 0x00000000, 0x1000000, CRC(ff65fdab) SHA1(abdd5ca43599a2daa722547a999119123dd9bb28) ) - ROM_LOAD32_WORD( "ddpdoj_bgh.u24", 0x00000002, 0x1000000, CRC(bb84d2a6) SHA1(a576a729831b5946287fa8f0d923016f43a9bedb) ) - - ROM_REGION( 0x1000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "ddpdoj_mapl0.u13", 0x00000000, 0x800000, CRC(bcfbb0fc) SHA1(9ec478eba9905913cf997bd9b46c70c1ad383630) ) - ROM_LOAD32_WORD( "ddpdoj_maph0.u15", 0x00000002, 0x800000, CRC(0cc75d4e) SHA1(6d1b5ef0fdebf1e84fa199b939ffa07b810b12c9) ) - - ROM_REGION( 0x2000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "ddpdoj_spa0.u9", 0x00000000, 0x1000000, CRC(1232c1b4) SHA1(ecc1c549ae19d2f052a85fe4a993608aedf49a25) ) - ROM_LOAD32_WORD( "ddpdoj_spb0.u18", 0x00000002, 0x1000000, CRC(6a9e2cbf) SHA1(8e0a4ea90f5ef534820303d62f0873f8ac9f080e) ) - - ROM_REGION( 0x1000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "ddpdoj_wave0.u12", 0x00000000, 0x1000000, CRC(2b71a324) SHA1(f69076cc561f40ca564d804bc7bd455066f8d77c) ) + DDPDOJH_VIDEO_SOUND_ROMS ROM_END +// Knights of Valour 3 + /* The Kov3 Program rom is a module consisting of a NOR flash and a FPGA, this provides an extra layer of encryption on top of the usual that is only unlocked when the correct sequence is recieved from the ARM MCU (IGS036) @@ -471,84 +489,97 @@ ROM_END Newer gambling games use the same modules. */ +#define KOV3_VIDEO_SOUND_ROMS \ + ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ + ROM_LOAD( "kov3_text.u1", 0x00000000, 0x0200000, CRC(198b52d6) SHA1(e4502abe7ba01053d16c02114f0c88a3f52f6f40) ) \ + \ + ROM_REGION( 0x2000000, "bgtile", 0 ) \ + ROM_LOAD32_WORD( "kov3_bgl.u6", 0x00000000, 0x1000000, CRC(49a4c5bc) SHA1(26b7da91067bda196252520e9b4893361c2fc675) ) \ + ROM_LOAD32_WORD( "kov3_bgh.u7", 0x00000002, 0x1000000, CRC(adc1aff1) SHA1(b10490f0dbef9905cdb064168c529f0b5a2b28b8) ) \ + \ + ROM_REGION( 0x4000000, "sprites_mask", 0 ) /* 1bpp sprite mask data */ \ + ROM_LOAD32_WORD( "kov3_mapl0.u15", 0x00000000, 0x2000000, CRC(9e569bf7) SHA1(03d26e000e9d8e744546be9649628d2130f2ec4c) ) \ + ROM_LOAD32_WORD( "kov3_maph0.u16", 0x00000002, 0x2000000, CRC(6f200ad8) SHA1(cd12c136d4f5d424bd7daeeacd5c4127beb3d565) ) \ + \ + ROM_REGION( 0x8000000, "sprites_colour", 0 ) /* sprite colour data */ \ + ROM_LOAD32_WORD( "kov3_spa0.u17", 0x00000000, 0x4000000, CRC(3a1e58a9) SHA1(6ba251407c69ee62f7ea0baae91bc133acc70c6f) ) \ + ROM_LOAD32_WORD( "kov3_spb0.u10", 0x00000002, 0x4000000, CRC(90396065) SHA1(01bf9f69d77a792d5b39afbba70fbfa098e194f1) ) \ + \ + ROM_REGION( 0x4000000, "ymz774", ROMREGION_ERASEFF ) /* ymz770 */ \ + ROM_LOAD16_WORD_SWAP( "kov3_wave0.u13", 0x00000000, 0x4000000, CRC(aa639152) SHA1(2314c6bd05524525a31a2a4668a36a938b924ba4) ) + ROM_START( kov3 ) ROM_REGION( 0x04000, "maincpu", 0 ) - ROM_LOAD( "kov3_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) + ROM_LOAD( "kov3_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) // CRC(c7d33764) SHA1(5cd48f876e637d60391d39ac6e40bf243300cc75) - ROM_REGION( 0x800000, "user1", 0 ) + ROM_REGION( 0x1000000, "user1", 0 ) ROM_LOAD( "kov3_v104cn_raw.bin", 0x00000000, 0x0800000, CRC(1b5cbd24) SHA1(6471d4842a08f404420dea2bd1c8b88798c80fd5) ) - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "kov3_text.u1", 0x00000000, 0x0200000, CRC(198b52d6) SHA1(e4502abe7ba01053d16c02114f0c88a3f52f6f40) ) - - ROM_REGION( 0x2000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "kov3_bgl.u6", 0x00000000, 0x1000000, CRC(49a4c5bc) SHA1(26b7da91067bda196252520e9b4893361c2fc675) ) - ROM_LOAD32_WORD( "kov3_bgh.u7", 0x00000002, 0x1000000, CRC(adc1aff1) SHA1(b10490f0dbef9905cdb064168c529f0b5a2b28b8) ) - - ROM_REGION( 0x4000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "kov3_mapl0.u15", 0x00000000, 0x2000000, CRC(9e569bf7) SHA1(03d26e000e9d8e744546be9649628d2130f2ec4c) ) - ROM_LOAD32_WORD( "kov3_maph0.u16", 0x00000002, 0x2000000, CRC(6f200ad8) SHA1(cd12c136d4f5d424bd7daeeacd5c4127beb3d565) ) - - ROM_REGION( 0x8000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "kov3_spa0.u17", 0x00000000, 0x4000000, CRC(3a1e58a9) SHA1(6ba251407c69ee62f7ea0baae91bc133acc70c6f) ) - ROM_LOAD32_WORD( "kov3_spb0.u10", 0x00000002, 0x4000000, CRC(90396065) SHA1(01bf9f69d77a792d5b39afbba70fbfa098e194f1) ) - - ROM_REGION( 0x4000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "kov3_wave0.u13", 0x00000000, 0x4000000, CRC(aa639152) SHA1(2314c6bd05524525a31a2a4668a36a938b924ba4) ) + KOV3_VIDEO_SOUND_ROMS ROM_END ROM_START( kov3_102 ) ROM_REGION( 0x04000, "maincpu", 0 ) ROM_LOAD( "kov3_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) - ROM_REGION( 0x800000, "user1", 0 ) + ROM_REGION( 0x1000000, "user1", 0 ) ROM_LOAD( "kov3_v102cn_raw.bin", 0x00000000, 0x0800000, CRC(61d0dabd) SHA1(959b22ef4e342ca39c2386549ac7274f9d580ab8) ) - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "kov3_text.u1", 0x00000000, 0x0200000, CRC(198b52d6) SHA1(e4502abe7ba01053d16c02114f0c88a3f52f6f40) ) - - ROM_REGION( 0x2000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "kov3_bgl.u6", 0x00000000, 0x1000000, CRC(49a4c5bc) SHA1(26b7da91067bda196252520e9b4893361c2fc675) ) - ROM_LOAD32_WORD( "kov3_bgh.u7", 0x00000002, 0x1000000, CRC(adc1aff1) SHA1(b10490f0dbef9905cdb064168c529f0b5a2b28b8) ) - - ROM_REGION( 0x4000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "kov3_mapl0.u15", 0x00000000, 0x2000000, CRC(9e569bf7) SHA1(03d26e000e9d8e744546be9649628d2130f2ec4c) ) - ROM_LOAD32_WORD( "kov3_maph0.u16", 0x00000002, 0x2000000, CRC(6f200ad8) SHA1(cd12c136d4f5d424bd7daeeacd5c4127beb3d565) ) - - ROM_REGION( 0x8000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "kov3_spa0.u17", 0x00000000, 0x4000000, CRC(3a1e58a9) SHA1(6ba251407c69ee62f7ea0baae91bc133acc70c6f) ) - ROM_LOAD32_WORD( "kov3_spb0.u10", 0x00000002, 0x4000000, CRC(90396065) SHA1(01bf9f69d77a792d5b39afbba70fbfa098e194f1) ) - - ROM_REGION( 0x4000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "kov3_wave0.u13", 0x00000000, 0x4000000, CRC(aa639152) SHA1(2314c6bd05524525a31a2a4668a36a938b924ba4) ) + KOV3_VIDEO_SOUND_ROMS ROM_END ROM_START( kov3_100 ) ROM_REGION( 0x04000, "maincpu", 0 ) ROM_LOAD( "kov3_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) - ROM_REGION( 0x800000, "user1", 0 ) + ROM_REGION( 0x1000000, "user1", 0 ) ROM_LOAD( "kov3_v100cn_raw.bin", 0x00000000, 0x0800000, CRC(93bca924) SHA1(ecaf2c4676eb3d9f5e4fdbd9388be41e51afa0e4) ) - ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) - ROM_LOAD( "kov3_text.u1", 0x00000000, 0x0200000, CRC(198b52d6) SHA1(e4502abe7ba01053d16c02114f0c88a3f52f6f40) ) + KOV3_VIDEO_SOUND_ROMS +ROM_END - ROM_REGION( 0x2000000, "bgtile", 0 ) - ROM_LOAD32_WORD( "kov3_bgl.u6", 0x00000000, 0x1000000, CRC(49a4c5bc) SHA1(26b7da91067bda196252520e9b4893361c2fc675) ) - ROM_LOAD32_WORD( "kov3_bgh.u7", 0x00000002, 0x1000000, CRC(adc1aff1) SHA1(b10490f0dbef9905cdb064168c529f0b5a2b28b8) ) +/* King of Fighters '98: Ultimate Match HERO - ROM_REGION( 0x4000000, "spritesa", 0 ) // 1bpp sprite mask data - ROM_LOAD32_WORD( "kov3_mapl0.u15", 0x00000000, 0x2000000, CRC(9e569bf7) SHA1(03d26e000e9d8e744546be9649628d2130f2ec4c) ) - ROM_LOAD32_WORD( "kov3_maph0.u16", 0x00000002, 0x2000000, CRC(6f200ad8) SHA1(cd12c136d4f5d424bd7daeeacd5c4127beb3d565) ) +device types were as follows - ROM_REGION( 0x8000000, "spritesb", 0 ) // sprite colour data - ROM_LOAD32_WORD( "kov3_spa0.u17", 0x00000000, 0x4000000, CRC(3a1e58a9) SHA1(6ba251407c69ee62f7ea0baae91bc133acc70c6f) ) - ROM_LOAD32_WORD( "kov3_spb0.u10", 0x00000002, 0x4000000, CRC(90396065) SHA1(01bf9f69d77a792d5b39afbba70fbfa098e194f1) ) +kof98umh_v100cn.u4 SAMSUNG K8Q2815UQB +ig-d3_text.u1 cFeon EN29LV160AB +all others: SPANSION S99-50070 - ROM_REGION( 0x4000000, "ymz770", ROMREGION_ERASEFF ) /* ymz770 */ - ROM_LOAD16_WORD_SWAP( "kov3_wave0.u13", 0x00000000, 0x4000000, CRC(aa639152) SHA1(2314c6bd05524525a31a2a4668a36a938b924ba4) ) -ROM_END +*/ +#define KOF98UMH_VIDEO_SOUND_ROMS \ + ROM_REGION( 0x200000, "tiles", ROMREGION_ERASEFF ) \ + ROM_LOAD( "ig-d3_text.u1", 0x00000000, 0x0200000, CRC(9a0ea82e) SHA1(7844fd7e46c3fbb2164060f160da528254fd177e) ) \ + \ + ROM_REGION( 0x2000000, "bgtile", ROMREGION_ERASEFF ) \ + /* bgl/bgh unpopulated (no background tilemap) */ \ + \ + ROM_REGION( 0x08000000, "sprites_mask", 0 ) /* 1bpp sprite mask data */ \ + ROM_LOAD32_WORD( "ig-d3_mapl0.u13", 0x00000000, 0x4000000, CRC(5571d63e) SHA1(dad73797a35738013d82e3b8ca96fa001ec56f69) ) \ + ROM_LOAD32_WORD( "ig-d3_maph0.u15", 0x00000002, 0x4000000, CRC(0da7b1b8) SHA1(87741242bd827eca3788b490df6dcb65f7a89733) ) \ + \ + ROM_REGION( 0x20000000, "sprites_colour", 0 ) /* sprite colour data - some byte are 0x40 or even 0xff, but verified on 2 boards */ \ + ROM_LOAD32_WORD( "ig-d3_spa0.u9", 0x00000000, 0x4000000, CRC(cfef8f7d) SHA1(54f58d1b9eb7d2e4bbe13fbdfd98f5b14ce2086b) ) \ + ROM_LOAD32_WORD( "ig-d3_spb0.u18", 0x00000002, 0x4000000, CRC(f199d5c8) SHA1(91f5e8efd1f6a9e5aada51afdf5a8f52bac24185) ) \ + /* spa1/spb1 unpopulated */ \ + ROM_LOAD32_WORD( "ig-d3_spa2.u10", 0x10000000, 0x4000000, CRC(03bfd35c) SHA1(814998cd5ee01c9da775b73f7a0ba4216fe4970e) ) \ + ROM_LOAD32_WORD( "ig-d3_spb2.u20", 0x10000002, 0x4000000, CRC(9aaa840b) SHA1(3c6078d53bb5eca5c501540214287dd102102ea1) ) \ + /* spa3/spb3 unpopulated */ \ + \ + ROM_REGION( 0x08000000, "ymz774", ROMREGION_ERASEFF ) /* ymz770 */ \ + ROM_LOAD16_WORD_SWAP( "ig-d3_wave0.u12", 0x00000000, 0x4000000, CRC(edf2332d) SHA1(7e01c7e03e515814d7de117c265c3668d32842fa) ) \ + ROM_LOAD16_WORD_SWAP( "ig-d3_wave1.u11", 0x04000000, 0x4000000, CRC(62321b20) SHA1(a388c8a2489430fbe92fb26b3ef81c66ce97f318) ) + +ROM_START( kof98umh ) + ROM_REGION( 0x04000, "maincpu", 0 ) + ROM_LOAD( "kof98uhm_igs036.rom", 0x00000000, 0x0004000, NO_DUMP ) // CRC(3ed2e50f) SHA1(35310045d375d9dda36c325e35257123a7b5b8c7) + + ROM_REGION( 0x1000000, "user1", 0 ) + ROM_LOAD( "kof98umh_v100cn.u4", 0x00000000, 0x1000000, CRC(2ea91e3b) SHA1(5a586bb99cc4f1b02e0db462d5aff721512e0640) ) + + KOF98UMH_VIDEO_SOUND_ROMS +ROM_END static void iga_u16_decode(uint16_t *rom, int len, int ixor) { @@ -600,56 +631,116 @@ static void iga_u12_decode(uint16_t* rom, int len, int ixor) } } +static void sprite_colour_decode(uint16_t* rom, int len) +{ + int i; + + for (i = 0; i < len / 2; i++) + { + rom[i] = BITSWAP16(rom[i], 15, 14, /* unused - 6bpp */ + 13, 12, 11, + 5, 4, 3, + 7, 6, /* unused - 6bpp */ + 10, 9, 8, + 2, 1, 0 ); + } +} + +READ32_MEMBER(pgm2_state::orleg2_speedup_r) +{ + int pc = space.device().safe_pc(); + if ((pc == 0x1002faec) || (pc == 0x1002f9b8)) + { + if ((m_mainram[0x20114 / 4] == 0x00) && (m_mainram[0x20118 / 4] == 0x00)) + space.device().execute().spin_until_interrupt(); + } + /*else + { + printf("pc is %08x\n", pc); + }*/ + + return m_mainram[0x20114 / 4]; +} + +READ32_MEMBER(pgm2_state::kov2nl_speedup_r) +{ + int pc = space.device().safe_pc(); + + if ((pc == 0x10053a94) || (pc == 0x1005332c) || (pc == 0x1005327c)) + { + if ((m_mainram[0x20470 / 4] == 0x00) && (m_mainram[0x20474 / 4] == 0x00)) + space.device().execute().spin_until_interrupt(); + } + /* + else + { + printf("pc is %08x\n", pc); + } + */ + + return m_mainram[0x20470 / 4]; +} + + + DRIVER_INIT_MEMBER(pgm2_state,orleg2) { - uint16_t *src = (uint16_t *)memregion("spritesa")->base(); + uint16_t *src = (uint16_t *)memregion("sprites_mask")->base(); iga_u12_decode(src, 0x2000000, 0x4761); iga_u16_decode(src, 0x2000000, 0xc79f); + src = (uint16_t *)memregion("sprites_colour")->base(); + sprite_colour_decode(src, 0x4000000); + igs036_decryptor decrypter(orleg2_key); decrypter.decrypter_rom(memregion("user1")); - pgm_create_dummy_internal_arm_region(); + machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x20020114, 0x20020117, read32_delegate(FUNC(pgm2_state::orleg2_speedup_r),this)); } DRIVER_INIT_MEMBER(pgm2_state,kov2nl) { - uint16_t *src = (uint16_t *)memregion("spritesa")->base(); + uint16_t *src = (uint16_t *)memregion("sprites_mask")->base(); iga_u12_decode(src, 0x2000000, 0xa193); iga_u16_decode(src, 0x2000000, 0xb780); + src = (uint16_t *)memregion("sprites_colour")->base(); + sprite_colour_decode(src, 0x4000000); + igs036_decryptor decrypter(kov2_key); decrypter.decrypter_rom(memregion("user1")); - pgm_create_dummy_internal_arm_region(); + machine().device("maincpu")->memory().space(AS_PROGRAM).install_read_handler(0x20020470, 0x20020473, read32_delegate(FUNC(pgm2_state::kov2nl_speedup_r), this)); } DRIVER_INIT_MEMBER(pgm2_state,ddpdojh) { - uint16_t *src = (uint16_t *)memregion("spritesa")->base(); + uint16_t *src = (uint16_t *)memregion("sprites_mask")->base(); + + iga_u12_decode(src, 0x1000000, 0x1e96); + iga_u16_decode(src, 0x1000000, 0x869c); - iga_u12_decode(src, 0x800000, 0x1e96); - iga_u16_decode(src, 0x800000, 0x869c); + src = (uint16_t *)memregion("sprites_colour")->base(); + sprite_colour_decode(src, 0x2000000); igs036_decryptor decrypter(ddpdoj_key); decrypter.decrypter_rom(memregion("user1")); - - pgm_create_dummy_internal_arm_region(); } DRIVER_INIT_MEMBER(pgm2_state,kov3) { - uint16_t *src = (uint16_t *)memregion("spritesa")->base(); + uint16_t *src = (uint16_t *)memregion("sprites_mask")->base(); - iga_u12_decode(src, 0x2000000, 0x956d); - iga_u16_decode(src, 0x2000000, 0x3d17); + iga_u12_decode(src, 0x4000000, 0x956d); + iga_u16_decode(src, 0x4000000, 0x3d17); + + src = (uint16_t *)memregion("sprites_colour")->base(); + sprite_colour_decode(src, 0x8000000); igs036_decryptor decrypter(kov3_key); decrypter.decrypter_rom(memregion("user1")); - - pgm_create_dummy_internal_arm_region(); } void pgm2_state::decrypt_kov3_module(uint32_t addrxor, uint16_t dataxor) @@ -683,25 +774,45 @@ DRIVER_INIT_MEMBER(pgm2_state, kov3_100) DRIVER_INIT_CALL(kov3); } +DRIVER_INIT_MEMBER(pgm2_state,kof98umh) +{ + uint16_t *src = (uint16_t *)memregion("sprites_mask")->base(); + + iga_u12_decode(src, 0x08000000, 0x1e96); // wrong + iga_u16_decode(src, 0x08000000, 0x869c); // wrong + + src = (uint16_t *)memregion("sprites_colour")->base(); + sprite_colour_decode(src, 0x20000000); + + igs036_decryptor decrypter(kof98umh_key); + decrypter.decrypter_rom(memregion("user1")); +} /* PGM2 */ -GAME( 2007, orleg2, 0, pgm2, pgm2, pgm2_state, orleg2, ROT0, "IGS", "Oriental Legend 2 (V104, China)", MACHINE_IS_SKELETON ) -GAME( 2007, orleg2o, orleg2, pgm2, pgm2, pgm2_state, orleg2, ROT0, "IGS", "Oriental Legend 2 (V103, China)", MACHINE_IS_SKELETON ) -GAME( 2007, orleg2oa, orleg2, pgm2, pgm2, pgm2_state, orleg2, ROT0, "IGS", "Oriental Legend 2 (V101, China)", MACHINE_IS_SKELETON ) -// should be a V100 too -GAME( 2008, kov2nl, 0, pgm2, pgm2, pgm2_state, kov2nl, ROT0, "IGS", "Knights of Valour 2 New Legend (V302, China)", MACHINE_IS_SKELETON ) -GAME( 2008, kov2nlo, kov2nl, pgm2, pgm2, pgm2_state, kov2nl, ROT0, "IGS", "Knights of Valour 2 New Legend (V301, China)", MACHINE_IS_SKELETON ) -GAME( 2008, kov2nloa, kov2nl, pgm2, pgm2, pgm2_state, kov2nl, ROT0, "IGS", "Knights of Valour 2 New Legend (V300, Taiwan)", MACHINE_IS_SKELETON ) +// Oriental Legend 2 - should be a V102 and V100 too +GAME( 2007, orleg2, 0, pgm2, pgm2, pgm2_state, orleg2, ROT0, "IGS", "Oriental Legend 2 (V104, China)", MACHINE_NOT_WORKING ) +GAME( 2007, orleg2_103, orleg2, pgm2, pgm2, pgm2_state, orleg2, ROT0, "IGS", "Oriental Legend 2 (V103, China)", MACHINE_NOT_WORKING ) +GAME( 2007, orleg2_101, orleg2, pgm2, pgm2, pgm2_state, orleg2, ROT0, "IGS", "Oriental Legend 2 (V101, China)", MACHINE_NOT_WORKING ) -GAME( 2010, ddpdojh, 0, pgm2, pgm2, pgm2_state, ddpdojh, ROT270, "IGS", "Dodonpachi Daioujou Tamashii (V201, China)", MACHINE_IS_SKELETON ) -// should be a V200 too +// Knights of Valour 2 New Legend +GAME( 2008, kov2nl, 0, pgm2, pgm2, pgm2_state, kov2nl, ROT0, "IGS", "Knights of Valour 2 New Legend (V302, China)", MACHINE_NOT_WORKING ) +GAME( 2008, kov2nl_301, kov2nl, pgm2, pgm2, pgm2_state, kov2nl, ROT0, "IGS", "Knights of Valour 2 New Legend (V301, China)", MACHINE_NOT_WORKING ) +GAME( 2008, kov2nl_300, kov2nl, pgm2, pgm2, pgm2_state, kov2nl, ROT0, "IGS", "Knights of Valour 2 New Legend (V300, China)", MACHINE_NOT_WORKING ) // was dumped from a Taiwan board tho -GAME( 2011, kov3, 0, pgm2, pgm2, pgm2_state, kov3_104, ROT0, "IGS", "Knights of Valour 3 (V104, China)", MACHINE_IS_SKELETON ) -GAME( 2011, kov3_102, kov3, pgm2, pgm2, pgm2_state, kov3_102, ROT0, "IGS", "Knights of Valour 3 (V102, China)", MACHINE_IS_SKELETON ) -GAME( 2011, kov3_100, kov3, pgm2, pgm2, pgm2_state, kov3_100, ROT0, "IGS", "Knights of Valour 3 (V100, China)", MACHINE_IS_SKELETON ) -// should be V103 and V101 at least +// Dodonpachi Daioujou Tamashii - should be a V200 too +GAME( 2010, ddpdojh, 0, pgm2, pgm2, pgm2_state, ddpdojh, ROT270, "IGS", "Dodonpachi Daioujou Tamashii (V201, China)", MACHINE_NOT_WORKING ) + +// Knights of Valour 3 - should be a V103 and V101 too +GAME( 2011, kov3, 0, pgm2, pgm2, pgm2_state, kov3_104, ROT0, "IGS", "Knights of Valour 3 (V104, China)", MACHINE_NOT_WORKING ) +GAME( 2011, kov3_102, kov3, pgm2, pgm2, pgm2_state, kov3_102, ROT0, "IGS", "Knights of Valour 3 (V102, China)", MACHINE_NOT_WORKING ) +GAME( 2011, kov3_100, kov3, pgm2, pgm2, pgm2_state, kov3_100, ROT0, "IGS", "Knights of Valour 3 (V100, China)", MACHINE_NOT_WORKING ) + +// King of Fighters '98: Ultimate Match Hero +GAME( 2009, kof98umh, 0, pgm2, pgm2, pgm2_state, kof98umh, ROT0, "IGS / SNK Playmore / NewChannel", "The King of Fighters '98: Ultimate Match HERO (China, V100, 09-08-23)", MACHINE_NOT_WORKING ) -// The King of Fighters '98 - Ultimate Match - Hero // Jigsaw World Arena -//Puzzle of Ocha / Ochainu No Pazuru + +// Puzzle of Ocha / Ochainu No Pazuru + + diff --git a/src/mame/drivers/picno.cpp b/src/mame/drivers/picno.cpp new file mode 100644 index 00000000000..08b088b9c04 --- /dev/null +++ b/src/mame/drivers/picno.cpp @@ -0,0 +1,71 @@ +// license:BSD-3-Clause +// copyright-holders:Robbbert +/****************************************************************************************************************************** + +Konami Picno and Picno2 + +Skeleton driver started on 2017-11-30, can be claimed by anyone interested. + +Information provided by Team Europe. + +Chips: HD6435328F10 (H8/532 CPU with inbuilt ROM), HN62334BP (27c040 ROM), Konami custom chip 054715 (rectangular 100 pins), + HM538121JP-10, M514256B-70J, OKI M6585. +Crystals: D200L2 (Y1) and D214A3 (Y2), frequencies unknown. + +The size of the address space and other things is controlled by the 3 mode pins. It's assumed we are in Mode 4. + +Can't do anything until the internal ROM is dumped. + +******************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/h8/h83002.h" +//#include "sound/multipcm.h" +//#include "screen.h" +//#include "speaker.h" + +class picno_state : public driver_device +{ +public: + picno_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { } + +private: + required_device<cpu_device> m_maincpu; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 16, picno_state ) + AM_RANGE(0x00000, 0x07fff) AM_ROM AM_REGION("roms", 0) // 32kb internal rom + AM_RANGE(0x0fb80, 0x0ff7f) AM_RAM // internal ram + AM_RANGE(0x0ff80, 0x0ffff) // internal controls + AM_RANGE(0x10000, 0x8ffff) AM_ROM AM_REGION("roms", 0x8000) // guess +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_IO, 8, picno_state ) +// ADDRESS_MAP_GLOBAL_MASK(0xff) +ADDRESS_MAP_END + +static INPUT_PORTS_START( picno ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( picno ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", H83002, XTAL_20MHz) /* TODO: correct CPU type (H8/532), crystal is a guess, divided by 2 in the cpu */ + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + + //MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") // no speaker in the unit, but there's a couple of sockets on the back + //MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) + //MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) +MACHINE_CONFIG_END + +ROM_START( picno ) + ROM_REGION(0x88000, "roms", 0) + ROM_LOAD( "hd6435328f10.u5", 0x00000, 0x08000, NO_DUMP ) // internal rom + ROM_LOAD( "hn62334bp.u2", 0x08000, 0x80000, CRC(ae89a9a5) SHA1(51ed458ffd151e19019beb23517263efce4be272) ) +ROM_END + +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +CONS( 1993, picno, 0, 0, picno, picno, picno_state, 0, "Konami", "Picno", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/pimps.cpp b/src/mame/drivers/pimps.cpp index 3476dacec8c..97f424b1dff 100644 --- a/src/mame/drivers/pimps.cpp +++ b/src/mame/drivers/pimps.cpp @@ -88,13 +88,13 @@ private: }; -static ADDRESS_MAP_START(pimps_mem, AS_PROGRAM, 8, pimps_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, pimps_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0xefff) AM_RAM AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION("roms", 0) ADDRESS_MAP_END -static ADDRESS_MAP_START(pimps_io, AS_IO, 8, pimps_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, pimps_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0xf0, 0xf0) AM_DEVREADWRITE("uart1", i8251_device, data_r, data_w) AM_RANGE(0xf1, 0xf1) AM_DEVREADWRITE("uart1", i8251_device, status_r, control_w) @@ -125,8 +125,8 @@ DEVICE_INPUT_DEFAULTS_END static MACHINE_CONFIG_START( pimps ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",I8085A, XTAL_2MHz) - MCFG_CPU_PROGRAM_MAP(pimps_mem) - MCFG_CPU_IO_MAP(pimps_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_DEVICE_ADD("uart_clock", CLOCK, 153600) MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("uart1", i8251_device, write_txc)) diff --git a/src/mame/drivers/playmark.cpp b/src/mame/drivers/playmark.cpp index 6b8742ae8ad..567965d00d1 100644 --- a/src/mame/drivers/playmark.cpp +++ b/src/mame/drivers/playmark.cpp @@ -414,6 +414,38 @@ static ADDRESS_MAP_START( oki_map, 0, 8, playmark_state ) ADDRESS_MAP_END +#define PLAYMARK_COINS \ + PORT_DIPNAME( 0x01, 0x01, "Coin Slots" ) PORT_DIPLOCATION("DSW1:1") \ + PORT_DIPSETTING( 0x00, "Separate" ) \ + PORT_DIPSETTING( 0x01, "Common" ) \ + PORT_DIPNAME( 0x1e, 0x1e, DEF_STR( Coinage ) ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01) PORT_DIPLOCATION("DSW1:2,3,4,5") \ + PORT_DIPSETTING( 0x14, DEF_STR( 6C_1C ) ) \ + PORT_DIPSETTING( 0x16, DEF_STR( 5C_1C ) ) \ + PORT_DIPSETTING( 0x18, DEF_STR( 4C_1C ) ) \ + PORT_DIPSETTING( 0x1a, DEF_STR( 3C_1C ) ) \ + PORT_DIPSETTING( 0x02, DEF_STR( 8C_3C ) ) \ + PORT_DIPSETTING( 0x1c, DEF_STR( 2C_1C ) ) \ + PORT_DIPSETTING( 0x04, DEF_STR( 5C_3C ) ) \ + PORT_DIPSETTING( 0x06, DEF_STR( 3C_2C ) ) \ + PORT_DIPSETTING( 0x1e, DEF_STR( 1C_1C ) ) \ + PORT_DIPSETTING( 0x08, DEF_STR( 2C_3C ) ) \ + PORT_DIPSETTING( 0x12, DEF_STR( 1C_2C ) ) \ + PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) \ + PORT_DIPSETTING( 0x0e, DEF_STR( 1C_4C ) ) \ + PORT_DIPSETTING( 0x0c, DEF_STR( 1C_5C ) ) \ + PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ) ) \ + PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) \ + PORT_DIPNAME( 0x06, 0x06, DEF_STR( Coin_A ) ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("DSW1:2,3") \ + PORT_DIPSETTING( 0x00, DEF_STR( 5C_1C ) ) \ + PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) ) \ + PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) ) \ + PORT_DIPSETTING( 0x06, DEF_STR( 1C_1C ) ) \ + PORT_DIPNAME( 0x18, 0x18, DEF_STR( Coin_B ) ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("DSW1:4,5") \ + PORT_DIPSETTING( 0x18, DEF_STR( 1C_2C ) ) \ + PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) \ + PORT_DIPSETTING( 0x08, DEF_STR( 1C_5C ) ) \ + PORT_DIPSETTING( 0x00, DEF_STR( 1C_6C ) ) + static INPUT_PORTS_START( bigtwin ) PORT_START("SYSTEM") @@ -447,168 +479,50 @@ static INPUT_PORTS_START( bigtwin ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) PORT_START("DSW1") - PORT_DIPNAME( 0x01, 0x01, "Coin Mode" ) PORT_DIPLOCATION("SW1:1") - PORT_DIPSETTING( 0x01, "Mode 1" ) - PORT_DIPSETTING( 0x00, "Mode 2" ) - PORT_DIPNAME( 0x1e, 0x1e, "Coinage Mode 1" ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3,4,5") - PORT_DIPSETTING( 0x14, DEF_STR( 6C_1C ) ) - PORT_DIPSETTING( 0x16, DEF_STR( 5C_1C ) ) - PORT_DIPSETTING( 0x18, DEF_STR( 4C_1C ) ) - PORT_DIPSETTING( 0x1a, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 8C_3C ) ) - PORT_DIPSETTING( 0x1c, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 5C_3C ) ) - PORT_DIPSETTING( 0x06, DEF_STR( 3C_2C ) ) - PORT_DIPSETTING( 0x1e, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 2C_3C ) ) - PORT_DIPSETTING( 0x12, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x0e, DEF_STR( 1C_4C ) ) - PORT_DIPSETTING( 0x0c, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) - PORT_DIPNAME( 0x06, 0x06, "Coin A Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3") - PORT_DIPSETTING( 0x00, DEF_STR( 5C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x06, DEF_STR( 1C_1C ) ) - PORT_DIPNAME( 0x18, 0x18, "Coin B Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:4,5") - PORT_DIPSETTING( 0x18, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x00, DEF_STR( 1C_6C ) ) - PORT_DIPNAME( 0x20, 0x20, "Minimum Credits to Start" ) PORT_DIPLOCATION("SW1:6") + PLAYMARK_COINS + PORT_DIPNAME( 0x20, 0x20, "Credits to Start" ) PORT_DIPLOCATION("DSW1:6") PORT_DIPSETTING( 0x20, "1" ) PORT_DIPSETTING( 0x00, "2" ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:7") + PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) PORT_DIPLOCATION("DSW1:7") PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:8") + PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("DSW1:8") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_START("DSW2") - PORT_DIPNAME( 0x01, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("SW2:1") + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("DSW2:1") PORT_DIPSETTING( 0x00, DEF_STR( English ) ) PORT_DIPSETTING( 0x01, DEF_STR( Italian ) ) - PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:2") + PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("DSW2:2") PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, "Censor Pictures" ) PORT_DIPLOCATION("SW2:3") + PORT_DIPNAME( 0x04, 0x00, "Censor Pictures" ) PORT_DIPLOCATION("DSW2:3") PORT_DIPSETTING( 0x00, DEF_STR( No ) ) PORT_DIPSETTING( 0x04, DEF_STR( Yes ) ) - PORT_DIPNAME( 0x08, 0x08, "Rising Ground Level" ) PORT_DIPLOCATION("SW2:4") // Starts from 55th ball drop on 2nd level + PORT_DIPNAME( 0x08, 0x08, "Rising Ground Level" ) PORT_DIPLOCATION("DSW2:4") // Starts from 55th ball drop on 2nd level PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x30, 0x30, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPNAME( 0x30, 0x30, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("DSW2:5,6") // PORT_DIPSETTING( 0x20, DEF_STR( Easy ) ) /* Seems same as Medium */ PORT_DIPSETTING( 0x30, DEF_STR( Medium ) ) PORT_DIPSETTING( 0x10, DEF_STR( Hard ) ) PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW2:7") + PORT_DIPNAME( 0x40, 0x40, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("DSW2:7") PORT_DIPSETTING( 0x00, DEF_STR( No ) ) PORT_DIPSETTING( 0x40, DEF_STR( Yes ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8") + PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("DSW2:8") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) INPUT_PORTS_END static INPUT_PORTS_START( bigtwinb ) - PORT_START("SYSTEM") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("P1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START1 ) + PORT_INCLUDE( bigtwin ) - PORT_START("P2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) - - PORT_START("DSW1") - PORT_DIPNAME( 0x01, 0x01, "Coin Mode" ) PORT_DIPLOCATION("SW1:1") - PORT_DIPSETTING( 0x01, "Mode 1" ) - PORT_DIPSETTING( 0x00, "Mode 2" ) - PORT_DIPNAME( 0x1e, 0x1e, "Coinage Mode 1" ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3,4,5") - PORT_DIPSETTING( 0x14, DEF_STR( 6C_1C ) ) - PORT_DIPSETTING( 0x16, DEF_STR( 5C_1C ) ) - PORT_DIPSETTING( 0x18, DEF_STR( 4C_1C ) ) - PORT_DIPSETTING( 0x1a, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 8C_3C ) ) - PORT_DIPSETTING( 0x1c, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 5C_3C ) ) - PORT_DIPSETTING( 0x06, DEF_STR( 3C_2C ) ) - PORT_DIPSETTING( 0x1e, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 2C_3C ) ) - PORT_DIPSETTING( 0x12, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x0e, DEF_STR( 1C_4C ) ) - PORT_DIPSETTING( 0x0c, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) - PORT_DIPNAME( 0x06, 0x06, "Coin A Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3") - PORT_DIPSETTING( 0x00, DEF_STR( 5C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x06, DEF_STR( 1C_1C ) ) - PORT_DIPNAME( 0x18, 0x18, "Coin B Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:4,5") - PORT_DIPSETTING( 0x18, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x00, DEF_STR( 1C_6C ) ) - PORT_DIPNAME( 0x20, 0x20, "Minimum Credits to Start" ) PORT_DIPLOCATION("SW1:6") - PORT_DIPSETTING( 0x20, "1" ) - PORT_DIPSETTING( 0x00, "2" ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:7") - PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:8") - PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - - PORT_START("DSW2") - PORT_DIPNAME( 0x01, 0x00, DEF_STR( Language ) ) PORT_DIPLOCATION("SW2:1") - PORT_DIPSETTING( 0x00, DEF_STR( English ) ) - PORT_DIPSETTING( 0x01, DEF_STR( Italian ) ) - PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:2") - PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:3") + PORT_MODIFY("DSW2") + PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) PORT_DIPLOCATION("DSW2:3") /* No nudes, No Censor dipswitch */ PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x08, "Rising Ground Level" ) PORT_DIPLOCATION("SW2:4") // Starts from 67th ball drop on 2nd level - PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x30, 0x30, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:5,6") -// PORT_DIPSETTING( 0x20, DEF_STR( Easy ) ) /* Seems same as Medium */ - PORT_DIPSETTING( 0x30, DEF_STR( Medium ) ) - PORT_DIPSETTING( 0x10, DEF_STR( Hard ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW2:7") - PORT_DIPSETTING( 0x00, DEF_STR( No ) ) - PORT_DIPSETTING( 0x40, DEF_STR( Yes ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8") - PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) INPUT_PORTS_END static INPUT_PORTS_START( wbeachvl ) @@ -695,64 +609,35 @@ static INPUT_PORTS_START( excelsr ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) PORT_START("DSW1") - PORT_DIPNAME( 0x01, 0x01, "Coin Mode" ) PORT_DIPLOCATION("SW1:1") - PORT_DIPSETTING( 0x01, "Mode 1" ) - PORT_DIPSETTING( 0x00, "Mode 2" ) - PORT_DIPNAME( 0x1e, 0x1e, "Coinage Mode 1" ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3,4,5") - PORT_DIPSETTING( 0x14, DEF_STR( 6C_1C ) ) - PORT_DIPSETTING( 0x16, DEF_STR( 5C_1C ) ) - PORT_DIPSETTING( 0x18, DEF_STR( 4C_1C ) ) - PORT_DIPSETTING( 0x1a, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 8C_3C ) ) - PORT_DIPSETTING( 0x1c, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 5C_3C ) ) - PORT_DIPSETTING( 0x06, DEF_STR( 3C_2C ) ) - PORT_DIPSETTING( 0x1e, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 2C_3C ) ) - PORT_DIPSETTING( 0x12, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x0e, DEF_STR( 1C_4C ) ) - PORT_DIPSETTING( 0x0c, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) - PORT_DIPNAME( 0x06, 0x06, "Coin A Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3") - PORT_DIPSETTING( 0x00, DEF_STR( 5C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x06, DEF_STR( 1C_1C ) ) - PORT_DIPNAME( 0x18, 0x18, "Coin B Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:4,5") - PORT_DIPSETTING( 0x18, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x00, DEF_STR( 1C_6C ) ) - PORT_DIPNAME( 0x20, 0x20, "Minimum Credits to Start" ) PORT_DIPLOCATION("SW1:6") + PLAYMARK_COINS + PORT_DIPNAME( 0x20, 0x20, "Credits to Start" ) PORT_DIPLOCATION("DSW1:6") PORT_DIPSETTING( 0x20, "1" ) PORT_DIPSETTING( 0x00, "2" ) - PORT_DIPNAME( 0x40, 0x40, "Percentage to Reveal" ) PORT_DIPLOCATION("SW1:7") + PORT_DIPNAME( 0x40, 0x40, "Percentage to Reveal" ) PORT_DIPLOCATION("DSW1:7") PORT_DIPSETTING( 0x40, "80%" ) PORT_DIPSETTING( 0x00, "90%" ) - PORT_SERVICE( 0x80, IP_ACTIVE_LOW ) PORT_DIPLOCATION("SW1:8") + PORT_SERVICE( 0x80, IP_ACTIVE_LOW ) PORT_DIPLOCATION("DSW1:8") PORT_START("DSW2") - PORT_DIPNAME( 0x03, 0x03, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:1,2") + PORT_DIPNAME( 0x03, 0x03, DEF_STR( Lives ) ) PORT_DIPLOCATION("DSW2:1,2") PORT_DIPSETTING( 0x00, "1" ) PORT_DIPSETTING( 0x02, "2" ) PORT_DIPSETTING( 0x03, "3" ) PORT_DIPSETTING( 0x01, "4" ) - PORT_DIPNAME( 0x0c, 0x00, "Censor Pictures" ) PORT_DIPLOCATION("SW2:3,4") + PORT_DIPNAME( 0x0c, 0x00, "Censor Pictures" ) PORT_DIPLOCATION("DSW2:3,4") PORT_DIPSETTING( 0x00, DEF_STR( No ) ) // PORT_DIPSETTING( 0x04, DEF_STR( No ) ) PORT_DIPSETTING( 0x08, "50%" ) PORT_DIPSETTING( 0x0c, "100%" ) - PORT_DIPNAME( 0x30, 0x20, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPNAME( 0x30, 0x20, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("DSW2:5,6") PORT_DIPSETTING( 0x30, DEF_STR( Easy ) ) PORT_DIPSETTING( 0x20, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x10, DEF_STR( Medium ) ) PORT_DIPSETTING( 0x00, DEF_STR( Hard ) ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW2:7") + PORT_DIPNAME( 0x40, 0x40, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("DSW2:7") PORT_DIPSETTING( 0x00, DEF_STR( No ) ) PORT_DIPSETTING( 0x40, DEF_STR( Yes ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8") + PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("DSW2:8") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) INPUT_PORTS_END @@ -789,64 +674,35 @@ static INPUT_PORTS_START( hrdtimes ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) PORT_START("DSW1") - PORT_DIPNAME( 0x01, 0x01, "Coin Mode" ) PORT_DIPLOCATION("SW1:1") - PORT_DIPSETTING( 0x01, "Mode 1" ) - PORT_DIPSETTING( 0x00, "Mode 2" ) - PORT_DIPNAME( 0x1e, 0x1e, "Coinage Mode 1" ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3,4,5") - PORT_DIPSETTING( 0x14, DEF_STR( 6C_1C ) ) - PORT_DIPSETTING( 0x16, DEF_STR( 5C_1C ) ) - PORT_DIPSETTING( 0x18, DEF_STR( 4C_1C ) ) - PORT_DIPSETTING( 0x1a, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 8C_3C ) ) - PORT_DIPSETTING( 0x1c, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 5C_3C ) ) - PORT_DIPSETTING( 0x06, DEF_STR( 3C_2C ) ) - PORT_DIPSETTING( 0x1e, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 2C_3C ) ) - PORT_DIPSETTING( 0x12, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x0e, DEF_STR( 1C_4C ) ) - PORT_DIPSETTING( 0x0c, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) - PORT_DIPNAME( 0x06, 0x06, "Coin A Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3") - PORT_DIPSETTING( 0x00, DEF_STR( 5C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x06, DEF_STR( 1C_1C ) ) - PORT_DIPNAME( 0x18, 0x18, "Coin B Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:4,5") - PORT_DIPSETTING( 0x18, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x00, DEF_STR( 1C_6C ) ) - PORT_DIPNAME( 0x20, 0x20, "Minimum Credits to Start" ) PORT_DIPLOCATION("SW1:6") + PLAYMARK_COINS + PORT_DIPNAME( 0x20, 0x20, "Credits to Start" ) PORT_DIPLOCATION("DSW1:6") PORT_DIPSETTING( 0x20, "1" ) PORT_DIPSETTING( 0x00, "2" ) - PORT_DIPNAME( 0x40, 0x40, "1 Life If Continue" ) PORT_DIPLOCATION("SW1:7") + PORT_DIPNAME( 0x40, 0x40, "1 Life If Continue" ) PORT_DIPLOCATION("DSW1:7") PORT_DIPSETTING( 0x40, DEF_STR( No ) ) PORT_DIPSETTING( 0x00, DEF_STR( Yes ) ) - PORT_SERVICE( 0x80, IP_ACTIVE_LOW ) PORT_DIPLOCATION("SW1:8") + PORT_SERVICE( 0x80, IP_ACTIVE_LOW ) PORT_DIPLOCATION("DSW1:8") PORT_START("DSW2") - PORT_DIPNAME( 0x03, 0x03, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:1,2") + PORT_DIPNAME( 0x03, 0x03, DEF_STR( Lives ) ) PORT_DIPLOCATION("DSW2:1,2") PORT_DIPSETTING( 0x00, "1" ) PORT_DIPSETTING( 0x02, "2" ) PORT_DIPSETTING( 0x03, "3" ) PORT_DIPSETTING( 0x01, "5" ) - PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:3,4") + PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("DSW2:3,4") PORT_DIPSETTING( 0x0c, "Every 300k - 500k" ) PORT_DIPSETTING( 0x08, "Every 500k - 500k" ) PORT_DIPSETTING( 0x04, "Only 500k" ) PORT_DIPSETTING( 0x00, DEF_STR( No ) ) - PORT_DIPNAME( 0x30, 0x30, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPNAME( 0x30, 0x30, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("DSW2:5,6") PORT_DIPSETTING( 0x20, DEF_STR( Easy ) ) PORT_DIPSETTING( 0x30, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x10, DEF_STR( Hard ) ) PORT_DIPSETTING( 0x00, DEF_STR( Very_Hard ) ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW2:7") + PORT_DIPNAME( 0x40, 0x40, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("DSW2:7") PORT_DIPSETTING( 0x00, DEF_STR( No ) ) PORT_DIPSETTING( 0x40, DEF_STR( Yes ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:8") + PORT_DIPNAME( 0x80, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("DSW2:8") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) INPUT_PORTS_END @@ -883,48 +739,19 @@ static INPUT_PORTS_START( hotmind ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("DSW1") - PORT_DIPNAME( 0x01, 0x01, "Coin Mode" ) PORT_DIPLOCATION("SW1:1") - PORT_DIPSETTING( 0x01, "Mode 1" ) - PORT_DIPSETTING( 0x00, "Mode 2" ) - PORT_DIPNAME( 0x1e, 0x1e, "Coinage Mode 1" ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3,4,5") - PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) - PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ) ) - PORT_DIPSETTING( 0x0c, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x0e, DEF_STR( 1C_4C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x12, DEF_STR( 1C_2C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 2C_3C ) ) - PORT_DIPSETTING( 0x1e, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x06, DEF_STR( 3C_2C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 5C_3C ) ) - PORT_DIPSETTING( 0x1c, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 8C_3C ) ) - PORT_DIPSETTING( 0x1a, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x18, DEF_STR( 4C_1C ) ) - PORT_DIPSETTING( 0x16, DEF_STR( 5C_1C ) ) - PORT_DIPSETTING( 0x14, DEF_STR( 6C_1C ) ) - PORT_DIPNAME( 0x06, 0x06, "Coin A Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:2,3") - PORT_DIPSETTING( 0x06, DEF_STR( 1C_1C ) ) - PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) ) - PORT_DIPSETTING( 0x02, DEF_STR( 3C_1C ) ) - PORT_DIPSETTING( 0x00, DEF_STR( 5C_1C ) ) - PORT_DIPNAME( 0x18, 0x18, "Coin B Mode 2" ) PORT_CONDITION("DSW1", 0x01, NOTEQUALS, 0x01) PORT_DIPLOCATION("SW1:4,5") - PORT_DIPSETTING( 0x00, DEF_STR( 1C_6C ) ) - PORT_DIPSETTING( 0x08, DEF_STR( 1C_5C ) ) - PORT_DIPSETTING( 0x10, DEF_STR( 1C_3C ) ) - PORT_DIPSETTING( 0x18, DEF_STR( 1C_2C ) ) - PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW1:6") + PLAYMARK_COINS + PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) PORT_DIPLOCATION("DSW1:6") PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x40, "Time Per Line" ) PORT_DIPLOCATION("SW1:7") + PORT_DIPNAME( 0x40, 0x40, "Time Per Line" ) PORT_DIPLOCATION("DSW1:7") PORT_DIPSETTING( 0x40, "10 Seconds" ) PORT_DIPSETTING( 0x00, "5 Seconds" ) - PORT_DIPNAME( 0x80, 0x80, "Clear All Memory" ) PORT_DIPLOCATION("SW1:8") + PORT_DIPNAME( 0x80, 0x80, "Clear All Memory" ) PORT_DIPLOCATION("DSW1:8") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_START("DSW2") - PORT_DIPNAME( 0x07, 0x07, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:1,2,3") + PORT_DIPNAME( 0x07, 0x07, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("DSW2:1,2,3") PORT_DIPSETTING( 0x07, DEF_STR( Easy ) ) PORT_DIPSETTING( 0x06, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x05, DEF_STR( Hard ) ) @@ -933,17 +760,17 @@ static INPUT_PORTS_START( hotmind ) PORT_DIPSETTING( 0x02, "Very Hard 3" ) PORT_DIPSETTING( 0x01, "Very Hard 4" ) PORT_DIPSETTING( 0x00, "Very Hard 5" ) - PORT_SERVICE( 0x08, IP_ACTIVE_LOW ) PORT_DIPLOCATION("SW2:4") - PORT_DIPNAME( 0x10, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:5") + PORT_SERVICE( 0x08, IP_ACTIVE_LOW ) PORT_DIPLOCATION("DSW2:4") + PORT_DIPNAME( 0x10, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("DSW2:5") PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x00, "Erogatore Gettoni" ) PORT_DIPLOCATION("SW2:6") + PORT_DIPNAME( 0x20, 0x00, "Erogatore Gettoni" ) PORT_DIPLOCATION("DSW2:6") PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, "Erogatore Ticket" ) PORT_DIPLOCATION("SW2:7") + PORT_DIPNAME( 0x40, 0x00, "Erogatore Ticket" ) PORT_DIPLOCATION("DSW2:7") PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x80, "Clear Partial Memory" ) PORT_DIPLOCATION("SW2:8") + PORT_DIPNAME( 0x80, 0x80, "Clear Partial Memory" ) PORT_DIPLOCATION("DSW2:8") PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) INPUT_PORTS_END diff --git a/src/mame/drivers/pm68k.cpp b/src/mame/drivers/pm68k.cpp index dbea0ee4bba..aa8068c0822 100644 --- a/src/mame/drivers/pm68k.cpp +++ b/src/mame/drivers/pm68k.cpp @@ -55,11 +55,6 @@ void pm68k_state::machine_reset() m_maincpu->reset(); } -static DEVICE_INPUT_DEFAULTS_START( terminal ) - DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9615 ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9615 ) -DEVICE_INPUT_DEFAULTS_END - static MACHINE_CONFIG_START( pm68k ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M68000, 8000000) @@ -83,7 +78,6 @@ static MACHINE_CONFIG_START( pm68k ) MCFG_RS232_RXD_HANDLER(DEVWRITELINE("mpsc", i8274_new_device, rxa_w)) MCFG_RS232_DSR_HANDLER(DEVWRITELINE("mpsc", i8274_new_device, dcda_w)) MCFG_RS232_CTS_HANDLER(DEVWRITELINE("mpsc", i8274_new_device, ctsa_w)) - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) MCFG_RS232_PORT_ADD("rs232b", default_rs232_devices, nullptr) MCFG_RS232_RXD_HANDLER(DEVWRITELINE("mpsc", i8274_new_device, rxb_w)) diff --git a/src/mame/drivers/pntnpuzl.cpp b/src/mame/drivers/pntnpuzl.cpp index 0d0e3c87fab..a58618a2326 100644 --- a/src/mame/drivers/pntnpuzl.cpp +++ b/src/mame/drivers/pntnpuzl.cpp @@ -3,8 +3,7 @@ /* paint & puzzle */ /* video is standard VGA */ /* -OK, here's a somewhat complete rundown of the PCB. There was 1 IC I didn't -get a pin count of(oops). +OK, here's a somewhat complete rundown of the PCB. Main PCB Reb B @@ -38,7 +37,7 @@ U5 18 pin IC PIC16C54-HS/P 9344 CGA -U6 +U6 48 pin IC P8798 L3372718E Intel @@ -68,6 +67,8 @@ U10 64 pin IC MC68000P12 OB26M8829 +The 6522 and 8798 each have a 93C46N EEPROM attached. + X1 16.000MHz -connected to U5 @@ -124,6 +125,8 @@ CN1 standard DB15 VGA connector (15KHz) #include "emu.h" #include "cpu/m68000/m68000.h" +#include "cpu/mcs96/i8x9x.h" +#include "machine/6522via.h" #include "machine/eepromser.h" #include "video/pc_vga.h" #include "screen.h" @@ -135,10 +138,9 @@ public: pntnpuzl_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this,"maincpu"), - m_eeprom(*this, "eeprom") + m_via(*this, "via") { } - uint16_t m_eeprom_data; uint16_t m_pntpzl_200000; uint16_t m_serial; uint16_t m_serial_out; @@ -154,33 +156,11 @@ public: DECLARE_READ16_MEMBER(irq2_ack_r); DECLARE_READ16_MEMBER(irq4_ack_r); DECLARE_INPUT_CHANGED_MEMBER(coin_inserted); - DECLARE_READ16_MEMBER(pntnpuzl_eeprom_r); - DECLARE_WRITE16_MEMBER(pntnpuzl_eeprom_w); DECLARE_DRIVER_INIT(pip); - required_device<eeprom_serial_93cxx_device> m_eeprom; + required_device<via6522_device> m_via; }; -READ16_MEMBER(pntnpuzl_state::pntnpuzl_eeprom_r) -{ - /* bit 11 is EEPROM data */ - return (m_eeprom_data & 0xf4ff) | (m_eeprom->do_read()<<11) | (ioport("IN1")->read() & 0x0300); -} - -WRITE16_MEMBER(pntnpuzl_state::pntnpuzl_eeprom_w) -{ - m_eeprom_data = data; - - /* bit 12 is data */ - /* bit 13 is clock (active high) */ - /* bit 14 is cs (active high) */ - - m_eeprom->di_write((data & 0x1000) >> 12); - m_eeprom->cs_write((data & 0x4000) ? ASSERT_LINE : CLEAR_LINE); - m_eeprom->clk_write((data & 0x2000) ? ASSERT_LINE : CLEAR_LINE); -} - - /* reading works this way: @@ -224,6 +204,8 @@ WRITE16_MEMBER(pntnpuzl_state::pntnpuzl_280018_w) m_serial >>= 1; if (data & 0x2000) m_serial |= 0x400; + + m_via->write(space, 0x18/2, data >> 8); } READ16_MEMBER(pntnpuzl_state::pntnpuzl_280014_r) @@ -231,6 +213,8 @@ READ16_MEMBER(pntnpuzl_state::pntnpuzl_280014_r) static const int startup[3] = { 0x80, 0x0c, 0x00 }; int res; + (void)m_via->read(space, 0x14/2); + if (m_serial_out == 0x11) { if (ioport("IN0")->read() & 0x10) @@ -286,18 +270,10 @@ static ADDRESS_MAP_START( pntnpuzl_map, AS_PROGRAM, 16, pntnpuzl_state ) AM_RANGE(0x100000, 0x100001) AM_READ(irq2_ack_r) AM_RANGE(0x180000, 0x180001) AM_READ(irq4_ack_r) AM_RANGE(0x200000, 0x200001) AM_WRITE(pntnpuzl_200000_w) - AM_RANGE(0x280000, 0x280001) AM_READ(pntnpuzl_eeprom_r) - AM_RANGE(0x280002, 0x280003) AM_READ_PORT("IN2") - AM_RANGE(0x280000, 0x280001) AM_WRITE(pntnpuzl_eeprom_w) - AM_RANGE(0x280008, 0x280009) AM_WRITENOP - AM_RANGE(0x28000a, 0x28000b) AM_WRITENOP - AM_RANGE(0x280010, 0x280011) AM_WRITENOP - AM_RANGE(0x280012, 0x280013) AM_WRITENOP AM_RANGE(0x280014, 0x280015) AM_READ(pntnpuzl_280014_r) - AM_RANGE(0x280016, 0x280017) AM_WRITENOP AM_RANGE(0x280018, 0x280019) AM_WRITE(pntnpuzl_280018_w) AM_RANGE(0x28001a, 0x28001b) AM_READ(pntnpuzl_28001a_r) - AM_RANGE(0x28001a, 0x28001b) AM_WRITENOP + AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8("via", via6522_device, read, write, 0xff00) /* standard VGA */ AM_RANGE(0x3a0000, 0x3bffff) AM_DEVREADWRITE8("vga", vga_device, mem_r, mem_w, 0xffff) @@ -308,12 +284,16 @@ static ADDRESS_MAP_START( pntnpuzl_map, AS_PROGRAM, 16, pntnpuzl_state ) AM_RANGE(0x400000, 0x407fff) AM_RAM ADDRESS_MAP_END +static ADDRESS_MAP_START( mcu_map, AS_PROGRAM, 8, pntnpuzl_state ) + AM_RANGE(0x2000, 0x3fff) AM_ROM AM_REGION("mcu", 0) +ADDRESS_MAP_END + INPUT_CHANGED_MEMBER(pntnpuzl_state::coin_inserted) { /* TODO: change this! */ if(newval) - generic_pulse_irq_line(*m_maincpu, (uint8_t)(uintptr_t)param, 1); + m_maincpu->pulse_input_line((uint8_t)(uintptr_t)param, m_maincpu->minimum_quantum_time()); } static INPUT_PORTS_START( pntnpuzl ) @@ -332,18 +312,22 @@ static INPUT_PORTS_START( pntnpuzl ) PORT_BIT( 0x7f, 0x40, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(Y, -1.0, 0.0, 0) PORT_MINMAX(0,0x7f) PORT_SENSITIVITY(25) PORT_KEYDELTA(13) PORT_START("IN1") - PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_S) - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_A) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_S) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_A) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, do_read) + PORT_BIT( 0x70, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("IN2") - PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_B) - PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_V) - PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_C) - PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_X) - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_Z) - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_G) - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_F) - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_D) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_B) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_V) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_C) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_X) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_Z) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_G) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_F) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_CODE(KEYCODE_D) INPUT_PORTS_END static MACHINE_CONFIG_START( pntnpuzl ) @@ -352,6 +336,16 @@ static MACHINE_CONFIG_START( pntnpuzl ) MCFG_EEPROM_SERIAL_93C46_ADD("eeprom") + MCFG_DEVICE_ADD("via", VIA6522, 1200000) // ?? + MCFG_VIA6522_READPA_HANDLER(IOPORT("IN2")) + MCFG_VIA6522_READPB_HANDLER(IOPORT("IN1")) + MCFG_VIA6522_WRITEPB_HANDLER(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, di_write)) MCFG_DEVCB_BIT(4) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, cs_write)) MCFG_DEVCB_BIT(6) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("eeprom", eeprom_serial_93cxx_device, clk_write)) MCFG_DEVCB_BIT(5) + + MCFG_CPU_ADD("mcu", P8098, 12000000) // ?? + MCFG_CPU_PROGRAM_MAP(mcu_map) // FIXME: this is all internal + /* video hardware */ MCFG_FRAGMENT_ADD( pcvideo_vga ) MACHINE_CONFIG_END @@ -361,6 +355,9 @@ ROM_START( pntnpuzl ) ROM_LOAD16_BYTE( "pntnpuzl.u2", 0x00001, 0x40000, CRC(dfda3f73) SHA1(cca8ccdd501a26cba07365b1238d7b434559bbc6) ) ROM_LOAD16_BYTE( "pntnpuzl.u3", 0x00000, 0x40000, CRC(4173f250) SHA1(516fe6f91b925f71c36b97532608b82e63bda436) ) + ROM_REGION( 0x2000, "mcu", 0 ) + ROM_LOAD( "pntnpzl8798.bin", 0x0000, 0x2000, CRC(3ff98e89) SHA1(c48665992cb5377b69902f2a352c9214602a0b84) ) + /* for reference, probably not used in any way by the game */ ROM_REGION( 0x10000, "video_bios", 0 ) ROM_LOAD( "trident_quadtel_tvga9000_isa16.bin", 0x0000, 0x10000, BAD_DUMP CRC(ad0e7351) SHA1(eb525460a80e1c1baa34642b93d54caf2607920d) ) diff --git a/src/mame/drivers/polgar.cpp b/src/mame/drivers/polgar.cpp index 44fccd3fdfb..e1e2c4d1a72 100644 --- a/src/mame/drivers/polgar.cpp +++ b/src/mame/drivers/polgar.cpp @@ -12,6 +12,7 @@ #include "cpu/arm/arm.h" #include "machine/nvram.h" #include "machine/mmboard.h" +#include "machine/ram.h" #include "machine/timer.h" #include "video/hd44780.h" #include "screen.h" @@ -45,6 +46,7 @@ public: : mephisto_polgar_state(mconfig, type, tag) , m_subcpu(*this, "subcpu") , m_rombank(*this, "rombank") + , m_ram(*this, "ram") { } DECLARE_WRITE8_MEMBER(bank_w); @@ -52,26 +54,22 @@ public: DECLARE_WRITE8_MEMBER(latch0_w); DECLARE_WRITE8_MEMBER(latch1_w); DECLARE_READ8_MEMBER(latch1_r); + DECLARE_READ32_MEMBER(disable_boot_rom_r); protected: virtual void machine_start() override; virtual void machine_reset() override; + void remove_boot_rom(); + TIMER_CALLBACK_MEMBER(disable_boot_rom); private: required_device<arm_cpu_device> m_subcpu; required_memory_bank m_rombank; + required_device<ram_device> m_ram; uint8_t m_bank; uint8_t m_com_latch0; uint8_t m_com_latch1; - - // ARM bootstrap HLE - void arm_bootstrap(uint8_t data); - TIMER_CALLBACK_MEMBER(clean_com_flag) { m_com_latch0 &= ~0x01; } - - emu_timer* m_arm_bootstrap_timer; - uint16_t m_com_offset; - uint8_t m_com_bits; - uint8_t m_com_data; + emu_timer* m_disable_boot_rom_timer; }; class mephisto_milano_state : public mephisto_polgar_state @@ -183,41 +181,8 @@ WRITE8_MEMBER(mephisto_risc_state::bank_w) m_rombank->set_entry(m_bank); } -void mephisto_risc_state::arm_bootstrap(uint8_t data) -{ - if (data & 0x02) - { - m_subcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - m_com_offset = 0; - } - - if (m_com_offset < 0x100 && ((m_com_latch1 ^ data) & 0x80)) - { - m_com_data |= (data & 1) << (7-m_com_bits); - m_com_bits++; - - if (m_com_bits == 8) - { - m_subcpu->space(AS_PROGRAM).write_byte(m_com_offset, m_com_data); - m_com_bits = 0; - m_com_data = 0; - m_com_offset++; - - if (m_com_offset == 0x100) - m_subcpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); - } - - if (m_com_offset < 0x100) - { - m_com_latch0 |= 0x01; - m_arm_bootstrap_timer->adjust(attotime::from_usec(15)); - } - } -} - WRITE8_MEMBER(mephisto_risc_state::latch1_w) { - arm_bootstrap(data); m_com_latch1 = data; m_subcpu->set_input_line(ARM_FIRQ_LINE, ASSERT_LINE); } @@ -239,6 +204,23 @@ READ8_MEMBER(mephisto_risc_state::latch0_r) return m_com_latch0; } +READ32_MEMBER(mephisto_risc_state::disable_boot_rom_r) +{ + m_disable_boot_rom_timer->adjust(m_subcpu->cycles_to_attotime(10)); + return space.unmap(); +} + +void mephisto_risc_state::remove_boot_rom() +{ + m_subcpu->space(AS_PROGRAM).install_ram(0x00000000, m_ram->size() - 1, m_ram->pointer()); +} + + +TIMER_CALLBACK_MEMBER(mephisto_risc_state::disable_boot_rom) +{ + remove_boot_rom(); +} + static ADDRESS_MAP_START(mrisc_mem, AS_PROGRAM, 8, mephisto_risc_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0x1fff ) AM_RAM AM_SHARE("nvram") @@ -252,6 +234,7 @@ static ADDRESS_MAP_START(mrisc_mem, AS_PROGRAM, 8, mephisto_risc_state) AM_RANGE( 0x3406, 0x3407 ) AM_WRITE(bank_w) AM_RANGE( 0x3800, 0x3800 ) AM_WRITE(latch1_w) AM_RANGE( 0x3c00, 0x3c00 ) AM_READ(latch0_r) + AM_RANGE( 0x4000, 0x7fff ) AM_ROM AM_RANGE( 0x8000, 0xffff ) AM_ROMBANK("rombank") ADDRESS_MAP_END @@ -259,6 +242,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(mrisc_arm_mem, AS_PROGRAM, 32, mephisto_risc_state) AM_RANGE( 0x00000000, 0x000fffff ) AM_RAM AM_RANGE( 0x00400000, 0x007fffff ) AM_READWRITE8(latch1_r, latch0_w, 0x000000ff) + AM_RANGE( 0x01800000, 0x01800003 ) AM_READ(disable_boot_rom_r) ADDRESS_MAP_END @@ -424,15 +408,14 @@ INPUT_PORTS_END void mephisto_risc_state::machine_start() { - m_arm_bootstrap_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mephisto_risc_state::clean_com_flag), this)); + m_disable_boot_rom_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mephisto_risc_state::disable_boot_rom), this)); m_rombank->configure_entries(0, 4, memregion("maincpu")->base(), 0x8000); save_item(NAME(m_bank)); save_item(NAME(m_com_latch0)); save_item(NAME(m_com_latch1)); - save_item(NAME(m_com_offset)); - save_item(NAME(m_com_bits)); - save_item(NAME(m_com_data)); + + machine().save().register_postload(save_prepost_delegate(FUNC(mephisto_risc_state::remove_boot_rom), this)); } void mephisto_risc_state::machine_reset() @@ -441,12 +424,10 @@ void mephisto_risc_state::machine_reset() m_com_latch0 = 0; m_com_latch1 = 0; m_rombank->set_entry(m_bank); + m_subcpu->space(AS_PROGRAM).install_ram(0x00, m_ram->size() - 1, m_ram->pointer()); - // ARM bootstrap HLE - m_com_offset = 0; - m_com_bits = 0; - m_com_data = 0; - m_subcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + // ARM bootstrap code + m_subcpu->space(AS_PROGRAM).install_rom(0x00000000, 0x0000007f, memregion("arm_bootstrap")->base()); } void mephisto_milano_state::machine_start() @@ -506,6 +487,9 @@ static MACHINE_CONFIG_START( mrisc ) MCFG_NVRAM_ADD_0FILL("nvram") + MCFG_RAM_ADD("ram") + MCFG_RAM_DEFAULT_SIZE("1M") + MCFG_MEPHISTO_SENSORS_BOARD_ADD("board") MCFG_MEPHISTO_DISPLAY_MODUL_ADD("display") MCFG_DEFAULT_LAYOUT(layout_mephisto_lcd) @@ -564,22 +548,22 @@ ROM_START(mrisc) ROM_REGION(0x20000, "maincpu", 0) ROM_LOAD("Meph-RiscI-V1-2.bin", 0x00000, 0x20000, CRC(19c6ab83) SHA1(0baab84e5aa6999c24250938d207145144945fd5)) - ROM_REGION(0x80, "arm_bootstrap", 0) - ROM_LOAD32_BYTE( "74s288.1", 0x00, 0x20, NO_DUMP ) - ROM_LOAD32_BYTE( "74s288.2", 0x01, 0x20, NO_DUMP ) - ROM_LOAD32_BYTE( "74s288.3", 0x02, 0x20, NO_DUMP ) - ROM_LOAD32_BYTE( "74s288.4", 0x03, 0x20, NO_DUMP ) + ROM_REGION32_LE(0x80, "arm_bootstrap", 0) + ROM_LOAD32_BYTE( "74s288.1", 0x00, 0x20, CRC(284114e2) SHA1(df4037536d505d7240bb1d70dc58f59a34ab77b4) ) + ROM_LOAD32_BYTE( "74s288.2", 0x01, 0x20, CRC(9f239c75) SHA1(aafaf30dac90f36b01f9ee89903649fc4ea0480d) ) + ROM_LOAD32_BYTE( "74s288.3", 0x02, 0x20, CRC(0455360b) SHA1(f1486142330f2c39a4d6c479646030d31443d1c8) ) + ROM_LOAD32_BYTE( "74s288.4", 0x03, 0x20, CRC(c7c9aba8) SHA1(cbb5b12b5917e36679d45bcbc36ea9285223a75d) ) ROM_END ROM_START(mrisc2) ROM_REGION(0x20000, "maincpu", 0) ROM_LOAD("Meph-RiscII-V2.bin", 0x00000, 0x20000, CRC(9ecf9cd3) SHA1(7bfc628183037a172242c9589f15aca218d8fb12)) - ROM_REGION(0x80, "arm_bootstrap", 0) - ROM_LOAD32_BYTE( "74s288.1", 0x00, 0x20, NO_DUMP ) - ROM_LOAD32_BYTE( "74s288.2", 0x01, 0x20, NO_DUMP ) - ROM_LOAD32_BYTE( "74s288.3", 0x02, 0x20, NO_DUMP ) - ROM_LOAD32_BYTE( "74s288.4", 0x03, 0x20, NO_DUMP ) + ROM_REGION32_LE(0x80, "arm_bootstrap", 0) + ROM_LOAD32_BYTE( "74s288.1", 0x00, 0x20, CRC(284114e2) SHA1(df4037536d505d7240bb1d70dc58f59a34ab77b4) ) + ROM_LOAD32_BYTE( "74s288.2", 0x01, 0x20, CRC(9f239c75) SHA1(aafaf30dac90f36b01f9ee89903649fc4ea0480d) ) + ROM_LOAD32_BYTE( "74s288.3", 0x02, 0x20, CRC(0455360b) SHA1(f1486142330f2c39a4d6c479646030d31443d1c8) ) + ROM_LOAD32_BYTE( "74s288.4", 0x03, 0x20, CRC(c7c9aba8) SHA1(cbb5b12b5917e36679d45bcbc36ea9285223a75d) ) ROM_END ROM_START(academy) @@ -624,8 +608,8 @@ ROM_END /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ CONS( 1989, polgar, 0, 0, polgar, polgar, mephisto_polgar_state, 0, "Hegener & Glaser", "Mephisto Polgar", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) CONS( 1990, polgar10, polgar, 0, polgar10, polgar, mephisto_polgar_state, 0, "Hegener & Glaser", "Mephisto Polgar 10MHz", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) -CONS( 1992, mrisc, 0, 0, mrisc, polgar, mephisto_risc_state, 0, "Hegener & Glaser", "Mephisto RISC 1MB", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) -CONS( 1994, mrisc2, mrisc, 0, mrisc, polgar, mephisto_risc_state, 0, "Hegener & Glaser", "Mephisto RISC II", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) +CONS( 1992, mrisc, 0, 0, mrisc, polgar, mephisto_risc_state, 0, "Hegener & Glaser", "Mephisto RISC 1MB", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) +CONS( 1994, mrisc2, mrisc, 0, mrisc, polgar, mephisto_risc_state, 0, "Hegener & Glaser", "Mephisto RISC II", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) // not modular boards CONS( 1989, academy, 0, 0, academy, polgar, mephisto_academy_state, 0, "Hegener & Glaser", "Mephisto Academy", MACHINE_SUPPORTS_SAVE | MACHINE_CLICKABLE_ARTWORK ) diff --git a/src/mame/drivers/poly.cpp b/src/mame/drivers/poly.cpp index 51e62ddeb7c..eed42548906 100644 --- a/src/mame/drivers/poly.cpp +++ b/src/mame/drivers/poly.cpp @@ -86,8 +86,7 @@ static ADDRESS_MAP_START(poly_mem, AS_PROGRAM, 8, poly_state) AM_RANGE(0xa000,0xcfff) AM_ROM AM_RANGE(0xd000,0xdfff) AM_RAM AM_RANGE(0xe000,0xe003) AM_DEVREADWRITE("pia0", pia6821_device, read, write) //video control PIA 6821 - AM_RANGE(0xe004,0xe004) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0xe005,0xe005) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0xe004,0xe005) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0xe006,0xe006) AM_WRITE(baud_rate_w) AM_RANGE(0xe00c,0xe00f) AM_DEVREADWRITE("pia1", pia6821_device, read, write) //keyboard PIA 6821 AM_RANGE(0xe020,0xe027) AM_DEVREADWRITE("ptm", ptm6840_device, read, write) //timer 6840 diff --git a/src/mame/drivers/poly88.cpp b/src/mame/drivers/poly88.cpp index 6b366ed38d4..af60dced0a5 100644 --- a/src/mame/drivers/poly88.cpp +++ b/src/mame/drivers/poly88.cpp @@ -15,14 +15,25 @@ Poly-8813 is a disk-based computer with 3 mini-floppy drives. Booting is done by pressing the "Load" button, mounted on the front panel near the power switch. Although user manuals are easy - to obtain, technical information and schematics are not. The bios - makes use of illegal instructions which we do not correctly emulate. - The first of these is at 0x006A (print a character routine), while - the other is at 0x0100 (an internal copy routine). The code at 0x100 - can be replaced by 7E 12 13 23 03 79 B0 C2 00 01 C9, which exactly - fits into the available space. The disk format is known to be - 256 bytes per sector, 10 sectors per track, 35 tracks, single sided, - for a total of 89600 bytes. + to obtain, technical information and drive controller schematics + are not. The disk format is known to be 256 bytes per sector, 10 + sectors per track, 35 tracks, single sided, for a total of 89600 + bytes. + + The Poly-8813 BIOS makes use of undocumented instructions which we + do not currently emulate. These are at 006A (print a character + routine - ED ED 05); another is at 0100 (move memory routine - + ED ED 03); the last is at 087B (disk I/O routine - ED ED 01). The + code at 0100 can be replaced by 7E 12 13 23 03 79 B0 C2 00 01 C9, + which exactly fits into the available space. The routine at 006A is + likewise could be exactly replaced with F5 C5 D5 E5, which enters + a display routine that appears in other assembly listings but seems + to have no entry point here. Since the ED ED opcode is defined as + for CALLN in the NEC V20/V30's 8080 mode, it might be the case that + these are actually hooks patched into the original code for + emulation purposes. (There is also a slim possibility that this + opcode invokes an undocumented feature of the NEC uPD8080AF, which + at least some models of the Poly-88 are known to have used.) ****************************************************************************/ @@ -30,6 +41,7 @@ #include "includes/poly88.h" #include "cpu/i8085/i8085.h" +//#include "bus/s100/s100.h" #include "imagedev/cassette.h" #include "sound/wave.h" #include "screen.h" diff --git a/src/mame/drivers/popeye.cpp b/src/mame/drivers/popeye.cpp index a97fe11d9ab..7b1acd6a166 100644 --- a/src/mame/drivers/popeye.cpp +++ b/src/mame/drivers/popeye.cpp @@ -162,6 +162,7 @@ WRITE8_MEMBER(popeye_state::protection_w) static ADDRESS_MAP_START( skyskipr_map, AS_PROGRAM, 8, popeye_state ) AM_RANGE(0x0000, 0x7fff) AM_ROM AM_RANGE(0x8000, 0x87ff) AM_RAM + //AM_RANGE(0x8800, 0x8bff) AM_RAM // Attempts to initialize this area with 00 on boot AM_RANGE(0x8c00, 0x8c02) AM_RAM AM_SHARE("background_pos") AM_RANGE(0x8c03, 0x8c03) AM_RAM AM_SHARE("palettebank") AM_RANGE(0x8c04, 0x8e7f) AM_RAM AM_SHARE("spriteram") @@ -247,7 +248,7 @@ static INPUT_PORTS_START( skyskipr ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_START("DSW0") /* DSW0 */ - PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coinage ) ) + PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW1:1,2,3,4") PORT_DIPSETTING( 0x03, "A 3/1 B 1/2" ) PORT_DIPSETTING( 0x0e, DEF_STR( 2C_1C ) ) PORT_DIPSETTING( 0x01, "A 2/1 B 2/5" ) @@ -264,37 +265,29 @@ static INPUT_PORTS_START( skyskipr ) PORT_DIPSETTING( 0x05, "A 1/5 B 1/1" ) PORT_DIPSETTING( 0x08, "A 1/6 B 1/1" ) PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) - PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_BIT( 0x70, IP_ACTIVE_LOW, IPT_UNUSED) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(DEVICE_SELF, popeye_state, dsw1_read, nullptr) PORT_START("DSW1") /* DSW1 */ - PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) ) + PORT_DIPNAME( 0x03, 0x01, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:1,2") PORT_DIPSETTING( 0x03, "1" ) PORT_DIPSETTING( 0x02, "2" ) PORT_DIPSETTING( 0x01, "3" ) PORT_DIPSETTING( 0x00, "4" ) - PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:3") PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:4") PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:5") PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x20, DEF_STR( Bonus_Life ) ) + PORT_DIPNAME( 0x20, 0x20, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:6") PORT_DIPSETTING( 0x20, "15000" ) PORT_DIPSETTING( 0x00, "30000" ) - PORT_SERVICE( 0x40, IP_ACTIVE_LOW ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Cabinet ) ) + PORT_SERVICE_DIPLOC( 0x40, IP_ACTIVE_LOW, "SW2:7" ) + PORT_DIPNAME( 0x80, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW2:8") PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) PORT_DIPSETTING( 0x80, DEF_STR( Cocktail ) ) INPUT_PORTS_END diff --git a/src/mame/drivers/powerstack.cpp b/src/mame/drivers/powerstack.cpp index b09a206a57a..c565df94322 100644 --- a/src/mame/drivers/powerstack.cpp +++ b/src/mame/drivers/powerstack.cpp @@ -4,36 +4,39 @@ 2017-10-29 Skeleton -Motorola Powerstack II. CPU is a RISC-type. +Motorola Powerstack II. CPU is a PowerPC 604e @ 300MHz. ************************************************************************************************************************************/ #include "emu.h" -//#include "cpu/mcs51/mcs51.h" +#include "cpu/powerpc/ppc.h" class powerstack_state : public driver_device { public: powerstack_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) -// , maincpu(*this, "maincpu") +// , m_maincpu(*this, "maincpu") { } -protected: -// required_device<i80c52_device> maincpu; +private: +// required_device<cpu_device> m_maincpu; }; +//static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 64, powerstack_state ) +// AM_RANGE(0xFFF80000, 0xFFFFFFFF) AM_ROM AM_REGION("roms", 0) +//ADDRESS_MAP_END + static INPUT_PORTS_START( powerstack ) INPUT_PORTS_END -//static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, powerstack_state ) -//ADDRESS_MAP_END - static MACHINE_CONFIG_START( powerstack ) +// MCFG_CPU_ADD("maincpu", PPC604, 300'000'000) // PPC604E @ 300MHz +// MCFG_CPU_PROGRAM_MAP(mem_map) MACHINE_CONFIG_END ROM_START( powerstk ) - ROM_REGION( 0x80000, "maincpu", 0 ) + ROM_REGION( 0x80000, "roms", 0 ) ROM_LOAD( "motorola_powerstack2.bin", 0x0000, 0x80000, CRC(948e8fcd) SHA1(9a8c32b621c98bc33ee525f66747c34d39851685) ) ROM_END diff --git a/src/mame/drivers/proconn.cpp b/src/mame/drivers/proconn.cpp index b8d37ebb0e3..dc5131cbed5 100644 --- a/src/mame/drivers/proconn.cpp +++ b/src/mame/drivers/proconn.cpp @@ -30,7 +30,7 @@ #include "machine/meters.h" #include "machine/roc10937.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80pio.h" #include "sound/ay8910.h" #include "video/awpvid.h" @@ -190,7 +190,7 @@ protected: required_device<z80pio_device> m_z80pio_4; required_device<z80pio_device> m_z80pio_5; required_device<z80ctc_device> m_z80ctc; - required_device<z80dart_device> m_z80sio; + required_device<z80sio_device> m_z80sio; required_device<ay8910_device> m_ay; required_device<meters_device> m_meters; @@ -373,7 +373,7 @@ static MACHINE_CONFIG_START( proconn ) MCFG_DEVICE_ADD("z80ctc", Z80CTC, 4000000) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("z80sio", Z80SIO0, 4000000) /* ?? Mhz */ + MCFG_DEVICE_ADD("z80sio", Z80SIO, 4000000) /* ?? Mhz */ MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") diff --git a/src/mame/drivers/prophet600.cpp b/src/mame/drivers/prophet600.cpp index a03acd14202..6eb4f7f888c 100644 --- a/src/mame/drivers/prophet600.cpp +++ b/src/mame/drivers/prophet600.cpp @@ -241,10 +241,8 @@ static ADDRESS_MAP_START( cpu_map, AS_PROGRAM, 8, prophet600_state ) AM_RANGE(0x2000, 0x27ff) AM_RAM AM_RANGE(0x3000, 0x37ff) AM_RAM AM_RANGE(0x4000, 0x4001) AM_WRITE(dac_w) - AM_RANGE(0x6000, 0x6000) AM_DEVWRITE(UART_TAG, acia6850_device, control_w) - AM_RANGE(0x6001, 0x6001) AM_DEVWRITE(UART_TAG, acia6850_device, data_w) - AM_RANGE(0xe000, 0xe000) AM_DEVREAD(UART_TAG, acia6850_device, status_r) - AM_RANGE(0xe001, 0xe001) AM_DEVREAD(UART_TAG, acia6850_device, data_r) + AM_RANGE(0x6000, 0x6001) AM_DEVWRITE(UART_TAG, acia6850_device, write) + AM_RANGE(0xe000, 0xe001) AM_DEVREAD(UART_TAG, acia6850_device, read) ADDRESS_MAP_END static ADDRESS_MAP_START( io_map, AS_IO, 8, prophet600_state ) diff --git a/src/mame/drivers/proteus3.cpp b/src/mame/drivers/proteus3.cpp index 346553ac360..99caab87a81 100644 --- a/src/mame/drivers/proteus3.cpp +++ b/src/mame/drivers/proteus3.cpp @@ -138,10 +138,8 @@ static ADDRESS_MAP_START(proteus3_mem, AS_PROGRAM, 8, proteus3_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x7fff) AM_RAM AM_RANGE(0x8004, 0x8007) AM_DEVREADWRITE("pia", pia6821_device, read, write) - AM_RANGE(0x8008, 0x8008) AM_DEVREADWRITE("acia1", acia6850_device, status_r, control_w) // cassette - AM_RANGE(0x8009, 0x8009) AM_DEVREADWRITE("acia1", acia6850_device, data_r, data_w) - AM_RANGE(0x8010, 0x8010) AM_DEVREADWRITE("acia2", acia6850_device, status_r, control_w) // serial keyboard - AM_RANGE(0x8011, 0x8011) AM_DEVREADWRITE("acia2", acia6850_device, data_r, data_w) // never writes data + AM_RANGE(0x8008, 0x8009) AM_DEVREADWRITE("acia1", acia6850_device, read, write) // cassette + AM_RANGE(0x8010, 0x8011) AM_DEVREADWRITE("acia2", acia6850_device, read, write) // serial keyboard (never writes data) AM_RANGE(0xc000, 0xffff) AM_ROM ADDRESS_MAP_END diff --git a/src/mame/drivers/ps2sony.cpp b/src/mame/drivers/ps2sony.cpp new file mode 100644 index 00000000000..0a94dc03084 --- /dev/null +++ b/src/mame/drivers/ps2sony.cpp @@ -0,0 +1,338 @@ +// license:BSD-3-Clause +// copyright-holders: +/********************************************************************************************************************** + +2017-11-05 Skeleton PLACEHOLDER ONLY. + +Sony PlayStation 2. + +Related to: Konami Bemani/Python, Namco Systems 147, 246, 256 (info from system16.com). See namecops2.cpp for details. + +Technical specs: https://en.wikipedia.org/wiki/PlayStation_2_technical_specifications + +If development proceeds, it may be prudent to make this and namcops2.cpp derived classes of a common class. + +**********************************************************************************************************************/ +// the skeleton memory map and config was copied from namcops2.cpp +/********************************************************************************************************************* +Contents of INF files: + +SCPH-75008_BIOS_V14_RUS_220.INF +[EE] +CPUrev=0x2E42 +FPUrev=0x2E40 +BOARDid=0xFFFF +VU0MEMsize=4KB;4KB (*) +VU1MEMsize=16KB;16KB (*) +GSrev=0x551C +GSMEMsize=4MB (*) +ICache=16KB +Dcache=8KB +MEMsize=32MB + +[IOP] +CPUrev=0x0030 +ICache=4KB (*) +Dcache=1KB (*) +MEMsize=2MB +BOARDinf=0xFF +SPU2rev=0x08 +SPU2MEMsize=2M (*) +CDVDmecha=0x05060600 +CDVDmeka=0x00 +DEV9rev=0x0031 +SPDrev=0x13 (unknown) +SPDcaps=0x03 (eth+ata) +SPDmac=00:15:C1:6B:6D:AB +USBhcrev=0x00000010 +iLinkports=2 +iLinkspeed=400 +iLinkvendor=0x------ +iLinkdevice=0x------ +iLinkSGUID=0x-------- + +SCPH-77004_BIOS_V15_EUR_220.INF +[EE] +CPUrev=0x2E42 +FPUrev=0x2E40 +BOARDid=0xFFFF +VU0MEMsize=4KB;4KB (*) +VU1MEMsize=16KB;16KB (*) +GSrev=0x551D +GSMEMsize=4MB (*) +ICache=16KB +Dcache=8KB +MEMsize=32MB + +[IOP] +CPUrev=0x0030 +ICache=4KB (*) +Dcache=1KB (*) +MEMsize=2MB +BOARDinf=0xFF +SPU2rev=0x08 +SPU2MEMsize=2M (*) +CDVDmecha=0x02060A00 +CDVDmeka=0x00 +DEV9rev=0x0031 +SPDrev=0x13 (unknown) +SPDcaps=0x03 (eth+ata) +SPDmac=00:15:C1:BB:55:F3 +USBhcrev=0x00000010 +iLinkports=2 +iLinkspeed=400 +iLinkvendor=0x------ +iLinkdevice=0x------ +iLinkSGUID=0x-------- + +SCPH-77008_BIOS_V15_RUS_220.INF +[EE] +CPUrev=0x2E42 +FPUrev=0x2E40 +BOARDid=0xFFFF +VU0MEMsize=4KB;4KB (*) +VU1MEMsize=16KB;16KB (*) +GSrev=0x551C +GSMEMsize=4MB (*) +ICache=16KB +Dcache=8KB +MEMsize=32MB + +[IOP] +CPUrev=0x0030 +ICache=4KB (*) +Dcache=1KB (*) +MEMsize=2MB +BOARDinf=0xFF +SPU2rev=0x08 +SPU2MEMsize=2M (*) +CDVDmecha=0x05060A00 +CDVDmeka=0x00 +DEV9rev=0x0031 +SPDrev=0x13 (unknown) +SPDcaps=0x03 (eth+ata) +SPDmac=00:1D:0D:4D:EF:AB +USBhcrev=0x00000010 +iLinkports=2 +iLinkspeed=400 +iLinkvendor=0x------ +iLinkdevice=0x------ +iLinkSGUID=0x-------- + +SCPH-90001_BIOS_V18_USA_230.INF +[EE] +CPUrev=0x2E43 +FPUrev=0x2E40 +BOARDid=0xFFFF +VU0MEMsize=4KB;4KB (*) +VU1MEMsize=16KB;16KB (*) +GSrev=0x551F +GSMEMsize=4MB (*) +ICache=16KB +Dcache=8KB +MEMsize=32MB + +[IOP] +CPUrev=0x0030 +ICache=4KB (*) +Dcache=1KB (*) +MEMsize=2MB +BOARDinf=0xFF +SPU2rev=0x08 +SPU2MEMsize=2M (*) +CDVDmecha=0x01060C00 +CDVDmeka=0x00 +DEV9rev=0x0031 +SPDrev=0x13 (unknown) +SPDcaps=0x03 (eth+ata) +SPDmac=00:1F:A7:BF:4D:AB +USBhcrev=0x00000010 +iLinkports=2 +iLinkspeed=400 +iLinkvendor=0x------ +iLinkdevice=0x------ +iLinkSGUID=0x-------- + +(*) values are not detected +************************************************************************************************************************/ +#include "emu.h" +#include "cpu/mips/mips3.h" +#include "cpu/mips/r3000.h" +#include "screen.h" + + +class ps2sony_state : public driver_device +{ +public: + ps2sony_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { } + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + +private: + virtual void video_start() override; + required_device<cpu_device> m_maincpu; +}; + + +void ps2sony_state::video_start() +{ +} + +uint32_t ps2sony_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + return 0; +} + +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 32, ps2sony_state) + AM_RANGE(0x00000000, 0x01ffffff) AM_RAM // 32 MB RAM + AM_RANGE(0x1fc00000, 0x1fdfffff) AM_ROM AM_REGION("bios", 0) +ADDRESS_MAP_END + +static INPUT_PORTS_START( ps2sony ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( ps2sony ) + MCFG_CPU_ADD("maincpu", R5000LE, 294'912'000) // actually R5900 + MCFG_MIPS3_ICACHE_SIZE(16384) + MCFG_MIPS3_DCACHE_SIZE(16384) + MCFG_CPU_PROGRAM_MAP(mem_map) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_UPDATE_DRIVER(ps2sony_state, screen_update) + MCFG_SCREEN_SIZE(640, 480) + MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 479) + + MCFG_PALETTE_ADD("palette", 65536) +MACHINE_CONFIG_END + + +ROM_START( ps2 ) + // These came from the redump.org "Sony - PlayStation 2 - BIOS Datfile" (version 2017-10-26) + ROM_REGION(0x400000, "bios", 0) + ROM_DEFAULT_BIOS( "scph90002_e" ) + ROM_SYSTEM_BIOS( 0, "scph10000_t", "SCPH-10000 (Version 5.0 01/17/00 T)" ) + ROMX_LOAD( "ps2-0100j-20000117.bin", 0x0000, 0x400000, CRC(b7ef81a9) SHA1(aea061e6e263fdcc1c4fdbd68553ef78dae74263), ROM_BIOS(0) ) + ROM_SYSTEM_BIOS( 1, "dtlh10000_t_old", "DTL-H10000 (Version 5.0 02/17/00 T)" ) + ROMX_LOAD( "ps2-0101jd-20000217.bin", 0x0000, 0x400000, CRC(4f8b4205) SHA1(16f4a284d0e760ee13a2aff2f7dda928255e3080), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 2, "scph1000015000_t", "SCPH-10000/SCPH-15000 (Version 5.0 02/17/00 T)" ) + ROMX_LOAD( "ps2-0101j-20000217.bin", 0x0000, 0x400000, CRC(211dfb6a) SHA1(916e02431bcd73140504da3355c9598143b77e11), ROM_BIOS(2) ) + ROM_SYSTEM_BIOS( 3, "dtlh10000_t", "DTL-H10000 (Version 5.0 02/24/00 T)" ) + ROMX_LOAD( "ps2-0101xd-20000224.bin", 0x0000, 0x400000, CRC(2fef9faf) SHA1(4440b246bfde7bb31002c584a76c6ef384908e84), ROM_BIOS(3) ) + ROM_SYSTEM_BIOS( 4, "dtlh30001_a", "DTL-H30001 (Version 5.0 07/27/00 A)" ) + ROMX_LOAD( "ps2-0110ad-20000727.bin", 0x0000, 0x400000, CRC(795578c1) SHA1(339c646cf0699268552df5b05f18f0a03a9f55ff), ROM_BIOS(4) ) + ROM_SYSTEM_BIOS( 5, "scph30001_a_old", "SCPH-30001 (Version 5.0 07/27/00 A)" ) + ROMX_LOAD( "ps2-0110a-20000727.bin", 0x0000, 0x400000, CRC(9678ad6a) SHA1(20f6ce6693cf97e9494f8f0227f2b7988ffaf961), ROM_BIOS(5) ) + ROM_SYSTEM_BIOS( 6, "scph30001_a", "SCPH-30001 (Version 5.0 09/02/00 A)" ) + ROMX_LOAD( "ps2-0120a-20000902.bin", 0x0000, 0x400000, CRC(1ae71e5d) SHA1(dbc2318a1029347b5af3a0c74b0bdf88d19efee6), ROM_BIOS(6) ) + ROM_SYSTEM_BIOS( 7, "dtlh30002_e", "DTL-H30002 (Version 5.0 09/02/00 E)" ) + ROMX_LOAD( "ps2-0120ed-20000902.bin", 0x0000, 0x400000, CRC(25495aa7) SHA1(3bb1eecd618ab5c973c7bc53671a4475a02e1d5b), ROM_BIOS(7) ) + ROM_SYSTEM_BIOS( 8, "scph30002_e_old", "SCPH-30002/SCPH-30003/SCPH-30004 (Version 5.0 09/02/00 E)" ) + ROMX_LOAD( "ps2-0120e-20000902.bin", 0x0000, 0x400000, CRC(7b08c33b) SHA1(274c05fec654913a3f698d4b0d592085866a2cbd), ROM_BIOS(8) ) + ROM_SYSTEM_BIOS( 9, "scph18000_3_j", "SCPH-18000 (GH-003) (Version 5.0 10/27/00 J)" ) + ROMX_LOAD( "ps2-0120j-20001027-185015.bin", 0x0000, 0x400000, CRC(9b096622) SHA1(e481079eca752225555f0c26d14c9d0f94d9a8e9), ROM_BIOS(9) ) + ROM_SYSTEM_BIOS( 10, "scph18000_8_j", "SCPH-18000 (GH-008) (Version 5.0 10/27/00 J)" ) + ROMX_LOAD( "ps2-0120j-20001027-191435.bin", 0x0000, 0x400000, CRC(c1ccf3f6) SHA1(a9f5d8ed56cfff18add1b599010493461fa02448), ROM_BIOS(10) ) + ROM_SYSTEM_BIOS( 11, "dtlh30101_a", "DTL-H30101 (Version 5.0 12/28/00 A)" ) + ROMX_LOAD( "ps2-0150ad-20001228.bin", 0x0000, 0x400000, CRC(0380c2ce) SHA1(7284b9d16df9935afc384318e024c87ef0574fe5), ROM_BIOS(11) ) + ROM_SYSTEM_BIOS( 12, "scph30_a", "SCPH-30001/SCPH-35001 (Version 5.0 12/28/00 A)" ) + ROMX_LOAD( "ps2-0150a-20001228.bin", 0x0000, 0x400000, CRC(bce74746) SHA1(5af5b5077d84a9c037ebe12bfab8a38b31d8a543), ROM_BIOS(12) ) + ROM_SYSTEM_BIOS( 13, "scph30002_e", "SCPH-30002/SCPH-30003/SCPH-30004/SCHP-35002/SCPH-35003/SCPH-35004 (Version 5.0 12/28/00 E)" ) + ROMX_LOAD( "ps2-0150e-20001228.bin", 0x0000, 0x400000, CRC(1559fd43) SHA1(e22ef231faf3661edd92f2ee449a71297c82a092), ROM_BIOS(13) ) + ROM_SYSTEM_BIOS( 14, "dtlh30000_j", "DTL-H30000 (Version 5.0 01/18/01 J)" ) + ROMX_LOAD( "ps2-0150jd-20010118.bin", 0x0000, 0x400000, CRC(0b3ec2bc) SHA1(334e029fc7fd50222a399c50384ff42732652259), ROM_BIOS(14) ) + ROM_SYSTEM_BIOS( 15, "scph30000_j_old", "SCPH-30000 (Version 5.0 01/18/01 J)" ) + ROMX_LOAD( "ps2-0150j-20010118.bin", 0x0000, 0x400000, CRC(4fc3b495) SHA1(d6f365a0f07cd04ed28108e6ec5076e2f81e5f72), ROM_BIOS(15) ) + ROM_SYSTEM_BIOS( 16, "scph30001r_a_b", "SCPH-30001R (Version 5.0 04/27/01 A)" ) + ROMX_LOAD( "ps2-0160a-20010427.bin", 0x0000, 0x400000, CRC(4008ac18) SHA1(7331a40b4b4feb1b3f0f77b013b6d38483577baa), ROM_BIOS(16) ) + ROM_SYSTEM_BIOS( 17, "scph30000_j", "SCPH-30000 (Version 5.0 04/27/01 J)" ) + ROMX_LOAD( "ps2-0160j-20010427.bin", 0x0000, 0x400000, CRC(c268ef47) SHA1(e525a0c900e37acf0ae5a655d82a0abcb07c6f1f), ROM_BIOS(17) ) + ROM_SYSTEM_BIOS( 18, "scph30001r_a_a", "SCPH-30001R (Version 5.0 07/04/01 A)" ) + ROMX_LOAD( "ps2-0160a-20010704.bin", 0x0000, 0x400000, CRC(c506c693) SHA1(ce92e8e8c88665f2f645a9522e337823d47a914a), ROM_BIOS(18) ) + ROM_SYSTEM_BIOS( 19, "scph30002r_e_old", "SCPH-30002R/SCPH-30003R/SCPH-30004R (Version 5.0 07/04/01 E)" ) + ROMX_LOAD( "ps2-0160e-20010704.bin", 0x0000, 0x400000, CRC(f1ac735f) SHA1(3cbd048e437c785b5a05a0feced00117a8a42545), ROM_BIOS(19) ) + ROM_SYSTEM_BIOS( 20, "scph30001r_a", "SCPH-30001R (Version 5.0 10/04/01 A)" ) + ROMX_LOAD( "ps2-0160a-20011004.bin", 0x0000, 0x400000, CRC(a01ec625) SHA1(d257bce6ecaf3bafb704c75a1b4741b910bd2d49), ROM_BIOS(20) ) + ROM_SYSTEM_BIOS( 21, "scph30002r_e", "SCPH-30002R/SCPH-30003R/SCPH-30004R (Version 5.0 10/04/01 E)" ) + ROMX_LOAD( "ps2-0160e-20011004.bin", 0x0000, 0x400000, CRC(82aa5055) SHA1(ee34c3a87c53c75ca2a37d77b0042ca24d07831f), ROM_BIOS(21) ) + ROM_SYSTEM_BIOS( 22, "scph30006r_j", "SCPH-30006R (Version 5.0 07/30/01 J)" ) + ROMX_LOAD( "ps2-0160h-20010730.bin", 0x0000, 0x400000, CRC(75f83c67) SHA1(ba15dcf7aac13864c08222037e9321d7468c87d1), ROM_BIOS(22) ) + ROM_SYSTEM_BIOS( 23, "scph39001_a", "SCPH-39001 (Version 5.0 02/07/02 A)" ) + ROMX_LOAD( "ps2-0160a-20020207.bin", 0x0000, 0x400000, CRC(a19e0bf5) SHA1(f9a5d629a036b99128f7cb530c6e3ca016e9c8b7), ROM_BIOS(23) ) + ROM_SYSTEM_BIOS( 24, "scph39002_e", "SCPH-39002/SCPH-39003/SCPH-39004 (Version 5.0 03/19/02 E)" ) + ROMX_LOAD( "ps2-0160e-20020319.bin", 0x0000, 0x400000, CRC(2fe21e4d) SHA1(bff2902bd0ce9729a060581132541e9fd1a9fab6), ROM_BIOS(24) ) + ROM_SYSTEM_BIOS( 25, "scph39006_j", "SCPH-39006 (Version 5.0 04/26/02 J)" ) + ROMX_LOAD( "ps2-0160h-20020426.bin", 0x0000, 0x400000, CRC(3355623e) SHA1(e3a74125c426bcacabca00b513fab928665c8846), ROM_BIOS(25) ) + ROM_SYSTEM_BIOS( 26, "scph50000_j", "SCPH-50000 (Version 5.0 02/06/03 J)" ) + ROMX_LOAD( "ps2-0170j-20030206.bin", 0x0000, 0x400000, CRC(9457f64e) SHA1(d812ac65c357d392396ca9edee812dc41bed8bde), ROM_BIOS(26) ) + ROM_SYSTEM_BIOS( 27, "dtlh50002_e", "DTL-H50002 (Version 5.0 02/27/03 E)" ) + ROMX_LOAD( "ps2-0170ed-20030227.bin", 0x0000, 0x400000, CRC(970a9c56) SHA1(e220bb282378c1f48ea1b585b3675e51a6dca572), ROM_BIOS(27) ) + ROM_SYSTEM_BIOS( 28, "scph50002_e_old", "SCPH-50002/SCPH-50003/SCPH-50004 (Version 5.0 02/27/03 E)" ) + ROMX_LOAD( "ps2-0170e-20030227.bin", 0x0000, 0x400000, CRC(51b5fb8b) SHA1(ad15bd7eabd5bd81ba011516a5be44947d6641aa), ROM_BIOS(28) ) + ROM_SYSTEM_BIOS( 29, "dtlh50001_a", "DTL-H50001 (Version 5.0 03/25/03 A)" ) + ROMX_LOAD( "ps2-0170ad-20030325.bin", 0x0000, 0x400000, CRC(0e1ece79) SHA1(c5bc6e893b4c43d528142e56c96073024de64157), ROM_BIOS(29) ) + ROM_SYSTEM_BIOS( 30, "scph50001_a_old", "SCPH-50001 (Version 5.0 03/25/03 A)" ) + ROMX_LOAD( "ps2-0170a-20030325.bin", 0x0000, 0x400000, CRC(9a99e3f4) SHA1(d269d1ed513227f3ef7133c76cf1b3a64f97b15d), ROM_BIOS(30) ) + ROM_SYSTEM_BIOS( 31, "dtl50009_j", "DTL-50009 (Version 5.0 02/24/03 J)" ) + ROMX_LOAD( "ps2-0180cd-20030224.bin", 0x0000, 0x400000, CRC(8c1a04cf) SHA1(2de87767008fc4a303af64a46251156e965d9065), ROM_BIOS(31) ) + ROM_SYSTEM_BIOS( 32, "desr5000_j", "DESR-5000/DESR-5100/DESR-7000/DESR-7100 (Version 5.0 10/28/03 J)" ) + ROMX_LOAD( "ps2-0180j-20031028.bin", 0x0000, 0x400000, CRC(585fd27c) SHA1(aa4a35c14ee342cf7a03b1dde294ca10e64889e1), ROM_BIOS(32) ) + ROM_SYSTEM_BIOS( 33, "scph50001_a", "SCPH-50001 (Version 5.0 06/23/03 A)" ) + ROMX_LOAD( "ps2-0190a-20030623.bin", 0x0000, 0x400000, CRC(b3e87709) SHA1(c74d92a2952a2912b6698cbcf7742adac8f784d3), ROM_BIOS(33) ) + ROM_SYSTEM_BIOS( 34, "scph50002_e", "SCPH-50002/SCPH-50003/SCPH-50004 (Version 5.0 06/23/03 E)" ) + ROMX_LOAD( "ps2-0190e-20030623.bin", 0x0000, 0x400000, CRC(1752a52e) SHA1(18b9ba833c469c4683676cc20da5124080d980bb), ROM_BIOS(34) ) + ROM_SYSTEM_BIOS( 35, "scph50006_j", "SCPH-50006 (Version 5.0 06/23/03 J)" ) + ROMX_LOAD( "ps2-0190h-20030623.bin", 0x0000, 0x400000, CRC(36b0580c) SHA1(3e18fefb5b5a59046baf25a3f13da1e3a40b92be), ROM_BIOS(35) ) + ROM_SYSTEM_BIOS( 36, "scph50008_e", "SCPH-50008 (Version 5.0 06/23/03 E)" ) + ROMX_LOAD( "ps2-0190r-20030623.bin", 0x0000, 0x400000, CRC(25f6212a) SHA1(34a81db03ab617fbfdd7f9b861692dd2ecd57b82), ROM_BIOS(36) ) + ROM_SYSTEM_BIOS( 37, "scph50009_j", "SCPH-50009 (Version 5.0 06/23/03 J)" ) + ROMX_LOAD( "ps2-0190c-20030623.bin", 0x0000, 0x400000, CRC(d2347ee7) SHA1(92d9eb4b11cef97bb69a275b2851b72f7b0023d6), ROM_BIOS(37) ) + ROM_SYSTEM_BIOS( 38, "scph70000_j", "SCPH-70000 (Version 5.0 06/14/04 J)" ) + ROMX_LOAD( "ps2-0200j-20040614.bin", 0x0000, 0x400000, CRC(2f314730) SHA1(224ab5704ab719edeb05ca1d835812252c97c1b3), ROM_BIOS(38) ) + ROM_SYSTEM_BIOS( 39, "scph70001_a", "SCPH-70001/SCPH-70011/SCPH-70012 (Version 5.0 06/14/04 A)" ) + ROMX_LOAD( "ps2-0200a-20040614.bin", 0x0000, 0x400000, CRC(7ebd68de) SHA1(7a62e5f48603582707e9898eb055ea3eaee50d4c), ROM_BIOS(39) ) + ROM_SYSTEM_BIOS( 40, "scph70002_e", "SCPH-70002/SCPH-70003/SCPH-70004/SCPH-70008 (Version 5.0 06/14/04 E)" ) + ROMX_LOAD( "ps2-0200e-20040614.bin", 0x0000, 0x400000, CRC(6f8e3c29) SHA1(434bc0b4eb4827da0773ec0795aadc5162569a07), ROM_BIOS(40) ) + ROM_SYSTEM_BIOS( 41, "scph70006_j", "SCPH-70006 (Version 5.0 06/14/04 J)" ) + ROMX_LOAD( "ps2-0200h-20040614.bin", 0x0000, 0x400000, CRC(b57201bf) SHA1(7f8e812cab7c7393c85eac6c42661e1fd0a642df), ROM_BIOS(41) ) + ROM_SYSTEM_BIOS( 42, "desr5500_j", "DESR-5500/DESR-7500 (Version 5.0 09/17/04 J)" ) + ROMX_LOAD( "ps2-0210j-20040917.bin", 0x0000, 0x400000, CRC(55710d11) SHA1(bbb1af3085e77599691ec430d147810157da934f), ROM_BIOS(42) ) + ROM_SYSTEM_BIOS( 43, "scph75001_a", "SCPH-75001 (Version 5.0 06/20/05 A)" ) + ROMX_LOAD( "ps2-0220a-20050620.bin", 0x0000, 0x400000, CRC(d305a97a) SHA1(48d0445dffd1e879c7ae752c5166ec3101921555), ROM_BIOS(43) ) + ROM_SYSTEM_BIOS( 44, "scph75002_e", "SCPH-75002/SCPH-75003/SCPH-75004/SCPH-75008 (Version 5.0 06/20/05 E)" ) + ROMX_LOAD( "ps2-0220e-20050620.bin", 0x0000, 0x400000, CRC(e2862e39) SHA1(929a85e974faf4b40d0a7785023b758402c43bd9), ROM_BIOS(44) ) + ROM_SYSTEM_BIOS( 45, "scph77001_a", "SCPH-77001 (Version 5.0 02/10/06 A)" ) + ROMX_LOAD( "ps2-0220a-20060210.bin", 0x0000, 0x400000, CRC(1279fce9) SHA1(92e488d5b2705e4cca83d4d1efbc421012faf83e), ROM_BIOS(45) ) + ROM_SYSTEM_BIOS( 46, "scph77002_e", "SCPH-77002/SCPH-77003/SCPH-77004/SCPH-77008 (Version 5.0 02/10/06 E)" ) + ROMX_LOAD( "ps2-0220e-20060210.bin", 0x0000, 0x400000, CRC(23fa7baa) SHA1(28ad756d0cfd1e7b2e2de3de5d9e14207ee89761), ROM_BIOS(46) ) + ROM_SYSTEM_BIOS( 47, "scph77006_j", "SCPH-77006 (Version 5.0 02/10/06 J)" ) + ROMX_LOAD( "ps2-0220h-20060210.bin", 0x0000, 0x400000, CRC(23001fff) SHA1(fce2a24e5e0400cc6d98c08f426405d19173813e), ROM_BIOS(47) ) + ROM_SYSTEM_BIOS( 48, "scph79001_a", "SCPH-79001/SCPH-90001 (Version 5.0 09/05/06 A)" ) + ROMX_LOAD( "ps2-0220a-20060905.bin", 0x0000, 0x400000, CRC(1c17eafc) SHA1(8361d615cc895962e0f0838489337574dbdc9173), ROM_BIOS(48) ) + ROM_SYSTEM_BIOS( 49, "scph79002_e", "SCPH-79002/SCPH-79003/SCPH-79004/SCPH-79008/SCPH-90002/SCPH-90003/SCPH-90004 (Version 5.0 09/05/06 E)" ) + ROMX_LOAD( "ps2-0220e-20060905.bin", 0x0000, 0x400000, CRC(2d946dbf) SHA1(da5aacead2fb55807d6d4e70b1f10f4fdcfd3281), ROM_BIOS(49) ) + ROM_SYSTEM_BIOS( 50, "scph79006_j", "SCPH-79006/SCPH-90006 (Version 5.0 09/05/06 J)" ) + ROMX_LOAD( "ps2-0220h-20060905.bin", 0x0000, 0x400000, CRC(2d6e09ea) SHA1(a5a2ee0dd9a86ca35b94e97ca92476a584f755bf), ROM_BIOS(50) ) + ROM_SYSTEM_BIOS( 51, "scph90001_a", "SCPH-90001/SCPH-90010 (Version 5.0 02/20/08 A)" ) + ROMX_LOAD( "ps2-0230a-20080220.bin", 0x0000, 0x400000, CRC(286897c2) SHA1(f9229fe159d0353b9f0632f3fdc66819c9030458), ROM_BIOS(51) ) + ROM_SYSTEM_BIOS( 52, "scph90002_e", "SCPH-90002/SCPH-90003/SCPH-90004 (Version 5.0 02/20/08 E)" ) + ROMX_LOAD( "ps2-0230e-20080220.bin", 0x0000, 0x400000, CRC(19eb1081) SHA1(9915b5ba56798f4027ac1bd8d10abe0c1c9c326a), ROM_BIOS(52) ) + ROM_SYSTEM_BIOS( 53, "kdl22px300_j", "KDL-22PX300 (Version 5.0 04/15/10 J)" ) + ROMX_LOAD( "ps2-0250j-20100415.bin", 0x0000, 0x400000, CRC(4e8c160c) SHA1(4b5ef16b67e3b523d28ed2406106cb80470a06d0), ROM_BIOS(53) ) + + // These came from unknown sources and are of unknown quality + ROM_SYSTEM_BIOS( 54, "unknown", "Unknown" ) + ROM_LOAD( "scph-30004r_bios_v6_eur_160.bin", 0x000000, 0x400000, CRC(9386a740) SHA1(8fa040852d4b8688f0c84bcfffc65eb208f2b432) ) + ROM_LOAD( "scph39004.bin", 0x000000, 0x400000, CRC(1f2a283c) SHA1(004cc467439f053d5a1fcf4d1b7c13338ce63403) ) + ROM_LOAD( "scph50003.bin", 0x000000, 0x400000, CRC(a5860b09) SHA1(003f9bdae45a04c5eb28689813e818566a8c4610) ) + ROM_LOAD( "scph_bios_v9_eur_190.bin", 0x000000, 0x400000, CRC(bfe41270) SHA1(dbd7f4d41d54e4f0bf3c4042bb42a42d5d4ef95e) ) + ROM_LOAD( "scph_bios_v10_chn_190.bin", 0x000000, 0x400000, CRC(40d6c676) SHA1(b7548a92bd2caa9d60cbc7f79573a5d510f88012) ) + ROM_LOAD( "scph_bios_v12_rus_200.bin", 0x000000, 0x400000, CRC(92aa71a2) SHA1(cce6fac0f7e682ad167e1e828b2d53192c3d5051) ) + ROM_LOAD( "scph_bios_v15_jap_220.bin", 0x000000, 0x400000, CRC(493c1e58) SHA1(d9a7537fa463fcdd3e270af14a93731736cafc4a) ) +ROM_END + +CONS(2000, ps2, 0, 0, ps2sony, ps2sony, ps2sony_state, 0, "Sony", "PlayStation 2", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/psychic5.cpp b/src/mame/drivers/psychic5.cpp index 10a710e9de8..c359fdbc64e 100644 --- a/src/mame/drivers/psychic5.cpp +++ b/src/mame/drivers/psychic5.cpp @@ -722,8 +722,8 @@ static MACHINE_CONFIG_START( psychic5 ) MCFG_DEVICE_ADD("vrambank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(psychic5_vrambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(14) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_CPU_ADD("audiocpu", Z80, XTAL_5MHz) @@ -776,8 +776,8 @@ static MACHINE_CONFIG_START( bombsa ) MCFG_DEVICE_ADD("vrambank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bombsa_vrambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(14) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_CPU_ADD("audiocpu", Z80, XTAL_5MHz ) diff --git a/src/mame/drivers/pt68k4.cpp b/src/mame/drivers/pt68k4.cpp index f5cbc2c2f0a..e7385ce6fb7 100644 --- a/src/mame/drivers/pt68k4.cpp +++ b/src/mame/drivers/pt68k4.cpp @@ -399,11 +399,11 @@ static MACHINE_CONFIG_START( pt68k2 ) MCFG_CPU_ADD(M68K_TAG, M68000, XTAL_16MHz/2) // 68k2 came in 8, 10, and 12 MHz versions MCFG_CPU_PROGRAM_MAP(pt68k2_mem) - MCFG_MC68681_ADD("duart1", XTAL_3_6864MHz) + MCFG_DEVICE_ADD("duart1", MC68681, XTAL_3_6864MHz) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(pt68k4_state, duart1_irq)) MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(pt68k4_state, duart1_out)) - MCFG_MC68681_ADD("duart2", XTAL_3_6864MHz) + MCFG_DEVICE_ADD("duart2", MC68681, XTAL_3_6864MHz) MCFG_DEVICE_ADD(KBDC_TAG, PC_KBDC, 0) MCFG_PC_KBDC_OUT_CLOCK_CB(WRITELINE(pt68k4_state, keyboard_clock_w)) @@ -440,11 +440,11 @@ static MACHINE_CONFIG_START( pt68k4 ) MCFG_CPU_PROGRAM_MAP(pt68k4_mem) // add the DUARTS. first one has the console on channel A at 19200. - MCFG_MC68681_ADD("duart1", XTAL_16MHz / 4) + MCFG_DEVICE_ADD("duart1", MC68681, XTAL_16MHz / 4) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(pt68k4_state, duart1_irq)) MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(pt68k4_state, duart1_out)) - MCFG_MC68681_ADD("duart2", XTAL_16MHz / 4) + MCFG_DEVICE_ADD("duart2", MC68681, XTAL_16MHz / 4) MCFG_DEVICE_ADD(KBDC_TAG, PC_KBDC, 0) MCFG_PC_KBDC_OUT_CLOCK_CB(WRITELINE(pt68k4_state, keyboard_clock_w)) diff --git a/src/mame/drivers/ptcsol.cpp b/src/mame/drivers/ptcsol.cpp index 3e7fa3ed6e1..c17cd0490ed 100644 --- a/src/mame/drivers/ptcsol.cpp +++ b/src/mame/drivers/ptcsol.cpp @@ -113,6 +113,7 @@ #include "emu.h" #include "cpu/i8085/i8085.h" +//#include "bus/s100/s100.h" #include "imagedev/cassette.h" #include "machine/ay31015.h" #include "machine/keyboard.h" diff --git a/src/mame/drivers/pturn.cpp b/src/mame/drivers/pturn.cpp index a7bb4628411..4d411dcd36d 100644 --- a/src/mame/drivers/pturn.cpp +++ b/src/mame/drivers/pturn.cpp @@ -78,6 +78,7 @@ ROMS: All ROM labels say only "PROM" and a number. */ #include "emu.h" #include "cpu/z80/z80.h" +#include "machine/74259.h" #include "machine/gen_latch.h" #include "sound/ay8910.h" #include "screen.h" @@ -90,6 +91,7 @@ public: pturn_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), + m_audiocpu(*this, "audiocpu"), m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette"), m_soundlatch(*this, "soundlatch"), @@ -97,6 +99,7 @@ public: m_spriteram(*this, "spriteram") { } required_device<cpu_device> m_maincpu; + required_device<cpu_device> m_audiocpu; required_device<gfxdecode_device> m_gfxdecode; required_device<palette_device> m_palette; required_device<generic_latch_8_device> m_soundlatch; @@ -111,19 +114,21 @@ public: int m_bgpalette; int m_fgpalette; int m_bgcolor; - int m_nmi_main; - int m_nmi_sub; + bool m_nmi_main; + bool m_nmi_sub; DECLARE_WRITE8_MEMBER(videoram_w); - DECLARE_WRITE8_MEMBER(nmi_main_enable_w); + DECLARE_WRITE_LINE_MEMBER(nmi_main_enable_w); DECLARE_WRITE8_MEMBER(nmi_sub_enable_w); + DECLARE_WRITE_LINE_MEMBER(coin_counter_1_w); + DECLARE_WRITE_LINE_MEMBER(coin_counter_2_w); DECLARE_WRITE8_MEMBER(bgcolor_w); DECLARE_WRITE8_MEMBER(bg_scrollx_w); DECLARE_WRITE8_MEMBER(fgpalette_w); DECLARE_WRITE8_MEMBER(bg_scrolly_w); - DECLARE_WRITE8_MEMBER(fgbank_w); - DECLARE_WRITE8_MEMBER(bgbank_w); - DECLARE_WRITE8_MEMBER(flip_w); + DECLARE_WRITE_LINE_MEMBER(fgbank_w); + DECLARE_WRITE_LINE_MEMBER(bgbank_w); + DECLARE_WRITE_LINE_MEMBER(flip_w); DECLARE_READ8_MEMBER(custom_r); TILE_GET_INFO_MEMBER(get_tile_info); @@ -244,14 +249,28 @@ WRITE8_MEMBER(pturn_state::videoram_w) } -WRITE8_MEMBER(pturn_state::nmi_main_enable_w) +WRITE_LINE_MEMBER(pturn_state::nmi_main_enable_w) { - m_nmi_main = data; + m_nmi_main = state; + if (!m_nmi_main) + m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); } WRITE8_MEMBER(pturn_state::nmi_sub_enable_w) { - m_nmi_sub = data; + m_nmi_sub = BIT(data, 0); + if (!m_nmi_sub) + m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); +} + +WRITE_LINE_MEMBER(pturn_state::coin_counter_1_w) +{ + machine().bookkeeping().coin_counter_w(0, state); +} + +WRITE_LINE_MEMBER(pturn_state::coin_counter_2_w) +{ + machine().bookkeeping().coin_counter_w(1, state); } WRITE8_MEMBER(pturn_state::bgcolor_w) @@ -277,21 +296,21 @@ WRITE8_MEMBER(pturn_state::bg_scrolly_w) m_bgmap->set_scrollx(0, data); } -WRITE8_MEMBER(pturn_state::fgbank_w) +WRITE_LINE_MEMBER(pturn_state::fgbank_w) { - m_fgbank=data&1; + m_fgbank = state; m_fgmap->mark_all_dirty(); } -WRITE8_MEMBER(pturn_state::bgbank_w) +WRITE_LINE_MEMBER(pturn_state::bgbank_w) { - m_bgbank=data&1; + m_bgbank = state; m_bgmap->mark_all_dirty(); } -WRITE8_MEMBER(pturn_state::flip_w) +WRITE_LINE_MEMBER(pturn_state::flip_w) { - flip_screen_set(data); + flip_screen_set(state); } @@ -344,14 +363,7 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, pturn_state ) AM_RANGE(0xf805, 0xf805) AM_READ_PORT("DSW1") AM_RANGE(0xf806, 0xf806) AM_READNOP /* Protection related, ((val&3)==2) -> jump to 0 */ - AM_RANGE(0xfc00, 0xfc00) AM_WRITE(flip_w) - AM_RANGE(0xfc01, 0xfc01) AM_WRITE(nmi_main_enable_w) - AM_RANGE(0xfc02, 0xfc02) AM_WRITENOP /* Unknown */ - AM_RANGE(0xfc03, 0xfc03) AM_WRITENOP /* Unknown */ - AM_RANGE(0xfc04, 0xfc04) AM_WRITE(bgbank_w) - AM_RANGE(0xfc05, 0xfc05) AM_WRITE(fgbank_w) - AM_RANGE(0xfc06, 0xfc06) AM_WRITENOP /* Unknown */ - AM_RANGE(0xfc07, 0xfc07) AM_WRITENOP /* Unknown */ + AM_RANGE(0xfc00, 0xfc07) AM_DEVWRITE("mainlatch", ls259_device, write_d0) ADDRESS_MAP_END @@ -472,18 +484,14 @@ INPUT_PORTS_END INTERRUPT_GEN_MEMBER(pturn_state::sub_intgen) { - if(m_nmi_sub) - { - device.execute().set_input_line(INPUT_LINE_NMI,PULSE_LINE); - } + if (m_nmi_sub) + device.execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE); } INTERRUPT_GEN_MEMBER(pturn_state::main_intgen) { if (m_nmi_main) - { - device.execute().set_input_line(INPUT_LINE_NMI,PULSE_LINE); - } + device.execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE); } void pturn_state::machine_start() @@ -496,6 +504,7 @@ void pturn_state::machine_reset() { address_space &space = m_maincpu->space(AS_PROGRAM); m_soundlatch->clear_w(space,0,0); + m_nmi_sub = false; } static MACHINE_CONFIG_START( pturn ) @@ -507,6 +516,14 @@ static MACHINE_CONFIG_START( pturn ) MCFG_CPU_PROGRAM_MAP(sub_map) MCFG_CPU_PERIODIC_INT_DRIVER(pturn_state, sub_intgen, 3*60) + MCFG_DEVICE_ADD("mainlatch", LS259, 0) + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE(pturn_state, flip_w)) + MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(WRITELINE(pturn_state, nmi_main_enable_w)) + MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE(pturn_state, coin_counter_1_w)) + MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(WRITELINE(pturn_state, coin_counter_2_w)) + MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(WRITELINE(pturn_state, bgbank_w)) + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(WRITELINE(pturn_state, fgbank_w)) + MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(NOOP) // toggles frequently during gameplay MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) diff --git a/src/mame/drivers/pwrview.cpp b/src/mame/drivers/pwrview.cpp index 68830d1a6d9..413823f8831 100644 --- a/src/mame/drivers/pwrview.cpp +++ b/src/mame/drivers/pwrview.cpp @@ -380,8 +380,8 @@ static MACHINE_CONFIG_START( pwrview ) MCFG_DEVICE_ADD("bios_bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bios_bank) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(17) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(17) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MACHINE_CONFIG_END diff --git a/src/mame/drivers/px4.cpp b/src/mame/drivers/px4.cpp index 0c62cef6176..bea1adc7140 100644 --- a/src/mame/drivers/px4.cpp +++ b/src/mame/drivers/px4.cpp @@ -594,16 +594,22 @@ WRITE8_MEMBER( px4_state::sior_w ) { case 1: { - int year = dec_2_bcd(m_time.local_time.year); - year = (year & 0xff0f) | ((data & 0xf) << 4); - t->tm_year = bcd_2_dec(year) - 1900; + if (data < 10) + { + int year = dec_2_bcd(m_time.local_time.year); + year = (year & 0xff0f) | ((data & 0xf) << 4); + t->tm_year = bcd_2_dec(year) - 1900; + } } break; case 2: { - int year = dec_2_bcd(m_time.local_time.year); - year = (year & 0xfff0) | (data & 0xf); - t->tm_year = bcd_2_dec(year) - 1900; + if (data < 10) + { + int year = dec_2_bcd(m_time.local_time.year); + year = (year & 0xfff0) | (data & 0xf); + t->tm_year = bcd_2_dec(year) - 1900; + } } break; case 3: t->tm_mon = bcd_2_dec(data & 0x7f) - 1; break; diff --git a/src/mame/drivers/px8.cpp b/src/mame/drivers/px8.cpp index 6b38e05a1d1..0b19069fe9c 100644 --- a/src/mame/drivers/px8.cpp +++ b/src/mame/drivers/px8.cpp @@ -795,10 +795,10 @@ static MACHINE_CONFIG_START( px8 ) MCFG_SOUND_ROUTE(0, "mono", 0.25) /* cartridge */ - MCFG_GENERIC_CARTSLOT_ADD("capsule1", generic_plain_slot, nullptr) + MCFG_GENERIC_CARTSLOT_ADD("capsule1", generic_plain_slot, "px8_cart") MCFG_GENERIC_EXTENSIONS("bin,rom") - MCFG_GENERIC_CARTSLOT_ADD("capsule2", generic_plain_slot, nullptr) + MCFG_GENERIC_CARTSLOT_ADD("capsule2", generic_plain_slot, "px8_cart") MCFG_GENERIC_EXTENSIONS("bin,rom") /* devices */ @@ -812,6 +812,7 @@ static MACHINE_CONFIG_START( px8 ) MCFG_RAM_DEFAULT_SIZE("64K") // software + MCFG_SOFTWARE_LIST_ADD("cart_list", "px8_cart") MCFG_SOFTWARE_LIST_ADD("epson_cpm_list", "epson_cpm") MACHINE_CONFIG_END @@ -837,20 +838,8 @@ ROM_START( px8 ) ROM_LOAD( "upd7508 sub cpu internal rom.2e", 0x0000, 0x1000, NO_DUMP ) // Possibly cartridges - ROM_REGION( 0x54000, "carts", 0 ) + ROM_REGION( 0x8000, "carts", 0 ) ROM_LOAD( "px8-util.rom", 0x00000, 0x8000, CRC(4430a271) SHA1(58c23a5f25ad9cdb70ada44dc773e6899e9bd8bf) ) // various utilities - ROM_LOAD( "px8-ws.rom", 0x08000, 0x8000, CRC(7f64dd48) SHA1(6d9f4e797fd7ac7b1ae2f0083d5461fa16731842) ) // WordStar - ROM_LOAD( "px8-tam.rom", 0x10000, 0x8000, CRC(281c65d3) SHA1(e6a24161248877fa6c3edc18d56127b263f5b2e0) ) // The Traveling Appointment Manager - ROM_LOAD( "px8-tem.rom", 0x18000, 0x8000, CRC(f2a8aa41) SHA1(16203488eeac3cd21e11c8e0f2007527dd375597) ) // The Traveling Expense Manager - ROM_LOAD( "px8-ttm.rom", 0x20000, 0x8000, CRC(2303dcc3) SHA1(0cc3926ef58ce1cf05fbe8caedf259439d204388) ) // The Traveling Time Manager - ROM_LOAD( "clock.rom", 0x28000, 0x4000, CRC(6f254cc9) SHA1(003eaf209c01e0148dc112adc34a35d33ac0bf60) ) // Clock by Stefan Bodrato - ROM_LOAD( "dakcom_v1.1.bin", 0x2c000, 0x2000, CRC(3a74a975) SHA1(46300aeb10ec208a906143e2acd1f93badb6792d) ) // DakComm v1.1 (comms) - ROM_LOAD( "px8-dcom.rom", 0x2e000, 0x8000, CRC(ddea1bbf) SHA1(791c58bf2fec8a19ca0face2e7b3eebe25ef4823) ) // this may be DakComm overdumped - ROM_LOAD( "genevaconnection.bin", 0x36000, 0x2000, CRC(7971e79a) SHA1(97cc1af6e7733eabcb4a85663022c6d3acea9d5a) ) // Geneva Connection - ROM_LOAD( "othello.rom", 0x38000, 0x4000, CRC(1a01059e) SHA1(1e275ad3d3f5014dd6a6f553bf9e062a39221cb8) ) // Othello by Stefan Bodrato - ROM_LOAD( "supercalc-1.bin", 0x3c000, 0x8000, CRC(58a0a411) SHA1(7b80361cd594e3b9b9e925e6a193606f8faa185c) ) // Supercalc rom 1 - ROM_LOAD( "supercalc-2.bin", 0x44000, 0x8000, CRC(ba1c664b) SHA1(3c2a54a187f286eafb91f7571479a035d69d1df1) ) // Supercalc rom 2 - ROM_LOAD( "tpascal.rom", 0x4c000, 0x8000, CRC(30a71af7) SHA1(e3f89fc4db6df8acc2f940e86e12eafb7af1303d) ) // Turbo Pascal ROM_END /*************************************************************************** diff --git a/src/mame/drivers/qtsbc.cpp b/src/mame/drivers/qtsbc.cpp index b1e64cb99e7..988bcfeee41 100644 --- a/src/mame/drivers/qtsbc.cpp +++ b/src/mame/drivers/qtsbc.cpp @@ -2,63 +2,79 @@ // copyright-holders:Robbbert /*************************************************************************** - QT Computer Systems SBC +2/4 +QT Computer Systems SBC +2/4 - 11/12/2009 Skeleton driver. +2009-12-11 Skeleton driver. - It expects a rom or similar at E377-up, so currently it crashes. +This looks like the same system as the Compu/Time SBC-880 Processor Board. + +Currently it crashes. There's a memory move routine at 50A4, and after +a few turns it is told to move E603 bytes which corrupts everything. + +Chips: P8251, D8253C, MK3880N-4 (Z80). 3x 6-sw dips. Unmarked crystal. + Doesn't appear to be any ram? + +There's a blue jumper marked 4M and 2M. Assumed to be selectable CPU clock. +Also assumed this is what the "2/4" in the name refers to. + +Feature list from QT ad: +- 1K RAM (which can be located at any 1K boundary) plus one each + Parallel and Serial I/O ports on board +- Power on jump to onboard EPROM (2708 or 2716) +- EPROM addressable on any 1K or 2K boundary +- Full 64K use of RAM allowed in shadow mode +- Programmable Baud rate selection, 110-9600 +- 2 or 4MHz switch selectable +- DMA capability allows MWRT signal generation on CPU board or elsewhere + in system under DMA logic or front panel control +- Two programmable timers available for use by programs run with the + SBC+2/4 (timer output and controls available at parallel I/O connector; + parallel input and output ports available for use on CPU board). ****************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" -#include "machine/terminal.h" +#include "machine/i8251.h" +#include "machine/pit8253.h" +#include "bus/rs232/rs232.h" +//#include "bus/s100/s100.h" -#define TERMINAL_TAG "terminal" class qtsbc_state : public driver_device { public: qtsbc_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG), - m_p_ram(*this, "p_ram") - { - } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_p_ram(*this, "ram") + { } - required_device<cpu_device> m_maincpu; - required_device<generic_terminal_device> m_terminal; - DECLARE_READ8_MEMBER( qtsbc_06_r ); DECLARE_READ8_MEMBER( qtsbc_43_r ); - void kbd_put(u8 data); - required_shared_ptr<uint8_t> m_p_ram; - uint8_t m_term_data; + +private: virtual void machine_reset() override; + required_device<cpu_device> m_maincpu; + required_shared_ptr<u8> m_p_ram; }; -READ8_MEMBER( qtsbc_state::qtsbc_06_r ) -{ - uint8_t ret = m_term_data; - m_term_data = 0; - return ret; -} - READ8_MEMBER( qtsbc_state::qtsbc_43_r ) { - return 0; + return 0; // this controls where the new ram program gets built at. 0 = 0xE000. } -static ADDRESS_MAP_START(qtsbc_mem, AS_PROGRAM, 8, qtsbc_state) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, qtsbc_state ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE( 0x0000, 0xffff ) AM_RAM AM_SHARE("p_ram") AM_REGION("maincpu", 0) + AM_RANGE(0x0000, 0xffff) AM_RAM AM_SHARE("ram") AM_REGION("maincpu", 0) ADDRESS_MAP_END -static ADDRESS_MAP_START( qtsbc_io, AS_IO, 8, qtsbc_state) +static ADDRESS_MAP_START( io_map, AS_IO, 8, qtsbc_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) - AM_RANGE(0x06, 0x06) AM_READ(qtsbc_06_r) AM_DEVWRITE(TERMINAL_TAG, generic_terminal_device, write) + AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("pit", pit8253_device, read, write) + AM_RANGE(0x06, 0x06) AM_DEVREADWRITE("uart", i8251_device, data_r, data_w) + AM_RANGE(0x07, 0x07) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w) AM_RANGE(0x43, 0x43) AM_READ(qtsbc_43_r) ADDRESS_MAP_END @@ -73,29 +89,46 @@ void qtsbc_state::machine_reset() memcpy(m_p_ram, bios, 0x800); } -void qtsbc_state::kbd_put(u8 data) -{ - m_term_data = data; -} +static DEVICE_INPUT_DEFAULTS_START( terminal ) + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9600 ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9600 ) + DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) +DEVICE_INPUT_DEFAULTS_END static MACHINE_CONFIG_START( qtsbc ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) // Mostek MK3880 - MCFG_CPU_PROGRAM_MAP(qtsbc_mem) - MCFG_CPU_IO_MAP(qtsbc_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) - MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(qtsbc_state, kbd_put)) + MCFG_DEVICE_ADD("pit", PIT8253, 0) // U9 + MCFG_PIT8253_CLK0(XTAL_4MHz / 2) /* Timer 0: baud rate gen for 8251 */ + MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("uart", i8251_device, write_txc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart", i8251_device, write_rxc)) + + MCFG_DEVICE_ADD("uart", I8251, 0) // U8 + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart", i8251_device, write_rxd)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart", i8251_device, write_dsr)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart", i8251_device, write_cts)) + MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) // must be exactly here MACHINE_CONFIG_END /* ROM definition */ ROM_START( qtsbc ) ROM_REGION( 0x10800, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "qtsbc.bin", 0x10000, 0x0800, CRC(823fd942) SHA1(64c4f74dd069ae4d43d301f5e279185f32a1efa0)) + ROM_LOAD( "qtsbc.u23", 0x10000, 0x0800, CRC(823fd942) SHA1(64c4f74dd069ae4d43d301f5e279185f32a1efa0)) ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -COMP( 19??, qtsbc, 0, 0, qtsbc, qtsbc, qtsbc_state, 0, "Computer Systems Inc.", "QT SBC +2/4", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 19??, qtsbc, 0, 0, qtsbc, qtsbc, qtsbc_state, 0, "QT Computer Systems Inc.", "SBC + 2/4", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/r2dtank.cpp b/src/mame/drivers/r2dtank.cpp index b12dd0b949a..68e90407d9c 100644 --- a/src/mame/drivers/r2dtank.cpp +++ b/src/mame/drivers/r2dtank.cpp @@ -81,10 +81,9 @@ public: DECLARE_READ8_MEMBER(AY8910_port_r); DECLARE_WRITE8_MEMBER(AY8910_port_w); DECLARE_WRITE_LINE_MEMBER(flipscreen_w); - DECLARE_WRITE_LINE_MEMBER(display_enable_changed); DECLARE_WRITE8_MEMBER(pia_comp_w); virtual void machine_start() override; - DECLARE_WRITE8_MEMBER(ttl74123_output_changed); + DECLARE_WRITE_LINE_MEMBER(ttl74123_output_changed); MC6845_UPDATE_ROW(crtc_update_row); @@ -223,11 +222,11 @@ WRITE8_MEMBER(r2dtank_state::AY8910_port_w) * *************************************/ -WRITE8_MEMBER(r2dtank_state::ttl74123_output_changed) +WRITE_LINE_MEMBER(r2dtank_state::ttl74123_output_changed) { pia6821_device *pia = machine().device<pia6821_device>("pia_main"); - pia->ca1_w(data); - m_ttl74123_output = data; + pia->ca1_w(state); + m_ttl74123_output = state; } @@ -310,11 +309,6 @@ MC6845_UPDATE_ROW( r2dtank_state::crtc_update_row ) } -WRITE_LINE_MEMBER(r2dtank_state::display_enable_changed) -{ - machine().device<ttl74123_device>("74123")->a_w(generic_space(), 0, state); -} - /************************************* * @@ -461,7 +455,7 @@ static MACHINE_CONFIG_START( r2dtank ) MCFG_MC6845_SHOW_BORDER_AREA(false) MCFG_MC6845_CHAR_WIDTH(8) MCFG_MC6845_UPDATE_ROW_CB(r2dtank_state, crtc_update_row) - MCFG_MC6845_OUT_DE_CB(WRITELINE(r2dtank_state, display_enable_changed)) + MCFG_MC6845_OUT_DE_CB(DEVWRITELINE("74123", ttl74123_device, a_w)) /* 74LS123 */ @@ -472,7 +466,7 @@ static MACHINE_CONFIG_START( r2dtank ) MCFG_TTL74123_A_PIN_VALUE(1) /* A pin - driven by the CRTC */ MCFG_TTL74123_B_PIN_VALUE(1) /* B pin - pulled high */ MCFG_TTL74123_CLEAR_PIN_VALUE(1) /* Clear pin - pulled high */ - MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITE8(r2dtank_state, ttl74123_output_changed)) + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(r2dtank_state, ttl74123_output_changed)) MCFG_DEVICE_ADD("pia_main", PIA6821, 0) MCFG_PIA_READPA_HANDLER(IOPORT("IN0")) diff --git a/src/mame/drivers/rbmk.cpp b/src/mame/drivers/rbmk.cpp index b97c0d16dd8..67ad1b99107 100644 --- a/src/mame/drivers/rbmk.cpp +++ b/src/mame/drivers/rbmk.cpp @@ -39,7 +39,7 @@ Notes: * - Unpopulated position for PIC16F84 3.6V_BATT - Purpose of battery unknown, does not appear to be used for backup of suicide RAM, and there's no RTC on the board. - 93C46 - 128 x8 EEPROM. This chip was covered by a plactic cover. There's nothing else under + 93C46 - 128 x8 EEPROM. This chip was covered by a plastic cover. There's nothing else under the cover, but there was an unpopulated position for a PIC16F84 89C51 - Atmel 89C51 Microcontroller (protected) @@ -49,6 +49,8 @@ Notes: A1 - Atmel AT27C080 (GFX) B1 - Macronix MX261000 (GFX?? or PRG/data for 89C51?) S1 - Macronix MX27C2000 (OKI samples) + +Keep pressed 9 and press reset to enter service mode. */ #include "emu.h" @@ -68,53 +70,78 @@ class rbmk_state : public driver_device public: rbmk_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_gms_vidram2(*this, "gms_vidram2"), - m_gms_vidram(*this, "gms_vidram"), + m_vidram2(*this, "vidram2"), + m_vidram(*this, "vidram"), m_maincpu(*this, "maincpu"), m_mcu(*this, "mcu"), m_eeprom(*this, "eeprom"), m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette") { } - required_shared_ptr<uint16_t> m_gms_vidram2; - required_shared_ptr<uint16_t> m_gms_vidram; - uint16_t m_tilebank; - uint8_t m_mux_data; - DECLARE_READ16_MEMBER(gms_read); - DECLARE_WRITE16_MEMBER(gms_write1); - DECLARE_WRITE16_MEMBER(gms_write2); - DECLARE_WRITE16_MEMBER(gms_write3); - DECLARE_READ8_MEMBER(rbmk_mcu_io_r); - DECLARE_WRITE8_MEMBER(rbmk_mcu_io_w); + DECLARE_READ16_MEMBER(unk_r); + DECLARE_READ16_MEMBER(dip_mux_r); + DECLARE_WRITE16_MEMBER(dip_mux_w); + DECLARE_WRITE16_MEMBER(unk_w); + DECLARE_WRITE16_MEMBER(tilebank_w); + DECLARE_READ8_MEMBER(mcu_io_r); + DECLARE_WRITE8_MEMBER(mcu_io_w); DECLARE_WRITE8_MEMBER(mcu_io_mux_w); DECLARE_WRITE16_MEMBER(eeprom_w); - virtual void video_start() override; - uint32_t screen_update_rbmk(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(mcu_irq); + +protected: + virtual void video_start() override; + +private: + required_shared_ptr<uint16_t> m_vidram2; + required_shared_ptr<uint16_t> m_vidram; + required_device<cpu_device> m_maincpu; required_device<cpu_device> m_mcu; required_device<eeprom_serial_93cxx_device> m_eeprom; required_device<gfxdecode_device> m_gfxdecode; required_device<palette_device> m_palette; + + uint16_t m_tilebank; + uint8_t m_mux_data; + uint16_t m_dip_mux; }; -READ16_MEMBER(rbmk_state::gms_read) +READ16_MEMBER(rbmk_state::unk_r) { return machine().rand(); } +READ16_MEMBER(rbmk_state::dip_mux_r) +{ +/* +definitely muxed dips. See switch test in test mode. This implementation doesn't work properly, though. For now use the old one. + +uint16_t res = 0xffff; +switch(m_dip_mux) +{ +case 0x1000: res = ioport("DSW1")->read(); break; +case 0x2000: res = ioport("DSW2")->read(); break; +case 0x4000: res = ioport("DSW3")->read(); break; +} +return res;*/ + return ioport("DSW1")->read(); +} -WRITE16_MEMBER(rbmk_state::gms_write1) +WRITE16_MEMBER(rbmk_state::tilebank_w) { + m_tilebank = data; } -WRITE16_MEMBER(rbmk_state::gms_write2) +WRITE16_MEMBER(rbmk_state::dip_mux_w) { - m_tilebank=data; + m_dip_mux = data; } -WRITE16_MEMBER(rbmk_state::gms_write3) +WRITE16_MEMBER(rbmk_state::unk_w) { } @@ -132,28 +159,43 @@ WRITE16_MEMBER(rbmk_state::eeprom_w) static ADDRESS_MAP_START( rbmk_mem, AS_PROGRAM, 16, rbmk_state ) - AM_RANGE(0x000000, 0x07ffff) AM_ROM + AM_RANGE(0x000000, 0x07ffff) AM_ROM AM_WRITENOP AM_RANGE(0x100000, 0x10ffff) AM_RAM AM_RANGE(0x500000, 0x50ffff) AM_RAM - AM_RANGE(0x940000, 0x940fff) AM_RAM AM_SHARE("gms_vidram2") + AM_RANGE(0x940000, 0x940fff) AM_RAM AM_SHARE("vidram2") AM_RANGE(0x980300, 0x983fff) AM_RAM // 0x2048 words ???, byte access AM_RANGE(0x900000, 0x900fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") - AM_RANGE(0x9c0000, 0x9c0fff) AM_RAM AM_SHARE("gms_vidram") + AM_RANGE(0x9c0000, 0x9c0fff) AM_RAM AM_SHARE("vidram") AM_RANGE(0xb00000, 0xb00001) AM_WRITE(eeprom_w) - AM_RANGE(0xC00000, 0xC00001) AM_READ_PORT("IN0") AM_WRITE(gms_write1) - AM_RANGE(0xC08000, 0xC08001) AM_READ_PORT("IN1") AM_WRITE(gms_write2) - AM_RANGE(0xC10000, 0xC10001) AM_READ_PORT("IN3") - AM_RANGE(0xC18080, 0xC18081) AM_READ(gms_read) - AM_RANGE(0xC20000, 0xC20001) AM_READ_PORT("IN2") - AM_RANGE(0xC28000, 0xC28001) AM_WRITE(gms_write3) + AM_RANGE(0xc00000, 0xc00001) AM_READWRITE(dip_mux_r, dip_mux_w) + AM_RANGE(0xc08000, 0xc08001) AM_READ_PORT("IN1") AM_WRITE(tilebank_w) + AM_RANGE(0xc10000, 0xc10001) AM_READ_PORT("IN2") + AM_RANGE(0xc18080, 0xc18081) AM_READ(unk_r) + AM_RANGE(0xc20000, 0xc20001) AM_READ_PORT("IN3") + AM_RANGE(0xc28000, 0xc28001) AM_WRITE(unk_w) ADDRESS_MAP_END +static ADDRESS_MAP_START( rbspm_mem, AS_PROGRAM, 16, rbmk_state ) + AM_RANGE(0x000000, 0x07ffff) AM_ROM + AM_RANGE(0x200000, 0x200001) AM_WRITE(eeprom_w) // wrong + AM_RANGE(0x300000, 0x300001) AM_READWRITE(dip_mux_r, dip_mux_w) + AM_RANGE(0x308000, 0x308001) AM_READ_PORT("IN1") AM_WRITE(tilebank_w) // ok + AM_RANGE(0x310000, 0x310001) AM_READ_PORT("IN2") + AM_RANGE(0x318080, 0x318081) AM_READ(unk_r) + AM_RANGE(0x320000, 0x320001) AM_READ_PORT("IN3") + AM_RANGE(0x328000, 0x328001) AM_WRITE(unk_w) + AM_RANGE(0x500000, 0x50ffff) AM_RAM + AM_RANGE(0x900000, 0x900fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") // if removed fails gfx test? + AM_RANGE(0x940000, 0x940fff) AM_RAM AM_SHARE("vidram2") // if removed fails palette test? + AM_RANGE(0x980300, 0x983fff) AM_RAM // 0x2048 words ???, byte access, u25 and u26 according to test mode + AM_RANGE(0x9c0000, 0x9c0fff) AM_RAM AM_SHARE("vidram") +ADDRESS_MAP_END -static ADDRESS_MAP_START( rbmk_mcu_mem, AS_PROGRAM, 8, rbmk_state ) +static ADDRESS_MAP_START( mcu_mem, AS_PROGRAM, 8, rbmk_state ) // AM_RANGE(0x0000, 0x0fff) AM_ROM ADDRESS_MAP_END -READ8_MEMBER(rbmk_state::rbmk_mcu_io_r) +READ8_MEMBER(rbmk_state::mcu_io_r) { if(m_mux_data & 8) { @@ -171,7 +213,7 @@ READ8_MEMBER(rbmk_state::rbmk_mcu_io_r) return 0xff; } -WRITE8_MEMBER(rbmk_state::rbmk_mcu_io_w) +WRITE8_MEMBER(rbmk_state::mcu_io_w) { if(m_mux_data & 8) { machine().device<ym2151_device>("ymsnd")->write(space, offset & 1, data); } else if(m_mux_data & 4) @@ -188,99 +230,52 @@ WRITE8_MEMBER(rbmk_state::mcu_io_mux_w) m_mux_data = ~data; } -static ADDRESS_MAP_START( rbmk_mcu_io, AS_IO, 8, rbmk_state ) - AM_RANGE(0x0ff00, 0x0ffff) AM_READWRITE(rbmk_mcu_io_r, rbmk_mcu_io_w ) +static ADDRESS_MAP_START( mcu_io, AS_IO, 8, rbmk_state ) + AM_RANGE(0x0ff00, 0x0ffff) AM_READWRITE(mcu_io_r, mcu_io_w ) AM_RANGE(MCS51_PORT_P3, MCS51_PORT_P3) AM_WRITE(mcu_io_mux_w ) ADDRESS_MAP_END static INPUT_PORTS_START( rbmk ) - PORT_START("IN0") - PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0002, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0004, 0x0004, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0004, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0008, 0x0008, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0008, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0010, 0x0010, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0010, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Controls ) ) - PORT_DIPSETTING( 0x0080, DEF_STR( Joystick ) ) - PORT_DIPSETTING( 0x0000, "Keyboard" ) - - PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0200, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0400, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0800, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Version ) ) - PORT_DIPSETTING( 0x4000, "8.8" ) - PORT_DIPSETTING( 0x0000, "8.8-" ) - PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_START("IN1") /* 16bit */ - PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP ) - - PORT_DIPNAME( 0x0020, 0x0020, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0020, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_MAHJONG_BET ) PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON2 ) - - PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x1000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("IN2") /* 16bit */ - PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) PORT_TOGGLE + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_MEMORY_RESET ) PORT_TOGGLE + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, do_read) + + + PORT_START("DSW1") /* 16bit, in test mode first 8 are recognised as dsw1, second 8 as dsw4*/ + PORT_DIPNAME( 0x0001, 0x0001, "DSW1" ) PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) @@ -301,9 +296,10 @@ static INPUT_PORTS_START( rbmk ) PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0040, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x0080, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Controls ) ) + PORT_DIPSETTING( 0x0080, DEF_STR( Joystick ) ) + PORT_DIPSETTING( 0x0000, "Keyboard" ) + PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x0100, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) @@ -322,16 +318,15 @@ static INPUT_PORTS_START( rbmk ) PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x2000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) + PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Version ) ) + PORT_DIPSETTING( 0x4000, "8.8" ) + PORT_DIPSETTING( 0x0000, "8.8-" ) PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - - PORT_START("IN3") /* 16bit */ - PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) + PORT_START("DSW2") /* 16bit, in test mode first 8 are recognised as dsw2, second 8 as dsw5*/ + PORT_DIPNAME( 0x0001, 0x0001, "DSW2" ) // 1,2,3 should be coinage PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) @@ -376,10 +371,12 @@ static INPUT_PORTS_START( rbmk ) PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x4000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, do_read) + PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unknown ) ) + PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_START("IN4") /* 16bit */ - PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) + PORT_START("DSW3") /* 16bit, in test mode first 8 are recognised as dsw3, second 8 as dsw6*/ + PORT_DIPNAME( 0x0001, 0x0001, "DSW3" ) PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) @@ -428,8 +425,8 @@ static INPUT_PORTS_START( rbmk ) PORT_DIPSETTING( 0x8000, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) - PORT_START("IN5") /* 16bit */ - PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ) ) + PORT_START("IN3") /* 16bit, not verified in test mode? */ + PORT_DIPNAME( 0x0001, 0x0001, "IN3" ) PORT_DIPSETTING( 0x0001, DEF_STR( Off ) ) PORT_DIPSETTING( 0x0000, DEF_STR( On ) ) PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Unknown ) ) @@ -480,6 +477,15 @@ static INPUT_PORTS_START( rbmk ) INPUT_PORTS_END +static INPUT_PORTS_START( rbspm ) + PORT_INCLUDE( rbmk ) + + PORT_MODIFY("DSW1") + PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Version ) ) + PORT_DIPSETTING( 0x4000, "4.1" ) + PORT_DIPSETTING( 0x0000, "4.2" ) +INPUT_PORTS_END + static const gfx_layout rbmk32_layout = { 8,32, @@ -511,9 +517,12 @@ GFXDECODE_END void rbmk_state::video_start() { + save_item(NAME(m_tilebank)); + save_item(NAME(m_mux_data)); + save_item(NAME(m_dip_mux)); } -uint32_t rbmk_state::screen_update_rbmk(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t rbmk_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int x,y; int count = 0; @@ -522,7 +531,7 @@ uint32_t rbmk_state::screen_update_rbmk(screen_device &screen, bitmap_ind16 &bit { for (x=0;x<64;x++) { - int tile = m_gms_vidram2[count+0x600]; + int tile = m_vidram2[count+0x600]; m_gfxdecode->gfx(0)->opaque(bitmap,cliprect,(tile&0xfff)+((m_tilebank&0x10)>>4)*0x1000,tile>>12,0,0,x*8,y*32); count++; } @@ -534,7 +543,7 @@ uint32_t rbmk_state::screen_update_rbmk(screen_device &screen, bitmap_ind16 &bit { for (x=0;x<64;x++) { - int tile = m_gms_vidram[count]; + int tile = m_vidram[count]; m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,(tile&0xfff)+((m_tilebank>>1)&3)*0x1000,tile>>12,0,0,x*8,y*8,0); count++; } @@ -553,19 +562,18 @@ static MACHINE_CONFIG_START( rbmk ) MCFG_CPU_VBLANK_INT_DRIVER("screen", rbmk_state, irq1_line_hold) MCFG_CPU_ADD("mcu", AT89C4051, 22000000 / 4) // frequency isn't right - MCFG_CPU_PROGRAM_MAP(rbmk_mcu_mem) - MCFG_CPU_IO_MAP(rbmk_mcu_io) + MCFG_CPU_PROGRAM_MAP(mcu_mem) + MCFG_CPU_IO_MAP(mcu_io) MCFG_CPU_VBLANK_INT_DRIVER("screen", rbmk_state, mcu_irq) MCFG_GFXDECODE_ADD("gfxdecode", "palette", rbmk) - MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(58) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) MCFG_SCREEN_SIZE(64*8, 32*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 64*8-1, 0*8, 32*8-1) - MCFG_SCREEN_UPDATE_DRIVER(rbmk_state, screen_update_rbmk) + MCFG_SCREEN_UPDATE_DRIVER(rbmk_state, screen_update) MCFG_SCREEN_PALETTE("palette") MCFG_PALETTE_ADD("palette", 0x800) @@ -585,6 +593,16 @@ static MACHINE_CONFIG_START( rbmk ) MCFG_SOUND_ROUTE(1, "rspeaker", 0.60) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( rbspm, rbmk ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(rbspm_mem) + + MCFG_CPU_MODIFY("mcu") + MCFG_DEVICE_DISABLE() // until decapped + + // PIC16F84 if decapped +MACHINE_CONFIG_END + ROM_START( rbmk ) ROM_REGION( 0x80000, "maincpu", 0 ) /* 68000 Code */ ROM_LOAD( "p1.u64", 0x00000, 0x80000, CRC(83b3c505) SHA1(b943d7312dacdf46d4a55f9dc3cf92e291c40ce7) ) @@ -608,5 +626,37 @@ ROM_START( rbmk ) ROM_LOAD16_WORD_SWAP( "93c46.u51", 0x00, 0x080, CRC(4ca6ff01) SHA1(66c456eac5b0d1176ef9130baf2e746efdf30152) ) ROM_END +/* +Gameplay videos: +http://youtu.be/pPk-6N1wXoE +http://youtu.be/VGbrR7GfDck +*/ + +ROM_START( rbspm ) + ROM_REGION( 0x80000, "maincpu", 0 ) /* 68000 Code */ + ROM_LOAD( "MJ-DFMJ-P1.bin", 0x00000, 0x80000, CRC(8f81f154) SHA1(50a9a373dec96b0265907f053d068d636bdabd61) ) + + ROM_REGION( 0x1000, "mcu", 0 ) /* protected MCU */ + ROM_LOAD( "89c51.bin", 0x0, 0x1000, NO_DUMP ) // reads as all 0xff + + ROM_REGION( 0x1000, "pic", 0 ) /* pic was populated on this board */ + ROM_LOAD( "pic16f84.bin", 0x0, 0x1000, NO_DUMP ) + + ROM_REGION( 0x20000, "user1", 0 ) /* ??? mcu data / code */ + ROM_LOAD( "MJ-DFMJ-2.2-XX.bin", 0x00000, 0x20000, CRC(58a9eea2) SHA1(1a251e9b049bc8dafbc0728b3d876fdd5a1c8dd9) ) + + ROM_REGION( 0x080000, "oki", 0 ) /* Samples */ + ROM_LOAD( "MJ-DFMJ-2.2-S1.bin", 0x00000, 0x80000, CRC(2410bb61) SHA1(54e258e4af089841a63e45f25aad70310a28d76b) ) // 1st and 2nd half identical + + ROM_REGION( 0x80000, "gfx1", 0 ) /* 8x32 tiles, lots of girls etc. */ + ROM_LOAD( "MJ-DFMJ-4.2-A1.bin", 0x00000, 0x80000, CRC(b0a3a866) SHA1(cc950532160a066fc6ce427f6df9d58ee4589821) ) + + ROM_REGION( 0x80000, "gfx2", 0 ) /* 8x8 tiles? cards etc */ + ROM_LOAD( "MJ-DFMJ-4.8-T1.bin", 0x00000, 0x80000, CRC(2b8b689d) SHA1(65ab643fac1e734af8b3a86caa06b532baafa0fe) ) + + ROM_REGION16_BE( 0x80, "eeprom", 0 ) /* eeprom */ + ROM_LOAD16_WORD_SWAP( "93c46.u51", 0x00, 0x080, NO_DUMP ) +ROM_END -GAME( 1998, rbmk, 0, rbmk, rbmk, rbmk_state, 0, ROT0, "GMS", "Real Battle Mahjong King", MACHINE_NOT_WORKING ) +GAME( 1998, rbmk, 0, rbmk, rbmk, rbmk_state, 0, ROT0, "GMS", "Real Battle Mahjong King (Version 8.8)", MACHINE_NOT_WORKING ) +GAME( 1998, rbspm, 0, rbspm, rbspm, rbmk_state, 0, ROT0, "GMS", "Real Battle Super Phoenix Mahjong (Version 4.1)", MACHINE_NOT_WORKING ) diff --git a/src/mame/drivers/rd100.cpp b/src/mame/drivers/rd100.cpp index c59cf054f5e..63386eda565 100644 --- a/src/mame/drivers/rd100.cpp +++ b/src/mame/drivers/rd100.cpp @@ -34,15 +34,14 @@ private: }; -static ADDRESS_MAP_START( rd100_mem, AS_PROGRAM, 8, rd100_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, rd100_state ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x0000, 0x87ff) AM_RAM + AM_RANGE(0x0000, 0x7fff) AM_RAM + //AM_RANGE(0x8640, 0x8643) // device + //AM_RANGE(0x8700, 0x8700) // device AM_RANGE(0x8800, 0xffff) AM_ROM AM_REGION("roms", 0x800) ADDRESS_MAP_END -static ADDRESS_MAP_START( rd100_io, AS_IO, 8, rd100_state ) -ADDRESS_MAP_END - /* Input ports */ static INPUT_PORTS_START( rd100 ) INPUT_PORTS_END @@ -89,8 +88,7 @@ MACHINE_RESET_MEMBER( rd100_state, rd100 ) static MACHINE_CONFIG_START( rd100 ) // basic machine hardware MCFG_CPU_ADD("maincpu",M6809E, XTAL_4MHz) // freq unknown - MCFG_CPU_PROGRAM_MAP(rd100_mem) - MCFG_CPU_IO_MAP(rd100_io) + MCFG_CPU_PROGRAM_MAP(mem_map) MCFG_MACHINE_RESET_OVERRIDE(rd100_state, rd100) diff --git a/src/mame/drivers/rex6000.cpp b/src/mame/drivers/rex6000.cpp index ecf130f3dc8..5e1c6f53e28 100644 --- a/src/mame/drivers/rex6000.cpp +++ b/src/mame/drivers/rex6000.cpp @@ -898,13 +898,13 @@ static MACHINE_CONFIG_START( rex6000 ) MCFG_DEVICE_ADD("bank0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(rex6000_banked_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_DEVICE_ADD("bank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(rex6000_banked_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_DEVICE_ADD( "ns16550", NS16550, XTAL_1_8432MHz ) @@ -987,13 +987,13 @@ static MACHINE_CONFIG_START( oz750 ) MCFG_DEVICE_ADD("bank0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(oz750_banked_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_DEVICE_ADD("bank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(oz750_banked_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) /* quickload */ diff --git a/src/mame/drivers/riscpc.cpp b/src/mame/drivers/riscpc.cpp index 6a89cf73a0d..86f9f9a4e68 100644 --- a/src/mame/drivers/riscpc.cpp +++ b/src/mame/drivers/riscpc.cpp @@ -589,7 +589,7 @@ TIMER_CALLBACK_MEMBER(riscpc_state::IOMD_timer0_callback) m_IRQ_status_A|=0x20; if(m_IRQ_mask_A&0x20) { - generic_pulse_irq_line(*m_maincpu, ARM7_IRQ_LINE,1); + m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); } } @@ -598,7 +598,7 @@ TIMER_CALLBACK_MEMBER(riscpc_state::IOMD_timer1_callback) m_IRQ_status_A|=0x40; if(m_IRQ_mask_A&0x40) { - generic_pulse_irq_line(*m_maincpu, ARM7_IRQ_LINE,1); + m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); } } @@ -607,7 +607,7 @@ TIMER_CALLBACK_MEMBER(riscpc_state::flyback_timer_callback) m_IRQ_status_A|=0x08; if(m_IRQ_mask_A&0x08) { - generic_pulse_irq_line(*m_maincpu, ARM7_IRQ_LINE,1); + m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); } m_flyback_timer->adjust(machine().first_screen()->time_until_pos(m_vidc20_vert_reg[VDER])); @@ -883,8 +883,8 @@ ROM_START(rpc600) ROM_REGION( 0x800000, "user1", ROMREGION_ERASEFF ) // Version 3.50 ROM_SYSTEM_BIOS( 0, "350", "RiscOS 3.50" ) - ROMX_LOAD( "0277,521-01.bin", 0x000000, 0x100000, CRC(8ba4444e) SHA1(1b31d7a6e924bef0e0056c3a00a3fed95e55b175), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1)) - ROMX_LOAD( "0277,522-01.bin", 0x000002, 0x100000, CRC(2bc95c9f) SHA1(f8c6e2a1deb4fda48aac2e9fa21b9e01955331cf), ROM_GROUPWORD | ROM_SKIP(2) | ROM_BIOS(1)) + ROMX_LOAD( "0277,521-01.bin", 0x000000, 0x100000, CRC(8ba4444e) SHA1(1b31d7a6e924bef0e0056c3a00a3fed95e55b175), ROM_BIOS(1)) + ROMX_LOAD( "0277,522-01.bin", 0x100000, 0x100000, CRC(2bc95c9f) SHA1(f8c6e2a1deb4fda48aac2e9fa21b9e01955331cf), ROM_BIOS(1)) ROM_REGION( 0x800000, "vram", ROMREGION_ERASE00 ) ROM_END diff --git a/src/mame/drivers/rt1715.cpp b/src/mame/drivers/rt1715.cpp index 73838113c6c..fc04e2392d1 100644 --- a/src/mame/drivers/rt1715.cpp +++ b/src/mame/drivers/rt1715.cpp @@ -18,7 +18,7 @@ #include "cpu/z80/z80.h" #include "machine/ram.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80dma.h" #include "machine/z80pio.h" #include "video/i8275.h" @@ -194,7 +194,7 @@ static ADDRESS_MAP_START( rt1715_io, AS_IO, 8, rt1715_state ) AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("a71", z80pio_device, read_alt, write_alt) AM_RANGE(0x04, 0x07) AM_DEVREADWRITE("a72", z80pio_device, read_alt, write_alt) AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE("a30", z80ctc_device, read, write) - AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("a29", z80sio0_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("a29", z80sio_device, ba_cd_r, ba_cd_w) AM_RANGE(0x18, 0x19) AM_DEVREADWRITE("a26", i8275_device, read, write) AM_RANGE(0x20, 0x20) AM_WRITE(rt1715_floppy_enable) AM_RANGE(0x28, 0x28) AM_WRITE(rt1715_rom_disable) @@ -303,7 +303,7 @@ static MACHINE_CONFIG_START( rt1715 ) MCFG_DEVICE_ADD("a30", Z80CTC, XTAL_10MHz/4 /* ? */) - MCFG_DEVICE_ADD("a29", Z80SIO0, XTAL_10MHz/4 /* ? */) + MCFG_DEVICE_ADD("a29", Z80SIO, XTAL_10MHz/4 /* ? */) /* floppy */ MCFG_DEVICE_ADD("a71", Z80PIO, XTAL_10MHz/4 /* ? */) diff --git a/src/mame/drivers/sacstate.cpp b/src/mame/drivers/sacstate.cpp index 067b2703563..33db4bbf8f8 100644 --- a/src/mame/drivers/sacstate.cpp +++ b/src/mame/drivers/sacstate.cpp @@ -38,28 +38,27 @@ Other input will either result in '!' message, or halt. #include "cpu/i8008/i8008.h" #include "machine/terminal.h" -#define TERMINAL_TAG "terminal" class sacstate_state : public driver_device { public: sacstate_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG) - { - } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_terminal(*this, "terminal") + { } - required_device<cpu_device> m_maincpu; - required_device<generic_terminal_device> m_terminal; DECLARE_READ8_MEMBER(port00_r); DECLARE_READ8_MEMBER(port01_r); DECLARE_READ8_MEMBER(port04_r); DECLARE_WRITE8_MEMBER(port08_w); void kbd_put(u8 data); +private: uint8_t m_term_data; uint8_t m_val; virtual void machine_reset() override; + required_device<cpu_device> m_maincpu; + required_device<generic_terminal_device> m_terminal; }; READ8_MEMBER( sacstate_state::port01_r ) @@ -105,7 +104,7 @@ static ADDRESS_MAP_START(sacstate_io, AS_IO, 8, sacstate_state) AM_RANGE(0x01,0x01) AM_READ(port01_r) AM_RANGE(0x04,0x04) AM_READ(port04_r) AM_RANGE(0x08,0x08) AM_WRITE(port08_w) - AM_RANGE(0x16,0x16) AM_DEVWRITE(TERMINAL_TAG, generic_terminal_device, write) + AM_RANGE(0x16,0x16) AM_DEVWRITE("terminal", generic_terminal_device, write) AM_RANGE(0x17,0x1f) AM_WRITENOP ADDRESS_MAP_END @@ -135,7 +134,7 @@ static MACHINE_CONFIG_START( sacstate ) MCFG_CPU_IO_MAP(sacstate_io) /* video hardware */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) + MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(sacstate_state, kbd_put)) MACHINE_CONFIG_END diff --git a/src/mame/drivers/savia84.cpp b/src/mame/drivers/savia84.cpp index ad3e76c7685..35c0b53b071 100644 --- a/src/mame/drivers/savia84.cpp +++ b/src/mame/drivers/savia84.cpp @@ -58,14 +58,14 @@ private: required_device<i8255_device> m_ppi8255; }; -static ADDRESS_MAP_START( savia84_mem, AS_PROGRAM, 8, savia84_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, savia84_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0x7fff) // A15 not connected at the CPU AM_RANGE(0x0000, 0x07ff) AM_ROM AM_RANGE(0x1800, 0x1fff) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( savia84_io, AS_IO, 8, savia84_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, savia84_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0x07) AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("ppi8255", i8255_device, read, write) // ports F8-FB @@ -173,8 +173,8 @@ READ8_MEMBER( savia84_state::savia84_8255_portc_r ) // IN FA - read keyboard static MACHINE_CONFIG_START( savia84 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz / 2) - MCFG_CPU_PROGRAM_MAP(savia84_mem) - MCFG_CPU_IO_MAP(savia84_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_DEFAULT_LAYOUT(layout_savia84) diff --git a/src/mame/drivers/scramble.cpp b/src/mame/drivers/scramble.cpp index 114ca3f620e..31d6d039e19 100644 --- a/src/mame/drivers/scramble.cpp +++ b/src/mame/drivers/scramble.cpp @@ -962,7 +962,7 @@ static INPUT_PORTS_START( cavelon ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* protection check? */ INPUT_PORTS_END -/* Same as 'mimonkey' (scobra.c driver) */ +/* Same as 'mimonkey' (scobra.cpp driver) */ static INPUT_PORTS_START( mimonscr ) PORT_START("IN0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) @@ -1394,7 +1394,7 @@ static MACHINE_CONFIG_DERIVED( newsin7, scramble ) MCFG_VIDEO_START_OVERRIDE(scramble_state,newsin7) MACHINE_CONFIG_END -static MACHINE_CONFIG_DERIVED( mrkougar, scramble ) +static MACHINE_CONFIG_DERIVED( mrkougb, scramble ) /* basic machine hardware */ MCFG_CPU_MODIFY("maincpu") @@ -1406,27 +1406,15 @@ static MACHINE_CONFIG_DERIVED( mrkougar, scramble ) MCFG_I8255_OUT_PORTB_CB(WRITE8(scramble_state, mrkougar_sh_irqtrigger_w)) /* video hardware */ - MCFG_GFXDECODE_MODIFY("gfxdecode", mrkougar) MCFG_PALETTE_MODIFY("palette") MCFG_PALETTE_ENTRIES(32+64+2+0) /* 32 for characters, 64 for stars, 2 for bullets, 0/1 for background */ MCFG_PALETTE_INIT_OWNER(scramble_state,galaxold) MACHINE_CONFIG_END -static MACHINE_CONFIG_DERIVED( mrkougb, scramble ) - - /* basic machine hardware */ - MCFG_CPU_MODIFY("maincpu") - MCFG_CPU_PROGRAM_MAP(mrkougar_map) - - MCFG_DEVICE_REMOVE("ppi8255_1") - MCFG_DEVICE_ADD("ppi8255_1", I8255A, 0) - MCFG_I8255_OUT_PORTA_CB(DEVWRITE8("soundlatch", generic_latch_8_device, write)) - MCFG_I8255_OUT_PORTB_CB(WRITE8(scramble_state, mrkougar_sh_irqtrigger_w)) +static MACHINE_CONFIG_DERIVED( mrkougar, mrkougb ) /* video hardware */ - MCFG_PALETTE_MODIFY("palette") - MCFG_PALETTE_ENTRIES(32+64+2+0) /* 32 for characters, 64 for stars, 2 for bullets, 0/1 for background */ - MCFG_PALETTE_INIT_OWNER(scramble_state,galaxold) + MCFG_GFXDECODE_MODIFY("gfxdecode", mrkougar) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( ckongs, scramble ) @@ -1969,6 +1957,25 @@ ROM_START( mrkougb2 ) ROM_LOAD( "atw-prom.bin", 0x0000, 0x0020, CRC(c65db188) SHA1(90f0a5f22bb761693ab5895da08b20821e79ba65) ) ROM_END +ROM_START( troopy ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "ic2cb.bin", 0x0000, 0x1000, CRC(a1798961) SHA1(45a1f6183016229fced3b459c95c99d83408151a) ) + ROM_LOAD( "ic2eb.bin", 0x1000, 0x1000, CRC(7f3572f9) SHA1(2f89f743a32378ed4ac4184627ed9be007c3334a) ) + ROM_LOAD( "ic2fb.bin", 0x2000, 0x1000, CRC(42e666fd) SHA1(caa6a2b07098ef1d6203309ddd3a591194b4ac70) ) + + ROM_REGION( 0x10000, "audiocpu", 0 ) + ROM_LOAD( "ic5c.bin", 0x0000, 0x1000, CRC(af42a371) SHA1(edacbb29df34fdf400a5c726d851af1479a34c70) ) + ROM_LOAD( "ic5d.bin", 0x1000, 0x1000, CRC(862b8902) SHA1(91dcbc634f7c7ed78dfbd0be5cf1e0631429cfbf) ) + ROM_LOAD( "ic5e.bin", 0x2000, 0x1000, CRC(a0396cc8) SHA1(c8266b58b144a4bc564f3a2503d5b953c0ba6ca7) ) + + ROM_REGION( 0x1000, "gfx1", 0 ) + ROM_LOAD( "ic5h_neu.bin", 0x0000, 0x0800, CRC(0f4a2394) SHA1(a6c309ca6afa59fbe6549d6fd282902f018a1a48) ) + ROM_LOAD( "ic5f_neu.bin", 0x0800, 0x0800, CRC(cbbfefc2) SHA1(2378949275b8d3fc69551b00d9b2c654b91fd780) ) + + ROM_REGION( 0x0020, "proms", 0 ) + ROM_LOAD( "82s123", 0x0000, 0x0020, CRC(4e3caeab) SHA1(a25083c3e36d28afdefe4af6e6d4f3155e303625) ) +ROM_END + ROM_START( hotshock ) ROM_REGION( 0x10000, "maincpu", 0 ) ROM_LOAD( "0d.l10", 0x0000, 0x1000, CRC(3e8aeaeb) SHA1(0572623928d36d106c9d8028d92fbd02375291a5) ) @@ -2204,7 +2211,7 @@ ROM_START( ad2083 ) ROM_END -ROM_START( harem ) /* Main PCB version simular to Scorpion (also developed by I.G.R), sound PCB is identical to Scorpion */ +ROM_START( harem ) /* Main PCB version similar to Scorpion (also developed by I.G.R), sound PCB is identical to Scorpion */ ROM_REGION( 0x10000, "maincpu", 0 ) ROM_LOAD( "harem_prom0.ic85", 0x0000, 0x2000, CRC(4521b753) SHA1(9033f9c3be8fec1e5ff251e9f60faaf3848a1a1e) ) ROM_LOAD( "harem_prom1.ic87", 0x8000, 0x2000, CRC(3cc5d1e8) SHA1(827e2d20de2a00ec016ead249ed3afdccd0c856c) ) // encrypted @@ -2213,7 +2220,7 @@ ROM_START( harem ) /* Main PCB version simular to Scorpion (also developed by I. ROM_LOAD( "harem_sound1.ic12", 0x0000, 0x2000, CRC(b54799dd) SHA1(b6aeb010257cba48a52afd33b4f8031c7d99550c) ) ROM_LOAD( "harem_sound2.ic13", 0x2000, 0x1000, CRC(2d5573a4) SHA1(1fdcd99d89e078509634742b2116a35bb199fe4b) ) - ROM_REGION( 0x2000, "digitalker", 0 ) // DigiTalker ROM (same exact sound PCB as Scorpion (galaxian.c)) + ROM_REGION( 0x2000, "digitalker", 0 ) // DigiTalker ROM (same exact sound PCB as Scorpion (galaxian.cpp)) ROM_LOAD( "harem_h1+h2.ic25", 0x0000, 0x2000, CRC(279f923a) SHA1(166b1b625997766f0de7cc18af52c42268022fcb) ) ROM_REGION( 0x4000, "gfx1", 0 ) @@ -2245,8 +2252,9 @@ GAME( 1982, newsin7a, newsin7, newsin7, newsin7, scramble_state, newsin7a, GAME( 1984, mrkougar, 0, mrkougar, mrkougar, scramble_state, mrkougar, ROT90, "ATW", "Mr. Kougar", MACHINE_SUPPORTS_SAVE ) GAME( 1983, mrkougar2,mrkougar, mrkougar, mrkougar, scramble_state, mrkougar, ROT90, "ATW", "Mr. Kougar (earlier)", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, mrkougb, mrkougar, mrkougb, mrkougar, scramble_state, mrkougb, ROT90, "bootleg", "Mr. Kougar (bootleg set 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1983, mrkougb2, mrkougar, mrkougb, mrkougar, scramble_state, mrkougb, ROT90, "bootleg", "Mr. Kougar (bootleg set 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1984, mrkougb, mrkougar, mrkougb, mrkougar, scramble_state, 0, ROT90, "bootleg (Gross)", "Mr. Kougar (German bootleg)", MACHINE_SUPPORTS_SAVE ) +GAME( 1983, mrkougb2, mrkougar, mrkougb, mrkougar, scramble_state, 0, ROT90, "bootleg", "Mr. Kougar (bootleg)", MACHINE_SUPPORTS_SAVE ) +GAME( 1984, troopy, mrkougar, mrkougb, mrkougar, scramble_state, mrkougar, ROT90, "bootleg", "Troopy (bootleg of Mr. Kougar)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) // wrong loading / decoding or bad GFX ROMs? GAME( 1982, hotshock, 0, hotshock, hotshock, scramble_state, hotshock, ROT90, "E.G. Felaco (Domino license)", "Hot Shocker", MACHINE_SUPPORTS_SAVE ) GAME( 1982, hotshockb,hotshock, hotshock, hotshock, scramble_state, hotshock, ROT90, "E.G. Felaco", "Hot Shocker (early revision?)", MACHINE_SUPPORTS_SAVE ) // has "Dudley presents" (protagonist of the game), instead of Domino diff --git a/src/mame/drivers/sdk86.cpp b/src/mame/drivers/sdk86.cpp index 0ca083a2898..510a819db78 100644 --- a/src/mame/drivers/sdk86.cpp +++ b/src/mame/drivers/sdk86.cpp @@ -2,7 +2,7 @@ // copyright-holders:Miodrag Milanovic, Jonathan Gevaryahu, Robbbert /*************************************************************************** - Intel SDK-86 + Intel MCS-86 System Design Kit (SDK-86) 12/05/2009 Skeleton driver by Micko 29/11/2009 Some fleshing out by Lord Nightmare @@ -31,6 +31,7 @@ ToDo: #include "cpu/i86/i86.h" #include "machine/clock.h" #include "machine/i8251.h" +#include "machine/i8255.h" #include "machine/i8279.h" #include "sdk86.lh" @@ -65,8 +66,8 @@ static ADDRESS_MAP_START(sdk86_io, AS_IO, 16, sdk86_state) AM_RANGE(0xfff0, 0xfff1) AM_MIRROR(4) AM_DEVREADWRITE8(I8251_TAG, i8251_device, data_r, data_w, 0xff) AM_RANGE(0xfff2, 0xfff3) AM_MIRROR(4) AM_DEVREADWRITE8(I8251_TAG, i8251_device, status_r, control_w, 0xff) AM_RANGE(0xffe8, 0xffeb) AM_MIRROR(4) AM_DEVREADWRITE8("i8279", i8279_device, read, write, 0xff) - // FFF8-FFFF = 2 x 8255A i/o chips. chip 1 uses the odd addresses, chip 2 uses the even addresses. - // ports are A,B,C,control in that order. + AM_RANGE(0xfff8, 0xffff) AM_DEVREADWRITE8("port1", i8255_device, read, write, 0xff00) + AM_RANGE(0xfff8, 0xffff) AM_DEVREADWRITE8("port2", i8255_device, read, write, 0x00ff) ADDRESS_MAP_END /* Input ports */ @@ -155,7 +156,7 @@ static MACHINE_CONFIG_START( sdk86 ) MCFG_RS232_DSR_HANDLER(DEVWRITELINE(I8251_TAG, i8251_device, write_dsr)) MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) - MCFG_DEVICE_ADD("usart_clock", CLOCK, 307200) + MCFG_DEVICE_ADD("usart_clock", CLOCK, XTAL_14_7456MHz/3/16) MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE(I8251_TAG, i8251_device, write_txc)) MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE(I8251_TAG, i8251_device, write_rxc)) @@ -166,6 +167,8 @@ static MACHINE_CONFIG_START( sdk86 ) MCFG_I8279_IN_SHIFT_CB(GND) // Shift key MCFG_I8279_IN_CTRL_CB(GND) + MCFG_DEVICE_ADD("port1", I8255A, 0) + MCFG_DEVICE_ADD("port2", I8255A, 0) MACHINE_CONFIG_END /* ROM definition */ @@ -209,4 +212,4 @@ ROM_END /* Driver */ /* YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS */ -COMP( 1979, sdk86, 0, 0, sdk86, sdk86, sdk86_state, 0, "Intel", "SDK-86", MACHINE_NO_SOUND_HW) +COMP( 1979, sdk86, 0, 0, sdk86, sdk86, sdk86_state, 0, "Intel", "MCS-86 System Design Kit", MACHINE_NO_SOUND_HW) diff --git a/src/mame/drivers/seattlecmp.cpp b/src/mame/drivers/seattlecmp.cpp index 3ce4e6f88b6..2d5956bf215 100644 --- a/src/mame/drivers/seattlecmp.cpp +++ b/src/mame/drivers/seattlecmp.cpp @@ -35,6 +35,7 @@ There is a 4MHz crystal connected to the 9513. #include "machine/i8251.h" #include "machine/pic8259.h" #include "bus/rs232/rs232.h" +//#include "bus/s100/s100.h" class seattle_comp_state : public driver_device @@ -63,13 +64,13 @@ READ8_MEMBER(seattle_comp_state::pic_slave_ack) } -static ADDRESS_MAP_START(seattle_mem, AS_PROGRAM, 16, seattle_comp_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 16, seattle_comp_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00000,0xff7ff) AM_RAM AM_RANGE(0xff800,0xfffff) AM_ROM AM_REGION("user1", 0) ADDRESS_MAP_END -static ADDRESS_MAP_START(seattle_io, AS_IO, 16, seattle_comp_state) +static ADDRESS_MAP_START(io_map, AS_IO, 16, seattle_comp_state) //ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0xf0, 0xf1) AM_DEVREADWRITE8("pic1", pic8259_device, read, write, 0xffff) @@ -99,8 +100,8 @@ DEVICE_INPUT_DEFAULTS_END static MACHINE_CONFIG_START( seattle ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", I8086, XTAL_24MHz / 3) // 8 MHz or 4 MHz selectable - MCFG_CPU_PROGRAM_MAP(seattle_mem) - MCFG_CPU_IO_MAP(seattle_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic1", pic8259_device, inta_cb) MCFG_DEVICE_ADD("pic1", PIC8259, 0) @@ -134,7 +135,7 @@ static MACHINE_CONFIG_START( seattle ) MACHINE_CONFIG_END /* ROM definition */ -ROM_START( seattle ) +ROM_START( scp300f ) ROM_REGION( 0x800, "user1", 0 ) ROM_LOAD( "mon86 v1.5tdd", 0x0000, 0x0800, CRC(7db23169) SHA1(c791b02ca33a4e1f8e95eb541624a59738f378c4)) ROM_END @@ -142,4 +143,4 @@ ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1986, seattle, 0, 0, seattle, seattle, seattle_comp_state, 0, "Seattle Computer", "SCP-300F", MACHINE_NO_SOUND_HW ) +COMP( 1986, scp300f, 0, 0, seattle, seattle, seattle_comp_state, 0, "Seattle Computer", "SCP-300F", MACHINE_NO_SOUND_HW ) diff --git a/src/mame/drivers/segac2.cpp b/src/mame/drivers/segac2.cpp index ce827f0f14a..fe536d93d3e 100644 --- a/src/mame/drivers/segac2.cpp +++ b/src/mame/drivers/segac2.cpp @@ -2559,7 +2559,7 @@ GAME( 1994, tantrbl3, tantr, segac, ichir, segac2_state, tantr, ROT0, GAME( 1992, wwmarine, 0, segac2, wwmarine, segac2_state, bloxeedc, ROT0, "Sega", "Waku Waku Marine", 0 ) // not really sure how this should hook up, things like the 'sold out' flags could be mechanical sensors, or from another MCU / CPU board in the actual popcorn part of the machine? -GAME( 199?, anpanman, 0, segac2, anpanman, segac2_state, bloxeedc, ROT0, "Sega", "Soreike! Anpanman Popcorn Factory (Rev B)", MACHINE_MECHANICAL ) // 'Mechanical' part isn't emulated +GAME( 1992, anpanman, 0, segac2, anpanman, segac2_state, bloxeedc, ROT0, "Sega", "Soreike! Anpanman Popcorn Factory (Rev B)", MACHINE_MECHANICAL ) // 'Mechanical' part isn't emulated GAME( 1993, sonicpop, 0, segac2, sonicpop, segac2_state, bloxeedc, ROT0, "Sega", "SegaSonic Popcorn Shop (Rev B)", MACHINE_MECHANICAL ) // region DSW for USA / Export / Japan, still speaks Japanese tho. 'Mechanical' part isn't emulated GAME( 1993, sonicfgt, 0, segac2, systemc_generic, segac2_state, bloxeedc, ROT0, "Sega", "Sega Sonic Cosmo Fighter", 0 ) diff --git a/src/mame/drivers/segam1.cpp b/src/mame/drivers/segam1.cpp index b4ce2ac3031..da97eb34220 100644 --- a/src/mame/drivers/segam1.cpp +++ b/src/mame/drivers/segam1.cpp @@ -426,4 +426,4 @@ ROM_START( unkm1 ) // 1992.01.31 string ROM_END GAME( 1994, bingpty, 0, segam1, segam1, segam1_state, 0, ROT0, "Sega", "Bingo Party Multicart (Rev B) (M1 Satellite board)", MACHINE_NOT_WORKING ) -GAME( 1992, unkm1, 0, unkm1, segam1, segam1_state, 0, ROT0, "Sega", "Unknown Sega gambling game (M1 Satellite board)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +GAME( 1992, unkm1, 0, unkm1, segam1, segam1_state, 0, ROT0, "Sega", "unknown Sega gambling game (M1 Satellite board)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/segas16a.cpp b/src/mame/drivers/segas16a.cpp index 06d4f8481ca..6650af776f7 100644 --- a/src/mame/drivers/segas16a.cpp +++ b/src/mame/drivers/segas16a.cpp @@ -1188,6 +1188,83 @@ static INPUT_PORTS_START( afighter ) INPUT_PORTS_END +CUSTOM_INPUT_MEMBER(afighter_16a_analog_state::afighter_accel_r) +{ + int accel = m_accel->read(); + + switch ((accel & 0xc0) >> 4) + { + case 0x00: return 0; + case 0x04: return (1 << 0); + case 0x08: return (1 << 1); + case 0x0c: return (1 << 2); + } + + return 0; +} + +CUSTOM_INPUT_MEMBER(afighter_16a_analog_state::afighter_handl_left_r) +{ + int steer = m_steer->read(); + + switch ((steer & 0xf0) >> 4) + { + case 0x00: return (1<<7); + case 0x01: return (1<<6); + case 0x02: return (1<<5); + case 0x03: return (1<<4); + case 0x04: return (1<<3); + case 0x05: return (1<<2); + case 0x06: return (1<<1); + case 0x07: return (1<<0); + } + return 0x00; +} + +CUSTOM_INPUT_MEMBER(afighter_16a_analog_state::afighter_handl_right_r) +{ + int steer = m_steer->read(); + + switch ((steer & 0xf0)>>4) + { + case 0x0f: return (1<<7); + case 0x0e: return (1<<6); + case 0x0d: return (1<<5); + case 0x0c: return (1<<4); + case 0x0b: return (1<<3); + case 0x0a: return (1<<2); + case 0x09: return (1<<1); + case 0x08: return (1<<0); + } + + return 0x00; +} + +static INPUT_PORTS_START( afighter_analog ) + PORT_INCLUDE( afighter ) + + PORT_MODIFY("P1") + PORT_BIT( 0x07, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, afighter_16a_analog_state, afighter_accel_r, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) // SHOT + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) // WEAPON1 + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) // WEAPON2 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4 ) // WEAPON3 + + PORT_MODIFY("P2") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, afighter_16a_analog_state, afighter_handl_left_r, nullptr) + + PORT_MODIFY("UNUSED") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, afighter_16a_analog_state, afighter_handl_right_r, nullptr) + + PORT_START("STEER") // steering + PORT_BIT( 0xff, 0x00, IPT_PADDLE ) PORT_SENSITIVITY(100) PORT_KEYDELTA(4) + + PORT_START("ACCEL") // gas pedal + PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) +INPUT_PORTS_END + + static INPUT_PORTS_START( alexkidd ) PORT_INCLUDE( system16a_generic ) @@ -2115,6 +2192,7 @@ ROM_END // Action Fighter, Sega System 16A // CPU: FD1089A 317-0018?@(dedicated cabinet version uses 317-0014) // + ROM_START( afighter ) ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code ROM_LOAD16_BYTE( "epr-10350", 0x00001, 0x08000, CRC(f2cd6b3f) SHA1(380f75b8c1696b388179641866cd1d23f78664e7) ) @@ -2146,6 +2224,123 @@ ROM_START( afighter ) ROM_LOAD( "317-0018.key", 0x0000, 0x2000, CRC(fee04be8) SHA1(c58d78299ef4cede517be823a8a8a90e46c6ba0d) ) ROM_END +ROM_START( afightera ) + ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code + ROM_LOAD16_BYTE( "epr10315.bin", 0x00001, 0x08000, CRC(2ea55eae) SHA1(91d582eaa0483d547d1a37dedb8f029a0fccb526) ) // decrypted version of 10350 + ROM_LOAD16_BYTE( "epr10318.bin", 0x00000, 0x08000, CRC(d05b240d) SHA1(aa4aa7b18b53ac7b533855a44f9a4a0c14e1da2a) ) + ROM_LOAD16_BYTE( "epr10316.bin", 0x10001, 0x08000, CRC(07522474) SHA1(1a4bce4c04defab3516a90b9fa62fad1945a1176) ) // == epr10294.bin + ROM_LOAD16_BYTE( "epr10319.bin", 0x10000, 0x08000, CRC(e48c4d80) SHA1(9c40972f81e004de84db4199e7dc0ceb6a998e76) ) // == epr10297.bin + ROM_LOAD16_BYTE( "epr10317.bin", 0x20001, 0x08000, CRC(6e00db36) SHA1(5e3d03f7441515ad7dac411f492f2e159330a90a) ) + ROM_LOAD16_BYTE( "epr10320.bin", 0x20000, 0x08000, CRC(5f97c2fa) SHA1(5fef94bc275d9132dde8b72bfb661f10efdc91b1) ) + + ROM_REGION( 0x30000, "gfx1", 0 ) // tiles + ROM_LOAD( "epr-10281.95", 0x00000, 0x10000, CRC(30e92cda) SHA1(36293a2a8a22dca5350571f19f3d5d04e1b27458) ) + ROM_LOAD( "epr-10282.94", 0x10000, 0x10000, CRC(b67b8910) SHA1(f3f029a3e6547114cec28e5cf8fda65ef434c353) ) + ROM_LOAD( "epr-10283.93", 0x20000, 0x10000, CRC(e7dbfd2d) SHA1(91bae3fbc4a3c612dc507eecfa8de1c2e1e7afee) ) + + ROM_REGION16_BE( 0x40000, "sprites", 0 ) // sprites + ROM_LOAD16_BYTE( "epr-10285", 0x00001, 0x08000, CRC(98aa3d04) SHA1(1d26d17a72e55281e3444fee9c5af69ffb9e3c69) ) + ROM_LOAD16_BYTE( "epr-10286", 0x10001, 0x08000, CRC(8da050cf) SHA1(c28e8968dbd9c110672581f4486f70d5f45df7f5) ) + ROM_LOAD16_BYTE( "epr-10287", 0x20001, 0x08000, CRC(7989b74a) SHA1(a87acafe82b37a11d8f8b1f2ee4c9b2e1bb8161c) ) + ROM_LOAD16_BYTE( "epr-10288", 0x30001, 0x08000, CRC(d3ce551a) SHA1(0ff2170d9ef89058273025dd8d5e1021094adef1) ) + ROM_LOAD16_BYTE( "epr-10289", 0x00000, 0x08000, CRC(c59d1b98) SHA1(e232f2519234981c0e4ffecdd25c48083d9f93a8) ) + ROM_LOAD16_BYTE( "epr-10290", 0x10000, 0x08000, CRC(39354223) SHA1(d8a73d3f7fc2d83d23bb7434f43bc8804f35cc16) ) + ROM_LOAD16_BYTE( "epr-10291", 0x20000, 0x08000, CRC(6e4b245c) SHA1(1f8cecf7ea2d2dfa5ce18d7ee34b0da2cc40221e) ) + ROM_LOAD16_BYTE( "epr-10292", 0x30000, 0x08000, CRC(cef289a3) SHA1(7ab817b6348c168f79be325fb3cc2cca14ee0f8e) ) + + ROM_REGION( 0x10000, "soundcpu", 0 ) // sound CPU + ROM_LOAD( "epr-10284.12", 0x00000, 0x8000, CRC(8ff09116) SHA1(8b99b6d2499897cfbd037a7e7cf5bc53bce8a63a) ) +ROM_END + +ROM_START( afighterb ) + ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code + ROM_LOAD16_BYTE( "epr10293.bin", 0x00001, 0x08000, CRC(186ae21a) SHA1(65bff753b7ed7b3b03cc70634df9f2ff0d233323) ) // == decrypted 10275 + ROM_LOAD16_BYTE( "epr10296.bin", 0x00000, 0x08000, CRC(7370e889) SHA1(d240defae86e97467002e549d213359c3e23ec54) ) + ROM_LOAD16_BYTE( "epr10294.bin", 0x10001, 0x08000, CRC(07522474) SHA1(1a4bce4c04defab3516a90b9fa62fad1945a1176) ) + ROM_LOAD16_BYTE( "epr10297.bin", 0x10000, 0x08000, CRC(e48c4d80) SHA1(9c40972f81e004de84db4199e7dc0ceb6a998e76) ) + ROM_LOAD16_BYTE( "epr10295.bin", 0x20001, 0x08000, CRC(a940fde6) SHA1(7b7c2b904ae83dfb9e9ac0855e30408234fe371f) ) + ROM_LOAD16_BYTE( "epr10298.bin", 0x20000, 0x08000, CRC(f6bab36e) SHA1(1e7a0403de5ede8055507274bd43ea7ab1219f27) ) + + ROM_REGION( 0x30000, "gfx1", 0 ) // tiles + ROM_LOAD( "epr-10281.95", 0x00000, 0x10000, CRC(30e92cda) SHA1(36293a2a8a22dca5350571f19f3d5d04e1b27458) ) + ROM_LOAD( "epr-10282.94", 0x10000, 0x10000, CRC(b67b8910) SHA1(f3f029a3e6547114cec28e5cf8fda65ef434c353) ) + ROM_LOAD( "epr-10283.93", 0x20000, 0x10000, CRC(e7dbfd2d) SHA1(91bae3fbc4a3c612dc507eecfa8de1c2e1e7afee) ) + + ROM_REGION16_BE( 0x40000, "sprites", 0 ) // sprites + ROM_LOAD16_BYTE( "epr-10285", 0x00001, 0x08000, CRC(98aa3d04) SHA1(1d26d17a72e55281e3444fee9c5af69ffb9e3c69) ) + ROM_LOAD16_BYTE( "epr-10286", 0x10001, 0x08000, CRC(8da050cf) SHA1(c28e8968dbd9c110672581f4486f70d5f45df7f5) ) + ROM_LOAD16_BYTE( "epr-10287", 0x20001, 0x08000, CRC(7989b74a) SHA1(a87acafe82b37a11d8f8b1f2ee4c9b2e1bb8161c) ) + ROM_LOAD16_BYTE( "epr-10288", 0x30001, 0x08000, CRC(d3ce551a) SHA1(0ff2170d9ef89058273025dd8d5e1021094adef1) ) + ROM_LOAD16_BYTE( "epr-10289", 0x00000, 0x08000, CRC(c59d1b98) SHA1(e232f2519234981c0e4ffecdd25c48083d9f93a8) ) + ROM_LOAD16_BYTE( "epr-10290", 0x10000, 0x08000, CRC(39354223) SHA1(d8a73d3f7fc2d83d23bb7434f43bc8804f35cc16) ) + ROM_LOAD16_BYTE( "epr-10291", 0x20000, 0x08000, CRC(6e4b245c) SHA1(1f8cecf7ea2d2dfa5ce18d7ee34b0da2cc40221e) ) + ROM_LOAD16_BYTE( "epr-10292", 0x30000, 0x08000, CRC(cef289a3) SHA1(7ab817b6348c168f79be325fb3cc2cca14ee0f8e) ) + + ROM_REGION( 0x10000, "soundcpu", 0 ) // sound CPU + ROM_LOAD( "epr-10284.12", 0x00000, 0x8000, CRC(8ff09116) SHA1(8b99b6d2499897cfbd037a7e7cf5bc53bce8a63a) ) +ROM_END + +ROM_START( afighterc ) + ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code + ROM_LOAD16_BYTE( "epr10299.bin", 0x00001, 0x08000, CRC(d57b0955) SHA1(ce3bf962313cad25a4bff1348b52da12414c9182) ) // = encrypted 10315 + ROM_LOAD16_BYTE( "epr10302.bin", 0x00000, 0x08000, CRC(e4ccefa2) SHA1(f8ec34fad2c290cc977b49326b3e27552718ddc2) ) + ROM_LOAD16_BYTE( "epr10300.bin", 0x10001, 0x08000, CRC(1c91baa1) SHA1(338a7e56f47623c577dd77e2da56ca2f3e12027e) ) // missing (but probably == epr10276 as encryption seems the same and in the unencrypted sets they match) + ROM_LOAD16_BYTE( "epr10303.bin", 0x10000, 0x08000, CRC(fb67bdce) SHA1(29aba3eeee61a6aa8b695f3be211f5797479566d) ) // missing (but probably == epr10279 as encryption seems the same and in the unencrypted sets they match) + ROM_LOAD16_BYTE( "epr10301.bin", 0x20001, 0x08000, CRC(6b4ef29b) SHA1(3383a25f67b7a153637d0f81cf61d330f8236951) ) + ROM_LOAD16_BYTE( "epr10304.bin", 0x20000, 0x08000, CRC(756f5472) SHA1(44e23fa4e17d4d7573adaaf3f1a14547359e2d06) ) + + ROM_REGION( 0x30000, "gfx1", 0 ) // tiles + ROM_LOAD( "epr-10281.95", 0x00000, 0x10000, CRC(30e92cda) SHA1(36293a2a8a22dca5350571f19f3d5d04e1b27458) ) + ROM_LOAD( "epr-10282.94", 0x10000, 0x10000, CRC(b67b8910) SHA1(f3f029a3e6547114cec28e5cf8fda65ef434c353) ) + ROM_LOAD( "epr-10283.93", 0x20000, 0x10000, CRC(e7dbfd2d) SHA1(91bae3fbc4a3c612dc507eecfa8de1c2e1e7afee) ) + + ROM_REGION16_BE( 0x40000, "sprites", 0 ) // sprites + ROM_LOAD16_BYTE( "epr-10285", 0x00001, 0x08000, CRC(98aa3d04) SHA1(1d26d17a72e55281e3444fee9c5af69ffb9e3c69) ) + ROM_LOAD16_BYTE( "epr-10286", 0x10001, 0x08000, CRC(8da050cf) SHA1(c28e8968dbd9c110672581f4486f70d5f45df7f5) ) + ROM_LOAD16_BYTE( "epr-10287", 0x20001, 0x08000, CRC(7989b74a) SHA1(a87acafe82b37a11d8f8b1f2ee4c9b2e1bb8161c) ) + ROM_LOAD16_BYTE( "epr-10288", 0x30001, 0x08000, CRC(d3ce551a) SHA1(0ff2170d9ef89058273025dd8d5e1021094adef1) ) + ROM_LOAD16_BYTE( "epr-10289", 0x00000, 0x08000, CRC(c59d1b98) SHA1(e232f2519234981c0e4ffecdd25c48083d9f93a8) ) + ROM_LOAD16_BYTE( "epr-10290", 0x10000, 0x08000, CRC(39354223) SHA1(d8a73d3f7fc2d83d23bb7434f43bc8804f35cc16) ) + ROM_LOAD16_BYTE( "epr-10291", 0x20000, 0x08000, CRC(6e4b245c) SHA1(1f8cecf7ea2d2dfa5ce18d7ee34b0da2cc40221e) ) + ROM_LOAD16_BYTE( "epr-10292", 0x30000, 0x08000, CRC(cef289a3) SHA1(7ab817b6348c168f79be325fb3cc2cca14ee0f8e) ) + + ROM_REGION( 0x10000, "soundcpu", 0 ) // sound CPU + ROM_LOAD( "epr-10284.12", 0x00000, 0x8000, CRC(8ff09116) SHA1(8b99b6d2499897cfbd037a7e7cf5bc53bce8a63a) ) + + ROM_REGION( 0x2000, "maincpu:key", 0 ) // decryption key + ROM_LOAD( "317-unknown.key", 0x0000, 0x2000, NO_DUMP ) +ROM_END + +ROM_START( afighterd ) + ROM_REGION( 0x40000, "maincpu", 0 ) // 68000 code + ROM_LOAD16_BYTE( "epr10275.bin", 0x00001, 0x08000, CRC(964c1985) SHA1(cf3d15e6f6611bb5a5ef230a0b25828af776ca33) ) // = encrypted 10293 + ROM_LOAD16_BYTE( "epr10278.bin", 0x00000, 0x08000, CRC(13c6bbad) SHA1(889ad10e27b1638372dbefdab4111488a7ef873c) ) + ROM_LOAD16_BYTE( "epr10276.bin", 0x10001, 0x08000, CRC(1c91baa1) SHA1(338a7e56f47623c577dd77e2da56ca2f3e12027e) ) + ROM_LOAD16_BYTE( "epr10279.bin", 0x10000, 0x08000, CRC(fb67bdce) SHA1(29aba3eeee61a6aa8b695f3be211f5797479566d) ) + ROM_LOAD16_BYTE( "epr10277.bin", 0x20001, 0x08000, CRC(a1534a1b) SHA1(7d3423b2e74624b2ce2b4ad5077653dfcc0226ec) ) + ROM_LOAD16_BYTE( "epr10280.bin", 0x20000, 0x08000, CRC(9bc5496c) SHA1(e7f529feaa4fe4c1d6bcec2cd447cba4b3267d62) ) + + ROM_REGION( 0x30000, "gfx1", 0 ) // tiles + ROM_LOAD( "epr-10281.95", 0x00000, 0x10000, CRC(30e92cda) SHA1(36293a2a8a22dca5350571f19f3d5d04e1b27458) ) + ROM_LOAD( "epr-10282.94", 0x10000, 0x10000, CRC(b67b8910) SHA1(f3f029a3e6547114cec28e5cf8fda65ef434c353) ) + ROM_LOAD( "epr-10283.93", 0x20000, 0x10000, CRC(e7dbfd2d) SHA1(91bae3fbc4a3c612dc507eecfa8de1c2e1e7afee) ) + + ROM_REGION16_BE( 0x40000, "sprites", 0 ) // sprites + ROM_LOAD16_BYTE( "epr-10285", 0x00001, 0x08000, CRC(98aa3d04) SHA1(1d26d17a72e55281e3444fee9c5af69ffb9e3c69) ) + ROM_LOAD16_BYTE( "epr-10286", 0x10001, 0x08000, CRC(8da050cf) SHA1(c28e8968dbd9c110672581f4486f70d5f45df7f5) ) + ROM_LOAD16_BYTE( "epr-10287", 0x20001, 0x08000, CRC(7989b74a) SHA1(a87acafe82b37a11d8f8b1f2ee4c9b2e1bb8161c) ) + ROM_LOAD16_BYTE( "epr-10288", 0x30001, 0x08000, CRC(d3ce551a) SHA1(0ff2170d9ef89058273025dd8d5e1021094adef1) ) + ROM_LOAD16_BYTE( "epr-10289", 0x00000, 0x08000, CRC(c59d1b98) SHA1(e232f2519234981c0e4ffecdd25c48083d9f93a8) ) + ROM_LOAD16_BYTE( "epr-10290", 0x10000, 0x08000, CRC(39354223) SHA1(d8a73d3f7fc2d83d23bb7434f43bc8804f35cc16) ) + ROM_LOAD16_BYTE( "epr-10291", 0x20000, 0x08000, CRC(6e4b245c) SHA1(1f8cecf7ea2d2dfa5ce18d7ee34b0da2cc40221e) ) + ROM_LOAD16_BYTE( "epr-10292", 0x30000, 0x08000, CRC(cef289a3) SHA1(7ab817b6348c168f79be325fb3cc2cca14ee0f8e) ) + + ROM_REGION( 0x10000, "soundcpu", 0 ) // sound CPU + ROM_LOAD( "epr-10284.12", 0x00000, 0x8000, CRC(8ff09116) SHA1(8b99b6d2499897cfbd037a7e7cf5bc53bce8a63a) ) + + ROM_REGION( 0x2000, "maincpu:key", 0 ) // decryption key + ROM_LOAD( "317-unknown.key", 0x0000, 0x2000, NO_DUMP ) +ROM_END //************************************************************************************************************************* //************************************************************************************************************************* @@ -3735,7 +3930,11 @@ GAME( 1987, aliensynjo, aliensyn, system16a_fd1089a, aliensynj, segas16a GAME( 1988, aceattaca, aceattac, aceattaca_fd1094, aceattaca, segas16a_state,aceattaca, ROT270, "Sega", "Ace Attacker (Japan, System 16A, FD1094 317-0060)", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, afighter, 0, system16a_fd1089a_no7751, afighter, segas16a_state,generic, ROT270, "Sega", "Action Fighter (FD1089A 317-0018)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, afighter, 0, system16a_fd1089a_no7751, afighter, segas16a_state, generic, ROT270, "Sega", "Action Fighter (FD1089A 317-0018)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, afightera, afighter, system16a_no7751, afighter, segas16a_state, generic, ROT270, "Sega", "Action Fighter (unprotected)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, afighterb, afighter, system16a_no7751, afighter_analog, afighter_16a_analog_state,generic, ROT270, "Sega", "Action Fighter (unprotected, analog controls)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, afighterc, afighter, system16a_fd1089a_no7751, afighter, segas16a_state, generic, ROT270, "Sega", "Action Fighter (FD1089A 317-unknown)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) // encrypted version of afightera +GAME( 1986, afighterd, afighter, system16a_fd1089a_no7751, afighter_analog, afighter_16a_analog_state,generic, ROT270, "Sega", "Action Fighter (FD1089A 317-unknown, analog controls)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) // encrypted version of afighterb GAME( 1986, alexkidd, 0, system16a, alexkidd, segas16a_state,generic, ROT0, "Sega", "Alex Kidd: The Lost Stars (set 2, unprotected)", MACHINE_SUPPORTS_SAVE ) GAME( 1986, alexkidd1, alexkidd, system16a_fd1089a, alexkidd, segas16a_state,generic, ROT0, "Sega", "Alex Kidd: The Lost Stars (set 1, FD1089A 317-0021)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/segas16b.cpp b/src/mame/drivers/segas16b.cpp index f094761bf69..8cea6b979a7 100644 --- a/src/mame/drivers/segas16b.cpp +++ b/src/mame/drivers/segas16b.cpp @@ -2104,6 +2104,111 @@ static INPUT_PORTS_START( aliensynj ) PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) INPUT_PORTS_END +static INPUT_PORTS_START( afighter ) + PORT_INCLUDE( system16b_generic ) + + PORT_MODIFY("DSW2") + PORT_DIPNAME( 0x01, 0x00, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW2:1") + PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x01, DEF_STR( Cocktail ) ) + PORT_DIPNAME( 0x02, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:3,4") + PORT_DIPSETTING( 0x08, "2" ) + PORT_DIPSETTING( 0x0c, "3" ) + PORT_DIPSETTING( 0x04, "4" ) + PORT_DIPSETTING( 0x00, DEF_STR( Infinite ) ) + PORT_DIPNAME( 0x30, 0x30, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPSETTING( 0x30, "10000 - 20000" ) + PORT_DIPSETTING( 0x20, "20000 - 40000" ) + PORT_DIPSETTING( 0x10, "30000 - 60000" ) + PORT_DIPSETTING( 0x00, "40000 - 80000" ) + PORT_DIPNAME( 0x40, 0x40, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:7") + PORT_DIPSETTING( 0x40, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hard ) ) + PORT_DIPNAME( 0x80, 0x80, DEF_STR( Allow_Continue ) ) PORT_DIPLOCATION("SW2:8") + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x80, DEF_STR( Yes ) ) +INPUT_PORTS_END + +/* this is identical to the s16a implementation, maybe should be moved to common class */ +CUSTOM_INPUT_MEMBER(afighter_16b_analog_state::afighter_accel_r) +{ + int accel = m_accel->read(); + + switch ((accel & 0xc0) >> 4) + { + case 0x00: return 0; + case 0x04: return (1 << 0); + case 0x08: return (1 << 1); + case 0x0c: return (1 << 2); + } + + return 0; +} + +CUSTOM_INPUT_MEMBER(afighter_16b_analog_state::afighter_handl_left_r) +{ + int steer = m_steer->read(); + + switch ((steer & 0xf0) >> 4) + { + case 0x00: return (1<<7); + case 0x01: return (1<<6); + case 0x02: return (1<<5); + case 0x03: return (1<<4); + case 0x04: return (1<<3); + case 0x05: return (1<<2); + case 0x06: return (1<<1); + case 0x07: return (1<<0); + } + return 0x00; +} + +CUSTOM_INPUT_MEMBER(afighter_16b_analog_state::afighter_handl_right_r) +{ + int steer = m_steer->read(); + + switch ((steer & 0xf0)>>4) + { + case 0x0f: return (1<<7); + case 0x0e: return (1<<6); + case 0x0d: return (1<<5); + case 0x0c: return (1<<4); + case 0x0b: return (1<<3); + case 0x0a: return (1<<2); + case 0x09: return (1<<1); + case 0x08: return (1<<0); + } + + return 0x00; +} + +static INPUT_PORTS_START( afighter_analog ) + PORT_INCLUDE( afighter ) + + PORT_MODIFY("P1") + PORT_BIT( 0x07, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, afighter_16b_analog_state, afighter_accel_r, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) // SHOT + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) // WEAPON1 + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) // WEAPON2 + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4 ) // WEAPON3 + + PORT_MODIFY("P2") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, afighter_16b_analog_state, afighter_handl_left_r, nullptr) + + PORT_MODIFY("UNUSED") + PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, afighter_16b_analog_state, afighter_handl_right_r, nullptr) + + PORT_START("STEER") // steering + PORT_BIT( 0xff, 0x00, IPT_PADDLE ) PORT_SENSITIVITY(100) PORT_KEYDELTA(4) + + PORT_START("ACCEL") // gas pedal + PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) +INPUT_PORTS_END + static INPUT_PORTS_START( altbeast ) PORT_INCLUDE( system16b_generic ) @@ -4062,6 +4167,136 @@ ROM_END //************************************************************************************************************************* //************************************************************************************************************************* //************************************************************************************************************************* +// Action Fighter, Sega System 16B + + +ROM_START( afightere ) + ROM_REGION( 0x30000, "maincpu", 0 ) // 68000 code + ROM_LOAD16_BYTE( "epr10269.bin", 0x00001, 0x08000, CRC(688b4ff7) SHA1(8972b75b6fa72513a6ebb3a5ed5988a43f1b6266) ) + ROM_LOAD16_BYTE( "epr10272.bin", 0x00000, 0x08000, CRC(bc3b75b6) SHA1(54c2be1cc4833ef7a18c4023e511654737d554c9) ) + ROM_LOAD16_BYTE( "epr10270.bin", 0x10001, 0x08000, CRC(53fab467) SHA1(62617b2bd097a9754c509ce0ca7baaa8dd63401b) ) + ROM_LOAD16_BYTE( "epr10273.bin", 0x10000, 0x08000, CRC(0ca74019) SHA1(ab7337e777ac162ff17b72096e4f619362339279) ) + ROM_LOAD16_BYTE( "epr10271.bin", 0x20001, 0x08000, CRC(d0d73af5) SHA1(7d13858c50bd5fa2b5ae4650747d3e237567281b) ) + ROM_LOAD16_BYTE( "epr10274.bin", 0x20000, 0x08000, CRC(d2601561) SHA1(0f2a97491aae859102d3ed80377b0c5fe4a0f4d8) ) + + ROM_REGION( 0x30000, "gfx1", 0 ) // tiles + ROM_LOAD( "epr10048.bin", 0x00000, 0x10000, CRC(643ca883) SHA1(dd2ffdeca5b06992fe71e5a9e59dcadf98f9e888) ) + ROM_LOAD( "epr10049.bin", 0x10000, 0x10000, CRC(f8b5058b) SHA1(ff62c220200e23c2f35f657175c0cd5123b6a1ba) ) + ROM_LOAD( "epr10050.bin", 0x20000, 0x10000, CRC(0ffb48dd) SHA1(2a88913ed177ec406ad7f788ab36ba12a8398a1b) ) + + ROM_REGION16_BE( 0x080000, "sprites", 0 ) // sprites + ROM_LOAD16_BYTE( "epr10044.bin", 0x00000, 0x08000, CRC(71d0db1f) SHA1(db2766474fc1f160bf886f65894259dfce891ed7) ) + ROM_LOAD16_BYTE( "epr10040.bin", 0x00001, 0x08000, CRC(5a9f81f9) SHA1(fedd427c95ccc8251bf713b6ae05c2efb74cd976) ) + ROM_LOAD16_BYTE( "epr10045.bin", 0x20000, 0x08000, CRC(39354223) SHA1(d8a73d3f7fc2d83d23bb7434f43bc8804f35cc16) ) + ROM_LOAD16_BYTE( "epr10041.bin", 0x20001, 0x08000, CRC(8da050cf) SHA1(c28e8968dbd9c110672581f4486f70d5f45df7f5) ) + ROM_LOAD16_BYTE( "epr10046.bin", 0x40000, 0x08000, CRC(b49b3136) SHA1(afb992acf4529204419707f0870e9a259e6fe00f) ) + ROM_LOAD16_BYTE( "epr10042.bin", 0x40001, 0x08000, CRC(dd706d18) SHA1(95c10f7ca29898f531bf8e3c0e8c9d0484d96b4a) ) + ROM_LOAD16_BYTE( "epr10047.bin", 0x60000, 0x08000, CRC(84a49518) SHA1(4f3c89d8f736889931ec09af3694d3891371c9e4) ) + ROM_LOAD16_BYTE( "epr10043.bin", 0x60001, 0x08000, CRC(645ccfb9) SHA1(84ba9a33bbf4ecc9909f543e798a2b3687872a71) ) + + ROM_REGION( 0x50000, "soundcpu", 0 ) // sound CPU + ROM_LOAD( "epr10039.bin", 0x00000, 0x8000, CRC(b04757b0) SHA1(24bface5a23ed658675f414c9937bf9d7f7ed5ec) ) +ROM_END + +ROM_START( afighterf ) + ROM_REGION( 0x30000, "maincpu", 0 ) // 68000 code + ROM_LOAD16_BYTE( "epr10033.bin", 0x00001, 0x08000, CRC(1b836a91) SHA1(a770a0ca9db052553184ffb0f647d033a0a4ab63) ) // == encrypted version of 10169 + ROM_LOAD16_BYTE( "epr10036.bin", 0x00000, 0x08000, CRC(d0589391) SHA1(55ceb189a48a5664955650e2d4e8ad1da2209295) ) + ROM_LOAD16_BYTE( "epr10034.bin", 0x10001, 0x08000, CRC(423e983e) SHA1(4437d4988c52b5033611ee4d6b4c50955ba70200) ) + ROM_LOAD16_BYTE( "epr10037.bin", 0x10000, 0x08000, CRC(3a312b9e) SHA1(ea371474b0ca5ead93b788e17192f80e6c8cf939) ) + ROM_LOAD16_BYTE( "epr10035.bin", 0x20001, 0x08000, CRC(68177755) SHA1(7f498a7932079cecb5908b11722244961a9d4927) ) + ROM_LOAD16_BYTE( "epr10038.bin", 0x20000, 0x08000, CRC(22c2b533) SHA1(9256888884dcfcf51ebcf64a1f60164a57891676) ) + + ROM_REGION( 0x30000, "gfx1", 0 ) // tiles + ROM_LOAD( "epr10048.bin", 0x00000, 0x10000, CRC(643ca883) SHA1(dd2ffdeca5b06992fe71e5a9e59dcadf98f9e888) ) + ROM_LOAD( "epr10049.bin", 0x10000, 0x10000, CRC(f8b5058b) SHA1(ff62c220200e23c2f35f657175c0cd5123b6a1ba) ) + ROM_LOAD( "epr10050.bin", 0x20000, 0x10000, CRC(0ffb48dd) SHA1(2a88913ed177ec406ad7f788ab36ba12a8398a1b) ) + + ROM_REGION16_BE( 0x080000, "sprites", 0 ) // sprites + ROM_LOAD16_BYTE( "epr10044.bin", 0x00000, 0x08000, CRC(71d0db1f) SHA1(db2766474fc1f160bf886f65894259dfce891ed7) ) + ROM_LOAD16_BYTE( "epr10040.bin", 0x00001, 0x08000, CRC(5a9f81f9) SHA1(fedd427c95ccc8251bf713b6ae05c2efb74cd976) ) + ROM_LOAD16_BYTE( "epr10045.bin", 0x20000, 0x08000, CRC(39354223) SHA1(d8a73d3f7fc2d83d23bb7434f43bc8804f35cc16) ) + ROM_LOAD16_BYTE( "epr10041.bin", 0x20001, 0x08000, CRC(8da050cf) SHA1(c28e8968dbd9c110672581f4486f70d5f45df7f5) ) + ROM_LOAD16_BYTE( "epr10046.bin", 0x40000, 0x08000, CRC(b49b3136) SHA1(afb992acf4529204419707f0870e9a259e6fe00f) ) + ROM_LOAD16_BYTE( "epr10042.bin", 0x40001, 0x08000, CRC(dd706d18) SHA1(95c10f7ca29898f531bf8e3c0e8c9d0484d96b4a) ) + ROM_LOAD16_BYTE( "epr10047.bin", 0x60000, 0x08000, CRC(84a49518) SHA1(4f3c89d8f736889931ec09af3694d3891371c9e4) ) + ROM_LOAD16_BYTE( "epr10043.bin", 0x60001, 0x08000, CRC(645ccfb9) SHA1(84ba9a33bbf4ecc9909f543e798a2b3687872a71) ) + + ROM_REGION( 0x50000, "soundcpu", 0 ) // sound CPU + ROM_LOAD( "epr10039.bin", 0x00000, 0x8000, CRC(b04757b0) SHA1(24bface5a23ed658675f414c9937bf9d7f7ed5ec) ) + + ROM_REGION( 0x2000, "maincpu:key", 0 ) // decryption key + ROM_LOAD( "317-unknown.key", 0x0000, 0x2000, NO_DUMP ) +ROM_END + + +ROM_START( afighterg ) // could be 16A + ROM_REGION( 0x30000, "maincpu", 0 ) // 68000 code + ROM_LOAD16_BYTE( "epr10160.bin", 0x00001, 0x08000, CRC(86f020da) SHA1(e7ac4b70dc375d9e2491f1a90ae154699e7627a2) ) // == encrypted 10169 (not perfect match) (same rev as 10354) + ROM_LOAD16_BYTE( "epr10163.bin", 0x00000, 0x08000, CRC(6d62eccd) SHA1(a400850f717a71a3e0059173d77f0bd067f1b520) ) + ROM_LOAD16_BYTE( "epr10161.bin", 0x10001, 0x08000, CRC(423e983e) SHA1(4437d4988c52b5033611ee4d6b4c50955ba70200) ) + ROM_LOAD16_BYTE( "epr10164.bin", 0x10000, 0x08000, CRC(3a312b9e) SHA1(ea371474b0ca5ead93b788e17192f80e6c8cf939) ) + ROM_LOAD16_BYTE( "epr10162.bin", 0x20001, 0x08000, CRC(a20acfd5) SHA1(2158deade6188ec7400423c5aa9634b37169c5a9) ) + ROM_LOAD16_BYTE( "epr10165.bin", 0x20000, 0x08000, CRC(cc68a82d) SHA1(ada7761076dfa9ab734a16382b55415929c39671) ) + + ROM_REGION( 0x30000, "gfx1", 0 ) // tiles + ROM_LOAD( "epr10048.bin", 0x00000, 0x10000, CRC(643ca883) SHA1(dd2ffdeca5b06992fe71e5a9e59dcadf98f9e888) ) + ROM_LOAD( "epr10049.bin", 0x10000, 0x10000, CRC(f8b5058b) SHA1(ff62c220200e23c2f35f657175c0cd5123b6a1ba) ) + ROM_LOAD( "epr10050.bin", 0x20000, 0x10000, CRC(0ffb48dd) SHA1(2a88913ed177ec406ad7f788ab36ba12a8398a1b) ) + + ROM_REGION16_BE( 0x080000, "sprites", 0 ) // sprites + ROM_LOAD16_BYTE( "epr10044.bin", 0x00000, 0x08000, CRC(71d0db1f) SHA1(db2766474fc1f160bf886f65894259dfce891ed7) ) + ROM_LOAD16_BYTE( "epr10040.bin", 0x00001, 0x08000, CRC(5a9f81f9) SHA1(fedd427c95ccc8251bf713b6ae05c2efb74cd976) ) + ROM_LOAD16_BYTE( "epr10045.bin", 0x20000, 0x08000, CRC(39354223) SHA1(d8a73d3f7fc2d83d23bb7434f43bc8804f35cc16) ) + ROM_LOAD16_BYTE( "epr10041.bin", 0x20001, 0x08000, CRC(8da050cf) SHA1(c28e8968dbd9c110672581f4486f70d5f45df7f5) ) + ROM_LOAD16_BYTE( "epr10046.bin", 0x40000, 0x08000, CRC(b49b3136) SHA1(afb992acf4529204419707f0870e9a259e6fe00f) ) + ROM_LOAD16_BYTE( "epr10042.bin", 0x40001, 0x08000, CRC(dd706d18) SHA1(95c10f7ca29898f531bf8e3c0e8c9d0484d96b4a) ) + ROM_LOAD16_BYTE( "epr10047.bin", 0x60000, 0x08000, CRC(84a49518) SHA1(4f3c89d8f736889931ec09af3694d3891371c9e4) ) + ROM_LOAD16_BYTE( "epr10043.bin", 0x60001, 0x08000, CRC(645ccfb9) SHA1(84ba9a33bbf4ecc9909f543e798a2b3687872a71) ) + + ROM_REGION( 0x50000, "soundcpu", 0 ) // sound CPU + ROM_LOAD( "epr10039.bin", 0x00000, 0x8000, CRC(b04757b0) SHA1(24bface5a23ed658675f414c9937bf9d7f7ed5ec) ) + + ROM_REGION( 0x2000, "maincpu:key", 0 ) // decryption key + ROM_LOAD( "317-unknown.key", 0x0000, 0x2000, NO_DUMP ) +ROM_END + + +ROM_START( afighterh ) // could be 16A + ROM_REGION( 0x30000, "maincpu", 0 ) // 68000 code + ROM_LOAD16_BYTE( "epr10354.bin", 0x00001, 0x08000, CRC(6dad6dd1) SHA1(8cdd1c10d60cda09f888b2f03b7d4c76100b4ad0) ) // == encrypted 10169 (not perfect match) (same rev as 10160) + ROM_LOAD16_BYTE( "epr10357.bin", 0x00000, 0x08000, CRC(69777a15) SHA1(26fcca4b5476596cec9a59f5445f0b24c9373a8b) ) + ROM_LOAD16_BYTE( "epr10355.bin", 0x10001, 0x08000, CRC(ac865097) SHA1(113b00da9496d610c079c2084a81f85007390189) ) + ROM_LOAD16_BYTE( "epr10358.bin", 0x10000, 0x08000, CRC(8f9da9a0) SHA1(8c1ff6156a2680952ae9fa4210477ec27e140c21) ) + ROM_LOAD16_BYTE( "epr10356.bin", 0x20001, 0x08000, CRC(da7f05f2) SHA1(a65ec89b481d0b2ce5684a5668f8fafb7def7867) ) + ROM_LOAD16_BYTE( "epr10359.bin", 0x20000, 0x08000, CRC(1dc12296) SHA1(fc8b86f764266b64728b40a5958ab354751e643a) ) + + ROM_REGION( 0x30000, "gfx1", 0 ) // tiles + ROM_LOAD( "epr10048.bin", 0x00000, 0x10000, CRC(643ca883) SHA1(dd2ffdeca5b06992fe71e5a9e59dcadf98f9e888) ) + ROM_LOAD( "epr10049.bin", 0x10000, 0x10000, CRC(f8b5058b) SHA1(ff62c220200e23c2f35f657175c0cd5123b6a1ba) ) + ROM_LOAD( "epr10050.bin", 0x20000, 0x10000, CRC(0ffb48dd) SHA1(2a88913ed177ec406ad7f788ab36ba12a8398a1b) ) + + ROM_REGION16_BE( 0x080000, "sprites", 0 ) // sprites + ROM_LOAD16_BYTE( "epr10044.bin", 0x00000, 0x08000, CRC(71d0db1f) SHA1(db2766474fc1f160bf886f65894259dfce891ed7) ) + ROM_LOAD16_BYTE( "epr10040.bin", 0x00001, 0x08000, CRC(5a9f81f9) SHA1(fedd427c95ccc8251bf713b6ae05c2efb74cd976) ) + ROM_LOAD16_BYTE( "epr10045.bin", 0x20000, 0x08000, CRC(39354223) SHA1(d8a73d3f7fc2d83d23bb7434f43bc8804f35cc16) ) + ROM_LOAD16_BYTE( "epr10041.bin", 0x20001, 0x08000, CRC(8da050cf) SHA1(c28e8968dbd9c110672581f4486f70d5f45df7f5) ) + ROM_LOAD16_BYTE( "epr10046.bin", 0x40000, 0x08000, CRC(b49b3136) SHA1(afb992acf4529204419707f0870e9a259e6fe00f) ) + ROM_LOAD16_BYTE( "epr10042.bin", 0x40001, 0x08000, CRC(dd706d18) SHA1(95c10f7ca29898f531bf8e3c0e8c9d0484d96b4a) ) + ROM_LOAD16_BYTE( "epr10047.bin", 0x60000, 0x08000, CRC(84a49518) SHA1(4f3c89d8f736889931ec09af3694d3891371c9e4) ) + ROM_LOAD16_BYTE( "epr10043.bin", 0x60001, 0x08000, CRC(645ccfb9) SHA1(84ba9a33bbf4ecc9909f543e798a2b3687872a71) ) + + ROM_REGION( 0x50000, "soundcpu", 0 ) // sound CPU + ROM_LOAD( "epr10039.bin", 0x00000, 0x8000, CRC(b04757b0) SHA1(24bface5a23ed658675f414c9937bf9d7f7ed5ec) ) + + ROM_REGION( 0x2000, "maincpu:key", 0 ) // decryption key + ROM_LOAD( "317-unknown.key", 0x0000, 0x2000, NO_DUMP ) +ROM_END + + +//************************************************************************************************************************* +//************************************************************************************************************************* +//************************************************************************************************************************* // Altered Beast, Sega System 16B // CPU: 68000 + i8751 (317-0078) // ROM Board type: 171-5521 @@ -8710,7 +8945,6 @@ DRIVER_INIT_MEMBER(segas16b_state,aliensyn7_5358_small) downcast<mc8123_device &>(*m_soundcpu).decode(memregion("soundcpu")->base(), m_sound_decrypted_opcodes, 0x8000); } - DRIVER_INIT_MEMBER(segas16b_state,altbeasj_5521) { DRIVER_INIT_CALL(generic_5521); @@ -8855,6 +9089,11 @@ GAME( 1987, aliensyn7, aliensyn, system16b_mc8123, aliensyn, segas16b_state, GAME( 1987, aliensyn3, aliensyn, system16b_fd1089a, aliensyn, segas16b_state,generic_5358_small, ROT0, "Sega", "Alien Syndrome (set 3, System 16B, FD1089A 317-0033)", 0 ) GAME( 1987, aliensynj, aliensyn, system16b_fd1089a, aliensynj,segas16b_state,generic_5358_small, ROT0, "Sega", "Alien Syndrome (set 6, Japan, new, System 16B, FD1089A 317-0033)", 0 ) +GAME( 1987, afightere, afighter, system16b, afighter_analog,afighter_16b_analog_state,generic_5358_small, ROT270, "Sega", "Action Fighter (System 16B, unprotected, analog controls)", 0 ) +GAME( 1987, afighterf, afighter, system16b_fd1089a, afighter_analog,afighter_16b_analog_state,generic_5358_small, ROT270, "Sega", "Action Fighter (System 16B, FD1089A 317-unknown, analog controls)", MACHINE_NOT_WORKING ) // encrypted version of afightere +GAME( 1987, afighterg, afighter, system16b_fd1089a, afighter, segas16b_state, generic_5358_small, ROT270, "Sega", "Action Fighter (System 16B, FD1089A 317-unknown, set 1)", MACHINE_NOT_WORKING ) // same encryption as afighterf +GAME( 1987, afighterh, afighter, system16b_fd1089a, afighter, segas16b_state, generic_5358_small, ROT270, "Sega", "Action Fighter (System 16B, FD1089A 317-unknown, set 2)", MACHINE_NOT_WORKING ) // different encryption, same rev as afighterg + GAME( 1988, altbeast, 0, system16b_i8751, altbeast, segas16b_state,generic_5521, ROT0, "Sega", "Altered Beast (set 8) (8751 317-0078)", 0 ) GAME( 1988, altbeastj, altbeast, system16b_i8751, altbeast, segas16b_state,altbeasj_5521, ROT0, "Sega", "Juuouki (set 7, Japan) (8751 317-0077)", 0 ) GAME( 1988, altbeast6, altbeast, system16b_i8751, altbeast, segas16b_state,altbeas5_5521, ROT0, "Sega", "Altered Beast (set 6) (8751 317-0076)", 0 ) diff --git a/src/mame/drivers/segaxbd.cpp b/src/mame/drivers/segaxbd.cpp index 9f1496e53c0..17dd5761480 100644 --- a/src/mame/drivers/segaxbd.cpp +++ b/src/mame/drivers/segaxbd.cpp @@ -4745,9 +4745,9 @@ GAME( 1990, abcop, 0, sega_xboard_fd1094, abcop, segaxbd_new_state GAME( 1990, abcopj, abcop, sega_xboard_fd1094, abcop, segaxbd_new_state, 0, ROT0, "Sega", "A.B. Cop (Japan) (FD1094 317-0169b)", 0 ) // wasn't officially available as a single PCB setup, but runs anyway albeit with messages suggesting you can compete against a rival that doesn't exist? -GAME( 1990, gpriders, gprider, sega_xboard_fd1094, gprider, segaxbd_new_state, gprider, ROT0, "Sega", "GP Rider (World, FD1094 317-0163)", 0 ) -GAME( 1990, gpriderus,gprider, sega_xboard_fd1094, gprider, segaxbd_new_state, gprider, ROT0, "Sega", "GP Rider (US, FD1094 317-0162)", 0 ) -GAME( 1990, gpriderjs,gprider, sega_xboard_fd1094, gprider, segaxbd_new_state, gprider, ROT0, "Sega", "GP Rider (Japan, FD1094 317-0161)", 0 ) +GAME( 1990, gpriders, gprider, sega_xboard_fd1094, gprider, segaxbd_new_state, gprider, ROT0, "Sega", "GP Rider (World, FD1094 317-0163)", MACHINE_NODEVICE_LAN ) +GAME( 1990, gpriderus,gprider, sega_xboard_fd1094, gprider, segaxbd_new_state, gprider, ROT0, "Sega", "GP Rider (US, FD1094 317-0162)", MACHINE_NODEVICE_LAN ) +GAME( 1990, gpriderjs,gprider, sega_xboard_fd1094, gprider, segaxbd_new_state, gprider, ROT0, "Sega", "GP Rider (Japan, FD1094 317-0161)", MACHINE_NODEVICE_LAN ) // multi X-Board (2 stacks directly connected, shared RAM on bridge PCB - not networked) GAME( 1990, gprider, 0, sega_xboard_fd1094_double, gprider_double, segaxbd_new_state_double, gprider_double, ROT0, "Sega", "GP Rider (World, FD1094 317-0163) (Twin setup)", 0 ) @@ -4755,7 +4755,7 @@ GAME( 1990, gprideru,gprider, sega_xboard_fd1094_double, gprider_double, segax GAME( 1990, gpriderj,gprider, sega_xboard_fd1094_double, gprider_double, segaxbd_new_state_double, gprider_double, ROT0, "Sega", "GP Rider (Japan, FD1094 317-0161) (Twin setup)", 0 ) // X-Board + other boards? -GAME( 1991, rascot, 0, sega_rascot, rascot, segaxbd_new_state, rascot, ROT0, "Sega", "Royal Ascot (Japan, terminal?)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +GAME( 1991, rascot, 0, sega_rascot, rascot, segaxbd_new_state, rascot, ROT0, "Sega", "Royal Ascot (Japan, terminal?)", MACHINE_NODEVICE_LAN | MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // decrypted bootlegs diff --git a/src/mame/drivers/seibucats.cpp b/src/mame/drivers/seibucats.cpp index 8aeeb792914..63d802478d4 100644 --- a/src/mame/drivers/seibucats.cpp +++ b/src/mame/drivers/seibucats.cpp @@ -4,6 +4,15 @@ Seibu CATS E-Touch Mahjong Series (c) 2001 Seibu Kaihatsu + TODO: + - verify obj roms (maybe bad or wrong decryption); + - coins inputs are ok? + - touchscreen; + - sound; + - DVD player; + +========================================================================================================================================================= + CPU and system control devices: - Intel i386DX (U0169; lower right corner) - SEI600 SB08-1513 custom DMA chip (U0154; above i386DX) @@ -69,6 +78,7 @@ #include "machine/i8251.h" //#include "machine/microtch.h" //#include "machine/rtc4543.h" +#include "machine/seibuspi.h" #include "sound/ymz280b.h" #include "screen.h" #include "speaker.h" @@ -91,6 +101,7 @@ class seibucats_state : public seibuspi_state public: seibucats_state(const machine_config &mconfig, device_type type, const char *tag) : seibuspi_state(mconfig, type, tag) +// m_key(*this, "KEY.%u", 0) { } @@ -103,6 +114,7 @@ public: DECLARE_WRITE16_MEMBER(input_select_w); DECLARE_WRITE16_MEMBER(output_latch_w); DECLARE_WRITE16_MEMBER(aux_rtc_w); + DECLARE_DRIVER_INIT(seibucats); protected: // driver_device overrides @@ -114,18 +126,28 @@ protected: private: uint16_t m_input_select; + +// optional_ioport_array<5> m_key; +// optional_ioport m_special; }; +// identical to EJ Sakura READ16_MEMBER(seibucats_state::input_mux_r) { - // TODO: mahjong keyboard is read from here - return m_eeprom->do_read() << 14; + uint16_t ret = m_special->read(); + + // multiplexed inputs + for (int i = 0; i < 5; i++) + if (m_input_select >> i & 1) + ret &= m_key[i]->read(); + + return ret; } WRITE16_MEMBER(seibucats_state::input_select_w) { // Note that this is active high in ejsakura but active low here - m_input_select = data; + m_input_select = data ^ 0xffff; } WRITE16_MEMBER(seibucats_state::output_latch_w) @@ -166,60 +188,61 @@ static ADDRESS_MAP_START( seibucats_map, AS_PROGRAM, 32, seibucats_state ) AM_RANGE(0xffe00000, 0xffffffff) AM_ROM AM_REGION("ipl", 0) ADDRESS_MAP_END +static INPUT_PORTS_START( spi_mahjong_keyboard ) + PORT_START("KEY.0") + PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_MAHJONG_PON ) + PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_MAHJONG_L ) + PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_MAHJONG_H ) + PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_MAHJONG_D ) + PORT_BIT( 0xffffffe0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("KEY.1") + PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_MAHJONG_BIG ) + PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_MAHJONG_FLIP_FLOP ) + PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP ) + PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_MAHJONG_SCORE ) + PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_MAHJONG_LAST_CHANCE ) + PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) + PORT_BIT( 0xffffffc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("KEY.2") + PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_MAHJONG_RON ) + PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_MAHJONG_CHI ) + PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_MAHJONG_K ) + PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_MAHJONG_G ) + PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_MAHJONG_C ) + PORT_BIT( 0xffffffe0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("KEY.3") + PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_MAHJONG_KAN ) + PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_MAHJONG_M ) + PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_MAHJONG_I ) + PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_MAHJONG_E ) + PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_MAHJONG_A ) + PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0xffffffc0, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("KEY.4") + PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_MAHJONG_REACH ) + PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_MAHJONG_N ) + PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_MAHJONG_J ) + PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_MAHJONG_F ) + PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_MAHJONG_B ) + PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_MAHJONG_BET ) + PORT_SERVICE_NO_TOGGLE( 0x00000200, IP_ACTIVE_LOW) + PORT_BIT( 0xfffffdc0, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + + static INPUT_PORTS_START( seibucats ) - /* dummy active high structure */ - PORT_START("SYSA") - PORT_DIPNAME( 0x01, 0x00, "SYSA" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x10, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x20, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x80, DEF_STR( On ) ) - - /* dummy active low structure */ - PORT_START("DSWA") - PORT_DIPNAME( 0x01, 0x01, "DSWA" ) - PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_INCLUDE( spi_mahjong_keyboard ) + + PORT_START("SPECIAL") + PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_BIT( 0x00004000, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", eeprom_serial_93cxx_device, do_read) + PORT_BIT( 0xffffbf3f, IP_ACTIVE_LOW, IPT_UNUSED ) INPUT_PORTS_END static const gfx_layout sys386f_spritelayout = @@ -309,6 +332,14 @@ MACHINE_CONFIG_END ***************************************************************************/ +#define SEIBUCATS_OBJ_LOAD \ + ROM_REGION( 0x400000, "gfx3", ROMREGION_ERASE00) \ +/* obj4.u0234 empty slot */ \ + ROM_LOAD16_WORD_SWAP("obj03.u0232", 0x100000, 0x100000, BAD_DUMP CRC(15c230cf) SHA1(7e12871d6e34e28cd4b5b23af6b0cbdff9432500) ) \ + ROM_LOAD16_WORD_SWAP("obj02.u0233", 0x200000, 0x100000, BAD_DUMP CRC(dffd0114) SHA1(b74254061b6da5a2ce310ea89684db430b43583e) ) \ + ROM_LOAD16_WORD_SWAP("obj01.u0231", 0x300000, 0x100000, BAD_DUMP CRC(ee5ae0fd) SHA1(0baff6ca4e8bceac4e09732da267f57578dcc280) ) + + ROM_START( emjjoshi ) ROM_REGION32_LE( 0x200000, "ipl", 0 ) /* i386 program */ ROM_LOAD32_BYTE( "prg0.u016", 0x000000, 0x080000, CRC(e69bed6d) SHA1(e9626e704c5d28419cfa6a7a2c1b13b4b46f941c) ) @@ -320,11 +351,7 @@ ROM_START( emjjoshi ) ROM_REGION( 0x900000, "gfx2", ROMREGION_ERASEFF ) /* background layer roms - none! */ - ROM_REGION( 0x600000, "gfx3", 0) - ROM_LOAD("obj1.u0231", 0x000000, 0x200000, NO_DUMP ) - ROM_LOAD("obj2.u0233", 0x200000, 0x200000, NO_DUMP ) - ROM_LOAD("obj3.u0232", 0x400000, 0x200000, NO_DUMP ) -// obj4.u0234 empty slot + SEIBUCATS_OBJ_LOAD DISK_REGION("dvd") DISK_IMAGE_READONLY( "At the Girls Dorm SKTP-10002", 0, SHA1(be47c105089d6ef4ce05a6e1ba2ec7a3101015dc) ) @@ -343,11 +370,7 @@ ROM_START( emjscanb ) ROM_REGION( 0x900000, "gfx2", ROMREGION_ERASEFF ) /* background layer roms - none! */ - ROM_REGION( 0x600000, "gfx3", 0) - ROM_LOAD("obj1.u0231", 0x000000, 0x200000, NO_DUMP ) - ROM_LOAD("obj2.u0233", 0x200000, 0x200000, NO_DUMP ) - ROM_LOAD("obj3.u0232", 0x400000, 0x200000, NO_DUMP ) -// obj4.u0234 empty slot + SEIBUCATS_OBJ_LOAD DISK_REGION("dvd") DISK_IMAGE_READONLY( "Scandal Blue SKTP-10008", 0, SHA1(17fe67698a9bc5dbd452c4b1afa739294ec2011c) ) @@ -364,25 +387,41 @@ ROM_START( emjtrapz ) ROM_REGION( 0x900000, "gfx2", ROMREGION_ERASEFF ) /* background layer roms - none! */ - ROM_REGION( 0x600000, "gfx3", 0) - ROM_LOAD("obj1.u0231", 0x000000, 0x200000, NO_DUMP ) - ROM_LOAD("obj2.u0233", 0x200000, 0x200000, NO_DUMP ) - ROM_LOAD("obj3.u0232", 0x400000, 0x200000, NO_DUMP ) -// obj4.u0234 empty slot + SEIBUCATS_OBJ_LOAD DISK_REGION("dvd") DISK_IMAGE_READONLY( "Trap Zone SKTP-00009", 0, SHA1(b4a51f42eeaeefc329031651859caa108418a96e) ) ROM_END +DRIVER_INIT_MEMBER(seibucats_state,seibucats) +{ + int i, j; + uint16_t *src = (uint16_t *)memregion("gfx3")->base(); + uint16_t tmp[0x40 / 2], offset; + + // sprite_reorder() only + for (i = 0; i < memregion("gfx3")->bytes() / 0x40; i++) + { + memcpy(tmp, src, 0x40); + + for (j = 0; j < 0x40 / 2; j++) + { + offset = (j >> 1) | (j << 4 & 0x10); + *src++ = tmp[offset]; + } + } +// seibuspi_rise11_sprite_decrypt_rfjet(memregion("gfx3")->base(), 0x300000); +} + // Gravure Collection // Pakkun Ball TV /* 01 */ // Mahjong Shichau zo! -/* 02 */ GAME( 1999, emjjoshi, 0, seibucats, seibucats, seibucats_state, 0, ROT0, "Seibu Kaihatsu / CATS", "E-Touch Mahjong Series #2: Joshiryou de NE! (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +/* 02 */ GAME( 1999, emjjoshi, 0, seibucats, seibucats, seibucats_state, seibucats, ROT0, "Seibu Kaihatsu / CATS", "E-Touch Mahjong Series #2: Joshiryou de NE! (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) /* 03 */ // Lingerie DE Ikou /* 04 */ // Marumie Network /* 05 */ // BINKAN Lips -/* 06 */ GAME( 2001, emjscanb, 0, seibucats, seibucats, seibucats_state, 0, ROT0, "Seibu Kaihatsu / CATS", "E-Touch Mahjong Series #6: Scandal Blue - Midara na Daishou (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -/* 07 */ GAME( 2001, emjtrapz, 0, seibucats, seibucats, seibucats_state, 0, ROT0, "Seibu Kaihatsu / CATS", "E-Touch Mahjong Series #7: Trap Zone - Yokubou no Kaisoku Densha (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +/* 06 */ GAME( 2001, emjscanb, 0, seibucats, seibucats, seibucats_state, seibucats, ROT0, "Seibu Kaihatsu / CATS", "E-Touch Mahjong Series #6: Scandal Blue - Midara na Daishou (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +/* 07 */ GAME( 2001, emjtrapz, 0, seibucats, seibucats, seibucats_state, seibucats, ROT0, "Seibu Kaihatsu / CATS", "E-Touch Mahjong Series #7: Trap Zone - Yokubou no Kaisoku Densha (Japan)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) /* 08 */ // Poison /* 09 */ // Nurse Call /* 10 */ // Secret Love diff --git a/src/mame/drivers/seta.cpp b/src/mame/drivers/seta.cpp index 19194e4f925..a18d62feeb3 100644 --- a/src/mame/drivers/seta.cpp +++ b/src/mame/drivers/seta.cpp @@ -8,16 +8,16 @@ CPU : 68000 + [65C02] (only in the earlier games) -Custom : X1-001A X1-002A (SDIP64) Sprites +Custom : X1-001A, X1-002A (SDIP64) Sprites X1-001 X1-002 - X1-003 + X1-003 or X1-007 (SDIP42) Video blanking (feeds RGB DACs) X1-004 (SDIP52) Inputs - X1-005 X0-005 - X1-006 X0-006 - X1-007 (SDIP42) Video DAC + X1-005 + X1-006 (SDIP64) Palette X1-010 (QFP80) Sound: 16 Bit PCM - X1-011 X1-012 (QFP100) Tilemaps + X1-011 (QFP80) Graphics mixing + X1-012 (QFP100) Tilemaps X1-014 Sprites? ------------------------------------------------------------------------------- @@ -1925,48 +1925,32 @@ ADDRESS_MAP_END and Zombie Raid (with slight variations) ***************************************************************************/ -READ16_MEMBER(seta_state::zombraid_gun_r)// Serial interface +ADC083X_INPUT_CB(seta_state::zombraid_adc_cb) { - static const char *const portnames[] = { "GUNX1", "GUNY1", "GUNX2", "GUNY2" }; + if (input == ADC083X_AGND) + return 0.0; + else if (input == ADC083X_VREF) + return 1.0; + else + return m_gun_inputs[input - ADC083X_CH0]->read() / 255.0; +} - int data = ioport(portnames[m_gun_input_src])->read(); // Input Ports 5-8 - return (data >> m_gun_input_bit) & 1; +READ16_MEMBER(seta_state::zombraid_gun_r)// Serial interface +{ + return m_adc->do_read(); } // Bit 0 is clock, 1 is data, 2 is reset WRITE16_MEMBER(seta_state::zombraid_gun_w) { - if(data&4) { m_gun_bit_count = 0; return; } // Reset - - if((data&1) == m_gun_old_clock) return; // No change - - if(m_gun_old_clock == 0) // Rising edge - { - switch (m_gun_bit_count) - { - case 0: - case 1: // Starting sequence 2,3,2,3. Other inputs? - break; - case 2: // First bit of source - m_gun_input_src = (m_gun_input_src&2) | (data>>1); - break; - case 3: // Second bit of source - m_gun_input_src = (m_gun_input_src&1) | (data&2); - break; - default: - /* Gun Recoils */ - /* Note: In debug menu recoil solenoids strobe when held down. Is this correct?? */ - output().set_value("Player1_Gun_Recoil", (data & 0x10)>>4 ); - output().set_value("Player2_Gun_Recoil", (data & 0x8)>>3 ); - - m_gun_input_bit = m_gun_bit_count - 4; - m_gun_input_bit = 8 - m_gun_input_bit; // Reverse order - break; - } - m_gun_bit_count++; - } - - m_gun_old_clock = data & 1; + m_adc->cs_write(BIT(data, 2)); + m_adc->di_write(BIT(data, 1)); + m_adc->clk_write(BIT(data, 0)); + + /* Gun Recoils */ + /* Note: In debug menu recoil solenoids strobe when held down. Is this correct?? */ + output().set_value("Player1_Gun_Recoil", BIT(data, 4)); + output().set_value("Player2_Gun_Recoil", BIT(data, 3)); } READ16_MEMBER(seta_state::extra_r) @@ -2011,8 +1995,10 @@ static ADDRESS_MAP_START( wrofaero_map, AS_PROGRAM, 16, seta_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( zombraid_map, AS_PROGRAM, 16, seta_state ) - AM_IMPORT_FROM( wrofaero_map ) AM_RANGE(0x300000, 0x30ffff) AM_RAM AM_SHARE("nvram") // actually 8K x8 SRAM + AM_RANGE(0xf00000, 0xf00001) AM_WRITE(zombraid_gun_w) + AM_RANGE(0xf00002, 0xf00003) AM_READ(zombraid_gun_r) + AM_IMPORT_FROM( wrofaero_map ) ADDRESS_MAP_END READ16_MEMBER(seta_state::zingzipbl_unknown_r) @@ -2889,7 +2875,7 @@ static ADDRESS_MAP_START( thunderlbl_map, AS_PROGRAM, 16, seta_state ) AM_RANGE(0xb00002, 0xb00003) AM_READ_PORT("P2") // P2 AM_RANGE(0xb00004, 0xb00005) AM_READ_PORT("COINS") // Coins // AM_RANGE(0xb0000c, 0xb0000d) AM_READ(thunderl_protection_r ) // Protection (not in wits) - AM_RANGE(0xb00008, 0xb00009) AM_READ_PORT("P3") AM_WRITE(wiggie_soundlatch_w) // P3 (wits) + AM_RANGE(0xb00008, 0xb00009) AM_READ_PORT("P3") AM_DEVWRITE8("soundlatch", generic_latch_8_device, write, 0xff00) // P3 (wits) AM_RANGE(0xb0000a, 0xb0000b) AM_READ_PORT("P4") // P4 (wits) /**/AM_RANGE(0xc00000, 0xc00001) AM_RAM // ? 0x4000 /**/AM_RANGE(0xd00000, 0xd005ff) AM_RAM AM_DEVREADWRITE("spritegen", seta001_device, spriteylow_r16, spriteylow_w16) // Sprites Y @@ -2902,21 +2888,10 @@ ADDRESS_MAP_END Wiggie Waggie ***************************************************************************/ -READ8_MEMBER(seta_state::wiggie_soundlatch_r) -{ - return m_wiggie_soundlatch; -} - -WRITE16_MEMBER(seta_state::wiggie_soundlatch_w) -{ - m_wiggie_soundlatch = data >> 8; - m_audiocpu->set_input_line(0, HOLD_LINE); -} - - static ADDRESS_MAP_START( wiggie_map, AS_PROGRAM, 16, seta_state ) AM_RANGE(0x000000, 0x01ffff) AM_ROM // ROM AM_RANGE(0xffc000, 0xffffff) AM_RAM // RAM + AM_RANGE(0x100000, 0x103fff) AM_NOP // X1_010 is not used AM_RANGE(0x200000, 0x200001) AM_WRITENOP // ? AM_RANGE(0x300000, 0x300001) AM_WRITENOP // ? AM_RANGE(0x400000, 0x40ffff) AM_WRITE(thunderl_protection_w) // Protection (not in wits) @@ -2928,6 +2903,7 @@ static ADDRESS_MAP_START( wiggie_map, AS_PROGRAM, 16, seta_state ) AM_RANGE(0xb00004, 0xb00005) AM_READ_PORT("COINS") // Coins AM_RANGE(0xb0000c, 0xb0000d) AM_READ(thunderl_protection_r) // Protection (not in wits) AM_RANGE(0xb00008, 0xb00009) AM_READ_PORT("P3") // P3 (wits) + AM_RANGE(0xb00008, 0xb00009) AM_DEVWRITE8("soundlatch", generic_latch_8_device, write, 0xff00) AM_RANGE(0xb0000a, 0xb0000b) AM_READ_PORT("P4") // P4 (wits) /**/AM_RANGE(0xc00000, 0xc00001) AM_RAM // ? 0x4000 /**/AM_RANGE(0xd00000, 0xd005ff) AM_RAM AM_DEVREADWRITE("spritegen", seta001_device, spriteylow_r16, spriteylow_w16) // Sprites Y @@ -2940,7 +2916,7 @@ static ADDRESS_MAP_START( wiggie_sound_map, AS_PROGRAM, 8, seta_state ) AM_RANGE(0x0000, 0x7fff) AM_ROM AM_RANGE(0x8000, 0x87ff) AM_RAM AM_RANGE(0x9800, 0x9800) AM_DEVREADWRITE("oki", okim6295_device, read, write) - AM_RANGE(0xa000, 0xa000) AM_READ(wiggie_soundlatch_r) + AM_RANGE(0xa000, 0xa000) AM_DEVREAD("soundlatch", generic_latch_8_device, read) ADDRESS_MAP_END @@ -2972,13 +2948,12 @@ ADDRESS_MAP_END Ultra Toukond Densetsu ***************************************************************************/ -WRITE16_MEMBER(seta_state::utoukond_soundlatch_w) +WRITE8_MEMBER(seta_state::utoukond_sound_control_w) { - if (ACCESSING_BITS_0_7) - { - m_audiocpu->set_input_line(0, HOLD_LINE); - m_soundlatch->write(space, 0, data & 0xff); - } + if (!BIT(data, 6)) + m_soundlatch->acknowledge_w(space, 0, 0); + + // other bits used for banking? (low nibble seems to always be 2) } static ADDRESS_MAP_START( utoukond_map, AS_PROGRAM, 16, seta_state ) @@ -2997,7 +2972,7 @@ static ADDRESS_MAP_START( utoukond_map, AS_PROGRAM, 16, seta_state ) AM_RANGE(0xa00000, 0xa005ff) AM_RAM AM_DEVREADWRITE("spritegen", seta001_device, spriteylow_r16, spriteylow_w16) // Sprites Y AM_RANGE(0xa00600, 0xa00607) AM_RAM AM_DEVREADWRITE("spritegen", seta001_device, spritectrl_r16, spritectrl_w16) AM_RANGE(0xb00000, 0xb03fff) AM_RAM AM_DEVREADWRITE("spritegen", seta001_device, spritecode_r16, spritecode_w16) // Sprites Code + X + Attr - AM_RANGE(0xc00000, 0xc00001) AM_WRITE(utoukond_soundlatch_w) // To Sound CPU (cause an IRQ) + AM_RANGE(0xc00000, 0xc00001) AM_DEVWRITE8("soundlatch", generic_latch_8_device, write, 0x00ff) AM_RANGE(0xe00000, 0xe00001) AM_WRITENOP // ? ack ADDRESS_MAP_END @@ -3524,7 +3499,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( utoukond_sound_io_map, AS_IO, 8, seta_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("ymsnd", ym3438_device, read, write) - AM_RANGE(0x80, 0x80) AM_WRITENOP //? + AM_RANGE(0x80, 0x80) AM_WRITE(utoukond_sound_control_w) AM_RANGE(0xc0, 0xc0) AM_DEVREAD("soundlatch", generic_latch_8_device, read) ADDRESS_MAP_END @@ -8287,7 +8262,7 @@ static ADDRESS_MAP_START( blockcarb_sound_portmap, AS_IO, 8, seta_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) // AM_RANGE(0x00, 0x01) AM_MIRROR(0x3e) AM_DEVREADWRITE("ymsnd", ym2151_device, read, write) -// AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x3f) AM_READ(wiggie_soundlatch_r) +// AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x3f) AM_DEVREAD("soundlatch", generic_latch_8_device, read) ADDRESS_MAP_END static MACHINE_CONFIG_DERIVED( blockcarb, blockcar ) @@ -8690,6 +8665,9 @@ static MACHINE_CONFIG_DERIVED( zombraid, gundhara ) MCFG_CPU_PROGRAM_MAP(zombraid_map) MCFG_NVRAM_ADD_0FILL("nvram") + + MCFG_DEVICE_ADD("adc", ADC0834, 0) + MCFG_ADC083X_INPUT_CB(seta_state, zombraid_adc_cb) MACHINE_CONFIG_END /*************************************************************************** @@ -9286,7 +9264,6 @@ static ADDRESS_MAP_START( thunderlbl_sound_map, AS_PROGRAM, 8, seta_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x7fff) AM_ROM AM_RANGE(0x8000, 0xdfff) AM_ROM - AM_RANGE(0xe800, 0xe800) AM_READ(wiggie_soundlatch_r) AM_RANGE(0xf800, 0xffff) AM_RAM ADDRESS_MAP_END @@ -9294,7 +9271,7 @@ static ADDRESS_MAP_START( thunderlbl_sound_portmap, AS_IO, 8, seta_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x01) AM_MIRROR(0x3e) AM_DEVREADWRITE("ymsnd", ym2151_device, read, write) - AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x3f) AM_READ(wiggie_soundlatch_r) + AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x3f) AM_DEVREAD("soundlatch", generic_latch_8_device, read) ADDRESS_MAP_END @@ -9314,6 +9291,9 @@ static MACHINE_CONFIG_DERIVED( thunderlbl, thunderl ) MCFG_YM2151_ADD("ymsnd", 10000000/2) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) + + MCFG_GENERIC_LATCH_8_ADD("soundlatch") + MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0)) MACHINE_CONFIG_END @@ -9350,6 +9330,9 @@ static MACHINE_CONFIG_START( wiggie ) MCFG_OKIM6295_ADD("oki", 1000000, PIN7_HIGH) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) + + MCFG_GENERIC_LATCH_8_ADD("soundlatch") + MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0)) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( superbar, wiggie ) @@ -9464,6 +9447,8 @@ static MACHINE_CONFIG_START( utoukond ) MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_GENERIC_LATCH_8_ADD("soundlatch") + MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0)) + MCFG_GENERIC_LATCH_SEPARATE_ACKNOWLEDGE(true) MCFG_SOUND_ADD("x1snd", X1_010, 16000000) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) @@ -11847,13 +11832,6 @@ DRIVER_INIT_MEMBER(seta_state,eightfrc) } -DRIVER_INIT_MEMBER(seta_state,zombraid) -{ - m_maincpu->space(AS_PROGRAM).install_read_handler(0xf00002, 0xf00003, read16_delegate(FUNC(seta_state::zombraid_gun_r),this)); - m_maincpu->space(AS_PROGRAM).install_write_handler(0xf00000, 0xf00001, write16_delegate(FUNC(seta_state::zombraid_gun_w),this)); -} - - DRIVER_INIT_MEMBER(seta_state,kiwame) { uint16_t *RAM = (uint16_t *) memregion("maincpu")->base(); @@ -11898,11 +11876,6 @@ DRIVER_INIT_MEMBER(seta_state,wiggie) } - - /* X1_010 is not used. */ - m_maincpu->space(AS_PROGRAM).nop_readwrite(0x100000, 0x103fff); - m_maincpu->space(AS_PROGRAM).install_write_handler(0xB00008, 0xB00009, write16_delegate(FUNC(seta_state::wiggie_soundlatch_w),this)); - } DRIVER_INIT_MEMBER(seta_state,crazyfgt) @@ -12044,8 +12017,8 @@ GAME( 1995, gundharac, gundhara, gundhara, gundhara, seta_state, 0, GAME( 1995, sokonuke, 0, extdwnhl, sokonuke, seta_state, 0, ROT0, "Sammy Industries", "Sokonuke Taisen Game (Japan)", MACHINE_IMPERFECT_SOUND ) -GAME( 1995, zombraid, 0, zombraid, zombraid, seta_state, zombraid, ROT0, "American Sammy", "Zombie Raid (9/28/95, US)", MACHINE_NO_COCKTAIL ) -GAME( 1995, zombraidp, zombraid, zombraid, zombraid, seta_state, zombraid, ROT0, "American Sammy", "Zombie Raid (9/28/95, US, prototype PCB)", MACHINE_NO_COCKTAIL ) // actual code is same as the released version -GAME( 1995, zombraidpj,zombraid, zombraid, zombraid, seta_state, zombraid, ROT0, "Sammy Industries Co.,Ltd.", "Zombie Raid (9/28/95, Japan, prototype PCB)", MACHINE_NO_COCKTAIL ) // just 3 bytes different from above +GAME( 1995, zombraid, 0, zombraid, zombraid, seta_state, 0, ROT0, "American Sammy", "Zombie Raid (9/28/95, US)", MACHINE_NO_COCKTAIL ) +GAME( 1995, zombraidp, zombraid, zombraid, zombraid, seta_state, 0, ROT0, "American Sammy", "Zombie Raid (9/28/95, US, prototype PCB)", MACHINE_NO_COCKTAIL ) // actual code is same as the released version +GAME( 1995, zombraidpj,zombraid, zombraid, zombraid, seta_state, 0, ROT0, "Sammy Industries Co.,Ltd.", "Zombie Raid (9/28/95, Japan, prototype PCB)", MACHINE_NO_COCKTAIL ) // just 3 bytes different from above GAME( 1996, crazyfgt, 0, crazyfgt, crazyfgt, seta_state, crazyfgt, ROT0, "Subsino", "Crazy Fight", MACHINE_UNEMULATED_PROTECTION | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) diff --git a/src/mame/drivers/sh4robot.cpp b/src/mame/drivers/sh4robot.cpp index 68be2643c8e..a61d47ec513 100644 --- a/src/mame/drivers/sh4robot.cpp +++ b/src/mame/drivers/sh4robot.cpp @@ -2,11 +2,14 @@ // copyright-holders:Miodrag Milanovic /*************************************************************************** - SH4 Robot +SH4 Robot - http://perso.telecom-paristech.fr/~polti/robot/ +http://web.archive.org/web/20131127151413/perso.telecom-paristech.fr/~polti/robot/ - 27/11/2013 Skeleton driver. +Original site died. None of the downloads in the above wayback page work, so fairly useless. + + +2013-11-27 Skeleton driver. 0x0000 0000 - 0x7FFF FFFF : P0 area, cachable @@ -34,15 +37,16 @@ class sh4robot_state : public driver_device { public: sh4robot_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu") { } - + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { } +private: required_device<cpu_device> m_maincpu; }; -static ADDRESS_MAP_START(sh4robot_mem, AS_PROGRAM, 64, sh4robot_state) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 64, sh4robot_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00000000, 0x00000fff) AM_ROM AM_RANGE(0x08000000, 0x08ffffff) AM_RAM // SDRAM 1 @@ -50,7 +54,7 @@ static ADDRESS_MAP_START(sh4robot_mem, AS_PROGRAM, 64, sh4robot_state) AM_RANGE(0xa0000000, 0xa0000fff) AM_ROM AM_REGION("maincpu", 0) ADDRESS_MAP_END -static ADDRESS_MAP_START( sh4robot_io, AS_IO, 64, sh4robot_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 64, sh4robot_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_END @@ -70,8 +74,8 @@ static MACHINE_CONFIG_START( sh4robot ) MCFG_SH4_MD7(1) MCFG_SH4_MD8(0) MCFG_SH4_CLOCK(200000000) - MCFG_CPU_PROGRAM_MAP(sh4robot_mem) - MCFG_CPU_IO_MAP(sh4robot_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_CPU_FORCE_NO_DRC() MACHINE_CONFIG_END @@ -91,4 +95,4 @@ ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -COMP( 20??, sh4robot, 0, 0, sh4robot, sh4robot, sh4robot_state, 0, "<unknown>", "Robot", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 20??, sh4robot, 0, 0, sh4robot, sh4robot, sh4robot_state, 0, "<unknown>", "Robot", MACHINE_IS_SKELETON_MECHANICAL ) diff --git a/src/mame/drivers/shanghai.cpp b/src/mame/drivers/shanghai.cpp index 8985698bff4..da6e6e67ade 100644 --- a/src/mame/drivers/shanghai.cpp +++ b/src/mame/drivers/shanghai.cpp @@ -7,9 +7,11 @@ Shanghai driver by Nicola Salmoria TODO: -- games are currently too fast (especially noticeable with kothello screen transitions), either irqs actually - fires every two frames or a HD63484 SR bit isn't behaving correctly; +- games are currently too fast (especially noticeable with kothello screen transitions), maybe unemulated HD63484 wait state penalties? - minor glitch with gfx copy on shanghai stage info panel (garbage on right); +- irq ack, shanghai and shangha2 uses it, kothello auto acks, maybe latter really runs on NMI instead + (vector 2 matches same pattern as shanghai games); +- shanghai: IC37 returns bad in service mode; * kothello @@ -20,11 +22,10 @@ displayed. ***************************************************************************/ #include "emu.h" -#include "audio/seibu.h" - #include "cpu/nec/nec.h" -#include "sound/2203intf.h" #include "video/hd63484.h" +#include "audio/seibu.h" +#include "sound/2203intf.h" #include "screen.h" #include "speaker.h" @@ -34,15 +35,17 @@ class shanghai_state : public driver_device public: shanghai_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu") { } - - required_device<cpu_device> m_maincpu; - - DECLARE_WRITE16_MEMBER(shanghai_coin_w); + m_maincpu(*this, "maincpu"), + m_screen(*this,"screen") + { } + DECLARE_WRITE8_MEMBER(shanghai_coin_w); DECLARE_PALETTE_INIT(shanghai); + INTERRUPT_GEN_MEMBER(half_vblank_irq); - INTERRUPT_GEN_MEMBER(interrupt); +private: + required_device<cpu_device> m_maincpu; + required_device<screen_device> m_screen; }; @@ -50,12 +53,10 @@ PALETTE_INIT_MEMBER(shanghai_state,shanghai) { int i; - for (i = 0;i < palette.entries();i++) { int bit0,bit1,bit2,r,g,b; - /* red component */ bit0 = (i >> 2) & 0x01; bit1 = (i >> 3) & 0x01; @@ -76,18 +77,17 @@ PALETTE_INIT_MEMBER(shanghai_state,shanghai) } } -INTERRUPT_GEN_MEMBER(shanghai_state::interrupt) +INTERRUPT_GEN_MEMBER(shanghai_state::half_vblank_irq) { - device.execute().set_input_line_and_vector(0,HOLD_LINE,0x80); + // definitely running at vblank / 2 (hd63484 irq mask not used) + if(m_screen->frame_number() & 1) + device.execute().set_input_line_and_vector(0,HOLD_LINE,0x80); } -WRITE16_MEMBER(shanghai_state::shanghai_coin_w) +WRITE8_MEMBER(shanghai_state::shanghai_coin_w) { - if (ACCESSING_BITS_0_7) - { - machine().bookkeeping().coin_counter_w(0,data & 1); - machine().bookkeeping().coin_counter_w(1,data & 2); - } + machine().bookkeeping().coin_counter_w(0,data & 1); + machine().bookkeeping().coin_counter_w(1,data & 2); } static ADDRESS_MAP_START( shanghai_map, AS_PROGRAM, 16, shanghai_state ) @@ -110,7 +110,7 @@ static ADDRESS_MAP_START( shanghai_portmap, AS_IO, 16, shanghai_state ) AM_RANGE(0x40, 0x41) AM_READ_PORT("P1") AM_RANGE(0x44, 0x45) AM_READ_PORT("P2") AM_RANGE(0x48, 0x49) AM_READ_PORT("SYSTEM") - AM_RANGE(0x4c, 0x4d) AM_WRITE(shanghai_coin_w) + AM_RANGE(0x4c, 0x4d) AM_WRITE8(shanghai_coin_w,0x00ff) ADDRESS_MAP_END @@ -121,7 +121,7 @@ static ADDRESS_MAP_START( shangha2_portmap, AS_IO, 16, shanghai_state ) AM_RANGE(0x30, 0x31) AM_DEVREADWRITE("hd63484", hd63484_device, status_r, address_w) AM_RANGE(0x32, 0x33) AM_DEVREADWRITE("hd63484", hd63484_device, data_r, data_w) AM_RANGE(0x40, 0x43) AM_DEVREADWRITE8("ymsnd", ym2203_device, read, write, 0x00ff) - AM_RANGE(0x50, 0x51) AM_WRITE(shanghai_coin_w) + AM_RANGE(0x50, 0x51) AM_WRITE8(shanghai_coin_w,0x00ff) ADDRESS_MAP_END static ADDRESS_MAP_START( kothello_map, AS_PROGRAM, 16, shanghai_state ) @@ -241,37 +241,40 @@ static INPUT_PORTS_START( kothello ) PORT_DIPSETTING( 0x00, "4" ) INPUT_PORTS_END - -static INPUT_PORTS_START( shanghai ) +static INPUT_PORTS_START( shanghai_common ) PORT_START("P1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Select Button") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Cancel Button") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Help Button") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("P2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_COCKTAIL + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Select Button") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Cancel Button") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Help Button") PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("SYSTEM") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) +INPUT_PORTS_END + +static INPUT_PORTS_START( shanghai ) + PORT_INCLUDE( shanghai_common ) PORT_START("DSW1") PORT_SERVICE_DIPLOC( 0x01, IP_ACTIVE_LOW, "SW1:8" ) @@ -322,35 +325,7 @@ static INPUT_PORTS_START( shanghai ) INPUT_PORTS_END static INPUT_PORTS_START( shangha2 ) - PORT_START("P1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("P2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_COCKTAIL - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - - PORT_START("SYSTEM") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN3 ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_INCLUDE( shanghai_common ) PORT_START("DSW1") PORT_SERVICE_DIPLOC( 0x01, IP_ACTIVE_LOW, "SW2:8" ) @@ -409,7 +384,7 @@ static MACHINE_CONFIG_START( shanghai ) MCFG_CPU_ADD("maincpu", V30, XTAL_16MHz/2) /* NEC D70116C-8 */ MCFG_CPU_PROGRAM_MAP(shanghai_map) MCFG_CPU_IO_MAP(shanghai_portmap) - MCFG_CPU_VBLANK_INT_DRIVER("screen", shanghai_state, interrupt) + MCFG_CPU_VBLANK_INT_DRIVER("screen", shanghai_state, half_vblank_irq) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -445,7 +420,7 @@ static MACHINE_CONFIG_START( shangha2 ) MCFG_CPU_ADD("maincpu", V30, XTAL_16MHz/2) /* ? */ MCFG_CPU_PROGRAM_MAP(shangha2_map) MCFG_CPU_IO_MAP(shangha2_portmap) - MCFG_CPU_VBLANK_INT_DRIVER("screen", shanghai_state, interrupt) + MCFG_CPU_VBLANK_INT_DRIVER("screen", shanghai_state, half_vblank_irq) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -479,7 +454,7 @@ static MACHINE_CONFIG_START( kothello ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", V30, XTAL_16MHz) MCFG_CPU_PROGRAM_MAP(kothello_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", shanghai_state, interrupt) + MCFG_CPU_VBLANK_INT_DRIVER("screen", shanghai_state, half_vblank_irq) MCFG_CPU_ADD("audiocpu", Z80, XTAL_16MHz/4) MCFG_CPU_PROGRAM_MAP(kothello_sound_map) @@ -573,7 +548,7 @@ ROM_START( shanghai ) ROM_LOAD16_BYTE( "shg-21a.ic21", 0xa0000, 0x10000, CRC(4ab06d32) SHA1(02667d1270b101386b947d5b9bfe64052e498041) ) ROM_LOAD16_BYTE( "shg-28a.ic28", 0xc0001, 0x10000, CRC(983ec112) SHA1(110e120e35815d055d6108a7603e83d2d990c666) ) ROM_LOAD16_BYTE( "shg-27a.ic27", 0xc0000, 0x10000, CRC(41af0945) SHA1(dfc4638a17f716ccc8e59f275571d6dc1093a745) ) - ROM_LOAD16_BYTE( "shg-37b.ic37", 0xe0001, 0x10000, CRC(ead3d66c) SHA1(f9be9a4773ea6c9ba931f7aa8c79121caacc231c) ) /* Single byte difference from IC37 below 0xD58C == 0x01 */ + ROM_LOAD16_BYTE( "shg-37b.ic37", 0xe0001, 0x10000, BAD_DUMP CRC(ead3d66c) SHA1(f9be9a4773ea6c9ba931f7aa8c79121caacc231c) ) /* Single byte difference from IC37 below 0xD58C == 0x01 */ ROM_LOAD16_BYTE( "shg-36b.ic36", 0xe0000, 0x10000, CRC(a1d6af96) SHA1(01c4c22bf03b3d260fffcbc6dfc5f2dd2bcba14a) ) ROM_END diff --git a/src/mame/drivers/simpsons.cpp b/src/mame/drivers/simpsons.cpp index 52fbcf9506b..cf9ecf32def 100644 --- a/src/mame/drivers/simpsons.cpp +++ b/src/mame/drivers/simpsons.cpp @@ -331,15 +331,15 @@ static MACHINE_CONFIG_START( simpsons ) MCFG_DEVICE_ADD("bank0000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank0000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MCFG_DEVICE_ADD("bank2000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank2000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(14) MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) MCFG_EEPROM_SERIAL_ER5911_8BIT_ADD("eeprom") diff --git a/src/mame/drivers/sitcom.cpp b/src/mame/drivers/sitcom.cpp index 16ede822bb2..a23a0cc3f5e 100644 --- a/src/mame/drivers/sitcom.cpp +++ b/src/mame/drivers/sitcom.cpp @@ -340,8 +340,8 @@ MACHINE_CONFIG_START( sitcom ) MCFG_DEVICE_ADD("bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(sitcom_bank) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MCFG_CLOCK_ADD("100hz", 100) diff --git a/src/mame/drivers/skimaxx.cpp b/src/mame/drivers/skimaxx.cpp index 524ab14ba95..3c621dc4329 100644 --- a/src/mame/drivers/skimaxx.cpp +++ b/src/mame/drivers/skimaxx.cpp @@ -175,12 +175,12 @@ void skimaxx_state::video_start() // TODO: Might not be used TMS340X0_TO_SHIFTREG_CB_MEMBER(skimaxx_state::to_shiftreg) { - memcpy(shiftreg, &m_fg_buffer[TOWORD(address)], 512 * sizeof(uint16_t)); + memcpy(shiftreg, &m_fg_buffer[address >> 4], 512 * sizeof(uint16_t)); } TMS340X0_FROM_SHIFTREG_CB_MEMBER(skimaxx_state::from_shiftreg) { - memcpy(&m_fg_buffer[TOWORD(address)], shiftreg, 512 * sizeof(uint16_t)); + memcpy(&m_fg_buffer[address >> 4], shiftreg, 512 * sizeof(uint16_t)); } diff --git a/src/mame/drivers/slc1.cpp b/src/mame/drivers/slc1.cpp index b97e8c2ab07..f0311452563 100644 --- a/src/mame/drivers/slc1.cpp +++ b/src/mame/drivers/slc1.cpp @@ -60,19 +60,20 @@ class slc1_state : public driver_device { public: slc1_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_speaker(*this, "speaker") + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_speaker(*this, "speaker") { } - required_device<cpu_device> m_maincpu; - required_device<speaker_sound_device> m_speaker; DECLARE_READ8_MEMBER( io_r ); DECLARE_WRITE8_MEMBER( io_w ); +private: uint8_t m_digit; bool m_kbd_type; virtual void machine_reset() override; virtual void machine_start() override; + required_device<cpu_device> m_maincpu; + required_device<speaker_sound_device> m_speaker; }; @@ -180,14 +181,14 @@ void slc1_state::machine_reset() ***************************************************************************/ -static ADDRESS_MAP_START( slc1_map, AS_PROGRAM, 8, slc1_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, slc1_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0x4fff) AM_RANGE(0x0000, 0x0fff) AM_ROM AM_RANGE(0x4000, 0x43ff) AM_RAM AM_MIRROR(0xc00) ADDRESS_MAP_END -static ADDRESS_MAP_START( slc1_io, AS_IO, 8, slc1_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, slc1_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0xffff) AM_READWRITE(io_r,io_w) ADDRESS_MAP_END @@ -255,8 +256,8 @@ INPUT_PORTS_END static MACHINE_CONFIG_START( slc1 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, 2500000) - MCFG_CPU_PROGRAM_MAP(slc1_map) - MCFG_CPU_IO_MAP(slc1_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_DEFAULT_LAYOUT(layout_slc1) diff --git a/src/mame/drivers/slicer.cpp b/src/mame/drivers/slicer.cpp index ebe607a763a..872a69b7da4 100644 --- a/src/mame/drivers/slicer.cpp +++ b/src/mame/drivers/slicer.cpp @@ -7,6 +7,7 @@ #include "emu.h" #include "cpu/i86/i186.h" +#include "machine/74259.h" #include "machine/wd_fdc.h" #include "machine/mc68681.h" #include "bus/rs232/rs232.h" @@ -24,7 +25,7 @@ public: } DECLARE_WRITE8_MEMBER(sio_out_w); - DECLARE_WRITE8_MEMBER(drive_sel_w); + template<unsigned int drive> DECLARE_WRITE_LINE_MEMBER(drive_sel_w); protected: required_device<fd1797_device> m_fdc; @@ -46,35 +47,18 @@ WRITE8_MEMBER(slicer_state::sio_out_w) } } -WRITE8_MEMBER(slicer_state::drive_sel_w) +template<unsigned int drive> +WRITE_LINE_MEMBER(slicer_state::drive_sel_w) { - data &= 1; - switch(offset) - { - case 0: - m_sasi->write_sel(data); - break; - case 1: - m_sasi->write_rst(data); - break; - case 7: - m_fdc->dden_w(data); - break; - - default: - { - floppy_image_device *floppy; - char devname[8]; - unsigned int drive = 3 - (offset - 2); - if((drive > 3) || !data) - break; - - sprintf(devname, "%d", drive); - floppy = m_fdc->subdevice<floppy_connector>(devname)->get_device(); - m_fdc->set_floppy(floppy); - break; - } - } + floppy_image_device *floppy; + char devname[8]; + + if (!state) + return; + + sprintf(devname, "%d", drive); + floppy = m_fdc->subdevice<floppy_connector>(devname)->get_device(); + m_fdc->set_floppy(floppy); } static ADDRESS_MAP_START( slicer_map, AS_PROGRAM, 16, slicer_state ) @@ -85,8 +69,8 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( slicer_io, AS_IO, 16, slicer_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x007f) AM_DEVREADWRITE8("fdc", fd1797_device, read, write, 0x00ff) //PCS0 - AM_RANGE(0x0080, 0x00ff) AM_DEVREADWRITE8("sc2681", mc68681_device, read, write, 0x00ff) //PCS1 - AM_RANGE(0x0100, 0x017f) AM_WRITE8(drive_sel_w, 0x00ff) //PCS2 + AM_RANGE(0x0080, 0x00ff) AM_DEVREADWRITE8("duart", scn2681_device, read, write, 0x00ff) //PCS1 + AM_RANGE(0x0100, 0x0107) AM_MIRROR(0x0078) AM_DEVWRITE8("drivelatch", ls259_device, write_d0, 0x00ff) //PCS2 // TODO: 0x180 sets ack AM_RANGE(0x0180, 0x0181) AM_DEVREAD8("sasi_data_in", input_buffer_device, read, 0x00ff) AM_DEVWRITE8("sasi_data_out", output_latch_device, write, 0x00ff) //PCS3 AM_RANGE(0x0180, 0x0181) AM_DEVREAD8("sasi_ctrl_in", input_buffer_device, read, 0xff00) @@ -104,16 +88,16 @@ static MACHINE_CONFIG_START( slicer ) MCFG_CPU_PROGRAM_MAP(slicer_map) MCFG_CPU_IO_MAP(slicer_io) - MCFG_MC68681_ADD("sc2681", XTAL_3_6864MHz) + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) MCFG_MC68681_IRQ_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, int0_w)) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("rs232_1", rs232_port_device, write_txd)) MCFG_MC68681_B_TX_CALLBACK(DEVWRITELINE("rs232_2", rs232_port_device, write_txd)) MCFG_MC68681_OUTPORT_CALLBACK(WRITE8(slicer_state, sio_out_w)) MCFG_RS232_PORT_ADD("rs232_1", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sc2681", mc68681_device, rx_a_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_a_w)) MCFG_RS232_PORT_ADD("rs232_2", default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sc2681", mc68681_device, rx_b_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_b_w)) MCFG_FD1797_ADD("fdc", XTAL_16MHz/2/8) MCFG_WD_FDC_INTRQ_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, int1_w)) @@ -123,6 +107,15 @@ static MACHINE_CONFIG_START( slicer ) MCFG_FLOPPY_DRIVE_ADD("fdc:2", slicer_floppies, nullptr, floppy_image_device::default_floppy_formats) MCFG_FLOPPY_DRIVE_ADD("fdc:3", slicer_floppies, nullptr, floppy_image_device::default_floppy_formats) + MCFG_DEVICE_ADD("drivelatch", LS259, 0) // U29 + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(DEVWRITELINE("sasi", scsi_port_device, write_sel)) + MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(DEVWRITELINE("sasi", scsi_port_device, write_rst)) + MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE(slicer_state, drive_sel_w<3>)) + MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(WRITELINE(slicer_state, drive_sel_w<2>)) + MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(WRITELINE(slicer_state, drive_sel_w<1>)) + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(WRITELINE(slicer_state, drive_sel_w<0>)) + MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(DEVWRITELINE("fdc", fd1797_device, dden_w)) + MCFG_DEVICE_ADD("sasi", SCSI_PORT, 0) MCFG_SCSI_DATA_INPUT_BUFFER("sasi_data_in") MCFG_SCSI_BSY_HANDLER(DEVWRITELINE("sasi_ctrl_in", input_buffer_device, write_bit3)) diff --git a/src/mame/drivers/sm7238.cpp b/src/mame/drivers/sm7238.cpp index 05b9fb1d65b..10a95e6f859 100644 --- a/src/mame/drivers/sm7238.cpp +++ b/src/mame/drivers/sm7238.cpp @@ -3,16 +3,15 @@ /*************************************************************************** SM 7238 (aka T3300) color/mono text terminal, compatible with DEC VT 240. - Graphics option adds Tek 401x and DEC ReGIS support on a 512x250 bitmap. + Graphics options add Tek 401x and DEC ReGIS support Technical manual and schematics: http://doc.pdp-11.org.ru/Terminals/CM7238/ To do: - - handle more text_control_w bits - - 80/132 columns switching on the fly, reverse video - - graphics option + . handle more text_control_w bits + - downloadable fonts (stored in nvram) + - graphics options - colors - - run vblank from timer output? - document hardware and ROM variants, verify if pixel stretching is done ****************************************************************************/ @@ -21,6 +20,7 @@ #include "bus/rs232/rs232.h" #include "cpu/i8085/i8085.h" +#include "machine/bankdev.h" #include "machine/clock.h" #include "machine/i8251.h" #include "machine/pit8253.h" @@ -29,15 +29,15 @@ #include "machine/nvram.h" #include "screen.h" -#define KSM_COLUMNS 80 // or 132 -#define KSM_TOTAL_HORZ KSM_COLUMNS*10 -#define KSM_DISP_HORZ KSM_COLUMNS*8 -#define KSM_HORZ_START KSM_COLUMNS +#define KSM_COLUMNS_MAX 132 + +#define KSM_TOTAL_HORZ (KSM_COLUMNS_MAX*10) +#define KSM_DISP_HORZ (KSM_COLUMNS_MAX*8) #define KSM_TOTAL_VERT 260 #define KSM_DISP_VERT 250 -#define KSM_VERT_START 5 + #define VERBOSE_DBG 1 /* general debug messages */ @@ -59,6 +59,7 @@ public: : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_nvram(*this, "nvram") + , m_videobank(*this, "videobank") , m_p_videoram(*this, "videoram") , m_p_chargen(*this, "chargen") , m_pic8259(*this, "pic8259") @@ -84,10 +85,11 @@ public: DECLARE_WRITE8_MEMBER(control_w); DECLARE_WRITE8_MEMBER(text_control_w); + DECLARE_WRITE8_MEMBER(vmem_w); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); private: - void text_memory_clear(); void recompute_parameters(); struct @@ -95,12 +97,14 @@ private: uint8_t control; uint16_t ptr; int stride; + bool reverse; } m_video; virtual void machine_reset() override; virtual void video_start() override; required_device<cpu_device> m_maincpu; required_device<nvram_device> m_nvram; + required_device<address_map_bank_device> m_videobank; required_shared_ptr<uint8_t> m_p_videoram; required_region_ptr<u8> m_p_chargen; required_device<pic8259_device> m_pic8259; @@ -125,7 +129,12 @@ static ADDRESS_MAP_START( sm7238_mem, AS_PROGRAM, 8, sm7238_state ) AM_RANGE (0xb800, 0xb800) AM_WRITE(text_control_w) AM_RANGE (0xbc00, 0xbc00) AM_WRITE(control_w) AM_RANGE (0xc000, 0xcfff) AM_RAM // chargen - AM_RANGE (0xe000, 0xffff) AM_RAM AM_SHARE("videoram") // e000 -- chars, f000 -- attrs + AM_RANGE (0xe000, 0xffff) AM_DEVICE("videobank", address_map_bank_device, amap8) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( videobank_map, AS_PROGRAM, 8, sm7238_state ) + AM_RANGE (0x0000, 0x1fff) AM_RAM AM_SHARE("videoram") + AM_RANGE (0x2000, 0x2fff) AM_MIRROR(0x1000) AM_WRITE(vmem_w) ADDRESS_MAP_END static ADDRESS_MAP_START( sm7238_io, AS_IO, 8, sm7238_state ) @@ -147,6 +156,7 @@ ADDRESS_MAP_END void sm7238_state::machine_reset() { memset(&m_video, 0, sizeof(m_video)); + m_videobank->set_bank(0); } void sm7238_state::video_start() @@ -155,28 +165,39 @@ void sm7238_state::video_start() WRITE8_MEMBER(sm7238_state::control_w) { - DBG_LOG(1,"Control Write", ("%02xh: lut %d nvram %d c2 %d iack %d\n", + DBG_LOG(1, "Control Write", ("%02xh: lut %d nvram %d c2 %d iack %d\n", data, BIT(data, 0), BIT(data, 2), BIT(data, 3), BIT(data, 5))); } WRITE8_MEMBER(sm7238_state::text_control_w) { if (data ^ m_video.control) - DBG_LOG(1,"Text Control Write", ("%02xh: 80/132 %d dma %d clr %d dlt %d inv %d ?? %d\n", - data, BIT(data, 0), BIT(data, 1), BIT(data, 2), BIT(data, 3), BIT(data, 4), BIT(data, 5))); - - if (!BIT(data, 2) && !BIT(data, 3)) - text_memory_clear(); + { + DBG_LOG(1, "Text Control Write", ("%02xh: 80/132 %d dma %d clr %d dlt %d inv %d ?? %d\n", + data, BIT(data, 0), BIT(data, 1), BIT(data, 2), BIT(data, 3), BIT(data, 4), BIT(data, 5))); + } if (BIT((data ^ m_video.control), 0)) { m_video.stride = BIT(data, 0) ? 80 : 132; -// recompute_parameters(); + recompute_parameters(); + } + + if (BIT((data ^ m_video.control), 2)) + { + m_videobank->set_bank(1 - BIT(data, 2)); } + m_video.reverse = BIT(data, 4); m_video.control = data; } +WRITE8_MEMBER(sm7238_state::vmem_w) +{ + m_p_videoram[offset] = data; + m_p_videoram[offset + 0x1000] = data; +} + WRITE_LINE_MEMBER(sm7238_state::write_keyboard_clock) { m_i8251kbd->write_txc(state); @@ -189,34 +210,29 @@ WRITE_LINE_MEMBER(sm7238_state::write_printer_clock) m_i8251prn->write_rxc(state); } -void sm7238_state::text_memory_clear() -{ - int y = 0, ptr = 0; - - do - { - memset(&m_p_videoram[ptr], 0x20, m_video.stride); - memset(&m_p_videoram[ptr + 0x1000], 0x20, m_video.stride); - ptr = m_p_videoram[ptr + m_video.stride + 1] | (m_p_videoram[ptr + 0x1000 + m_video.stride + 1] << 8); - ptr &= 0x0fff; - y++; - } while (y < 26); -} - void sm7238_state::recompute_parameters() { rectangle visarea; - int horiz_pix_total = m_video.stride * 8; + attoseconds_t refresh; + + visarea.set(0, m_video.stride * 8 - 1, 0, KSM_DISP_VERT - 1); + + if (m_video.stride == 80) + { + refresh = HZ_TO_ATTOSECONDS(XTAL_12_5MHz) * m_video.stride * 10 * KSM_TOTAL_VERT; + } + else + { + refresh = HZ_TO_ATTOSECONDS(XTAL_20_625MHz) * m_video.stride * 10 * KSM_TOTAL_VERT; + } - visarea.set(0, horiz_pix_total - 1, 0, KSM_DISP_VERT - 1); - machine().first_screen()->configure(horiz_pix_total, KSM_DISP_VERT, visarea, - HZ_TO_ATTOSECONDS((m_video.stride == 80) ? 60 : 57.1 )); + machine().first_screen()->configure(m_video.stride * 10, KSM_TOTAL_VERT, visarea, refresh); } uint32_t sm7238_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { uint8_t y, ra, gfx, fg, bg, attr, ctl1, ctl2 = 0; - uint16_t chr, sy = KSM_VERT_START, ma = 0, x = 0; + uint16_t chr, sy = 0, ma = 0, x = 0; bool double_width = false, double_height = false, bottom_half = false; if (!BIT(m_video.control, 3)) @@ -232,12 +248,27 @@ uint32_t sm7238_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap if (y == 1 && ctl2 && ra < ctl2) continue; - uint16_t *p = &bitmap.pix16(sy++, KSM_HORZ_START); + uint16_t *p = &bitmap.pix16(sy++, 0); for (x = ma; x < ma + m_video.stride; x++) { chr = m_p_videoram[x] << 4; attr = m_p_videoram[x + 0x1000]; + + // alternate font 1 + if (BIT(attr, 6)) + { + chr += 0x1000; + } + // alternate font 2 -- only in models .05 and .06 + if (BIT(attr, 7)) + { + chr = 0x11a << 4; + } + + bg = 0; + fg = 1; + if (double_height) { gfx = m_p_chargen[chr | (bottom_half ? (5 + (ra >> 1)) : (ra >> 1))] ^ 255; @@ -247,9 +278,6 @@ uint32_t sm7238_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap gfx = m_p_chargen[chr | ra] ^ 255; } - bg = 0; - fg = 1; - /* Process attributes */ if ((BIT(attr, 1)) && (ra == 9)) { @@ -261,42 +289,33 @@ uint32_t sm7238_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap gfx ^= 0xff; // reverse video } if (BIT(attr, 4)) + { fg = 2; // highlight + } else + { fg = 1; + } + if (m_video.reverse) + { + bg = fg; + fg = 0; + } - *p++ = BIT(gfx, 7) ? fg : bg; - if (double_width) - *p++ = BIT(gfx, 7) ? fg : bg; - *p++ = BIT(gfx, 6) ? fg : bg; - if (double_width) - *p++ = BIT(gfx, 6) ? fg : bg; - *p++ = BIT(gfx, 5) ? fg : bg; - if (double_width) - *p++ = BIT(gfx, 5) ? fg : bg; - *p++ = BIT(gfx, 4) ? fg : bg; - if (double_width) - *p++ = BIT(gfx, 4) ? fg : bg; - *p++ = BIT(gfx, 3) ? fg : bg; - if (double_width) - *p++ = BIT(gfx, 3) ? fg : bg; - *p++ = BIT(gfx, 2) ? fg : bg; - if (double_width) - *p++ = BIT(gfx, 2) ? fg : bg; - *p++ = BIT(gfx, 1) ? fg : bg; - if (double_width) - *p++ = BIT(gfx, 1) ? fg : bg; - *p++ = BIT(gfx, 0) ? fg : bg; - if (double_width) - *p++ = BIT(gfx, 0) ? fg : bg; + for (int i = 7; i >= 0; i--) + { + *p++ = BIT(gfx, i) ? fg : bg; + if (double_width) + *p++ = BIT(gfx, i) ? fg : bg; + } if (double_width) x++; } } ctl1 = m_p_videoram[ma + 0x1000 + m_video.stride]; - double_width = BIT(ctl1, 6); + double_width = BIT(ctl1, 6); double_height = BIT(ctl1, 7); - bottom_half = BIT(ctl1, 5); + bottom_half = BIT(ctl1, 5); ctl2 = m_p_videoram[ma + 0x1000 + m_video.stride + 1] >> 4; @@ -313,7 +332,7 @@ uint32_t sm7238_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap static const gfx_layout sm7238_charlayout = { 8, 12, /* most chars use 8x10 pixels */ - 256, /* 256 characters */ + 512, /* 512 characters */ 1, /* 1 bits per pixel */ { 0 }, /* no bitplanes */ /* x offsets */ @@ -340,18 +359,16 @@ static MACHINE_CONFIG_START( sm7238 ) MCFG_CPU_IO_MAP(sm7238_io) MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("pic8259", pic8259_device, inta_cb) + MCFG_DEVICE_ADD("videobank", ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(videobank_map) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) + MCFG_NVRAM_ADD_0FILL("nvram") MCFG_SCREEN_ADD("screen", RASTER) -#if KSM_COLUMNS == 80 - MCFG_SCREEN_RAW_PARAMS(XTAL_12_5MHz, - KSM_TOTAL_HORZ, KSM_HORZ_START, KSM_HORZ_START+KSM_DISP_HORZ, - KSM_TOTAL_VERT, KSM_VERT_START, KSM_VERT_START+KSM_DISP_VERT); -#else - MCFG_SCREEN_RAW_PARAMS(XTAL_20_625MHz, - KSM_TOTAL_HORZ, KSM_HORZ_START, KSM_HORZ_START+KSM_DISP_HORZ, - KSM_TOTAL_VERT, KSM_VERT_START, KSM_VERT_START+KSM_DISP_VERT); -#endif + MCFG_SCREEN_RAW_PARAMS(XTAL_20_625MHz, KSM_TOTAL_HORZ, 0, KSM_DISP_HORZ, KSM_TOTAL_VERT, 0, KSM_DISP_VERT); MCFG_SCREEN_UPDATE_DRIVER(sm7238_state, screen_update) MCFG_SCREEN_VBLANK_CALLBACK(DEVWRITELINE("pic8259", pic8259_device, ir2_w)) MCFG_SCREEN_PALETTE("palette") diff --git a/src/mame/drivers/socrates.cpp b/src/mame/drivers/socrates.cpp index a9f114dac0b..aa48b8ee051 100644 --- a/src/mame/drivers/socrates.cpp +++ b/src/mame/drivers/socrates.cpp @@ -1454,19 +1454,19 @@ static MACHINE_CONFIG_START( socrates ) MCFG_DEVICE_ADD("rombank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(socrates_rombank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("rambank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(socrates_rambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("rambank2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(socrates_rambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) /* video hardware */ @@ -1520,25 +1520,25 @@ static MACHINE_CONFIG_START( iqunlimz ) MCFG_DEVICE_ADD("rombank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(iqunlimz_rombank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("rombank2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(iqunlimz_rombank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("rambank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(iqunlimz_rambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("rambank2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(iqunlimz_rambank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) /* video hardware */ diff --git a/src/mame/drivers/solbourne.cpp b/src/mame/drivers/solbourne.cpp index 32a28630712..f0ec941b5f0 100644 --- a/src/mame/drivers/solbourne.cpp +++ b/src/mame/drivers/solbourne.cpp @@ -9,26 +9,25 @@ Solbourne computer workstation. This looks like the Series 5E which uses the Cyp ************************************************************************************************************************************/ #include "emu.h" -//#include "cpu/mcs51/mcs51.h" class solbourne_state : public driver_device { public: solbourne_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) -// , maincpu(*this, "maincpu") +// , m_maincpu(*this, "maincpu") { } -protected: -// required_device<i80c52_device> maincpu; +private: +// required_device<cpu_device> m_maincpu; }; +//static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, solbourne_state ) +//ADDRESS_MAP_END + static INPUT_PORTS_START( solbourne ) INPUT_PORTS_END -//static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, solbourne_state ) -//ADDRESS_MAP_END - static MACHINE_CONFIG_START( solbourne ) MACHINE_CONFIG_END diff --git a/src/mame/drivers/sothello.cpp b/src/mame/drivers/sothello.cpp index a214612262c..ff48bcdb680 100644 --- a/src/mame/drivers/sothello.cpp +++ b/src/mame/drivers/sothello.cpp @@ -56,7 +56,7 @@ public: m_subcpu(*this, "subcpu"), m_v9938(*this, "v9938"), m_msm(*this, "msm"), - m_bank1(*this, "mainbank") + m_mainbank(*this, "mainbank") { } DECLARE_WRITE8_MEMBER(bank_w); @@ -91,7 +91,7 @@ private: required_device<cpu_device> m_subcpu; required_device<v9938_device> m_v9938; required_device<msm5205_device> m_msm; - required_memory_bank m_bank1; + required_memory_bank m_mainbank; }; @@ -109,7 +109,7 @@ private: void sothello_state::machine_start() { - m_bank1->configure_entries(0, 4, memregion("maincpu")->base() + 0x8000, 0x4000); + m_mainbank->configure_entries(0, 4, memregion("maincpu")->base() + 0x8000, 0x4000); save_item(NAME(m_subcpu_status)); save_item(NAME(m_soundcpu_busy)); @@ -126,7 +126,7 @@ WRITE8_MEMBER(sothello_state::bank_w) case 4: bank=2; break; case 8: bank=3; break; } - m_bank1->set_entry(bank); + m_mainbank->set_entry(bank); } TIMER_CALLBACK_MEMBER(sothello_state::subcpu_suspend) @@ -412,4 +412,4 @@ ROM_START( sothello ) ROM_LOAD( "6.7f", 0x0000, 0x8000, CRC(ee80fc78) SHA1(9a9d7925847d7a36930f0761c70f67a9affc5e7c) ) ROM_END -GAME( 1986, sothello, 0, sothello, sothello, sothello_state, 0, ROT0, "Success / Fujiwara", "Super Othello", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, sothello, 0, sothello, sothello, sothello_state, 0, ROT0, "Success / Fujiwara", "Super Othello", 0 ) diff --git a/src/mame/drivers/spiders.cpp b/src/mame/drivers/spiders.cpp index c25b6eac5b7..c28978e00fe 100644 --- a/src/mame/drivers/spiders.cpp +++ b/src/mame/drivers/spiders.cpp @@ -276,10 +276,10 @@ INTERRUPT_GEN_MEMBER(spiders_state::update_pia_1) * *************************************/ -WRITE8_MEMBER(spiders_state::ic60_74123_output_changed) +WRITE_LINE_MEMBER(spiders_state::ic60_74123_output_changed) { pia6821_device *pia2 = machine().device<pia6821_device>("pia2"); - pia2->ca1_w(data); + pia2->ca1_w(state); } /************************************* @@ -368,11 +368,6 @@ MC6845_UPDATE_ROW( spiders_state::crtc_update_row ) } -WRITE_LINE_MEMBER(spiders_state::display_enable_changed) -{ - machine().device<ttl74123_device>("ic60")->a_w(generic_space(), 0, state); -} - /************************************* * @@ -564,7 +559,7 @@ static MACHINE_CONFIG_START( spiders ) MCFG_MC6845_SHOW_BORDER_AREA(false) MCFG_MC6845_CHAR_WIDTH(8) MCFG_MC6845_UPDATE_ROW_CB(spiders_state, crtc_update_row) - MCFG_MC6845_OUT_DE_CB(WRITELINE(spiders_state, display_enable_changed)) + MCFG_MC6845_OUT_DE_CB(DEVWRITELINE("ic60", ttl74123_device, a_w)) /* 74LS123 */ @@ -599,7 +594,7 @@ static MACHINE_CONFIG_START( spiders ) MCFG_TTL74123_A_PIN_VALUE(1) /* A pin - driven by the CRTC */ MCFG_TTL74123_B_PIN_VALUE(1) /* B pin - pulled high */ MCFG_TTL74123_CLEAR_PIN_VALUE(1) /* Clear pin - pulled high */ - MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITE8(spiders_state, ic60_74123_output_changed)) + MCFG_TTL74123_OUTPUT_CHANGED_CB(WRITELINE(spiders_state, ic60_74123_output_changed)) /* audio hardware */ MCFG_FRAGMENT_ADD(spiders_audio) diff --git a/src/mame/drivers/srmp2.cpp b/src/mame/drivers/srmp2.cpp index 05f6230552e..85d59bd3fd5 100644 --- a/src/mame/drivers/srmp2.cpp +++ b/src/mame/drivers/srmp2.cpp @@ -30,17 +30,19 @@ System specs : CPU : 68000 (8MHz) Sound : AY8910 + MSM5205 Chips : X1-001, X1-002A, X1-003, X1-004x2, X0-005 x2 - X1-001, X1-002A : Sprites - X1-003 : Video output - X1-004 : ??? - X1-005 : ??? + X1-001, X1-002A (64 pins) : Sprites + X1-003 (?? pins) : Video output + X1-004 (52 pins) : Inputs + X0-005 (40 pins) : Interface Known issues : =============== - IOX might be either a shared component between PCBs or every game have its own configuration. For now I've opted for the latter solution, until an HW test will be done ... - Could also be that's a MCU of some sort. + - X0-005 is a probable MCU, most likely a 8741/8742 UPI type like the "M-Chip" in tnzs.cpp. + One X0-005 handles the inputs; the other drives the MSM5205 with the aid of a 8243 expander. + Are both of these functions really performed by the same (undumped) internal program? - AY-3-8910 sound may be wrong. - CPU clock of srmp3 does not match the real machine. - MSM5205 clock frequency in srmp3 is wrong. diff --git a/src/mame/drivers/ssfindo.cpp b/src/mame/drivers/ssfindo.cpp index 6560b23586f..6f7037e304c 100644 --- a/src/mame/drivers/ssfindo.cpp +++ b/src/mame/drivers/ssfindo.cpp @@ -339,7 +339,7 @@ TIMER_CALLBACK_MEMBER(ssfindo_state::PS7500_Timer0_callback) m_PS7500_IO[IRQSTA]|=0x20; if(m_PS7500_IO[IRQMSKA]&0x20) { - generic_pulse_irq_line(*m_maincpu, ARM7_IRQ_LINE, 1); + m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); } } @@ -358,7 +358,7 @@ TIMER_CALLBACK_MEMBER(ssfindo_state::PS7500_Timer1_callback) m_PS7500_IO[IRQSTA]|=0x40; if(m_PS7500_IO[IRQMSKA]&0x40) { - generic_pulse_irq_line(*m_maincpu, ARM7_IRQ_LINE, 1); + m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); } } @@ -376,7 +376,7 @@ INTERRUPT_GEN_MEMBER(ssfindo_state::interrupt) m_PS7500_IO[IRQSTA]|=0x08; if(m_PS7500_IO[IRQMSKA]&0x08) { - generic_pulse_irq_line(device.execute(), ARM7_IRQ_LINE, 1); + device.execute().pulse_input_line(ARM7_IRQ_LINE, device.execute().minimum_quantum_time()); } } diff --git a/src/mame/drivers/ssozumo.cpp b/src/mame/drivers/ssozumo.cpp index 2c7fe9c11c0..71f698dcaf9 100644 --- a/src/mame/drivers/ssozumo.cpp +++ b/src/mame/drivers/ssozumo.cpp @@ -148,9 +148,9 @@ INPUT_PORTS_END static const gfx_layout charlayout = { 8,8, /* 8*8 characters */ - 1024, /* 1024 characters */ + RGN_FRAC(1,3), /* 1024 characters */ 3, /* 3 bits per pixel */ - { 2*1024*8*8, 1024*8*8, 0 }, /* the bitplanes are separated */ + { RGN_FRAC(2,3), RGN_FRAC(1,3), RGN_FRAC(0,3) }, /* the bitplanes are separated */ { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, 8*8 /* every char takes 8 consecutive bytes */ @@ -210,10 +210,12 @@ static MACHINE_CONFIG_START( ssozumo ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_REFRESH_RATE(60) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) - MCFG_SCREEN_SIZE(32*8, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8 - 1, 1*8, 31*8 - 1) +// MCFG_SCREEN_REFRESH_RATE(60) +// MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) +// MCFG_SCREEN_SIZE(32*8, 32*8) +// MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8 - 1, 1*8, 31*8 - 1) + // DECO video CRTC, unverified + MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,384,0,256,272,8,248) MCFG_SCREEN_UPDATE_DRIVER(ssozumo_state, screen_update) MCFG_SCREEN_PALETTE("palette") @@ -226,10 +228,10 @@ static MACHINE_CONFIG_START( ssozumo ) MCFG_GENERIC_LATCH_8_ADD("soundlatch") - MCFG_SOUND_ADD("ay1", AY8910, 1500000) + MCFG_SOUND_ADD("ay1", YM2149, 1500000) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.3) - MCFG_SOUND_ADD("ay2", AY8910, 1500000) + MCFG_SOUND_ADD("ay2", YM2149, 1500000) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.3) MCFG_SOUND_ADD("dac", DAC_8BIT_R2R, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.3) // unknown DAC diff --git a/src/mame/drivers/starshp1.cpp b/src/mame/drivers/starshp1.cpp index 705cccc77af..6d71cde804c 100644 --- a/src/mame/drivers/starshp1.cpp +++ b/src/mame/drivers/starshp1.cpp @@ -21,7 +21,7 @@ Atari Starship 1 driver INTERRUPT_GEN_MEMBER(starshp1_state::starshp1_interrupt) { if ((ioport("SYSTEM")->read() & 0x90) != 0x90) - generic_pulse_irq_line(device.execute(), 0, 1); + device.execute().pulse_input_line(0, device.execute().minimum_quantum_time()); } diff --git a/src/mame/drivers/stuntair.cpp b/src/mame/drivers/stuntair.cpp index 7d8f4f9b75d..b7b3b9a0b68 100644 --- a/src/mame/drivers/stuntair.cpp +++ b/src/mame/drivers/stuntair.cpp @@ -27,7 +27,7 @@ Bg 1,5kb (2114 x3) Sprites 1kb (2148 x2) color 320byte (27ls00 x10) -Rom definiton: +Rom definition: -top pcb- stuntair.a0,a1,a3,a4,a6 main program stuntair.e14 sound program diff --git a/src/mame/drivers/stv.cpp b/src/mame/drivers/stv.cpp index 8d0df302af0..192cbb18320 100644 --- a/src/mame/drivers/stv.cpp +++ b/src/mame/drivers/stv.cpp @@ -3634,47 +3634,47 @@ GAME( 1997, znpwfvt, znpwfv, stv, stv, stv_state, znpwfv, ROT /* Unemulated printer / camera devices */ // USA sets -GAME( 1997, pclub2, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 (U 970921 V1.000)", MACHINE_NOT_WORKING ) -GAME( 1999, pclub2v3, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 3 (U 990310 V1.000)", MACHINE_NOT_WORKING ) // Hello Kitty themed -GAME( 1999, pclubpok, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club Pokemon B (U 991126 V1.000)", MACHINE_NOT_WORKING ) +GAME( 1997, pclub2, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 (U 970921 V1.000)", MACHINE_NOT_WORKING ) +GAME( 1999, pclub2v3, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 3 (U 990310 V1.000)", MACHINE_NOT_WORKING ) // Hello Kitty themed +GAME( 1999, pclubpok, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club Pokemon B (U 991126 V1.000)", MACHINE_NOT_WORKING ) // Japan sets -GAME( 1999, pclub2fc, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Felix The Cat (Rev. A) (J 970415 V1.100)", MACHINE_NOT_WORKING ) -GAME( 1998, pclub2pf, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Puffy (Japan)", MACHINE_NOT_WORKING ) // version info is blank -GAME( 1997, pclub2pe, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Pepsiman (J 970618 V1.100)", MACHINE_NOT_WORKING ) -GAME( 1997, pclub2wb, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Warner Bros (J 970228 V1.000)", MACHINE_NOT_WORKING ) - -GAME( 1997, pclb2elk, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Earth Limited Kobe (Print Club Custom) (J 970808 V1.000)", MACHINE_NOT_WORKING ) -GAME( 1997, pckobe99, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Kobe Luminaire '99 (Print Club Custom 3) (J 991203 V1.000)", MACHINE_NOT_WORKING ) - -GAME( 1997, pclub26w, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 6 Winter (J 961210 V1.000)", MACHINE_NOT_WORKING ) // internal string is 'PURIKURA2 97FUYU' (but in reality it seems to be an end of 96 Winter version) -GAME( 1997, pclub26wa, pclub26w,stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 6 Winter (J 970121 V1.200)", MACHINE_NOT_WORKING ) // ^ -GAME( 1997, pclub27s, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 7 Spring (J 970313 V1.100)", MACHINE_NOT_WORKING ) -GAME( 1997, prc28su, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 8 Summer (J 970616 V1.100)", MACHINE_NOT_WORKING ) // internal string 97SUMMER -GAME( 1997, prc29au, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 9 Autumn (J V1.100)", MACHINE_NOT_WORKING ) // internal string 97AUTUMN, no date code! (all 0) -GAME( 1997, prc297wi, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '97 Winter Ver (J 971017 V1.100, set 1)", MACHINE_NOT_WORKING ) // internal string is '97WINTER' -GAME( 1997, prc297wia, prc297wi,stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '97 Winter Ver (J 971017 V1.100, set 2)", MACHINE_NOT_WORKING ) // different program revision, same date code, clearly didn't get updated properly -GAME( 1998, prc298sp, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '98 Spring Ver (J 971017 V1.100)", MACHINE_NOT_WORKING ) // again, date doesn't appear to have bene updated, this should be early 98 -GAME( 1998, prc298su, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '98 Summer Ver (J 980603 V1.100)", MACHINE_NOT_WORKING ) // -GAME( 1998, prc298au, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 '98 Autumn Ver (J 980827 V1.000)", MACHINE_NOT_WORKING ) -GAME( 2000, prc2ksu, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club 2 2000 Summer (J 000509 V1.000)", MACHINE_NOT_WORKING ) // internal string 2000_SUMMER - - -GAME( 1999, pclubor, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club Goukakenran (J 991104 V1.000)", MACHINE_NOT_WORKING ) -GAME( 1999, pclubol, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club Olive (J 980717 V1.000)", MACHINE_NOT_WORKING ) -GAME( 1997, pclub2kc, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club Kome Kome Club (J 970203 V1.000)", MACHINE_NOT_WORKING ) -GAME( 1997, pclubyo2, stvbios, stv, stv, stv_state, stv, ROT0, "Atlus", "Print Club Yoshimoto V2 (J 970422 V1.100)", MACHINE_NOT_WORKING ) - - -GAME( 1997, pclove, stvbios, stv_5838, stv, stv_state, decathlt, ROT0, "Atlus", "Print Club LoveLove (J 970421 V1.000)", MACHINE_NOT_WORKING ) // uses the same type of protection as decathlete!! -GAME( 1997, pclove2, stvbios, stv_5838, stv, stv_state, decathlt, ROT0, "Atlus", "Print Club LoveLove Ver 2 (J 970825 V1.000)", MACHINE_NOT_WORKING ) // ^ -GAME( 1997, pcpooh2, stvbios, stv_5838, stv, stv_state, decathlt, ROT0, "Atlus", "Print Club Winnie-the-Pooh Vol. 2 (J 971218 V1.000)", MACHINE_NOT_WORKING ) // ^ -GAME( 1998, pcpooh3, stvbios, stv_5838, stv, stv_state, decathlt, ROT0, "Atlus", "Print Club Winnie-the-Pooh Vol. 3 (J 980406 V1.000)", MACHINE_NOT_WORKING ) // ^ - -GAME( 1998, stress, stvbios, stv, stv, stv_state, stv, ROT0, "Sega", "Stress Busters (J 981020 V1.000)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) - -GAME( 1996, nameclub, stvbios, stv_5838, stv, stv_state, decathlt, ROT0, "Sega", "Name Club (J 960315 V1.000)", MACHINE_NOT_WORKING ) // uses the same type of protection as decathlete!! -GAME( 1996, nclubv2, stvbios, stv_5838, stv, stv_state, decathlt, ROT0, "Sega", "Name Club Ver.2 (J 960315 V1.000)", MACHINE_NOT_WORKING ) // ^ (has the same datecode as nameclub, probably incorrect unless both were released today) -GAME( 1997, nclubv3, stvbios, stv, stv, stv_state, nameclv3, ROT0, "Sega", "Name Club Ver.3 (J 970723 V1.000)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) // no protection +GAME( 1999, pclub2fc, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Felix The Cat (Rev. A) (J 970415 V1.100)", MACHINE_NOT_WORKING ) +GAME( 1998, pclub2pf, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Puffy (Japan)", MACHINE_NOT_WORKING ) // version info is blank +GAME( 1997, pclub2pe, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Pepsiman (J 970618 V1.100)", MACHINE_NOT_WORKING ) +GAME( 1997, pclub2wb, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Warner Bros (J 970228 V1.000)", MACHINE_NOT_WORKING ) + +GAME( 1997, pclb2elk, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Earth Limited Kobe (Print Club Custom) (J 970808 V1.000)", MACHINE_NOT_WORKING ) +GAME( 1997, pckobe99, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Kobe Luminaire '99 (Print Club Custom 3) (J 991203 V1.000)", MACHINE_NOT_WORKING ) + +GAME( 1997, pclub26w, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 6 Winter (J 961210 V1.000)", MACHINE_NOT_WORKING ) // internal string is 'PURIKURA2 97FUYU' (but in reality it seems to be an end of 96 Winter version) +GAME( 1997, pclub26wa, pclub26w,stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 6 Winter (J 970121 V1.200)", MACHINE_NOT_WORKING ) // ^ +GAME( 1997, pclub27s, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 7 Spring (J 970313 V1.100)", MACHINE_NOT_WORKING ) +GAME( 1997, prc28su, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 8 Summer (J 970616 V1.100)", MACHINE_NOT_WORKING ) // internal string 97SUMMER +GAME( 1997, prc29au, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 Vol. 9 Autumn (J V1.100)", MACHINE_NOT_WORKING ) // internal string 97AUTUMN, no date code! (all 0) +GAME( 1997, prc297wi, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 '97 Winter Ver (J 971017 V1.100, set 1)", MACHINE_NOT_WORKING ) // internal string is '97WINTER' +GAME( 1997, prc297wia, prc297wi,stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 '97 Winter Ver (J 971017 V1.100, set 2)", MACHINE_NOT_WORKING ) // different program revision, same date code, clearly didn't get updated properly +GAME( 1998, prc298sp, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 '98 Spring Ver (J 971017 V1.100)", MACHINE_NOT_WORKING ) // again, date doesn't appear to have bene updated, this should be early 98 +GAME( 1998, prc298su, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 '98 Summer Ver (J 980603 V1.100)", MACHINE_NOT_WORKING ) // +GAME( 1998, prc298au, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 '98 Autumn Ver (J 980827 V1.000)", MACHINE_NOT_WORKING ) +GAME( 2000, prc2ksu, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club 2 2000 Summer (J 000509 V1.000)", MACHINE_NOT_WORKING ) // internal string 2000_SUMMER + + +GAME( 1999, pclubor, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club Goukakenran (J 991104 V1.000)", MACHINE_NOT_WORKING ) +GAME( 1999, pclubol, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club Olive (J 980717 V1.000)", MACHINE_NOT_WORKING ) +GAME( 1997, pclub2kc, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club Kome Kome Club (J 970203 V1.000)", MACHINE_NOT_WORKING ) +GAME( 1997, pclubyo2, stvbios, stv, stv, stvpc_state, stv, ROT0, "Atlus", "Print Club Yoshimoto V2 (J 970422 V1.100)", MACHINE_NOT_WORKING ) + + +GAME( 1997, pclove, stvbios, stv_5838, stv, stvpc_state, decathlt, ROT0, "Atlus", "Print Club LoveLove (J 970421 V1.000)", MACHINE_NOT_WORKING ) // uses the same type of protection as decathlete!! +GAME( 1997, pclove2, stvbios, stv_5838, stv, stvpc_state, decathlt, ROT0, "Atlus", "Print Club LoveLove Ver 2 (J 970825 V1.000)", MACHINE_NOT_WORKING ) // ^ +GAME( 1997, pcpooh2, stvbios, stv_5838, stv, stvpc_state, decathlt, ROT0, "Atlus", "Print Club Winnie-the-Pooh Vol. 2 (J 971218 V1.000)", MACHINE_NOT_WORKING ) // ^ +GAME( 1998, pcpooh3, stvbios, stv_5838, stv, stvpc_state, decathlt, ROT0, "Atlus", "Print Club Winnie-the-Pooh Vol. 3 (J 980406 V1.000)", MACHINE_NOT_WORKING ) // ^ + +GAME( 1998, stress, stvbios, stv, stv, stvpc_state, stv, ROT0, "Sega", "Stress Busters (J 981020 V1.000)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND ) + +GAME( 1996, nameclub, stvbios, stv_5838, stv, stvpc_state, decathlt, ROT0, "Sega", "Name Club (J 960315 V1.000)", MACHINE_NOT_WORKING ) // uses the same type of protection as decathlete!! +GAME( 1996, nclubv2, stvbios, stv_5838, stv, stvpc_state, decathlt, ROT0, "Sega", "Name Club Ver.2 (J 960315 V1.000)", MACHINE_NOT_WORKING ) // ^ (has the same datecode as nameclub, probably incorrect unless both were released today) +GAME( 1997, nclubv3, stvbios, stv, stv, stvpc_state, nameclv3, ROT0, "Sega", "Name Club Ver.3 (J 970723 V1.000)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) // no protection diff --git a/src/mame/drivers/sun1.cpp b/src/mame/drivers/sun1.cpp index 2deaf1d28d4..5ba37f222b6 100644 --- a/src/mame/drivers/sun1.cpp +++ b/src/mame/drivers/sun1.cpp @@ -110,11 +110,6 @@ void sun1_state::machine_reset() } -static DEVICE_INPUT_DEFAULTS_START( terminal ) - DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9615 ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9615 ) -DEVICE_INPUT_DEFAULTS_END - static MACHINE_CONFIG_START( sun1 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M68000, XTAL_16MHz / 2) @@ -143,7 +138,6 @@ static MACHINE_CONFIG_START( sun1 ) MCFG_RS232_RXD_HANDLER(DEVWRITELINE("iouart", upd7201_new_device, rxa_w)) MCFG_RS232_CTS_HANDLER(DEVWRITELINE("iouart", upd7201_new_device, ctsa_w)) MCFG_RS232_DCD_HANDLER(DEVWRITELINE("iouart", upd7201_new_device, dcda_w)) - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) MCFG_RS232_PORT_ADD("rs232b", default_rs232_devices, nullptr) MCFG_RS232_RXD_HANDLER(DEVWRITELINE("iouart", upd7201_new_device, rxb_w)) diff --git a/src/mame/drivers/sun2.cpp b/src/mame/drivers/sun2.cpp index 6579402b176..740804d1665 100644 --- a/src/mame/drivers/sun2.cpp +++ b/src/mame/drivers/sun2.cpp @@ -601,28 +601,28 @@ static MACHINE_CONFIG_START( sun2vme ) MCFG_DEVICE_ADD("type0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype0space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000) // MMU Type 1 device space MCFG_DEVICE_ADD("type1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype1space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000) // MMU Type 2 device space MCFG_DEVICE_ADD("type2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype2space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000) // MMU Type 3 device space MCFG_DEVICE_ADD("type3", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype3space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000) MCFG_SCREEN_ADD("bwtwo", RASTER) @@ -673,28 +673,28 @@ static MACHINE_CONFIG_START( sun2mbus ) MCFG_DEVICE_ADD("type0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(mbustype0space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000) // MMU Type 1 device space MCFG_DEVICE_ADD("type1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(mbustype1space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000) // MMU Type 2 device space MCFG_DEVICE_ADD("type2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(mbustype2space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000) // MMU Type 3 device space MCFG_DEVICE_ADD("type3", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(mbustype3space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000) MCFG_SCREEN_ADD("bwtwo", RASTER) diff --git a/src/mame/drivers/sun3.cpp b/src/mame/drivers/sun3.cpp index f19e4bf33e4..ec0835abfa9 100644 --- a/src/mame/drivers/sun3.cpp +++ b/src/mame/drivers/sun3.cpp @@ -973,28 +973,28 @@ static MACHINE_CONFIG_START( sun3 ) MCFG_DEVICE_ADD("type0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype0space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // MMU Type 1 device space MCFG_DEVICE_ADD("type1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype1space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // MMU Type 2 device space MCFG_DEVICE_ADD("type2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype2space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // MMU Type 3 device space MCFG_DEVICE_ADD("type3", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype3space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) MCFG_TIMER_DRIVER_ADD_PERIODIC("timer", sun3_state, sun3_timer, attotime::from_hz(100)) @@ -1077,28 +1077,28 @@ static MACHINE_CONFIG_START( sun3_50 ) MCFG_DEVICE_ADD("type0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype0space_novram_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // MMU Type 1 device space MCFG_DEVICE_ADD("type1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype1space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // MMU Type 2 device space MCFG_DEVICE_ADD("type2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype2space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // MMU Type 3 device space MCFG_DEVICE_ADD("type3", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vmetype3space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) MCFG_SCC8530_ADD(SCC1_TAG, XTAL_4_9152MHz, 0, 0, 0, 0) diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp index 925905db48a..6470413eafe 100644 --- a/src/mame/drivers/sun4.cpp +++ b/src/mame/drivers/sun4.cpp @@ -1909,14 +1909,14 @@ static MACHINE_CONFIG_START( sun4 ) MCFG_DEVICE_ADD("type0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(type0space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // MMU Type 1 device space MCFG_DEVICE_ADD("type1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(type1space_s4_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // Keyboard/mouse @@ -1974,14 +1974,14 @@ static MACHINE_CONFIG_START( sun4c ) MCFG_DEVICE_ADD("type0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(type0space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // MMU Type 1 device space MCFG_DEVICE_ADD("type1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(type1space_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(32) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(32) MCFG_ADDRESS_MAP_BANK_STRIDE(0x80000000) // Keyboard/mouse diff --git a/src/mame/drivers/super6.cpp b/src/mame/drivers/super6.cpp index 17f069478d3..af0c70056b0 100644 --- a/src/mame/drivers/super6.cpp +++ b/src/mame/drivers/super6.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "bus/rs232/rs232.h" +//#include "bus/s100/s100.h" #include "includes/super6.h" #include "softlist.h" diff --git a/src/mame/drivers/superslave.cpp b/src/mame/drivers/superslave.cpp index 0afcdd76c42..6c45a221ede 100644 --- a/src/mame/drivers/superslave.cpp +++ b/src/mame/drivers/superslave.cpp @@ -22,6 +22,7 @@ Oxx,yy = Out port #include "emu.h" #include "bus/rs232/rs232.h" +//#include "bus/s100/s100.h" #include "cpu/z80/z80.h" #include "cpu/z80/z80daisy.h" #include "machine/com8116.h" diff --git a/src/mame/drivers/surpratk.cpp b/src/mame/drivers/surpratk.cpp index d9bbb1f316a..17a94814974 100644 --- a/src/mame/drivers/surpratk.cpp +++ b/src/mame/drivers/surpratk.cpp @@ -177,8 +177,8 @@ static MACHINE_CONFIG_START( surpratk ) MCFG_DEVICE_ADD("bank0000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank0000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x800) MCFG_WATCHDOG_ADD("watchdog") diff --git a/src/mame/drivers/svi318.cpp b/src/mame/drivers/svi318.cpp index bb8aec7062d..58890dc1278 100644 --- a/src/mame/drivers/svi318.cpp +++ b/src/mame/drivers/svi318.cpp @@ -529,8 +529,8 @@ static MACHINE_CONFIG_START( svi318 ) MCFG_DEVICE_ADD("io", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(svi3x8_io_bank) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(9) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(9) MCFG_ADDRESS_MAP_BANK_STRIDE(0x100) MCFG_DEVICE_ADD("ppi", I8255, 0) diff --git a/src/mame/drivers/swtpc.cpp b/src/mame/drivers/swtpc.cpp index aa73c8fadca..cd7acfc2461 100644 --- a/src/mame/drivers/swtpc.cpp +++ b/src/mame/drivers/swtpc.cpp @@ -2,26 +2,24 @@ // copyright-holders:Robbbert /*************************************************************************** - SWTPC 6800 + SWTPC 6800 Computer System 10/12/2009 Skeleton driver. http://www.swtpc.com/mholley/swtpc_6800.htm - bios 0 (SWTBUG) is made for a PIA (parallel) interface. - bios 1 (MIKBUG) is made for a ACIA (serial) interface at the same address. + MIKBUG is made for a PIA (parallel) interface. + SWTBUG is made for a ACIA (serial) interface at the same address. MIKBUG will actually read the bits as they arrive and assemble a byte. - - Since the interface is optional, it is not on the schematics, so I've - looked at the code and come up with something horrible that works. + Its delay loops are based on an underclocked XTAL. Note: All commands must be in uppercase. See the SWTBUG manual. ToDo: - - Add PIA and work out the best way to hook up the keyboard. As can be - seen from the code below, it might be tricky. + - Add more SS-50 interface slot options + - Emulate MP-A2 revision of CPU board, with four 2716 ROM sockets + and allowance for extra RAM boards at A000-BFFF and C000-DFFF - - Finish conversion to modern. Commands: B Breakpoint @@ -42,59 +40,42 @@ Z Goto Prom (0xC000) #include "emu.h" #include "cpu/m6800/m6800.h" -#include "machine/terminal.h" - -#define TERMINAL_TAG "terminal" +#include "machine/input_merger.h" +#include "machine/mc14411.h" +#include "machine/ram.h" +#include "bus/ss50/interface.h" +#include "bus/ss50/mps.h" class swtpc_state : public driver_device { public: swtpc_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG) - { - } - - DECLARE_READ8_MEMBER(swtpc_status_r); - DECLARE_READ8_MEMBER(swtpc_terminal_r); - DECLARE_READ8_MEMBER(swtpc_tricky_r); - void kbd_put(u8 data); + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_ram(*this, "ram") + , m_brg(*this, "brg") + { } -protected: - virtual void machine_reset() override; + virtual void machine_start() override; +private: required_device<cpu_device> m_maincpu; - required_device<generic_terminal_device> m_terminal; - uint8_t m_term_data; + required_device<ram_device> m_ram; + required_device<mc14411_device> m_brg; }; -// bit 0 - ready to receive a character; bit 1 - ready to send a character to the terminal -READ8_MEMBER( swtpc_state::swtpc_status_r ) -{ - return (m_term_data) ? 3 : 0x82; -} - -READ8_MEMBER( swtpc_state::swtpc_terminal_r ) -{ - uint8_t ret = m_term_data; - m_term_data = 0; - return ret; -} - -READ8_MEMBER( swtpc_state::swtpc_tricky_r ) -{ - uint8_t ret = m_term_data; - return ret; -} - -static ADDRESS_MAP_START(swtpc_mem, AS_PROGRAM, 8, swtpc_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, swtpc_state) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE( 0x8004, 0x8004 ) AM_READ(swtpc_status_r) - AM_RANGE( 0x8005, 0x8005 ) AM_READ(swtpc_terminal_r) AM_DEVWRITE(TERMINAL_TAG, generic_terminal_device, write) - AM_RANGE( 0x8007, 0x8007 ) AM_READ(swtpc_tricky_r) - AM_RANGE( 0xa000, 0xa07f ) AM_RAM - AM_RANGE( 0xe000, 0xe3ff ) AM_MIRROR(0x1c00) AM_ROM + AM_RANGE(0x8000, 0x8003) AM_MIRROR(0x1fc0) AM_DEVREADWRITE("io0", ss50_interface_port_device, read, write) + AM_RANGE(0x8004, 0x8007) AM_MIRROR(0x1fc0) AM_DEVREADWRITE("io1", ss50_interface_port_device, read, write) + AM_RANGE(0x8008, 0x800b) AM_MIRROR(0x1fc0) AM_DEVREADWRITE("io2", ss50_interface_port_device, read, write) + AM_RANGE(0x800c, 0x800f) AM_MIRROR(0x1fc0) AM_DEVREADWRITE("io3", ss50_interface_port_device, read, write) + AM_RANGE(0x8010, 0x8013) AM_MIRROR(0x1fc0) AM_DEVREADWRITE("io4", ss50_interface_port_device, read, write) + AM_RANGE(0x8014, 0x8017) AM_MIRROR(0x1fc0) AM_DEVREADWRITE("io5", ss50_interface_port_device, read, write) + AM_RANGE(0x8018, 0x801b) AM_MIRROR(0x1fc0) AM_DEVREADWRITE("io6", ss50_interface_port_device, read, write) + AM_RANGE(0x801c, 0x801f) AM_MIRROR(0x1fc0) AM_DEVREADWRITE("io7", ss50_interface_port_device, read, write) + AM_RANGE(0xa000, 0xa07f) AM_RAM // MCM6810 + AM_RANGE(0xe000, 0xe3ff) AM_MIRROR(0x1c00) AM_ROM AM_REGION("mcm6830", 0) ADDRESS_MAP_END /* Input ports */ @@ -102,36 +83,120 @@ static INPUT_PORTS_START( swtpc ) INPUT_PORTS_END -void swtpc_state::machine_reset() +void swtpc_state::machine_start() { -} + m_brg->rsa_w(0); + m_brg->rsb_w(1); -void swtpc_state::kbd_put(u8 data) -{ - m_term_data = data; + m_maincpu->space(AS_PROGRAM).install_ram(0, m_ram->size() - 1, m_ram->pointer()); } static MACHINE_CONFIG_START( swtpc ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", M6800, XTAL_1MHz) - MCFG_CPU_PROGRAM_MAP(swtpc_mem) + MCFG_CPU_ADD("maincpu", M6800, XTAL_1_8432MHz / 2) + MCFG_CPU_PROGRAM_MAP(mem_map) + + MCFG_DEVICE_ADD("brg", MC14411, XTAL_1_8432MHz) + MCFG_MC14411_F7_CB(DEVWRITELINE("io0", ss50_interface_port_device, f600_1200_w)) // 1200b + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io1", ss50_interface_port_device, f600_1200_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io2", ss50_interface_port_device, f600_1200_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io3", ss50_interface_port_device, f600_1200_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io4", ss50_interface_port_device, f600_1200_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io5", ss50_interface_port_device, f600_1200_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io6", ss50_interface_port_device, f600_1200_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io7", ss50_interface_port_device, f600_1200_w)) + MCFG_MC14411_F8_CB(DEVWRITELINE("io0", ss50_interface_port_device, f600_4800_w)) // 600b + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io1", ss50_interface_port_device, f600_4800_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io2", ss50_interface_port_device, f600_4800_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io3", ss50_interface_port_device, f600_4800_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io4", ss50_interface_port_device, f600_4800_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io5", ss50_interface_port_device, f600_4800_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io6", ss50_interface_port_device, f600_4800_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io7", ss50_interface_port_device, f600_4800_w)) + MCFG_MC14411_F9_CB(DEVWRITELINE("io0", ss50_interface_port_device, f300_w)) // 300b + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io1", ss50_interface_port_device, f300_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io2", ss50_interface_port_device, f300_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io3", ss50_interface_port_device, f300_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io4", ss50_interface_port_device, f300_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io5", ss50_interface_port_device, f300_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io6", ss50_interface_port_device, f300_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io7", ss50_interface_port_device, f300_w)) + MCFG_MC14411_F11_CB(DEVWRITELINE("io0", ss50_interface_port_device, f150_9600_w)) // 150b + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io1", ss50_interface_port_device, f150_9600_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io2", ss50_interface_port_device, f150_9600_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io3", ss50_interface_port_device, f150_9600_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io4", ss50_interface_port_device, f150_9600_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io5", ss50_interface_port_device, f150_9600_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io6", ss50_interface_port_device, f150_9600_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io7", ss50_interface_port_device, f150_9600_w)) + MCFG_MC14411_F13_CB(DEVWRITELINE("io0", ss50_interface_port_device, f110_w)) // 110b + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io1", ss50_interface_port_device, f110_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io2", ss50_interface_port_device, f110_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io3", ss50_interface_port_device, f110_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io4", ss50_interface_port_device, f110_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io5", ss50_interface_port_device, f110_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io6", ss50_interface_port_device, f110_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("io7", ss50_interface_port_device, f110_w)) + + MCFG_SS50_INTERFACE_PORT_ADD("io0", default_2rs_devices, nullptr) + MCFG_SS50_INTERFACE_IRQ_CALLBACK(DEVWRITELINE("mainirq", input_merger_device, in_w<0>)) + MCFG_SS50_INTERFACE_FIRQ_CALLBACK(DEVWRITELINE("mainnmi", input_merger_device, in_w<0>)) + MCFG_SS50_INTERFACE_PORT_ADD("io1", default_2rs_devices, "mps") + MCFG_SS50_INTERFACE_IRQ_CALLBACK(DEVWRITELINE("mainirq", input_merger_device, in_w<1>)) + MCFG_SS50_INTERFACE_FIRQ_CALLBACK(DEVWRITELINE("mainnmi", input_merger_device, in_w<1>)) + MCFG_SS50_INTERFACE_PORT_ADD("io2", default_2rs_devices, nullptr) + MCFG_SS50_INTERFACE_IRQ_CALLBACK(DEVWRITELINE("mainirq", input_merger_device, in_w<2>)) + MCFG_SS50_INTERFACE_FIRQ_CALLBACK(DEVWRITELINE("mainnmi", input_merger_device, in_w<2>)) + MCFG_SS50_INTERFACE_PORT_ADD("io3", default_2rs_devices, nullptr) + MCFG_SS50_INTERFACE_IRQ_CALLBACK(DEVWRITELINE("mainirq", input_merger_device, in_w<3>)) + MCFG_SS50_INTERFACE_FIRQ_CALLBACK(DEVWRITELINE("mainnmi", input_merger_device, in_w<3>)) + MCFG_SS50_INTERFACE_PORT_ADD("io4", default_2rs_devices, nullptr) + MCFG_SS50_INTERFACE_IRQ_CALLBACK(DEVWRITELINE("mainirq", input_merger_device, in_w<4>)) + MCFG_SS50_INTERFACE_FIRQ_CALLBACK(DEVWRITELINE("mainnmi", input_merger_device, in_w<4>)) + MCFG_SS50_INTERFACE_PORT_ADD("io5", default_2rs_devices, nullptr) + MCFG_SS50_INTERFACE_IRQ_CALLBACK(DEVWRITELINE("mainirq", input_merger_device, in_w<5>)) + MCFG_SS50_INTERFACE_FIRQ_CALLBACK(DEVWRITELINE("mainnmi", input_merger_device, in_w<5>)) + MCFG_SS50_INTERFACE_PORT_ADD("io6", default_2rs_devices, nullptr) + MCFG_SS50_INTERFACE_IRQ_CALLBACK(DEVWRITELINE("mainirq", input_merger_device, in_w<6>)) + MCFG_SS50_INTERFACE_FIRQ_CALLBACK(DEVWRITELINE("mainnmi", input_merger_device, in_w<6>)) + MCFG_SS50_INTERFACE_PORT_ADD("io7", default_2rs_devices, nullptr) + MCFG_SS50_INTERFACE_IRQ_CALLBACK(DEVWRITELINE("mainirq", input_merger_device, in_w<7>)) + MCFG_SS50_INTERFACE_FIRQ_CALLBACK(DEVWRITELINE("mainnmi", input_merger_device, in_w<7>)) + + MCFG_INPUT_MERGER_ANY_HIGH("mainirq") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", M6800_IRQ_LINE)) + MCFG_INPUT_MERGER_ANY_HIGH("mainnmi") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", INPUT_LINE_NMI)) + + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("2K") + MCFG_RAM_EXTRA_OPTIONS("4K,8K,12K,16K,20K,24K,28K,32K") +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( swtpcm, swtpc ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_CLOCK(XTAL_1_7971MHz / 2) + MCFG_DEVICE_MODIFY("brg") + MCFG_DEVICE_CLOCK(XTAL_1_7971MHz) - /* video hardware */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) - MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(swtpc_state, kbd_put)) + MCFG_DEVICE_MODIFY("io1") + MCFG_SLOT_DEFAULT_OPTION("mpc") MACHINE_CONFIG_END /* ROM definition */ ROM_START( swtpc ) - ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) - ROM_SYSTEM_BIOS( 0, "swt", "SWTBUG" ) - ROMX_LOAD( "swtbug.bin", 0xe000, 0x0400, CRC(f9130ef4) SHA1(089b2d2a56ce9526c3e78ce5d49ce368b9eabc0c), ROM_BIOS(1)) - ROM_SYSTEM_BIOS( 1, "mik", "MIKBUG" ) - ROMX_LOAD( "mikbug.bin", 0xe000, 0x0400, CRC(e7f4d9d0) SHA1(5ad585218f9c9c70f38b3c74e3ed5dfe0357621c), ROM_BIOS(2)) + ROM_REGION( 0x0400, "mcm6830", 0 ) + ROM_LOAD("swtbug.bin", 0x0000, 0x0400, CRC(f9130ef4) SHA1(089b2d2a56ce9526c3e78ce5d49ce368b9eabc0c)) +ROM_END + +ROM_START( swtpcm ) + ROM_REGION( 0x0400, "mcm6830", 0 ) + ROM_LOAD("mikbug.bin", 0x0000, 0x0400, CRC(e7f4d9d0) SHA1(5ad585218f9c9c70f38b3c74e3ed5dfe0357621c)) ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -COMP( 1975, swtpc, 0, 0, swtpc, swtpc, swtpc_state, 0, "Southwest Technical Products Corporation", "SWTPC 6800", MACHINE_NO_SOUND) +COMP( 1977, swtpc, 0, 0, swtpc, swtpc, swtpc_state, 0, "Southwest Technical Products Corporation", "SWTPC 6800 Computer System (with SWTBUG)", MACHINE_NO_SOUND_HW ) +COMP( 1975, swtpcm, swtpc, 0, swtpcm, swtpc, swtpc_state, 0, "Southwest Technical Products Corporation", "SWTPC 6800 Computer System (with MIKBUG)", MACHINE_NO_SOUND_HW ) diff --git a/src/mame/drivers/swtpc09.cpp b/src/mame/drivers/swtpc09.cpp index 07c50da26b7..2ef045486fa 100644 --- a/src/mame/drivers/swtpc09.cpp +++ b/src/mame/drivers/swtpc09.cpp @@ -60,9 +60,76 @@ /* Address map is dynamically setup when DAT memory is written to */ /* only ROM from FF00-FFFF and DAT memory at FFF0-FFFF (write only) is guaranteed always*/ -static ADDRESS_MAP_START(swtpc09_mem, AS_PROGRAM, 8, swtpc09_state) - AM_RANGE(0xff00, 0xffef) AM_ROM - AM_RANGE(0xfff0, 0xffff) AM_ROM AM_WRITE(dat_w) +static ADDRESS_MAP_START(mp09_mem, AS_PROGRAM, 8, swtpc09_state) + AM_RANGE(0x0000, 0xffef) AM_READWRITE(main_r, main_w) + AM_RANGE(0xff00, 0xffff) AM_ROM AM_REGION("maincpu", 0xff00) + AM_RANGE(0xff00, 0xff0f) AM_MIRROR(0xf0) AM_WRITEONLY AM_SHARE("dat") +ADDRESS_MAP_END + +static ADDRESS_MAP_START(flex_dmf2_mem, AS_PROGRAM, 8, swtpc09_state) + AM_RANGE(0xe000, 0xe003) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xe004, 0xe005) AM_MIRROR(0xf0000) AM_DEVREADWRITE("acia", acia6850_device, read, write) + AM_RANGE(0xe080, 0xe083) AM_MIRROR(0xf000c) AM_DEVREADWRITE("pia", pia6821_device, read, write) + AM_RANGE(0xe090, 0xe097) AM_MIRROR(0xf0008) AM_DEVREADWRITE("ptm", ptm6840_device, read, write) + AM_RANGE(0xe0a0, 0xefff) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xf000, 0xf01f) AM_MIRROR(0xf0000) AM_READWRITE(m6844_r, m6844_w) + AM_RANGE(0xf020, 0xf023) AM_MIRROR(0xf0000) AM_DEVREADWRITE("fdc", fd1793_device, read, write) + AM_RANGE(0xf024, 0xf03f) AM_MIRROR(0xf0000) AM_READWRITE(dmf2_control_reg_r, dmf2_control_reg_w) + //AM_RANGE(0xf042, 0xf7ff) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xf800, 0xffff) AM_MIRROR(0xf0000) AM_ROM AM_REGION("maincpu", 0xf800) + AM_RANGE(0x00000, 0xfffff) AM_RAM AM_SHARE("mainram") // all the rest is treated as ram, 1MB ram emulated +ADDRESS_MAP_END + +static ADDRESS_MAP_START(flex_dc4_piaide_mem, AS_PROGRAM, 8, swtpc09_state) + AM_RANGE(0xe000, 0xe003) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xe004, 0xe005) AM_MIRROR(0xf0000) AM_DEVREADWRITE("acia", acia6850_device, read, write) + AM_RANGE(0xe014, 0xe014) AM_MIRROR(0xf0000) AM_WRITE(dc4_control_reg_w) + AM_RANGE(0xe018, 0xe01b) AM_MIRROR(0xf0000) AM_DEVREADWRITE("fdc", fd1793_device, read, write) + //AM_RANGE(0xe01c, 0xe05f) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xe060, 0xe063) AM_MIRROR(0xf000c) AM_DEVREADWRITE("piaide", pia6821_device, read, write) + //AM_RANGE(0xe070, 0xe07f) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xe080, 0xe083) AM_MIRROR(0xf000c) AM_DEVREADWRITE("pia", pia6821_device, read, write) + AM_RANGE(0xe090, 0xe097) AM_MIRROR(0xf0008) AM_DEVREADWRITE("ptm", ptm6840_device, read, write) + //AM_RANGE(0xe0a0, 0xe7ff) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xe800, 0xefff) AM_MIRROR(0xf0000) AM_ROM AM_REGION("maincpu", 0xe800) //piaide rom + //AM_RANGE(0xf000, 0xf01f) AM_MIRROR(0xf0000) AM_READWRITE(m6844_r, m6844_w) + //AM_RANGE(0xf020, 0xf023) AM_MIRROR(0xf0000) AM_DEVREADWRITE("fdc", fd1793_device, read, write) + //AM_RANGE(0xf024, 0xf03f) AM_MIRROR(0xf0000) AM_READWRITE(dmf2_control_reg_r, dmf2_control_reg_w) + //AM_RANGE(0xf040, 0xf041) AM_MIRROR(0xf0000) AM_READWRITE(dmf2_dma_address_reg_r, dmf2_dma_address_reg_w) + AM_RANGE(0xf000, 0xf7ff) AM_MIRROR(0xf0000) AM_RAM AM_SHARE("s09ram") // 2k ram for piaide on s09 board + AM_RANGE(0xf800, 0xffff) AM_MIRROR(0xf0000) AM_ROM AM_REGION("maincpu", 0xf800) + AM_RANGE(0x00000, 0xfffff) AM_RAM AM_SHARE("mainram") // all the rest is treated as ram, 1MB ram emulated +ADDRESS_MAP_END + +static ADDRESS_MAP_START(uniflex_dmf2_mem, AS_PROGRAM, 8, swtpc09_state) + AM_RANGE(0xe000, 0xe001) AM_MIRROR(0xf0000) AM_DEVREADWRITE("acia", acia6850_device, read, write) + AM_RANGE(0xe002, 0xe07f) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xe080, 0xe083) AM_MIRROR(0xf000c) AM_DEVREADWRITE("pia", pia6821_device, read, write) + AM_RANGE(0xe090, 0xe097) AM_MIRROR(0xf0008) AM_DEVREADWRITE("ptm", ptm6840_device, read, write) + AM_RANGE(0xe0a0, 0xefff) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xf000, 0xf01f) AM_MIRROR(0xf0000) AM_READWRITE(m6844_r, m6844_w) + AM_RANGE(0xf020, 0xf023) AM_MIRROR(0xf0000) AM_DEVREADWRITE("fdc", fd1793_device, read, write) + AM_RANGE(0xf024, 0xf03f) AM_MIRROR(0xf0000) AM_READWRITE(dmf2_control_reg_r, dmf2_control_reg_w) + //AM_RANGE(0xf042, 0xf7ff) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xf800, 0xffff) AM_MIRROR(0xf0000) AM_ROM AM_REGION("maincpu", 0xf800) + AM_RANGE(0x00000, 0xfffff) AM_RAM AM_SHARE("mainram") // all the rest is treated as ram, 1MB ram emulated +ADDRESS_MAP_END + +static ADDRESS_MAP_START(uniflex_dmf3_mem, AS_PROGRAM, 8, swtpc09_state) + AM_RANGE(0xe000, 0xe001) AM_MIRROR(0xf0000) AM_DEVREADWRITE("acia", acia6850_device, read, write) + AM_RANGE(0xe002, 0xe07f) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xe080, 0xe083) AM_MIRROR(0xf000c) AM_DEVREADWRITE("pia", pia6821_device, read, write) + AM_RANGE(0xe090, 0xe097) AM_MIRROR(0xf0008) AM_DEVREADWRITE("ptm", ptm6840_device, read, write) + AM_RANGE(0xe0a0, 0xefff) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xf000, 0xf01f) AM_MIRROR(0xf0000) AM_READWRITE(m6844_r, m6844_w) + AM_RANGE(0xf020, 0xf023) AM_MIRROR(0xf0000) AM_DEVREADWRITE("fdc", fd1793_device, read, write) + AM_RANGE(0xf024, 0xf024) AM_MIRROR(0xf0000) AM_READWRITE(dmf3_control_reg_r, dmf3_control_reg_w) + AM_RANGE(0xf025, 0xf025) AM_MIRROR(0xf0000) AM_READWRITE(dmf3_dma_address_reg_r, dmf3_dma_address_reg_w) + //AM_RANGE(0xf030, 0xf03f) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xf040, 0xf04f) AM_MIRROR(0xf0000) AM_DEVREADWRITE("via", via6522_device, read, write) + //AM_RANGE(0xf050, 0xf7ff) AM_MIRROR(0xf0000) AM_NOP + AM_RANGE(0xf800, 0xffff) AM_MIRROR(0xf0000) AM_ROM AM_REGION("maincpu", 0xf800) + AM_RANGE(0x00000, 0xfffff) AM_RAM AM_SHARE("mainram") // all the rest is treated as ram, 1MB ram emulated ADDRESS_MAP_END @@ -92,83 +159,58 @@ SLOT_INTERFACE_END /* Machine driver */ /* MPU09, MPID, MPS2 DMF2 */ -static MACHINE_CONFIG_START( swtpc09 ) +static MACHINE_CONFIG_START( swtpc09_base ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M6809, 1000000) - MCFG_CPU_PROGRAM_MAP(swtpc09_mem) + MCFG_CPU_PROGRAM_MAP(mp09_mem) - /* video hardware */ - MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts)) - - MCFG_DEVICE_ADD("ptm", PTM6840, 2000000) - MCFG_PTM6840_EXTERNAL_CLOCKS(50, 0, 50) - MCFG_PTM6840_OUT0_CB(WRITELINE(swtpc09_state, ptm_o1_callback)) - MCFG_PTM6840_OUT2_CB(WRITELINE(swtpc09_state, ptm_o3_callback)) - MCFG_PTM6840_IRQ_CB(WRITELINE(swtpc09_state, ptm_irq)) + MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) + MCFG_DEVICE_PROGRAM_MAP(flex_dmf2_mem) MCFG_DEVICE_ADD("pia", PIA6821, 0) MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_a_r)) MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_ca1_r)) MCFG_PIA_IRQA_HANDLER(WRITELINE(swtpc09_state, pia0_irq_a)) - MCFG_DEVICE_ADD("acia", ACIA6850, 0) - MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) - MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) - MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(swtpc09_state, acia_interrupt)) - - MCFG_DEVICE_ADD("acia_clock", CLOCK, 153600) - MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("acia", acia6850_device, write_txc)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("acia", acia6850_device, write_rxc)) - - MCFG_FD1793_ADD("fdc", XTAL_1MHz) - MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(swtpc09_state, fdc_intrq_w)) - MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(swtpc09_state, fdc_drq_w)) - - MCFG_FLOPPY_DRIVE_ADD("fdc:0", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) - MCFG_FLOPPY_DRIVE_ADD("fdc:1", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) - MCFG_FLOPPY_DRIVE_ADD("fdc:2", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) - MCFG_FLOPPY_DRIVE_ADD("fdc:3", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) -MACHINE_CONFIG_END - -/* MPU09, MPID, MPS2 DC4 PIAIDE*/ -static MACHINE_CONFIG_START( swtpc09i ) - /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", M6809, 1000000) - MCFG_CPU_PROGRAM_MAP(swtpc09_mem) - - /* video hardware */ - MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts)) - MCFG_DEVICE_ADD("ptm", PTM6840, 2000000) MCFG_PTM6840_EXTERNAL_CLOCKS(50, 0, 50) MCFG_PTM6840_OUT0_CB(WRITELINE(swtpc09_state, ptm_o1_callback)) MCFG_PTM6840_OUT2_CB(WRITELINE(swtpc09_state, ptm_o3_callback)) MCFG_PTM6840_IRQ_CB(WRITELINE(swtpc09_state, ptm_irq)) - MCFG_DEVICE_ADD("pia", PIA6821, 0) - MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_a_r)) - MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_ca1_r)) - MCFG_PIA_IRQA_HANDLER(WRITELINE(swtpc09_state, pia0_irq_a)) + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts)) MCFG_DEVICE_ADD("acia", ACIA6850, 0) MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(swtpc09_state, acia_interrupt)) - MCFG_DEVICE_ADD("acia_clock", CLOCK, 153600) - MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("acia", acia6850_device, write_txc)) + MCFG_DEVICE_ADD("brg", MC14411, XTAL_1_8432MHz) + MCFG_MC14411_F1_CB(DEVWRITELINE("acia", acia6850_device, write_txc)) MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("acia", acia6850_device, write_rxc)) MCFG_FD1793_ADD("fdc", XTAL_1MHz) - MCFG_FLOPPY_DRIVE_ADD("fdc:0", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) MCFG_FLOPPY_DRIVE_ADD("fdc:1", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) MCFG_FLOPPY_DRIVE_ADD("fdc:2", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) MCFG_FLOPPY_DRIVE_ADD("fdc:3", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( swtpc09, swtpc09_base ) + MCFG_DEVICE_MODIFY("fdc") + MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(swtpc09_state, fdc_intrq_w)) + MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(swtpc09_state, fdc_drq_w)) +MACHINE_CONFIG_END + +/* MPU09, MPID, MPS2 DC4 PIAIDE*/ +static MACHINE_CONFIG_DERIVED( swtpc09i, swtpc09_base ) + MCFG_DEVICE_MODIFY("bankdev") + MCFG_DEVICE_PROGRAM_MAP(flex_dc4_piaide_mem) MCFG_DEVICE_ADD("piaide", PIA6821, 0) @@ -181,44 +223,26 @@ static MACHINE_CONFIG_START( swtpc09i ) MACHINE_CONFIG_END -/* MPU09, MPID, MPS2 DMF3 */ -static MACHINE_CONFIG_START( swtpc09d3 ) - /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", M6809, 2000000) - MCFG_CPU_PROGRAM_MAP(swtpc09_mem) - - /* video hardware */ - MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts)) - - MCFG_DEVICE_ADD("ptm", PTM6840, 2000000) - MCFG_PTM6840_EXTERNAL_CLOCKS(50, 0, 50) - MCFG_PTM6840_OUT0_CB(WRITELINE(swtpc09_state, ptm_o1_callback)) - MCFG_PTM6840_OUT2_CB(WRITELINE(swtpc09_state, ptm_o3_callback)) - MCFG_PTM6840_IRQ_CB(WRITELINE(swtpc09_state, ptm_irq)) +static MACHINE_CONFIG_DERIVED( swtpc09u, swtpc09 ) + MCFG_DEVICE_MODIFY("bankdev") + MCFG_DEVICE_PROGRAM_MAP(uniflex_dmf2_mem) +MACHINE_CONFIG_END - MCFG_DEVICE_ADD("pia", PIA6821, 0) - MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_a_r)) - MCFG_PIA_READPA_HANDLER(READ8(swtpc09_state, pia0_ca1_r)) - MCFG_PIA_IRQA_HANDLER(WRITELINE(swtpc09_state, pia0_irq_a)) - MCFG_DEVICE_ADD("acia", ACIA6850, 0) - MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd)) - MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts)) - MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(swtpc09_state, acia_interrupt)) - MCFG_ACIA6850_IRQ_HANDLER(INPUTLINE("maincpu", M6809_IRQ_LINE)) +/* MPU09, MPID, MPS2 DMF3 */ +static MACHINE_CONFIG_DERIVED( swtpc09d3, swtpc09_base ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_CLOCK(2000000) - MCFG_DEVICE_ADD("acia_clock", CLOCK, 153600) - MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("acia", acia6850_device, write_txc)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("acia", acia6850_device, write_rxc)) + MCFG_DEVICE_MODIFY("pia") + MCFG_DEVICE_CLOCK(2000000) - MCFG_FD1793_ADD("fdc", XTAL_1MHz) + MCFG_DEVICE_MODIFY("bankdev") + MCFG_DEVICE_PROGRAM_MAP(uniflex_dmf3_mem) - MCFG_FLOPPY_DRIVE_ADD("fdc:0", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) - MCFG_FLOPPY_DRIVE_ADD("fdc:1", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) - MCFG_FLOPPY_DRIVE_ADD("fdc:2", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) - MCFG_FLOPPY_DRIVE_ADD("fdc:3", swtpc09_floppies, "dd", swtpc09_state::floppy_formats) + /* video hardware */ + MCFG_DEVICE_MODIFY("acia") + MCFG_ACIA6850_IRQ_HANDLER(INPUTLINE("maincpu", M6809_IRQ_LINE)) MCFG_DEVICE_ADD("via", VIA6522, XTAL_4MHz / 4) MCFG_VIA6522_READPA_HANDLER(READ8(swtpc09_state, dmf3_via_read_porta)) @@ -256,5 +280,5 @@ ROM_END // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS COMP( 1980, swtpc09, 0, 0, swtpc09, swtpc09, swtpc09_state, swtpc09, "SWTPC", "swtpc S/09 Sbug", MACHINE_NO_SOUND_HW ) COMP( 1980, swtpc09i, swtpc09, 0, swtpc09i, swtpc09, swtpc09_state, swtpc09i, "SWTPC", "swtpc S/09 Sbug + piaide", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW ) -COMP( 1980, swtpc09u, swtpc09, 0, swtpc09, swtpc09, swtpc09_state, swtpc09u, "SWTPC", "swtpc S/09 UNIBug + DMF2", MACHINE_NO_SOUND_HW ) +COMP( 1980, swtpc09u, swtpc09, 0, swtpc09u, swtpc09, swtpc09_state, swtpc09u, "SWTPC", "swtpc S/09 UNIBug + DMF2", MACHINE_NO_SOUND_HW ) COMP( 1980, swtpc09d3, swtpc09, 0, swtpc09d3, swtpc09, swtpc09_state, swtpc09d3, "SWTPC", "swtpc S/09 UNIBug + DMF3", MACHINE_NO_SOUND_HW ) diff --git a/src/mame/drivers/sys2900.cpp b/src/mame/drivers/sys2900.cpp index 1f26f87244a..2693762f1c8 100644 --- a/src/mame/drivers/sys2900.cpp +++ b/src/mame/drivers/sys2900.cpp @@ -1,42 +1,52 @@ // license:BSD-3-Clause // copyright-holders:Robbbert -/*************************************************************************** +/****************************************************************************************** - System 2900 +Systems Group (a division of Measurement Systems and Controls) System 2900 S100 computer - 12/05/2009 Skeleton driver. +2009-05-12 Skeleton driver. - The system contains 4 S100 boards, 2 8" floppies, enormous power supply, - 1/4" thick mother board, 4 RS232 I/F boards, and an Australian made - "Computer Patch Board". - The S100 boards that make up the unit are: +Photos: https://www.vintagecomputer.net/Systems-Group/2900/ + +The system contains 4 S100 boards, 2 8" floppies, enormous power supply, +1/4" thick mother board, 4 RS232 I/F boards, and an Australian made +"Computer Patch Board". + +The S100 boards that make up the unit are: CPU board - Model CPC2810 Rev D - The board has a Z80A CPU, CTC, PIO, DART and SIO. - U16 (24 pin) is missing (boot EPROM?). + The board has a MK3880N-4 (Z80A CPU), CTC, 2x MK3884N-4 (Z80SIO), PIO. It has a lot of jumpers and an 8 way DIP switch. + Crystals: 8.0000MHz, 4.91520MHz Memory board - Model HDM2800 Rev B This contains 18 4164's and a lot of logic. Again, a lot of jumpers, and several banks of links. - Also contains 2 Motorola chips I cannot identify, - MC3480P (24 pin) and MC3242AP (28 pin). - (I have searched the Motorola site and the Chip - Directory; nothing even close.) + Also contains 2 large Motorola chips: + MC3480P (dynamic memory controller) and + MC3242AP (memory address multiplexer). + Dips: 2x 8-sw, 2x 4-sw, 1x 2-sw. Disk Controller board - Model FDC2800 Rev D This board is damaged. The small voltage regulators for +/- 12V have been fried. Also, 3 sockets are empty - U1 and U38 (16 pin) appear to be spares, and U10 (14 pin). 8 port Serial I/O board - Model INO2808 Rev C - Room for 8 8251 USART's. + Room for 8 8251 USARTs. I have traced out this board and managed to get it working in another S100 system. - The "Computer Patch Board" seems to provide some sort of watch dog - facility. -****************************************************************************/ +The "Computer Patch Board" seems to provide some sort of watch dog facility. + +Status: +- Appears to be looping waiting for a disk + +*****************************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" +#include "machine/z80ctc.h" +#include "machine/z80pio.h" +#include "machine/z80sio.h" +//#include "bus/s100/s100.h" #include "screen.h" @@ -49,13 +59,14 @@ public: }; sys2900_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) , - m_maincpu(*this, "maincpu") { } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") { } DECLARE_DRIVER_INIT(sys2900); + uint32_t screen_update_sys2900(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); +private: virtual void machine_reset() override; virtual void video_start() override; - uint32_t screen_update_sys2900(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); required_device<cpu_device> m_maincpu; protected: @@ -63,7 +74,7 @@ protected: }; -static ADDRESS_MAP_START(sys2900_mem, AS_PROGRAM, 8, sys2900_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, sys2900_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0x07ff ) AM_RAMBANK("boot") AM_RANGE( 0x0800, 0xefff ) AM_RAM @@ -71,9 +82,16 @@ static ADDRESS_MAP_START(sys2900_mem, AS_PROGRAM, 8, sys2900_state) AM_RANGE( 0xf800, 0xffff ) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START(sys2900_io, AS_IO, 8, sys2900_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, sys2900_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("sio1", z80sio_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x24, 0x27) AM_DEVREADWRITE("pio", z80pio_device, read_alt, write_alt) + AM_RANGE(0x28, 0x2b) AM_DEVREADWRITE("sio2", z80sio_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x2c, 0x2f) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) + AM_RANGE(0x80, 0x83) // unknown device, disk related? + AM_RANGE(0xa0, 0xaf) // unknown device + AM_RANGE(0xc0, 0xc3) // unknown device ADDRESS_MAP_END /* Input ports */ @@ -117,10 +135,9 @@ uint32_t sys2900_state::screen_update_sys2900(screen_device &screen, bitmap_ind1 static MACHINE_CONFIG_START( sys2900 ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) - MCFG_CPU_PROGRAM_MAP(sys2900_mem) - MCFG_CPU_IO_MAP(sys2900_io) - + MCFG_CPU_ADD("maincpu", Z80, XTAL_8MHz / 2) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -133,12 +150,16 @@ static MACHINE_CONFIG_START( sys2900 ) MCFG_PALETTE_ADD_MONOCHROME("palette") + MCFG_DEVICE_ADD("ctc", Z80CTC, 0) + MCFG_DEVICE_ADD("pio", Z80PIO, 0) + MCFG_DEVICE_ADD("sio1", Z80SIO, 0) + MCFG_DEVICE_ADD("sio2", Z80SIO, 0) MACHINE_CONFIG_END /* ROM definition */ ROM_START( sys2900 ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) - ROM_LOAD( "104401cpc.bin", 0xf000, 0x0800, CRC(6c8848bc) SHA1(890e0578e5cb0e3433b4b173e5ed71d72a92af26)) + ROM_LOAD( "104401cpc.bin", 0xf000, 0x0800, CRC(6c8848bc) SHA1(890e0578e5cb0e3433b4b173e5ed71d72a92af26)) // label says BE 5 1/4 107701 ROM_END /* Driver */ diff --git a/src/mame/drivers/sys9002.cpp b/src/mame/drivers/sys9002.cpp index 8b7ae48e825..bab16aa5c48 100644 --- a/src/mame/drivers/sys9002.cpp +++ b/src/mame/drivers/sys9002.cpp @@ -12,10 +12,19 @@ NEC D4016C-3 * 4 + 2 ST M2764A-4F1 * 4 HD6845P + +Seems a chargen is missing. +If write to the 6845 is enabled, MAME freezes after 1 or 2 seconds. + ****************************************************************************/ #include "emu.h" #include "cpu/i8085/i8085.h" +#include "video/mc6845.h" +#include "screen.h" +#include "machine/clock.h" +#include "machine/i8251.h" +#include "bus/rs232/rs232.h" class sys9002_state : public driver_device { @@ -23,10 +32,16 @@ public: sys9002_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_p_videoram(*this, "videoram") + , m_palette(*this, "palette") { } + MC6845_UPDATE_ROW(crtc_update_row); + private: required_device<cpu_device> m_maincpu; + required_shared_ptr<uint8_t> m_p_videoram; + required_device<palette_device> m_palette; }; @@ -34,23 +49,121 @@ static ADDRESS_MAP_START(sys9002_mem, AS_PROGRAM, 8, sys9002_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x7fff) AM_ROM // 4 * 4K ROM AM_RANGE(0x8000, 0x9fff) AM_RAM // 4 * 2k RAM - AM_RANGE(0xa000, 0xa7ff) AM_RAM // 2k RAM + AM_RANGE(0xa000, 0xa7ff) AM_RAM AM_SHARE("videoram") // 2k RAM + AM_RANGE(0xc000, 0xc07f) AM_RAM // ?? ADDRESS_MAP_END static ADDRESS_MAP_START(sys9002_io, AS_IO, 8, sys9002_state) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) + //AM_RANGE(0x04, 0x04) AM_DEVREADWRITE("crtc", mc6845_device, status_r, address_w) // left commented out as mame freezes after about 2 seconds + //AM_RANGE(0x05, 0x05) AM_DEVREADWRITE("crtc", mc6845_device, register_r, register_w) + AM_RANGE(0x08, 0x08) AM_DEVREADWRITE("uart1", i8251_device, data_r, data_w) + AM_RANGE(0x09, 0x09) AM_DEVREADWRITE("uart1", i8251_device, status_r, control_w) // 7 bits even parity, x64 + AM_RANGE(0x11, 0x11) AM_READNOP // continuous read + AM_RANGE(0x1c, 0x1c) AM_DEVREADWRITE("uart2", i8251_device, data_r, data_w) + AM_RANGE(0x1d, 0x1d) AM_DEVREADWRITE("uart2", i8251_device, status_r, control_w) // enabled for transmit only, 8 bits odd parity, x64 ADDRESS_MAP_END /* Input ports */ static INPUT_PORTS_START( sys9002 ) INPUT_PORTS_END +MC6845_UPDATE_ROW( sys9002_state::crtc_update_row ) +{ + const rgb_t *pens = m_palette->palette()->entry_list_raw(); + uint8_t chr,gfx; + uint16_t mem,x; + uint32_t *p = &bitmap.pix32(y); + + for (x = 0; x < x_count; x++) + { + mem = (ma + x) & 0x7ff; + chr = m_p_videoram[mem]; + + /* get pattern of pixels for that character scanline */ + gfx = chr; //gfx = m_p_chargen[(chr<<4) | ra] ^ ((x == cursor_x) ? 0xff : 0); + + /* Display a scanline of a character (8 pixels) */ + *p++ = pens[BIT(gfx, 7)]; + *p++ = pens[BIT(gfx, 6)]; + *p++ = pens[BIT(gfx, 5)]; + *p++ = pens[BIT(gfx, 4)]; + *p++ = pens[BIT(gfx, 3)]; + *p++ = pens[BIT(gfx, 2)]; + *p++ = pens[BIT(gfx, 1)]; + *p++ = pens[BIT(gfx, 0)]; + } +} + + +static DEVICE_INPUT_DEFAULTS_START( uart1 ) + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9600 ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9600 ) + DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_7 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_ODD ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) +DEVICE_INPUT_DEFAULTS_END + +static DEVICE_INPUT_DEFAULTS_START( uart2 ) + DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9600 ) + DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9600 ) + DEVICE_INPUT_DEFAULTS( "RS232_STARTBITS", 0xff, RS232_STARTBITS_1 ) + DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_8 ) + DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_EVEN ) + DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 ) +DEVICE_INPUT_DEFAULTS_END + static MACHINE_CONFIG_START( sys9002 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",I8085A, XTAL_2MHz) // XTAL not visible on images MCFG_CPU_PROGRAM_MAP(sys9002_mem) MCFG_CPU_IO_MAP(sys9002_io) + + /* video hardware */ + MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) + MCFG_SCREEN_REFRESH_RATE(60) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // not correct + MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update) + MCFG_SCREEN_SIZE(32*8, 32*8) + MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1) + //MCFG_GFXDECODE_ADD("gfxdecode", "palette", mx2178) + MCFG_PALETTE_ADD_MONOCHROME("palette") + + /* Devices */ + MCFG_MC6845_ADD("crtc", MC6845, "screen", XTAL_2MHz) // clk unknown + MCFG_MC6845_SHOW_BORDER_AREA(false) + MCFG_MC6845_CHAR_WIDTH(8) + MCFG_MC6845_UPDATE_ROW_CB(sys9002_state, crtc_update_row) + + MCFG_DEVICE_ADD("uart_clock", CLOCK, 614400) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("uart1", i8251_device, write_txc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", i8251_device, write_rxc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart2", i8251_device, write_txc)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart2", i8251_device, write_rxc)) + + MCFG_DEVICE_ADD("uart1", I8251, 0) + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232a", rs232_port_device, write_txd)) + MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232a", rs232_port_device, write_dtr)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232a", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232a", default_rs232_devices, nullptr) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart1", i8251_device, write_rxd)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart1", i8251_device, write_dsr)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart1", i8251_device, write_cts)) + MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", uart1) + + MCFG_DEVICE_ADD("uart2", I8251, 0) + MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232b", rs232_port_device, write_txd)) + MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232b", rs232_port_device, write_dtr)) + MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232b", rs232_port_device, write_rts)) + + MCFG_RS232_PORT_ADD("rs232b", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart2", i8251_device, write_rxd)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart2", i8251_device, write_dsr)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart2", i8251_device, write_cts)) + MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", uart2) MACHINE_CONFIG_END /* ROM definition */ diff --git a/src/mame/drivers/tail2nos.cpp b/src/mame/drivers/tail2nos.cpp index 56b6d9daa1f..f153dc1827e 100644 --- a/src/mame/drivers/tail2nos.cpp +++ b/src/mame/drivers/tail2nos.cpp @@ -52,8 +52,7 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 16, tail2nos_state ) AM_RANGE(0xfff004, 0xfff005) AM_READ_PORT("DSW") AM_RANGE(0xfff008, 0xfff009) AM_READ8(sound_semaphore_r, 0x00ff) AM_DEVWRITE8("soundlatch", generic_latch_8_device, write, 0x00ff) AM_RANGE(0xfff020, 0xfff023) AM_DEVWRITE8("gga", vsystem_gga_device, write, 0x00ff) - AM_RANGE(0xfff030, 0xfff031) AM_DEVREADWRITE8("acia", acia6850_device, status_r, control_w, 0x00ff) - AM_RANGE(0xfff032, 0xfff033) AM_DEVREADWRITE8("acia", acia6850_device, data_r, data_w, 0x00ff) + AM_RANGE(0xfff030, 0xfff033) AM_DEVREADWRITE8("acia", acia6850_device, read, write, 0x00ff) ADDRESS_MAP_END static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, tail2nos_state ) diff --git a/src/mame/drivers/taito_b.cpp b/src/mame/drivers/taito_b.cpp index 9d7c0e68b06..766f29dc897 100644 --- a/src/mame/drivers/taito_b.cpp +++ b/src/mame/drivers/taito_b.cpp @@ -3806,6 +3806,6 @@ GAME( 1994, spacedxo, spacedx, spacedxo, spacedxo, taitob_state, taito_b, ROT0, in that it has a punching pad that player needs to punch to hit the enemy. */ -GAME( 1990, sbm, 0, sbm, sbm, taitob_state, taito_b, ROT0, "Taito Corporation", "Sonic Blast Man (US)", MACHINE_SUPPORTS_SAVE | MACHINE_MECHANICAL ) -GAME( 1990, sbmj, sbm, sbm, sbm, taitob_state, taito_b, ROT0, "Taito Corporation", "Sonic Blast Man (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_MECHANICAL ) -GAME( 1994, realpunc, 0, realpunc, realpunc, taitob_state, taito_b, ROT0, "Taito Corporation Japan", "Real Puncher", MACHINE_SUPPORTS_SAVE | MACHINE_MECHANICAL ) +GAME( 1990, sbm, 0, sbm, sbm, taitob_state, taito_b, ROT0, "Taito Corporation", "Sonic Blast Man (US)", MACHINE_SUPPORTS_SAVE | MACHINE_MECHANICAL ) +GAME( 1990, sbmj, sbm, sbm, sbm, taitob_state, taito_b, ROT0, "Taito Corporation", "Sonic Blast Man (Japan)", MACHINE_SUPPORTS_SAVE | MACHINE_MECHANICAL ) +GAME( 1994, realpunc, 0, realpunc, realpunc, taitob_c_state, taito_b, ROT0, "Taito Corporation Japan", "Real Puncher", MACHINE_SUPPORTS_SAVE | MACHINE_MECHANICAL ) diff --git a/src/mame/drivers/taito_z.cpp b/src/mame/drivers/taito_z.cpp index 6005149aba5..093768a1231 100644 --- a/src/mame/drivers/taito_z.cpp +++ b/src/mame/drivers/taito_z.cpp @@ -13,7 +13,6 @@ Nicola Salmoria. Thanks to Richard Bush and the Raine team, whose open source was very helpful in many areas particularly the sprites.) - The Taito Z system has a number of similarities with the Taito F2 system, and uses some of the same custom Taito components. @@ -83,7 +82,7 @@ Taito Sound PCB J1100137A K1100314A: Notes: B33-30 is a OKI M27512-15 -Taito Video Baord PCB J1100139A K1100316A: +Taito Video Board PCB J1100139A K1100316A: B33-03 TC0050VDZ TC0050VDZ TC0050VDZ B33-04 @@ -858,7 +857,7 @@ Strange page in test mode which lets you alter all sorts of settings, may relate to sit-in cockpit version. Can't find a dip that disables this. <- Test Mode 1? That's used for lamps and motor testing... -AS -Motors (located at the 0xe000**) are mirrored, they uses both bytes of a +Motors (located at the 0xe000**) are mirrored, they use both bytes of a word, the high one is used during gameplay and the other one is used on service mode. The gameplay port is xor'ed (!). It works like this: @@ -882,6 +881,9 @@ in the upright version), they lights when the player gets hit and/or if he's dyi Aqua Jack --------- +Some wrong colors. Hovercraft body should be red. 1st level sky/water +should be blue. + Sprites left on screen under hiscore table. Deliberate? Or is there a sprite disable bit somewhere. diff --git a/src/mame/drivers/taitogn.cpp b/src/mame/drivers/taitogn.cpp index 077264dbd7e..0adb428d762 100644 --- a/src/mame/drivers/taitogn.cpp +++ b/src/mame/drivers/taitogn.cpp @@ -730,7 +730,7 @@ static MACHINE_CONFIG_START( coh3002t ) MCFG_DEVICE_ADD("flashbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(flashbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000000) // 5MHz NEC uPD78081 MCU: diff --git a/src/mame/drivers/taitojc.cpp b/src/mame/drivers/taitojc.cpp index 72bcdb7bc48..124b5e007e8 100644 --- a/src/mame/drivers/taitojc.cpp +++ b/src/mame/drivers/taitojc.cpp @@ -969,7 +969,7 @@ static INPUT_PORTS_START( landgear ) PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(35) PORT_KEYDELTA(5) PORT_START("AN.2") // Throttle - PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(35) PORT_KEYDELTA(5) PORT_REVERSE + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(35) PORT_KEYDELTA(5) PORT_CENTERDELTA(0) PORT_REVERSE INPUT_PORTS_END static INPUT_PORTS_START( sidebs ) diff --git a/src/mame/drivers/taitosj.cpp b/src/mame/drivers/taitosj.cpp index d3db46e4a63..c1d4346cbe4 100644 --- a/src/mame/drivers/taitosj.cpp +++ b/src/mame/drivers/taitosj.cpp @@ -1799,12 +1799,12 @@ static MACHINE_CONFIG_START( nomcu ) MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT) MCFG_AY8910_PORT_A_WRITE_CB(DEVWRITE8("dac", dac_byte_interface, write)) MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(taitosj_state, taitosj_dacvol_w)) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.15) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.5) MCFG_SOUND_ADD("ay3", AY8910, XTAL_6MHz/4) // 6mhz/4 on GAME board, AY-3-8910 @ IC49 MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT) MCFG_AY8910_PORT_A_WRITE_CB(WRITE8(taitosj_state, input_port_4_f0_w)) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.15) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.5) MCFG_SOUND_ADD("ay4", AY8910, XTAL_6MHz/4) // 6mhz/4 on GAME board, AY-3-8910 @ IC50 MCFG_AY8910_OUTPUT_TYPE(AY8910_SINGLE_OUTPUT) @@ -1815,12 +1815,12 @@ static MACHINE_CONFIG_START( nomcu ) Bio Attack uses this? */ MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(taitosj_state, taitosj_sndnmi_msk_w)) /* port Bwrite */ - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.3) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 1.0) MCFG_WATCHDOG_ADD("watchdog") MCFG_WATCHDOG_VBLANK_INIT("screen", 128); // 74LS393 on CPU board, counts 128 vblanks before firing watchdog - MCFG_SOUND_ADD("dac", DAC_8BIT_R2R, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.2) // 30k r-2r network + MCFG_SOUND_ADD("dac", DAC_8BIT_R2R, 0) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.15) // 30k r-2r network MCFG_SOUND_ADD("dacvol", DISCRETE, 0) MCFG_DISCRETE_INTF(taitosj_dacvol) MCFG_SOUND_ROUTE_EX(0, "dac", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE_EX(0, "dac", -1.0, DAC_VREF_NEG_INPUT) MACHINE_CONFIG_END diff --git a/src/mame/drivers/taitotz.cpp b/src/mame/drivers/taitotz.cpp index 1b9a05fe395..7a04f0da8e0 100644 --- a/src/mame/drivers/taitotz.cpp +++ b/src/mame/drivers/taitotz.cpp @@ -57,7 +57,7 @@ Bottom board IC40 Toshiba TMP95C063F IC55 Panasonic MN89306 -EPSON 9X5C pscillator near IC55 +EPSON 9X5C oscillator near IC55 IC56 HY57V161610D TC-10 IC22 ID7133 SA70J 25.000 oscillator near IC22 @@ -84,7 +84,7 @@ HIN239CB (+5v Powered RS-232 Transmitter/Receiver - 120kbps) LC321664AM-80 (1Meg (65536 words x 16bits) DRAM) 74HC4040A (12-Stage Binary Ripple Counter) -E74-07.IC6 & E74-08.IC8 are the OKI samples and are indentical +E74-07.IC6 & E74-08.IC8 are the OKI samples and are identical E74-06.IC2 is the TMP95C063 program code. @@ -598,6 +598,7 @@ public: DECLARE_DRIVER_INIT(pwrshovl); DECLARE_DRIVER_INIT(batlgear); DECLARE_DRIVER_INIT(landhigh); + DECLARE_DRIVER_INIT(landhigha); DECLARE_DRIVER_INIT(raizpin); DECLARE_DRIVER_INIT(raizpinj); DECLARE_DRIVER_INIT(styphp); @@ -2628,6 +2629,9 @@ void taitotz_state::init_taitotz_111a() static const char LANDHIGH_HDD_SERIAL[] = // "824915746386 " { 0x38, 0x32, 0x34, 0x39, 0x31, 0x35, 0x37, 0x34, 0x36, 0x33, 0x38, 0x36, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; +static const char LANDHIGHA_HDD_SERIAL[] = // "824915546750 " + { 0x38, 0x32, 0x34, 0x39, 0x31, 0x35, 0x35, 0x34, 0x36, 0x37, 0x35, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; + static const char BATLGR2_HDD_SERIAL[] = // " 05412842" { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x35, 0x34, 0x31, 0x32, 0x38, 0x34, 0x32 }; @@ -2652,6 +2656,15 @@ DRIVER_INIT_MEMBER(taitotz_state,landhigh) m_scr_base = 0x1c0000; } +DRIVER_INIT_MEMBER(taitotz_state,landhigha) +{ + init_taitotz_152(); + + m_hdd_serial_number = LANDHIGHA_HDD_SERIAL; + + m_scr_base = 0x1c0000; +} + DRIVER_INIT_MEMBER(taitotz_state,batlgear) { init_taitotz_111a(); @@ -2777,6 +2790,26 @@ ROM_START( landhigh ) DISK_IMAGE( "landhigh", 0, SHA1(7cea4ea5c3899e6ac774a4eb12821f44541d9c9c) ) ROM_END +ROM_START( landhigha ) + ROM_REGION64_BE( 0x100000, "user1", 0 ) + TAITOTZ_BIOS_V152 + + ROM_REGION( 0x40000, "io_cpu", 0 ) + ROM_LOAD16_BYTE( "e82-03.ic14", 0x000000, 0x020000, CRC(0de65b4d) SHA1(932316f7435259b723a29843d58b2e3dca92e7b7) ) + ROM_LOAD16_BYTE( "e82-04.ic15", 0x000001, 0x020000, CRC(b3cb0f3d) SHA1(80414f50a1593c6b849d9f37e94a32168699a5c1) ) + + ROM_REGION( 0x10000, "sound_cpu", 0 ) /* Internal ROM :( */ + ROM_LOAD( "e68-01.ic7", 0x000000, 0x010000, NO_DUMP ) + + ROM_REGION( 0x500, "plds", 0 ) + ROM_LOAD( "e82-01.ic44", 0x000, 0x117, CRC(49eea30f) SHA1(ef97c792358f05b9214a2f58ee1e97e8208806c4) ) + ROM_LOAD( "e82-02.ic45", 0x117, 0x2dd, CRC(f581cff5) SHA1(468e0e6a3828f2dcda35c6d523154510f9c99db7) ) + ROM_LOAD( "e68-06.ic24", 0x3f4, 0x100, NO_DUMP ) + + DISK_REGION( "ata:0:hdd:image" ) + DISK_IMAGE( "landhigha", 0, SHA1(830ff12671a977a4c243491b68444f8ca69d0819) ) +ROM_END + ROM_START( batlgear ) ROM_REGION64_BE( 0x100000, "user1", 0 ) TAITOTZ_BIOS_V111A @@ -2916,7 +2949,8 @@ ROM_START( styphp ) ROM_END GAME( 1999, taitotz, 0, taitotz, taitotz, taitotz_state, 0, ROT0, "Taito", "Type Zero BIOS", MACHINE_NO_SOUND|MACHINE_NOT_WORKING|MACHINE_IS_BIOS_ROOT) -GAME( 1999, landhigh, taitotz, landhigh, landhigh, taitotz_state, landhigh, ROT0, "Taito", "Landing High Japan (Ver 2.01 OK)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +GAME( 1999, landhigh, taitotz, landhigh, landhigh, taitotz_state, landhigh, ROT0, "Taito", "Landing High Japan (Ver 2.01 OK)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +GAME( 1999, landhigha, landhigh, landhigh, landhigh, taitotz_state, landhigha,ROT0, "Taito", "Landing High Japan (Ver 2.02 O)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) GAME( 1999, batlgear, taitotz, taitotz, batlgr2, taitotz_state, batlgear, ROT0, "Taito", "Battle Gear (Ver 2.40 A)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) GAME( 1999, pwrshovl, taitotz, taitotz, pwrshovl, taitotz_state, pwrshovl, ROT0, "Taito", "Power Shovel ni Norou!! - Power Shovel Simulator (v2.07J)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // 1999/8/5 19:13:35 GAME( 1999, pwrshovla, pwrshovl, taitotz, pwrshovl, taitotz_state, pwrshovl, ROT0, "Taito", "Power Shovel ni Norou!! - Power Shovel Simulator (v2.07J, alt)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) // seem to be some differences in drive content, but identifies as the same revision, is it just user data changes?? diff --git a/src/mame/drivers/tandy1t.cpp b/src/mame/drivers/tandy1t.cpp index 77fb2d00076..657dc23b197 100644 --- a/src/mame/drivers/tandy1t.cpp +++ b/src/mame/drivers/tandy1t.cpp @@ -622,7 +622,7 @@ GFXDECODE_END static MACHINE_CONFIG_START(tandy1000_common) MCFG_DEVICE_ADD("mb", T1000_MOTHERBOARD, 0) - t1000_mb_device::static_set_cputag(*device, "maincpu"); + t1000_mb_device::static_set_cputag(*device, "^maincpu"); /* video hardware */ MCFG_PCVIDEO_T1000_ADD("pcvideo_t1000") @@ -702,8 +702,8 @@ static MACHINE_CONFIG_START( t1000rl ) MCFG_DEVICE_ADD("biosbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(biosbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_MACHINE_RESET_OVERRIDE(tandy1000_state,tandy1000rl) diff --git a/src/mame/drivers/tattack.cpp b/src/mame/drivers/tattack.cpp index 91d59a71f9a..26c6949e021 100644 --- a/src/mame/drivers/tattack.cpp +++ b/src/mame/drivers/tattack.cpp @@ -1,9 +1,10 @@ // license:BSD-3-Clause -// copyright-holders:Tomasz Slanina +// copyright-holders:Tomasz Slanina, Angelo Salese /**************************************************************************** Time Attacker driver by Tomasz Slanina analog[at]op.pl + improvements by Angelo Salese Z80A, xtal 8MHz, @@ -15,9 +16,12 @@ no proms TODO: - - colors - - sound (requires Epson 7910 Multi-Melody emulation) - - game logic + - non-tilemap video offsets/sizes are guessworked; + - random brick flickering effect is guessworked too, leave MACHINE_IMPERFECT_COLORS in until is tested on HW. + - outputs (coin counter port same as sound writes?); + - some dipswitches; + - sound (requires Epson 7910 Multi-Melody emulation?) + \- victory BGM cuts off too late? Connector pinout from manual @@ -47,6 +51,8 @@ #include "emu.h" #include "cpu/z80/z80.h" #include "screen.h" +#include "sound/samples.h" +#include "speaker.h" class tattack_state : public driver_device @@ -54,21 +60,47 @@ class tattack_state : public driver_device public: tattack_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_ram(*this, "ram"), m_videoram(*this, "videoram"), m_colorram(*this, "colorram"), - m_maincpu(*this, "maincpu"), - m_gfxdecode(*this, "gfxdecode") { } - - required_shared_ptr<uint8_t> m_videoram; - required_shared_ptr<uint8_t> m_colorram; - tilemap_t *m_tmap; + m_gfxdecode(*this, "gfxdecode"), + m_samples(*this,"samples") + { } + + DECLARE_WRITE8_MEMBER(paddle_w); + DECLARE_WRITE8_MEMBER(ball_w); + DECLARE_WRITE8_MEMBER(brick_dma_w); + DECLARE_WRITE8_MEMBER(sound_w); DECLARE_DRIVER_INIT(tattack); TILE_GET_INFO_MEMBER(get_tile_info); - virtual void video_start() override; DECLARE_PALETTE_INIT(tattack); + uint32_t screen_update_tattack(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); +protected: + virtual void video_start() override; +private: required_device<cpu_device> m_maincpu; + required_shared_ptr<uint8_t> m_ram; + required_shared_ptr<uint8_t> m_videoram; + required_shared_ptr<uint8_t> m_colorram; required_device<gfxdecode_device> m_gfxdecode; + required_device<samples_device> m_samples; + tilemap_t *m_tmap; + uint8_t m_ball_regs[2]; + uint8_t m_paddle_reg; + int m_paddle_ysize; + bool m_bottom_edge_enable; + bool m_bricks_color_bank; + + void draw_gameplay_bitmap(bitmap_ind16 &bitmap, const rectangle &cliprect); + void draw_edge_bitmap(bitmap_ind16 &bitmap, const rectangle &cliprect); + + static const uint8_t white_pen = 0xf; + static const uint8_t green_pen = 0x5; + static const uint8_t yellow_pen = 0x7; + static const uint8_t red_pen = 0x3; + static const int paddle_xpos = 38; }; @@ -89,10 +121,101 @@ TILE_GET_INFO_MEMBER(tattack_state::get_tile_info) 0); } +void tattack_state::draw_edge_bitmap(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + // left column + bitmap.plot_box(0,16,216,4,white_pen); + // upper row + bitmap.plot_box(216,16,6,226,white_pen); + // right column + bitmap.plot_box(0,238,216,4,white_pen); + if(m_bottom_edge_enable == true) + bitmap.plot_box(paddle_xpos,16,4,226,white_pen); +} + +void tattack_state::draw_gameplay_bitmap(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + uint16_t ram_offs; + const uint16_t ram_base = 0x40+(m_ram[0x33] & 0x10); + const int x_base = -8; + int xi,yi; + + // draw brick pattern + for(ram_offs=ram_base;ram_offs<ram_base+0xe;ram_offs++) + { + uint8_t cur_column = m_ram[ram_offs]; + + for(int bit=7;bit>-1;bit--) + { + bool draw_block = ((cur_column >> bit) & 1) == 1; + + // blinking + // If player hits a blinking brick then a 30 seconds bonus is awarded. + // Sometimes game forgets to update the location or the blinking itself (both bits 0) + // can be either intentional or a game bug. + // TODO: the mask used here is guessed + if((m_ram[0x33] & 0x3) == 3) + { + int blink_row = m_ram[0x2b]; + int blink_col = m_ram[0x2c]; + + if(bit == blink_col && (ram_offs & 0xf) == blink_row) + draw_block = false; + } + + if(draw_block == true) + { + for(xi=0;xi<3;xi++) + { + for(yi=0;yi<15;yi++) + { + int resx = bit*4+xi+160+x_base; + int resy = (ram_offs & 0xf)*16+yi+16; + + if(cliprect.contains(resx,resy)) + bitmap.pix16(resy, resx) = m_bricks_color_bank == true ? red_pen : (bit & 4 ? yellow_pen : green_pen); + } + } + } + } + } + + // draw paddle + if(m_bottom_edge_enable == false) + { + for(xi=0;xi<4;xi++) + for(yi=0;yi<m_paddle_ysize;yi++) + { + int resx =(paddle_xpos+xi); + int resy = m_paddle_reg+yi; + + if(cliprect.contains(resx,resy)) + bitmap.pix16(resy, resx) = white_pen; + } + } + // draw ball + for(xi=0;xi<3;xi++) + for(yi=0;yi<3;yi++) + { + int resx = m_ball_regs[0]+xi-2+x_base; + int resy = m_ball_regs[1]+yi; + + if(cliprect.contains(resx,resy)) + bitmap.pix16(resy, resx) = (white_pen); + } +} + uint32_t tattack_state::screen_update_tattack(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { m_tmap->mark_all_dirty(); m_tmap->draw(screen, bitmap, cliprect, 0,0); + + // draw bricks/ball/paddle + draw_gameplay_bitmap(bitmap, cliprect); + // draw edges + // probably enables thru 0xe040? + draw_edge_bitmap(bitmap,cliprect); + return 0; } @@ -101,59 +224,96 @@ void tattack_state::video_start() m_tmap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tattack_state::get_tile_info),this),TILEMAP_SCAN_ROWS,8,8,32,32 ); } -static ADDRESS_MAP_START( mem, AS_PROGRAM, 8, tattack_state ) +WRITE8_MEMBER(tattack_state::paddle_w) +{ + m_paddle_reg = data; +} + +WRITE8_MEMBER(tattack_state::ball_w) +{ + m_ball_regs[offset] = data; +} + +WRITE8_MEMBER(tattack_state::brick_dma_w) +{ + // bit 7: 0->1 transfers from RAM to internal video buffer + // bit 6: bricks color bank + m_bricks_color_bank = BIT(data,6); + // bit 5: flip screen + flip_screen_set(!(data & 0x20)); + // bit 4: x paddle half size + m_paddle_ysize = data & 0x10 ? 8 : 16; + // bit 3: enable bottom edge + m_bottom_edge_enable = BIT(data,3); +// popmessage("%02x",data&0x7f); +} + +WRITE8_MEMBER(tattack_state::sound_w) +{ + // bit 4 enabled on coin insertion (coin counter?) + // bit 3-0 samples enable, @see tattack_sample_names + for(int i=0;i<4;i++) + { + // don't restart playing if it is still enabled (victory BGM relies on this) + if(data & 1 << i && m_samples->playing(i) == false) + m_samples->start(i,i); + //if((data & 1 << i) == 0 && m_samples->playing(i) == true) + // m_samples->stop(i); + } +} + +static ADDRESS_MAP_START( tattack_map, AS_PROGRAM, 8, tattack_state ) AM_RANGE(0x0000, 0x0fff) AM_ROM -// AM_RANGE(0x4000, 0x4000) AM_READNOP $315 + AM_RANGE(0x4000, 0x4000) AM_READ_PORT("AN_PADDLE") // $315, checks again with same memory, loops if different (?) AM_RANGE(0x5000, 0x53ff) AM_RAM AM_SHARE("videoram") - AM_RANGE(0x7000, 0x73ff) AM_RAM AM_SHARE("colorram") // color map ? something else .. only bits 1-3 are used AM_RANGE(0x6000, 0x6000) AM_READ_PORT("DSW2") + AM_RANGE(0x7000, 0x73ff) AM_RAM AM_SHARE("colorram") // color map ? something else .. only bits 1-3 are used AM_RANGE(0xa000, 0xa000) AM_READ_PORT("DSW1") // dsw ? something else ? - AM_RANGE(0xc000, 0xc000) AM_READ_PORT("INPUTS") AM_WRITENOP - AM_RANGE(0xc001, 0xc002) AM_WRITENOP // bit 7 = strobe ($302) - AM_RANGE(0xc005, 0xc007) AM_WRITENOP - AM_RANGE(0xe000, 0xe3ff) AM_RAM + AM_RANGE(0xc000, 0xc000) AM_READ_PORT("INPUTS") AM_WRITE(sound_w) // sound + AM_RANGE(0xc001, 0xc001) AM_WRITE(brick_dma_w) // bit 7 = strobe ($302) + AM_RANGE(0xc002, 0xc002) AM_WRITENOP // same as sound port, outputs? + AM_RANGE(0xc005, 0xc005) AM_WRITE(paddle_w) + AM_RANGE(0xc006, 0xc007) AM_WRITE(ball_w) + AM_RANGE(0xe000, 0xe3ff) AM_RAM AM_SHARE("ram") ADDRESS_MAP_END static INPUT_PORTS_START( tattack ) PORT_START("INPUTS") - PORT_DIPNAME( 0x01, 0x00, "1-01" ) + PORT_DIPNAME( 0x01, 0x00, "1-01" ) // reset switch? PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, "1-02" ) + PORT_DIPNAME( 0x02, 0x02, "1-02" ) PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, "1-03" ) + PORT_DIPNAME( 0x04, 0x04, "1-03" ) PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, "1-04" ) + PORT_DIPNAME( 0x08, 0x08, "1-04" ) PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON3 ) - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON2 ) + PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) + PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_START2 ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_START("DSW1") - PORT_DIPNAME( 0x01, 0x00, "DSW1 1" ) - PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - + PORT_DIPNAME( 0x01, 0x00, "Enable green square blocks" ) + PORT_DIPSETTING( 0x00, DEF_STR( No ) ) + PORT_DIPSETTING( 0x01, DEF_STR( Yes ) ) PORT_DIPNAME( 0x02, 0x00, DEF_STR( Coin_A ) ) PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) ) PORT_DIPSETTING( 0x02, DEF_STR( 1C_2C ) ) - - PORT_DIPNAME( 0x04, 0x00, "Time" ) + PORT_DIPNAME( 0x04, 0x04, "Number of bricks to destroy" ) PORT_DIPSETTING( 0x04, "112" ) - PORT_DIPSETTING( 0x00, "5" ) + PORT_DIPSETTING( 0x00, "5" ) // testing option? PORT_DIPNAME( 0x08, 0x00, "DSW1 4" ) PORT_DIPSETTING( 0x08, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x00, "DSW1 5" ) - PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x00, "DSW1 6" ) - PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x30, 0x00, "Paddle in middle of screen" ) + PORT_DIPSETTING( 0x00, "Never on screen" ) + PORT_DIPSETTING( 0x10, "Mode 1" ) // - appears after a set number of bricks destroyed, might be same setting + PORT_DIPSETTING( 0x20, "Mode 2" ) // / + PORT_DIPSETTING( 0x30, "Always on screen" ) PORT_DIPNAME( 0x40, 0x00, "DSW1 7" ) PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) @@ -177,15 +337,17 @@ static INPUT_PORTS_START( tattack ) PORT_DIPNAME( 0x10, 0x00, "DSW2 5" ) PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x00, "DSW2 6" ) - PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, "DSW2 7" ) - PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x00, "DSW2 8" ) - PORT_DIPSETTING( 0x80, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x20, 0x00, DEF_STR( Cabinet ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x20, DEF_STR( Cocktail ) ) + PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Lives ) ) + PORT_DIPSETTING( 0x00, "3" ) + PORT_DIPSETTING( 0x40, "5" ) + PORT_DIPSETTING( 0x80, "7" ) + PORT_DIPSETTING( 0xc0, DEF_STR( Infinite ) ) + + PORT_START("AN_PADDLE") + PORT_BIT( 0xff, 0x00, IPT_PADDLE ) PORT_MINMAX(0,0xff) PORT_SENSITIVITY(10) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) INPUT_PORTS_END @@ -220,17 +382,26 @@ PALETTE_INIT_MEMBER(tattack_state, tattack) else r=g=b=128; - palette.set_pen_color(2*i,rgb_t(0x00,0x00,0x00)); + palette.set_pen_color(2*i,rgb_t(0x00,0x00,0xff)); palette.set_pen_color(2*i+1,rgb_t(r,g,b)); } } +static const char *const tattack_sample_names[] = +{ + "*tattack", + "paddle_hit", + "wall_hit", + "brick_destroy", + "win_bgm", + nullptr +}; static MACHINE_CONFIG_START( tattack ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, 8000000 / 2) /* 4 MHz ? */ - MCFG_CPU_PROGRAM_MAP(mem) + MCFG_CPU_PROGRAM_MAP(tattack_map) MCFG_CPU_VBLANK_INT_DRIVER("screen", tattack_state, irq0_line_hold) /* video hardware */ @@ -238,7 +409,7 @@ static MACHINE_CONFIG_START( tattack ) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500) /* not accurate */) MCFG_SCREEN_SIZE(32*8, 32*8) - MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1) + MCFG_SCREEN_VISIBLE_AREA(24, 256-32-1, 13, 256-11-1) MCFG_SCREEN_UPDATE_DRIVER(tattack_state, screen_update_tattack) MCFG_SCREEN_PALETTE("palette") @@ -247,8 +418,16 @@ static MACHINE_CONFIG_START( tattack ) MCFG_PALETTE_INIT_OWNER(tattack_state, tattack) /* sound hardware */ - /* Discrete ???? */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("samples", SAMPLES, 0) + MCFG_SAMPLES_CHANNELS(4) + MCFG_SAMPLES_NAMES(tattack_sample_names) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.6) + /* Discrete ???? */ +// MCFG_SOUND_ADD("discrete", DISCRETE, 0) +// MCFG_DISCRETE_INTF(tattack) +// MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) MACHINE_CONFIG_END /*************************************************************************** @@ -263,23 +442,22 @@ ROM_START( tattack ) ROM_REGION( 0x1000, "gfx1", 0 ) ROM_LOAD( "rom.6c", 0x0000, 0x1000, CRC(88ce45cf) SHA1(c7a43bfc9e9c2aeb75a98f723558bc88e53401a7) ) - ROM_END DRIVER_INIT_MEMBER(tattack_state,tattack) { - uint8_t *rom = memregion("maincpu")->base(); +// uint8_t *rom = memregion("maincpu")->base(); - rom[0x1b4]=0; - rom[0x1b5]=0; +// rom[0x1b4]=0; +// rom[0x1b5]=0; - rom[0x262]=0; - rom[0x263]=0; - rom[0x264]=0; +// rom[0x262]=0; +// rom[0x263]=0; +// rom[0x264]=0; - rom[0x32a]=0; - rom[0x32b]=0; - rom[0x32c]=0; +// rom[0x32a]=0; +// rom[0x32b]=0; +// rom[0x32c]=0; /* possible jumps to 0 (protection checks?) @@ -303,4 +481,5 @@ DRIVER_INIT_MEMBER(tattack_state,tattack) } -GAME( 198?, tattack, 0, tattack, tattack, tattack_state, tattack, ROT270, "Shonan", "Time Attacker", MACHINE_NO_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_NOT_WORKING) +GAME( 1983?, tattack, 0, tattack, tattack, tattack_state, tattack, ROT270, "Shonan", "Time Attacker", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_COLORS | MACHINE_NO_COCKTAIL ) +// there is another undumped version with katakana Shonan logo and black background diff --git a/src/mame/drivers/tavernie.cpp b/src/mame/drivers/tavernie.cpp index 4a341ae4609..afa3ca22b92 100644 --- a/src/mame/drivers/tavernie.cpp +++ b/src/mame/drivers/tavernie.cpp @@ -116,8 +116,7 @@ static ADDRESS_MAP_START(cpu09_mem, AS_PROGRAM, 8, tavernie_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x1000, 0x1fff) AM_NOP AM_RANGE(0xeb00, 0xeb03) AM_DEVREADWRITE("pia", pia6821_device, read, write) - AM_RANGE(0xeb04, 0xeb04) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0xeb05, 0xeb05) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0xeb04, 0xeb05) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0xeb08, 0xeb0f) AM_DEVREADWRITE("ptm", ptm6840_device, read, write) AM_RANGE(0xec00, 0xefff) AM_RAM // 1Kx8 RAM MK4118 AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION("roms", 0) @@ -132,8 +131,7 @@ static ADDRESS_MAP_START(ivg09_mem, AS_PROGRAM, 8, tavernie_state) AM_RANGE(0xe000, 0xe003) AM_DEVREADWRITE("fdc", fd1795_device, read, write) AM_RANGE(0xe080, 0xe080) AM_WRITE(ds_w) AM_RANGE(0xeb00, 0xeb03) AM_DEVREADWRITE("pia", pia6821_device, read, write) - AM_RANGE(0xeb04, 0xeb04) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0xeb05, 0xeb05) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0xeb04, 0xeb05) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0xeb08, 0xeb0f) AM_DEVREADWRITE("ptm", ptm6840_device, read, write) AM_RANGE(0xec00, 0xefff) AM_RAM // 1Kx8 RAM MK4118 AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION("roms", 0) diff --git a/src/mame/drivers/techno.cpp b/src/mame/drivers/techno.cpp index 9bc7018fe1f..eba5c5ef94b 100644 --- a/src/mame/drivers/techno.cpp +++ b/src/mame/drivers/techno.cpp @@ -29,6 +29,12 @@ public: , m_switch(*this, "SWITCH.%u", 0) { } + enum + { + IRQ_SET_TIMER, + IRQ_ADVANCE_TIMER + }; + DECLARE_READ16_MEMBER(key_r); DECLARE_READ16_MEMBER(rtrg_r); DECLARE_READ16_MEMBER(sound_r); @@ -40,15 +46,22 @@ public: DECLARE_WRITE16_MEMBER(sol1_w); DECLARE_WRITE16_MEMBER(sol2_w); DECLARE_WRITE16_MEMBER(sound_w); - INTERRUPT_GEN_MEMBER(techno_intgen); + private: + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + virtual void machine_start() override; + virtual void machine_reset() override; + + required_device<cpu_device> m_maincpu; + required_ioport_array<8> m_switch; + + emu_timer *m_irq_set_timer; + emu_timer *m_irq_advance_timer; + bool m_digwait; uint8_t m_keyrow; uint16_t m_digit; uint8_t m_vector; - virtual void machine_reset() override; - required_device<cpu_device> m_maincpu; - required_ioport_array<8> m_switch; }; @@ -228,28 +241,47 @@ static INPUT_PORTS_START( techno ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Fix top left target middle") PORT_CODE(KEYCODE_EQUALS) INPUT_PORTS_END -INTERRUPT_GEN_MEMBER(techno_state::techno_intgen) +void techno_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - // vectors change per int: 88-8F, 98-9F) - if ((m_vector & 7) == 7) - m_vector = (m_vector ^ 0x10) & 0x97; - m_vector++; - // core doesn't support clearing of irq via hardware - generic_pulse_irq_line_and_vector(device.execute(), 1, m_vector, 1); + if (id == IRQ_ADVANCE_TIMER) + { + // vectors change per int: 88-8F, 98-9F) + if ((m_vector & 7) == 7) + m_vector = (m_vector ^ 0x10) & 0x97; + m_vector++; + + // schematics show a 74HC74 cleared only upon IRQ acknowledgment or reset, but this is clearly incorrect for xforce + m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); + } + else if (id == IRQ_SET_TIMER) + { + m_maincpu->set_input_line_and_vector(M68K_IRQ_1, ASSERT_LINE, m_vector); + m_irq_advance_timer->adjust(attotime::from_hz(XTAL_8MHz / 32)); + } +} + +void techno_state::machine_start() +{ + m_irq_set_timer = timer_alloc(IRQ_SET_TIMER); + m_irq_advance_timer = timer_alloc(IRQ_ADVANCE_TIMER); } void techno_state::machine_reset() { m_vector = 0x88; m_digit = 0; + + attotime freq = attotime::from_hz(XTAL_8MHz / 256); // 31250Hz + m_irq_set_timer->adjust(freq, 0, freq); + m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); } static MACHINE_CONFIG_START( techno ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M68000, XTAL_8MHz) MCFG_CPU_PROGRAM_MAP(techno_map) - MCFG_CPU_PERIODIC_INT_DRIVER(techno_state, techno_intgen, XTAL_8MHz/256) // 31250Hz MCFG_NVRAM_ADD_0FILL("nvram") + //MCFG_CPU_ADD("cpu2", TMS7000, XTAL_4MHz) //MCFG_CPU_PROGRAM_MAP(techno_sub_map) diff --git a/src/mame/drivers/tek405x.cpp b/src/mame/drivers/tek405x.cpp index f0b7cd15401..fe57f3dfdcc 100644 --- a/src/mame/drivers/tek405x.cpp +++ b/src/mame/drivers/tek405x.cpp @@ -180,8 +180,7 @@ static ADDRESS_MAP_START( tek4051_mem, AS_PROGRAM, 8, tek4051_state ) AM_RANGE(0x87b0, 0x87b3) AM_DEVREADWRITE(MC6820_GPIB_TAG, pia6821_device, read, write) AM_RANGE(0x87c0, 0x87c0) AM_MIRROR(0x03) AM_WRITE(lbs_w) // AM_RANGE(0x87c0, 0x87c3) AM_DEVREADWRITE(MC6820_COM_TAG, pia6821_device, read, write) -// AM_RANGE(0x87c4, 0x87c4) AM_MIRROR(0x02) AM_DEVREADWRITE(MC6850_TAG, acia6850_device, status_r, control_w) -// AM_RANGE(0x87c5, 0x87c5) AM_MIRROR(0x02) AM_DEVREADWRITE(MC6850_TAG, acia6850_device, data_r, data_w) +// AM_RANGE(0x87c4, 0x87c5) AM_MIRROR(0x02) AM_DEVREADWRITE(MC6850_TAG, acia6850_device, read, write) // AM_RANGE(0x87c8, 0x87cb) XPC2 // AM_RANGE(0x87cc, 0x87cf) XPC3 // AM_RANGE(0x87d0, 0x87d3) XPC4 diff --git a/src/mame/drivers/terak.cpp b/src/mame/drivers/terak.cpp index be2216212ef..f74fe30e878 100644 --- a/src/mame/drivers/terak.cpp +++ b/src/mame/drivers/terak.cpp @@ -2,9 +2,12 @@ // copyright-holders:Miodrag Milanovic /*************************************************************************** - Terak 8510A +Terak 8510A - 23/02/2009 Skeleton driver. +2009-02-23 Skeleton driver. + +Known chips: i8257 DMA, i8272a FDC +Floppies were 8 inch IBM format. ****************************************************************************/ @@ -17,26 +20,29 @@ class terak_state : public driver_device { public: terak_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) , - m_maincpu(*this, "maincpu") { } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + { } DECLARE_READ16_MEMBER(terak_fdc_status_r); DECLARE_WRITE16_MEMBER(terak_fdc_command_w); DECLARE_READ16_MEMBER(terak_fdc_data_r); DECLARE_WRITE16_MEMBER(terak_fdc_data_w); + uint32_t screen_update_terak(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + +private: uint8_t m_unit; uint8_t m_cmd; - uint16_t m_data; virtual void machine_reset() override; virtual void video_start() override; - uint32_t screen_update_terak(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); required_device<cpu_device> m_maincpu; }; READ16_MEMBER( terak_state::terak_fdc_status_r ) { logerror("terak_fdc_status_r\n"); - if (m_cmd==3) { + if (m_cmd==3) + { logerror("cmd is 3\n"); return 0xffff; } @@ -61,7 +67,7 @@ WRITE16_MEMBER( terak_state::terak_fdc_data_w ) logerror("terak_fdc_data_w %04x\n",data); } -static ADDRESS_MAP_START(terak_mem, AS_PROGRAM, 16, terak_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 16, terak_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0xf5ff ) AM_RAM // RAM @@ -94,8 +100,7 @@ static MACHINE_CONFIG_START( terak ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",T11, XTAL_4MHz) MCFG_T11_INITIAL_MODE(6 << 13) - MCFG_CPU_PROGRAM_MAP(terak_mem) - + MCFG_CPU_PROGRAM_MAP(mem_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) @@ -114,9 +119,14 @@ MACHINE_CONFIG_END ROM_START( terak ) ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF ) ROM_LOAD( "terak.rom", 0173000, 0x0080, CRC(fd654b8e) SHA1(273a9933b68a290c5aedcd6d69faa7b1d22c0344)) + + ROM_REGION( 0x2000, "kbd", 0) + // keytronic keyboard, roms are unlabelled, type 6301-1J. CPU is 30293E-003. No crystal. + ROM_LOAD( "82s129.z2", 0x0000, 0x0100, CRC(a5dce419) SHA1(819197a03eb9b6ea3318f5afc37c0b436dd747a7) ) + ROM_LOAD( "82s129.z1", 0x0100, 0x0100, CRC(f34e061f) SHA1(3cb354b2680056d4b3234c680958d4591279ac8a) ) ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -COMP( ????, terak, 0, 0, terak, terak, terak_state, 0, "Terak", "Terak 8510A", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1977, terak, 0, 0, terak, terak, terak_state, 0, "Terak", "Terak 8510A", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/terco.cpp b/src/mame/drivers/terco.cpp index 1395d7e2d8b..4bc0bbb4187 100644 --- a/src/mame/drivers/terco.cpp +++ b/src/mame/drivers/terco.cpp @@ -35,7 +35,7 @@ #include "emu.h" #include "cpu/m6800/m6800.h" #include "machine/6821pia.h" -//#include "machine/6850acia.h" +#include "machine/6850acia.h" //#include "machine/kb3600.h" //#include "machine/mc14411.h" @@ -71,7 +71,7 @@ * 555 - analog timer circuit * 6800 - 8 bit CPU * 6821 - PIA paralell interface - * 6850 - ACIA serial interface + * 6850 - ACIA serial interface * 7400 - Quad 2 input NAND gates * 7402 - Quad 2 input NOR gates * 7408 - Quad 2 input AND gates @@ -81,15 +81,15 @@ * 7476 - Dual JK flip flops with preset and clear * 7490 - Decade Counters, divide by 2 and divide by 5 outputs * 74116 - Dual 4-bit latches - * 74138 - 3 to 8 line decoder/demultiplexer - * 74139 - Dual 2 to 4 line decoder/demultiplexer + * 74138 - 3 to 8 line decoder/demultiplexer + * 74139 - Dual 2 to 4 line decoder/demultiplexer * 74154 - 4 line to 16 line decoders/multiplexers * 74164 - 8 bit paralell output serial shift register * 74174 - 6 D-type flip flops * 74240 - Inverted 3-state outputs * 74244 - Non-inverted 3-state outputs * AY3600 - Keyboard Controller - * CA339 - Quad Voltage Comparators + * CA339 - Quad Voltage Comparators * CD4050B - CMOS Hex Non-Inverting Buffer and Converter * CIC2414 - CMOS RAM suspects * DS1210 - NVRAM controller, inhibits access and supply battery power on power down @@ -267,7 +267,7 @@ public: { } private: required_device<m6800_cpu_device> m_maincpu; - // virtual void machine_reset() override { m_maincpu->reset(); LOG("--->%s()\n", FUNCNAME); }; + // virtual void machine_reset() override { m_maincpu->reset(); LOG("--->%s()\n", FUNCNAME); }; required_device<pia6821_device> m_pia1; required_device<pia6821_device> m_pia2; //required_device<pia6821_device> m_pia3; @@ -280,9 +280,9 @@ static ADDRESS_MAP_START( t4490_map, AS_PROGRAM, 8, t4490_state ) AM_RANGE(0x0000, 0x1fff) AM_RAM AM_RANGE(0x3000, 0x3fff) AM_ROM AM_REGION("maincpu", 0x3000) AM_RANGE(0x9500, 0x95ff) AM_RAM - AM_RANGE(0x9036, 0x9037) AM_DEVREADWRITE("pia1", pia6821_device, read, write) - AM_RANGE(0x903a, 0x903b) AM_DEVREADWRITE("pia2", pia6821_device, read, write) -// AM_RANGE(0xc820, 0xc823) AM_DEVREADWRITE("acia", acia6850_device, read, write) + AM_RANGE(0x9030, 0x9031) AM_DEVREADWRITE("acia", acia6850_device, read, write) + AM_RANGE(0x9034, 0x9037) AM_DEVREADWRITE("pia1", pia6821_device, read, write) + AM_RANGE(0x9038, 0x903b) AM_DEVREADWRITE("pia2", pia6821_device, read, write) AM_RANGE(0xa000, 0xffff) AM_ROM AM_REGION("maincpu", 0xa000) ADDRESS_MAP_END @@ -297,6 +297,7 @@ static MACHINE_CONFIG_START( t4490 ) /* devices */ MCFG_DEVICE_ADD("pia1", PIA6821, 0) MCFG_DEVICE_ADD("pia2", PIA6821, 0) + MCFG_DEVICE_ADD("acia", ACIA6850, 0) MACHINE_CONFIG_END ROM_START( t4490 ) diff --git a/src/mame/drivers/terminals.cpp b/src/mame/drivers/terminals.cpp new file mode 100644 index 00000000000..6fe1eb7ab60 --- /dev/null +++ b/src/mame/drivers/terminals.cpp @@ -0,0 +1,372 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-17 Skeleton + +A selection of terminals from Bitsavers. A placeholder for now. + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/z80/z80.h" + +class terminals_state : public driver_device +{ +public: + terminals_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + //, m_p_chargen(*this, "chargen") + { } + +private: + required_device<cpu_device> m_maincpu; + //required_region_ptr<u8> m_p_chargen; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, terminals_state ) +ADDRESS_MAP_END + +static INPUT_PORTS_START( terminals ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( terminals ) + MCFG_CPU_ADD("maincpu", Z80, 2'000'000) + MCFG_CPU_PROGRAM_MAP(mem_map) +MACHINE_CONFIG_END + +/************************************************************************************************************** + +Ann Arbor Ambassador. +Chips: Z80A, M58725P (16k RAM), 2x SCN2651C, nvram, button-battery +Crystals: 18.414, 6.0688 + +***************************************************************************************************************/ + +ROM_START( aaa ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "459_1.bin", 0x0000, 0x1000, CRC(55fb3e3b) SHA1(349cd257b1468827e1b389be7c989d0e4a13a5f1) ) + ROM_LOAD( "459_3.bin", 0x1000, 0x1000, CRC(e1e84ca4) SHA1(42dc5f4211beee79178f0c03bb45c66833119eae) ) + ROM_LOAD( "459_4.bin", 0x8000, 0x2000, CRC(4038aa89) SHA1(caf33c1f87aa396860324b9c73b35e4221f03d2e) ) + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "202510b.bin", 0x0000, 0x1000, CRC(deda4aa4) SHA1(0bce5a8dc260ba51f3e431d8da408eac1f41acf7) ) +ROM_END + +COMP( 1981, aaa, 0, 0, terminals, terminals, terminals_state, 0, "Ann Arbor", "Ambassador", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Hewlett-Packard HP-700/92. +Chips: TC5564APL-15, proprietory square chip, D70108C (V20), SCN2681, Beeper +Crystals: 29.4912 + +***************************************************************************************************************/ + +ROM_START( hp700_92 ) + ROM_REGION(0x20000, "maincpu", 0) + ROM_LOAD( "5181-8672.u803", 0x00000, 0x20000, CRC(21440d2f) SHA1(69a3de064ae2b18adc46c2fdd0bf69620375efe7) ) +ROM_END + +COMP( 1987, hp700_92, 0, 0, terminals, terminals, terminals_state, 0, "HP", "HP-700/92", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Hewlett-Packard HP-2622A. +Chips: National 8367 CRTC (labeled B8250), SY6551 (labeled 8251), Z8400A (Z80) +Crystal: 25.7715 + +***************************************************************************************************************/ + +ROM_START( hp2622a ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "1818-1685.xu63", 0x0000, 0x2000, CRC(a57ffe5e) SHA1(4d7844320deba916d9ec289927af987fea025b02) ) + ROM_LOAD( "1818-1686.xu64", 0x2000, 0x2000, CRC(bee9274c) SHA1(20796c559031a91cb2666776fcf7ffdb52a0a318) ) + ROM_LOAD( "1818-1687.xu65", 0x4000, 0x2000, CRC(e9ecd489) SHA1(9b249b8d066d256069ccdb8809bb808c414f106a) ) + + ROM_REGION(0x2000, "chargen", 0) + ROM_LOAD( "1818-1489.xu311", 0x0000, 0x2000, CRC(9879b153) SHA1(fc1705d6de38eb6d3a67f1ae439e359e5124d028) ) +ROM_END + +COMP( 1982, hp2622a, 0, 0, terminals, terminals, terminals_state, 0, "HP", "HP-2622A", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Qume QVT-70. +Chips: Z80, Z80 DART, 5x CXK5864CM-70LL/W242575-70LL, 801000-02, 303489-01, DS1231, Button battery, Beeper +Crystals: unreadable + +***************************************************************************************************************/ + +ROM_START( qvt70 ) + ROM_REGION(0x30000, "maincpu", 0) + ROM_LOAD( "251513-04_revj.u12", 0x00000, 0x10000, CRC(3960bbd5) SHA1(9db306cef09be21ff43c081ebe11e9b46f617861) ) + ROM_LOAD( "251513-03_revj.u11", 0x10000, 0x20000, CRC(c56796fe) SHA1(afe024ff93d5e75dc18041219d61e1a22fc6d883) ) +ROM_END + +COMP( 1992, qvt70, 0, 0, terminals, terminals, terminals_state, 0, "Qume", "QVT-70", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Qume QVT-102. +Chips: HD46800DP (6800), HD46505SP (6845), HD46850P (6850), M58725P-15 (16k RAM), LH0082 (Z80CTC), Button battery +Crystals: 16.6698 +Keyboard: D8748D, 6.000, Beeper + +***************************************************************************************************************/ + +ROM_START( qvt102 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "t205m.u8", 0x0000, 0x2000, CRC(59cc04f6) SHA1(ee2e3a3ea7b57a231483fcc74266f0f3f51204af) ) + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "c3205m.u32", 0x0000, 0x1000, CRC(f6d86e87) SHA1(c0885e4a35095a730d760bf91a1cf4e8edd6a2bb) ) + + ROM_REGION(0x10000, "keyboard", 0) + ROM_LOAD( "k301.u302", 0x0000, 0x0400, CRC(67564b20) SHA1(5897ff920f8fae4aa498d3a4dfd45b58183c041d) ) +ROM_END + +COMP( 1983, qvt102, 0, 0, terminals, terminals, terminals_state, 0, "Qume", "QVT-102", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Qume QVT-103. +Chips: Z80A, Z80A DART, Z80A CTC, 2x CRT9212, 5x HM6116P-2, TC5516APL, D8741AD, CRT9007, 1x 10-sw dip, Button battery. +Crystals: (all hard to read) 29.876, 6.000 +Keyboard CPU, Crystal, ROM are on the main board. + +***************************************************************************************************************/ + +ROM_START( qvt103 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "t103e1.u28", 0x0000, 0x2000, CRC(eace3cbe) SHA1(1e7f395c5233d8656df5305163d050275f0a8033) ) + ROM_LOAD( "t103e2.u27", 0x2000, 0x4000, CRC(100cf542) SHA1(4b2569d509790a0f94b4447fb9d3d42582fcaf66) ) + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "c103b.u40", 0x0000, 0x1000, CRC(3419760d) SHA1(3455c70ed48c7f7769d73a84f152beddf508094f) ) + + ROM_REGION(0x10000, "keyboard", 0) + ROM_LOAD( "k304a.u24", 0x0000, 0x0400, CRC(e4b1f0da) SHA1(e9f8c48c34105464b3db206b34f67e7603484fea) ) +ROM_END + +COMP( 1983, qvt103, 0, 0, terminals, terminals, terminals_state, 0, "Qume", "QVT-103", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Qume QVT-190. +Chips: MC68B00P, 2x MC68B50P, MC68B45P, V61C16P55L, M5M5165P-70L, ABHGA101006, button battery, 7-DIL-jumper +Crystal: unreadable + +***************************************************************************************************************/ + +ROM_START( qvt190 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "95987-267.u19", 0x0000, 0x8000, CRC(78894d8e) SHA1(0a0f6883dd18872bddeb3ed18ebe496080e6591b) ) + + ROM_REGION(0x2000, "chargen", 0) + ROM_LOAD( "95864-304.u17", 0x0000, 0x2000, CRC(2792e99b) SHA1(4a84d029d0e63975fc95dc7056d2523193dff986) ) +ROM_END + +COMP( 1987, qvt190, 0, 0, terminals, terminals, terminals_state, 0, "Qume", "QVT-190", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Qume QVT-201. +Chips: Z80A, SCN2681A, SCN2672B, 4x HM6116P-2, D446C-2, button battery +Crystals: (from schematics, unreadable on photo) 48.654 MHz (Y1), 3.6864 MHz (Y2) +Board is marked QVT-202. + +***************************************************************************************************************/ + +ROM_START( qvt201 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "390410-002.u11", 0x0000, 0x4000, CRC(69337561) SHA1(022e49bf5e8d76a3c2cc5af65630d3f77cc32bc1) ) + ROM_LOAD( "390410-001.u10", 0x4000, 0x4000, CRC(977cc138) SHA1(a019980ea6da2dce53617bced420014ab4e03ec8) ) + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "301847-01.u42", 0x0000, 0x1000, CRC(546ed236) SHA1(312d57a7012f50327310bd11bda000149f13342e) ) +ROM_END + +COMP( 1986, qvt201, 0, 0, terminals, terminals, terminals_state, 0, "Qume", "QVT-201", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Relisys TR175 II. +Chips: MC68000P12, HM82C11C, SCN2681, 3x W24257-70L, KDA0476BCN-66 (RAMDAC), 4 undumped proms, Beeper, Button battery +Crystals: 28.322, 46.448, 11.0592, unknown. +Colour screen. + +***************************************************************************************************************/ + +ROM_START( tr175 ) + ROM_REGION(0x20000, "maincpu", 0) + ROM_LOAD16_BYTE( "v6.05.u50", 0x00000, 0x10000, CRC(5a33b6b3) SHA1(d673f50dd88f8a154ddaabe34cfcc9ab91435a4c) ) + ROM_LOAD16_BYTE( "v6.05.u45", 0x00001, 0x10000, CRC(e220befe) SHA1(8402280577e6de4b85843222bbd6b06a3f625b3b) ) +ROM_END + +COMP( 1982, tr175, 0, 0, terminals, terminals, terminals_state, 0, "Relisys", "TR175II", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Televideo TVI-912C. +Chips: i8035, TMS9927NL, AY5-1013A (COM2502) +Crystals: 23.814 (divide by 4 for CPU clock) +Other: 1x 8-sw DIP, 1x 10-sw DIP (internal), 2x 10-sw DIP (available to user at the back) + +***************************************************************************************************************/ + +ROM_START( tv912c ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "a49c1.bin", 0x0000, 0x1000, CRC(d21851bf) SHA1(28fe77a218a5eee11de376f5d16e9380b616b3ca) ) // last half is all FF + + ROM_REGION(0x0800, "chargen", 0) + ROM_LOAD( "a3-2.bin", 0x0000, 0x0800, CRC(bb9a7fbd) SHA1(5f1c4d41b25bd3ca4dbc336873362935daf283da) ) +ROM_END + +COMP( 1978, tv912c, 0, 0, terminals, terminals, terminals_state, 0, "TeleVideo", "TVI-912C", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Televideo TVI-955 +Chips: G65SC02P-3, 3x S6551AP, SCN2674B, AMI 131406-00 (unknown 40-pin DIL), odd round silver thing, might be a battery +Crystals: 19.3396, 31.684, 3.6864 +Keyboard: M5L8049-230P-6, 5.7143, Beeper + +***************************************************************************************************************/ + +ROM_START( tv955 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "t180002-88d_955.u4", 0x0000, 0x4000, CRC(5767fbe7) SHA1(49a2241612af5c3af09778ffa541ac0bc186e05a) ) + ROM_LOAD( "t180002-91a_calc.u5", 0x4000, 0x2000, CRC(f86c103a) SHA1(fa3ada3a5d8913e519e2ea4817e96166c1fedd32) ) // first half is all FF + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "t180002-26b.u45", 0x0000, 0x1000, CRC(69c9ebc7) SHA1(32282c816ec597a7c45e939acb7a4155d35ea584) ) + + ROM_REGION(0x10000, "keyboard", 0) + ROM_LOAD( "8049.kbd", 0x0000, 0x0800, CRC(bc86e349) SHA1(0b62003ab7931822f1bcac8370517c685849f62c) ) +ROM_END + +COMP( 1985, tv955, 0, 0, terminals, terminals, terminals_state, 0, "TeleVideo", "TVI-955", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Televideo TVI-965 +Chips: G65SC816P-5, SCN2672TC5N40, 271582-00 (unknown square chip), 2x UM6551A, Beeper +Crystals: 44.4528, 26.9892, 3.6864 + +***************************************************************************************************************/ + +ROM_START( tv965 ) + ROM_REGION(0x20000, "maincpu", 0) + ROM_LOAD( "180003-30h.u8", 0x00000, 0x010000, CRC(c7b9ca39) SHA1(1d95a8b0a4ea5caf3fb628c44c7a3567700a0b59) ) + ROM_LOAD( "180003-38h.u9", 0x10000, 0x008000, CRC(30fae408) SHA1(f05bb2a9ce2df60b046733f746d8d8a1eb3ac8bc) ) +ROM_END + +COMP( 1989, tv965, 0, 0, terminals, terminals, terminals_state, 0, "TeleVideo", "TVI-965", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Visual 100. (VT-100 clone) +Chips: D780C-1 (Z80), CRT5037, D8255AC-5, uPB8214C, COM8116T-020, D8251AC, ER1400, 8-sw dip +Crystal: 47.736 + +***************************************************************************************************************/ + +ROM_START( v100 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "262-047.u108", 0x0000, 0x1000, CRC(e82f708c) SHA1(20ed83a41fd0703d72a20e170af971181cfbd575) ) + ROM_LOAD( "262-048.u110", 0x1000, 0x1000, CRC(830923d3) SHA1(108590234ff84b5856cc2784d738a2a625305953) ) + + ROM_REGION(0x0800, "chargen", 0) + ROM_LOAD( "241-001.u29", 0x0000, 0x0800, CRC(ef807141) SHA1(cbf3fed001811c5840b9a131d2d3133843cb3b6a) ) +ROM_END + +COMP( 1982, v100, 0, 0, terminals, terminals, terminals_state, 0, "Visual Technology", "Visual 100", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Visual 102. (VT-102 clone plus graphics) +Chips: D780C-1 (Z80), CRT9021B-018, COM8251A, D8255AC-5, 2x CRT9006-135, CRT9007, M5L8253P-5, X2804AP-35, D7201C +Crystals: 18.575000 +Keyboard: TMP8039P-6 + +***************************************************************************************************************/ + +ROM_START( v102 ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "245-001.u1", 0x0000, 0x4000, CRC(c36cc525) SHA1(a45e75ded10979c8e3ad262e2cf5818e08db762c) ) + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "260-001.u50", 0x0000, 0x1000, CRC(732f5b99) SHA1(d105bf9f3ed41109d7181bcf0223bb280afe3f0a) ) + + ROM_REGION(0x10000, "keyboard", 0) + ROM_LOAD( "150.kbd", 0x0000, 0x0800, CRC(afe55cff) SHA1(b26ebdde63ec0e94c08780285def39a282e128b3) ) +ROM_END + +COMP( 1984, v102, 0, 0, terminals, terminals, terminals_state, 0, "Visual Technology", "Visual 102", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +DEC VT420. +Chips: SCN8031HFCN40, SCN2681TC1N40, M5M4464AP, HM62256LFP-10T, TC23SC070AT, TC531001CP-1815 +Crystals: 43.320 + +***************************************************************************************************************/ + +ROM_START( vt420 ) + ROM_REGION(0x20000, "maincpu", 0) + ROM_LOAD( "23-068e9-00.e2", 0x00000, 0x20000, CRC(22c3f93b) SHA1(b212911c41e4dba2e09d91fdd1f72d6c7536b0af) ) +ROM_END + +COMP( 1990, vt420, 0, 0, terminals, terminals, terminals_state, 0, "DEC", "VT-420", MACHINE_IS_SKELETON ) + + + +/************************************************************************************************************** + +Zentec Zephyr (Model 00-441-01). +Chips: COM2017, i8085A, 2x unreadable (40-pin AMI DIP), Beeper +Crystal: 45.582000 + +***************************************************************************************************************/ + +ROM_START( zephyr ) + ROM_REGION(0x10000, "maincpu", 0) + ROM_LOAD( "23-006-32c.bin", 0x0000, 0x0800, CRC(0a3a5447) SHA1(a8c25730a1d7e5b9c86e0d504afc923e931f9025) ) + ROM_LOAD( "23-067-004b.bin", 0x0800, 0x0800, CRC(37741104) SHA1(52b9998e0a8d4949e0dc7c3349b3681e13345061) ) + ROM_LOAD( "23-067-03b.bin", 0x1000, 0x0800, CRC(29cfa003) SHA1(9de7a8402173a2c448e54ee433ba3050db7b70bb) ) // this doesn't seem to fit + + ROM_REGION(0x0800, "chargen", 0) + ROM_LOAD( "23-066-02a.bin", 0x0000, 0x0800, CRC(d5650b6c) SHA1(e6333e59018d9904f12abb270db4ba28aeff1995) ) +ROM_END + +COMP( 1979, zephyr, 0, 0, terminals, terminals, terminals_state, 0, "Zentec", "Zephyr", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/thomson.cpp b/src/mame/drivers/thomson.cpp index 7864b3a1d8c..8b5e9086f6d 100644 --- a/src/mame/drivers/thomson.cpp +++ b/src/mame/drivers/thomson.cpp @@ -626,6 +626,12 @@ static MACHINE_CONFIG_START( to7 ) MCFG_CPU_ADD ( "maincpu", M6809, 1000000 ) MCFG_CPU_PROGRAM_MAP ( to7) + MCFG_INPUT_MERGER_ANY_HIGH("mainirq") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", M6809_IRQ_LINE)) + + MCFG_INPUT_MERGER_ANY_HIGH("mainfirq") + MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", M6809_FIRQ_LINE)) + /* video */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE ( /*50*/ 1./0.019968 ) @@ -664,7 +670,7 @@ static MACHINE_CONFIG_START( to7 ) MCFG_MC6846_OUT_CP2_CB(DEVWRITELINE("buzzer", dac_bit_interface, write)) MCFG_MC6846_IN_PORT_CB(READ8(thomson_state, to7_timer_port_in)) MCFG_MC6846_OUT_CTO_CB(WRITELINE(thomson_state, to7_set_cassette)) - MCFG_MC6846_IRQ_CB(WRITELINE(thomson_state, thom_dev_irq_0)) + MCFG_MC6846_IRQ_CB(DEVWRITELINE("mainirq", input_merger_device, in_w<0>)) /* floppy */ MCFG_DEVICE_ADD("mc6843", MC6843, 0) @@ -699,16 +705,16 @@ static MACHINE_CONFIG_START( to7 ) MCFG_PIA_WRITEPB_HANDLER(WRITE8(thomson_state, to7_sys_portb_out)) MCFG_PIA_CA2_HANDLER(WRITELINE(thomson_state, to7_set_cassette_motor)) MCFG_PIA_CB2_HANDLER(WRITELINE(thomson_state, to7_sys_cb2_out)) - MCFG_PIA_IRQA_HANDLER(WRITELINE(thomson_state, thom_firq_1)) - MCFG_PIA_IRQB_HANDLER(WRITELINE(thomson_state, thom_firq_1)) + MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("mainfirq", input_merger_device, in_w<1>)) + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("mainfirq", input_merger_device, in_w<1>)) MCFG_DEVICE_ADD(THOM_PIA_GAME, PIA6821, 0) MCFG_PIA_READPA_HANDLER(READ8(thomson_state, to7_game_porta_in)) MCFG_PIA_READPB_HANDLER(READ8(thomson_state, to7_game_portb_in)) MCFG_PIA_WRITEPB_HANDLER(WRITE8(thomson_state, to7_game_portb_out)) MCFG_PIA_CB2_HANDLER(WRITELINE(thomson_state, to7_game_cb2_out)) - MCFG_PIA_IRQA_HANDLER(WRITELINE(thomson_state, thom_irq_1)) - MCFG_PIA_IRQB_HANDLER(WRITELINE(thomson_state, thom_irq_1)) + MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("mainirq", input_merger_device, in_w<1>)) + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("mainirq", input_merger_device, in_w<1>)) /* TODO: CONVERT THIS TO A SLOT DEVICE (RF 57-932) */ MCFG_DEVICE_ADD("acia", MOS6551, 0) @@ -1130,7 +1136,7 @@ static MACHINE_CONFIG_DERIVED( mo5, to7 ) MCFG_PIA_WRITEPB_HANDLER(DEVWRITE8("buzzer", dac_bit_interface, write)) MCFG_PIA_CA2_HANDLER(WRITELINE(thomson_state, mo5_set_cassette_motor)) MCFG_PIA_CB2_HANDLER(NOOP) - MCFG_PIA_IRQB_HANDLER(WRITELINE(thomson_state, thom_irq_1)) /* WARNING: differs from TO7 ! */ + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("mainirq", input_merger_device, in_w<1>)) // WARNING: differs from TO7 ! MCFG_DEVICE_REMOVE("cartslot") MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "mo_cart") @@ -1866,7 +1872,7 @@ static MACHINE_CONFIG_DERIVED( to9p, to7 ) MCFG_PIA_WRITEPB_HANDLER(WRITE8(thomson_state, to8_sys_portb_out)) MCFG_PIA_CB2_HANDLER(NOOP) MCFG_PIA_IRQA_HANDLER(NOOP) - MCFG_PIA_IRQB_HANDLER(WRITELINE(thomson_state, thom_firq_1)) + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("mainfirq", input_merger_device, in_w<1>)) MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(thomson_state, write_centronics_busy)) @@ -2221,7 +2227,7 @@ static MACHINE_CONFIG_DERIVED( mo6, to7 ) MCFG_PIA_WRITEPB_HANDLER(DEVWRITE8("buzzer", dac_bit_interface, write)) MCFG_PIA_CA2_HANDLER(WRITELINE(thomson_state, mo5_set_cassette_motor)) MCFG_PIA_CB2_HANDLER(WRITELINE(thomson_state, mo6_sys_cb2_out)) - MCFG_PIA_IRQB_HANDLER(WRITELINE(thomson_state, thom_irq_1)) /* differs from TO */ + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("mainirq", input_merger_device, in_w<1>)) // differs from TO MCFG_DEVICE_MODIFY(THOM_PIA_GAME) MCFG_PIA_WRITEPA_HANDLER(WRITE8(thomson_state, mo6_game_porta_out)) @@ -2490,7 +2496,7 @@ static MACHINE_CONFIG_DERIVED( mo5nr, to7 ) MCFG_PIA_WRITEPB_HANDLER(DEVWRITE8("buzzer", dac_bit_interface, write)) MCFG_PIA_CA2_HANDLER(WRITELINE(thomson_state, mo5_set_cassette_motor)) MCFG_PIA_CB2_HANDLER(WRITELINE(thomson_state, mo6_sys_cb2_out)) - MCFG_PIA_IRQB_HANDLER(WRITELINE(thomson_state, thom_irq_1)) /* differs from TO */ + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("mainirq", input_merger_device, in_w<1>)) // differs from TO MCFG_DEVICE_MODIFY(THOM_PIA_GAME) MCFG_PIA_WRITEPA_HANDLER(WRITE8(thomson_state, mo6_game_porta_out)) diff --git a/src/mame/drivers/thunderx.cpp b/src/mame/drivers/thunderx.cpp index a24fafb78b0..e82af57c369 100644 --- a/src/mame/drivers/thunderx.cpp +++ b/src/mame/drivers/thunderx.cpp @@ -643,8 +643,8 @@ static MACHINE_CONFIG_START( scontra ) MCFG_DEVICE_ADD("bank5800", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(scontra_bank5800_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(12) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(12) MCFG_ADDRESS_MAP_BANK_STRIDE(0x0800) MCFG_WATCHDOG_ADD("watchdog") @@ -705,7 +705,7 @@ static MACHINE_CONFIG_DERIVED( thunderx, scontra ) MCFG_DEVICE_MODIFY("bank5800") MCFG_DEVICE_PROGRAM_MAP(thunderx_bank5800_map) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_DEVICE_REMOVE("k007232") MACHINE_CONFIG_END diff --git a/src/mame/drivers/ti74.cpp b/src/mame/drivers/ti74.cpp index 0d8e3be42f3..180ef4d8f0a 100644 --- a/src/mame/drivers/ti74.cpp +++ b/src/mame/drivers/ti74.cpp @@ -271,12 +271,6 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, ti74_state ) AM_RANGE(0xc000, 0xdfff) AM_ROMBANK("sysbank") ADDRESS_MAP_END -static ADDRESS_MAP_START( main_io_map, AS_IO, 8, ti74_state ) - AM_RANGE(TMS7000_PORTA, TMS7000_PORTA) AM_READ(keyboard_r) - AM_RANGE(TMS7000_PORTB, TMS7000_PORTB) AM_WRITE(bankswitch_w) - AM_RANGE(TMS7000_PORTE, TMS7000_PORTE) AM_WRITE(keyboard_w) AM_READNOP -ADDRESS_MAP_END - /*************************************************************************** @@ -514,7 +508,9 @@ static MACHINE_CONFIG_START( ti74 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", TMS70C46, XTAL_4MHz) MCFG_CPU_PROGRAM_MAP(main_map) - MCFG_CPU_IO_MAP(main_io_map) + MCFG_TMS7000_IN_PORTA_CB(READ8(ti74_state, keyboard_r)) + MCFG_TMS7000_OUT_PORTB_CB(WRITE8(ti74_state, bankswitch_w)) + MCFG_TMS7000_OUT_PORTE_CB(WRITE8(ti74_state, keyboard_w)) MCFG_NVRAM_ADD_0FILL("sysram.ic3") @@ -548,7 +544,9 @@ static MACHINE_CONFIG_START( ti95 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", TMS70C46, XTAL_4MHz) MCFG_CPU_PROGRAM_MAP(main_map) - MCFG_CPU_IO_MAP(main_io_map) + MCFG_TMS7000_IN_PORTA_CB(READ8(ti74_state, keyboard_r)) + MCFG_TMS7000_OUT_PORTB_CB(WRITE8(ti74_state, bankswitch_w)) + MCFG_TMS7000_OUT_PORTE_CB(WRITE8(ti74_state, keyboard_w)) MCFG_NVRAM_ADD_0FILL("sysram.ic3") diff --git a/src/mame/drivers/ti85.cpp b/src/mame/drivers/ti85.cpp index 840c65baab6..5599e2a7c44 100644 --- a/src/mame/drivers/ti85.cpp +++ b/src/mame/drivers/ti85.cpp @@ -683,25 +683,25 @@ static MACHINE_CONFIG_DERIVED( ti83p, ti81 ) MCFG_DEVICE_ADD("membank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(ti83p_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("membank2", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(ti83p_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("membank3", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(ti83p_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("membank4", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(ti83p_banked_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_DEVICE_ADD("t6a04", T6A04, 0) diff --git a/src/mame/drivers/tickee.cpp b/src/mame/drivers/tickee.cpp index 6686a4c1457..b4c4a60ed92 100644 --- a/src/mame/drivers/tickee.cpp +++ b/src/mame/drivers/tickee.cpp @@ -303,14 +303,14 @@ READ16_MEMBER(tickee_state::rapidfir_transparent_r) TMS340X0_TO_SHIFTREG_CB_MEMBER(tickee_state::rapidfir_to_shiftreg) { if (address < 0x800000) - memcpy(shiftreg, &m_vram[TOWORD(address)], TOBYTE(0x2000)); + memcpy(shiftreg, &m_vram[address >> 4], 0x400); } TMS340X0_FROM_SHIFTREG_CB_MEMBER(tickee_state::rapidfir_from_shiftreg) { if (address < 0x800000) - memcpy(&m_vram[TOWORD(address)], shiftreg, TOBYTE(0x2000)); + memcpy(&m_vram[address >> 4], shiftreg, 0x400); } diff --git a/src/mame/drivers/tim100.cpp b/src/mame/drivers/tim100.cpp index e42f4cdb297..49449025898 100644 --- a/src/mame/drivers/tim100.cpp +++ b/src/mame/drivers/tim100.cpp @@ -10,7 +10,6 @@ Mihajlo Pupin Institute Notes: - Serial terminals appear to need 8 bits, 2 stop bits, odd parity @ 9600 -- Unable to set these settings as default, because std::bad_cast fatal error occurs at start - Unable to type anything as it seems uarts want BRKDET activated all the time, which we cannot do. - Unable to find any technical info at all, so it's all guesswork. diff --git a/src/mame/drivers/tk2000.cpp b/src/mame/drivers/tk2000.cpp index 4e8771a862a..23a9b75be20 100644 --- a/src/mame/drivers/tk2000.cpp +++ b/src/mame/drivers/tk2000.cpp @@ -591,7 +591,7 @@ static MACHINE_CONFIG_START( tk2000 ) MCFG_DEVICE_ADD(A2_UPPERBANK_TAG, ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(inhbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MCFG_RAM_ADD(RAM_TAG) diff --git a/src/mame/drivers/tmaster.cpp b/src/mame/drivers/tmaster.cpp index 260e822c0dd..742964de8c9 100644 --- a/src/mame/drivers/tmaster.cpp +++ b/src/mame/drivers/tmaster.cpp @@ -364,7 +364,7 @@ static MACHINE_CONFIG_START( tm ) MCFG_CPU_PROGRAM_MAP(tmaster_map) MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", tmaster_state, scanline_interrupt, "screen", 0, 1) - MCFG_MC68681_ADD( "duart68681", XTAL_8_664MHz / 2 /*??*/) + MCFG_DEVICE_ADD( "duart68681", MC68681, XTAL_8_664MHz / 2 /*??*/) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(tmaster_state, duart_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("microtouch", microtouch_device, rx)) diff --git a/src/mame/drivers/tmc600.cpp b/src/mame/drivers/tmc600.cpp index 5ab8ae1df32..9ab3a7b32b9 100644 --- a/src/mame/drivers/tmc600.cpp +++ b/src/mame/drivers/tmc600.cpp @@ -50,30 +50,30 @@ Notes: CN2 - 10x2 pin printer connector [TMC-700] CN3 - 32x3 pin EURO connector CN4 - DIN5D tape connector - 1 input (500 mV / 47 kohm) + 1 input (500 mV / 47 Kohm) 2 GND - 3 output (580 mV / 47 kohm) - 4 input (500 mV / 47 kohm) - 5 output (580 mV / 47 kohm) + 3 output (580 mV / 47 Kohm) + 4 input (500 mV / 47 Kohm) + 5 output (580 mV / 47 Kohm) CN5 - DIN5X video connector 1 GND 2 GND - 3 ? + 3 composite video output (75 ohm) 4 GND - 5 ? + 5 composite video output (75 ohm) CN6 - DIN2 power connector - 1 8..12V DC..400Hz 300mA + 1 input 8..12V DC..400Hz 300mA 2 GND CN7 - DIN5D audio connector [TMCP-300] - 1 NC + 1 N/C 2 GND - 3 AUDIO - 4 NC - 5 AUDIO + 3 mono audio output + 4 N/C + 5 mono audio output CN8 - 10x2 pin keyboard connector - SW1 - RUN/STOP switch + SW1 - RUN/STOP switch (left=run, right=stop) SW2 - internal speaker/external audio switch [TMCP-300] - P1 - color phase lock adjustment + P1 - color phase lock adjustment potentiometer C1 - dot oscillator adjustment variable capacitor C2 - chroma oscillator adjustment variable capacitor T1 - RF signal strength adjustment potentiometer [TMC-700] @@ -88,38 +88,50 @@ Notes: /* - TODO: + TODO - - proper emulation of the VISMAC interface (cursor blinking, color RAM), schematics are needed - - disk interface - - serial interface expansion card - - centronics printer handshaking + - connect expansion bus */ #include "emu.h" #include "includes/tmc600.h" -/* Read/Write Handlers */ +READ8_MEMBER( tmc600_state::rtc_r ) +{ + m_rtc_int = m_vismac_reg_latch >> 3; + + return 0; +} -WRITE8_MEMBER( tmc600_state::keyboard_latch_w ) +WRITE8_MEMBER( tmc600_state::printer_w ) { - m_keylatch = data; + m_centronics->write_data0(BIT(data, 0)); + m_centronics->write_data1(BIT(data, 1)); + m_centronics->write_data2(BIT(data, 2)); + m_centronics->write_data3(BIT(data, 3)); + m_centronics->write_data4(BIT(data, 4)); + m_centronics->write_data5(BIT(data, 5)); + m_centronics->write_data6(BIT(data, 6)); + m_centronics->write_data7(BIT(data, 7)); + + m_centronics->write_strobe(0); + m_centronics->write_strobe(1); } /* Memory Maps */ static ADDRESS_MAP_START( tmc600_map, AS_PROGRAM, 8, tmc600_state ) - AM_RANGE(0x0000, 0x4fff) AM_ROM - AM_RANGE(0x6000, 0xbfff) AM_RAM + AM_RANGE(0x0000, 0x5fff) AM_ROM + AM_RANGE(0x6000, 0x7fff) AM_RAM AM_RANGE(0xf400, 0xf7ff) AM_DEVICE(CDP1869_TAG, cdp1869_device, char_map) AM_RANGE(0xf800, 0xffff) AM_DEVICE(CDP1869_TAG, cdp1869_device, page_map) ADDRESS_MAP_END static ADDRESS_MAP_START( tmc600_io_map, AS_IO, 8, tmc600_state ) - AM_RANGE(0x03, 0x03) AM_WRITE(keyboard_latch_w) - AM_RANGE(0x04, 0x04) AM_DEVWRITE("cent_data_out", output_latch_device, write) - AM_RANGE(0x05, 0x05) AM_WRITE(vismac_data_w) + AM_RANGE(0x03, 0x03) AM_DEVWRITE(CDP1852_KB_TAG, cdp1852_device, write) + AM_RANGE(0x04, 0x04) AM_DEVWRITE(CDP1852_TMC700_TAG, cdp1852_device, write) + AM_RANGE(0x05, 0x05) AM_READWRITE(rtc_r, vismac_data_w) // AM_RANGE(0x06, 0x06) AM_WRITE(floppy_w) AM_RANGE(0x07, 0x07) AM_WRITE(vismac_register_w) ADDRESS_MAP_END @@ -208,16 +220,11 @@ static INPUT_PORTS_START( tmc600 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) PORT_START("RUN") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Run/Stop") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_TOGGLE + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("Run/Stop") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_TOGGLE PORT_WRITE_LINE_DEVICE_MEMBER(CDP1802_TAG, cosmac_device, clear_w) INPUT_PORTS_END /* CDP1802 Interface */ -READ_LINE_MEMBER( tmc600_state::clear_r ) -{ - return BIT(m_run->read(), 0); -} - READ_LINE_MEMBER( tmc600_state::ef2_r ) { return m_cassette->input() < 0; @@ -225,9 +232,9 @@ READ_LINE_MEMBER( tmc600_state::ef2_r ) READ_LINE_MEMBER( tmc600_state::ef3_r ) { - uint8_t data = ~m_key_row[m_keylatch / 8]->read(); + uint8_t keylatch = m_bwio->do_r(); - return BIT(data, m_keylatch % 8); + return !BIT(m_key_row[(keylatch >> 3) & 0x07]->read(), keylatch & 0x07); } WRITE_LINE_MEMBER( tmc600_state::q_w ) @@ -235,81 +242,89 @@ WRITE_LINE_MEMBER( tmc600_state::q_w ) m_cassette->output(state ? +1.0 : -1.0); } -/* Machine Initialization */ - -void tmc600_state::machine_start() +WRITE8_MEMBER( tmc600_state::sc_w ) { - address_space &program = m_maincpu->space(AS_PROGRAM); - - /* configure RAM */ - switch (m_ram->size()) - { - case 8*1024: - program.unmap_readwrite(0x8000, 0xbfff); - break; - - case 16*1024: - program.unmap_readwrite(0xa000, 0xbfff); - break; + if (data == COSMAC_STATE_CODE_S3_INTERRUPT) { + m_maincpu->int_w(CLEAR_LINE); } - - /* register for state saving */ - save_item(NAME(m_keylatch)); } /* Machine Drivers */ static MACHINE_CONFIG_START( tmc600 ) - // basic system hardware + // CPU MCFG_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_3_57MHz) MCFG_CPU_PROGRAM_MAP(tmc600_map) MCFG_CPU_IO_MAP(tmc600_io_map) MCFG_COSMAC_WAIT_CALLBACK(VCC) - MCFG_COSMAC_CLEAR_CALLBACK(READLINE(tmc600_state, clear_r)) MCFG_COSMAC_EF2_CALLBACK(READLINE(tmc600_state, ef2_r)) MCFG_COSMAC_EF3_CALLBACK(READLINE(tmc600_state, ef3_r)) MCFG_COSMAC_Q_CALLBACK(WRITELINE(tmc600_state, q_w)) + MCFG_COSMAC_SC_CALLBACK(WRITE8(tmc600_state, sc_w)) // sound and video hardware MCFG_FRAGMENT_ADD(tmc600_video) - /* devices */ - MCFG_CENTRONICS_ADD(CENTRONICS_TAG, centronics_devices, "printer") + // keyboard output latch + MCFG_DEVICE_ADD(CDP1852_KB_TAG, CDP1852, XTAL_3_57MHz/8) // clock is CDP1802 TPB + MCFG_CDP1852_MODE_CALLBACK(VCC) + + // address bus demux for expansion bus + MCFG_DEVICE_ADD(CDP1852_BUS_TAG, CDP1852, 0) // clock is expansion bus TPA + MCFG_CDP1852_MODE_CALLBACK(GND) - MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", CENTRONICS_TAG) + // printer output latch + MCFG_DEVICE_ADD(CDP1852_TMC700_TAG, CDP1852, XTAL_3_57MHz/8) // clock is CDP1802 TPB + MCFG_CDP1852_MODE_CALLBACK(VCC) + MCFG_CDP1852_DO_CALLBACK(WRITE8(tmc600_state, printer_w)) + // printer connector + MCFG_CENTRONICS_ADD(CENTRONICS_TAG, centronics_devices, nullptr) + MCFG_CENTRONICS_BUSY_HANDLER(DEVWRITELINE(CDP1802_TAG, cosmac_device, ef4_w)) MCFG_DEVCB_XOR(1) + + // cassette MCFG_CASSETTE_ADD("cassette") MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED) - /* internal ram */ + // expansion bus connector + MCFG_TMC600_EURO_BUS_SLOT_ADD(TMC600_EURO_BUS_TAG, tmc600_euro_bus_cards, nullptr) + + // internal RAM MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("8K") - MCFG_RAM_EXTRA_OPTIONS("16K,24K") MACHINE_CONFIG_END /* ROMs */ #if 0 ROM_START( tmc600s1 ) - ROM_REGION( 0x5000, CDP1802_TAG, 0 ) + ROM_REGION( 0x6000, CDP1802_TAG, 0 ) ROM_LOAD( "sb20", 0x0000, 0x1000, NO_DUMP ) ROM_LOAD( "sb21", 0x1000, 0x1000, NO_DUMP ) ROM_LOAD( "sb22", 0x2000, 0x1000, NO_DUMP ) ROM_LOAD( "sb23", 0x3000, 0x1000, NO_DUMP ) - ROM_LOAD( "190482_2", 0x4000, 0x1000, NO_DUMP ) + ROM_SYSTEM_BIOS( 0, "sb040282", "SB040282" ) + ROMX_LOAD( "190482", 0x4000, 0x1000, NO_DUMP, ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "sbdos", "SBDOS" ) + ROMX_LOAD( "190482_", 0x4000, 0x1000, NO_DUMP, ROM_BIOS(2) ) + ROMX_LOAD( "190482_v", 0x5000, 0x1000, NO_DUMP, ROM_BIOS(2) ) ROM_REGION( 0x1000, "chargen", 0 ) - ROM_LOAD( "chargen", 0x0000, 0x1000, NO_DUMP ) + ROM_LOAD( "chargen", 0x0000, 0x1000, CRC(93f92cbf) SHA1(371156fb38fa5319c6fde537ccf14eed94e7adfb) ) ROM_END #endif ROM_START( tmc600s2 ) - ROM_REGION( 0x5000, CDP1802_TAG, 0 ) + ROM_REGION( 0x6000, CDP1802_TAG, 0 ) ROM_LOAD( "sb30", 0x0000, 0x1000, CRC(95d1292a) SHA1(1fa52d59d3005f8ac74a32c2164fdb22947c2748) ) ROM_LOAD( "sb31", 0x1000, 0x1000, CRC(2c8f3d17) SHA1(f14e8adbcddeaeaa29b1e7f3dfa741f4e230f599) ) ROM_LOAD( "sb32", 0x2000, 0x1000, CRC(dd58a128) SHA1(be9bdb0fc5e0cc3dcc7f2fb7ccab69bf5b043803) ) ROM_LOAD( "sb33", 0x3000, 0x1000, CRC(b7d241fa) SHA1(6f3eadf86c4e3aaf93d123e302a18dc4d9db964b) ) - ROM_LOAD( "151182", 0x4000, 0x1000, CRC(c1a8d9d8) SHA1(4552e1f06d0e338ba7b0f1c3a20b8a51c27dafde) ) + ROM_SYSTEM_BIOS( 0, "sb040282", "SB040282" ) + ROMX_LOAD( "151182", 0x4000, 0x1000, CRC(c1a8d9d8) SHA1(4552e1f06d0e338ba7b0f1c3a20b8a51c27dafde), ROM_BIOS(1) ) + ROM_SYSTEM_BIOS( 1, "sbdos", "SBDOS" ) + ROMX_LOAD( "151182_", 0x4000, 0x1000, NO_DUMP, ROM_BIOS(2) ) + ROMX_LOAD( "151182_v", 0x5000, 0x1000, NO_DUMP, ROM_BIOS(2) ) ROM_REGION( 0x1000, "chargen", 0 ) ROM_LOAD( "chargen", 0x0000, 0x1000, CRC(93f92cbf) SHA1(371156fb38fa5319c6fde537ccf14eed94e7adfb) ) diff --git a/src/mame/drivers/tnzs.cpp b/src/mame/drivers/tnzs.cpp index 3d3f5804049..c5a73d241d7 100644 --- a/src/mame/drivers/tnzs.cpp +++ b/src/mame/drivers/tnzs.cpp @@ -875,8 +875,8 @@ MACHINE_CONFIG_START( tnzs_mainbank ) MCFG_DEVICE_ADD("mainbank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(mainbank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(17) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(17) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MACHINE_CONFIG_END diff --git a/src/mame/drivers/toaplan1.cpp b/src/mame/drivers/toaplan1.cpp index e41835300ef..ba0e34bc7aa 100644 --- a/src/mame/drivers/toaplan1.cpp +++ b/src/mame/drivers/toaplan1.cpp @@ -2184,7 +2184,7 @@ static MACHINE_CONFIG_START( outzonecv ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) - MCFG_SCREEN_RAW_PARAMS(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND+16, VBSTART+16) + MCFG_SCREEN_RAW_PARAMS(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART) MCFG_SCREEN_UPDATE_DRIVER(toaplan1_state, screen_update_toaplan1) MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(toaplan1_state, screen_vblank_toaplan1)) MCFG_SCREEN_PALETTE("palette") diff --git a/src/mame/drivers/tosh1000.cpp b/src/mame/drivers/tosh1000.cpp index e3a994fed0c..7130c47de77 100644 --- a/src/mame/drivers/tosh1000.cpp +++ b/src/mame/drivers/tosh1000.cpp @@ -148,8 +148,8 @@ static MACHINE_CONFIG_START( tosh1000 ) MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(tosh1000_romdos) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MCFG_MACHINE_RESET_OVERRIDE(tosh1000_state, tosh1000) diff --git a/src/mame/drivers/trs80.cpp b/src/mame/drivers/trs80.cpp index 3e595bd4d78..7891e4a906e 100644 --- a/src/mame/drivers/trs80.cpp +++ b/src/mame/drivers/trs80.cpp @@ -302,6 +302,27 @@ static ADDRESS_MAP_START( meritum_io, AS_IO, 8, trs80_state ) AM_RANGE(0xff, 0xff) AM_READWRITE(trs80_ff_r, trs80_ff_w) ADDRESS_MAP_END +static ADDRESS_MAP_START( cp500_io, AS_IO, 8, trs80_state ) + ADDRESS_MAP_GLOBAL_MASK(0xff) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0xe0, 0xe3) AM_READWRITE(trs80m4_e0_r, trs80m4_e0_w) + AM_RANGE(0xe4, 0xe4) AM_READWRITE(trs80m4_e4_r, trs80m4_e4_w) + AM_RANGE(0xe8, 0xe8) AM_READWRITE(trs80m4_e8_r, trs80m4_e8_w) + AM_RANGE(0xe9, 0xe9) AM_READ_PORT("E9") AM_WRITE(trs80m4_e9_w) + AM_RANGE(0xea, 0xea) AM_READWRITE(trs80m4_ea_r, trs80m4_ea_w) + AM_RANGE(0xeb, 0xeb) AM_READWRITE(trs80m4_eb_r, trs80m4_eb_w) + AM_RANGE(0xec, 0xef) AM_READWRITE(trs80m4_ec_r, trs80m4_ec_w) + AM_RANGE(0xf0, 0xf0) AM_READ(trs80_wd179x_r) + AM_RANGE(0xf0, 0xf0) AM_DEVWRITE("fdc", fd1793_device, cmd_w) + AM_RANGE(0xf1, 0xf1) AM_DEVREADWRITE("fdc", fd1793_device, track_r, track_w) + AM_RANGE(0xf2, 0xf2) AM_DEVREADWRITE("fdc", fd1793_device, sector_r, sector_w) + AM_RANGE(0xf3, 0xf3) AM_DEVREADWRITE("fdc", fd1793_device, data_r, data_w) + AM_RANGE(0xf4, 0xf4) AM_WRITE(trs80m4_f4_w) + AM_RANGE(0xf4, 0xf7) AM_READ(cp500_a11_flipflop_toggle) + AM_RANGE(0xf8, 0xfb) AM_READWRITE(trs80_printer_r, trs80_printer_w) + AM_RANGE(0xfc, 0xff) AM_READWRITE(trs80m4_ff_r, trs80m4_ff_w) +ADDRESS_MAP_END + /************************************************************************** w/o SHIFT with SHIFT +-------------------------------+ +-------------------------------+ @@ -709,6 +730,13 @@ static MACHINE_CONFIG_DERIVED( meritum, sys80 ) MCFG_GFXDECODE_MODIFY("gfxdecode", meritum) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( cp500, model3 ) + MCFG_CPU_MODIFY( "maincpu" ) + MCFG_CPU_IO_MAP( cp500_io) + + MCFG_MACHINE_RESET_OVERRIDE(trs80_state, cp500 ) +MACHINE_CONFIG_END + /*************************************************************************** Game driver(s) @@ -890,6 +918,17 @@ ROM_START( meritum_net ) ROM_LOAD( "char.bin", 0x0000, 0x1000, CRC(2c09a5a7) SHA1(146891b3ddfc2de95e6a5371536394a657880054)) ROM_END +ROM_START( cp500 ) + ROM_REGION(0x20000, "maincpu", 0) + ROM_LOAD("s_8407_cn62516n_cp500a_prologica_83.ci111", 0x0000, 0x4000, CRC(c2fc1b92) SHA1(0eb07baee80f1ee1f28a609eb63a9245dcb68adb)) + + ROM_REGION(0x20000, "bootrom", 0) + ROM_LOAD("s_8407_cn62516n_cp500a_prologica_83.ci111", 0x0000, 0x4000, CRC(c2fc1b92) SHA1(0eb07baee80f1ee1f28a609eb63a9245dcb68adb)) + + ROM_REGION(0x0800, "chargen", 0) + ROM_LOAD( "100.105.ci36", 0x0000, 0x800, CRC(1765931e) SHA1(49176ceea6cc003efa04fad2f31829b9432fe10f)) +ROM_END + DRIVER_INIT_MEMBER(trs80_state,trs80) { m_mode = 0; @@ -938,3 +977,4 @@ COMP( 1984, ht1080z2, trs80, 0, ht1080z, trs80, trs80_state, trs80l2 COMP( 1985, ht108064, trs80, 0, ht1080z, trs80, trs80_state, trs80, "Hiradastechnika Szovetkezet", "HT-1080Z/64", 0 ) COMP( 1985, meritum, trs80, 0, meritum, trs80, trs80_state, trs80l2, "Mera-Elzab", "Meritum I (Model 2)", 0 ) COMP( 1985, meritum_net, trs80, 0, meritum, trs80, trs80_state, trs80l2, "Mera-Elzab", "Meritum I (Model 2) (network)", 0 ) +COMP( 1982, cp500, trs80, 0, cp500, trs80m3, trs80_state, trs80m4, "Prológica", "CP-500 (PVIII REV.3)", 0 ) diff --git a/src/mame/drivers/trs80dt1.cpp b/src/mame/drivers/trs80dt1.cpp index 99d6ad3ada2..25930b6881e 100644 --- a/src/mame/drivers/trs80dt1.cpp +++ b/src/mame/drivers/trs80dt1.cpp @@ -18,12 +18,10 @@ Core bugs noted: ToDo: - Serial i/o - Centronics printer -- Fix video (it is hooked up as per schematic, but when text is present it - scrolls crazily and flickers). +- Fix video - displays every other line on top & bottom half of the screen - Check that attributes are correctly applied -- When a key is pressed it endlessly autorepeats. - Connect up ports 1 and 3. -- Fix random crashes, especially while in the debugger. +- Fix timing issue with timer interrupt and remove hack You can get into the setup menu by pressing Ctrl+Shift+Enter. @@ -33,6 +31,7 @@ You can get into the setup menu by pressing Ctrl+Shift+Enter. #include "emu.h" #include "cpu/mcs51/mcs51.h" #include "video/i8275.h" +#include "machine/7474.h" #include "machine/x2212.h" #include "sound/beep.h" #include "screen.h" @@ -52,6 +51,7 @@ public: , m_nvram(*this,"nvram") , m_keyboard(*this, "X%u", 0) , m_beep(*this, "beeper") + , m_7474(*this, "7474") { } DECLARE_READ8_MEMBER(dma_r); @@ -59,12 +59,9 @@ public: DECLARE_WRITE8_MEMBER(store_w); DECLARE_WRITE8_MEMBER(port1_w); DECLARE_WRITE8_MEMBER(port3_w); - DECLARE_WRITE_LINE_MEMBER(irq_w); - DECLARE_WRITE_LINE_MEMBER(hrtc_w); I8275_DRAW_CHARACTER_MEMBER(crtc_update_row); private: - bool m_irq_state; bool m_bow; virtual void machine_reset() override; virtual void machine_start() override; @@ -76,13 +73,14 @@ private: required_device<x2210_device> m_nvram; required_ioport_array<10> m_keyboard; required_device<beep_device> m_beep; + required_device<ttl7474_device> m_7474; }; void trs80dt1_state::machine_reset() { - m_irq_state = 0; m_bow = 0; - // line is actually active low in the real chip + m_7474->preset_w(1); + // line is active low in the real chip m_nvram->recall(1); m_nvram->recall(0); } @@ -90,6 +88,17 @@ void trs80dt1_state::machine_reset() READ8_MEMBER( trs80dt1_state::dma_r ) { m_crtc->dack_w(space, 0, m_p_videoram[offset]); // write to /BS pin + // Temporary hack to work around a timing issue + // timer interrupts fires too early and ends the psuedo-dma transfer after only 77 chars + // we send the last three manually until this is fixed + if (offset%80 == 76) { + offset++; + m_crtc->dack_w(space, 0, m_p_videoram[offset]); + offset++; + m_crtc->dack_w(space, 0, m_p_videoram[offset]); + offset++; + m_crtc->dack_w(space, 0, m_p_videoram[offset]); + } return 0x7f; } @@ -102,21 +111,9 @@ READ8_MEMBER( trs80dt1_state::key_r ) return 0xff; } -WRITE_LINE_MEMBER( trs80dt1_state::irq_w ) -{ - if (!state && m_irq_state) - m_maincpu->set_input_line(MCS51_INT1_LINE, CLEAR_LINE); - m_irq_state = state; -} - -WRITE_LINE_MEMBER( trs80dt1_state::hrtc_w ) -{ - m_maincpu->set_input_line(MCS51_INT1_LINE, m_irq_state ? HOLD_LINE : CLEAR_LINE); -} - WRITE8_MEMBER( trs80dt1_state::store_w ) { - // line is actually active low in the real chip + // line is active low in the real chip m_nvram->store(1); m_nvram->store(0); } @@ -166,101 +163,101 @@ ADDRESS_MAP_END /* Input ports */ static INPUT_PORTS_START( trs80dt1 ) PORT_START("X0") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x7f) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(32) - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_CHAR(0x7f) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_CHAR(9) + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(32) + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_START("X1") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("BS") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_START("X2") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':') + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X') + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_START("X3") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') PORT_CHAR('\\') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('\"') + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C') + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') PORT_CHAR('\\') + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_START("X4") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3') PORT_CHAR('~') - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Enter") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V') + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_CHAR('3') PORT_CHAR('~') + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_START("X5") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_END) PORT_CHAR(3) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_END) PORT_CHAR(3) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_CHAR(27) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B') + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL_PAD) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_START("X6") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Clear") PORT_CODE(KEYCODE_HOME) - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Linefeed") PORT_CODE(KEYCODE_INSERT) - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Clear") PORT_CODE(KEYCODE_HOME) + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Linefeed") PORT_CODE(KEYCODE_INSERT) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N') + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("X7") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('}') PORT_CHAR(']') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('}') PORT_CHAR(']') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M') + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("X8") - PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') - PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('{') PORT_CHAR('[') - PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') - PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') - PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNUSED) - PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('{') PORT_CHAR('[') + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P') + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_START("X9") PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_CODE(KEYCODE_LSHIFT) PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RCONTROL) PORT_CODE(KEYCODE_LCONTROL) PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE - PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED) - PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_UNUSED) // Jumper - LOW for 60Hz, high for 50Hz + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_UNUSED) // No Connect PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_UNUSED) PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED) @@ -320,7 +317,7 @@ static MACHINE_CONFIG_START( trs80dt1 ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_UPDATE_DEVICE("crtc", i8275_device, screen_update) - MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ MCFG_SCREEN_SIZE(40*12, 16*16) MCFG_SCREEN_VISIBLE_AREA(0, 40*12-1, 0, 16*16-1) @@ -329,14 +326,18 @@ static MACHINE_CONFIG_START( trs80dt1 ) MCFG_DEVICE_ADD("crtc", I8275, 12480000 / 8) MCFG_I8275_CHARACTER_WIDTH(8) MCFG_I8275_DRAW_CHARACTER_CALLBACK_OWNER(trs80dt1_state, crtc_update_row) - MCFG_I8275_DRQ_CALLBACK(INPUTLINE("maincpu", MCS51_INT0_LINE)) // BRDY pin - MCFG_I8275_IRQ_CALLBACK(WRITELINE(trs80dt1_state, irq_w)) // INT pin - MCFG_I8275_HRTC_CALLBACK(WRITELINE(trs80dt1_state, hrtc_w)) + MCFG_I8275_DRQ_CALLBACK(INPUTLINE("maincpu", MCS51_INT0_LINE)) // BRDY pin goes through inverter to /INT0, so we don't invert + MCFG_I8275_IRQ_CALLBACK(DEVWRITELINE("7474", ttl7474_device, clear_w)) // INT pin + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("7474", ttl7474_device, d_w)) + MCFG_I8275_VRTC_CALLBACK(DEVWRITELINE("7474", ttl7474_device, clock_w)) MCFG_VIDEO_SET_SCREEN("screen") MCFG_PALETTE_ADD("palette", 3) MCFG_X2210_ADD("nvram") + MCFG_DEVICE_ADD("7474", TTL7474, 0) + MCFG_7474_COMP_OUTPUT_CB(INPUTLINE("maincpu", MCS51_INT1_LINE)) MCFG_DEVCB_INVERT // /Q connects directly to /INT1, so we need to invert? + /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") MCFG_SOUND_ADD("beeper", BEEP, 2000) diff --git a/src/mame/drivers/ts3000.cpp b/src/mame/drivers/ts3000.cpp index c65364da180..a54e870bf38 100644 --- a/src/mame/drivers/ts3000.cpp +++ b/src/mame/drivers/ts3000.cpp @@ -11,31 +11,39 @@ There are 25-pin serial and parallel ports, and a FDC connector. There's an undu ************************************************************************************************************************************/ #include "emu.h" -//#include "cpu/mcs51/mcs51.h" +#include "cpu/i86/i86.h" class ts3000_state : public driver_device { public: ts3000_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) -// , maincpu(*this, "maincpu") +// , m_maincpu(*this, "maincpu") { } -protected: -// required_device<i80c52_device> maincpu; +private: +// required_device<cpu_device> m_maincpu; }; +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, ts3000_state ) + AM_RANGE(0x00000,0x0ffff) AM_RAM + AM_RANGE(0xfc000,0xfffff) AM_ROM AM_REGION("roms", 0) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_PROGRAM, 8, ts3000_state ) +ADDRESS_MAP_END + static INPUT_PORTS_START( ts3000 ) INPUT_PORTS_END -//static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, ts3000_state ) -//ADDRESS_MAP_END - static MACHINE_CONFIG_START( ts3000 ) + MCFG_CPU_ADD("maincpu", I8088, XTAL_14_31818MHz/3) // no idea of clock + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MACHINE_CONFIG_END ROM_START( ts3000 ) - ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_REGION( 0x4000, "roms", 0 ) ROM_LOAD( "U25 VER 2.03 BIOS D.u25", 0x0000, 0x4000, CRC(abaff64c) SHA1(b2f0e73d2a25a03d5bac558580919bd0400f4fcf) ) // The D at the end is handwritten ROM_END diff --git a/src/mame/drivers/ts802.cpp b/src/mame/drivers/ts802.cpp index f63ae4acd47..84319cea6e7 100644 --- a/src/mame/drivers/ts802.cpp +++ b/src/mame/drivers/ts802.cpp @@ -30,17 +30,14 @@ #include "machine/z80dart.h" #include "machine/wd_fdc.h" -#define TERMINAL_TAG "terminal" - class ts802_state : public driver_device { public: ts802_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu"), - m_terminal(*this, TERMINAL_TAG) - { - } + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_terminal(*this, "terminal") + { } DECLARE_DRIVER_INIT(ts802); DECLARE_MACHINE_RESET(ts802); @@ -78,21 +75,21 @@ static ADDRESS_MAP_START(ts802_io, AS_IO, 8, ts802_state) // 04 - written once after OS boot to bank in RAM from 0000-3FFF instead of ROM. 4000-FFFF is always RAM. AM_RANGE(0x04, 0x07) AM_WRITE(port04_w) // 08-0B: Z80 CTC - AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE("z80ctc", z80ctc_device, read, write) + AM_RANGE(0x08, 0x0b) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) // 0C-0F: Z80 SIO #1 - //AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("z80dart1", z80dart_device, ba_cd_r, ba_cd_w) + //AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("dart1", z80dart_device, ba_cd_r, ba_cd_w) AM_RANGE(0x0c, 0x0c) AM_READ(port0c_r) - AM_RANGE(0x0d, 0x0d) AM_READ(port0d_r) AM_DEVWRITE(TERMINAL_TAG, generic_terminal_device, write) + AM_RANGE(0x0d, 0x0d) AM_READ(port0d_r) AM_DEVWRITE("terminal", generic_terminal_device, write) AM_RANGE(0x0e, 0x0e) AM_READ(port0e_r) AM_RANGE(0x0f, 0x0f) AM_READ(port0f_r) // 10: Z80 DMA - AM_RANGE(0x10, 0x13) AM_DEVREADWRITE("z80dma", z80dma_device, read, write) + AM_RANGE(0x10, 0x13) AM_DEVREADWRITE("dma", z80dma_device, read, write) // 14-17: WD 1793 AM_RANGE(0x14, 0x17) AM_DEVREADWRITE("fdc", fd1793_device, read, write) // 18: floppy misc. AM_RANGE(0x18, 0x1c) AM_WRITE(port18_w) // 20-23: Z80 SIO #2 - AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("z80dart2", z80dart_device, ba_cd_r, ba_cd_w) + AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("dart2", z80dart_device, ba_cd_r, ba_cd_w) // 48-4F: WD1000 harddisk controller // 80: LEDs AM_RANGE(0x80, 0x80) AM_WRITE(port80_w) @@ -162,10 +159,10 @@ void ts802_state::kbd_put(u8 data) // not correct static const z80_daisy_config daisy_chain_intf[] = { - { "z80dart1" }, - { "z80dart2" }, - { "z80dma" }, - { "z80ctc" }, + { "dart1" }, + { "dart2" }, + { "dma" }, + { "ctc" }, { nullptr } }; #endif @@ -191,10 +188,10 @@ static MACHINE_CONFIG_START( ts802 ) MCFG_MACHINE_RESET_OVERRIDE(ts802_state, ts802) /* Devices */ - MCFG_DEVICE_ADD(TERMINAL_TAG, GENERIC_TERMINAL, 0) + MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(ts802_state, kbd_put)) - MCFG_DEVICE_ADD("z80dma", Z80DMA, XTAL_16MHz / 4) + MCFG_DEVICE_ADD("dma", Z80DMA, XTAL_16MHz / 4) MCFG_Z80DMA_OUT_BUSREQ_CB(INPUTLINE("maincpu", INPUT_LINE_HALT)) MCFG_Z80DMA_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_Z80DMA_IN_MREQ_CB(READ8(ts802_state, memory_read_byte)) @@ -202,13 +199,13 @@ static MACHINE_CONFIG_START( ts802 ) MCFG_Z80DMA_IN_IORQ_CB(READ8(ts802_state, io_read_byte)) MCFG_Z80DMA_OUT_IORQ_CB(WRITE8(ts802_state, io_write_byte)) - MCFG_DEVICE_ADD("z80dart1", Z80DART, XTAL_16MHz / 4) + MCFG_DEVICE_ADD("dart1", Z80DART, XTAL_16MHz / 4) MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("z80dart2", Z80DART, XTAL_16MHz / 4) + MCFG_DEVICE_ADD("dart2", Z80DART, XTAL_16MHz / 4) MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("z80ctc", Z80CTC, XTAL_16MHz / 4) + MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_16MHz / 4) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_FD1793_ADD("fdc", XTAL_4MHz / 2) // unknown clock diff --git a/src/mame/drivers/ts816.cpp b/src/mame/drivers/ts816.cpp index 180f05a19d7..6d750775526 100644 --- a/src/mame/drivers/ts816.cpp +++ b/src/mame/drivers/ts816.cpp @@ -23,7 +23,7 @@ TODO: #include "cpu/z80/z80daisy.h" #include "machine/z80ctc.h" #include "machine/z80pio.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80dma.h" class ts816_state : public driver_device @@ -71,18 +71,18 @@ static ADDRESS_MAP_START(ts816_io, AS_IO, 8, ts816_state) AM_RANGE(0x04, 0x04) // Tape output latch byte 2 AM_RANGE(0x05, 0x05) // Tape output latch byte 1 AM_RANGE(0x07, 0x07) // Indicator load (LED) - AM_RANGE(0x10, 0x13) AM_DEVREADWRITE("sio1", z80sio2_device, cd_ba_r, cd_ba_w) // SIO 1 for user 1 & 2 - AM_RANGE(0x18, 0x1b) AM_DEVREADWRITE("sio5", z80sio2_device, cd_ba_r, cd_ba_w) // SIO 5 for user 9 & 10 - AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("sio2", z80sio2_device, cd_ba_r, cd_ba_w) // SIO 2 for user 3 & 4 - AM_RANGE(0x28, 0x2b) AM_DEVREADWRITE("sio6", z80sio2_device, cd_ba_r, cd_ba_w) // SIO 6 for user 11 & 12 - AM_RANGE(0x30, 0x33) AM_DEVREADWRITE("sio3", z80sio2_device, cd_ba_r, cd_ba_w) // SIO 3 for user 5 & 6 - AM_RANGE(0x38, 0x3b) AM_DEVREADWRITE("sio7", z80sio2_device, cd_ba_r, cd_ba_w) // SIO 7 for user 13 & 14 - AM_RANGE(0x40, 0x43) AM_DEVREADWRITE("sio4", z80sio2_device, cd_ba_r, cd_ba_w) // SIO 4 for user 7 & 8 - AM_RANGE(0x48, 0x4b) AM_DEVREADWRITE("sio8", z80sio2_device, cd_ba_r, cd_ba_w) // SIO 8 for user 15 & 16 + AM_RANGE(0x10, 0x13) AM_DEVREADWRITE("sio1", z80sio_device, cd_ba_r, cd_ba_w) // SIO 1 for user 1 & 2 + AM_RANGE(0x18, 0x1b) AM_DEVREADWRITE("sio5", z80sio_device, cd_ba_r, cd_ba_w) // SIO 5 for user 9 & 10 + AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("sio2", z80sio_device, cd_ba_r, cd_ba_w) // SIO 2 for user 3 & 4 + AM_RANGE(0x28, 0x2b) AM_DEVREADWRITE("sio6", z80sio_device, cd_ba_r, cd_ba_w) // SIO 6 for user 11 & 12 + AM_RANGE(0x30, 0x33) AM_DEVREADWRITE("sio3", z80sio_device, cd_ba_r, cd_ba_w) // SIO 3 for user 5 & 6 + AM_RANGE(0x38, 0x3b) AM_DEVREADWRITE("sio7", z80sio_device, cd_ba_r, cd_ba_w) // SIO 7 for user 13 & 14 + AM_RANGE(0x40, 0x43) AM_DEVREADWRITE("sio4", z80sio_device, cd_ba_r, cd_ba_w) // SIO 4 for user 7 & 8 + AM_RANGE(0x48, 0x4b) AM_DEVREADWRITE("sio8", z80sio_device, cd_ba_r, cd_ba_w) // SIO 8 for user 15 & 16 //AM_RANGE(0x50, 0x53) // SIO 0 for RS232 1 and part of tape interface AM_RANGE(0x50, 0x50) AM_READ(keyin_r) AM_DEVWRITE("terminal", generic_terminal_device, write) AM_RANGE(0x52, 0x52) AM_READ(status_r) - AM_RANGE(0x58, 0x5b) AM_DEVREADWRITE("sio9", z80sio2_device, cd_ba_r, cd_ba_w) // SIO 9 for RS232 2 & 3 + AM_RANGE(0x58, 0x5b) AM_DEVREADWRITE("sio9", z80sio_device, cd_ba_r, cd_ba_w) // SIO 9 for RS232 2 & 3 AM_RANGE(0x60, 0x60) AM_READ_PORT("DSW") AM_RANGE(0x68, 0x68) AM_WRITE(port68_w) // set 2nd bank latch AM_RANGE(0x70, 0x78) AM_WRITE(port78_w) // reset 2nd bank latch (manual can't decide between 70 and 78, so we take both) @@ -266,26 +266,26 @@ static MACHINE_CONFIG_START( ts816 ) MCFG_DEVICE_ADD("terminal", GENERIC_TERMINAL, 0) MCFG_GENERIC_TERMINAL_KEYBOARD_CB(PUT(ts816_state, kbd_put)) - //MCFG_DEVICE_ADD("sio0", Z80SIO2, XTAL_16MHz / 4) - //MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio1", Z80SIO2, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio2", Z80SIO2, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio3", Z80SIO2, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio4", Z80SIO2, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio5", Z80SIO2, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio6", Z80SIO2, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio7", Z80SIO2, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio8", Z80SIO2, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("sio9", Z80SIO2, XTAL_16MHz / 4) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + //MCFG_DEVICE_ADD("sio0", Z80SIO, XTAL_16MHz / 4) + //MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio1", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio2", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio3", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio4", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio5", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio6", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio7", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio8", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_DEVICE_ADD("sio9", Z80SIO, XTAL_16MHz / 4) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) MCFG_DEVICE_ADD("pio", Z80PIO, XTAL_16MHz / 4) MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) diff --git a/src/mame/drivers/tsamurai.cpp b/src/mame/drivers/tsamurai.cpp index c1a0a49a606..6b300c8029c 100644 --- a/src/mame/drivers/tsamurai.cpp +++ b/src/mame/drivers/tsamurai.cpp @@ -855,6 +855,7 @@ static MACHINE_CONFIG_START( m660 ) MCFG_SOUND_ROUTE_EX(0, "dac2", 1.0, DAC_VREF_POS_INPUT) MCFG_SOUND_ROUTE_EX(0, "dac2", -1.0, DAC_VREF_NEG_INPUT) MACHINE_CONFIG_END + /*******************************************************************************/ ROM_START( tsamurai ) // there's a protection device labeled B5 at location l3 on the main board @@ -1240,6 +1241,50 @@ ROM_START( alphaxz ) ROM_LOAD( "5r.bpr", 0x200, 0x100, CRC(b7d6fdb5) SHA1(67d3bb16470f5d4ec35164a391ad6b65850f824a) ) ROM_END + +/* +This version of the game is the original which was tested in small quantities in Taito owned arcades. +Taito lost the license to sell the title which Kaneko sold to Wood Place. +Same hardware as Samurai Nihon-ichi. +*/ + +ROM_START( the26thz ) // there's a protection device labeled 6 or 9 on the main board (seems to be the same as the tsamurai one) + ROM_REGION( 0x10000, "maincpu", 0 ) /* Z80 code - main CPU */ + ROM_LOAD( "A72_01.3R", 0x0000, 0x4000, CRC(2be77520) SHA1(26c65a9c59a0cf3609d084ec4e0af4e670a3069c) ) // 27128 + ROM_LOAD( "A72_02.3T", 0x4000, 0x4000, CRC(ef2646f2) SHA1(0b178793420bd5e5fb77cf55e049a73f0fbc2d0f) ) // 27128 + ROM_LOAD( "A72_03.3V", 0x8000, 0x4000, CRC(d83b7758) SHA1(ff025c67e7ace9b178fd46642f98d79e18076d28) ) // 27128 + + ROM_REGION( 0x10000, "audiocpu", 0 ) /* Z80 code - sample player */ + ROM_LOAD( "A72_16.4N", 0x0000, 0x4000, CRC(5734db5a) SHA1(ff99bf618018be20a4b38fcfbe75d9c5bb6fd176) ) // 27128 + + ROM_REGION( 0x10000, "audio2", 0 ) /* Z80 code - sample player */ + ROM_LOAD( "A72_15.4J", 0x0000, 0x4000, CRC(fba51cf7) SHA1(b18571112dcbe3214a803d0898b0a21957dc5e5f) ) // 27128 + + ROM_REGION( 0x10000, "audio3", 0 ) /* Z80 code AY driver, identical to the parent set but split in 2 ROMs */ + ROM_LOAD( "A72_14.4E", 0x0000, 0x4000, CRC(d078373e) SHA1(939c8c1eb651d34b3c873db3aeef4c59b4f70a9f) ) // 27128 + ROM_LOAD( "A72_13.4D", 0x4000, 0x4000, CRC(11980449) SHA1(e17611980043c152c518b334ffda8e93d368e4a9) ) // 27128 + + ROM_REGION( 0xc000, "gfx1", 0 ) // tiles + ROM_LOAD( "A72_04.10A", 0x00000, 0x4000, CRC(23da4e3d) SHA1(fd48c86769360a778057a673d5c1dfdfe00f6c18) ) // 27128 + ROM_LOAD( "A72_05.10B", 0x04000, 0x4000, CRC(8746ff69) SHA1(6b95f209d931601155ad492652e3016df3e5dfb0) ) // 27128 + ROM_LOAD( "A72_06.10D", 0x08000, 0x4000, CRC(6e494964) SHA1(9f42935281502a1e73f602cb93ca241aeaa03201) ) // 27128 + + ROM_REGION( 0x6000, "gfx2", 0 ) // characters + ROM_LOAD( "A72_10.11N", 0x00000, 0x1000, CRC(a23e4829) SHA1(329ff6bd21c804c103938e333b355c7387b5d0be) ) // 2732 + ROM_LOAD( "A72_11.11Q", 0x02000, 0x1000, CRC(9717229f) SHA1(ecc1bbde29fbd28eebc2016ca5e04bc841ca061e) ) // 2732 + ROM_LOAD( "A72_12.11R", 0x04000, 0x1000, CRC(7a602979) SHA1(32c40ad1cb1b6bb49c6f37da443a4368fd24faf7) ) // 2732 + + ROM_REGION( 0xc000, "gfx3", 0 ) // sprites + ROM_LOAD( "A72_07.12H", 0x00000, 0x4000, CRC(5f9cc65e) SHA1(235b4a8762ba429855cc9db07477efde2a62e03d) ) // 27128 + ROM_LOAD( "A72_08.12J", 0x04000, 0x4000, CRC(23e3a6ba) SHA1(d6d035b7b7530a909669ac045aea51e297ba784e) ) // 27128 + ROM_LOAD( "A72_09.12K", 0x08000, 0x4000, CRC(7096fa71) SHA1(f9697b30d7eec5ee9122d783f9ee7b9cdbab9262) ) // 27128 + + ROM_REGION( 0x300, "proms", 0 ) + ROM_LOAD( "A72_17.2K", 0x000, 0x100, CRC(cd16d0f1) SHA1(4b0a68f28329fb86d252f4170edd2ab0488805e5) ) // 82S129 + ROM_LOAD( "A72_18.2L", 0x100, 0x100, CRC(22e8b22c) SHA1(2934ca96495fca72a33fa2881dc65ab21342c410) ) // 82S129 + ROM_LOAD( "A72_19.2M", 0x200, 0x100, CRC(b7d6fdb5) SHA1(67d3bb16470f5d4ec35164a391ad6b65850f824a) ) // 82S129 +ROM_END + ROM_START( vsgongf ) ROM_REGION( 0x10000, "maincpu", 0 ) /* Z80 code - main CPU */ ROM_LOAD( "1.5a", 0x0000, 0x2000, CRC(2c056dee) SHA1(f063fdd571949a1b7ac36f88e17feec7354ea894) ) /* good? */ @@ -1324,21 +1369,28 @@ ROM_START( ringfgt2 ) ROM_LOAD( "clr.6p", 0x200, 0x0100, CRC(0e4fd17a) SHA1(d4e32bd9dd903177af61f77976a25c5db1467bba) ) ROM_END -GAME( 1984, vsgongf, 0, vsgongf, vsgongf, tsamurai_state, 0, ROT90, "Kaneko", "VS Gong Fight", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) -GAME( 1984, ringfgt, vsgongf, vsgongf, vsgongf, tsamurai_state, 0, ROT90, "Kaneko (Taito license)", "Ring Fighter (set 1)", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) -GAME( 1984, ringfgt2, vsgongf, vsgongf, vsgongf, tsamurai_state, 0, ROT90, "Kaneko (Taito license)", "Ring Fighter (set 2)", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) +DRIVER_INIT_MEMBER(tsamurai_state, the26thz) +{ + m_maincpu->space(AS_PROGRAM).unmap_read(0xd803, 0xd803); + m_maincpu->space(AS_PROGRAM).install_read_handler(0xd803, 0xd803, read8_delegate(FUNC(tsamurai_state::tsamurai_unknown_d803_r), this)); +} + +GAME( 1984, vsgongf, 0, vsgongf, vsgongf, tsamurai_state, 0, ROT90, "Kaneko", "VS Gong Fight", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE | MACHINE_UNEMULATED_PROTECTION ) +GAME( 1984, ringfgt, vsgongf, vsgongf, vsgongf, tsamurai_state, 0, ROT90, "Kaneko (Taito license)", "Ring Fighter (set 1)", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) +GAME( 1984, ringfgt2, vsgongf, vsgongf, vsgongf, tsamurai_state, 0, ROT90, "Kaneko (Taito license)", "Ring Fighter (set 2)", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) -GAME( 1985, tsamurai, 0, tsamurai, tsamurai, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Samurai Nihon-Ichi (set 1)", MACHINE_SUPPORTS_SAVE ) -GAME( 1985, tsamurai2, tsamurai, tsamurai, tsamurai, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Samurai Nihon-Ichi (set 2)", MACHINE_SUPPORTS_SAVE ) -GAME( 1985, tsamuraih, tsamurai, tsamurai, tsamurai, tsamurai_state, 0, ROT90, "bootleg", "Samurai Nihon-Ichi (bootleg, harder)", MACHINE_SUPPORTS_SAVE ) +GAME( 1985, tsamurai, 0, tsamurai, tsamurai, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Samurai Nihon-Ichi (set 1)", MACHINE_SUPPORTS_SAVE ) +GAME( 1985, tsamurai2, tsamurai, tsamurai, tsamurai, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Samurai Nihon-Ichi (set 2)", MACHINE_SUPPORTS_SAVE ) +GAME( 1985, tsamuraih, tsamurai, tsamurai, tsamurai, tsamurai_state, 0, ROT90, "bootleg", "Samurai Nihon-Ichi (bootleg, harder)", MACHINE_SUPPORTS_SAVE ) -GAME( 1985, ladymstr, 0, tsamurai, ladymstr, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Lady Master of Kung Fu (set 1, newer)", MACHINE_SUPPORTS_SAVE ) -GAME( 1985, ladymstr2, ladymstr, tsamurai, ladymstr, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Lady Master of Kung Fu (set 2, older)", MACHINE_SUPPORTS_SAVE ) -GAME( 1985, nunchaku, ladymstr, tsamurai, nunchaku, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Nunchackun", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) +GAME( 1985, ladymstr, 0, tsamurai, ladymstr, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Lady Master of Kung Fu (set 1, newer)", MACHINE_SUPPORTS_SAVE ) +GAME( 1985, ladymstr2, ladymstr, tsamurai, ladymstr, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Lady Master of Kung Fu (set 2, older)", MACHINE_SUPPORTS_SAVE ) +GAME( 1985, nunchaku, ladymstr, tsamurai, nunchaku, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Nunchackun", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) -GAME( 1985, yamagchi, 0, tsamurai, yamagchi, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Go Go Mr. Yamaguchi / Yuke Yuke Yamaguchi-kun", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) +GAME( 1985, yamagchi, 0, tsamurai, yamagchi, tsamurai_state, 0, ROT90, "Kaneko / Taito", "Go Go Mr. Yamaguchi / Yuke Yuke Yamaguchi-kun", MACHINE_IMPERFECT_COLORS | MACHINE_SUPPORTS_SAVE ) -GAME( 1986, m660, 0, m660, m660, tsamurai_state, 0, ROT90, "Wood Place Inc. (Taito America Corporation license)", "Mission 660 (US)", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, m660j, m660, m660, m660, tsamurai_state, 0, ROT90, "Wood Place Inc. (Taito Corporation license)", "Mission 660 (Japan)", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, m660b, m660, m660, m660, tsamurai_state, 0, ROT90, "bootleg", "Mission 660 (bootleg)", MACHINE_SUPPORTS_SAVE ) -GAME( 1986, alphaxz, m660, m660, m660, tsamurai_state, 0, ROT90, "Ed Co. Ltd. (Wood Place Inc. license)", "The Alphax Z (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, m660, 0, m660, m660, tsamurai_state, 0, ROT90, "Wood Place Inc. (Taito America Corporation license)", "Mission 660 (US)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, m660j, m660, m660, m660, tsamurai_state, 0, ROT90, "Wood Place Inc. (Taito Corporation license)", "Mission 660 (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, m660b, m660, m660, m660, tsamurai_state, 0, ROT90, "bootleg", "Mission 660 (bootleg)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, alphaxz, m660, m660, m660, tsamurai_state, 0, ROT90, "Ed Co. Ltd. (Wood Place Inc. license)", "The Alphax Z (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1986, the26thz, m660, m660, m660, tsamurai_state, the26thz, ROT90, "Ed Co. Ltd. (Taito license)", "The 26th Z (Japan, location test)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/tti.cpp b/src/mame/drivers/tti.cpp new file mode 100644 index 00000000000..a8665790e6e --- /dev/null +++ b/src/mame/drivers/tti.cpp @@ -0,0 +1,86 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/*********************************************************************************************************************************** + +2017-11-02 Skeleton + +Transitional Technology Inc. SCSI host adapter, possibly part of the QTx (Q-Bus) series or UTx (Unibus) series. +Model number not known, zipfile was named "TTI_10012000.zip" + +Chips: NCR 53C90A, Motorola MC68901P, Fujitsu 8464A-10L (8KB static ram), Xicor X24C44P (16x16 serial NOVRAM), and 14 undumped +Lattice PLDs. + +Other: LED, 20MHz crystal. Next to the MC68901P is another chip just as large (48 pin DIL), with a huge "MFG. UNDER LICENSE FROM + DIGITAL EQUIPMENT CORP." sticker covering all details. Assumed to be a Motorola MC68008 CPU. + +************************************************************************************************************************************/ + +#include "emu.h" +#include "bus/rs232/rs232.h" +#include "cpu/m68000/m68000.h" +#include "machine/74259.h" +#include "machine/eepromser.h" +#include "machine/mc68901.h" + +class tti_state : public driver_device +{ +public: + tti_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_mfp(*this, "mfp") + { } + + IRQ_CALLBACK_MEMBER(intack); + +protected: + required_device<cpu_device> m_maincpu; + required_device<mc68901_device> m_mfp; +}; + +IRQ_CALLBACK_MEMBER(tti_state::intack) +{ + return m_mfp->get_vector(); +} + +static INPUT_PORTS_START( tti ) +INPUT_PORTS_END + +static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, tti_state ) + AM_RANGE(0x00000, 0x07fff) AM_ROM AM_REGION("maincpu", 0) + AM_RANGE(0x7e000, 0x7ffff) AM_RAM + AM_RANGE(0x80000, 0x80017) AM_DEVREADWRITE("mfp", mc68901_device, read, write) + AM_RANGE(0x80070, 0x80077) AM_DEVWRITE("bitlatch", ls259_device, write_d0) +ADDRESS_MAP_END + +static MACHINE_CONFIG_START( tti ) + MCFG_DEVICE_ADD("maincpu", M68008, XTAL_20MHz / 2) // guess + MCFG_CPU_PROGRAM_MAP(prg_map) + MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(tti_state, intack) + + MCFG_DEVICE_ADD("mfp", MC68901, 0) + MCFG_MC68901_TIMER_CLOCK(XTAL_20MHz / 2) // guess + MCFG_MC68901_RX_CLOCK(9600) // for testing (FIXME: actually 16x) + MCFG_MC68901_TX_CLOCK(9600) // for testing (FIXME: actually 16x) + MCFG_MC68901_OUT_SO_CB(DEVWRITELINE("rs232", rs232_port_device, write_txd)) + MCFG_MC68901_OUT_IRQ_CB(INPUTLINE("maincpu", M68K_IRQ_5)) + + MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("mfp", mc68901_device, write_rx)) + + MCFG_EEPROM_SERIAL_X24C44_ADD("novram") + MCFG_EEPROM_SERIAL_DO_CALLBACK(DEVWRITELINE("mfp", mc68901_device, i0_w)) + + MCFG_DEVICE_ADD("bitlatch", LS259, 0) // U17 + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(DEVWRITELINE("novram", eeprom_serial_x24c44_device, di_write)) + MCFG_ADDRESSABLE_LATCH_Q1_OUT_CB(DEVWRITELINE("novram", eeprom_serial_x24c44_device, clk_write)) + MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(DEVWRITELINE("novram", eeprom_serial_x24c44_device, cs_write)) +MACHINE_CONFIG_END + +ROM_START( tti ) + ROM_REGION( 0x8000, "maincpu", 0 ) + ROM_LOAD( "tti_10012000_rev2.3.bin", 0x0000, 0x8000, CRC(95a5bce8) SHA1(46d7c99e37ca5598aec2062dfd9759853a237c14) ) + ROM_LOAD( "tti_10012000_rev1.7.bin", 0x0000, 0x8000, CRC(6660c059) SHA1(05d97009b5b8034dda520f655c73c474da97f822) ) +ROM_END + +COMP( 1989, tti, 0, 0, tti, tti, tti_state, 0, "Transitional Technology Inc", "unknown TTI SCSI host adapter", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/tv950.cpp b/src/mame/drivers/tv950.cpp index 6922e37c3c9..5730eb940fd 100644 --- a/src/mame/drivers/tv950.cpp +++ b/src/mame/drivers/tv950.cpp @@ -50,7 +50,7 @@ #define RS232A_TAG "rs232a" #define RS232B_TAG "rs232b" -#define MASTER_CLOCK (23814000) +#define MASTER_CLOCK XTAL_23_814MHz class tv950_state : public driver_device { @@ -315,8 +315,18 @@ ROM_START( tv950 ) ROM_REGION(0x1000, "kbd", 0) ROM_LOAD( "950kbd_8748_pn52080723-02.bin", 0x000000, 0x000400, CRC(11c8f22c) SHA1(99e73e9c74b10055733e89b92adbc5bf7f4ff338) ) + + ROM_REGION(0x10000, "user1", 0) + // came with "tv950.zip" + ROM_LOAD( "tv-043h.rom", 0x0000, 0x1000, CRC(89b826be) SHA1(fd5575be04317682d0c9062702b5932b46f89926) ) + ROM_LOAD( "tv-044h.rom", 0x0000, 0x1000, CRC(24b0383d) SHA1(71cabb7f3da8652a36afdf3d505ab8a41651e801) ) + ROM_LOAD( "180000-43i_a25_05ce.bin", 0x0000, 0x1000, CRC(ac6f0bfc) SHA1(2a3863700405fbb9e510613559d78fceee3544e8) ) + ROM_LOAD( "180000-44i_a20_689e.bin", 0x0000, 0x1000, CRC(db91a727) SHA1(e94724ed1a563fb846f4203ae6523ee6b4c6577f) ) + // came with "tv950kbd.zip" + ROM_LOAD( "tv950_a32_1800000-003a.bin", 0x0000, 0x1000, CRC(eaef0138) SHA1(7198851299fce07c95d18e32cbfbe936c0dbec2a) ) + ROM_LOAD( "tv950_a33_1800000-002a.bin", 0x0000, 0x1000, CRC(856dd85c) SHA1(e2570017e098b0e1ead7749e9c2ac40be2367433) ) ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -COMP( 1981, tv950, 0, 0, tv950, tv950, tv950_state, 0, "TeleVideo", "TV950", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1981, tv950, 0, 0, tv950, tv950, tv950_state, 0, "TeleVideo", "Model 950 Video Display Terminal", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/tvgame.cpp b/src/mame/drivers/tvgame.cpp index 1ad716e471d..77bad6bcefe 100644 --- a/src/mame/drivers/tvgame.cpp +++ b/src/mame/drivers/tvgame.cpp @@ -36,14 +36,14 @@ private: required_shared_ptr<uint8_t> m_p_videoram; }; -static ADDRESS_MAP_START( tvgame_mem, AS_PROGRAM, 8, tvgame_state ) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, tvgame_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0x7fff ) AM_ROM AM_RANGE( 0x8000, 0xbfff ) AM_RAM AM_RANGE( 0xc000, 0xdfff ) AM_RAM AM_SHARE("videoram") ADDRESS_MAP_END -static ADDRESS_MAP_START( tvgame_io, AS_IO, 8, tvgame_state ) +static ADDRESS_MAP_START( io_map, AS_IO, 8, tvgame_state ) ADDRESS_MAP_GLOBAL_MASK(3) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0x0003) AM_DEVREADWRITE("ppi", i8255_device, read, write) @@ -96,8 +96,8 @@ uint32_t tvgame_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap static MACHINE_CONFIG_START( tvgame ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, XTAL_4MHz) - MCFG_CPU_PROGRAM_MAP(tvgame_mem) - MCFG_CPU_IO_MAP(tvgame_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) diff --git a/src/mame/drivers/twincobr.cpp b/src/mame/drivers/twincobr.cpp index 8f684a4da56..416273f3d1e 100644 --- a/src/mame/drivers/twincobr.cpp +++ b/src/mame/drivers/twincobr.cpp @@ -385,6 +385,7 @@ Shark Zame #include "cpu/mcs48/mcs48.h" #include "cpu/tms32010/tms32010.h" #include "cpu/z80/z80.h" +#include "machine/74259.h" #include "sound/3812intf.h" #include "speaker.h" @@ -411,8 +412,8 @@ static ADDRESS_MAP_START( main_program_map, AS_PROGRAM, 16, twincobr_state ) AM_RANGE(0x078004, 0x078005) AM_READ_PORT("P1") AM_RANGE(0x078006, 0x078007) AM_READ_PORT("P2") AM_RANGE(0x078008, 0x078009) AM_READ_PORT("VBLANK") /* V-Blank & FShark Coin/Start */ - AM_RANGE(0x07800a, 0x07800b) AM_WRITE(fshark_coin_dsp_w) /* Flying Shark DSP Comms & coin stuff */ - AM_RANGE(0x07800c, 0x07800d) AM_WRITE(twincobr_control_w) /* Twin Cobra DSP Comms & system control */ + AM_RANGE(0x07800a, 0x07800b) AM_DEVWRITE8("coinlatch", ls259_device, write_nibble_d0, 0x00ff) /* Flying Shark DSP Comms & coin stuff */ + AM_RANGE(0x07800c, 0x07800d) AM_DEVWRITE8("mainlatch", ls259_device, write_nibble_d0, 0x00ff) /* Twin Cobra DSP Comms & system control */ AM_RANGE(0x07a000, 0x07afff) AM_READWRITE(twincobr_sharedram_r, twincobr_sharedram_w) /* 16-bit on 68000 side, 8-bit on Z80 side */ AM_RANGE(0x07e000, 0x07e001) AM_READWRITE(twincobr_txram_r, twincobr_txram_w) /* data for text video RAM */ AM_RANGE(0x07e002, 0x07e003) AM_READWRITE(twincobr_bgram_r, twincobr_bgram_w) /* data for bg video RAM */ @@ -431,7 +432,7 @@ static ADDRESS_MAP_START( sound_io_map, AS_IO, 8, twincobr_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x01) AM_DEVREADWRITE("ymsnd", ym3812_device, read, write) AM_RANGE(0x10, 0x10) AM_READ_PORT("SYSTEM") /* Twin Cobra - Coin/Start */ - AM_RANGE(0x20, 0x20) AM_WRITE(twincobr_coin_w) /* Twin Cobra coin count-lockout */ + AM_RANGE(0x20, 0x20) AM_DEVWRITE("coinlatch", ls259_device, write_nibble_d0) /* Twin Cobra coin count-lockout */ AM_RANGE(0x40, 0x40) AM_READ_PORT("DSWA") AM_RANGE(0x50, 0x50) AM_READ_PORT("DSWB") ADDRESS_MAP_END @@ -675,6 +676,20 @@ static MACHINE_CONFIG_START( twincobr ) MCFG_MACHINE_RESET_OVERRIDE(twincobr_state,twincobr) + MCFG_DEVICE_ADD("mainlatch", LS259, 0) + MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE(twincobr_state, int_enable_w)) + MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(WRITELINE(twincobr_state, flipscreen_w)) + MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(WRITELINE(twincobr_state, bg_ram_bank_w)) + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(WRITELINE(twincobr_state, fg_rom_bank_w)) + MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE(twincobr_state, dsp_int_w)) + MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE(twincobr_state, display_on_w)) + + MCFG_DEVICE_ADD("coinlatch", LS259, 0) + MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(WRITELINE(twincobr_state, coin_counter_1_w)) + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(WRITELINE(twincobr_state, coin_counter_2_w)) + MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE(twincobr_state, coin_lockout_1_w)) + MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE(twincobr_state, coin_lockout_2_w)) + /* video hardware */ MCFG_MC6845_ADD("crtc", HD6845, "screen", XTAL_28MHz/8) /* 3.5MHz measured on CLKin */ MCFG_MC6845_SHOW_BORDER_AREA(false) @@ -707,6 +722,12 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( fshark, twincobr ) + MCFG_DEVICE_MODIFY("mainlatch") + MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(NOOP) + + MCFG_DEVICE_MODIFY("coinlatch") + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE(twincobr_state, dsp_int_w)) + MCFG_DEVICE_MODIFY("scu") toaplan_scu_device::static_set_xoffsets(*device, 32, 14); MACHINE_CONFIG_END diff --git a/src/mame/drivers/twinkle.cpp b/src/mame/drivers/twinkle.cpp index 5326a791d83..2788dc976b0 100644 --- a/src/mame/drivers/twinkle.cpp +++ b/src/mame/drivers/twinkle.cpp @@ -9,7 +9,7 @@ driver by smf and R. Belmont TODO: dvd check for bmiidx, bmiidxa, bmiidxc & bmiidxca -finish sound board emulation and remove response hle +remove dummy 8mb bank emulate dvd player and video mixing 16seg led font @@ -247,6 +247,8 @@ Notes: #include "sound/rf5c400.h" #include "speaker.h" +#include "bmiidx.lh" + class twinkle_state : public driver_device { public: @@ -256,6 +258,8 @@ public: m_ata(*this, "ata"), m_waveram(*this, "rfsnd"), m_spu_ata_dma(0), + m_spu_ata_dmarq(0), + m_wave_bank(0), m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu") { @@ -269,14 +273,16 @@ public: uint8_t m_spu_shared[0x400]; // SPU/PSX shared dual-ported RAM uint32_t m_spu_ata_dma; int m_spu_ata_dmarq; + uint32_t m_wave_bank; int m_io_offset; int m_output_last[ 0x100 ]; - int m_last_io_offset; uint8_t m_sector_buffer[ 4096 ]; DECLARE_WRITE8_MEMBER(twinkle_io_w); DECLARE_READ8_MEMBER(twinkle_io_r); DECLARE_WRITE16_MEMBER(twinkle_output_w); + DECLARE_WRITE16_MEMBER(led_w); + DECLARE_WRITE16_MEMBER(key_led_w); DECLARE_WRITE16_MEMBER(serial_w); DECLARE_WRITE8_MEMBER(shared_psx_w); DECLARE_READ8_MEMBER(shared_psx_r); @@ -287,6 +293,8 @@ public: DECLARE_WRITE16_MEMBER(twinkle_waveram_w); DECLARE_READ16_MEMBER(shared_68k_r); DECLARE_WRITE16_MEMBER(shared_68k_w); + DECLARE_WRITE16_MEMBER(spu_led_w); + DECLARE_WRITE16_MEMBER(spu_wavebank_w); DECLARE_READ16_MEMBER(unk_68k_r); DECLARE_WRITE_LINE_MEMBER(spu_ata_irq); DECLARE_WRITE_LINE_MEMBER(spu_ata_dmarq); @@ -304,8 +312,6 @@ public: int m_output_clock; }; -/* RTC */ - #define LED_A1 0x0001 #define LED_A2 0x0002 #define LED_B 0x0004 @@ -332,29 +338,24 @@ public: static const uint16_t asciicharset[]= { - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_J | LED_M, // 0 - LED_B | LED_C, // 1 - LED_A1 | LED_A2 | LED_B | LED_D1 | LED_D2 | LED_E | LED_G1 | LED_G2, // 2 - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_G2, // 3 - LED_B | LED_C | LED_F | LED_G1 | LED_G2 , // 4 - LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_F | LED_G1 | LED_K, // 5 - LED_A1 | LED_A2 | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_G1 | LED_G2, // 6 - LED_A1 | LED_A2 | LED_B | LED_C, // 7 - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F, // 8 - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_F, // 9 - LED_A1 | LED_A2 | LED_B | LED_C | LED_E | LED_F, // A - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_G2 | LED_I | LED_L, // B - LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_E | LED_F, // C - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_I | LED_L, // D - LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_E | LED_F | LED_G1 | LED_G2, // E - LED_A1 | LED_A2 | LED_E | LED_F | LED_G1, // F -// 16 +// 0 + 0, // (default on boot) + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 0, 0, 0, 0, 0, 0, +// 0x10 0, 0, 0, @@ -365,63 +366,70 @@ static const uint16_t asciicharset[]= 0, 0, 0, -// 32 + 0, + 0, + 0, + 0, + 0, + 0, +// 0x20 0, // space - 0, // ! - 0, // " + LED_D2 | LED_A2 | LED_I | LED_J, // ! + LED_I | LED_B, // " 0, // # 0, // $ 0, // % - 0, // & + LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_H | LED_J | LED_M | LED_K | LED_C, // & 0, // ' - 0, // ( - 0, // ) - 0, // * + LED_J | LED_K, // ( + LED_H | LED_M, // ) + LED_G1 | LED_G2 | LED_H | LED_I | LED_J | LED_K | LED_L | LED_M, // * 0, // + 0, // , - 0, // - + LED_G1 | LED_G2, // - 0, // . - 0, // / -// 48 + LED_J | LED_M, // / +// 0x30 LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_J | LED_M, // 0 LED_B | LED_C, // 1 - LED_A1 | LED_A2 | LED_B | LED_D1 | LED_D2 | LED_E | LED_G1 | LED_G2, // 2 - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_G2, // 3 + LED_A1 | LED_A2 | LED_B | LED_D1 | LED_D2 | LED_E | LED_G1 | LED_G2, // 2 + LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_G1 | LED_G2, // 3 LED_B | LED_C | LED_F | LED_G1 | LED_G2 , // 4 - LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_F | LED_G1 | LED_K, // 5 - LED_A1 | LED_A2 | LED_C | LED_D1 | LED_D2 | LED_E | LED_F, // 6 - LED_A1 | LED_A2 | LED_B | LED_C, // 7 - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F, // 8 - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_F, // 9 + LED_A1 | LED_A2 | LED_C | LED_D1 | LED_D2 | LED_F | LED_G1 | LED_G2, // 5 + LED_A1 | LED_A2 | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_G1 | LED_G2, // 6 + LED_A1 | LED_A2 | LED_B | LED_C | LED_F, // 7 + LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_G1 | LED_G2, // 8 + LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_F | LED_G1 | LED_G2, // 9 0, // : 0, // ; 0, // < 0, // = 0, // > - 0, // ? -// 64 + LED_A1 | LED_A2 | LED_J | LED_D2, // ? +// 0x40 0, // @ - LED_A1 | LED_A2 | LED_B | LED_C | LED_E | LED_F, // A - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_G2 | LED_I | LED_L, // B + LED_A1 | LED_A2 | LED_B | LED_C | LED_E | LED_F | LED_G1 | LED_G2, // A + LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_E | LED_F | LED_G1 | LED_J | LED_K, // B LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_E | LED_F, // C - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_I | LED_L, // D + LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_G1 | LED_G2, // D LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_E | LED_F | LED_G1 | LED_G2, // E - LED_A1 | LED_A2 | LED_E | LED_F | LED_G1, // F + LED_A1 | LED_A2 | LED_E | LED_F | LED_G1 | LED_G2, // F LED_A1 | LED_A2 | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_G2, // G LED_B | LED_C | LED_E | LED_F | LED_G1 | LED_G2, // H - LED_I | LED_L, // I - LED_B | LED_C | LED_D1 | LED_D2 | LED_E, // J + LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_I | LED_L, // I + LED_A1 | LED_A2 | LED_I | LED_L | LED_D2, // J LED_E | LED_F | LED_G1 | LED_J | LED_K, // K LED_D1 | LED_D2 | LED_E | LED_F, // L LED_B | LED_C | LED_E | LED_F | LED_H | LED_J, // M LED_B | LED_C | LED_E | LED_F | LED_H | LED_K, // N LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F, // O - LED_A1 | LED_A2 | LED_B | LED_E | LED_F, // P +// 0x50 + LED_A1 | LED_A2 | LED_B | LED_E | LED_F | LED_G1 | LED_G2, // P LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_K, // Q - LED_A1 | LED_A2 | LED_B | LED_E | LED_F | LED_K, // R + LED_A1 | LED_A2 | LED_B | LED_E | LED_F | LED_K | LED_G1 | LED_G2, // R LED_A1 | LED_A2 | LED_C | LED_D1 | LED_D2 | LED_F | LED_G1 | LED_G2, // S LED_A1 | LED_A2 | LED_I | LED_L, // T - LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F, // O + LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F, // U LED_E | LED_F | LED_M | LED_J, // V LED_B | LED_C | LED_E | LED_F | LED_M | LED_K, // W LED_H | LED_J | LED_K | LED_M, // X @@ -432,33 +440,35 @@ static const uint16_t asciicharset[]= 0, // ] 0, // ^ 0, // _ +// 0x60 0, // ` - LED_A1 | LED_A2 | LED_B | LED_C | LED_E | LED_F, // A - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_G2 | LED_I | LED_L, // B - LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_E | LED_F, // C - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_I | LED_L, // D - LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_E | LED_F | LED_G1 | LED_G2, // E - LED_A1 | LED_A2 | LED_E | LED_F | LED_G1, // F - LED_A1 | LED_A2 | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_G2, // G - LED_B | LED_C | LED_E | LED_F | LED_G1 | LED_G2, // H - LED_I | LED_L, // I - LED_B | LED_C | LED_D1 | LED_D2 | LED_E, // J - LED_E | LED_F | LED_G1 | LED_J | LED_K, // K - LED_D1 | LED_D2 | LED_E | LED_F, // L - LED_B | LED_C | LED_E | LED_F | LED_H | LED_J, // M - LED_B | LED_C | LED_E | LED_F | LED_H | LED_K, // N - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F, // O - LED_A1 | LED_A2 | LED_B | LED_E | LED_F, // P - LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_K, // Q - LED_A1 | LED_A2 | LED_B | LED_E | LED_F | LED_K, // R - LED_A1 | LED_A2 | LED_C | LED_D1 | LED_D2 | LED_F | LED_G1 | LED_G2, // S - LED_A1 | LED_A2 | LED_I | LED_L, // T - LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F, // O - LED_E | LED_F | LED_M | LED_J, // V - LED_B | LED_C | LED_E | LED_F | LED_M | LED_K, // W - LED_H | LED_J | LED_K | LED_M, // X - LED_H | LED_J | LED_L, // Y - LED_A1 | LED_A2 | LED_D1 | LED_D2 | LED_J | LED_M, // Z + 0, // a + 0, // b + 0, // c + 0, // d + 0, // e + 0, // f + LED_A1 | LED_A2 | LED_B | LED_C | LED_D1 | LED_D2 | LED_E | LED_F | LED_G1 | LED_G2 | LED_H | LED_I | LED_J | LED_K | LED_L | LED_M, // g (16 seg led test) + 0, // h + 0, // i + 0, // j + 0, // k + 0, // l + LED_D2, // m (".") + 0, // n + 0, // o +// 0x70 + 0, // p + LED_J, // q ("'") + 0, // r + 0, // s + 0, // t + LED_M, // u (",") + 0, // v + 0, // w + 0, // x + 0, // y + 0, // z 0, // { 0, // | 0, // } @@ -484,9 +494,25 @@ WRITE8_MEMBER(twinkle_state::twinkle_io_w) case 0x1f: case 0x27: case 0x2f: + if (data != 0xff) + { + osd_printf_warning("unknown io %02x = %02x\n", m_io_offset, data); + } + break; + case 0x37: + output().set_value("1p", (~data >> 0) & 1); + output().set_value("2p", (~data >> 1) & 1); + output().set_value("vefx", (~data >> 2) & 1); + output().set_value("effect", (~data >> 3) & 1); + output().set_value("credit", (~data >> 4) & 1); + + if ((data & 0xe0) != 0xe0) + { + osd_printf_warning("unknown io %02x = %02x\n", m_io_offset, data); + } + break; - /* led */ case 0x3f: case 0x47: case 0x4f: @@ -496,7 +522,7 @@ WRITE8_MEMBER(twinkle_state::twinkle_io_w) case 0x6f: case 0x77: case 0x7f: - output().set_indexed_value( "led", ( m_io_offset - 7 ) / 8, asciicharset[ ( data ^ 0xff ) & 0x7f ] ); + output().set_indexed_value( "led", ( m_io_offset - 0x3f ) / 8, asciicharset[ ( data ^ 0xff ) & 0x7f ] ); break; case 0x87: @@ -517,7 +543,7 @@ WRITE8_MEMBER(twinkle_state::twinkle_io_w) if( ( data & 0xf8 ) != 0xf8 ) { - printf("%02x = %02x\n", m_io_offset, data ); + osd_printf_warning("unknown io %02x = %02x\n", m_io_offset, data); } break; @@ -568,10 +594,7 @@ READ8_MEMBER(twinkle_state::twinkle_io_r) break; default: - if( m_last_io_offset != m_io_offset ) - { - m_last_io_offset = m_io_offset; - } + osd_printf_warning("unknown io 0x%02x\n", m_io_offset); break; } break; @@ -595,7 +618,7 @@ WRITE16_MEMBER(twinkle_state::twinkle_output_w) /* data */ break; case 0x08: - /* ?? */ + // overlay enable? break; case 0x10: { @@ -642,6 +665,45 @@ WRITE16_MEMBER(twinkle_state::twinkle_output_w) } } +WRITE16_MEMBER(twinkle_state::led_w) +{ + output().set_indexed_value("main_led", 0, (~data >> 0) & 1); + output().set_indexed_value("main_led", 1, (~data >> 1) & 1); + output().set_indexed_value("main_led", 2, (~data >> 2) & 1); + output().set_indexed_value("main_led", 3, (~data >> 3) & 1); + output().set_indexed_value("main_led", 4, (~data >> 4) & 1); + output().set_indexed_value("main_led", 5, (~data >> 5) & 1); + output().set_indexed_value("main_led", 6, (~data >> 6) & 1); + output().set_indexed_value("main_led", 7, (~data >> 7) & 1); + output().set_indexed_value("main_led", 8, (~data >> 8) & 1); + + if ((data & 0xfe00) != 0xfe00) + { + osd_printf_warning("led_w unknown %04x\n", data); + } +} + +WRITE16_MEMBER(twinkle_state::key_led_w) +{ + // words are written using a byte write + output().set_indexed_value("key1-", 1, (data >> 0) & 1); + output().set_indexed_value("key1-", 2, (data >> 1) & 1); + output().set_indexed_value("key1-", 3, (data >> 2) & 1); + output().set_indexed_value("key1-", 4, (data >> 3) & 1); + output().set_indexed_value("key1-", 5, (data >> 4) & 1); + output().set_indexed_value("key1-", 6, (data >> 5) & 1); + output().set_indexed_value("key1-", 7, (data >> 6) & 1); + output().set_indexed_value("key2-", 1, (data >> 7) & 1); + output().set_indexed_value("key2-", 2, (data >> 8) & 1); + output().set_indexed_value("key2-", 3, (data >> 9) & 1); + output().set_indexed_value("key2-", 4, (data >> 10) & 1); + output().set_indexed_value("key2-", 5, (data >> 11) & 1); + output().set_indexed_value("key2-", 6, (data >> 12) & 1); + output().set_indexed_value("key2-", 7, (data >> 13) & 1); + output().set_value("unknown3", (data >> 14) & 1); + output().set_value("unknown4", (data >> 15) & 1); +} + WRITE16_MEMBER(twinkle_state::serial_w) { int _do = ( data >> 4 ) & 1; @@ -703,9 +765,9 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 32, twinkle_state ) AM_RANGE(0x1f218000, 0x1f218003) AM_DEVWRITE8("watchdog", watchdog_timer_device, reset_w, 0x000000ff) /* LTC1232 */ AM_RANGE(0x1f220000, 0x1f220003) AM_WRITE8(twinkle_io_w, 0x00ff00ff) AM_RANGE(0x1f220004, 0x1f220007) AM_READ8(twinkle_io_r, 0x00ff00ff) - AM_RANGE(0x1f230000, 0x1f230003) AM_WRITENOP + AM_RANGE(0x1f230000, 0x1f230003) AM_WRITE16(led_w, 0x0000ffff) AM_RANGE(0x1f240000, 0x1f240003) AM_READ_PORT("IN6") - AM_RANGE(0x1f250000, 0x1f250003) AM_WRITENOP + AM_RANGE(0x1f250000, 0x1f250003) AM_WRITE16(key_led_w, 0x0000ffff) AM_RANGE(0x1f260000, 0x1f260003) AM_WRITE16(serial_w, 0x0000ffff) AM_RANGE(0x1f270000, 0x1f270003) AM_WRITE_PORT("OUTSEC") AM_RANGE(0x1f280000, 0x1f280003) AM_READ_PORT("INSEC") @@ -764,7 +826,8 @@ WRITE16_MEMBER(twinkle_state::spu_ata_dma_low_w) WRITE16_MEMBER(twinkle_state::spu_ata_dma_high_w) { - m_spu_ata_dma = (m_spu_ata_dma & 0xffff) | (data << 16); + m_spu_ata_dma = (m_spu_ata_dma & 0xffff) | ((uint32_t)data << 16); + //printf("DMA now %x\n", m_spu_ata_dma); } WRITE_LINE_MEMBER(twinkle_state::spu_ata_dmarq) @@ -781,17 +844,10 @@ WRITE_LINE_MEMBER(twinkle_state::spu_ata_dmarq) { uint16_t data = m_ata->read_dma(); //printf("spu_ata_dmarq %08x %04x\n", m_spu_ata_dma * 2, data); - //waveram[m_spu_ata_dma++] = (data >> 8) | (data << 8); + m_waveram[m_wave_bank+m_spu_ata_dma] = data; //(data >> 8) | (data << 8); + m_spu_ata_dma++; // bp 4a0e ;bmiidx4 checksum // bp 4d62 ;bmiidx4 dma - - // $$$HACK - game DMAs nothing useful to 0x400000 but all sound plays are 0x400000 or above - // so limit sound RAM to 4MB (there's 6 MB on the board) and let the 5c400's address masking - // work for us until we figure out what's actually going on. - if (m_spu_ata_dma < 0x200000) - { - m_waveram[m_spu_ata_dma++] = data; - } } m_ata->write_dmack(CLEAR_LINE); @@ -799,14 +855,26 @@ WRITE_LINE_MEMBER(twinkle_state::spu_ata_dmarq) } } +WRITE16_MEMBER(twinkle_state::spu_wavebank_w) +{ + //printf("%x to wavebank_w, mask %04x\n", data, mem_mask); + + // banks are fairly clearly 8MB, so there's 3 of them in the 24 MB of RAM. + // the games load up the full 24MB of RAM 8 MB at a time, first to bank 1, + // then to bank 2, and finally to bank 3. + // + // neither the 68k nor DMA access wave RAM when the bank is 0. + m_wave_bank = data * (4*1024*1024); +} + READ16_MEMBER(twinkle_state::twinkle_waveram_r) { - return m_waveram[offset]; + return m_waveram[offset+m_wave_bank]; } WRITE16_MEMBER(twinkle_state::twinkle_waveram_w) { - COMBINE_DATA(&m_waveram[offset]); + COMBINE_DATA(&m_waveram[offset+m_wave_bank]); } READ16_MEMBER(twinkle_state::shared_68k_r) @@ -825,27 +893,34 @@ WRITE16_MEMBER(twinkle_state::shared_68k_w) m_spu_shared[offset] = data & 0xff; } -READ16_MEMBER(twinkle_state::unk_68k_r) +WRITE16_MEMBER(twinkle_state::spu_led_w) { - return 0xffff; // must return 0xff for 68000 POST to complete properly + // upper 8 bits are occassionally written as all zeros + output().set_indexed_value("spu_led", 0, (~data >> 0) & 1); + output().set_indexed_value("spu_led", 1, (~data >> 1) & 1); + output().set_indexed_value("spu_led", 2, (~data >> 2) & 1); + output().set_indexed_value("spu_led", 3, (~data >> 3) & 1); + output().set_indexed_value("spu_led", 4, (~data >> 4) & 1); + output().set_indexed_value("spu_led", 5, (~data >> 5) & 1); + output().set_indexed_value("spu_led", 6, (~data >> 6) & 1); + output().set_indexed_value("spu_led", 7, (~data >> 7) & 1); } static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 16, twinkle_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM AM_RANGE(0x100000, 0x13ffff) AM_RAM - AM_RANGE(0x200000, 0x200001) AM_READ(unk_68k_r) - // 220000 = LEDs? + AM_RANGE(0x200000, 0x200001) AM_READ_PORT("SPU_DSW") + AM_RANGE(0x220000, 0x220001) AM_WRITE(spu_led_w) AM_RANGE(0x230000, 0x230003) AM_WRITE(twinkle_spu_ctrl_w) - AM_RANGE(0x240000, 0x240003) AM_WRITE(spu_ata_dma_low_w) - AM_RANGE(0x250000, 0x250003) AM_WRITE(spu_ata_dma_high_w) - // 260000 = ??? + AM_RANGE(0x240000, 0x240003) AM_WRITE(spu_ata_dma_low_w) AM_READNOP + AM_RANGE(0x250000, 0x250003) AM_WRITE(spu_ata_dma_high_w) AM_READNOP + AM_RANGE(0x260000, 0x260001) AM_WRITE(spu_wavebank_w) AM_READNOP AM_RANGE(0x280000, 0x280fff) AM_READWRITE(shared_68k_r, shared_68k_w) AM_RANGE(0x300000, 0x30000f) AM_DEVREADWRITE("ata", ata_interface_device, read_cs0, write_cs0) // 34000E = ??? AM_RANGE(0x34000e, 0x34000f) AM_WRITENOP AM_RANGE(0x400000, 0x400fff) AM_DEVREADWRITE("rfsnd", rf5c400_device, rf5c400_r, rf5c400_w) - AM_RANGE(0x800000, 0xbfffff) AM_READWRITE(twinkle_waveram_r, twinkle_waveram_w ) - AM_RANGE(0xfe0000, 0xffffff) AM_RAM // ...and the RAM test checks this last 128k (mirror of the work RAM at 0x100000?) + AM_RANGE(0x800000, 0xffffff) AM_READWRITE(twinkle_waveram_r, twinkle_waveram_w) ADDRESS_MAP_END /* SCSI */ @@ -993,7 +1068,7 @@ static MACHINE_CONFIG_START( twinkle ) MCFG_SOUND_ROUTE( 0, "speakerleft", 0.75 ) MCFG_SOUND_ROUTE( 1, "speakerright", 0.75 ) - MCFG_RF5C400_ADD("rfsnd", 32000000/2) + MCFG_RF5C400_ADD("rfsnd", XTAL_33_8688MHz/2); MCFG_SOUND_ROUTE(0, "speakerleft", 1.0) MCFG_SOUND_ROUTE(1, "speakerright", 1.0) MACHINE_CONFIG_END @@ -1055,6 +1130,16 @@ static INPUT_PORTS_START( twinkle ) PORT_START("OUTSEC") PORT_START("INSEC") + + PORT_START("SPU_DSW") + PORT_DIPUNKNOWN_DIPLOC( 0x01, IP_ACTIVE_LOW, "SPU DSW:1" ) + PORT_DIPUNKNOWN_DIPLOC( 0x02, IP_ACTIVE_LOW, "SPU DSW:2" ) + PORT_DIPUNKNOWN_DIPLOC( 0x04, IP_ACTIVE_LOW, "SPU DSW:3" ) + PORT_DIPUNKNOWN_DIPLOC( 0x08, IP_ACTIVE_LOW, "SPU DSW:4" ) + PORT_DIPUNKNOWN_DIPLOC( 0x10, IP_ACTIVE_LOW, "SPU DSW:5" ) + PORT_DIPUNKNOWN_DIPLOC( 0x20, IP_ACTIVE_LOW, "SPU DSW:6" ) + PORT_DIPUNKNOWN_DIPLOC( 0x40, IP_ACTIVE_LOW, "SPU DSW:7" ) + PORT_DIPUNKNOWN_DIPLOC( 0x80, IP_ACTIVE_LOW, "SPU DSW:8" ) INPUT_PORTS_END static INPUT_PORTS_START( twinklex ) @@ -1087,7 +1172,7 @@ INPUT_PORTS_END ROM_REGION32_LE( 0x080000, "audiocpu", 0 )\ ROM_LOAD16_WORD_SWAP( "863a05.2x", 0x000000, 0x080000, CRC(6f42a09e) SHA1(cab5209f90f47b9ee6e721479913ad74e3ba84b1) )\ \ - ROM_REGION16_LE(0x400000, "rfsnd", ROMREGION_ERASE00) + ROM_REGION16_LE(0x2000000, "rfsnd", ROMREGION_ERASE00) // the first 8mb isn't populated ROM_START( gq863 ) TWINKLE_BIOS @@ -1333,20 +1418,20 @@ ROM_START( bmiidxc2 ) DISK_IMAGE_READONLY( "983hdda01", 0, SHA1(bcbbf55acf8bebc5773ffc5769420a0129f4da57) ) ROM_END -GAME( 1999, gq863, 0, twinkle, twinkle, twinkle_state, 0, ROT0, "Konami", "Twinkle System", MACHINE_IS_BIOS_ROOT ) - -GAME( 1999, bmiidx, gq863, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX (863 JAB)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1999, bmiidxa, bmiidx, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX (863 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1999, bmiidxc, gq863, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX with DDR 2nd Club Version (896 JAB)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1999, bmiidxca, bmiidxc, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX with DDR 2nd Club Version (896 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1999, bmiidxs, gq863, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX Substream (983 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1999, bmiidxc2, gq863, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX Substream with DDR 2nd Club Version 2 (984 A01 BM)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1999, bmiidx2, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 2nd style (GC985 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 2000, bmiidx3, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 3rd style (GC992 JAC)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 2000, bmiidx3a, bmiidx3, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 3rd style (GC992 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 2000, bmiidx4, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 4th style (GCA03 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 2001, bmiidx5, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 5th style (GCA17 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 2001, bmiidx6, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 6th style (GCB4U JAB)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 2001, bmiidx6a, bmiidx6, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 6th style (GCB4U JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 2002, bmiidx7, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 7th style (GCB44 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 2002, bmiidx8, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 8th style (GCC44 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) +GAMEL( 1999, gq863, 0, twinkle, twinkle, twinkle_state, 0, ROT0, "Konami", "Twinkle System", MACHINE_IS_BIOS_ROOT, layout_bmiidx ) + +GAMEL( 1999, bmiidx, gq863, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX (863 JAB)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING, layout_bmiidx ) +GAMEL( 1999, bmiidxa, bmiidx, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX (863 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING, layout_bmiidx ) +GAMEL( 1999, bmiidxc, gq863, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX with DDR 2nd Club Version (896 JAB)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING, layout_bmiidx ) +GAMEL( 1999, bmiidxca, bmiidxc, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX with DDR 2nd Club Version (896 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING, layout_bmiidx ) +GAMEL( 1999, bmiidxs, gq863, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX Substream (983 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING, layout_bmiidx ) +GAMEL( 1999, bmiidxc2, gq863, twinklex, twinklex, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX Substream with DDR 2nd Club Version 2 (984 A01 BM)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS, layout_bmiidx ) +GAMEL( 1999, bmiidx2, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 2nd style (GC985 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING, layout_bmiidx ) +GAMEL( 2000, bmiidx3, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 3rd style (GC992 JAC)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING, layout_bmiidx ) +GAMEL( 2000, bmiidx3a, bmiidx3, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 3rd style (GC992 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING, layout_bmiidx ) +GAMEL( 2000, bmiidx4, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 4th style (GCA03 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS, layout_bmiidx ) +GAMEL( 2001, bmiidx5, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 5th style (GCA17 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING, layout_bmiidx ) +GAMEL( 2001, bmiidx6, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 6th style (GCB4U JAB)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS, layout_bmiidx ) +GAMEL( 2001, bmiidx6a, bmiidx6, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 6th style (GCB4U JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS, layout_bmiidx ) +GAMEL( 2002, bmiidx7, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 7th style (GCB44 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS, layout_bmiidx ) +GAMEL( 2002, bmiidx8, gq863, twinklei, twinklei, twinkle_state, 0, ROT0, "Konami", "beatmania IIDX 8th style (GCC44 JAA)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS, layout_bmiidx ) diff --git a/src/mame/drivers/unichamp.cpp b/src/mame/drivers/unichamp.cpp index c6f23d02f62..301c03d49fd 100644 --- a/src/mame/drivers/unichamp.cpp +++ b/src/mame/drivers/unichamp.cpp @@ -77,6 +77,8 @@ public: DECLARE_READ16_MEMBER(unichamp_trapl_r); DECLARE_WRITE16_MEMBER(unichamp_trapl_w); + DECLARE_READ16_MEMBER(read_ff); + uint32_t screen_update_unichamp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); protected: @@ -106,7 +108,7 @@ static ADDRESS_MAP_START( unichamp_mem, AS_PROGRAM, 16, unichamp_state ) ADDRESS_MAP_GLOBAL_MASK(0x1FFF) //B13/B14/B15 are grounded! AM_RANGE(0x0000, 0x00FF) AM_READWRITE8(unichamp_gicram_r, unichamp_gicram_w, 0x00ff) AM_RANGE(0x0100, 0x07FF) AM_READWRITE(unichamp_trapl_r, unichamp_trapl_w) - AM_RANGE(0x0800, 0x17FF) AM_ROM AM_REGION("maincpu", 0x0800 << 1) // Carts and EXE ROM, 10-bits wide + AM_RANGE(0x0800, 0x0FFF) AM_ROM AM_REGION("maincpu", 0) // Carts and EXE ROM, 10-bits wide ADDRESS_MAP_END @@ -134,7 +136,7 @@ READ8_MEMBER(unichamp_state::bext_r) //The BEXT instruction pushes a user-defined nibble out on the four EBCA pins (EBCA0 to EBCA3) //and reads the ECBI input pin for HIGH or LOW signal to know whether or not to branch - //The unisonic control system couldnt be simpler in desing. + //The unisonic control system couldnt be simpler in design. //Each of the two player controllers has three buttons: //one tying !RESET(GIC pin 21) to ground when closed - resetting the WHOLE system. //a YES button (connecting EBCA0 to EBCI for Player1 and EBC2 to EBCI for Player2) @@ -154,6 +156,11 @@ DRIVER_INIT_MEMBER(unichamp_state,unichamp) { } +READ16_MEMBER(unichamp_state::read_ff) +{ + return 0xffff; +} + void unichamp_state::machine_start() { if (m_cart->exists()){ @@ -166,10 +173,11 @@ void unichamp_state::machine_start() ptr[i] = ptr[i+1]; ptr[i+1] = TEMP; } - - m_maincpu->space(AS_PROGRAM).install_read_handler(0x1000, 0x1800, + m_maincpu->space(AS_PROGRAM).install_read_handler(0x1000, 0x17ff, read16_delegate(FUNC(generic_slot_device::read16_rom),(generic_slot_device*)m_cart)); - } + } else + m_maincpu->space(AS_PROGRAM).install_read_handler(0x1000, 0x17ff, + read16_delegate(FUNC(unichamp_state::read_ff), this)); } /* Set Reset and INTR/INTRM Vector */ @@ -193,8 +201,9 @@ void unichamp_state::machine_reset() /* Set initial PC */ m_maincpu->set_state_int(cp1610_cpu_device::CP1610_R7, 0x0800); -} + memset(m_ram, 0, sizeof(m_ram)); +} uint32_t unichamp_state::screen_update_unichamp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { @@ -265,9 +274,9 @@ MACHINE_CONFIG_END ROM_START(unichamp) - ROM_REGION(0x10000<<1,"maincpu", ROMREGION_ERASEFF) + ROM_REGION(0x1000,"maincpu", ROMREGION_ERASEFF) - ROM_LOAD16_WORD( "9501-01009.u2", 0x0800<<1, 0x1000, CRC(49a0bd8f) SHA1(f4d126d3462ad351da4b75d76c75942d5a6f27ef)) + ROM_LOAD16_WORD( "9501-01009.u2", 0, 0x1000, CRC(49a0bd8f) SHA1(f4d126d3462ad351da4b75d76c75942d5a6f27ef)) //these below are for local tests. you can use them in softlist or -cart //ROM_LOAD16_WORD( "pac-02.bin", 0x1000<<1, 0x1000, CRC(fe3213be) SHA1(5b9c407fe86865f3454d4be824a7f2bf53478f73)) diff --git a/src/mame/drivers/univac.cpp b/src/mame/drivers/univac.cpp index 6386475511d..74b79251466 100644 --- a/src/mame/drivers/univac.cpp +++ b/src/mame/drivers/univac.cpp @@ -1,34 +1,58 @@ // license:BSD-3-Clause -// copyright-holders:Robbbert +// copyright-holders:Robbbert,Vas Crabb /*************************************************************************** - Univac Terminals +Univac Terminals - The terminals are models UTS20, UTS30, UTS40, UTS50 and SVT1120, - however only the UTS20 is dumped (program roms only). +2009-05-25 Skeleton driver - 25/05/2009 Skeleton driver +The terminals are models UTS20, UTS30, UTS40, UTS50 and SVT1120, +however only the UTS20 is dumped (program roms only). - The terminal has 2 screens selectable by the operator with the Fn + 1-2 - buttons. Thus the user can have two sessions open at once, to different - mainframes or applications. +There were other terminals (Uniscope 100/200/300/400) and UTS60, but +they had different hardware. Uniscope models are believed to use the i8080, +and the UTS60 was a colour graphics terminal with a MC68000 and 2 floppy drives. - Sound is a beeper. +The terminal has 2 screens selectable by the operator with the Fn + 1-2 +buttons. Thus the user can have two sessions open at once, to different +mainframes or applications. The keyboard connected to the terminal with +a coiled cord and a 9-pin D-connector. - This driver is all guesswork; Unisys never released technical info - to customers. All parts on the PCBs have internal Unisys part numbers - instead of the manufacturer's numbers. +Sound is a beeper. + +This driver is all guesswork; Unisys never released technical info +to customers. All parts on the PCBs have internal Unisys part numbers +instead of the manufacturer's numbers. + +Notes: +* Port $C6 probably controls serial loopback + - at a guess, bit 0 enables loopback on both channels +* The NVRAM is 4 bits wide on the LSBs, but (0x81) & 0x10 does something + - NVRAM nybbles are read/written on the LSBs of 64 ports 0x80 to 0xb4 + - Nybbles are packed/unpacked into 32 bytes starting at 0xd7d7 + - On boot it reads (0x81) & 0x10, and if set preserves 0xd831 to 0xd863 + - This has to be some kind of warm boot detection, but how does it work? ****************************************************************************/ #include "emu.h" #include "cpu/z80/z80.h" #include "cpu/z80/z80daisy.h" +#include "machine/clock.h" #include "machine/nvram.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" -#include "machine/clock.h" +#include "machine/z80sio.h" +#include "sound/beep.h" #include "screen.h" +#include "speaker.h" + +#define LOG_GENERAL (1U << 0) +#define LOG_PARITY (1U << 1) + +//#define VERBOSE (LOG_GENERAL | LOG_PARITY) +#include "logmacro.h" + +#define LOGPARITY(...) LOGMASKED(LOG_PARITY, __VA_ARGS__) class univac_state : public driver_device @@ -37,65 +61,146 @@ public: univac_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") - , m_p_videoram(*this, "videoram") , m_nvram(*this, "nvram") , m_ctc(*this, "ctc") - , m_dart(*this, "dart") + , m_uart(*this, "uart") + , m_beep(*this, "beeper") , m_p_chargen(*this, "chargen") + , m_p_videoram(*this, "videoram") + , m_p_nvram(*this, "nvram") + , m_bank_mask(0) + , m_parity_check(0) + , m_parity_poison(0) + , m_framecnt(0) { } - DECLARE_READ8_MEMBER(vram_r); - DECLARE_WRITE8_MEMBER(vram_w); + DECLARE_READ8_MEMBER(ram_r); + DECLARE_READ8_MEMBER(bank_r); + DECLARE_WRITE8_MEMBER(ram_w); + DECLARE_WRITE8_MEMBER(bank_w); + DECLARE_WRITE8_MEMBER(nvram_w); + DECLARE_WRITE8_MEMBER(port43_w); - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + DECLARE_WRITE8_MEMBER(portc4_w); + DECLARE_WRITE8_MEMBER(porte6_w); -private: - bool m_screen_num; - uint8_t m_framecnt; + u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + +protected: virtual void machine_start() override; virtual void machine_reset() override; - required_device<cpu_device> m_maincpu; - required_shared_ptr<uint8_t> m_p_videoram; - required_device<nvram_device> m_nvram; - required_device<z80ctc_device> m_ctc; - required_device<z80dart_device> m_dart; + virtual void device_post_load() override; + +private: + required_device<cpu_device> m_maincpu; + required_device<nvram_device> m_nvram; + required_device<z80ctc_device> m_ctc; + required_device<z80sio_device> m_uart; + required_device<beep_device> m_beep; + required_region_ptr<u8> m_p_chargen; + required_shared_ptr<u8> m_p_videoram; + required_shared_ptr<u8> m_p_nvram; + std::unique_ptr<u8 []> m_p_parity; + + u16 m_bank_mask; + u8 m_parity_check; + u8 m_parity_poison; + u8 m_framecnt; }; +READ8_MEMBER( univac_state::ram_r ) +{ + if (BIT(m_p_parity[offset >> 3], offset & 0x07) && !machine().side_effect_disabled()) + { + LOGPARITY("parity check failed offset = %04X\n", offset); + m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); + } + return m_p_videoram[offset]; +} + +READ8_MEMBER( univac_state::bank_r ) +{ + return space.read_byte((0xc000 | offset) ^ m_bank_mask); +} + +WRITE8_MEMBER( univac_state::ram_w ) +{ + if (m_parity_poison) + { + LOGPARITY("poison parity offset = %04X\n", offset); + m_p_parity[offset >> 3] |= u8(1) << (offset & 0x07); + } + else + { + m_p_parity[offset >> 3] &= ~(u8(1) << (offset & 0x07)); + } + m_p_videoram[offset] = data; +} + +WRITE8_MEMBER( univac_state::bank_w ) +{ + space.write_byte((0xc000 | offset) ^ m_bank_mask, data); +} + +WRITE8_MEMBER( univac_state::nvram_w ) +{ + // NVRAM is four bits wide, accessed in the low nybble + // It's simplest to hack it when writing to make the upper bits read back high on the open bus + m_p_nvram[offset] = data | 0xf0; +} + WRITE8_MEMBER( univac_state::port43_w ) { - m_screen_num = BIT(data, 0); + m_bank_mask = BIT(data, 0) ? 0x2000 : 0x0000; } -READ8_MEMBER( univac_state::vram_r ) +WRITE8_MEMBER( univac_state::portc4_w ) { - offs_t offs = (offset & 0x1fff) ^ (BIT(offset, 13) ? 0x2000 : 0) ^ (m_screen_num ? 0x2000 : 0); - return m_p_videoram[offs]; + m_parity_poison = BIT(data, 0); + u8 const check = BIT(data, 1); + if (check != m_parity_check) + { + m_parity_check = check; + address_space &space(m_maincpu->space(AS_PROGRAM)); + space.unmap_read(0xc000, 0xffff); + if (check) + { + LOGPARITY("parity check enabled\n"); + space.install_read_handler(0xc000, 0xffff, read8_delegate(FUNC(univac_state::ram_r), this)); + } + else + { + LOGPARITY("parity check disabled\n"); + space.install_rom(0xc000, 0xffff, &m_p_videoram[0]); + } + } } -WRITE8_MEMBER( univac_state::vram_w ) +WRITE8_MEMBER( univac_state::porte6_w ) { - offs_t offs = (offset & 0x1fff) ^ (BIT(offset, 13) ? 0x2000 : 0) ^ (m_screen_num ? 0x2000 : 0); - m_p_videoram[offs] = data; + m_beep->set_state(BIT(data, 0)); } -static ADDRESS_MAP_START(uts20_mem, AS_PROGRAM, 8, univac_state) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, univac_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0x4fff ) AM_ROM AM_REGION("roms", 0) - AM_RANGE( 0x8000, 0xbfff ) AM_READWRITE(vram_r,vram_w) - AM_RANGE( 0xc000, 0xffff ) AM_RAM AM_SHARE("videoram") + AM_RANGE( 0x8000, 0xbfff ) AM_READWRITE(bank_r, bank_w) + AM_RANGE( 0xc000, 0xffff ) AM_RAM_WRITE(ram_w) AM_SHARE("videoram") ADDRESS_MAP_END -static ADDRESS_MAP_START( uts20_io, AS_IO, 8, univac_state) +static ADDRESS_MAP_START( io_map, AS_IO, 8, univac_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("dart", z80dart_device, cd_ba_r, cd_ba_w) + AM_RANGE(0x00, 0x03) AM_DEVREADWRITE("uart", z80sio_device, cd_ba_r, cd_ba_w) AM_RANGE(0x20, 0x23) AM_DEVREADWRITE("ctc", z80ctc_device, read, write) AM_RANGE(0x43, 0x43) AM_WRITE(port43_w) - AM_RANGE(0x80, 0xbf) AM_RAM AM_SHARE("nvram") + AM_RANGE(0x80, 0xbf) AM_RAM_WRITE(nvram_w) AM_SHARE("nvram") + AM_RANGE(0xc4, 0xc4) AM_WRITE(portc4_w) + AM_RANGE(0xe6, 0xe6) AM_WRITE(porte6_w) ADDRESS_MAP_END /* Input ports */ @@ -105,26 +210,42 @@ INPUT_PORTS_END void univac_state::machine_start() { -// D7DC and D7DD are checked for valid RID and SID (usually 21 and 51) if not valid then NVRAM gets initialised. + // D7DC and D7DD are checked for valid RID and SID (usually 21 and 51) if not valid then NVRAM gets initialised. + + std::size_t const parity_bytes = (m_p_videoram.bytes() + 7) / 8; + m_p_parity.reset(new u8[parity_bytes]); + std::fill_n(m_p_parity.get(), parity_bytes, 0); + + save_pointer(NAME(m_p_parity.get()), parity_bytes); + save_item(NAME(m_bank_mask)); + save_item(NAME(m_parity_check)); + save_item(NAME(m_parity_poison)); + save_item(NAME(m_framecnt)); } void univac_state::machine_reset() { - m_screen_num = 0; + m_beep->set_state(0); + + m_bank_mask = 0x0000; + m_parity_check = 0; + m_parity_poison = 0; } -uint32_t univac_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +void univac_state::device_post_load() { - // this is used to get the ctc to pass the test - bool state = BIT(m_framecnt,0); - m_ctc->trg0(state); - m_ctc->trg1(state); - m_ctc->trg2(state); - m_ctc->trg3(state); + if (m_parity_check) + { + address_space &space(m_maincpu->space(AS_PROGRAM)); + space.unmap_read(0xc000, 0xffff); + space.install_read_handler(0xc000, 0xffff, read8_delegate(FUNC(univac_state::ram_r), this)); + } +} +uint32_t univac_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ uint8_t y,ra,chr,gfx; - uint16_t sy=0,ma=0,x; - uint8_t *videoram = m_p_videoram;//+(m_screen_num ? 0x2000 : 0); + uint16_t sy=0,x,ma=0; //m_bank_mask; (it isn't port43 that selects the screen) m_framecnt++; @@ -136,7 +257,7 @@ uint32_t univac_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap for (x = ma; x < ma + 80; x++) { - chr = videoram[x]; + chr = m_p_videoram[x]; /* Take care of 'corner' characters */ if (((chr == 0x1c) || (chr == 0x1d)) && (m_framecnt & 16)) @@ -160,18 +281,36 @@ uint32_t univac_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap return 0; } +/* F4 Character Displayer */ +static const gfx_layout c10_charlayout = +{ + 8, 9, /* 8 x 9 characters */ + 512, /* 512 characters */ + 1, /* 1 bits per pixel */ + { 0 }, /* no bitplanes */ + /* x offsets */ + { 0, 1, 2, 3, 4, 5, 6, 7 }, + /* y offsets */ + { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8 }, + 8*16 /* every char takes 16 bytes */ +}; + +static GFXDECODE_START( c10 ) + GFXDECODE_ENTRY( "chargen", 0x0000, c10_charlayout, 0, 1 ) +GFXDECODE_END + static const z80_daisy_config daisy_chain[] = { - { "dart" }, + { "uart" }, { "ctc" }, { nullptr } }; static MACHINE_CONFIG_START( uts20 ) /* basic machine hardware */ - MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) // unknown clock - MCFG_CPU_PROGRAM_MAP(uts20_mem) - MCFG_CPU_IO_MAP(uts20_io) + MCFG_CPU_ADD("maincpu", Z80, XTAL_4MHz) // unknown clock + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MCFG_Z80_DAISY_CHAIN(daisy_chain) /* video hardware */ @@ -183,19 +322,33 @@ static MACHINE_CONFIG_START( uts20 ) MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 249) MCFG_SCREEN_PALETTE("palette") MCFG_PALETTE_ADD_MONOCHROME("palette") + MCFG_GFXDECODE_ADD("gfxdecode", "palette", c10) MCFG_NVRAM_ADD_1FILL("nvram") - MCFG_DEVICE_ADD("uart_clock", CLOCK, 153600) - MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("dart", z80dart_device, txca_w)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("dart", z80dart_device, rxca_w)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("dart", z80dart_device, txcb_w)) - MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("dart", z80dart_device, rxcb_w)) + MCFG_DEVICE_ADD("ctc_clock", CLOCK, 2000000) + MCFG_CLOCK_SIGNAL_HANDLER(DEVWRITELINE("ctc", z80ctc_device, trg0)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc", z80ctc_device, trg1)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc", z80ctc_device, trg2)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("ctc", z80ctc_device, trg3)) MCFG_DEVICE_ADD("ctc", Z80CTC, XTAL_4MHz) MCFG_Z80CTC_INTR_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) - MCFG_DEVICE_ADD("dart", Z80DART, XTAL_4MHz) - MCFG_Z80DART_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80CTC_ZC1_CB(DEVWRITELINE("uart", z80sio_device, txca_w)) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart", z80sio_device, rxca_w)) + MCFG_Z80CTC_ZC2_CB(DEVWRITELINE("uart", z80sio_device, rxtxcb_w)) + + MCFG_DEVICE_ADD("uart", Z80SIO, XTAL_4MHz) + MCFG_Z80SIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) + MCFG_Z80SIO_OUT_TXDA_CB(DEVWRITELINE("uart", z80sio_device, rxa_w)) // FIXME: hacked in permanent loopback to pass test + MCFG_Z80SIO_OUT_TXDB_CB(DEVWRITELINE("uart", z80sio_device, rxb_w)) // FIXME: hacked in permanent loopback to pass test + MCFG_Z80SIO_OUT_WRDYB_CB(DEVWRITELINE("uart", z80sio_device, dcdb_w)) // FIXME: hacked in permanent loopback to pass test + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart", z80sio_device, ctsb_w)) // FIXME: hacked in permanent loopback to pass test + + /* Sound */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_SOUND_ADD("beeper", BEEP, 950) // guess + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.05) MACHINE_CONFIG_END @@ -207,16 +360,47 @@ ROM_START( uts20 ) ROM_LOAD( "uts20c.rom", 0x2000, 0x1000, CRC(4e334705) SHA1(ff1a730551b42f29d20af8ecc4495fd30567d35b) ) ROM_LOAD( "uts20d.rom", 0x3000, 0x1000, CRC(76757cf7) SHA1(b0509d9a35366b21955f83ec3685163844c4dbf1) ) ROM_LOAD( "uts20e.rom", 0x4000, 0x1000, CRC(0dfc8062) SHA1(cd681020bfb4829d4cebaf1b5bf618e67b55bda3) ) - ROM_FILL(0x2bd,1,0xaf) // test 2 - ROM_FILL(0x3c1,2,0xaf) // test 5 - ROM_FILL(0x928,1,0x00) /* character generator not dumped, using the one from 'c10' for now */ ROM_REGION( 0x2000, "chargen", 0 ) ROM_LOAD("c10_char.bin", 0x0000, 0x2000, BAD_DUMP CRC(cb530b6f) SHA1(95590bbb433db9c4317f535723b29516b9b9fcbf) ) + // create special unisys gfx + ROM_FILL(0x1C0, 0x30, 0) + // left corner + ROM_FILL(0x1C0, 1, 0xF8) + ROM_FILL(0x1C1, 1, 0xF0) + ROM_FILL(0x1C2, 1, 0xE0) + ROM_FILL(0x1C3, 1, 0xC0) + ROM_FILL(0x1C4, 1, 0x80) + // right corner + ROM_FILL(0x1D0, 1, 0x1F) + ROM_FILL(0x1D1, 1, 0x0F) + ROM_FILL(0x1D2, 1, 0x07) + ROM_FILL(0x1D3, 1, 0x03) + ROM_FILL(0x1D4, 1, 0x01) + // SOE + ROM_FILL(0x1E0, 1, 0x80) + ROM_FILL(0x1E1, 1, 0xC0) + ROM_FILL(0x1E2, 1, 0xE0) + ROM_FILL(0x1E3, 1, 0xF0) + ROM_FILL(0x1E4, 1, 0xF8) + ROM_FILL(0x1E5, 1, 0xF0) + ROM_FILL(0x1E6, 1, 0xE0) + ROM_FILL(0x1E7, 1, 0xC0) + ROM_FILL(0x1E8, 1, 0x80) + // cursor + ROM_FILL(0x000, 1, 0x7F) + ROM_FILL(0x001, 1, 0x7E) + ROM_FILL(0x002, 1, 0x7C) + ROM_FILL(0x003, 1, 0x79) + ROM_FILL(0x004, 1, 0x73) + ROM_FILL(0x005, 1, 0x67) + ROM_FILL(0x006, 1, 0x4F) + ROM_FILL(0x007, 1, 0x1F) + ROM_FILL(0x008, 1, 0x7F) ROM_END /* Driver */ // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1980, uts20, 0, 0, uts20, uts20, univac_state, 0, "Sperry Univac", "UTS-20", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +COMP( 1980, uts20, 0, 0, uts20, uts20, univac_state, 0, "Sperry Univac", "UTS-20", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/unixpc.cpp b/src/mame/drivers/unixpc.cpp index 4f5102e862e..1edc150534c 100644 --- a/src/mame/drivers/unixpc.cpp +++ b/src/mame/drivers/unixpc.cpp @@ -338,7 +338,7 @@ static MACHINE_CONFIG_START( unixpc ) MCFG_DEVICE_ADD("ramrombank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(ramrombank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400000) // floppy diff --git a/src/mame/drivers/upscope.cpp b/src/mame/drivers/upscope.cpp index ac732c80370..ab10bdd9dd9 100644 --- a/src/mame/drivers/upscope.cpp +++ b/src/mame/drivers/upscope.cpp @@ -265,8 +265,8 @@ static MACHINE_CONFIG_START( upscope ) MCFG_DEVICE_ADD("overlay", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(overlay_512kb_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(22) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(22) MCFG_ADDRESS_MAP_BANK_STRIDE(0x200000) MCFG_NVRAM_ADD_0FILL("nvram") diff --git a/src/mame/drivers/v6809.cpp b/src/mame/drivers/v6809.cpp index 09eab4db5ff..c9a27f1ea2f 100644 --- a/src/mame/drivers/v6809.cpp +++ b/src/mame/drivers/v6809.cpp @@ -117,10 +117,8 @@ static ADDRESS_MAP_START(v6809_mem, AS_PROGRAM, 8, v6809_state) AM_RANGE(0xf000, 0xf000) AM_MIRROR(0xfe) AM_DEVREAD("crtc", mc6845_device, status_r) AM_WRITE(v6809_address_w) AM_RANGE(0xf001, 0xf001) AM_MIRROR(0xfe) AM_DEVREAD("crtc", mc6845_device, register_r) AM_WRITE(v6809_register_w) AM_RANGE(0xf200, 0xf200) AM_MIRROR(0xff) AM_WRITE(videoram_w) - AM_RANGE(0xf500, 0xf500) AM_MIRROR(0x36) AM_DEVREADWRITE("acia0", acia6850_device, status_r, control_w) // modem - AM_RANGE(0xf501, 0xf501) AM_MIRROR(0x36) AM_DEVREADWRITE("acia0", acia6850_device, data_r, data_w) - AM_RANGE(0xf508, 0xf508) AM_MIRROR(0x36) AM_DEVREADWRITE("acia1", acia6850_device, status_r, control_w) // printer - AM_RANGE(0xf509, 0xf509) AM_MIRROR(0x36) AM_DEVREADWRITE("acia1", acia6850_device, data_r, data_w) + AM_RANGE(0xf500, 0xf501) AM_MIRROR(0x36) AM_DEVREADWRITE("acia0", acia6850_device, read, write) // modem + AM_RANGE(0xf508, 0xf509) AM_MIRROR(0x36) AM_DEVREADWRITE("acia1", acia6850_device, read, write) // printer AM_RANGE(0xf600, 0xf603) AM_MIRROR(0x3c) AM_DEVREADWRITE("fdc", mb8876_device, read, write) AM_RANGE(0xf640, 0xf64f) AM_MIRROR(0x30) AM_DEVREADWRITE("rtc", mm58274c_device, read, write) AM_RANGE(0xf680, 0xf683) AM_MIRROR(0x3c) AM_DEVREADWRITE("pia0", pia6821_device, read, write) diff --git a/src/mame/drivers/vcs80.cpp b/src/mame/drivers/vcs80.cpp index 7cc93cef46e..2fbbcf7fa48 100644 --- a/src/mame/drivers/vcs80.cpp +++ b/src/mame/drivers/vcs80.cpp @@ -236,7 +236,7 @@ static MACHINE_CONFIG_START( vcs80 ) MCFG_DEVICE_ADD("bdmem", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vcs80_bd_mem) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MACHINE_CONFIG_END diff --git a/src/mame/drivers/vectrix.cpp b/src/mame/drivers/vectrix.cpp new file mode 100644 index 00000000000..792e5696572 --- /dev/null +++ b/src/mame/drivers/vectrix.cpp @@ -0,0 +1,61 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-02 Skeleton + +Vectrix Graphics Processor. The VX384 was the main model, with 384K of RAM, and used an analog monitor. + The VX128 was the cheaper model with 128K of RAM and less colours. It used a TTL-level monitor. + Don't know which one this is, but VX384 is assumed. + +It replaced your serial or centronics printer, which then plugged into the unit instead. The unit could be considered as a +terminal which could decode simple commands into complex graphics. + + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/i86/i86.h" +#include "machine/i8251.h" + +class vectrix_state : public driver_device +{ +public: + vectrix_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) +// , m_maincpu(*this, "maincpu") + { } + +private: +// required_device<cpu_device> m_maincpu; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, vectrix_state ) + AM_RANGE(0x00000,0x07fff) AM_RAM + AM_RANGE(0x0c000,0x0ffff) AM_ROM AM_REGION("roms", 0) + AM_RANGE(0xfc000,0xfffff) AM_ROM AM_REGION("roms", 0) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_PROGRAM, 8, vectrix_state ) + AM_RANGE(0x3000, 0x3000) AM_DEVREADWRITE("uart1", i8251_device, data_r, data_w) + AM_RANGE(0x3001, 0x3001) AM_DEVREADWRITE("uart1", i8251_device, status_r, control_w) +ADDRESS_MAP_END + +static INPUT_PORTS_START( vectrix ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( vectrix ) + MCFG_CPU_ADD("maincpu", I8088, XTAL_14_31818MHz/3) // no idea of clock + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + + MCFG_DEVICE_ADD("uart1", I8251, 0) +MACHINE_CONFIG_END + +ROM_START( vectrix ) + ROM_REGION( 0x4000, "roms", 0 ) + ROM_LOAD( "vectrixl.bin", 0x0000, 0x2000, CRC(10b93e38) SHA1(0b1a23d384bfde4cd27c482f667eedd94f8f2406) ) + ROM_LOAD( "vectrixr.bin", 0x2000, 0x2000, CRC(33f9b06b) SHA1(6a1dffe5c2c0254824a8dddb8543f86d9ad8f173) ) +ROM_END + +COMP( 1983, vectrix, 0, 0, vectrix, vectrix, vectrix_state, 0, "Vectrix", "VX384 Graphics Processor Terminal", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/vendetta.cpp b/src/mame/drivers/vendetta.cpp index 25f940718f2..838fae4d76b 100644 --- a/src/mame/drivers/vendetta.cpp +++ b/src/mame/drivers/vendetta.cpp @@ -429,15 +429,15 @@ static MACHINE_CONFIG_START( vendetta ) MCFG_DEVICE_ADD("videobank0", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(videobank0_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MCFG_DEVICE_ADD("videobank1", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(videobank1_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MCFG_CPU_ADD("audiocpu", Z80, XTAL_3_579545MHz) /* verified with PCB */ diff --git a/src/mame/drivers/vgmplay.cpp b/src/mame/drivers/vgmplay.cpp index 0a5b117c45c..ed094c13dbe 100644 --- a/src/mame/drivers/vgmplay.cpp +++ b/src/mame/drivers/vgmplay.cpp @@ -37,6 +37,16 @@ #define AS_IO16 1 #define MCFG_CPU_IO16_MAP MCFG_CPU_DATA_MAP +class vgmplay_disassembler : public util::disasm_interface +{ +public: + vgmplay_disassembler() = default; + virtual ~vgmplay_disassembler() = default; + + virtual uint32_t opcode_alignment() const override; + virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override; +}; + class vgmplay_device : public cpu_device { public: @@ -90,9 +100,7 @@ public: virtual void state_export(const device_state_entry &entry) override; virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; - virtual uint32_t disasm_min_opcode_bytes() const override; - virtual uint32_t disasm_max_opcode_bytes() const override; - virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual util::disasm_interface *create_disassembler() override; READ8_MEMBER(segapcm_rom_r); READ8_MEMBER(ymf271_rom_r); @@ -580,104 +588,104 @@ void vgmplay_device::state_string_export(const device_state_entry &entry, std::s { } -uint32_t vgmplay_device::disasm_min_opcode_bytes() const +util::disasm_interface *vgmplay_device::create_disassembler() { - return 1; + return new vgmplay_disassembler; } -uint32_t vgmplay_device::disasm_max_opcode_bytes() const +uint32_t vgmplay_disassembler::opcode_alignment() const { - return 9; + return 1; } -offs_t vgmplay_device::disasm_disassemble(std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) +offs_t vgmplay_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { - switch(oprom[0]) { + switch(opcodes.r8(pc)) { case 0x4f: - util::stream_format(stream, "psg r06 = %02x", oprom[1]); - return 2 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "psg r06 = %02x", opcodes.r8(pc+1)); + return 2 | SUPPORTED; case 0x50: - util::stream_format(stream, "psg write %02x", oprom[1]); - return 2 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "psg write %02x", opcodes.r8(pc+1)); + return 2 | SUPPORTED; case 0x51: - util::stream_format(stream, "ym2413 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2413 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x52: - util::stream_format(stream, "ym2612.0 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2612.0 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x53: - util::stream_format(stream, "ym2612.1 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2612.1 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x54: - util::stream_format(stream, "ym2151 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2151 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x55: - util::stream_format(stream, "ym2203a r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2203a r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x56: - util::stream_format(stream, "ym2608.0 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2608.0 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x57: - util::stream_format(stream, "ym2608.1 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2608.1 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x58: - util::stream_format(stream, "ym2610.0 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2610.0 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x59: - util::stream_format(stream, "ym2610.1 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2610.1 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x5a: - util::stream_format(stream, "ym3812 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym3812 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x5b: - util::stream_format(stream, "ym3526 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym3526 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x5c: - util::stream_format(stream, "y8950 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "y8950 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x5d: - util::stream_format(stream, "ymz280b r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ymz280b r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x5e: - util::stream_format(stream, "ymf262.0 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ymf262.0 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x5f: - util::stream_format(stream, "ymf262.1 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ymf262.1 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0x61: { - uint32_t duration = oprom[1] | (oprom[2] << 8); + uint32_t duration = opcodes.r8(pc+1) | (opcodes.r8(pc+2) << 8); util::stream_format(stream, "wait %d", duration); - return 3 | DASMFLAG_SUPPORTED; + return 3 | SUPPORTED; } case 0x62: util::stream_format(stream, "wait 735"); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; case 0x63: util::stream_format(stream, "wait 882"); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; case 0x66: util::stream_format(stream, "end"); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; case 0x67: { static const char *const basic_types[8] = { @@ -725,8 +733,8 @@ offs_t vgmplay_device::disasm_disassemble(std::ostream &stream, offs_t pc, const "es5503 ram" }; - uint8_t type = oprom[2]; - uint32_t size = oprom[3] | (oprom[4] << 8) | (oprom[5] << 16) | (oprom[6] << 24); + uint8_t type = opcodes.r8(pc+2); + uint32_t size = opcodes.r8(pc+3) | (opcodes.r8(pc+4) << 8) | (opcodes.r8(pc+5) << 16) | (opcodes.r8(pc+6) << 24); if(type < 0x8) util::stream_format(stream, "data-block %x, %s", size, basic_types[type]); else if(type < 0x40) @@ -736,7 +744,7 @@ offs_t vgmplay_device::disasm_disassemble(std::ostream &stream, offs_t pc, const else if(type < 0x7f) util::stream_format(stream, "data-block %x comp., %02x", size, type & 0x3f); else if(type < 0x80) - util::stream_format(stream, "decomp-table %x, %02x/%02x", size, oprom[7], oprom[8]); + util::stream_format(stream, "decomp-table %x, %02x/%02x", size, opcodes.r8(pc+7), opcodes.r8(pc+8)); else if(type < 0x94) util::stream_format(stream, "data-block %x, %s", size, rom_types[type & 0x7f]); else if(type < 0xc0) @@ -749,135 +757,135 @@ offs_t vgmplay_device::disasm_disassemble(std::ostream &stream, offs_t pc, const util::stream_format(stream, "data-block %x, %s", size, ram2_types[type & 0x1f]); else util::stream_format(stream, "data-block %x, ram %02x", size, type); - return (7+size) | DASMFLAG_SUPPORTED; + return (7+size) | SUPPORTED; } case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: - util::stream_format(stream, "wait %d", 1+(oprom[0] & 0x0f)); - return 1 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "wait %d", 1+(opcodes.r8(pc) & 0x0f)); + return 1 | SUPPORTED; case 0x80: util::stream_format(stream, "ym2612.0 r2a = rom++"); - return 1 | DASMFLAG_SUPPORTED; + return 1 | SUPPORTED; case 0x81: case 0x82: case 0x83: case 0x84: case 0x85: case 0x86: case 0x87: case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f: - util::stream_format(stream, "ym2612.0 r2a = rom++; wait %d", oprom[0] & 0xf); - return 1 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2612.0 r2a = rom++; wait %d", opcodes.r8(pc) & 0xf); + return 1 | SUPPORTED; case 0xa0: - util::stream_format(stream, "ay8910 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ay8910 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xa5: - util::stream_format(stream, "ym2203b r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ym2203b r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xb0: - util::stream_format(stream, "rf5c68 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "rf5c68 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xb1: - util::stream_format(stream, "rf5c164 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "rf5c164 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xb2: - util::stream_format(stream, "pwm r%x = %03x", oprom[1] >> 4, oprom[2] | ((oprom[1] & 0xf) << 8)); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "pwm r%x = %03x", opcodes.r8(pc+1) >> 4, opcodes.r8(pc+2) | ((opcodes.r8(pc+1) & 0xf) << 8)); + return 3 | SUPPORTED; case 0xb3: - util::stream_format(stream, "dmg r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "dmg r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xb4: - util::stream_format(stream, "nesapu r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "nesapu r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xb5: - util::stream_format(stream, "multipcm r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "multipcm r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xb6: - util::stream_format(stream, "upd7759 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "upd7759 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xb7: - util::stream_format(stream, "okim6258 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "okim6258 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xb8: - util::stream_format(stream, "okim6295 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "okim6295 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xb9: - util::stream_format(stream, "huc6280 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "huc6280 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xba: - util::stream_format(stream, "k053260 r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "k053260 r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xbb: - util::stream_format(stream, "pokey r%02x = %02x", oprom[1], oprom[2]); - return 3 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "pokey r%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2)); + return 3 | SUPPORTED; case 0xc0: - util::stream_format(stream, "segapcm %04x = %02x", oprom[1] | (oprom[2] << 8), oprom[3]); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "segapcm %04x = %02x", opcodes.r8(pc+1) | (opcodes.r8(pc+2) << 8), opcodes.r8(pc+3)); + return 4 | SUPPORTED; case 0xc1: - util::stream_format(stream, "rf5c68 %04x = %02x", oprom[1] | (oprom[2] << 8), oprom[3]); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "rf5c68 %04x = %02x", opcodes.r8(pc+1) | (opcodes.r8(pc+2) << 8), opcodes.r8(pc+3)); + return 4 | SUPPORTED; case 0xc2: - util::stream_format(stream, "rf5c163 %04x = %02x", oprom[1] | (oprom[2] << 8), oprom[3]); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "rf5c163 %04x = %02x", opcodes.r8(pc+1) | (opcodes.r8(pc+2) << 8), opcodes.r8(pc+3)); + return 4 | SUPPORTED; case 0xc3: - util::stream_format(stream, "multipcm c%02x.off = %04x", oprom[1], oprom[2] | (oprom[3] << 8)); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "multipcm c%02x.off = %04x", opcodes.r8(pc+1), opcodes.r8(pc+2) | (opcodes.r8(pc+3) << 8)); + return 4 | SUPPORTED; case 0xc4: - util::stream_format(stream, "qsound %02x = %04x", oprom[3], oprom[2] | (oprom[1] << 8)); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "qsound %02x = %04x", opcodes.r8(pc+3), opcodes.r8(pc+2) | (opcodes.r8(pc+1) << 8)); + return 4 | SUPPORTED; case 0xd0: - util::stream_format(stream, "ymf278b r%02x.%02x = %02x", oprom[1], oprom[2], oprom[3]); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ymf278b r%02x.%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2), opcodes.r8(pc+3)); + return 4 | SUPPORTED; case 0xd1: - util::stream_format(stream, "ymf271 r%02x.%02x = %02x", oprom[1], oprom[2], oprom[3]); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "ymf271 r%02x.%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2), opcodes.r8(pc+3)); + return 4 | SUPPORTED; case 0xd2: - util::stream_format(stream, "scc1 r%02x.%02x = %02x", oprom[1], oprom[2], oprom[3]); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "scc1 r%02x.%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2), opcodes.r8(pc+3)); + return 4 | SUPPORTED; case 0xd3: - util::stream_format(stream, "k054539 r%02x.%02x = %02x", oprom[1], oprom[2], oprom[3]); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "k054539 r%02x.%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2), opcodes.r8(pc+3)); + return 4 | SUPPORTED; case 0xd4: - util::stream_format(stream, "c140 r%02x.%02x = %02x", oprom[1], oprom[2], oprom[3]); - return 4 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "c140 r%02x.%02x = %02x", opcodes.r8(pc+1), opcodes.r8(pc+2), opcodes.r8(pc+3)); + return 4 | SUPPORTED; case 0xe0: { - uint32_t off = oprom[1] | (oprom[2] << 8) | (oprom[3] << 16) | (oprom[4] << 24); + uint32_t off = opcodes.r8(pc+1) | (opcodes.r8(pc+2) << 8) | (opcodes.r8(pc+3) << 16) | (opcodes.r8(pc+4) << 24); util::stream_format(stream, "ym2612 offset = %x", off); - return 5 | DASMFLAG_SUPPORTED; + return 5 | SUPPORTED; } case 0xe1: { - uint16_t addr = (oprom[1] << 8) | oprom[2]; - uint16_t data = (oprom[3] << 8) | oprom[4]; + uint16_t addr = (opcodes.r8(pc+1) << 8) | opcodes.r8(pc+2); + uint16_t data = (opcodes.r8(pc+3) << 8) | opcodes.r8(pc+4); util::stream_format(stream, "c352 r%04x = %04x", addr, data); - return 5 | DASMFLAG_SUPPORTED; + return 5 | SUPPORTED; } default: - util::stream_format(stream, "?? %02x", oprom[0]); - return 1 | DASMFLAG_SUPPORTED; + util::stream_format(stream, "?? %02x", opcodes.r8(pc)); + return 1 | SUPPORTED; } } diff --git a/src/mame/drivers/vicdual.cpp b/src/mame/drivers/vicdual.cpp index fa493668e3b..e8564c07243 100644 --- a/src/mame/drivers/vicdual.cpp +++ b/src/mame/drivers/vicdual.cpp @@ -57,6 +57,7 @@ #include "audio/depthch.h" #include "audio/invinco.h" #include "audio/pulsar.h" +#include "audio/tranqgun.h" #include "audio/vicdual.h" #include "audio/vicdual-97271p.h" #include "video/vicdual-97269pb.h" @@ -675,23 +676,26 @@ static INPUT_PORTS_START( supcrash ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) - PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) ) // both this and the following switch seem to select between 5 and 6 lives? but in combination with 0x02 of IN1 you can get 3 and 4 lives? PORT_DIPSETTING( 0x10, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) ) PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) ) + PORT_DIPNAME( 0x40, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_START("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, vicdual_state, get_timer_value, nullptr) + PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) ) // see comment above + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) PORT_DIPNAME( 0x04, 0x04, "Rom Test" ) PORT_DIPSETTING( 0x04, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_BIT( 0x7a, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */ + PORT_BIT( 0x78, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, vicdual_state, read_coin_status, nullptr) PORT_COIN_DEFAULT @@ -809,28 +813,22 @@ MACHINE_CONFIG_END * *************************************/ -READ8_MEMBER(vicdual_state::headon2_io_r) +READ8_MEMBER( vicdual_state::headon2_io_r ) { - uint8_t ret = 0; + uint8_t data = 0xff; - if (offset & 0x01) ret = m_in0->read(); - if (offset & 0x02) { /* schematics show this as in input port, but never read from */ } - if (offset & 0x04) ret = m_in1->read(); - if (offset & 0x08) ret = m_in2->read(); - if (offset & 0x12) logerror("********* Read from port %x\n", offset); + if (offset & 0x01) data &= m_in0->read(); // schematics IN1 + if (offset & 0x02) data &= 0xff; // schematics IN2 (not read) + if (offset & 0x04) data &= m_in1->read(); // schematics IN4 + if (offset & 0x08) data &= m_in2->read(); - return ret; + return data; } - WRITE8_MEMBER(vicdual_state::headon2_io_w) { - if (offset & 0x01) assert_coin_status(); - if (offset & 0x02) headon_audio_w(space, 0, data); - if (offset & 0x04) palette_bank_w(space, 0, data); - if (offset & 0x08) { /* schematics show this as going into a shifter circuit, but never written to */ } - if (offset & 0x10) { /* schematics show this as going to an edge connector, but never written to */ } - if (offset & 0x18) logerror("********* Write to port %x\n", offset); + if (offset & 0x01) assert_coin_status(); + if (offset & 0x02) headon_audio_w(space, 0, data); } @@ -861,9 +859,6 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( headon2_io_map, AS_IO, 8, vicdual_state ) ADDRESS_MAP_GLOBAL_MASK(0x1f) - - /* no decoder, just logic gates, so in theory the - game can read/write from multiple locations at once */ AM_RANGE(0x00, 0x1f) AM_READWRITE(headon2_io_r, headon2_io_w) ADDRESS_MAP_END @@ -879,31 +874,31 @@ ADDRESS_MAP_END static INPUT_PORTS_START( headon2 ) PORT_START("IN0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_START2) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_BUTTON1) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_4WAY + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_4WAY + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_4WAY + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_4WAY PORT_START("IN1") - PORT_BIT( 0x07, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */ - PORT_DIPNAME( 0x18, 0x18, DEF_STR( Lives ) ) - PORT_DIPSETTING( 0x18, "4" ) - PORT_DIPSETTING( 0x10, "5" ) - PORT_DIPSETTING( 0x00, "6" ) - /*PORT_DIPSETTING( 0x08, "5" )*/ - PORT_BIT( 0xe0, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */ + PORT_BIT(0x07, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_DIPNAME(0x18, 0x08, DEF_STR( Lives )) + PORT_DIPSETTING( 0x08, "4" ) + PORT_DIPSETTING( 0x10, "5" ) + PORT_DIPSETTING( 0x18, "5" ) + PORT_DIPSETTING( 0x00, "6" ) + PORT_BIT(0xe0, IP_ACTIVE_LOW, IPT_UNUSED) PORT_START("IN2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, vicdual_state, get_timer_value, nullptr) - PORT_DIPNAME( 0x02, 0x02, DEF_STR( Demo_Sounds ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_BIT( 0x7c, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* probably unused */ - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, vicdual_state, read_coin_status, nullptr) + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_DIPNAME(0x02, 0x02, DEF_STR( Demo_Sounds )) + PORT_DIPSETTING( 0x00, DEF_STR( Off )) + PORT_DIPSETTING( 0x02, DEF_STR( On )) + PORT_BIT(0x7c, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_SPECIAL) PORT_CUSTOM_MEMBER(DEVICE_SELF, vicdual_state, read_coin_status, nullptr) PORT_COIN_DEFAULT INPUT_PORTS_END @@ -984,6 +979,12 @@ static INPUT_PORTS_START( digger ) INPUT_PORTS_END +MACHINE_RESET_MEMBER( vicdual_state, headon2 ) +{ + m_palette_bank = 3; +} + + static MACHINE_CONFIG_DERIVED( headon2, vicdual_root ) /* basic machine hardware */ @@ -991,6 +992,8 @@ static MACHINE_CONFIG_DERIVED( headon2, vicdual_root ) MCFG_CPU_PROGRAM_MAP(headon2_map) MCFG_CPU_IO_MAP(headon2_io_map) + MCFG_MACHINE_RESET_OVERRIDE(vicdual_state, headon2) + /* video hardware */ MCFG_SCREEN_MODIFY("screen") MCFG_SCREEN_UPDATE_DRIVER(vicdual_state, screen_update_color) @@ -1075,7 +1078,7 @@ WRITE8_MEMBER(vicdual_state::sspacaho_io_w) WRITE8_MEMBER(vicdual_state::tranqgun_io_w) { - if (offset & 0x01) { /* tranqgun_audio_w(space, 0, data) */ } + if (offset & 0x01) tranqgun_audio_w(space, 0, data); if (offset & 0x02) palette_bank_w(space, 0, data); if (offset & 0x08) assert_coin_status(); } @@ -1137,6 +1140,21 @@ WRITE8_MEMBER(vicdual_state::alphaho_io_w) } +WRITE8_MEMBER(vicdual_state::headonn_io_w) +{ + if (offset & 0x01) invho2_audio_w(space, 0, data); + if (offset & 0x02) + { + // 7654---- unused? + // ----32-- always 1 + // ------10 palette bank (bit 0 inverted) + + palette_bank_w(space, 0, (data & 3) ^ 1); + } + if (offset & 0x08) assert_coin_status(); +} + + static ADDRESS_MAP_START( vicdual_dualgame_map, AS_PROGRAM, 8, vicdual_state ) AM_RANGE(0x0000, 0x3fff) AM_MIRROR(0x4000) AM_ROM AM_RANGE(0x8000, 0x83ff) AM_MIRROR(0x7000) AM_RAM_WRITE(videoram_w) AM_SHARE("videoram") @@ -1303,6 +1321,20 @@ static ADDRESS_MAP_START( alphaho_io_map, AS_IO, 8, vicdual_state ) ADDRESS_MAP_END +static ADDRESS_MAP_START( headonn_io_map, AS_IO, 8, vicdual_state ) + ADDRESS_MAP_GLOBAL_MASK(0x7f) + + AM_RANGE(0x00, 0x00) AM_MIRROR(0x7c) AM_READ_PORT("IN0") + AM_RANGE(0x01, 0x01) AM_MIRROR(0x7c) AM_READ_PORT("IN1") + AM_RANGE(0x02, 0x02) AM_MIRROR(0x7c) AM_READ_PORT("IN2") + AM_RANGE(0x03, 0x03) AM_MIRROR(0x7c) AM_READ_PORT("IN3") + + /* no decoder, just logic gates, so in theory the + game can write to multiple locations at once */ + AM_RANGE(0x00, 0x7f) AM_WRITE(headonn_io_w) +ADDRESS_MAP_END + + /* several of the games' lives DIPs are spread across two input ports */ CUSTOM_INPUT_MEMBER(vicdual_state::fake_lives_r) { @@ -1967,6 +1999,50 @@ static INPUT_PORTS_START( alphaho ) INPUT_PORTS_END +// there is a dip switch with 8 switches on the board, but only switch a is used +static INPUT_PORTS_START( headonn ) + PORT_START("IN0") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_4WAY PORT_COCKTAIL + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_COCKTAIL + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_DIPNAME(0x08, 0x00, DEF_STR(Lives)) PORT_DIPLOCATION("DSW:1") + PORT_DIPSETTING( 0x00, "3") + PORT_DIPSETTING( 0x08, "4") + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_4WAY + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP) PORT_4WAY + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("IN1") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_4WAY PORT_COCKTAIL + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_4WAY + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT) PORT_4WAY + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("IN2") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN) PORT_4WAY PORT_COCKTAIL + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_START1) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON1) + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_START("IN3") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT) PORT_4WAY PORT_COCKTAIL + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_SPECIAL) PORT_CUSTOM_MEMBER(DEVICE_SELF, vicdual_state, read_coin_status, nullptr) + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_START2) + PORT_BIT(0xc0, IP_ACTIVE_LOW, IPT_UNUSED) + + PORT_COIN_DEFAULT +INPUT_PORTS_END + + static MACHINE_CONFIG_DERIVED( vicdual_dualgame_root, vicdual_root ) /* basic machine hardware */ @@ -2060,6 +2136,10 @@ static MACHINE_CONFIG_DERIVED( tranqgun, vicdual_dualgame_root ) /* basic machine hardware */ MCFG_CPU_MODIFY("maincpu") MCFG_CPU_IO_MAP(tranqgun_io_map) + + /* audio hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_FRAGMENT_ADD(tranqgun_audio) MACHINE_CONFIG_END @@ -2103,6 +2183,17 @@ static MACHINE_CONFIG_DERIVED( alphaho, vicdual_dualgame_root ) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( headonn, vicdual_dualgame_root ) + + /* basic machine hardware */ + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_IO_MAP(headonn_io_map) + + /* audio hardware */ + MCFG_SPEAKER_STANDARD_MONO("mono") + MCFG_FRAGMENT_ADD(headon_audio) +MACHINE_CONFIG_END + /************************************* * @@ -2819,6 +2910,43 @@ ROM_START( headon1 ) ROM_LOAD( "316-0042.u88", 0x0020, 0x0020, CRC(a1506b9d) SHA1(037c3db2ea40eca459e8acba9d1506dd28d72d10) ) /* sequence PROM */ ROM_END +/* +Head-On N (Nintendo) + +EPROMS were all Intel 2708's. + +Bi-polar proms were Signetics 82s123's + +prom B6 = lines on screen when removed, address decoding? +prom G2 = white screen when removed, colour prom? +prom F2 = blank screen, audio screeches - no booting... + +CPU clock pin 6 = 1933520 hz + +PCBs: +THO CPU PI-500890 +THO VIDEO PI-500891 +*/ + +ROM_START( headonn ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "ROM.E4", 0x0000, 0x0400, CRC(a6cd13fc) SHA1(0fda6b06e7864feae8e4e94cf17f50c9c033aa39) ) + ROM_LOAD( "ROM.F4", 0x0400, 0x0400, CRC(d1cd498f) SHA1(ded1a97c7f76af195b247135469b84c25d4096c4) ) + ROM_LOAD( "ROM.G4", 0x0800, 0x0400, CRC(0fb02db2) SHA1(6e9ad34a205838339a76ba6eeaf02cf663c2b750) ) + ROM_LOAD( "ROM.H4", 0x0c00, 0x0400, CRC(38db2d02) SHA1(a86c4208154f65a83f55c1fbfd041b56ebd11106) ) + ROM_LOAD( "ROM.I4", 0x1000, 0x0400, CRC(a04d8522) SHA1(58d6c3168ac7227e78ff699449008dbf999ea794) ) + ROM_LOAD( "ROM.J4", 0x1400, 0x0400, CRC(52bd2151) SHA1(4f6bc10dabadf65f638aed46b0f0a1ba00e83afd) ) + ROM_LOAD( "ROM.K4", 0x1800, 0x0400, CRC(9488a8b3) SHA1(a7e8bc341c839eba3b84af78f19cefafe91d42e3) ) + ROM_LOAD( "ROM.L4", 0x1c00, 0x0400, CRC(a37f0be0) SHA1(4548cf05256764588feeade29368f5abfbf75a7d) ) + + ROM_REGION( 0x0020, "proms", 0 ) + ROM_LOAD( "PROM.G2", 0x0000, 0x0020, CRC(67104ea9) SHA1(26b6bd2a1973b83bb9af4e3385d8cb14cb3f62f2) ) + + ROM_REGION( 0x0040, "user1", 0 ) /* timing PROMs */ + ROM_LOAD( "PROM.B6", 0x0000, 0x0020, CRC(67104ea9) SHA1(26b6bd2a1973b83bb9af4e3385d8cb14cb3f62f2) ) /* control PROM */ + ROM_LOAD( "PROM.F2", 0x0020, 0x0020, CRC(a1506b9d) SHA1(037c3db2ea40eca459e8acba9d1506dd28d72d10) ) /* sequence PROM */ +ROM_END + ROM_START( headonmz ) ROM_REGION( 0x10000, "maincpu", 0 ) ROM_LOAD( "0.bin", 0x0000, 0x0400, CRC(1febc85a) SHA1(7cc422d6819d5a2507467bdf91f82e76b0d12643) ) // this ROM was loose from the rest, but should be correct.. @@ -3652,10 +3780,11 @@ GAME( 1979, sspaceatc, sspaceat, sspaceat, sspaceat, vicdual_state, 0, ROT270 GAME( 1979, sspacaho, 0, sspacaho, sspacaho, vicdual_state, 0, ROT270, "Sega", "Space Attack / Head On", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, headon, 0, headon, headon, vicdual_state, 0, ROT0, "Gremlin", "Head On (2 players)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, headon1, headon, headon, headon, vicdual_state, 0, ROT0, "Gremlin", "Head On (1 player)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1979, headonn, headon, headonn, headonn, vicdual_state, 0, ROT270, "Nintendo", "Head On N", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, headons, headon, headons, headons, vicdual_state, 0, ROT0, "bootleg (Sidam)", "Head On (Sidam bootleg, set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, headonsa, headon, headons, headons, vicdual_state, 0, ROT0, "bootleg (Sidam)", "Head On (Sidam bootleg, set 2)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // won't coin up? GAME( 1979, headonmz, headon, headon, headonmz, vicdual_state, 0, ROT0, "bootleg", "Head On (bootleg, alt maze)", MACHINE_SUPPORTS_SAVE ) -GAME( 1979, supcrash, headon, headons, supcrash, vicdual_state, 0, ROT0, "bootleg", "Super Crash (bootleg of Head On)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1979, supcrash, headon, headons, supcrash, vicdual_state, 0, ROT0, "bootleg (VGG)", "Super Crash (bootleg of Head On)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, hocrash, headon, headons, headons, vicdual_state, 0, ROT0, "bootleg (Fraber)", "Crash (bootleg of Head On)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, headon2, 0, headon2, headon2, vicdual_state, 0, ROT0, "Sega", "Head On 2", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, headon2s, headon2, headon2bw, car2, vicdual_state, 0, ROT0, "bootleg (Sidam)", "Head On 2 (Sidam bootleg)", MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) // won't coin up? @@ -3666,9 +3795,9 @@ GAME( 1980, samurai, 0, samurai, samurai, vicdual_state, 0, ROT270 GAME( 1979, invinco, 0, invinco, invinco, vicdual_state, 0, ROT270, "Sega", "Invinco", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, invds, 0, invds, invds, vicdual_state, 0, ROT270, "Sega", "Invinco / Deep Scan", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1979, carhntds, 0, carhntds, carhntds, vicdual_state, 0, ROT270, "Sega", "Car Hunt / Deep Scan (France)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, tranqgun, 0, tranqgun, tranqgun, vicdual_state, 0, ROT270, "Sega", "Tranquillizer Gun", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, spacetrk, 0, spacetrk, spacetrk, vicdual_state, 0, ROT270, "Sega", "Space Trek (upright)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1980, spacetrkc, spacetrk, spacetrk, spacetrkc, vicdual_state, 0, ROT270, "Sega", "Space Trek (cocktail)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, tranqgun, 0, tranqgun, tranqgun, vicdual_state, 0, ROT270, "Sega", "Tranquillizer Gun", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, spacetrk, 0, spacetrk, spacetrk, vicdual_state, 0, ROT270, "Sega", "Space Trek (upright)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) +GAME( 1980, spacetrkc, spacetrk, spacetrk, spacetrkc, vicdual_state, 0, ROT270, "Sega", "Space Trek (cocktail)", MACHINE_IMPERFECT_GRAPHICS |MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1980, carnival, 0, carnival, carnival, vicdual_state, 0, ROT270, "Sega", "Carnival (upright)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1980, carnivalc, carnival, carnival, carnivalc, vicdual_state, 0, ROT270, "Sega", "Carnival (cocktail)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1980, carnivalh, carnival, carnivalh, carnivalh, vicdual_state, 0, ROT270, "Sega", "Carnival (Head On hardware, set 1)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) @@ -3677,7 +3806,7 @@ GAME( 1981, brdrline, 0, brdrline, brdrline, vicdual_state, 0, ROT270 GAME( 1981, starrkr, brdrline, brdrline, starrkr, vicdual_state, 0, ROT270, "Sega", "Star Raker", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1981, brdrlins, brdrline, brdrline, brdrline, vicdual_state, 0, ROT270, "bootleg (Sidam)", "Borderline (Sidam bootleg)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1981, brdrlinb, brdrline, brdrline, brdrline, vicdual_state, 0, ROT270, "bootleg (Karateco)", "Borderline (Karateco bootleg)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) -GAME( 1981, brdrlinet, brdrline, tranqgun, tranqgun, vicdual_state, 0, ROT270, "Sega", "Borderline (Tranquillizer Gun conversion)", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) // official factory conversion +GAME( 1981, brdrlinet, brdrline, tranqgun, tranqgun, vicdual_state, 0, ROT270, "Sega", "Borderline (Tranquillizer Gun conversion)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) // official factory conversion GAME( 198?, startrks, 0, headons, headons, vicdual_state, 0, ROT0, "bootleg (Sidam)", "Star Trek (Head On hardware)", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1980, digger, 0, digger, digger, vicdual_state, 0, ROT270, "Sega", "Digger", MACHINE_NO_SOUND | MACHINE_SUPPORTS_SAVE ) GAME( 1981, pulsar, 0, pulsar, pulsar, vicdual_state, 0, ROT270, "Sega", "Pulsar", MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/vii.cpp b/src/mame/drivers/vii.cpp index 7b3475a62a2..cce05e5d358 100644 --- a/src/mame/drivers/vii.cpp +++ b/src/mame/drivers/vii.cpp @@ -294,7 +294,7 @@ void vii_state::blit(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t x bits <<= nc; if(nbits < nc) { - uint16_t b = space.read_word((m++ & 0x3fffff) << 1); + uint16_t b = space.read_word(m++ & 0x3fffff); b = (b << 8) | (b >> 8); bits |= b << (nc - nbits); nbits += 16; @@ -360,7 +360,7 @@ void vii_state::blit_page(bitmap_rgb32 &bitmap, const rectangle &cliprect, int d { for(x0 = 0; x0 < wn; x0++) { - uint16_t tile = space.read_word((tilemap + x0 + wn * y0) << 1); + uint16_t tile = space.read_word(tilemap + x0 + wn * y0); uint16_t palette = 0; uint32_t xx, yy; @@ -369,7 +369,7 @@ void vii_state::blit_page(bitmap_rgb32 &bitmap, const rectangle &cliprect, int d continue; } - palette = space.read_word((palette_map + (x0 + wn * y0) / 2) << 1); + palette = space.read_word(palette_map + (x0 + wn * y0) / 2); if(x0 & 1) { palette >>= 8; @@ -405,10 +405,10 @@ void vii_state::blit_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, int uint32_t h, w; uint32_t bitmap_addr = 0x40 * m_video_regs[0x22]; - tile = space.read_word((base_addr + 0) << 1); - x = space.read_word((base_addr + 1) << 1); - y = space.read_word((base_addr + 2) << 1); - attr = space.read_word((base_addr + 3) << 1); + tile = space.read_word(base_addr + 0); + x = space.read_word(base_addr + 1); + y = space.read_word(base_addr + 2); + attr = space.read_word(base_addr + 3); if(!tile) { @@ -449,7 +449,7 @@ void vii_state::blit_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, in for(n = 0; n < 256; n++) { - //if(space.read_word((0x2c00 + 4*n) << 1)) + //if(space.read_word(0x2c00 + 4*n) { blit_sprite(bitmap, cliprect, depth, 0x2c00 + 4*n); } @@ -495,7 +495,7 @@ void vii_state::do_dma(uint32_t len) for(j = 0; j < len; j++) { - mem.write_word((dst+j) << 1, mem.read_word((src+j) << 1)); + mem.write_word(dst+j, mem.read_word(src+j)); } m_video_regs[0x72] = 0; @@ -697,7 +697,7 @@ void vii_state::spg_do_dma(uint32_t len) uint32_t j; for(j = 0; j < len; j++) - mem.write_word((dst+j) << 1, mem.read_word((src+j) << 1)); + mem.write_word(dst+j, mem.read_word(src+j)); m_io_regs[0x102] = 0; } diff --git a/src/mame/drivers/vk100.cpp b/src/mame/drivers/vk100.cpp index 6d53403aec5..9ab61e5a94d 100644 --- a/src/mame/drivers/vk100.cpp +++ b/src/mame/drivers/vk100.cpp @@ -422,7 +422,7 @@ TIMER_CALLBACK_MEMBER(vk100_state::execute_vg) m_vgPAT_Mask >>= 1; // shift the mask if (m_vgPAT_Mask == 0) m_vgPAT_Mask = 0x80; // reset mask if it hits 0 } - if (m_vgGO) timer_set(attotime::from_hz(XTAL_45_6192Mhz/3/12/2), TIMER_EXECUTE_VG); // /3/12/2 is correct. the sync counter is clocked by the dot clock, despite the error on figure 5-21 + if (m_vgGO) timer_set(attotime::from_hz(XTAL_45_6192MHz/3/12/2), TIMER_EXECUTE_VG); // /3/12/2 is correct. the sync counter is clocked by the dot clock, despite the error on figure 5-21 } /* ports 0x40 and 0x41: load low and high bytes of vector gen X register */ @@ -1040,10 +1040,10 @@ static MACHINE_CONFIG_START( vk100 ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_RAW_PARAMS(XTAL_45_6192Mhz/3, 882, 0, 720, 370, 0, 350 ) // fake screen timings for startup until 6845 sets real ones + MCFG_SCREEN_RAW_PARAMS(XTAL_45_6192MHz/3, 882, 0, 720, 370, 0, 350 ) // fake screen timings for startup until 6845 sets real ones MCFG_SCREEN_UPDATE_DEVICE( "crtc", mc6845_device, screen_update ) - MCFG_MC6845_ADD( "crtc", H46505, "screen", XTAL_45_6192Mhz/3/12) + MCFG_MC6845_ADD( "crtc", H46505, "screen", XTAL_45_6192MHz/3/12) MCFG_MC6845_SHOW_BORDER_AREA(false) MCFG_MC6845_CHAR_WIDTH(12) MCFG_MC6845_UPDATE_ROW_CB(vk100_state, crtc_update_row) diff --git a/src/mame/drivers/vlc.cpp b/src/mame/drivers/vlc.cpp index 5574256c365..0b76cf3640a 100644 --- a/src/mame/drivers/vlc.cpp +++ b/src/mame/drivers/vlc.cpp @@ -624,15 +624,15 @@ static MACHINE_CONFIG_START( nevada ) MCFG_SOUND_ADD("aysnd", AY8912, SOUND_CLOCK) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75) - MCFG_MC68681_ADD( "duart18_68681", XTAL_3_6864MHz ) // UARTA = Modem 1200Baud + MCFG_DEVICE_ADD("duart18_68681", MC68681, XTAL_3_6864MHz) // UARTA = Modem 1200Baud MCFG_MC68681_IRQ_CALLBACK(WRITELINE(nevada_state, duart18_irq_handler)) MCFG_MC68681_INPORT_CALLBACK(IOPORT("DSW1")) - MCFG_MC68681_ADD( "duart39_68681", XTAL_3_6864MHz ) // UARTA = Printer + MCFG_DEVICE_ADD("duart39_68681", MC68681, XTAL_3_6864MHz) // UARTA = Printer MCFG_MC68681_IRQ_CALLBACK(WRITELINE(nevada_state, duart39_irq_handler)) MCFG_MC68681_INPORT_CALLBACK(IOPORT("DSW2")) - MCFG_MC68681_ADD( "duart40_68681", XTAL_3_6864MHz ) // UARTA = Touch , UARTB = Bill Acceptor + MCFG_DEVICE_ADD("duart40_68681", MC68681, XTAL_3_6864MHz) // UARTA = Touch , UARTB = Bill Acceptor MCFG_MC68681_IRQ_CALLBACK(WRITELINE(nevada_state, duart40_irq_handler)) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("microtouch", microtouch_device, rx)) MCFG_MC68681_INPORT_CALLBACK(IOPORT("DSW3")) diff --git a/src/mame/drivers/votrtnt.cpp b/src/mame/drivers/votrtnt.cpp index ae75ba53662..6b4e2d34792 100644 --- a/src/mame/drivers/votrtnt.cpp +++ b/src/mame/drivers/votrtnt.cpp @@ -81,8 +81,7 @@ private: static ADDRESS_MAP_START(6802_mem, AS_PROGRAM, 8, votrtnt_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x03ff) AM_MIRROR(0x9c00) AM_RAM /* RAM, 2114*2 (0x400 bytes) mirrored 4x */ - AM_RANGE(0x2000, 0x2000) AM_MIRROR(0x9ffe) AM_DEVREADWRITE("acia", acia6850_device, status_r, control_w) - AM_RANGE(0x2001, 0x2001) AM_MIRROR(0x9ffe) AM_DEVREADWRITE("acia", acia6850_device, data_r, data_w) + AM_RANGE(0x2000, 0x2001) AM_MIRROR(0x9ffe) AM_DEVREADWRITE("acia", acia6850_device, read, write) AM_RANGE(0x4000, 0x4000) AM_MIRROR(0x9fff) AM_DEVWRITE("votrax", votrax_sc01_device, write) AM_RANGE(0x6000, 0x6fff) AM_MIRROR(0x9000) AM_ROM /* ROM in potted block */ ADDRESS_MAP_END diff --git a/src/mame/drivers/vp122.cpp b/src/mame/drivers/vp122.cpp new file mode 100644 index 00000000000..dfb0269ee35 --- /dev/null +++ b/src/mame/drivers/vp122.cpp @@ -0,0 +1,114 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +Skeleton driver for ADDS Viewpoint 122 terminal. + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/i8085/i8085.h" +#include "machine/i8251.h" +#include "machine/mc68681.h" +#include "machine/nvram.h" +#include "machine/pit8253.h" +#include "video/scn2674.h" +#include "screen.h" + +class vp122_state : public driver_device +{ +public: + vp122_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + , m_screen(*this, "screen") + //, m_p_chargen(*this, "chargen") + { } + + SCN2674_DRAW_CHARACTER_MEMBER(draw_character); + +private: + required_device<cpu_device> m_maincpu; + required_device<screen_device> m_screen; + //required_region_ptr<u8> m_p_chargen; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, vp122_state ) + AM_RANGE(0x0000, 0x9fff) AM_ROM AM_REGION("maincpu", 0) + AM_RANGE(0xa000, 0xa7ff) AM_RAM AM_SHARE("nvram") + AM_RANGE(0xe000, 0xe7ff) AM_NOP +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_IO, 8, vp122_state ) + AM_RANGE(0x00, 0x07) AM_DEVREADWRITE("avdc", scn2674_device, read, write) + AM_RANGE(0x10, 0x1f) AM_DEVREADWRITE("duart", scn2681_device, read, write) + AM_RANGE(0x20, 0x20) AM_DEVREADWRITE("usart", i8251_device, data_r, data_w) + AM_RANGE(0x21, 0x21) AM_DEVREADWRITE("usart", i8251_device, status_r, control_w) + AM_RANGE(0x50, 0x50) AM_WRITENOP + AM_RANGE(0x60, 0x60) AM_WRITENOP + AM_RANGE(0x70, 0x73) AM_DEVREADWRITE("pit", pit8253_device, read, write) +ADDRESS_MAP_END + + +SCN2674_DRAW_CHARACTER_MEMBER(vp122_state::draw_character) +{ +} + +static ADDRESS_MAP_START( vram_map, 0, 8, vp122_state ) + AM_RANGE(0x0000, 0x07ff) AM_NOP + AM_RANGE(0x1800, 0x2fff) AM_NOP +ADDRESS_MAP_END + + +static INPUT_PORTS_START( vp122 ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( vp122 ) + MCFG_CPU_ADD("maincpu", I8085A, XTAL_8MHz) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + + MCFG_NVRAM_ADD_0FILL("nvram") // MK48Z02 + + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_REFRESH_RATE(50) + MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ + MCFG_SCREEN_SIZE(720, 360) + MCFG_SCREEN_VISIBLE_AREA(0, 720-1, 0, 360-1) + MCFG_SCREEN_UPDATE_DEVICE("avdc", scn2674_device, screen_update) + + MCFG_DEVICE_ADD("avdc", SCN2674, 4000000) + MCFG_SCN2674_INTR_CALLBACK(INPUTLINE("maincpu", I8085_RST65_LINE)) + MCFG_SCN2674_TEXT_CHARACTER_WIDTH(8) + MCFG_SCN2674_GFX_CHARACTER_WIDTH(8) + MCFG_SCN2674_DRAW_CHARACTER_CALLBACK_OWNER(vp122_state, draw_character) + MCFG_DEVICE_ADDRESS_MAP(0, vram_map) + MCFG_VIDEO_SET_SCREEN("screen") + + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) + MCFG_MC68681_IRQ_CALLBACK(INPUTLINE("maincpu", I8085_RST55_LINE)) + + MCFG_DEVICE_ADD("usart", I8251, XTAL_8MHz / 4) + + MCFG_DEVICE_ADD("pit", PIT8253, 0) +MACHINE_CONFIG_END + +/************************************************************************************************************** + +ADDS Viewpoint 122 (VPT-122). +Chips: D8085AC-2, SCN2674B, SCB2675T, D8251AFC, SCN2681A, D8253C-2, 5x MB8128-15, MK48Z02B-20 +Crystals: 22.096, 14.916, 3.6864, 8.000 + +***************************************************************************************************************/ + +ROM_START( vp122 ) + ROM_REGION(0xc000, "maincpu", 0) + ROM_LOAD( "223-48600.uj1", 0x0000, 0x4000, CRC(4d140c69) SHA1(04aa5a4f0c0e0d07b9dc983a6d626ee88ef8b8ba) ) + ROM_LOAD( "223-48500.ug1", 0x4000, 0x4000, CRC(4e98554d) SHA1(0cbb9cb7efd02a3209caed410ccc8495a5ec1772) ) + ROM_LOAD( "223-49400.uj2", 0x8000, 0x4000, CRC(447d90d3) SHA1(f8c0db824198b5a571eef80cc3eaf1e829aa2c2a) ) + + ROM_REGION(0x2000, "chargen", 0) + ROM_LOAD( "223-48700.uk4", 0x0000, 0x2000, CRC(4dbab4bd) SHA1(18e9a23ba22e2096fa529541fa329f5a56740e62) ) +ROM_END + +COMP( 1985, vp122, 0, 0, vp122, vp122, vp122_state, 0, "ADDS", "Viewpoint 122", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/vp60.cpp b/src/mame/drivers/vp60.cpp new file mode 100644 index 00000000000..f5c0826f841 --- /dev/null +++ b/src/mame/drivers/vp60.cpp @@ -0,0 +1,77 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +Skeleton driver for ADDS Viewpoint 60 terminal. +No significant progress can be made until the 8051 has its internal ROM dumped. + +************************************************************************************************************************************/ + +#include "emu.h" +#include "cpu/mcs48/mcs48.h" +#include "cpu/mcs51/mcs51.h" +//#include "machine/er2055.h" +//#include "video/i8275.h" +//#include "screen.h" + +class vp60_state : public driver_device +{ +public: + vp60_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") + //, m_p_chargen(*this, "chargen") + { } + +private: + required_device<cpu_device> m_maincpu; + //required_region_ptr<u8> m_p_chargen; +}; + +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, vp60_state ) + AM_RANGE(0x0000, 0x3fff) AM_ROM AM_REGION("maincpu", 0) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_PROGRAM, 8, vp60_state ) + AM_RANGE(0x8000, 0x87ff) AM_RAM +ADDRESS_MAP_END + +static ADDRESS_MAP_START( kbd_map, AS_PROGRAM, 8, vp60_state ) + AM_RANGE(0x000, 0x3ff) AM_ROM AM_REGION("keyboard", 0) +ADDRESS_MAP_END + +static INPUT_PORTS_START( vp60 ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( vp60 ) + MCFG_CPU_ADD("maincpu", I8051, XTAL_10_920MHz) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) + + MCFG_CPU_ADD("kbdcpu", I8035, 5000000) + MCFG_CPU_PROGRAM_MAP(kbd_map) +MACHINE_CONFIG_END + + +/************************************************************************************************************** + +ADDS Viewpoint 60. +Chips: P8051, P8275, EAROM ER-2055, HM6116P-4 +Crystals: 25.92, 10.920 +Keyboard: INS8035N-6, unknown crystal marked 48-300-010. + +***************************************************************************************************************/ + +ROM_START( vp60 ) + ROM_REGION(0x4000, "maincpu", ROMREGION_ERASE00) + ROM_LOAD( "p8051.ub1", 0x0000, 0x2000, NO_DUMP ) // internal ROM not dumped + ROM_LOAD( "pgm.uc1", 0x2000, 0x2000, CRC(714ca569) SHA1(405424369fd5458e02c845c104b2cb386bd857d2) ) + + ROM_REGION(0x1000, "chargen", 0) + ROM_LOAD( "font.uc4", 0x0000, 0x1000, CRC(3c4d39c0) SHA1(9503c0d5a76e8073c94c86be57bcb312641f6cc4) ) + + ROM_REGION(0x400, "keyboard", 0) + ROM_LOAD( "195.kbd", 0x0000, 0x0400, CRC(14885da3) SHA1(3b06f658af1a62b28e62d8b3a557b74169917a12) ) +ROM_END + +COMP( 1982, vp60, 0, 0, vp60, vp60, vp60_state, 0, "ADDS", "Viewpoint 60", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/vt220.cpp b/src/mame/drivers/vt220.cpp index abb63cfab67..94927aad235 100644 --- a/src/mame/drivers/vt220.cpp +++ b/src/mame/drivers/vt220.cpp @@ -13,6 +13,7 @@ #include "emu.h" #include "cpu/mcs51/mcs51.h" +#include "machine/mc68681.h" #include "machine/ram.h" #include "screen.h" @@ -38,6 +39,8 @@ static ADDRESS_MAP_START(vt220_mem, AS_PROGRAM, 8, vt220_state) ADDRESS_MAP_END static ADDRESS_MAP_START(vt220_io, AS_IO, 8, vt220_state) + AM_RANGE(0x2000, 0x2fff) AM_MIRROR(0xc000) AM_RAM + AM_RANGE(0x3000, 0x300f) AM_MIRROR(0xc7f0) AM_DEVREADWRITE("duart", scn2681_device, read, write) ADDRESS_MAP_END /* Input ports */ @@ -65,6 +68,7 @@ static MACHINE_CONFIG_START( vt220 ) MCFG_CPU_PROGRAM_MAP(vt220_mem) MCFG_CPU_IO_MAP(vt220_io) + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) diff --git a/src/mame/drivers/vt240.cpp b/src/mame/drivers/vt240.cpp index d824d23102b..6e088eac2f7 100644 --- a/src/mame/drivers/vt240.cpp +++ b/src/mame/drivers/vt240.cpp @@ -57,7 +57,7 @@ public: required_device<cpu_device> m_maincpu; required_device<cpu_device> m_i8085; required_device<i8251_device> m_i8251; - required_device<mc68681_device> m_duart; + required_device<scn2681_device> m_duart; required_device<rs232_port_device> m_host; required_device<upd7220_device> m_hgdc; required_device<address_map_bank_device> m_bank; @@ -370,7 +370,7 @@ WRITE8_MEMBER(vt240_state::vom_w) if(!BIT(m_reg0, 2)) { m_vom[offset] = data; - data = ~BITSWAP8(data, 0, 1, 2, 3, 4, 5, 6, 7); + data = ~BITSWAP8(data, 1, 0, 3, 2, 5, 4, 7, 6); m_palette->set_pen_color(offset, pal2bit(data >> 6), pal2bit(data >> 6), pal2bit(data >> 6)); m_palette->set_pen_color((offset + 16), pal2bit(data >> 0), pal2bit(data >> 2), pal2bit(data >> 4)); } @@ -653,14 +653,14 @@ static MACHINE_CONFIG_START( vt240 ) MCFG_DEVICE_ADD("bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(20) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(20) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_SIZE(640, 480) - MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1) + MCFG_SCREEN_SIZE(800, 480) + MCFG_SCREEN_VISIBLE_AREA(0, 800-1, 0, 480-1) MCFG_SCREEN_UPDATE_DEVICE("upd7220", upd7220_device, screen_update) MCFG_PALETTE_ADD("palette", 32) MCFG_GFXDECODE_ADD("gfxdecode", "palette", vt240) @@ -672,7 +672,7 @@ static MACHINE_CONFIG_START( vt240 ) MCFG_UPD7220_BLANK_CALLBACK(INPUTLINE("charcpu", I8085_RST55_LINE)) MCFG_VIDEO_SET_SCREEN("screen") - MCFG_MC68681_ADD("duart", XTAL_3_6864MHz) /* 2681 duart (not 68681!) */ + MCFG_DEVICE_ADD("duart", SCN2681, XTAL_3_6864MHz) MCFG_MC68681_IRQ_CALLBACK(WRITELINE(vt240_state, irq13_w)) MCFG_MC68681_A_TX_CALLBACK(DEVWRITELINE("host", rs232_port_device, write_txd)) MCFG_MC68681_B_TX_CALLBACK(DEVWRITELINE("printer", rs232_port_device, write_txd)) @@ -691,13 +691,13 @@ static MACHINE_CONFIG_START( vt240 ) MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(vt240_state, write_keyboard_clock)) MCFG_RS232_PORT_ADD("host", default_rs232_devices, "null_modem") - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", mc68681_device, rx_a_w)) - MCFG_RS232_DSR_HANDLER(DEVWRITELINE("duart", mc68681_device, ip5_w)) - MCFG_RS232_CTS_HANDLER(DEVWRITELINE("duart", mc68681_device, ip0_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_a_w)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("duart", scn2681_device, ip5_w)) + MCFG_RS232_CTS_HANDLER(DEVWRITELINE("duart", scn2681_device, ip0_w)) MCFG_RS232_PORT_ADD("printer", default_rs232_devices, nullptr) - MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", mc68681_device, rx_b_w)) - MCFG_RS232_DSR_HANDLER(DEVWRITELINE("duart", mc68681_device, ip1_w)) + MCFG_RS232_RXD_HANDLER(DEVWRITELINE("duart", scn2681_device, rx_b_w)) + MCFG_RS232_DSR_HANDLER(DEVWRITELINE("duart", scn2681_device, ip1_w)) MCFG_X2212_ADD("x2212") MACHINE_CONFIG_END diff --git a/src/mame/drivers/vta2000.cpp b/src/mame/drivers/vta2000.cpp index 2655f2e0ee8..3bcfc7f45b8 100644 --- a/src/mame/drivers/vta2000.cpp +++ b/src/mame/drivers/vta2000.cpp @@ -43,14 +43,14 @@ private: required_region_ptr<u8> m_p_chargen; }; -static ADDRESS_MAP_START(vta2000_mem, AS_PROGRAM, 8, vta2000_state) +static ADDRESS_MAP_START(mem_map, AS_PROGRAM, 8, vta2000_state) ADDRESS_MAP_UNMAP_HIGH AM_RANGE( 0x0000, 0x5fff ) AM_ROM AM_REGION("roms", 0) AM_RANGE( 0x8000, 0xc7ff ) AM_RAM AM_SHARE("videoram") AM_RANGE( 0xc800, 0xc8ff ) AM_ROM AM_REGION("roms", 0x5000) ADDRESS_MAP_END -static ADDRESS_MAP_START(vta2000_io, AS_IO, 8, vta2000_state) +static ADDRESS_MAP_START(io_map, AS_IO, 8, vta2000_state) ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_END @@ -157,8 +157,8 @@ PALETTE_INIT_MEMBER(vta2000_state, vta2000) static MACHINE_CONFIG_START( vta2000 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",I8080, XTAL_4MHz / 4) - MCFG_CPU_PROGRAM_MAP(vta2000_mem) - MCFG_CPU_IO_MAP(vta2000_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) diff --git a/src/mame/drivers/wardner.cpp b/src/mame/drivers/wardner.cpp index 0de5a882755..834881e7c3f 100644 --- a/src/mame/drivers/wardner.cpp +++ b/src/mame/drivers/wardner.cpp @@ -132,6 +132,7 @@ out: #include "cpu/tms32010/tms32010.h" #include "cpu/z80/z80.h" +#include "machine/74259.h" #include "machine/bankdev.h" #include "sound/3812intf.h" #include "speaker.h" @@ -200,8 +201,8 @@ static ADDRESS_MAP_START( main_io_map, AS_IO, 8, wardner_state ) AM_RANGE(0x54, 0x54) AM_READ_PORT("P1") AM_RANGE(0x56, 0x56) AM_READ_PORT("P2") AM_RANGE(0x58, 0x58) AM_READ_PORT("SYSTEM") - AM_RANGE(0x5a, 0x5a) AM_WRITE(wardner_coin_dsp_w) /* Machine system control */ - AM_RANGE(0x5c, 0x5c) AM_WRITE(wardner_control_w) /* Machine system control */ + AM_RANGE(0x5a, 0x5a) AM_DEVWRITE("coinlatch", ls259_device, write_nibble_d0) + AM_RANGE(0x5c, 0x5c) AM_DEVWRITE("mainlatch", ls259_device, write_nibble_d0) AM_RANGE(0x60, 0x65) AM_READWRITE(wardner_videoram_r, wardner_videoram_w) AM_RANGE(0x70, 0x70) AM_WRITE(wardner_bank_w) ADDRESS_MAP_END @@ -356,9 +357,6 @@ void wardner_state::machine_reset() { MACHINE_RESET_CALL_MEMBER(twincobr); - m_toaplan_main_cpu = 1; /* Z80 */ - twincobr_display(1); - m_membank->set_bank(0); } @@ -373,8 +371,8 @@ static MACHINE_CONFIG_START( wardner ) MCFG_DEVICE_ADD("membank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(main_bank_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x8000) MCFG_CPU_ADD("audiocpu", Z80, XTAL_14MHz/4) /* 3.5MHz */ @@ -389,6 +387,20 @@ static MACHINE_CONFIG_START( wardner ) MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* 100 CPU slices per frame */ + MCFG_DEVICE_ADD("mainlatch", LS259, 0) + MCFG_ADDRESSABLE_LATCH_Q2_OUT_CB(WRITELINE(wardner_state, int_enable_w)) + MCFG_ADDRESSABLE_LATCH_Q3_OUT_CB(WRITELINE(wardner_state, flipscreen_w)) + MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(WRITELINE(wardner_state, bg_ram_bank_w)) + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(WRITELINE(wardner_state, fg_rom_bank_w)) + MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE(wardner_state, display_on_w)) + + MCFG_DEVICE_ADD("coinlatch", LS259, 0) + MCFG_ADDRESSABLE_LATCH_Q0_OUT_CB(WRITELINE(wardner_state, dsp_int_w)) + MCFG_ADDRESSABLE_LATCH_Q4_OUT_CB(WRITELINE(wardner_state, coin_counter_1_w)) + MCFG_ADDRESSABLE_LATCH_Q5_OUT_CB(WRITELINE(wardner_state, coin_counter_2_w)) + MCFG_ADDRESSABLE_LATCH_Q6_OUT_CB(WRITELINE(wardner_state, coin_lockout_1_w)) + MCFG_ADDRESSABLE_LATCH_Q7_OUT_CB(WRITELINE(wardner_state, coin_lockout_2_w)) + /* video hardware */ MCFG_MC6845_ADD("crtc", HD6845, "screen", XTAL_14MHz/4) /* 3.5MHz measured on CLKin */ MCFG_MC6845_SHOW_BORDER_AREA(false) diff --git a/src/mame/drivers/wgp.cpp b/src/mame/drivers/wgp.cpp index 5984b390e04..d37ae351ea3 100644 --- a/src/mame/drivers/wgp.cpp +++ b/src/mame/drivers/wgp.cpp @@ -322,7 +322,7 @@ Stephh's notes (based on the game M68000 code and some tests) : * 0x0000 (Japan) use TAITO_COINAGE_JAPAN_NEW * 0x0001 (US) use TAITO_COINAGE_US * 0x0002 (World), 0x0003 (US, licensed to ROMSTAR) and 0x0004 (licensed to PHOENIX ELECTRONICS CO.) - use slighlty different TAITO_COINAGE_WORLD : 1C_7C instead of 1C_6C for Coin B + use slightly different TAITO_COINAGE_WORLD : 1C_7C instead of 1C_6C for Coin B - GP order relies on the sub-region (code at 0x00bc9c) : * 0x0000 : 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 * 0x0001 : 0x01 0x00 0x02 0x03 0x04 0x05 0x06 0x07 @@ -380,12 +380,12 @@ Stephh's notes (based on the game M68000 code and some tests) : - Coinage relies on the region (code at 0x00166e) : * 0x0000 (Japan) use TAITO_COINAGE_JAPAN_NEW * 0x0001 (US) use TAITO_COINAGE_US - * 0x0002 (World) use slighlty different TAITO_COINAGE_WORLD : + * 0x0002 (World) use slightly different TAITO_COINAGE_WORLD : 1C_7C instead of 1C_6C for Coin B, same settings otherwise - Notice screen only if region = 0x0000 or region = 0x0001 - FBI logo only if region = 0x0001 - Routine at 0x01116c is the same as the one in 'wgp' based on sub-region; - however, as you can partically select your GP at start, and as I suck + however, as you can practically select your GP at start, and as I suck at such driving game, I wonder if this routine is still called ! - DSWA bit 0 does the following things when set to ON : * unknown effect (code at 0x0126f6) @@ -399,7 +399,6 @@ Stephh's notes (based on the game M68000 code and some tests) : #include "emu.h" #include "includes/wgp.h" #include "includes/taitoipt.h" -#include "audio/taitosnd.h" #include "cpu/z80/z80.h" #include "cpu/m68000/m68000.h" @@ -439,14 +438,14 @@ void wgp_state::device_timer(emu_timer &timer, device_timer_id id, int param, vo switch (id) { /* 68000 A */ - case TIMER_WGP_INTERRUPT4: + case TIMER_INTERRUPT4: m_maincpu->set_input_line(4, HOLD_LINE); break; - case TIMER_WGP_INTERRUPT6: + case TIMER_INTERRUPT6: m_maincpu->set_input_line(6, HOLD_LINE); break; /* 68000 B */ - case TIMER_WGP_CPUB_INTERRUPT6: + case TIMER_CPUB_INTERRUPT6: m_subcpu->set_input_line(6, HOLD_LINE); /* assumes Z80 sandwiched between the 68Ks */ break; default: @@ -460,9 +459,9 @@ void wgp_state::device_timer(emu_timer &timer, device_timer_id id, int param, vo /* FWIW offset of 10000,10500 on ints can get CPUB obeying the first CPUA command the same frame; probably not necessary */ -INTERRUPT_GEN_MEMBER(wgp_state::wgp_cpub_interrupt) +INTERRUPT_GEN_MEMBER(wgp_state::cpub_interrupt) { - timer_set(downcast<cpu_device *>(&device)->cycles_to_attotime(200000-500), TIMER_WGP_CPUB_INTERRUPT6); + m_cpub_int6_timer->adjust(m_subcpu->cycles_to_attotime(200000-500)); device.execute().set_input_line(4, HOLD_LINE); } @@ -518,7 +517,7 @@ WRITE16_MEMBER(wgp_state::rotate_port_w) #define UNKNOWN_PORT_TAG "UNKNOWN" #define FAKE_PORT_TAG "FAKE" -READ16_MEMBER(wgp_state::wgp_adinput_r) +READ16_MEMBER(wgp_state::adinput_r) { int steer = 0x40; int fake = m_fake.read_safe(0); @@ -579,13 +578,13 @@ logerror("CPU #0 PC %06x: warning - read unmapped a/d input offset %06x\n",space return 0xff; } -WRITE16_MEMBER(wgp_state::wgp_adinput_w) +WRITE16_MEMBER(wgp_state::adinput_w) { /* Each write invites a new interrupt as soon as the hardware has got the next a/d conversion ready. We set a token delay of 10000 cycles although our inputs are always ready. */ - timer_set(downcast<cpu_device *>(&space.device())->cycles_to_attotime(10000), TIMER_WGP_INTERRUPT6); + m_int6_timer->adjust(m_maincpu->cycles_to_attotime(10000)); } WRITE8_MEMBER(wgp_state::coins_w) @@ -606,23 +605,6 @@ WRITE8_MEMBER(wgp_state::sound_bankswitch_w) m_z80bank->set_entry(data & 3); } -WRITE16_MEMBER(wgp_state::wgp_sound_w) -{ - if (offset == 0) - m_tc0140syt->master_port_w(space, 0, data & 0xff); - else if (offset == 1) - m_tc0140syt->master_comm_w(space, 0, data & 0xff); -} - -READ16_MEMBER(wgp_state::wgp_sound_r) -{ - if (offset == 1) - return ((m_tc0140syt->master_comm_r(space, 0) & 0xff)); - else - return 0; -} - - /***************************************************************** MEMORY STRUCTURES *****************************************************************/ @@ -633,15 +615,15 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 16, wgp_state ) AM_RANGE(0x140000, 0x143fff) AM_RAM AM_SHARE("sharedram") AM_RANGE(0x180000, 0x18000f) AM_DEVREADWRITE8("tc0220ioc", tc0220ioc_device, read, write, 0xff00) AM_RANGE(0x1c0000, 0x1c0001) AM_WRITE(cpua_ctrl_w) - AM_RANGE(0x200000, 0x20000f) AM_READWRITE(wgp_adinput_r,wgp_adinput_w) + AM_RANGE(0x200000, 0x20000f) AM_READWRITE(adinput_r, adinput_w) AM_RANGE(0x300000, 0x30ffff) AM_DEVREADWRITE("tc0100scn", tc0100scn_device, word_r, word_w) /* tilemaps */ AM_RANGE(0x320000, 0x32000f) AM_DEVREADWRITE("tc0100scn", tc0100scn_device, ctrl_word_r, ctrl_word_w) AM_RANGE(0x400000, 0x40bfff) AM_RAM AM_SHARE("spritemap") /* sprite tilemaps */ AM_RANGE(0x40c000, 0x40dfff) AM_RAM AM_SHARE("spriteram") /* sprite ram */ AM_RANGE(0x40fff0, 0x40fff1) AM_WRITENOP /* ?? (writes 0x8000 and 0 alternately - Wgp2 just 0) */ AM_RANGE(0x500000, 0x501fff) AM_RAM /* unknown/unused */ - AM_RANGE(0x502000, 0x517fff) AM_READWRITE(wgp_pivram_word_r, wgp_pivram_word_w) AM_SHARE("pivram") /* piv tilemaps */ - AM_RANGE(0x520000, 0x52001f) AM_READWRITE(wgp_piv_ctrl_word_r, wgp_piv_ctrl_word_w) AM_SHARE("piv_ctrlram") + AM_RANGE(0x502000, 0x517fff) AM_RAM_WRITE(pivram_word_w) AM_SHARE("pivram") /* piv tilemaps */ + AM_RANGE(0x520000, 0x52001f) AM_RAM_WRITE(piv_ctrl_word_w) AM_SHARE("piv_ctrlram") AM_RANGE(0x600000, 0x600003) AM_WRITE(rotate_port_w) /* rotation control ? */ AM_RANGE(0x700000, 0x701fff) AM_RAM_DEVWRITE("palette", palette_device, write) AM_SHARE("palette") ADDRESS_MAP_END @@ -650,7 +632,8 @@ static ADDRESS_MAP_START( cpu2_map, AS_PROGRAM, 16 /* LAN areas not mapped... * AM_RANGE(0x000000, 0x03ffff) AM_ROM AM_RANGE(0x100000, 0x103fff) AM_RAM AM_RANGE(0x140000, 0x143fff) AM_RAM AM_SHARE("sharedram") - AM_RANGE(0x200000, 0x200003) AM_READWRITE(wgp_sound_r,wgp_sound_w) + AM_RANGE(0x200000, 0x200001) AM_DEVWRITE8("tc0140syt", tc0140syt_device, master_port_w, 0x00ff) + AM_RANGE(0x200002, 0x200003) AM_DEVREADWRITE8("tc0140syt", tc0140syt_device, master_comm_r, master_comm_w, 0x00ff) // AM_RANGE(0x380000, 0x383fff) AM_READONLY // LAN RAM // AM_RANGE(0x380000, 0x383fff) AM_WRITEONLY // LAN RAM AM_RANGE(0x380000, 0x380001) AM_READ(lan_status_r) // ?? @@ -886,20 +869,18 @@ However sync to vblank is lacking, which is causing the graphics glitches. ***********************************************************/ -void wgp_state::wgp_postload() +void wgp_state::postload() { parse_control(); } void wgp_state::machine_reset() { - int i; - m_cpua_ctrl = 0xff; m_port_sel = 0; m_piv_ctrl_reg = 0; - for (i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { m_piv_zoom[i] = 0; m_piv_scrollx[i] = 0; @@ -913,9 +894,12 @@ void wgp_state::machine_start() { m_z80bank->configure_entries(0, 4, memregion("audiocpu")->base(), 0x4000); + m_int6_timer = timer_alloc(TIMER_INTERRUPT6); + m_cpub_int6_timer = timer_alloc(TIMER_CPUB_INTERRUPT6); + save_item(NAME(m_cpua_ctrl)); save_item(NAME(m_port_sel)); - machine().save().register_postload(save_prepost_delegate(FUNC(wgp_state::wgp_postload), this)); + machine().save().register_postload(save_prepost_delegate(FUNC(wgp_state::postload), this)); } static MACHINE_CONFIG_START( wgp ) @@ -923,14 +907,14 @@ static MACHINE_CONFIG_START( wgp ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", M68000, 12000000) /* 12 MHz ??? */ MCFG_CPU_PROGRAM_MAP(main_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", wgp_state, irq4_line_hold) + MCFG_CPU_VBLANK_INT_DRIVER("screen", wgp_state, irq4_line_hold) MCFG_CPU_ADD("audiocpu", Z80, 16000000/4) /* 4 MHz ??? */ MCFG_CPU_PROGRAM_MAP(z80_sound_map) MCFG_CPU_ADD("sub", M68000, 12000000) /* 12 MHz ??? */ MCFG_CPU_PROGRAM_MAP(cpu2_map) - MCFG_CPU_VBLANK_INT_DRIVER("screen", wgp_state, wgp_cpub_interrupt) + MCFG_CPU_VBLANK_INT_DRIVER("screen", wgp_state, cpub_interrupt) MCFG_QUANTUM_TIME(attotime::from_hz(30000)) @@ -949,7 +933,7 @@ static MACHINE_CONFIG_START( wgp ) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) MCFG_SCREEN_SIZE(40*8, 32*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 2*8, 32*8-1) - MCFG_SCREEN_UPDATE_DRIVER(wgp_state, screen_update_wgp) + MCFG_SCREEN_UPDATE_DRIVER(wgp_state, screen_update) MCFG_SCREEN_PALETTE("palette") MCFG_GFXDECODE_ADD("gfxdecode", "palette", wgp) @@ -982,7 +966,7 @@ static MACHINE_CONFIG_DERIVED( wgp2, wgp ) MCFG_QUANTUM_TIME(attotime::from_hz(12000)) /* video hardware */ - MCFG_VIDEO_START_OVERRIDE(wgp_state,wgp2) + MCFG_VIDEO_START_OVERRIDE(wgp_state, wgp2) MCFG_DEVICE_MODIFY("tc0100scn") MCFG_TC0100SCN_OFFSETS(4, 2) @@ -1211,8 +1195,8 @@ DRIVER_INIT_MEMBER(wgp_state,wgp2) /* Working Games with some graphics problems - e.g. missing rotation */ -GAME( 1989, wgp, 0, wgp, wgp, wgp_state, wgp, ROT0, "Taito America Corporation", "World Grand Prix (US)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1989, wgpj, wgp, wgp, wgpj, wgp_state, wgp, ROT0, "Taito Corporation", "World Grand Prix (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1989, wgpjoy, wgp, wgp, wgpjoy, wgp_state, wgp, ROT0, "Taito Corporation", "World Grand Prix (joystick version) (Japan, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1989, wgpjoya, wgp, wgp, wgpjoy, wgp_state, wgp, ROT0, "Taito Corporation", "World Grand Prix (joystick version) (Japan, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) -GAME( 1990, wgp2, wgp, wgp2, wgp2, wgp_state, wgp2, ROT0, "Taito Corporation", "World Grand Prix 2 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING ) +GAME( 1989, wgp, 0, wgp, wgp, wgp_state, wgp, ROT0, "Taito America Corporation", "World Grand Prix (US)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +GAME( 1989, wgpj, wgp, wgp, wgpj, wgp_state, wgp, ROT0, "Taito Corporation", "World Grand Prix (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +GAME( 1989, wgpjoy, wgp, wgp, wgpjoy, wgp_state, wgp, ROT0, "Taito Corporation", "World Grand Prix (joystick version) (Japan, set 1)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +GAME( 1989, wgpjoya, wgp, wgp, wgpjoy, wgp_state, wgp, ROT0, "Taito Corporation", "World Grand Prix (joystick version) (Japan, set 2)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) +GAME( 1990, wgp2, wgp, wgp2, wgp2, wgp_state, wgp2, ROT0, "Taito Corporation", "World Grand Prix 2 (Japan)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NODEVICE_LAN | MACHINE_NOT_WORKING | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/wicat.cpp b/src/mame/drivers/wicat.cpp index 0eabbc0756e..a81237738a3 100644 --- a/src/mame/drivers/wicat.cpp +++ b/src/mame/drivers/wicat.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Robbbert, Barry Rodewald +// copyright-holders:Barry Rodewald /*************************************************************************** Wicat - various systems. diff --git a/src/mame/drivers/wildpkr.cpp b/src/mame/drivers/wildpkr.cpp index 7313d113fce..701a69d4346 100644 --- a/src/mame/drivers/wildpkr.cpp +++ b/src/mame/drivers/wildpkr.cpp @@ -456,7 +456,7 @@ static MACHINE_CONFIG_START( wildpkr ) MCFG_CPU_PROGRAM_MAP(wildpkr_map) //MCFG_CPU_VBLANK_INT_DRIVER("screen", wildpkr_state, irq2_line_hold) // guess - MCFG_MC68681_ADD("duart", SEC_CLOCK) + MCFG_DEVICE_ADD("duart", MC68681, SEC_CLOCK) MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) @@ -490,7 +490,7 @@ static MACHINE_CONFIG_START( tabpkr ) MCFG_NVRAM_ADD_1FILL("nvram") // DS1220Y - MCFG_MC68681_ADD("duart", 3686400) + MCFG_DEVICE_ADD("duart", MC68681, 3686400) MCFG_MC68681_IRQ_CALLBACK(ASSERTLINE("maincpu", M68K_IRQ_2)) MCFG_DEVICE_ADD("id", DS2401, 0) diff --git a/src/mame/drivers/williams.cpp b/src/mame/drivers/williams.cpp index 9101957e002..2368d868229 100644 --- a/src/mame/drivers/williams.cpp +++ b/src/mame/drivers/williams.cpp @@ -1496,8 +1496,8 @@ static MACHINE_CONFIG_DERIVED( defender, williams ) MCFG_DEVICE_ADD("bankc000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(defender_bankc000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(16) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(16) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) MCFG_MACHINE_START_OVERRIDE(williams_state,defender) @@ -1659,8 +1659,8 @@ static MACHINE_CONFIG_START( williams2 ) MCFG_DEVICE_ADD("bank8000", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(williams2_bank8000_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(12) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(12) MCFG_ADDRESS_MAP_BANK_STRIDE(0x0800) MCFG_MACHINE_START_OVERRIDE(williams2_state,williams2) diff --git a/src/mame/drivers/wiping.cpp b/src/mame/drivers/wiping.cpp index 64d31775af3..75ba2093546 100644 --- a/src/mame/drivers/wiping.cpp +++ b/src/mame/drivers/wiping.cpp @@ -319,7 +319,7 @@ static MACHINE_CONFIG_START( wiping ) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("wiping", WIPING, 0) + MCFG_SOUND_ADD("wiping", WIPING_CUSTOM, 96000) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0) MACHINE_CONFIG_END diff --git a/src/mame/drivers/wyse.cpp b/src/mame/drivers/wyse.cpp index 41774221865..2ab3081e734 100644 --- a/src/mame/drivers/wyse.cpp +++ b/src/mame/drivers/wyse.cpp @@ -4,41 +4,110 @@ 2017-10-27 Skeleton -Wyse is a well-known maker of terminals. It is presumed this is one of them. +Wyse terminals. + +WY-30+: P8031AH, OKI M76V020, TC5565APL-12, HY6116AP-15, Beeper, 31.2795, 7.3728 (for CPU) + +WY-50: SAB8031P, SCN2672A (CRTC), SCN2661B (UART), 2x MSM2128-15RS, SY2158A, 80-435-00 (WYSE proprietory gate array), + Beeper, 4.9152 (for UART), 11.000 (for CPU), 68.850 (for video). + +WY-60: SC67336P, P8051AN-40196, SCN2661B, 7219-0629, 4.9152, 11.000, 39.710, 26.580, Beeper + +WY-85: 5x HM6116P-3, AM9265EPC, SCN2681A, SCN2672B, SCN8032H, 48.5568, 11.000, 3.6854, Beeper + +WY-150: Philips P80C32SBPN, Toshiba 211009-02, Winbond ??, unknown crystal + + CPU EPROM VIDEO RAM Row Buffer Font RAM Font ROM NVRAM Serial Dot Clk CPU Clk Ser Clk +WY-30+ 8031 27128(250971-02) 211019-02 5565 6116 CAT59C11 31.2795 7.3728 +WY-50 8031 2764 2672/80-435-00 2x2Kx8 1Kx8 2716 ER-1400 2661 68.850 11.000 4.9152 +WY-55 8032 (251352-12) 211019-05 8k (8kx2) battery 16C452 49.423 14.7456 +WY-60 8051(202008-03) 27512(193003-01) 211003-02/205001-02 2064 ( 2064/2016/2016/2064) X24C04 2661 39.710/26.580 11.000 4.9152 +WY-85 8032 27128(250151-04) 2672 4x6116 6116 9265 M5G1400 2681 48.5568 11.000 3.6864 +WY-150 8032 27512(251167-06) 211009-02 6264 (2x6264) battery - 48.000 11.000 + ************************************************************************************************************************************/ #include "emu.h" -//#include "cpu/mcs51/mcs51.h" +#include "cpu/mcs51/mcs51.h" class wyse_state : public driver_device { public: wyse_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) -// , maincpu(*this, "maincpu") +// , m_maincpu(*this, "maincpu") { } -protected: -// required_device<i80c52_device> maincpu; +private: +// required_device<cpu_device> m_maincpu; }; +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, wyse_state ) + AM_RANGE(0x0000, 0x1fff) AM_ROM + AM_RANGE(0xc000, 0xffff) AM_RAM AM_SHARE("videoram") +ADDRESS_MAP_END + +static ADDRESS_MAP_START( io_map, AS_IO, 8, wyse_state ) +ADDRESS_MAP_END + static INPUT_PORTS_START( wyse ) INPUT_PORTS_END -//static ADDRESS_MAP_START( prg_map, AS_PROGRAM, 8, wyse_state ) -//ADDRESS_MAP_END - static MACHINE_CONFIG_START( wyse ) + MCFG_CPU_ADD("maincpu", I8031, 11'000'000) // confirmed for WY-50 + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) MACHINE_CONFIG_END -ROM_START( wyse ) +ROM_START( wy50 ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "2301_E.u6", 0x0000, 0x2000, CRC(2a62ea25) SHA1(f69c596aab307ef1872df29d353b5a61ff77bb74) ) + ROM_REGION( 0x1000, "chargen", 0 ) + ROM_LOAD( "2201_B.u16", 0x0000, 0x1000, CRC(ee318814) SHA1(0ac64b60ff978e607a087e9e6f4d547811c015c5) ) +ROM_END + +ROM_START( wy30p ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "250971-02.u4", 0x0000, 0x4000, CRC(3666549c) SHA1(23c432da2083df4b355daf566dd6514d1f9a7690) ) +ROM_END + +ROM_START( wy55 ) + ROM_REGION( 0x20000, "maincpu", 0 ) + ROM_LOAD( "251352-12.bin", 0x0000, 0x20000, CRC(efe41862) SHA1(52ee76d636b166fa10a37356aef81011a9b079cc) ) // v2.1 +ROM_END + +ROM_START( wy60 ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "193003-01.u9", 0x0000, 0x10000, CRC(26de0ea4) SHA1(91409f98a3990b514fbcb7de2eb45944bf5b95bc) ) + ROM_REGION( 0x10000, "user1", 0 ) + ROM_LOAD( "wy-60_4k.u6", 0x0000, 0x10000, CRC(6daf2824) SHA1(23cd039ec7ae71b0742e8eebf75be8cd5992e3fd) ) +ROM_END + +ROM_START( wy85 ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "250151-04_revA.5e", 0x0000, 0x4000, CRC(8fcb9f43) SHA1(6c7e1d27fa6014870c29ab2b8b856ae412bfc411) ) + ROM_REGION( 0x2000, "user1", 0 ) + ROM_LOAD( "am9265.1h", 0x0000, 0x2000, CRC(5ee65b55) SHA1(a0b38a38838f262aaea22d212351e7441e4b07e8) ) +ROM_END + +ROM_START( wy150 ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "251167-01.bin", 0x00000, 0x10000, CRC(4f425b11) SHA1(e44f54aa98d9f9c668a6ad674ec07e47879fc2a0) ) + ROM_REGION( 0x20000, "link", 0 ) + ROM_LOAD( "link_mc3.bin", 0x00000, 0x10000, CRC(9e1d37d9) SHA1(d74c0faf6cf1eb06243607931967cf35a633ac8e) ) + ROM_LOAD( "link_mc5_xerox-wy30.bin", 0x10000, 0x10000, CRC(1aa00cb4) SHA1(6a7267132fe35c8e07deccd67c0fb4fe5a240c99) ) +ROM_END + +ROM_START( wy160 ) ROM_REGION( 0x10000, "maincpu", 0 ) - // unknown terminal (1984) - ROM_LOAD( "wyse_2201b.bin", 0x000000, 0x001000, CRC(ee318814) SHA1(0ac64b60ff978e607a087e9e6f4d547811c015c5) ) // chargen - ROM_LOAD( "wyse_2301e.bin", 0x000000, 0x002000, CRC(2a62ea25) SHA1(f69c596aab307ef1872df29d353b5a61ff77bb74) ) // program - // WY-160 terminal (1990) - ROM_LOAD( "wyse_251167-06.bin", 0x000000, 0x010000, CRC(36e920df) SHA1(8fb7f51b4f47ef63b21d421227d6fef98001e4e9) ) // program + ROM_LOAD( "251167-06.bin", 0x00000, 0x10000, CRC(36e920df) SHA1(8fb7f51b4f47ef63b21d421227d6fef98001e4e9) ) ROM_END -COMP( 19??, wyse, 0, 0, wyse, wyse, wyse_state, 0, "Wyse", "Unknown terminal", MACHINE_IS_SKELETON ) +COMP( 1984, wy50, 0, 0, wyse, wyse, wyse_state, 0, "Wyse", "WY-50", MACHINE_IS_SKELETON ) +COMP( 199?, wy55, wy50, 0, wyse, wyse, wyse_state, 0, "Wyse", "WY-55", MACHINE_IS_SKELETON ) +COMP( 1986, wy60, wy50, 0, wyse, wyse, wyse_state, 0, "Wyse", "WY-60", MACHINE_IS_SKELETON ) +COMP( 1985, wy85, wy50, 0, wyse, wyse, wyse_state, 0, "Wyse", "WY-85", MACHINE_IS_SKELETON ) +COMP( 1988, wy150, wy50, 0, wyse, wyse, wyse_state, 0, "Wyse", "WY-150", MACHINE_IS_SKELETON ) +COMP( 1990, wy160, wy50, 0, wyse, wyse, wyse_state, 0, "Wyse", "WY-160", MACHINE_IS_SKELETON ) +COMP( 1991, wy30p, wy50, 0, wyse, wyse, wyse_state, 0, "Wyse", "WY-30+", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/xtheball.cpp b/src/mame/drivers/xtheball.cpp index 4f2044f4461..e0551653dc0 100644 --- a/src/mame/drivers/xtheball.cpp +++ b/src/mame/drivers/xtheball.cpp @@ -120,9 +120,9 @@ TMS340X0_SCANLINE_RGB32_CB_MEMBER(xtheball_state::scanline_update) TMS340X0_TO_SHIFTREG_CB_MEMBER(xtheball_state::to_shiftreg) { if (address >= 0x01000000 && address <= 0x010fffff) - memcpy(shiftreg, &m_vram_bg[TOWORD(address & 0xff000)], TOBYTE(0x1000)); + memcpy(shiftreg, &m_vram_bg[(address & 0xff000) >> 4], 0x200); else if (address >= 0x02000000 && address <= 0x020fffff) - memcpy(shiftreg, &m_vram_fg[TOWORD(address & 0xff000)], TOBYTE(0x1000)); + memcpy(shiftreg, &m_vram_fg[(address & 0xff000) >> 4], 0x200); else logerror("%s:to_shiftreg(%08X)\n", space.machine().describe_context(), address); } @@ -131,9 +131,9 @@ TMS340X0_TO_SHIFTREG_CB_MEMBER(xtheball_state::to_shiftreg) TMS340X0_FROM_SHIFTREG_CB_MEMBER(xtheball_state::from_shiftreg) { if (address >= 0x01000000 && address <= 0x010fffff) - memcpy(&m_vram_bg[TOWORD(address & 0xff000)], shiftreg, TOBYTE(0x1000)); + memcpy(&m_vram_bg[(address & 0xff000) >> 4], shiftreg, 0x200); else if (address >= 0x02000000 && address <= 0x020fffff) - memcpy(&m_vram_fg[TOWORD(address & 0xff000)], shiftreg, TOBYTE(0x1000)); + memcpy(&m_vram_fg[(address & 0xff000) >> 4], shiftreg, 0x200); else logerror("%s:from_shiftreg(%08X)\n", space.machine().describe_context(), address); } diff --git a/src/mame/drivers/z100.cpp b/src/mame/drivers/z100.cpp index f873c6d7ef3..5042eeaa6e6 100644 --- a/src/mame/drivers/z100.cpp +++ b/src/mame/drivers/z100.cpp @@ -145,6 +145,7 @@ ZDIPSW EQU 0FFH ; Configuration dip switches #include "emu.h" #include "cpu/i86/i86.h" +//#include "bus/s100/s100.h" #include "imagedev/flopdrv.h" #include "machine/6821pia.h" #include "machine/pic8259.h" diff --git a/src/mame/drivers/z80dev.cpp b/src/mame/drivers/z80dev.cpp index a88275e75ed..f51237299ac 100644 --- a/src/mame/drivers/z80dev.cpp +++ b/src/mame/drivers/z80dev.cpp @@ -2,11 +2,11 @@ // copyright-holders:Robbbert /*************************************************************************** - Z80 dev board (unknown) +Z80 dev board (unknown) - http://retro.hansotten.nl/index.php?page=z80-dev-kit +http://retro.hansotten.nl/index.php?page=z80-dev-kit - 23/04/2010 Skeleton driver. +2010-04-23 Skeleton driver. Pasting: 0-F : as is @@ -29,13 +29,14 @@ class z80dev_state : public driver_device { public: z80dev_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu") + : driver_device(mconfig, type, tag) + , m_maincpu(*this, "maincpu") { } - required_device<cpu_device> m_maincpu; DECLARE_WRITE8_MEMBER( display_w ); DECLARE_READ8_MEMBER( test_r ); +private: + required_device<cpu_device> m_maincpu; }; WRITE8_MEMBER( z80dev_state::display_w ) @@ -52,13 +53,13 @@ READ8_MEMBER( z80dev_state::test_r ) return space.machine().rand(); } -static ADDRESS_MAP_START(z80dev_mem, AS_PROGRAM, 8, z80dev_state) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, z80dev_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x07ff) AM_ROM AM_RANGE(0x1000, 0x10ff) AM_RAM ADDRESS_MAP_END -static ADDRESS_MAP_START( z80dev_io , AS_IO, 8, z80dev_state) +static ADDRESS_MAP_START( io_map , AS_IO, 8, z80dev_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK (0xff) AM_RANGE(0x20, 0x20) AM_READ_PORT("LINE0") @@ -108,8 +109,8 @@ INPUT_PORTS_END static MACHINE_CONFIG_START( z80dev ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) - MCFG_CPU_PROGRAM_MAP(z80dev_mem) - MCFG_CPU_IO_MAP(z80dev_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_DEFAULT_LAYOUT(layout_z80dev) diff --git a/src/mame/drivers/zac_2.cpp b/src/mame/drivers/zac_2.cpp index 03cd81eff85..daccf3470ac 100644 --- a/src/mame/drivers/zac_2.cpp +++ b/src/mame/drivers/zac_2.cpp @@ -185,7 +185,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(zac_2_state::zac_2_inttimer) { // a pulse is sent via a capacitor (similar to what one finds at a reset pin) if (m_t_c > 0x80) - generic_pulse_irq_line_and_vector(*m_maincpu, INPUT_LINE_IRQ0, 0xbf, 2); + m_maincpu->pulse_input_line_and_vector(INPUT_LINE_IRQ0, 0xbf, 2 * m_maincpu->minimum_quantum_time()); else m_t_c++; } diff --git a/src/mame/drivers/zn.cpp b/src/mame/drivers/zn.cpp index 927d0f42ead..2db94b3e55a 100644 --- a/src/mame/drivers/zn.cpp +++ b/src/mame/drivers/zn.cpp @@ -5073,8 +5073,8 @@ ROM_START( jdredd ) AC_BIOS ROM_REGION32_LE( 0x200000, "roms", 0 ) - ROM_LOAD16_BYTE( "9e54_01-16-98_1566_u_36.u36", 0x000001, 0x020000, CRC(37addbf9) SHA1(a4061a1ba9e230f080f0bfea69bf77efe9264a92) ) /* known to have other dates like 11-21-97 - still same checksum of 9E54 */ - ROM_LOAD16_BYTE( "79d3_01-16-98_1565_u_35.u35", 0x000000, 0x020000, CRC(c1e17191) SHA1(82901439b1a51b9aadb4df4b9d944f26697a1460) ) /* known to have other dates like 11-21-97 - still same checksum of 79D3 */ + ROM_LOAD16_BYTE( "9e54_01-16-98_1566_u_36.u36", 0x000001, 0x020000, CRC(37addbf9) SHA1(a4061a1ba9e230f080f0bfea69bf77efe9264a92) ) /* ROMs for Rev.C hard drive are dated 01-16-98 - still same checksum of 9E54 */ + ROM_LOAD16_BYTE( "79d3_01-16-98_1565_u_35.u35", 0x000000, 0x020000, CRC(c1e17191) SHA1(82901439b1a51b9aadb4df4b9d944f26697a1460) ) /* ROMs for Rev.C hard drive are dated 01-16-98 - still same checksum of 79D3 */ DISK_REGION( "ata:0:hdd:image" ) DISK_IMAGE( "jdreddc", 0, SHA1(eee205f83e5f590f8baf36452c873d7063156bd0) ) /* label on drive reads: 1576 Rev.C */ @@ -5087,8 +5087,8 @@ ROM_START( jdreddb ) AC_BIOS ROM_REGION32_LE( 0x200000, "roms", 0 ) - ROM_LOAD16_BYTE( "9e54_01-16-98_1566_u_36.u36", 0x000001, 0x020000, CRC(37addbf9) SHA1(a4061a1ba9e230f080f0bfea69bf77efe9264a92) ) /* known to have other dates like 11-21-97 - still same checksum of 9E54 */ - ROM_LOAD16_BYTE( "79d3_01-16-98_1565_u_35.u35", 0x000000, 0x020000, CRC(c1e17191) SHA1(82901439b1a51b9aadb4df4b9d944f26697a1460) ) /* known to have other dates like 11-21-97 - still same checksum of 79D3 */ + ROM_LOAD16_BYTE( "9e54_11-21-97_1566_u_36.u36", 0x000001, 0x020000, CRC(37addbf9) SHA1(a4061a1ba9e230f080f0bfea69bf77efe9264a92) ) /* ROMs for Rev.B hard drive are dated 11-21-97 - still same checksum of 9E54 */ + ROM_LOAD16_BYTE( "79d3_11-21-97_1565_u_35.u35", 0x000000, 0x020000, CRC(c1e17191) SHA1(82901439b1a51b9aadb4df4b9d944f26697a1460) ) /* ROMs for Rev.B hard drive are dated 11-21-97 - still same checksum of 79D3 */ DISK_REGION( "ata:0:hdd:image" ) DISK_IMAGE( "jdreddb", 0, SHA1(20f696fa6e1fbf97793bac2a794631c5dd4fb39a) ) /* label on drive reads: 1576 Rev.B */ diff --git a/src/mame/drivers/zrt80.cpp b/src/mame/drivers/zrt80.cpp index 2b980acc2ce..f1c8752b64b 100644 --- a/src/mame/drivers/zrt80.cpp +++ b/src/mame/drivers/zrt80.cpp @@ -97,7 +97,7 @@ WRITE8_MEMBER(zrt80_state::zrt80_38_w) m_beep->set_state(1); } -static ADDRESS_MAP_START(zrt80_mem, AS_PROGRAM, 8, zrt80_state) +static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, zrt80_state ) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x0000, 0x0fff) AM_ROM // Z25 - Main firmware AM_RANGE(0x1000, 0x1fff) AM_ROM // Z24 - Expansion @@ -107,7 +107,7 @@ static ADDRESS_MAP_START(zrt80_mem, AS_PROGRAM, 8, zrt80_state) ADDRESS_MAP_END -static ADDRESS_MAP_START( zrt80_io, AS_IO, 8, zrt80_state) +static ADDRESS_MAP_START( io_map, AS_IO, 8, zrt80_state ) ADDRESS_MAP_UNMAP_HIGH ADDRESS_MAP_GLOBAL_MASK(0xff) AM_RANGE(0x00, 0x07) AM_DEVREADWRITE("ins8250", ins8250_device, ins8250_r, ins8250_w ) @@ -270,8 +270,8 @@ GFXDECODE_END static MACHINE_CONFIG_START( zrt80 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu",Z80, XTAL_2_4576MHz) - MCFG_CPU_PROGRAM_MAP(zrt80_mem) - MCFG_CPU_IO_MAP(zrt80_io) + MCFG_CPU_PROGRAM_MAP(mem_map) + MCFG_CPU_IO_MAP(io_map) /* video hardware */ MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green()) diff --git a/src/mame/drivers/zsbc3.cpp b/src/mame/drivers/zsbc3.cpp index 95654b03246..bae5b77a8c1 100644 --- a/src/mame/drivers/zsbc3.cpp +++ b/src/mame/drivers/zsbc3.cpp @@ -75,11 +75,6 @@ ADDRESS_MAP_END static INPUT_PORTS_START( zsbc3 ) INPUT_PORTS_END -static DEVICE_INPUT_DEFAULTS_START( terminal ) - DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_9615 ) - DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_9615 ) -DEVICE_INPUT_DEFAULTS_END - static MACHINE_CONFIG_START( zsbc3 ) /* basic machine hardware */ @@ -106,7 +101,6 @@ static MACHINE_CONFIG_START( zsbc3 ) MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "terminal") MCFG_RS232_RXD_HANDLER(DEVWRITELINE("sio", z80sio_device, rxa_w)) MCFG_RS232_CTS_HANDLER(DEVWRITELINE("sio", z80sio_device, ctsa_w)) - MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("terminal", terminal) MCFG_DEVICE_ADD("pio", Z80PIO, XTAL_16MHz / 4) //MCFG_Z80PIO_OUT_INT_CB(INPUTLINE("maincpu", INPUT_LINE_IRQ0)) diff --git a/src/mame/drivers/zt8802.cpp b/src/mame/drivers/zt8802.cpp new file mode 100644 index 00000000000..975b29c3e11 --- /dev/null +++ b/src/mame/drivers/zt8802.cpp @@ -0,0 +1,47 @@ +// license:BSD-3-Clause +// copyright-holders: +/*********************************************************************************************************************************** + +2017-11-02 Skeleton + +Ziatech ZT-8802 single-board computer. Advert says: V40 CPU @ 8MHz, 1MB DRAM, 512K EPROM, 3 RS-232 PORTS. + +CPU is NEC D70208L-10 (V40) which is a V20 with 8251,8253,8255 included. + +Chips: Maxim MAX249CQH, Exar XT16C452CJPS, Ziatech ICPSMCI-16C49A, 2x GAL22V10D, 2x ACT15245, 2x ACT11245, + ACT11240, PALCE 16V??-15JC, 2x CYM1465LPD-120C (RAM). + +Other: A 3.6volt battery, a tiny crystal, a red LED, and about 2 dozen jumpers. + +************************************************************************************************************************************/ + +#include "emu.h" + +class zt8802_state : public driver_device +{ +public: + zt8802_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) +// , m_maincpu(*this, "maincpu") + { } + +private: +// required_device<cpu_device> m_maincpu; +}; + +//static ADDRESS_MAP_START( mem_map, AS_PROGRAM, 8, zt8802_state ) +// AM_RANGE(0x80000,0xfffff) AM_ROM AM_REGION("roms", 0) +//ADDRESS_MAP_END + +static INPUT_PORTS_START( zt8802 ) +INPUT_PORTS_END + +static MACHINE_CONFIG_START( zt8802 ) +MACHINE_CONFIG_END + +ROM_START( zt8802 ) + ROM_REGION( 0x80000, "roms", 0 ) + ROM_LOAD( "c103207-218 a.rom", 0x00000, 0x80000, CRC(fc1c6e99) SHA1(cfbb2f0c9927bac5abc85c12d2b82f7da46cab03) ) +ROM_END + +COMP( 1994, zt8802, 0, 0, zt8802, zt8802, zt8802_state, 0, "Ziatech", "ZT-8802 SBC", MACHINE_IS_SKELETON ) diff --git a/src/mame/drivers/zx.cpp b/src/mame/drivers/zx.cpp index b68e33bdb3d..1b2b4442568 100644 --- a/src/mame/drivers/zx.cpp +++ b/src/mame/drivers/zx.cpp @@ -1,7 +1,8 @@ // license:GPL-2.0+ // copyright-holders: Olivier Galibert, Juergen Buchmueller, Krzysztof Strzecha, Robbbert /*************************************************************************** - zx.c + + ZX-80/ZX-81 and derivatives Original driver by: Juergen Buchmueller, Dec 1999 @@ -81,6 +82,7 @@ static ADDRESS_MAP_START( pow3000_io_map, AS_IO, 8, zx_state ) AM_RANGE(0x0000, 0xffff) AM_READWRITE(pow3000_io_r, zx81_io_w) ADDRESS_MAP_END + /* Input Ports */ static INPUT_PORTS_START( zx80 ) @@ -307,18 +309,14 @@ INPUT_PORTS_END /* Palette Initialization */ - PALETTE_INIT_MEMBER(zx_state, zx) { palette.set_pen_color(0, rgb_t::white()); palette.set_pen_color(1, rgb_t::black()); } -PALETTE_INIT_MEMBER(zx_state,ts1000) -{ - palette.set_pen_color(0, rgb_t(64, 244, 244)); /* cyan */ - palette.set_pen_color(1, rgb_t::black()); -} + +/* Machine Configs */ static MACHINE_CONFIG_START( zx80 ) /* basic machine hardware */ @@ -383,12 +381,10 @@ static MACHINE_CONFIG_DERIVED( zx81_spk, zx81 ) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( ts1000, zx81 ) - MCFG_PALETTE_MODIFY("palette") - MCFG_PALETTE_INIT_OWNER(zx_state, ts1000) - /* internal ram */ MCFG_RAM_MODIFY(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("2K") + MCFG_RAM_EXTRA_OPTIONS("1K,16K,32K,48K") MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( ts1500, ts1000 ) @@ -492,6 +488,7 @@ ROM_START( zx97 ) ROM_LOAD( "zx97.rom", 0x0000, 0x8000, CRC(5cf49744) SHA1(b2a486efdc7b2bc3dc8e5a441ea5532bfa3207bd) ) ROM_END + /* Game Drivers */ // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS diff --git a/src/mame/etc/template_cpu.cpp b/src/mame/etc/template_cpu.cpp index 626e02171fb..a3094005e2c 100644 --- a/src/mame/etc/template_cpu.cpp +++ b/src/mame/etc/template_cpu.cpp @@ -123,7 +123,7 @@ void xxx_cpu_device::state_string_export(const device_state_entry &entry, std::s } -offs_t xxx_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const uint32_t *oprom, const uint32_t *opram, uint32_t options) +offs_t xxx_cpu_device::disassemble(char *buffer, offs_t pc, const uint32_t *oprom, const uint32_t *opram, uint32_t options) { - return CPU_DISASSEMBLE_NAME(xxx)(this, buffer, pc, oprom, opram, options); + return CPU_DISASSEMBLE_NAME(xxx)(this, buffer, pc, opcodes, params, options); } diff --git a/src/mame/etc/template_cpu.h b/src/mame/etc/template_cpu.h index 300d18b0464..72a0c78f89e 100644 --- a/src/mame/etc/template_cpu.h +++ b/src/mame/etc/template_cpu.h @@ -45,9 +45,8 @@ protected: 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(char *buffer, offs_t pc, const uint8_t *oprom, const uint8_t *opram, uint32_t options) override; + virtual uint32_t opcode_alignment() const override { return 4; } + virtual offs_t disassemble(char *buffer, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms, uint32_t options) override; private: address_space_config m_program_config; diff --git a/src/mame/etc/template_driver.cpp b/src/mame/etc/template_driver.cpp index d9a6ecf297d..0879ded9a03 100644 --- a/src/mame/etc/template_driver.cpp +++ b/src/mame/etc/template_driver.cpp @@ -156,7 +156,7 @@ static MACHINE_CONFIG_START( xxx ) // MCFG_SCREEN_SIZE(32*8, 32*8) // MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1) MCFG_SCREEN_RAW_PARAMS(MAIN_CLOCK/2, 442, 0, 320, 264, 0, 240) /* generic NTSC video timing at 320x240 */ - //MCFG_SCREEN_RAW_PARAMS(SYS_A_CPU_CLOCK/4, 442, 0, 256, 263, 16, 240) /* generic NTSC video timing at 256x224 */ + //MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2, 384, 0, 256, 264, 16, 240) /* generic NTSC video timing at 256x224 */ MCFG_SCREEN_PALETTE("palette") MCFG_GFXDECODE_ADD("gfxdecode", "palette", xxx) diff --git a/src/mame/includes/apollo.h b/src/mame/includes/apollo.h index e1006db7bee..d00be887813 100644 --- a/src/mame/includes/apollo.h +++ b/src/mame/includes/apollo.h @@ -327,7 +327,7 @@ void apollo_csr_set_status_register(uint16_t mask, uint16_t data); #define MCFG_APOLLO_SIO_OUTPORT_CALLBACK(_cb) \ devcb = &apollo_sio::set_outport_cb(*device, DEVCB_##_cb); -class apollo_sio: public mc68681_base_device +class apollo_sio: public duart_base_device { public: apollo_sio(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); @@ -340,7 +340,6 @@ protected: private: uint8_t m_csrb; - uint8_t m_ip6; }; DECLARE_DEVICE_TYPE(APOLLO_SIO, apollo_sio) diff --git a/src/mame/includes/aussiebyte.h b/src/mame/includes/aussiebyte.h index 7cb3a5268c6..af21382022a 100644 --- a/src/mame/includes/aussiebyte.h +++ b/src/mame/includes/aussiebyte.h @@ -20,7 +20,7 @@ #include "machine/msm5832.h" #include "machine/wd_fdc.h" #include "machine/z80ctc.h" -#include "machine/z80dart.h" +#include "machine/z80sio.h" #include "machine/z80dma.h" #include "machine/z80pio.h" @@ -49,8 +49,6 @@ public: , m_dma(*this, "dma") , m_pio1(*this, "pio1") , m_pio2(*this, "pio2") - , m_sio1(*this, "sio1") - , m_sio2(*this, "sio2") , m_centronics(*this, "centronics") , m_rs232(*this, "rs232") , m_fdc(*this, "fdc") @@ -92,11 +90,8 @@ public: DECLARE_WRITE_LINE_MEMBER(sio1_rdyb_w); DECLARE_WRITE_LINE_MEMBER(sio2_rdya_w); DECLARE_WRITE_LINE_MEMBER(sio2_rdyb_w); - DECLARE_WRITE_LINE_MEMBER(clock_w); DECLARE_MACHINE_RESET(aussiebyte); DECLARE_DRIVER_INIT(aussiebyte); - DECLARE_WRITE_LINE_MEMBER(ctc_z0_w); - DECLARE_WRITE_LINE_MEMBER(ctc_z1_w); DECLARE_WRITE_LINE_MEMBER(ctc_z2_w); DECLARE_WRITE8_MEMBER(address_w); DECLARE_WRITE8_MEMBER(register_w); @@ -127,8 +122,6 @@ private: required_device<z80dma_device> m_dma; required_device<z80pio_device> m_pio1; required_device<z80pio_device> m_pio2; - required_device<z80sio0_device> m_sio1; - required_device<z80sio0_device> m_sio2; required_device<centronics_device> m_centronics; required_device<rs232_port_device> m_rs232; required_device<wd2797_device> m_fdc; diff --git a/src/mame/includes/bbc.h b/src/mame/includes/bbc.h index b0ad68e3697..7fdc56713b4 100644 --- a/src/mame/includes/bbc.h +++ b/src/mame/includes/bbc.h @@ -161,6 +161,7 @@ public: DECLARE_MACHINE_RESET(bbcmc); DECLARE_MACHINE_RESET(ltmpbp); DECLARE_MACHINE_RESET(ltmpm); + DECLARE_MACHINE_START(cfa3000); DECLARE_PALETTE_INIT(bbc); INTERRUPT_GEN_MEMBER(bbcb_vsync); @@ -278,6 +279,9 @@ public: // HACK FOR MC6845 int m_pagedRAM; // BBC B+ memory handling int m_vdusel; // BBC B+ memory handling + bool m_lk18_ic41_paged_rom; // BBC Master Paged ROM/RAM select IC41 + bool m_lk19_ic37_paged_rom; // BBC Master Paged ROM/RAM select IC37 + /* ACCCON diff --git a/src/mame/includes/bishi.h b/src/mame/includes/bishi.h index b0339261384..8acc704420d 100644 --- a/src/mame/includes/bishi.h +++ b/src/mame/includes/bishi.h @@ -29,16 +29,30 @@ public: m_palette(*this, "palette"), m_screen(*this, "screen") { } + DECLARE_READ16_MEMBER(control_r); + DECLARE_WRITE16_MEMBER(control_w); + DECLARE_WRITE16_MEMBER(control2_w); + DECLARE_READ16_MEMBER(bishi_mirror_r); + DECLARE_READ16_MEMBER(bishi_K056832_rom_r); + uint32_t screen_update_bishi(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + TIMER_DEVICE_CALLBACK_MEMBER(bishi_scanline); + K056832_CB_MEMBER(tile_callback); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; +private: /* memory pointers */ uint8_t * m_ram; - /* video-related */ - int m_layer_colorbase[4]; - /* misc */ uint16_t m_cur_control; uint16_t m_cur_control2; + /* video-related */ + int m_layer_colorbase[4]; + /* devices */ required_device<cpu_device> m_maincpu; optional_device<cpu_device> m_audiocpu; @@ -47,15 +61,4 @@ public: required_device<k055555_device> m_k055555; required_device<palette_device> m_palette; required_device<screen_device> m_screen; - DECLARE_READ16_MEMBER(control_r); - DECLARE_WRITE16_MEMBER(control_w); - DECLARE_WRITE16_MEMBER(control2_w); - DECLARE_READ16_MEMBER(bishi_mirror_r); - DECLARE_READ16_MEMBER(bishi_K056832_rom_r); - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - uint32_t screen_update_bishi(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - TIMER_DEVICE_CALLBACK_MEMBER(bishi_scanline); - K056832_CB_MEMBER(tile_callback); }; diff --git a/src/mame/includes/cave.h b/src/mame/includes/cave.h index d78be9c2fa6..8f9c2d5fa28 100644 --- a/src/mame/includes/cave.h +++ b/src/mame/includes/cave.h @@ -1,5 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Luca Elia +#ifndef MAME_INCLUDES_CAVE_H +#define MAME_INCLUDES_CAVE_H + +#pragma once /*************************************************************************** @@ -14,26 +18,31 @@ #include "sound/okim6295.h" #include "screen.h" -struct sprite_cave +class cave_state : public driver_device { - int priority, flags; +public: + enum + { + MAX_PRIORITY = 4, + MAX_SPRITE_NUM = 0x400 + }; - const uint8_t *pen_data; /* points to top left corner of tile data */ - int line_offset; + struct sprite_cave + { + sprite_cave() { } - pen_t base_pen; - int tile_width, tile_height; - int total_width, total_height; /* in screen coordinates */ - int x, y, xcount0, ycount0; - int zoomx_re, zoomy_re; -}; + int priority = 0, flags = 0; -#define MAX_PRIORITY 4 -#define MAX_SPRITE_NUM 0x400 + const uint8_t *pen_data = nullptr; /* points to top left corner of tile data */ + int line_offset = 0; + + pen_t base_pen = 0; + int tile_width = 0, tile_height = 0; + int total_width = 0, total_height = 0; /* in screen coordinates */ + int x = 0, y = 0, xcount0 = 0, ycount0 = 0; + int zoomx_re = 0, zoomy_re = 0; + }; -class cave_state : public driver_device -{ -public: cave_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_videoregs(*this, "videoregs.%u", 0) @@ -63,8 +72,8 @@ public: optional_shared_ptr_array<uint16_t, 4> m_paletteram; /* video-related */ - struct sprite_cave *m_sprite[4]; - struct sprite_cave *m_sprite_table[4][MAX_PRIORITY][MAX_SPRITE_NUM + 1]; + std::unique_ptr<sprite_cave []> m_sprite[4]; + sprite_cave *m_sprite_table[4][MAX_PRIORITY][MAX_SPRITE_NUM + 1]; struct { @@ -268,10 +277,10 @@ private: void get_sprite_info_donpachi(int chip); void sprite_init_cave(); void cave_sprite_check(int chip, screen_device &screen, const rectangle &clip); - void do_blit_zoom32_cave( int chip, const struct sprite_cave *sprite ); - void do_blit_zoom32_cave_zb( int chip, const struct sprite_cave *sprite ); - void do_blit_32_cave( int chip, const struct sprite_cave *sprite ); - void do_blit_32_cave_zb( int chip, const struct sprite_cave *sprite ); + void do_blit_zoom32_cave( int chip, const sprite_cave *sprite ); + void do_blit_zoom32_cave_zb( int chip, const sprite_cave *sprite ); + void do_blit_32_cave( int chip, const sprite_cave *sprite ); + void do_blit_32_cave_zb( int chip, const sprite_cave *sprite ); void sprite_draw_cave( int chip, int priority ); void sprite_draw_cave_zbuf( int chip, int priority ); void sprite_draw_donpachi( int chip, int priority ); @@ -279,3 +288,5 @@ private: void init_cave(); void show_leds(); }; + +#endif // MAME_INCLUDES_CAVE_H diff --git a/src/mame/includes/chqflag.h b/src/mame/includes/chqflag.h index e750ec0d29e..ae70e7afe2b 100644 --- a/src/mame/includes/chqflag.h +++ b/src/mame/includes/chqflag.h @@ -30,6 +30,26 @@ public: m_soundlatch2(*this, "soundlatch2"), m_rombank(*this, "rombank") { } + DECLARE_READ8_MEMBER(k051316_1_ramrom_r); + DECLARE_READ8_MEMBER(k051316_2_ramrom_r); + DECLARE_WRITE8_MEMBER(chqflag_bankswitch_w); + DECLARE_WRITE8_MEMBER(chqflag_vreg_w); + DECLARE_WRITE8_MEMBER(select_analog_ctrl_w); + DECLARE_READ8_MEMBER(analog_read_r); + DECLARE_WRITE8_MEMBER(chqflag_sh_irqtrigger_w); + DECLARE_WRITE8_MEMBER(k007232_bankswitch_w); + DECLARE_WRITE8_MEMBER(k007232_extvolume_w); + DECLARE_WRITE8_MEMBER(volume_callback0); + DECLARE_WRITE8_MEMBER(volume_callback1); + DECLARE_WRITE_LINE_MEMBER(background_brt_w); + K051316_CB_MEMBER(zoom_callback_1); + K051316_CB_MEMBER(zoom_callback_2); + K051960_CB_MEMBER(sprite_callback); + uint32_t screen_update_chqflag(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); +protected: + virtual void machine_start() override; + virtual void machine_reset() override; +private: /* misc */ int m_k051316_readroms; int m_last_vreg; @@ -51,22 +71,5 @@ public: /* memory pointers */ required_memory_bank m_rombank; - - DECLARE_READ8_MEMBER(k051316_1_ramrom_r); - DECLARE_READ8_MEMBER(k051316_2_ramrom_r); - DECLARE_WRITE8_MEMBER(chqflag_bankswitch_w); - DECLARE_WRITE8_MEMBER(chqflag_vreg_w); - DECLARE_WRITE8_MEMBER(select_analog_ctrl_w); - DECLARE_READ8_MEMBER(analog_read_r); - DECLARE_WRITE8_MEMBER(chqflag_sh_irqtrigger_w); - DECLARE_WRITE8_MEMBER(k007232_bankswitch_w); - DECLARE_WRITE8_MEMBER(k007232_extvolume_w); - virtual void machine_start() override; - virtual void machine_reset() override; - uint32_t screen_update_chqflag(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - DECLARE_WRITE8_MEMBER(volume_callback0); - DECLARE_WRITE8_MEMBER(volume_callback1); - K051316_CB_MEMBER(zoom_callback_1); - K051316_CB_MEMBER(zoom_callback_2); - K051960_CB_MEMBER(sprite_callback); + void update_background_shadows(uint8_t data); }; diff --git a/src/mame/includes/coco.h b/src/mame/includes/coco.h index db443136174..698e5863d05 100644 --- a/src/mame/includes/coco.h +++ b/src/mame/includes/coco.h @@ -132,8 +132,8 @@ public: virtual address_space &cartridge_space() override; // disassembly override - static offs_t os9_dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options); - offs_t dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options); + static offs_t os9_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms); + offs_t dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms); protected: // device-level overrides diff --git a/src/mame/includes/darius.h b/src/mame/includes/darius.h index 5e4b14d85ae..1febec434f7 100644 --- a/src/mame/includes/darius.h +++ b/src/mame/includes/darius.h @@ -6,7 +6,6 @@ *************************************************************************/ -#include "audio/taitosnd.h" #include "sound/flt_vol.h" #include "sound/msm5205.h" #include "video/pc080sn.h" @@ -27,7 +26,6 @@ public: m_cpub(*this, "cpub"), m_adpcm(*this, "adpcm"), m_pc080sn(*this, "pc080sn"), - m_ciu(*this, "ciu"), m_filter0_0l(*this, "filter0.0l"), m_filter0_0r(*this, "filter0.0r"), m_filter0_1l(*this, "filter0.1l"), @@ -72,7 +70,6 @@ public: required_device<cpu_device> m_cpub; required_device<cpu_device> m_adpcm; required_device<pc080sn_device> m_pc080sn; - required_device<pc060ha_device> m_ciu; required_device<filter_volume_device> m_filter0_0l; required_device<filter_volume_device> m_filter0_0r; @@ -96,8 +93,8 @@ public: required_device<palette_device> m_palette; DECLARE_WRITE16_MEMBER(cpua_ctrl_w); - DECLARE_READ16_MEMBER(darius_ioc_r); - DECLARE_WRITE16_MEMBER(darius_ioc_w); + DECLARE_READ16_MEMBER(coin_r); + DECLARE_WRITE16_MEMBER(coin_w); DECLARE_WRITE8_MEMBER(sound_bankswitch_w); DECLARE_WRITE8_MEMBER(adpcm_command_w); DECLARE_WRITE8_MEMBER(darius_fm0_pan); diff --git a/src/mame/includes/dec0.h b/src/mame/includes/dec0.h index b748b05a5d0..38a29f172b7 100644 --- a/src/mame/includes/dec0.h +++ b/src/mame/includes/dec0.h @@ -28,6 +28,7 @@ public: m_tilegen3(*this, "tilegen3"), m_spritegen(*this, "spritegen"), m_pfprotect(*this, "pfprotect"), + m_sndprotect(*this, "sndprotect"), m_soundlatch(*this, "soundlatch"), m_ram(*this, "ram"), m_spriteram(*this, "spriteram"), @@ -45,6 +46,7 @@ public: optional_device<deco_bac06_device> m_tilegen3; optional_device<deco_mxc06_device> m_spritegen; optional_device<address_map_bank_device> m_pfprotect; + optional_device<address_map_bank_device> m_sndprotect; required_device<generic_latch_8_device> m_soundlatch; required_shared_ptr<uint16_t> m_ram; @@ -57,6 +59,7 @@ public: uint16_t m_i8751_return; uint16_t m_i8751_command; int m_slyspy_state; + int m_slyspy_sound_state; int m_hippodrm_msb; int m_hippodrm_lsb; uint8_t m_i8751_ports[4]; @@ -84,6 +87,9 @@ public: DECLARE_WRITE16_MEMBER(dec0_priority_w); DECLARE_READ16_MEMBER(ffantasybl_242024_r); + DECLARE_READ8_MEMBER(slyspy_sound_state_r); + DECLARE_READ8_MEMBER(slyspy_sound_state_reset_r); + DECLARE_DRIVER_INIT(robocop); DECLARE_DRIVER_INIT(hippodrm); DECLARE_DRIVER_INIT(hbarrel); diff --git a/src/mame/includes/dgn_beta.h b/src/mame/includes/dgn_beta.h index 9e6d7f24c7c..cd7cdad4d92 100644 --- a/src/mame/includes/dgn_beta.h +++ b/src/mame/includes/dgn_beta.h @@ -230,7 +230,7 @@ public: void ScanInKeyboard(void); void dgn_beta_frame_interrupt (int data); - offs_t dgnbeta_dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options); + offs_t dgnbeta_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms); private: void execute_beta_key_dump(int ref, const std::vector<std::string> ¶ms); diff --git a/src/mame/includes/einstein.h b/src/mame/includes/einstein.h deleted file mode 100644 index 7e12b8a4017..00000000000 --- a/src/mame/includes/einstein.h +++ /dev/null @@ -1,186 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Kevin Thacker, Dirk Best, Phill Harvey-Smith -/*************************************************************************** - - Tatung Einstein - -***************************************************************************/ - -#ifndef MAME_INCLUDES_EINSTEIN_H -#define MAME_INCLUDES_EINSTEIN_H - -#pragma once - -#include "cpu/z80/z80daisy.h" -#include "bus/einstein/pipe.h" -#include "machine/timer.h" -#include "machine/wd_fdc.h" -#include "machine/z80ctc.h" -#include "video/tms9928a.h" -#include "machine/ram.h" -#include "machine/i8251.h" -#include "bus/centronics/ctronics.h" -#include "screen.h" - - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* xtals */ -#define XTAL_X001 XTAL_10_738635MHz -#define XTAL_X002 XTAL_8MHz - -/* integrated circuits */ -#define IC_I001 "i001" /* Z8400A */ -#define IC_I030 "i030" /* AY-3-8910 */ -#define IC_I038 "i038" /* TMM9129 */ -#define IC_I042 "i042" /* WD1770-PH */ -#define IC_I050 "i050" /* ADC0844CCN */ -#define IC_I058 "i058" /* Z8430A */ -#define IC_I060 "i060" /* uPD8251A */ -#define IC_I063 "i063" /* Z8420A */ - -/* interrupt sources */ -#define EINSTEIN_KEY_INT (1<<0) -#define EINSTEIN_ADC_INT (1<<1) -#define EINSTEIN_FIRE_INT (1<<2) - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -class einstein_state : public driver_device -{ -public: - einstein_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, IC_I001), - m_pipe(*this, "pipe"), - m_fdc(*this, IC_I042), - m_uart(*this, IC_I060), - m_ram(*this, RAM_TAG), - m_centronics(*this, "centronics"), - m_region_bios(*this, "bios"), - m_bank1(*this, "bank1"), - m_bank2(*this, "bank2"), - m_bank3(*this, "bank3"), - m_line(*this, "LINE%u", 0), - m_extra(*this, "EXTRA"), - m_buttons(*this, "BUTTONS"), - m_config(*this, "config") - { - } - - DECLARE_FLOPPY_FORMATS( floppy_formats ); - DECLARE_WRITE8_MEMBER(einstein_keyboard_line_write); - DECLARE_READ8_MEMBER(einstein_keyboard_data_read); - DECLARE_WRITE8_MEMBER(einstein_rom_w); - DECLARE_READ8_MEMBER(einstein_kybintmsk_r); - DECLARE_WRITE8_MEMBER(einstein_kybintmsk_w); - DECLARE_WRITE8_MEMBER(einstein_adcintmsk_w); - DECLARE_WRITE8_MEMBER(einstein_fire_int_w); - DECLARE_WRITE_LINE_MEMBER(write_centronics_busy); - DECLARE_WRITE_LINE_MEMBER(write_centronics_perror); - DECLARE_WRITE_LINE_MEMBER(write_centronics_fault); - TIMER_DEVICE_CALLBACK_MEMBER(einstein_keyboard_timer_callback); - DECLARE_WRITE8_MEMBER(einstein_drsel_w); - DECLARE_WRITE_LINE_MEMBER(einstein_serial_transmit_clock); - DECLARE_WRITE_LINE_MEMBER(einstein_serial_receive_clock); - - int m_interrupt; - int m_interrupt_mask; - -protected: - virtual void machine_start() override; - virtual void machine_reset() override; - -private: - required_device<cpu_device> m_maincpu; - required_device<tatung_pipe_device> m_pipe; - required_device<wd1770_device> m_fdc; - - int m_rom_enabled; - - /* keyboard */ - uint8_t m_keyboard_line; - uint8_t m_keyboard_data; - - int m_centronics_busy; - int m_centronics_perror; - int m_centronics_fault; - - required_device<i8251_device> m_uart; - required_device<ram_device> m_ram; - required_device<centronics_device> m_centronics; - required_memory_region m_region_bios; - required_memory_bank m_bank1; - required_memory_bank m_bank2; - required_memory_bank m_bank3; - required_ioport_array<8> m_line; - required_ioport m_extra; - required_ioport m_buttons; - required_ioport m_config; - - void einstein_scan_keyboard(); - void einstein_page_rom(); -}; - - -// ======================> einstein_keyboard_daisy_device - -class einstein_keyboard_daisy_device : public device_t, public device_z80daisy_interface -{ -public: - // construction/destruction - einstein_keyboard_daisy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -private: - virtual void device_start() override; - // z80daisy_interface overrides - virtual int z80daisy_irq_state() override; - virtual int z80daisy_irq_ack() override; - virtual void z80daisy_irq_reti() override; -}; - -DECLARE_DEVICE_TYPE(EINSTEIN_KEYBOARD_DAISY, einstein_keyboard_daisy_device) - - -// ======================> einstein_adc_daisy_device - -class einstein_adc_daisy_device : public device_t, public device_z80daisy_interface -{ -public: - // construction/destruction - einstein_adc_daisy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -private: - virtual void device_start() override; - // z80daisy_interface overrides - virtual int z80daisy_irq_state() override; - virtual int z80daisy_irq_ack() override; - virtual void z80daisy_irq_reti() override; - -}; - -DECLARE_DEVICE_TYPE(EINSTEIN_ADC_DAISY, einstein_adc_daisy_device) - -// ======================> einstein_fire_daisy_device - -class einstein_fire_daisy_device : public device_t, public device_z80daisy_interface -{ -public: - // construction/destruction - einstein_fire_daisy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - -private: - virtual void device_start() override; - // z80daisy_interface overrides - virtual int z80daisy_irq_state() override; - virtual int z80daisy_irq_ack() override; - virtual void z80daisy_irq_reti() override; -}; - -DECLARE_DEVICE_TYPE(EINSTEIN_FIRE_DAISY, einstein_fire_daisy_device) - -#endif // MAME_INCLUDES_EINSTEIN_H diff --git a/src/mame/includes/electron.h b/src/mame/includes/electron.h index 3d2e7599cb8..f0f92d3dd77 100644 --- a/src/mame/includes/electron.h +++ b/src/mame/includes/electron.h @@ -75,7 +75,6 @@ public: m_maincpu(*this, "maincpu"), m_cassette(*this, "cassette"), m_beeper(*this, "beeper"), - m_cart(*this, "cartslot"), m_keybd(*this, "LINE.%u", 0), m_exp(*this, "exp"), m_ram(*this, RAM_TAG) @@ -109,14 +108,12 @@ public: required_device<cpu_device> m_maincpu; required_device<cassette_image_device> m_cassette; required_device<beep_device> m_beeper; - required_device<generic_slot_device> m_cart; required_ioport_array<14> m_keybd; required_device<electron_expansion_slot_device> m_exp; required_device<ram_device> m_ram; inline uint8_t read_vram( uint16_t addr ); inline void electron_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color); void electron_interrupt_handler(int mode, int interrupt); - DECLARE_DEVICE_IMAGE_LOAD_MEMBER( electron_cart ); DECLARE_INPUT_CHANGED_MEMBER( trigger_reset ); protected: diff --git a/src/mame/includes/fmtowns.h b/src/mame/includes/fmtowns.h index 7e6557146f6..ea04463de5f 100644 --- a/src/mame/includes/fmtowns.h +++ b/src/mame/includes/fmtowns.h @@ -95,7 +95,9 @@ class towns_state : public driver_device m_pit(*this, "pit"), m_dma_1(*this, "dma_1"), m_dma_2(*this, "dma_2"), - m_palette(*this, "palette"), + m_palette(*this, "palette256"), + m_palette16_0(*this, "palette16_0"), + m_palette16_1(*this, "palette16_1"), m_ram(*this, RAM_TAG), m_fdc(*this, "fdc"), m_flop0(*this, "fdc:0"), @@ -131,6 +133,8 @@ class towns_state : public driver_device required_device<upd71071_device> m_dma_1; required_device<upd71071_device> m_dma_2; required_device<palette_device> m_palette; + required_device<palette_device> m_palette16_0; + required_device<palette_device> m_palette16_1; required_device<ram_device> m_ram; required_device<mb8877_device> m_fdc; required_device<floppy_connector> m_flop0; diff --git a/src/mame/includes/gladiatr.h b/src/mame/includes/gladiatr.h index 7313527c675..5eddec0821d 100644 --- a/src/mame/includes/gladiatr.h +++ b/src/mame/includes/gladiatr.h @@ -14,6 +14,10 @@ public: DECLARE_WRITE8_MEMBER(paletteram_w); DECLARE_WRITE_LINE_MEMBER(spritebuffer_w); DECLARE_WRITE8_MEMBER(spritebuffer_w); + DECLARE_WRITE8_MEMBER(adpcm_command_w); + DECLARE_READ8_MEMBER(adpcm_command_r); + DECLARE_WRITE_LINE_MEMBER(flipscreen_w); + DECLARE_WRITE_LINE_MEMBER(ym_irq); protected: gladiatr_state_base(const machine_config &mconfig, device_type type, const char *tag) @@ -104,13 +108,9 @@ public: DECLARE_WRITE_LINE_MEMBER(spritebank_w); DECLARE_WRITE8_MEMBER(gladiatr_video_registers_w); - DECLARE_WRITE8_MEMBER(gladiator_cpu_sound_command_w); - DECLARE_READ8_MEMBER(gladiator_cpu_sound_command_r); - DECLARE_WRITE_LINE_MEMBER(flipscreen_w); DECLARE_WRITE8_MEMBER(gladiatr_irq_patch_w); DECLARE_WRITE8_MEMBER(gladiator_int_control_w); DECLARE_WRITE8_MEMBER(gladiator_adpcm_w); - DECLARE_WRITE_LINE_MEMBER(gladiator_ym_irq); DECLARE_WRITE_LINE_MEMBER(tclk_w); DECLARE_READ8_MEMBER(cctl_p1_r); @@ -159,24 +159,22 @@ public: ppking_state(const machine_config &mconfig, device_type type, const char *tag) : gladiatr_state_base(mconfig, type, tag) , m_nvram(*this, "nvram") - , m_data1(0) - , m_data2(0) - , m_flag1(0) - , m_flag2(0) + , m_soundlatch2(*this, "soundlatch2") { } DECLARE_READ8_MEMBER(ppking_f1_r); - DECLARE_READ8_MEMBER(ppking_f6a3_r); DECLARE_WRITE8_MEMBER(ppking_qx0_w); DECLARE_WRITE8_MEMBER(ppking_qx1_w); - DECLARE_WRITE8_MEMBER(ppking_qx2_w); DECLARE_WRITE8_MEMBER(ppking_qx3_w); - DECLARE_READ8_MEMBER(ppking_qx2_r); DECLARE_READ8_MEMBER(ppking_qx3_r); DECLARE_READ8_MEMBER(ppking_qx0_r); DECLARE_READ8_MEMBER(ppking_qx1_r); + DECLARE_READ8_MEMBER(ppking_qxcomu_r); + DECLARE_WRITE8_MEMBER(ppking_qxcomu_w); DECLARE_WRITE8_MEMBER(ppking_video_registers_w); + DECLARE_WRITE8_MEMBER(ppking_adpcm_w); + DECLARE_WRITE8_MEMBER(cpu2_irq_ack_w); DECLARE_DRIVER_INIT(ppking); @@ -187,9 +185,17 @@ public: private: required_shared_ptr<uint8_t> m_nvram; + required_device<generic_latch_8_device> m_soundlatch2; - u8 m_data1; - u8 m_data2; - u8 m_flag1; - u8 m_flag2; + struct + { + uint8_t rxd; + uint8_t txd; + uint8_t rst; + uint8_t state; + uint8_t packet_type; + } m_mcu[2]; + + bool mcu_parity_check(); + void mcu_input_check(); }; diff --git a/src/mame/includes/hyprduel.h b/src/mame/includes/hyprduel.h index 14e3397c785..0503888a071 100644 --- a/src/mame/includes/hyprduel.h +++ b/src/mame/includes/hyprduel.h @@ -18,6 +18,7 @@ public: m_vram_2(*this, "vram_2"), m_paletteram(*this, "paletteram"), m_spriteram(*this, "spriteram"), + m_spriteregs(*this, "spriteregs"), m_tiletable(*this, "tiletable"), m_blitter_regs(*this, "blitter_regs"), m_window(*this, "window"), @@ -34,12 +35,49 @@ public: m_screen(*this, "screen"), m_palette(*this, "palette") { } + DECLARE_READ16_MEMBER(irq_cause_r); + DECLARE_WRITE16_MEMBER(irq_cause_w); + DECLARE_WRITE16_MEMBER(subcpu_control_w); + DECLARE_READ16_MEMBER(hyprduel_cpusync_trigger1_r); + DECLARE_WRITE16_MEMBER(hyprduel_cpusync_trigger1_w); + DECLARE_READ16_MEMBER(hyprduel_cpusync_trigger2_r); + DECLARE_WRITE16_MEMBER(hyprduel_cpusync_trigger2_w); + DECLARE_READ16_MEMBER(bankedrom_r); + DECLARE_WRITE16_MEMBER(blitter_w); + DECLARE_WRITE16_MEMBER(paletteram_w); + DECLARE_WRITE16_MEMBER(vram_0_w); + DECLARE_WRITE16_MEMBER(vram_1_w); + DECLARE_WRITE16_MEMBER(vram_2_w); + DECLARE_WRITE16_MEMBER(window_w); + DECLARE_WRITE16_MEMBER(scrollreg_w); + DECLARE_WRITE16_MEMBER(scrollreg_init_w); + DECLARE_DRIVER_INIT(magerror); + DECLARE_DRIVER_INIT(hyprduel); + TILE_GET_INFO_MEMBER(get_tile_info_0_8bit); + TILE_GET_INFO_MEMBER(get_tile_info_1_8bit); + TILE_GET_INFO_MEMBER(get_tile_info_2_8bit); + DECLARE_MACHINE_START(hyprduel); + DECLARE_VIDEO_START(hyprduel_14220); + DECLARE_MACHINE_START(magerror); + DECLARE_VIDEO_START(magerror_14220); + DECLARE_VIDEO_START(common_14220); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + TIMER_CALLBACK_MEMBER(vblank_end_callback); + TIMER_CALLBACK_MEMBER(magerror_irq_callback); + TIMER_CALLBACK_MEMBER(blit_done); + TIMER_DEVICE_CALLBACK_MEMBER(interrupt); + +protected: + virtual void machine_reset() override; + +private: /* memory pointers */ required_shared_ptr<uint16_t> m_vram_0; required_shared_ptr<uint16_t> m_vram_1; required_shared_ptr<uint16_t> m_vram_2; required_shared_ptr<uint16_t> m_paletteram; required_shared_ptr<uint16_t> m_spriteram; + required_shared_ptr<uint16_t> m_spriteregs; required_shared_ptr<uint16_t> m_tiletable; required_shared_ptr<uint16_t> m_blitter_regs; required_shared_ptr<uint16_t> m_window; @@ -58,7 +96,6 @@ public: std::unique_ptr<uint8_t[]> m_dirtyindex; int m_sprite_xoffs; int m_sprite_yoffs; - int m_sprite_yoffs_sub; std::unique_ptr<uint8_t[]> m_expanded_gfx1; /* misc */ @@ -78,39 +115,6 @@ public: required_device<screen_device> m_screen; required_device<palette_device> m_palette; - DECLARE_READ16_MEMBER(irq_cause_r); - DECLARE_WRITE16_MEMBER(irq_cause_w); - DECLARE_WRITE16_MEMBER(subcpu_control_w); - DECLARE_READ16_MEMBER(hyprduel_cpusync_trigger1_r); - DECLARE_WRITE16_MEMBER(hyprduel_cpusync_trigger1_w); - DECLARE_READ16_MEMBER(hyprduel_cpusync_trigger2_r); - DECLARE_WRITE16_MEMBER(hyprduel_cpusync_trigger2_w); - DECLARE_READ16_MEMBER(bankedrom_r); - DECLARE_WRITE16_MEMBER(blitter_w); - DECLARE_WRITE16_MEMBER(paletteram_w); - DECLARE_WRITE16_MEMBER(vram_0_w); - DECLARE_WRITE16_MEMBER(vram_1_w); - DECLARE_WRITE16_MEMBER(vram_2_w); - DECLARE_WRITE16_MEMBER(window_w); - DECLARE_WRITE16_MEMBER(scrollreg_w); - DECLARE_WRITE16_MEMBER(scrollreg_init_w); - void blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask ); - DECLARE_DRIVER_INIT(magerror); - DECLARE_DRIVER_INIT(hyprduel); - TILE_GET_INFO_MEMBER(get_tile_info_0_8bit); - TILE_GET_INFO_MEMBER(get_tile_info_1_8bit); - TILE_GET_INFO_MEMBER(get_tile_info_2_8bit); - virtual void machine_reset() override; - DECLARE_MACHINE_START(hyprduel); - DECLARE_VIDEO_START(hyprduel_14220); - DECLARE_MACHINE_START(magerror); - DECLARE_VIDEO_START(magerror_14220); - DECLARE_VIDEO_START(common_14220); - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_CALLBACK_MEMBER(vblank_end_callback); - TIMER_CALLBACK_MEMBER(magerror_irq_callback); - TIMER_CALLBACK_MEMBER(blit_done); - TIMER_DEVICE_CALLBACK_MEMBER(interrupt); void postload(); inline void get_tile_info( tile_data &tileinfo, int tile_index, int layer, uint16_t *vram); inline void get_tile_info_8bit( tile_data &tileinfo, int tile_index, int layer, uint16_t *vram ); @@ -123,4 +127,5 @@ public: void dirty_tiles( int layer, uint16_t *vram ); void update_irq_state( ); inline int blt_read( const uint8_t *ROM, const int offs ); + void blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask ); }; diff --git a/src/mame/includes/interpro.h b/src/mame/includes/interpro.h index d64884fe77d..e40969ad172 100644 --- a/src/mame/includes/interpro.h +++ b/src/mame/includes/interpro.h @@ -15,7 +15,7 @@ #include "machine/interpro_arbga.h" #include "machine/ram.h" -#include "machine/eeprom.h" +#include "machine/28fxxx.h" #include "machine/mc146818.h" #include "machine/z80scc.h" #include "machine/upd765.h" @@ -55,37 +55,16 @@ #define INTERPRO_IDPROM_TAG "idprom" #define INTERPRO_EPROM_TAG "eprom" -#define INTERPRO_EEPROM_TAG "eeprom" +#define INTERPRO_FLASH_TAG "flash" #define INTERPRO_SRBUS_TAG "sr" -class interpro_eeprom_device : public eeprom_base_device -{ -public: - interpro_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - DECLARE_READ16_MEMBER(eeprom_r) { return read(offset); } - DECLARE_WRITE16_MEMBER(eeprom_w) { if (m_write_enable) write(offset, data); } - - DECLARE_WRITE_LINE_MEMBER(write_enable) { m_write_enable = state; } - -protected: - virtual void device_start() override { eeprom_base_device::device_start(); } - virtual void device_reset() override { eeprom_base_device::device_reset(); } - -private: - int m_write_enable; -}; - -DECLARE_DEVICE_TYPE(INTERPRO_EEPROM, interpro_eeprom_device) - class interpro_state : public driver_device { public: interpro_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, INTERPRO_CPU_TAG) - , m_mmu(*this, INTERPRO_MMU_TAG) , m_ram(*this, RAM_TAG) , m_mcga(*this, INTERPRO_MCGA_TAG) , m_sga(*this, INTERPRO_SGA_TAG) @@ -98,10 +77,10 @@ public: , m_scsi(*this, INTERPRO_SCSI_DEVICE_TAG) , m_eth(*this, INTERPRO_ETH_TAG) , m_ioga(*this, INTERPRO_IOGA_TAG) - { } + { + } required_device<clipper_device> m_maincpu; - required_device<cammu_device> m_mmu; required_device<ram_device> m_ram; required_device<interpro_mcga_device> m_mcga; @@ -116,7 +95,7 @@ public: required_device<i82586_base_device> m_eth; required_device<interpro_ioga_device> m_ioga; - DECLARE_DRIVER_INIT(interpro); + DECLARE_DRIVER_INIT(common); enum sreg_error_mask { @@ -200,9 +179,17 @@ class turquoise_state : public interpro_state public: turquoise_state(const machine_config &mconfig, device_type type, const char *tag) : interpro_state(mconfig, type, tag) - {} + , m_d_cammu(*this, INTERPRO_MMU_TAG "_d") + , m_i_cammu(*this, INTERPRO_MMU_TAG "_i") + { + } + + DECLARE_DRIVER_INIT(turquoise); DECLARE_WRITE8_MEMBER(sreg_error_w) { m_sreg_error = data; } + + required_device<cammu_c3_device> m_d_cammu; + required_device<cammu_c3_device> m_i_cammu; }; class sapphire_state : public interpro_state @@ -210,12 +197,20 @@ class sapphire_state : public interpro_state public: sapphire_state(const machine_config &mconfig, device_type type, const char *tag) : interpro_state(mconfig, type, tag) - , m_eeprom(*this, INTERPRO_EEPROM_TAG) - {} + , m_mmu(*this, INTERPRO_MMU_TAG) + , m_flash_lo(*this, INTERPRO_FLASH_TAG "_lo") + , m_flash_hi(*this, INTERPRO_FLASH_TAG "_hi") + { + } - required_device<interpro_eeprom_device> m_eeprom; + DECLARE_DRIVER_INIT(sapphire); virtual DECLARE_WRITE16_MEMBER(sreg_ctrl2_w) override; + + required_device<cammu_c4_device> m_mmu; + + required_device<intel_28f010_device> m_flash_lo; + required_device<intel_28f010_device> m_flash_hi; }; #endif // MAME_INCLUDES_INTERPRO_H diff --git a/src/mame/includes/kaypro.h b/src/mame/includes/kaypro.h index 19c872a49fb..2654546ffa0 100644 --- a/src/mame/includes/kaypro.h +++ b/src/mame/includes/kaypro.h @@ -38,17 +38,17 @@ public: {} DECLARE_WRITE_LINE_MEMBER(write_centronics_busy); - DECLARE_READ8_MEMBER(kaypro2x_87_r); - DECLARE_READ8_MEMBER(kaypro2x_system_port_r); - DECLARE_READ8_MEMBER(kaypro2x_status_r); - DECLARE_READ8_MEMBER(kaypro2x_videoram_r); - DECLARE_WRITE8_MEMBER(kaypro2x_system_port_w); - DECLARE_WRITE8_MEMBER(kaypro2x_index_w); - DECLARE_WRITE8_MEMBER(kaypro2x_register_w); - DECLARE_WRITE8_MEMBER(kaypro2x_videoram_w); + DECLARE_READ8_MEMBER(kaypro484_87_r); + DECLARE_READ8_MEMBER(kaypro484_system_port_r); + DECLARE_READ8_MEMBER(kaypro484_status_r); + DECLARE_READ8_MEMBER(kaypro484_videoram_r); + DECLARE_WRITE8_MEMBER(kaypro484_system_port_w); + DECLARE_WRITE8_MEMBER(kaypro484_index_w); + DECLARE_WRITE8_MEMBER(kaypro484_register_w); + DECLARE_WRITE8_MEMBER(kaypro484_videoram_w); DECLARE_READ8_MEMBER(pio_system_r); DECLARE_WRITE8_MEMBER(kayproii_pio_system_w); - DECLARE_WRITE8_MEMBER(kaypro4_pio_system_w); + DECLARE_WRITE8_MEMBER(kayproiv_pio_system_w); DECLARE_WRITE_LINE_MEMBER(fdc_intrq_w); DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); DECLARE_READ8_MEMBER(kaypro_videoram_r); @@ -58,12 +58,10 @@ public: DECLARE_VIDEO_START(kaypro); DECLARE_PALETTE_INIT(kaypro); DECLARE_DRIVER_INIT(kaypro); - DECLARE_FLOPPY_FORMATS(kayproii_floppy_formats); - DECLARE_FLOPPY_FORMATS(kaypro2x_floppy_formats); uint32_t screen_update_kayproii(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_kaypro2x(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + uint32_t screen_update_kaypro484(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); uint32_t screen_update_omni2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - MC6845_UPDATE_ROW(kaypro2x_update_row); + MC6845_UPDATE_ROW(kaypro484_update_row); DECLARE_QUICKLOAD_LOAD_MEMBER(kaypro); private: diff --git a/src/mame/includes/kyugo.h b/src/mame/includes/kyugo.h index dde5e87745e..b5ccabe8848 100644 --- a/src/mame/includes/kyugo.h +++ b/src/mame/includes/kyugo.h @@ -22,6 +22,28 @@ public: m_gfxdecode(*this, "gfxdecode"), m_palette(*this, "palette") { } + DECLARE_WRITE_LINE_MEMBER(nmi_mask_w); + DECLARE_WRITE8_MEMBER(coin_counter_w); + DECLARE_WRITE8_MEMBER(fgvideoram_w); + DECLARE_WRITE8_MEMBER(bgvideoram_w); + DECLARE_WRITE8_MEMBER(bgattribram_w); + DECLARE_READ8_MEMBER(spriteram_2_r); + DECLARE_WRITE8_MEMBER(scroll_x_lo_w); + DECLARE_WRITE8_MEMBER(gfxctrl_w); + DECLARE_WRITE8_MEMBER(scroll_y_w); + DECLARE_WRITE_LINE_MEMBER(flipscreen_w); + + DECLARE_DRIVER_INIT(srdmissn); + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + INTERRUPT_GEN_MEMBER(vblank_irq); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + +private: /* memory pointers */ required_shared_ptr<uint8_t> m_fgvideoram; required_shared_ptr<uint8_t> m_bgvideoram; @@ -30,6 +52,8 @@ public: required_shared_ptr<uint8_t> m_spriteram_2; required_shared_ptr<uint8_t> m_shared_ram; + uint8_t m_nmi_mask; + /* video-related */ tilemap_t *m_bg_tilemap; tilemap_t *m_fg_tilemap; @@ -46,24 +70,7 @@ public: required_device<gfxdecode_device> m_gfxdecode; required_device<palette_device> m_palette; - uint8_t m_nmi_mask; - DECLARE_WRITE_LINE_MEMBER(nmi_mask_w); - DECLARE_WRITE8_MEMBER(kyugo_coin_counter_w); - DECLARE_WRITE8_MEMBER(kyugo_fgvideoram_w); - DECLARE_WRITE8_MEMBER(kyugo_bgvideoram_w); - DECLARE_WRITE8_MEMBER(kyugo_bgattribram_w); - DECLARE_READ8_MEMBER(kyugo_spriteram_2_r); - DECLARE_WRITE8_MEMBER(kyugo_scroll_x_lo_w); - DECLARE_WRITE8_MEMBER(kyugo_gfxctrl_w); - DECLARE_WRITE8_MEMBER(kyugo_scroll_y_w); - DECLARE_WRITE_LINE_MEMBER(flipscreen_w); - DECLARE_DRIVER_INIT(srdmissn); TILE_GET_INFO_MEMBER(get_fg_tile_info); TILE_GET_INFO_MEMBER(get_bg_tile_info); - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - uint32_t screen_update_kyugo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(vblank_irq); - void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); }; diff --git a/src/mame/includes/m10.h b/src/mame/includes/m10.h index f7b9ec43733..401af2150be 100644 --- a/src/mame/includes/m10.h +++ b/src/mame/includes/m10.h @@ -111,8 +111,8 @@ public: uint32_t screen_update_m15(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(m15_interrupt); TIMER_CALLBACK_MEMBER(interrupt_callback); - DECLARE_WRITE8_MEMBER(ic8j1_output_changed); - DECLARE_WRITE8_MEMBER(ic8j2_output_changed); + DECLARE_WRITE_LINE_MEMBER(ic8j1_output_changed); + DECLARE_WRITE_LINE_MEMBER(ic8j2_output_changed); inline void plot_pixel_m10( bitmap_ind16 &bm, int x, int y, int col ); protected: diff --git a/src/mame/includes/mac.h b/src/mame/includes/mac.h index 67428390589..6c3cb4f9e41 100644 --- a/src/mame/includes/mac.h +++ b/src/mame/includes/mac.h @@ -523,7 +523,7 @@ public: void mac_driver_init(model_t model); void mac_install_memory(offs_t memory_begin, offs_t memory_end, offs_t memory_size, void *memory_data, int is_rom, const char *bank); - offs_t mac_dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options); + offs_t mac_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms); }; #endif /* MAC_H_ */ diff --git a/src/mame/includes/mc80.h b/src/mame/includes/mc80.h deleted file mode 100644 index 0d091897fdf..00000000000 --- a/src/mame/includes/mc80.h +++ /dev/null @@ -1,57 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Miodrag Milanovic -/***************************************************************************** - * - * includes/mc80.h - * - ****************************************************************************/ - -#ifndef MC80_H_ -#define MC80_H_ - -#include "cpu/z80/z80.h" -#include "machine/timer.h" -#include "machine/z80ctc.h" -#include "machine/z80pio.h" -#include "machine/z80dart.h" - -class mc80_state : public driver_device -{ -public: - mc80_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_p_videoram(*this, "videoram"), - m_maincpu(*this, "maincpu") { } - - DECLARE_WRITE8_MEMBER(mc8030_zve_write_protect_w); - DECLARE_WRITE8_MEMBER(mc8030_vis_w); - DECLARE_WRITE8_MEMBER(mc8030_eprom_prog_w); - DECLARE_WRITE_LINE_MEMBER(ctc_z0_w); - DECLARE_WRITE_LINE_MEMBER(ctc_z1_w); - DECLARE_READ8_MEMBER(mc80_port_b_r); - DECLARE_READ8_MEMBER(mc80_port_a_r); - DECLARE_WRITE8_MEMBER(mc80_port_a_w); - DECLARE_WRITE8_MEMBER(mc80_port_b_w); - DECLARE_READ8_MEMBER(zve_port_a_r); - DECLARE_READ8_MEMBER(zve_port_b_r); - DECLARE_WRITE8_MEMBER(zve_port_a_w); - DECLARE_WRITE8_MEMBER(zve_port_b_w); - DECLARE_READ8_MEMBER(asp_port_a_r); - DECLARE_READ8_MEMBER(asp_port_b_r); - DECLARE_WRITE8_MEMBER(asp_port_a_w); - DECLARE_WRITE8_MEMBER(asp_port_b_w); - optional_shared_ptr<uint8_t> m_p_videoram; - DECLARE_MACHINE_RESET(mc8020); - DECLARE_VIDEO_START(mc8020); - DECLARE_MACHINE_RESET(mc8030); - DECLARE_VIDEO_START(mc8030); - uint32_t screen_update_mc8020(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - uint32_t screen_update_mc8030(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_DEVICE_CALLBACK_MEMBER(mc8020_kbd); - DECLARE_WRITE_LINE_MEMBER(ctc_z2_w); - IRQ_CALLBACK_MEMBER(mc8020_irq_callback); - IRQ_CALLBACK_MEMBER(mc8030_irq_callback); - required_device<cpu_device> m_maincpu; -}; - -#endif diff --git a/src/mame/includes/mcr3.h b/src/mame/includes/mcr3.h index 70b349a53f5..573236b843e 100644 --- a/src/mame/includes/mcr3.h +++ b/src/mame/includes/mcr3.h @@ -5,6 +5,8 @@ Midway MCR-3 system **************************************************************************/ + +#include "machine/adc0844.h" #include "screen.h" class mcr3_state : public mcr_state @@ -13,17 +15,18 @@ public: mcr3_state(const machine_config &mconfig, device_type type, const char *tag) : mcr_state(mconfig, type, tag), m_spyhunt_alpharam(*this, "spyhunt_alpha"), + m_maxrpm_adc(*this, "adc"), m_screen(*this, "screen") { } optional_shared_ptr<uint8_t> m_spyhunt_alpharam; + optional_device<adc0844_device> m_maxrpm_adc; required_device<screen_device> m_screen; uint8_t m_input_mux; uint8_t m_latched_input; uint8_t m_last_op4; uint8_t m_maxrpm_adc_control; - uint8_t m_maxrpm_adc_select; uint8_t m_maxrpm_last_shift; int8_t m_maxrpm_p1_shift; int8_t m_maxrpm_p2_shift; diff --git a/src/mame/includes/mcr68.h b/src/mame/includes/mcr68.h index 23968284654..8dbdf8044d8 100644 --- a/src/mame/includes/mcr68.h +++ b/src/mame/includes/mcr68.h @@ -11,6 +11,7 @@ #include "audio/midway.h" #include "audio/williams.h" #include "machine/6840ptm.h" +#include "machine/adc0844.h" #include "screen.h" class mcr68_state : public driver_device @@ -21,6 +22,7 @@ public: m_sounds_good(*this, "sg"), m_turbo_cheap_squeak(*this, "tcs"), m_cvsd_sound(*this, "cvsd"), + m_adc(*this, "adc"), m_videoram(*this, "videoram"), m_spriteram(*this, "spriteram") , m_maincpu(*this, "maincpu"), @@ -32,6 +34,7 @@ public: optional_device<midway_sounds_good_device> m_sounds_good; optional_device<midway_turbo_cheap_squeak_device> m_turbo_cheap_squeak; optional_device<williams_cvsd_sound_device> m_cvsd_sound; + optional_device<adc0844_device> m_adc; required_shared_ptr<uint16_t> m_videoram; required_shared_ptr<uint16_t> m_spriteram; diff --git a/src/mame/includes/metro.h b/src/mame/includes/metro.h index 256ed80fb97..01cd5f82d81 100644 --- a/src/mame/includes/metro.h +++ b/src/mame/includes/metro.h @@ -10,8 +10,10 @@ #include "sound/ym2151.h" #include "sound/es8712.h" #include "video/k053936.h" +#include "video/imagetek_i4100.h" #include "machine/eepromser.h" #include "machine/gen_latch.h" +#include "machine/timer.h" #include "screen.h" class metro_state : public driver_device @@ -20,8 +22,7 @@ public: enum { TIMER_KARATOUR_IRQ, - TIMER_MOUJA_IRQ, - TIMER_METRO_BLIT_DONE + TIMER_MOUJA_IRQ }; metro_state(const machine_config &mconfig, device_type type, const char *tag) @@ -31,97 +32,21 @@ public: m_oki(*this, "oki"), m_ymsnd(*this, "ymsnd"), m_essnd(*this, "essnd"), + m_vdp(*this, "vdp"), + m_vdp2(*this, "vdp2"), + m_vdp3(*this, "vdp3"), m_k053936(*this, "k053936") , m_eeprom(*this, "eeprom"), m_gfxdecode(*this, "gfxdecode"), m_screen(*this, "screen"), - m_palette(*this, "palette"), m_soundlatch(*this, "soundlatch"), - m_vram_0(*this, "vram_0"), - m_vram_1(*this, "vram_1"), - m_vram_2(*this, "vram_2"), - m_spriteram(*this, "spriteram"), - m_tiletable(*this, "tiletable"), - m_blitter_regs(*this, "blitter_regs"), - m_scroll(*this, "scroll"), - m_window(*this, "window"), m_irq_enable(*this, "irq_enable"), m_irq_levels(*this, "irq_levels"), m_irq_vectors(*this, "irq_vectors"), - m_rombank(*this, "rombank"), - m_videoregs(*this, "videoregs"), - m_screenctrl(*this, "screenctrl"), m_input_sel(*this, "input_sel"), m_k053936_ram(*this, "k053936_ram") { } - /* devices */ - required_device<cpu_device> m_maincpu; - optional_device<cpu_device> m_audiocpu; - optional_device<okim6295_device> m_oki; - optional_device<device_t> m_ymsnd; // TODO set correct type - optional_device<es8712_device> m_essnd; - optional_device<k053936_device> m_k053936; - optional_device<eeprom_serial_93cxx_device> m_eeprom; - required_device<gfxdecode_device> m_gfxdecode; - required_device<screen_device> m_screen; - required_device<palette_device> m_palette; - optional_device<generic_latch_8_device> m_soundlatch; - - /* memory pointers */ - optional_shared_ptr<uint16_t> m_vram_0; - optional_shared_ptr<uint16_t> m_vram_1; - optional_shared_ptr<uint16_t> m_vram_2; - required_shared_ptr<uint16_t> m_spriteram; - optional_shared_ptr<uint16_t> m_tiletable; - optional_shared_ptr<uint16_t> m_blitter_regs; - optional_shared_ptr<uint16_t> m_scroll; - optional_shared_ptr<uint16_t> m_window; - optional_shared_ptr<uint16_t> m_irq_enable; - optional_shared_ptr<uint16_t> m_irq_levels; - optional_shared_ptr<uint16_t> m_irq_vectors; - optional_shared_ptr<uint16_t> m_rombank; - required_shared_ptr<uint16_t> m_videoregs; - optional_shared_ptr<uint16_t> m_screenctrl; - optional_shared_ptr<uint16_t> m_input_sel; - optional_shared_ptr<uint16_t> m_k053936_ram; - - int m_flip_screen; - - /* video-related */ - tilemap_t *m_k053936_tilemap; - int m_tilemap_scrolldx[3]; - - int m_support_8bpp; - int m_support_16x16; - int m_has_zoom; - int m_sprite_xoffs; - int m_sprite_yoffs; - int m_sprite_xoffs_dx; - emu_timer *m_blit_done_timer; - - std::unique_ptr<uint8_t[]> m_expanded_gfx1; - - /* irq_related */ - int m_vblank_bit; - int m_blitter_bit; - int m_irq_line; - uint8_t m_requested_int[8]; - emu_timer *m_mouja_irq_timer; - emu_timer *m_karatour_irq_timer; - - /* sound related */ - uint16_t m_soundstatus; - int m_porta; - int m_portb; - int m_busy_sndcpu; - bool m_essnd_gate; - - /* misc */ - int m_gakusai_oki_bank_lo; - int m_gakusai_oki_bank_hi; - - DECLARE_READ16_MEMBER(metro_irq_cause_r); DECLARE_WRITE16_MEMBER(metro_irq_cause_w); DECLARE_WRITE16_MEMBER(mouja_irq_timer_ctrl_w); @@ -136,39 +61,23 @@ public: DECLARE_WRITE8_MEMBER(daitorid_portb_w); DECLARE_WRITE16_MEMBER(metro_coin_lockout_1word_w); DECLARE_WRITE16_MEMBER(metro_coin_lockout_4words_w); - DECLARE_READ16_MEMBER(metro_bankedrom_r); - DECLARE_WRITE16_MEMBER(metro_blitter_w); DECLARE_READ16_MEMBER(balcube_dsw_r); - DECLARE_READ16_MEMBER(karatour_vram_0_r); - DECLARE_READ16_MEMBER(karatour_vram_1_r); - DECLARE_READ16_MEMBER(karatour_vram_2_r); - DECLARE_WRITE16_MEMBER(karatour_vram_0_w); - DECLARE_WRITE16_MEMBER(karatour_vram_1_w); - DECLARE_WRITE16_MEMBER(karatour_vram_2_w); DECLARE_READ16_MEMBER(gakusai_input_r); DECLARE_WRITE16_MEMBER(blzntrnd_sound_w); DECLARE_WRITE8_MEMBER(blzntrnd_sh_bankswitch_w); DECLARE_WRITE16_MEMBER(puzzlet_irq_enable_w); - DECLARE_WRITE16_MEMBER(vram_0_clr_w); - DECLARE_WRITE16_MEMBER(vram_1_clr_w); - DECLARE_WRITE16_MEMBER(vram_2_clr_w); DECLARE_WRITE16_MEMBER(puzzlet_portb_w); DECLARE_WRITE16_MEMBER(metro_k053936_w); - DECLARE_WRITE16_MEMBER(metro_vram_0_w); - DECLARE_WRITE16_MEMBER(metro_vram_1_w); - DECLARE_WRITE16_MEMBER(metro_vram_2_w); - DECLARE_WRITE16_MEMBER(metro_window_w); - void blt_write( address_space &space, const int tmap, const offs_t offs, const uint16_t data, const uint16_t mask ); DECLARE_CUSTOM_INPUT_MEMBER(custom_soundstatus_r); - DECLARE_WRITE16_MEMBER(gakusai_oki_bank_hi_w); - DECLARE_WRITE16_MEMBER(gakusai_oki_bank_lo_w); - DECLARE_READ16_MEMBER(gakusai_eeprom_r); - DECLARE_WRITE16_MEMBER(gakusai_eeprom_w); - DECLARE_READ16_MEMBER(dokyusp_eeprom_r); - DECLARE_WRITE16_MEMBER(dokyusp_eeprom_bit_w); - DECLARE_WRITE16_MEMBER(dokyusp_eeprom_reset_w); + DECLARE_WRITE8_MEMBER(gakusai_oki_bank_hi_w); + DECLARE_WRITE8_MEMBER(gakusai_oki_bank_lo_w); + DECLARE_READ8_MEMBER(gakusai_eeprom_r); + DECLARE_WRITE8_MEMBER(gakusai_eeprom_w); + DECLARE_READ8_MEMBER(dokyusp_eeprom_r); + DECLARE_WRITE8_MEMBER(dokyusp_eeprom_bit_w); + DECLARE_WRITE8_MEMBER(dokyusp_eeprom_reset_w); DECLARE_WRITE8_MEMBER(mouja_sound_rombank_w); - void gakusai_oki_bank_set(); + DECLARE_WRITE_LINE_MEMBER(vdp_blit_end_w); // vmetal DECLARE_WRITE8_MEMBER(vmetal_control_w); @@ -189,33 +98,71 @@ public: TILE_GET_INFO_MEMBER(metro_k053936_get_tile_info); TILE_GET_INFO_MEMBER(metro_k053936_gstrik2_get_tile_info); TILEMAP_MAPPER_MEMBER(tilemap_scan_gstrik2); - void expand_gfx1(); - DECLARE_VIDEO_START(metro_i4100); - DECLARE_VIDEO_START(metro_i4220); - DECLARE_VIDEO_START(metro_i4220_dx_tmap); - DECLARE_VIDEO_START(metro_i4220_dx_sprite); - DECLARE_VIDEO_START(metro_i4300); DECLARE_VIDEO_START(blzntrnd); DECLARE_VIDEO_START(gstrik2); - uint32_t screen_update_metro(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + uint32_t screen_update_psac_vdp2_mix(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); INTERRUPT_GEN_MEMBER(metro_vblank_interrupt); INTERRUPT_GEN_MEMBER(metro_periodic_interrupt); + TIMER_DEVICE_CALLBACK_MEMBER(bangball_scanline); INTERRUPT_GEN_MEMBER(karatour_interrupt); INTERRUPT_GEN_MEMBER(puzzlet_interrupt); - TIMER_CALLBACK_MEMBER(metro_blit_done); - void update_irq_state(); IRQ_CALLBACK_MEMBER(metro_irq_callback); - inline uint8_t get_tile_pix( uint16_t code, uint8_t x, uint8_t y, int big, uint16_t *pix ); - inline void metro_vram_w( offs_t offset, uint16_t data, uint16_t mem_mask, int layer, uint16_t *vram ); - void metro_draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ); - void draw_layers( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, int layers_ctrl ); - inline int blt_read( const uint8_t *ROM, const int offs ); - void metro_common( ); - void draw_tilemap( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint32_t flags, uint32_t pcode, - int sx, int sy, int wx, int wy, int big, uint16_t *tilemapram, int layer ); DECLARE_READ_LINE_MEMBER(metro_rxd_r); protected: virtual void machine_start() override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +private: + /* devices */ + required_device<cpu_device> m_maincpu; + optional_device<cpu_device> m_audiocpu; + optional_device<okim6295_device> m_oki; + optional_device<device_t> m_ymsnd; // TODO set correct type + optional_device<es8712_device> m_essnd; + optional_device<imagetek_i4100_device> m_vdp; + optional_device<imagetek_i4220_device> m_vdp2; + optional_device<imagetek_i4300_device> m_vdp3; + + optional_device<k053936_device> m_k053936; + optional_device<eeprom_serial_93cxx_device> m_eeprom; + required_device<gfxdecode_device> m_gfxdecode; + required_device<screen_device> m_screen; + optional_device<generic_latch_8_device> m_soundlatch; + + /* memory pointers */ + optional_shared_ptr<uint16_t> m_irq_enable; + optional_shared_ptr<uint16_t> m_irq_levels; + optional_shared_ptr<uint16_t> m_irq_vectors; + optional_shared_ptr<uint16_t> m_input_sel; + optional_shared_ptr<uint16_t> m_k053936_ram; + + /* video-related */ + tilemap_t *m_k053936_tilemap; + + /* irq_related */ + int m_vblank_bit; + int m_blitter_bit; + int m_irq_line; + uint8_t m_requested_int[8]; + emu_timer *m_mouja_irq_timer; + emu_timer *m_karatour_irq_timer; + + /* sound related */ + uint16_t m_soundstatus; + int m_porta; + int m_portb; + int m_busy_sndcpu; + bool m_essnd_gate; + + /* misc */ + int m_gakusai_oki_bank_lo; + int m_gakusai_oki_bank_hi; + + void update_irq_state(); + void metro_common(); + void gakusai_oki_bank_set(); + + // blazing tornado + bitmap_ind16 m_vdp_bitmap; }; diff --git a/src/mame/includes/micro3d.h b/src/mame/includes/micro3d.h index eeb57b3dbcf..528e4b91218 100644 --- a/src/mame/includes/micro3d.h +++ b/src/mame/includes/micro3d.h @@ -13,6 +13,7 @@ #include "cpu/tms34010/tms34010.h" #include "cpu/mcs51/mcs51.h" #include "sound/upd7759.h" +#include "machine/mc2661.h" #include "machine/mc68681.h" @@ -43,8 +44,7 @@ class micro3d_state : public driver_device public: enum { - TIMER_MAC_DONE, - TIMER_ADC_DONE + TIMER_MAC_DONE }; micro3d_state(const machine_config &mconfig, device_type type, const char *tag) @@ -55,7 +55,7 @@ public: m_drmath(*this, "drmath"), m_vgb(*this, "vgb"), m_palette(*this, "palette"), - m_duart68681(*this, "duart68681"), + m_duart(*this, "duart"), m_noise_1(*this, "noise_1"), m_noise_2(*this, "noise_2"), m_vertex(*this, "vertex"), @@ -63,10 +63,11 @@ public: m_volume(*this, "VOLUME"), m_joystick_x(*this, "JOYSTICK_X"), m_joystick_y(*this, "JOYSTICK_Y"), - m_throttle(*this, "THROTTLE"), m_shared_ram(*this, "shared_ram"), m_mac_sram(*this, "mac_sram"), - m_sprite_vram(*this, "sprite_vram") { } + m_sprite_vram(*this, "sprite_vram"), + m_vgb_uart(*this, "uart") + { } required_device<cpu_device> m_maincpu; required_device<i8051_device> m_audiocpu; @@ -74,7 +75,7 @@ public: required_device<cpu_device> m_drmath; required_device<tms34010_device> m_vgb; required_device<palette_device> m_palette; - required_device<mc68681_device> m_duart68681; + required_device<mc68681_device> m_duart; required_device<micro3d_sound_device> m_noise_1; required_device<micro3d_sound_device> m_noise_2; required_memory_region m_vertex; @@ -83,7 +84,6 @@ public: required_ioport m_volume; optional_ioport m_joystick_x; optional_ioport m_joystick_y; - optional_ioport m_throttle; required_shared_ptr<uint16_t> m_shared_ram; uint8_t m_m68681_tx0; @@ -91,14 +91,6 @@ public: /* Sound */ uint8_t m_sound_port_latch[4]; - /* TI UART */ - uint8_t m_ti_uart[9]; - int m_ti_uart_mode_cycle; - int m_ti_uart_sync_cycle; - - /* ADC */ - uint8_t m_adc_val; - /* Hardware version-check latch for BOTSS 1.1a */ uint8_t m_botss_latch; @@ -138,17 +130,14 @@ public: int m_drawing_buffer; int m_display_buffer; - DECLARE_WRITE16_MEMBER(micro3d_ti_uart_w); - DECLARE_READ16_MEMBER(micro3d_ti_uart_r); - DECLARE_WRITE32_MEMBER(micro3d_scc_w); - DECLARE_READ32_MEMBER(micro3d_scc_r); + DECLARE_WRITE8_MEMBER(vgb_uart_w); + DECLARE_READ8_MEMBER(vgb_uart_r); DECLARE_WRITE32_MEMBER(micro3d_mac1_w); DECLARE_READ32_MEMBER(micro3d_mac2_r); DECLARE_WRITE32_MEMBER(micro3d_mac2_w); DECLARE_READ16_MEMBER(micro3d_encoder_h_r); DECLARE_READ16_MEMBER(micro3d_encoder_l_r); - DECLARE_READ16_MEMBER(micro3d_adc_r); - DECLARE_WRITE16_MEMBER(micro3d_adc_w); + DECLARE_READ8_MEMBER(adc_volume_r); DECLARE_READ16_MEMBER(botss_140000_r); DECLARE_READ16_MEMBER(botss_180000_r); DECLARE_WRITE16_MEMBER(micro3d_reset_w); @@ -174,7 +163,6 @@ public: virtual void video_reset() override; INTERRUPT_GEN_MEMBER(micro3d_vblank); TIMER_CALLBACK_MEMBER(mac_done_callback); - TIMER_CALLBACK_MEMBER(adc_done_callback); DECLARE_WRITE8_MEMBER(micro3d_upd7759_w); DECLARE_WRITE8_MEMBER(data_from_i8031); DECLARE_READ8_MEMBER(data_to_i8031); @@ -197,6 +185,9 @@ public: protected: virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +private: + required_device<mc2661_device> m_vgb_uart; }; #endif // MAME_INCLUDES_MICRO3D_H diff --git a/src/mame/includes/midvunit.h b/src/mame/includes/midvunit.h index 7401afc1b07..d5afdf11a97 100644 --- a/src/mame/includes/midvunit.h +++ b/src/mame/includes/midvunit.h @@ -11,6 +11,7 @@ #include "machine/midwayic.h" #include "machine/timer.h" #include "machine/watchdog.h" +#include "machine/adc0844.h" #include "screen.h" #define MIDVUNIT_VIDEO_CLOCK 33000000 @@ -46,7 +47,6 @@ class midvunit_state : public driver_device public: enum { - TIMER_ADC_READY, TIMER_SCANLINE }; @@ -59,11 +59,11 @@ public: m_midvplus_misc(*this, "midvplus_misc"), m_videoram(*this, "videoram", 32), m_textureram(*this, "textureram") , - m_adc_ports(*this, {"WHEEL", "ACCEL", "BRAKE"}), m_maincpu(*this, "maincpu"), m_watchdog(*this, "watchdog"), m_screen(*this, "screen"), m_palette(*this, "palette"), + m_adc(*this, "adc"), m_midway_serial_pic(*this, "serial_pic"), m_midway_serial_pic2(*this, "serial_pic2"), m_midway_ioasic(*this, "ioasic"), @@ -78,11 +78,8 @@ public: required_shared_ptr<uint16_t> m_videoram; required_shared_ptr<uint32_t> m_textureram; - optional_ioport_array<3> m_adc_ports; - uint8_t m_cmos_protected; uint16_t m_control_data; - uint8_t m_adc_data; uint8_t m_adc_shift; uint16_t m_last_port0; uint8_t m_shifter_state; @@ -97,7 +94,6 @@ public: uint16_t m_page_control; uint8_t m_video_changed; emu_timer *m_scanline_timer; - emu_timer *m_adc_ready_timer; std::unique_ptr<midvunit_renderer> m_poly; uint8_t m_galil_input_index; uint8_t m_galil_input_length; @@ -120,8 +116,8 @@ public: DECLARE_WRITE32_MEMBER(midvunit_textureram_w); DECLARE_READ32_MEMBER(midvunit_textureram_r); DECLARE_READ32_MEMBER(port0_r); - DECLARE_READ32_MEMBER(midvunit_adc_r); - DECLARE_WRITE32_MEMBER(midvunit_adc_w); + DECLARE_READ32_MEMBER(adc_r); + DECLARE_WRITE32_MEMBER(adc_w); DECLARE_WRITE32_MEMBER(midvunit_cmos_protect_w); DECLARE_WRITE32_MEMBER(midvunit_cmos_w); DECLARE_READ32_MEMBER(midvunit_cmos_r); @@ -163,6 +159,7 @@ public: required_device<watchdog_timer_device> m_watchdog; required_device<screen_device> m_screen; required_device<palette_device> m_palette; + optional_device<adc0844_device> m_adc; optional_device<midway_serial_pic_device> m_midway_serial_pic; optional_device<midway_serial_pic2_device> m_midway_serial_pic2; optional_device<midway_ioasic_device> m_midway_ioasic; diff --git a/src/mame/includes/midxunit.h b/src/mame/includes/midxunit.h index d42f9e38683..07e3142c2a6 100644 --- a/src/mame/includes/midxunit.h +++ b/src/mame/includes/midxunit.h @@ -16,21 +16,11 @@ public: m_nvram(*this, "nvram"), m_midway_serial_pic(*this, "serial_pic") { } - required_shared_ptr<uint16_t> m_nvram; - required_device<midway_serial_pic_device> m_midway_serial_pic; - uint8_t m_cmos_write_enable; - uint16_t m_iodata[8]; - uint8_t m_ioshuffle[16]; - uint8_t m_analog_port; - uint8_t m_uart[8]; - uint8_t m_security_bits; DECLARE_READ16_MEMBER(midxunit_cmos_r); DECLARE_WRITE16_MEMBER(midxunit_cmos_w); DECLARE_WRITE16_MEMBER(midxunit_io_w); DECLARE_WRITE16_MEMBER(midxunit_unknown_w); - DECLARE_READ16_MEMBER(midxunit_io_r); - DECLARE_READ16_MEMBER(midxunit_analog_r); - DECLARE_WRITE16_MEMBER(midxunit_analog_select_w); + DECLARE_WRITE_LINE_MEMBER(adc_int_w); DECLARE_READ16_MEMBER(midxunit_status_r); DECLARE_READ16_MEMBER(midxunit_uart_r); DECLARE_WRITE16_MEMBER(midxunit_uart_w); @@ -46,4 +36,14 @@ public: DECLARE_VIDEO_START(midxunit); void register_state_saving(); TMS340X0_SCANLINE_IND16_CB_MEMBER(scanline_update); + +private: + required_shared_ptr<uint16_t> m_nvram; + required_device<midway_serial_pic_device> m_midway_serial_pic; + uint8_t m_cmos_write_enable; + uint16_t m_iodata[8]; + uint8_t m_ioshuffle[16]; + uint8_t m_uart[8]; + uint8_t m_security_bits; + bool m_adc_int; }; diff --git a/src/mame/includes/midyunit.h b/src/mame/includes/midyunit.h index e062f9b2fbe..ce4620cbcea 100644 --- a/src/mame/includes/midyunit.h +++ b/src/mame/includes/midyunit.h @@ -10,7 +10,7 @@ #include "audio/williams.h" #include "cpu/tms34010/tms34010.h" -#include "machine/gen_latch.h" +#include "machine/adc0844.h" #include "machine/gen_latch.h" #include "machine/nvram.h" #include "sound/okim6295.h" @@ -54,6 +54,7 @@ public: , m_cvsd_sound(*this, "cvsd") , m_adpcm_sound(*this, "adpcm") , m_soundlatch(*this, "soundlatch") + , m_term2_adc(*this, "adc") , m_generic_paletteram_16(*this, "paletteram") , m_gfx_rom(*this, "gfx_rom", 16) , m_mainram(*this, "mainram") @@ -70,6 +71,7 @@ public: optional_device<williams_cvsd_sound_device> m_cvsd_sound; optional_device<williams_adpcm_sound_device> m_adpcm_sound; optional_device<generic_latch_8_device> m_soundlatch; + optional_device<adc0844_device> m_term2_adc; required_shared_ptr<uint16_t> m_generic_paletteram_16; optional_shared_ptr<uint8_t> m_gfx_rom; @@ -81,7 +83,6 @@ public: uint16_t m_prot_result; uint16_t m_prot_sequence[3]; uint8_t m_prot_index; - uint8_t m_term2_analog_select; const struct protection_data *m_prot_data; uint8_t m_cmos_w_enable; uint8_t m_chip_type; diff --git a/src/mame/includes/model2.h b/src/mame/includes/model2.h index 560af94e7b5..7909a99dd5c 100644 --- a/src/mame/includes/model2.h +++ b/src/mame/includes/model2.h @@ -50,9 +50,12 @@ public: m_scsp(*this, "scsp"), m_cryptdevice(*this, "315_5881"), m_0229crypt(*this, "317_0229"), - m_in0(*this, "IN0"), + m_in(*this, "IN%u", 0), + m_steer(*this, "STEER"), + m_accel(*this, "ACCEL"), + m_brake(*this, "BRAKE"), m_gears(*this, "GEARS"), - m_analog_ports(*this, {"ANA0", "ANA1", "ANA2", "ANA3"}), + m_analog_ports(*this, "ANA%u", 0), m_lightgun_ports(*this, {"P1_Y", "P1_X", "P2_Y", "P2_X"}) { } @@ -86,11 +89,20 @@ public: optional_device<sega_315_5881_crypt_device> m_cryptdevice; optional_device<sega_315_5838_comp_device> m_0229crypt; - required_ioport m_in0; + optional_ioport_array<5> m_in; + optional_ioport m_steer; + optional_ioport m_accel; + optional_ioport m_brake; optional_ioport m_gears; optional_ioport_array<4> m_analog_ports; optional_ioport_array<4> m_lightgun_ports; + int m_port_1c00004; + int m_port_1c00006; + int m_port_1c00010; + int m_port_1c00012; + int m_port_1c00014; + uint32_t m_intreq; uint32_t m_intena; uint32_t m_coproctl; @@ -134,8 +146,7 @@ public: uint8_t m_gearsel; uint8_t m_lightgun_mux; - DECLARE_CUSTOM_INPUT_MEMBER(_1c00000_r); - DECLARE_CUSTOM_INPUT_MEMBER(_1c0001c_r); + DECLARE_READ8_MEMBER(model2_crx_in_r); DECLARE_CUSTOM_INPUT_MEMBER(srallyc_gearbox_r); DECLARE_CUSTOM_INPUT_MEMBER(rchase2_devices_r); DECLARE_READ32_MEMBER(timers_r); @@ -146,6 +157,7 @@ public: DECLARE_WRITE32_MEMBER(analog_2b_w); DECLARE_READ32_MEMBER(fifoctl_r); DECLARE_READ32_MEMBER(model2o_fifoctrl_r); + DECLARE_READ8_MEMBER(model2o_in_r); DECLARE_READ32_MEMBER(videoctl_r); DECLARE_WRITE32_MEMBER(videoctl_w); DECLARE_WRITE32_MEMBER(rchase2_devices_w); @@ -163,7 +175,7 @@ public: DECLARE_WRITE32_MEMBER(geo_prg_w); DECLARE_READ32_MEMBER(geo_r); DECLARE_WRITE32_MEMBER(geo_w); - DECLARE_READ32_MEMBER(hotd_lightgun_r); + DECLARE_READ8_MEMBER(hotd_lightgun_r); DECLARE_WRITE32_MEMBER(hotd_lightgun_w); DECLARE_READ32_MEMBER(daytona_unk_r); DECLARE_READ32_MEMBER(model2_irq_r); @@ -209,6 +221,7 @@ public: DECLARE_DRIVER_INIT(zerogun); DECLARE_DRIVER_INIT(sgt24h); DECLARE_MACHINE_START(model2); + DECLARE_MACHINE_START(srallyc); DECLARE_MACHINE_RESET(model2o); DECLARE_VIDEO_START(model2); DECLARE_MACHINE_RESET(model2); diff --git a/src/mame/includes/mtx.h b/src/mame/includes/mtx.h index f52d468e3cd..73e0c3e5481 100644 --- a/src/mame/includes/mtx.h +++ b/src/mame/includes/mtx.h @@ -12,6 +12,8 @@ #include "imagedev/snapquik.h" #include "imagedev/cassette.h" #include "bus/centronics/ctronics.h" +#include "bus/generic/slot.h" +#include "bus/generic/carts.h" #include "machine/z80dart.h" #include "machine/z80ctc.h" #include "sound/sn76496.h" @@ -32,14 +34,16 @@ class mtx_state : public driver_device { public: mtx_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag), - m_maincpu(*this, Z80_TAG), - m_sn(*this, SN76489A_TAG), - m_z80ctc(*this, Z80CTC_TAG), - m_z80dart(*this, Z80DART_TAG), - m_cassette(*this, "cassette"), - m_centronics(*this, CENTRONICS_TAG), - m_ram(*this, RAM_TAG) + : driver_device(mconfig, type, tag) + , m_maincpu(*this, Z80_TAG) + , m_sn(*this, SN76489A_TAG) + , m_z80ctc(*this, Z80CTC_TAG) + , m_z80dart(*this, Z80DART_TAG) + , m_cassette(*this, "cassette") + , m_centronics(*this, CENTRONICS_TAG) + , m_ram(*this, RAM_TAG) + , m_extrom(*this, "extrom") + , m_rompak(*this, "rompak") { } required_device<cpu_device> m_maincpu; @@ -49,6 +53,8 @@ public: required_device<cassette_image_device> m_cassette; required_device<centronics_device> m_centronics; required_device<ram_device> m_ram; + required_device<generic_slot_device> m_extrom; + required_device<generic_slot_device> m_rompak; /* keyboard state */ uint8_t m_key_sense; @@ -68,6 +74,7 @@ public: int m_centronics_perror; int m_centronics_select; + DECLARE_WRITE8_MEMBER(mtx_subpage_w); DECLARE_WRITE8_MEMBER(mtx_bankswitch_w); DECLARE_WRITE8_MEMBER(mtx_sound_latch_w); DECLARE_WRITE8_MEMBER(mtx_sense_w); @@ -88,13 +95,16 @@ public: DECLARE_READ8_MEMBER(mtx_strobe_r); DECLARE_READ8_MEMBER(mtx_sound_strobe_r); DECLARE_WRITE8_MEMBER(mtx_cst_w); + DECLARE_WRITE8_MEMBER(mtx_cst_motor_w); DECLARE_READ8_MEMBER(mtx_prt_r); DECLARE_WRITE_LINE_MEMBER(write_centronics_busy); DECLARE_WRITE_LINE_MEMBER(write_centronics_fault); DECLARE_WRITE_LINE_MEMBER(write_centronics_perror); DECLARE_WRITE_LINE_MEMBER(write_centronics_select); void bankswitch(uint8_t data); - DECLARE_SNAPSHOT_LOAD_MEMBER( mtx ); + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(extrom_load); + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rompak_load); + DECLARE_SNAPSHOT_LOAD_MEMBER(mtx); }; #endif /* __MTX_H__ */ diff --git a/src/mame/includes/nds.h b/src/mame/includes/nds.h index 6f2a2f1d44b..c7b3037ed3e 100644 --- a/src/mame/includes/nds.h +++ b/src/mame/includes/nds.h @@ -1,10 +1,13 @@ // license:BSD-3-Clause -// copyright-holders:Ryan Holtz +// copyright-holders:Ryan Holtz, R. Belmont +#pragma once #ifndef INCLUDES_NDS_H #define INCLUDES_NDS_H #include "cpu/arm7/arm7.h" #include "cpu/arm7/arm7core.h" +#include "machine/bankdev.h" +#include "machine/timer.h" class nds_state : public driver_device { @@ -13,7 +16,10 @@ public: : driver_device(mconfig, type, tag), m_arm7(*this, "arm7"), m_arm9(*this, "arm9"), - m_firmware(*this, "firmware") + m_firmware(*this, "firmware"), + m_arm7wrambnk(*this, "nds7wram"), + m_arm9wrambnk(*this, "nds9wram"), + m_arm7ram(*this, "arm7ram") { } void machine_start() override; @@ -27,22 +33,76 @@ public: DECLARE_READ32_MEMBER(arm9_io_r); DECLARE_WRITE32_MEMBER(arm9_io_w); + DECLARE_READ32_MEMBER(wram_first_half_r); + DECLARE_READ32_MEMBER(wram_second_half_r); + DECLARE_WRITE32_MEMBER(wram_first_half_w); + DECLARE_WRITE32_MEMBER(wram_second_half_w); + DECLARE_READ32_MEMBER(wram_arm7mirror_r); + DECLARE_WRITE32_MEMBER(wram_arm7mirror_w); + protected: required_device<arm7_cpu_device> m_arm7; required_device<arm946es_cpu_device> m_arm9; - required_region_ptr<uint32_t> m_firmware; + required_device<address_map_bank_device> m_arm7wrambnk, m_arm9wrambnk; + required_shared_ptr<uint32_t> m_arm7ram; enum { - POSTFLG_OFFSET = 0x300/4, + TIMER_OFFSET = (0x100/4), + RTC_OFFSET = (0x138/4), + IPCSYNC_OFFSET = (0x180/4), + AUX_SPI_CNT_OFFSET = (0x1a0/4), + GAMECARD_BUS_CTRL_OFFSET = (0x1a4/4), + GAMECARD_DATA_OFFSET = (0x1a8/4), + GAMECARD_DATA_2_OFFSET = (0x1ac/4), + SPI_CTRL_OFFSET = (0x1c0/4), + IME_OFFSET = (0x208/4), + IE_OFFSET = (0x210/4), + IF_OFFSET = (0x214/4), + WRAMSTAT_OFFSET = (0x241/4), + VRAMCNT_A_OFFSET = (0x240/4), + WRAMCNT_OFFSET = (0x244/4), + VRAMCNT_H_OFFSET = (0x248/4), + POSTFLG_OFFSET = (0x300/4), + GAMECARD_DATA_IN_OFFSET = (0x100010/4), POSTFLG_PBF_SHIFT = 0, POSTFLG_RAM_SHIFT = 1, POSTFLG_PBF_MASK = (1 << POSTFLG_PBF_SHIFT), POSTFLG_RAM_MASK = (1 << POSTFLG_RAM_SHIFT), + GAMECARD_DATA_READY = (1 << 23), + GAMECARD_BLOCK_BUSY = (1 << 31) }; uint32_t m_arm7_postflg; uint32_t m_arm9_postflg; + uint32_t m_gamecard_ctrl, m_cartdata_len; + uint32_t m_ime[2], m_ie[2], m_if[2]; + uint16_t m_arm7_ipcsync, m_arm9_ipcsync, m_spicnt; + uint8_t m_WRAM[0x8000]; + uint8_t m_wramcnt; + uint8_t m_vramcnta, m_vramcntb, m_vramcntc, m_vramcntd, m_vramcnte, m_vramcntf, m_vramcntg, m_vramcnth, m_vramcnti; + bool m_arm7halted; + + // DMA + emu_timer *m_dma_timer[8]; + uint32_t m_dma_src[8]; + uint32_t m_dma_dst[8]; + uint16_t m_dma_cnt[8]; + + // Timers + uint32_t m_timer_regs[8]; + uint16_t m_timer_reload[8]; + int m_timer_recalc[8]; + double m_timer_hz[8]; + + emu_timer *m_tmr_timer[8], *m_irq_timer; + + TIMER_CALLBACK_MEMBER(dma_complete); + TIMER_CALLBACK_MEMBER(timer_expire); + TIMER_CALLBACK_MEMBER(handle_irq); + + void request_irq(int which_cpu, uint32_t int_type); + void dma_exec(int ch); }; #endif // INCLUDES_NDS_H diff --git a/src/mame/includes/pacland.h b/src/mame/includes/pacland.h index d71cd094226..4cd4d6302ab 100644 --- a/src/mame/includes/pacland.h +++ b/src/mame/includes/pacland.h @@ -34,6 +34,7 @@ public: tilemap_t *m_bg_tilemap; tilemap_t *m_fg_tilemap; bitmap_ind16 m_fg_bitmap; + bitmap_ind16 m_sprite_bitmap; std::unique_ptr<uint32_t[]> m_transmask[3]; uint16_t m_scroll0; uint16_t m_scroll1; diff --git a/src/mame/includes/pgm2.h b/src/mame/includes/pgm2.h new file mode 100644 index 00000000000..1488486b250 --- /dev/null +++ b/src/mame/includes/pgm2.h @@ -0,0 +1,115 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#ifndef MAME_INCLUDES_PGM2_H +#define MAME_INCLUDES_PGM2_H + +#pragma once + +#include "emu.h" +#include "cpu/arm7/arm7.h" +#include "cpu/arm7/arm7core.h" +#include "sound/ymz770.h" +#include "machine/igs036crypt.h" +#include "screen.h" +#include "speaker.h" +#include "machine/nvram.h" +#include "machine/timer.h" +#include "machine/atmel_arm_aic.h" + +class pgm2_state : public driver_device +{ +public: + pgm2_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag), + m_maincpu(*this, "maincpu"), + m_screen(*this, "screen"), + m_lineram(*this, "lineram"), + m_sp_zoom(*this, "sp_zoom"), + m_mainram(*this, "mainram"), + m_fg_videoram(*this, "fg_videoram"), + m_bg_videoram(*this, "bg_videoram"), + m_sp_videoram(*this, "sp_videoram"), + m_bgscroll(*this, "bgscroll"), + m_gfxdecode2(*this, "gfxdecode2"), + m_gfxdecode3(*this, "gfxdecode3"), + m_arm_aic(*this, "arm_aic"), + m_sprites_mask(*this, "sprites_mask"), + m_sprites_colour(*this, "sprites_colour"), + m_sp_palette(*this, "sp_palette"), + m_bg_palette(*this, "bg_palette"), + m_tx_palette(*this, "tx_palette") + { } + + DECLARE_READ32_MEMBER(unk_startup_r); + DECLARE_READ32_MEMBER(rtc_r); + DECLARE_WRITE32_MEMBER(fg_videoram_w); + DECLARE_WRITE32_MEMBER(bg_videoram_w); + + DECLARE_READ32_MEMBER(orleg2_speedup_r); + DECLARE_READ32_MEMBER(kov2nl_speedup_r); + + DECLARE_DRIVER_INIT(kov2nl); + DECLARE_DRIVER_INIT(orleg2); + DECLARE_DRIVER_INIT(ddpdojh); + DECLARE_DRIVER_INIT(kov3); + DECLARE_DRIVER_INIT(kov3_104); + DECLARE_DRIVER_INIT(kov3_102); + DECLARE_DRIVER_INIT(kov3_100); + DECLARE_DRIVER_INIT(kof98umh); + + uint32_t screen_update_pgm2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + DECLARE_WRITE_LINE_MEMBER(screen_vblank_pgm2); + DECLARE_WRITE_LINE_MEMBER(irq); + + INTERRUPT_GEN_MEMBER(igs_interrupt); + TIMER_DEVICE_CALLBACK_MEMBER(igs_interrupt2); + +private: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + + TILE_GET_INFO_MEMBER(get_fg_tile_info); + TILE_GET_INFO_MEMBER(get_bg_tile_info); + + void decrypt_kov3_module(uint32_t addrxor, uint16_t dataxor); + + tilemap_t *m_fg_tilemap; + tilemap_t *m_bg_tilemap; + + std::unique_ptr<uint32_t[]> m_spritebufferram; // buffered spriteram + + bitmap_ind16 m_sprite_bitmap; + + void skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int reverse); + void draw_sprite_pixel(const rectangle &cliprect, int palette_offset, int realx, int realy, int pal); + void draw_sprite_chunk(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw, int realdraw_inc, int palette_inc); + void draw_sprite_line(const rectangle &cliprect, int &mask_offset, int &palette_offset, int x, int realy, int flipx, int reverse, int sizex, int pal, int zoomybit, int zoomx_bits, int growx); + void draw_sprites(screen_device &screen, const rectangle &cliprect, uint32_t* spriteram); + void copy_sprites_from_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri); + + uint32_t m_sprites_mask_mask; + uint32_t m_sprites_colour_mask; + + // devices + required_device<cpu_device> m_maincpu; + required_device<screen_device> m_screen; + required_shared_ptr<uint32_t> m_lineram; + required_shared_ptr<uint32_t> m_sp_zoom; + required_shared_ptr<uint32_t> m_mainram; + required_shared_ptr<uint32_t> m_fg_videoram; + required_shared_ptr<uint32_t> m_bg_videoram; + required_shared_ptr<uint32_t> m_sp_videoram; + required_shared_ptr<uint32_t> m_bgscroll; + required_device<gfxdecode_device> m_gfxdecode2; + required_device<gfxdecode_device> m_gfxdecode3; + required_device<arm_aic_device> m_arm_aic; + required_region_ptr<uint8_t> m_sprites_mask; + required_region_ptr<uint8_t> m_sprites_colour; + required_device<palette_device> m_sp_palette; + required_device<palette_device> m_bg_palette; + required_device<palette_device> m_tx_palette; +}; + +#endif diff --git a/src/mame/includes/scramble.h b/src/mame/includes/scramble.h index 50ebe4a204c..a4b5ae5a369 100644 --- a/src/mame/includes/scramble.h +++ b/src/mame/includes/scramble.h @@ -30,16 +30,6 @@ public: optional_device<digitalker_device> m_digitalker; required_device<generic_latch_8_device> m_soundlatch; - uint8_t m_cavelon_bank; - - // harem - uint8_t m_harem_decrypt_mode; - uint8_t m_harem_decrypt_bit; - uint8_t m_harem_decrypt_clk; - uint8_t m_harem_decrypt_count; - std::unique_ptr<uint8_t[]> m_harem_decrypted_data; - std::unique_ptr<uint8_t[]> m_harem_decrypted_opcodes; - DECLARE_CUSTOM_INPUT_MEMBER(darkplnt_custom_r); DECLARE_CUSTOM_INPUT_MEMBER(ckongs_coinage_r); DECLARE_READ8_MEMBER(hncholms_prot_r); @@ -66,7 +56,6 @@ public: DECLARE_DRIVER_INIT(cavelon); DECLARE_DRIVER_INIT(mariner); - DECLARE_DRIVER_INIT(mrkougb); DECLARE_DRIVER_INIT(scramble_ppi); DECLARE_DRIVER_INIT(mars); DECLARE_DRIVER_INIT(ckongs); @@ -92,8 +81,6 @@ public: DECLARE_MACHINE_RESET(scramble); DECLARE_MACHINE_RESET(explorer); DECLARE_WRITE_LINE_MEMBER(scramble_sh_7474_q_callback); - void cavelon_banksw(); - inline int bit(int i,int n); DECLARE_READ8_MEMBER( mariner_protection_1_r ); DECLARE_READ8_MEMBER( mariner_protection_2_r ); DECLARE_READ8_MEMBER( triplep_pip_r ); @@ -102,12 +89,26 @@ public: DECLARE_WRITE8_MEMBER( cavelon_banksw_w ); DECLARE_READ8_MEMBER( hunchbks_mirror_r ); DECLARE_WRITE8_MEMBER( hunchbks_mirror_w ); - void sh_init(); DECLARE_WRITE8_MEMBER( scramble_sh_irqtrigger_w ); DECLARE_WRITE8_MEMBER( mrkougar_sh_irqtrigger_w ); IRQ_CALLBACK_MEMBER( scramble_sh_irq_callback ); + +private: + void cavelon_banksw(); + inline int bit(int i,int n); + void sh_init(); + + uint8_t m_cavelon_bank; + + // harem + uint8_t m_harem_decrypt_mode; + uint8_t m_harem_decrypt_bit; + uint8_t m_harem_decrypt_clk; + uint8_t m_harem_decrypt_count; + std::unique_ptr<uint8_t[]> m_harem_decrypted_data; + std::unique_ptr<uint8_t[]> m_harem_decrypted_opcodes; }; -/*----------- defined in audio/scramble.c -----------*/ +/*----------- defined in audio/scramble.cpp -----------*/ MACHINE_CONFIG_EXTERN( ad2083_audio ); diff --git a/src/mame/includes/segas16a.h b/src/mame/includes/segas16a.h index 688e1400f72..60fdca74b97 100644 --- a/src/mame/includes/segas16a.h +++ b/src/mame/includes/segas16a.h @@ -166,3 +166,22 @@ protected: uint8_t m_mj_input_num; optional_ioport_array<6> m_mj_inputs; }; + +class afighter_16a_analog_state : public segas16a_state +{ +public: + // construction/destruction + afighter_16a_analog_state(const machine_config &mconfig, device_type type, const char *tag) + : segas16a_state(mconfig, type, tag), + m_accel(*this, "ACCEL"), + m_steer(*this, "STEER") + { } + + DECLARE_CUSTOM_INPUT_MEMBER(afighter_accel_r); + DECLARE_CUSTOM_INPUT_MEMBER(afighter_handl_left_r); + DECLARE_CUSTOM_INPUT_MEMBER(afighter_handl_right_r); + + protected: + required_ioport m_accel; + required_ioport m_steer; +}; diff --git a/src/mame/includes/segas16b.h b/src/mame/includes/segas16b.h index e988bedb011..630613167a7 100644 --- a/src/mame/includes/segas16b.h +++ b/src/mame/includes/segas16b.h @@ -241,6 +241,25 @@ protected: }; +class afighter_16b_analog_state : public segas16b_state +{ +public: + // construction/destruction + afighter_16b_analog_state(const machine_config &mconfig, device_type type, const char *tag) + : segas16b_state(mconfig, type, tag), + m_accel(*this, "ACCEL"), + m_steer(*this, "STEER") + { } + + DECLARE_CUSTOM_INPUT_MEMBER(afighter_accel_r); + DECLARE_CUSTOM_INPUT_MEMBER(afighter_handl_left_r); + DECLARE_CUSTOM_INPUT_MEMBER(afighter_handl_right_r); + + protected: + required_ioport m_accel; + required_ioport m_steer; +}; + // ======================> isgsm_state diff --git a/src/mame/includes/seta.h b/src/mame/includes/seta.h index e1c48f8c04a..5df792f5244 100644 --- a/src/mame/includes/seta.h +++ b/src/mame/includes/seta.h @@ -8,6 +8,7 @@ ***************************************************************************/ #include "machine/74157.h" +#include "machine/adc083x.h" #include "machine/gen_latch.h" #include "machine/ticket.h" #include "machine/timer.h" @@ -48,8 +49,10 @@ public: m_soundlatch2(*this, "soundlatch2"), m_upd4701(*this, "upd4701"), m_buttonmux(*this, "buttonmux"), + m_adc(*this, "adc"), m_dsw(*this, "DSW"), m_rot(*this, {"ROT1", "ROT2"}), + m_gun_inputs(*this, {"GUNX1", "GUNY1", "GUNX2", "GUNY2"}), m_p1(*this, "P1"), m_p2(*this, "P2"), m_coins(*this, "COINS"), @@ -78,9 +81,11 @@ public: optional_device<generic_latch_8_device> m_soundlatch2; optional_device<upd4701_device> m_upd4701; optional_device<hc157_device> m_buttonmux; + optional_device<adc083x_device> m_adc; optional_ioport m_dsw; optional_ioport_array<2> m_rot; + optional_ioport_array<4> m_gun_inputs; optional_ioport m_p1; optional_ioport m_p2; optional_ioport m_coins; @@ -120,17 +125,10 @@ public: int m_sub_ctrl_data; - int m_gun_input_bit; - int m_gun_input_src; - int m_gun_bit_count; - int m_gun_old_clock; - uint8_t m_usclssic_port_select; int m_keroppi_prize_hop; int m_keroppi_protection_count; - int m_wiggie_soundlatch; - uint8_t m_twineagl_xram[8]; int m_twineagl_tilebank[4]; @@ -155,6 +153,7 @@ public: DECLARE_CUSTOM_INPUT_MEMBER(usclssic_trackball_x_r); DECLARE_CUSTOM_INPUT_MEMBER(usclssic_trackball_y_r); DECLARE_WRITE8_MEMBER(usclssic_lockout_w); + ADC083X_INPUT_CB(zombraid_adc_cb); DECLARE_READ16_MEMBER(zombraid_gun_r); DECLARE_WRITE16_MEMBER(zombraid_gun_w); DECLARE_READ16_MEMBER(zingzipbl_unknown_r); @@ -167,9 +166,7 @@ public: DECLARE_READ16_MEMBER(kiwame_input_r); DECLARE_READ16_MEMBER(thunderl_protection_r); DECLARE_WRITE16_MEMBER(thunderl_protection_w); - DECLARE_READ8_MEMBER(wiggie_soundlatch_r); - DECLARE_WRITE16_MEMBER(wiggie_soundlatch_w); - DECLARE_WRITE16_MEMBER(utoukond_soundlatch_w); + DECLARE_WRITE8_MEMBER(utoukond_sound_control_w); DECLARE_READ16_MEMBER(pairlove_prot_r); DECLARE_WRITE16_MEMBER(pairlove_prot_w); DECLARE_WRITE8_MEMBER(sub_bankswitch_w); @@ -191,7 +188,6 @@ public: DECLARE_DRIVER_INIT(downtown); DECLARE_DRIVER_INIT(rezon); DECLARE_DRIVER_INIT(twineagl); - DECLARE_DRIVER_INIT(zombraid); DECLARE_DRIVER_INIT(crazyfgt); DECLARE_DRIVER_INIT(metafox); DECLARE_DRIVER_INIT(arbalest); diff --git a/src/mame/includes/spiders.h b/src/mame/includes/spiders.h index e6f188aa64d..9b00c1e347c 100644 --- a/src/mame/includes/spiders.h +++ b/src/mame/includes/spiders.h @@ -29,12 +29,11 @@ public: DECLARE_WRITE_LINE_MEMBER(main_cpu_irq); DECLARE_WRITE_LINE_MEMBER(flipscreen_w); - DECLARE_WRITE_LINE_MEMBER(display_enable_changed); DECLARE_WRITE8_MEMBER(gfx_rom_intf_w); DECLARE_READ8_MEMBER(gfx_rom_r); virtual void machine_start() override; INTERRUPT_GEN_MEMBER(update_pia_1); - DECLARE_WRITE8_MEMBER(ic60_74123_output_changed); + DECLARE_WRITE_LINE_MEMBER(ic60_74123_output_changed); DECLARE_WRITE8_MEMBER(spiders_audio_command_w); DECLARE_WRITE8_MEMBER(spiders_audio_a_w); DECLARE_WRITE8_MEMBER(spiders_audio_b_w); diff --git a/src/mame/includes/ssozumo.h b/src/mame/includes/ssozumo.h index 759698d84a3..0ef46e7a836 100644 --- a/src/mame/includes/ssozumo.h +++ b/src/mame/includes/ssozumo.h @@ -20,22 +20,6 @@ public: m_videoram2(*this, "videoram2"), m_colorram2(*this, "colorram2") { } - required_device<cpu_device> m_maincpu; - required_device<cpu_device> m_audiocpu; - required_device<gfxdecode_device> m_gfxdecode; - required_device<palette_device> m_palette; - required_device<generic_latch_8_device> m_soundlatch; - - required_shared_ptr<uint8_t> m_spriteram; - required_shared_ptr<uint8_t> m_paletteram; - required_shared_ptr<uint8_t> m_videoram; - required_shared_ptr<uint8_t> m_colorram; - required_shared_ptr<uint8_t> m_videoram2; - required_shared_ptr<uint8_t> m_colorram2; - - tilemap_t *m_bg_tilemap; - tilemap_t *m_fg_tilemap; - uint8_t m_sound_nmi_mask; DECLARE_WRITE8_MEMBER(sh_command_w); DECLARE_WRITE8_MEMBER(sound_nmi_mask_w); @@ -54,10 +38,31 @@ public: TILE_GET_INFO_MEMBER(get_bg_tile_info); TILE_GET_INFO_MEMBER(get_fg_tile_info); + DECLARE_PALETTE_INIT(ssozumo); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + +protected: virtual void machine_start() override; virtual void video_start() override; - DECLARE_PALETTE_INIT(ssozumo); - uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); +private: + required_device<cpu_device> m_maincpu; + required_device<cpu_device> m_audiocpu; + required_device<gfxdecode_device> m_gfxdecode; + required_device<palette_device> m_palette; + required_device<generic_latch_8_device> m_soundlatch; + + required_shared_ptr<uint8_t> m_spriteram; + required_shared_ptr<uint8_t> m_paletteram; + required_shared_ptr<uint8_t> m_videoram; + required_shared_ptr<uint8_t> m_colorram; + required_shared_ptr<uint8_t> m_videoram2; + required_shared_ptr<uint8_t> m_colorram2; + + tilemap_t *m_bg_tilemap; + tilemap_t *m_fg_tilemap; + uint8_t m_sound_nmi_mask; + uint8_t m_color_bank; + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect); }; diff --git a/src/mame/includes/stv.h b/src/mame/includes/stv.h index 959b75770f7..177458b1201 100644 --- a/src/mame/includes/stv.h +++ b/src/mame/includes/stv.h @@ -142,6 +142,12 @@ public: uint8_t m_prev_gamebank_select; }; +class stvpc_state : public stv_state +{ +public: + using stv_state::stv_state; + static constexpr feature_type unemulated_features() { return feature::CAMERA | feature::PRINTER; } +}; //#define MASTER_CLOCK_352 57272720 //#define MASTER_CLOCK_320 53693174 diff --git a/src/mame/includes/swtpc09.h b/src/mame/includes/swtpc09.h index 8b558c10b23..3136208398c 100644 --- a/src/mame/includes/swtpc09.h +++ b/src/mame/includes/swtpc09.h @@ -22,7 +22,8 @@ #include "machine/terminal.h" #include "imagedev/harddriv.h" #include "machine/idectrl.h" -#include "machine/clock.h" +#include "machine/bankdev.h" +#include "machine/mc14411.h" #include "bus/rs232/rs232.h" @@ -33,6 +34,7 @@ public: swtpc09_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") + , m_brg(*this, "brg") , m_pia(*this, "pia") , m_ptm(*this, "ptm") , m_acia(*this, "acia") @@ -45,6 +47,7 @@ public: , m_piaide(*this, "piaide") , m_harddisk(*this, "harddisk") , m_ide(*this, "ide") + , m_dat(*this, "dat") { } DECLARE_FLOPPY_FORMATS(floppy_formats); @@ -85,6 +88,8 @@ public: DECLARE_WRITE8_MEMBER ( dc4_control_reg_w ); DECLARE_WRITE8_MEMBER(dat_w); + DECLARE_READ8_MEMBER(main_r); + DECLARE_WRITE8_MEMBER(main_w); DECLARE_DRIVER_INIT( swtpc09 ); DECLARE_DRIVER_INIT( swtpc09i ); @@ -95,10 +100,15 @@ public: DECLARE_WRITE8_MEMBER ( m6844_w ); protected: + virtual void machine_start() override; + void swtpc09_fdc_dma_transfer(); void swtpc09_irq_handler(uint8_t peripheral, uint8_t state); + offs_t dat_translate(offs_t offset) const; + required_device<cpu_device> m_maincpu; + required_device<mc14411_device> m_brg; required_device<pia6821_device> m_pia; required_device<ptm6840_device> m_ptm; required_device<acia6850_device> m_acia; @@ -111,6 +121,7 @@ protected: optional_device<pia6821_device> m_piaide; optional_device<device_t> m_harddisk; optional_device<ide_controller_device> m_ide; + required_shared_ptr<uint8_t> m_dat; uint8_t m_term_data; // terminal keyboard value uint8_t m_pia_counter; // this is the counter on pia porta @@ -124,6 +135,8 @@ protected: uint8_t m_active_interrupt; uint8_t m_interrupt; + address_space *m_banked_space; + // TODO: move this in proper device /* channel_data structure holds info about each 6844 DMA channel */ diff --git a/src/mame/includes/taito_b.h b/src/mame/includes/taito_b.h index 53e3232895a..0af5385697e 100644 --- a/src/mame/includes/taito_b.h +++ b/src/mame/includes/taito_b.h @@ -40,41 +40,6 @@ public: m_screen(*this, "screen"), m_palette(*this, "palette") { } - /* memory pointers */ - required_shared_ptr<uint16_t> m_spriteram; - optional_shared_ptr<uint16_t> m_pixelram; - - /* video-related */ - /* framebuffer is a raw bitmap, remapped as a last step */ - std::unique_ptr<bitmap_ind16> m_framebuffer[2]; - std::unique_ptr<bitmap_ind16> m_pixel_bitmap; - std::unique_ptr<bitmap_ind16> m_realpunc_bitmap; - - uint16_t m_pixel_scroll[3]; - - int m_b_fg_color_base; - int m_b_sp_color_base; - - /* misc */ - uint16_t m_eep_latch; - uint16_t m_coin_word; - - uint16_t m_realpunc_video_ctrl; - - /* devices */ - required_device<cpu_device> m_maincpu; - required_device<cpu_device> m_audiocpu; - device_t *m_ym; - optional_device<hd63484_device> m_hd63484; - required_device<tc0180vcu_device> m_tc0180vcu; - optional_device<tc0640fio_device> m_tc0640fio; - optional_device<tc0220ioc_device> m_tc0220ioc; - optional_device<tc0510nio_device> m_tc0510nio; - optional_device<mb87078_device> m_mb87078; - required_device<gfxdecode_device> m_gfxdecode; - required_device<screen_device> m_screen; - required_device<palette_device> m_palette; - DECLARE_WRITE8_MEMBER(bankswitch_w); DECLARE_READ16_MEMBER(tracky1_hi_r); DECLARE_READ16_MEMBER(tracky1_lo_r); @@ -100,8 +65,6 @@ public: DECLARE_WRITE8_MEMBER(mb87078_gain_changed); DECLARE_INPUT_CHANGED_MEMBER(realpunc_sensor); DECLARE_DRIVER_INIT(taito_b); - virtual void machine_start() override; - virtual void machine_reset() override; DECLARE_VIDEO_START(taitob_color_order0); DECLARE_VIDEO_START(taitob_color_order1); DECLARE_VIDEO_START(taitob_color_order2); @@ -123,10 +86,56 @@ public: INTERRUPT_GEN_MEMBER(selfeena_interrupt); INTERRUPT_GEN_MEMBER(sbm_interrupt); INTERRUPT_GEN_MEMBER(realpunc_interrupt); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +private: + /* memory pointers */ + required_shared_ptr<uint16_t> m_spriteram; + optional_shared_ptr<uint16_t> m_pixelram; + + /* video-related */ + /* framebuffer is a raw bitmap, remapped as a last step */ + std::unique_ptr<bitmap_ind16> m_framebuffer[2]; + std::unique_ptr<bitmap_ind16> m_pixel_bitmap; + std::unique_ptr<bitmap_ind16> m_realpunc_bitmap; + + uint16_t m_pixel_scroll[3]; + + int m_b_fg_color_base; + int m_b_sp_color_base; + + /* misc */ + uint16_t m_eep_latch; + uint16_t m_coin_word; + + uint16_t m_realpunc_video_ctrl; + + /* devices */ + required_device<cpu_device> m_maincpu; + required_device<cpu_device> m_audiocpu; + device_t *m_ym; + optional_device<hd63484_device> m_hd63484; + required_device<tc0180vcu_device> m_tc0180vcu; + optional_device<tc0640fio_device> m_tc0640fio; + optional_device<tc0220ioc_device> m_tc0220ioc; + optional_device<tc0510nio_device> m_tc0510nio; + optional_device<mb87078_device> m_mb87078; + required_device<gfxdecode_device> m_gfxdecode; + required_device<screen_device> m_screen; + required_device<palette_device> m_palette; + void hitice_clear_pixel_bitmap( ); void draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ); void draw_framebuffer( bitmap_ind16 &bitmap, const rectangle &cliprect, int priority ); +}; -protected: - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; +class taitob_c_state : public taitob_state +{ +public: + using taitob_state::taitob_state; + static constexpr feature_type unemulated_features() { return feature::CAMERA; } }; diff --git a/src/mame/includes/thomson.h b/src/mame/includes/thomson.h index 58223220730..52ca0698b01 100644 --- a/src/mame/includes/thomson.h +++ b/src/mame/includes/thomson.h @@ -20,6 +20,7 @@ #include "imagedev/floppy.h" #include "machine/6821pia.h" #include "machine/6850acia.h" +#include "machine/input_merger.h" #include "machine/mc6843.h" #include "machine/mc6846.h" #include "machine/mc6846.h" @@ -116,6 +117,8 @@ public: m_mc6843(*this, "mc6843"), m_acia6850(*this, "acia6850"), m_screen(*this, "screen"), + m_mainirq(*this, "mainirq"), + m_mainfirq(*this, "mainfirq"), m_io_game_port_directions(*this, "game_port_directions"), m_io_game_port_buttons(*this, "game_port_buttons"), m_io_mouse_x(*this, "mouse_x"), @@ -152,8 +155,6 @@ public: DECLARE_WRITE_LINE_MEMBER( to7_set_cassette_motor ); DECLARE_WRITE_LINE_MEMBER( mo5_set_cassette_motor ); DECLARE_WRITE_LINE_MEMBER( thom_dev_irq_0 ); - DECLARE_WRITE_LINE_MEMBER( thom_irq_1 ); - DECLARE_WRITE_LINE_MEMBER( thom_firq_1 ); DECLARE_WRITE8_MEMBER( to7_cartridge_w ); DECLARE_READ8_MEMBER( to7_cartridge_r ); DECLARE_WRITE8_MEMBER( to7_timer_port_out ); @@ -369,6 +370,8 @@ protected: optional_device<mc6843_device> m_mc6843; optional_device<acia6850_device> m_acia6850; required_device<screen_device> m_screen; + required_device<input_merger_device> m_mainirq; + required_device<input_merger_device> m_mainfirq; required_ioport m_io_game_port_directions; required_ioport m_io_game_port_buttons; required_ioport m_io_mouse_x; @@ -403,9 +406,6 @@ protected: /* buffer storing demodulated bits, only for k7 and with speed hack */ uint32_t m_to7_k7_bitsize; uint8_t* m_to7_k7_bits; - /* several devices on the same irqs */ - uint8_t m_thom_irq; - uint8_t m_thom_firq; /* ------------ cartridge ------------ */ uint8_t m_thom_cart_nb_banks; /* number of 16 KB banks (up to 4) */ uint8_t m_thom_cart_bank; /* current bank */ @@ -513,14 +513,7 @@ protected: int to7_get_cassette(); int mo5_get_cassette(); void mo5_set_cassette( int data ); - void thom_set_irq( int line, int state ); - void thom_set_firq( int line, int state ); void thom_irq_reset(); - void thom_irq_init(); - void thom_irq_0( int state ); - void thom_irq_3( int state ); - void thom_firq_2( int state ); - void thom_irq_4( int state ); void thom_set_caps_led( int led ); void to7_update_cart_bank(); void to7_set_init( int init ); diff --git a/src/mame/includes/tmc600.h b/src/mame/includes/tmc600.h index 4c447910ed4..d006ae9d53b 100644 --- a/src/mame/includes/tmc600.h +++ b/src/mame/includes/tmc600.h @@ -9,15 +9,20 @@ #include "imagedev/cassette.h" #include "imagedev/snapquik.h" #include "bus/centronics/ctronics.h" +#include "bus/tmc600/euro.h" +#include "machine/cdp1852.h" #include "machine/ram.h" #include "machine/timer.h" #include "sound/cdp1869.h" #include "speaker.h" -#define SCREEN_TAG "screen" -#define CDP1802_TAG "cdp1802" -#define CDP1869_TAG "cdp1869" -#define CENTRONICS_TAG "centronics" +#define SCREEN_TAG "screen" +#define CDP1802_TAG "cdp1802" +#define CDP1869_TAG "cdp1869" +#define CDP1852_KB_TAG "cdp1852_kb" +#define CDP1852_BUS_TAG "cdp1852_bus" +#define CDP1852_TMC700_TAG "cdp1852_printer" +#define CENTRONICS_TAG "centronics" #define TMC600_PAGE_RAM_SIZE 0x400 #define TMC600_PAGE_RAM_MASK 0x3ff @@ -29,8 +34,10 @@ public: driver_device(mconfig, type, tag), m_maincpu(*this, CDP1802_TAG), m_vis(*this, CDP1869_TAG), + m_bwio(*this, CDP1852_KB_TAG), m_cassette(*this, "cassette"), m_centronics(*this, "centronics"), + m_bus(*this, TMC600_EURO_BUS_TAG), m_ram(*this, RAM_TAG), m_char_rom(*this, "chargen"), m_page_ram(*this, "page_ram"), @@ -41,8 +48,10 @@ public: required_device<cosmac_device> m_maincpu; required_device<cdp1869_device> m_vis; + required_device<cdp1852_device> m_bwio; required_device<cassette_image_device> m_cassette; required_device<centronics_device> m_centronics; + required_device<tmc600_euro_bus_slot_t> m_bus; required_device<ram_device> m_ram; required_region_ptr<uint8_t> m_char_rom; required_shared_ptr<uint8_t> m_page_ram; @@ -50,11 +59,10 @@ public: required_ioport m_run; required_ioport_array<8> m_key_row; - virtual void machine_start() override; - virtual void video_start() override; - DECLARE_WRITE8_MEMBER( keyboard_latch_w ); + DECLARE_READ8_MEMBER( rtc_r ); + DECLARE_WRITE8_MEMBER( printer_w ); DECLARE_WRITE8_MEMBER( vismac_register_w ); DECLARE_WRITE8_MEMBER( vismac_data_w ); DECLARE_WRITE8_MEMBER( page_ram_w ); @@ -62,17 +70,17 @@ public: DECLARE_READ_LINE_MEMBER( ef2_r ); DECLARE_READ_LINE_MEMBER( ef3_r ); DECLARE_WRITE_LINE_MEMBER( q_w ); + DECLARE_WRITE8_MEMBER( sc_w ); + DECLARE_WRITE_LINE_MEMBER( prd_w ); uint8_t get_color(uint16_t pma); // video state int m_vismac_reg_latch; // video register latch int m_vismac_color_latch; // color latch - int m_vismac_bkg_latch; // background color latch - int m_blink; // cursor blink - - // keyboard state - int m_keylatch; // key latch + bool m_blink; // cursor blink + int m_frame; + bool m_rtc_int; TIMER_DEVICE_CALLBACK_MEMBER(blink_tick); CDP1869_CHAR_RAM_READ_MEMBER(tmc600_char_ram_r); diff --git a/src/mame/includes/trs80.h b/src/mame/includes/trs80.h index c65340d9003..47cdaed7dd7 100644 --- a/src/mame/includes/trs80.h +++ b/src/mame/includes/trs80.h @@ -106,6 +106,7 @@ public: DECLARE_READ8_MEMBER( trs80_gfxram_r ); DECLARE_WRITE8_MEMBER( trs80_gfxram_w ); DECLARE_READ8_MEMBER (trs80_wd179x_r); + DECLARE_READ8_MEMBER (cp500_a11_flipflop_toggle); DECLARE_DRIVER_INIT(trs80m4); DECLARE_DRIVER_INIT(trs80l2); DECLARE_DRIVER_INIT(trs80m4p); @@ -118,6 +119,7 @@ public: DECLARE_QUICKLOAD_LOAD_MEMBER( trs80_cmd ); DECLARE_MACHINE_RESET(trs80m4); DECLARE_MACHINE_RESET(lnw80); + DECLARE_MACHINE_RESET(cp500); DECLARE_PALETTE_INIT(lnw80); uint32_t screen_update_trs80(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_trs80m4(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); @@ -150,6 +152,7 @@ private: uint16_t m_start_address; uint8_t m_crtc_reg; uint8_t m_size_store; + bool m_a11_flipflop; void trs80_fdc_interrupt_internal(); virtual void machine_start() override; virtual void machine_reset() override; diff --git a/src/mame/includes/tsamurai.h b/src/mame/includes/tsamurai.h index 4b30a28ac30..df1e64e3929 100644 --- a/src/mame/includes/tsamurai.h +++ b/src/mame/includes/tsamurai.h @@ -20,41 +20,6 @@ public: m_bg_videoram(*this, "bg_videoram"), m_spriteram(*this, "spriteram") { } - required_device<cpu_device> m_maincpu; - required_device<cpu_device> m_audiocpu; - optional_device<cpu_device> m_audio2; - optional_device<cpu_device> m_audio3; - required_device<gfxdecode_device> m_gfxdecode; - required_device<palette_device> m_palette; - optional_device<generic_latch_8_device> m_soundlatch; // vsgongf only - - required_shared_ptr<uint8_t> m_videoram; - optional_shared_ptr<uint8_t> m_colorram; - optional_shared_ptr<uint8_t> m_bg_videoram; - required_shared_ptr<uint8_t> m_spriteram; - - tilemap_t *m_background; - tilemap_t *m_foreground; - - //common - int m_flicker; - int m_textbank1; - int m_nmi_enabled; - - // tsamurai and m660 specific - int m_bgcolor; - int m_sound_command1; - int m_sound_command2; - - //m660 specific - int m_textbank2; - int m_sound_command3; - - //vsgongf specific - int m_vsgongf_sound_nmi_enabled; - int m_vsgongf_color; - int m_key_count; //debug only - // common DECLARE_WRITE_LINE_MEMBER(nmi_enable_w); DECLARE_WRITE_LINE_MEMBER(coin1_counter_w); @@ -93,23 +58,62 @@ public: DECLARE_READ8_MEMBER(vsgongf_a100_r); DECLARE_WRITE8_MEMBER(vsgongf_sound_command_w); - TILE_GET_INFO_MEMBER(get_bg_tile_info); - TILE_GET_INFO_MEMBER(get_fg_tile_info); - TILE_GET_INFO_MEMBER(get_vsgongf_tile_info); - - virtual void machine_start() override; DECLARE_MACHINE_START(m660); DECLARE_MACHINE_START(tsamurai); DECLARE_MACHINE_START(vsgongf); - virtual void video_start() override; DECLARE_VIDEO_START(m660); DECLARE_VIDEO_START(tsamurai); DECLARE_VIDEO_START(vsgongf); + DECLARE_DRIVER_INIT(the26thz); uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_vsgongf(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect ); INTERRUPT_GEN_MEMBER(interrupt); INTERRUPT_GEN_MEMBER(vsgongf_sound_interrupt); + +protected: + virtual void machine_start() override; + virtual void video_start() override; + +private: + required_device<cpu_device> m_maincpu; + required_device<cpu_device> m_audiocpu; + optional_device<cpu_device> m_audio2; + optional_device<cpu_device> m_audio3; + required_device<gfxdecode_device> m_gfxdecode; + required_device<palette_device> m_palette; + optional_device<generic_latch_8_device> m_soundlatch; // vsgongf only + + required_shared_ptr<uint8_t> m_videoram; + optional_shared_ptr<uint8_t> m_colorram; + optional_shared_ptr<uint8_t> m_bg_videoram; + required_shared_ptr<uint8_t> m_spriteram; + + tilemap_t *m_background; + tilemap_t *m_foreground; + + //common + int m_flicker; + int m_textbank1; + int m_nmi_enabled; + + // tsamurai and m660 specific + int m_bgcolor; + int m_sound_command1; + int m_sound_command2; + + //m660 specific + int m_textbank2; + int m_sound_command3; + + //vsgongf specific + int m_vsgongf_sound_nmi_enabled; + int m_vsgongf_color; + int m_key_count; //debug only + + TILE_GET_INFO_MEMBER(get_bg_tile_info); + TILE_GET_INFO_MEMBER(get_fg_tile_info); + TILE_GET_INFO_MEMBER(get_vsgongf_tile_info); + void draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect ); }; diff --git a/src/mame/includes/turrett.h b/src/mame/includes/turrett.h index 334219c23a8..4de2ec6a290 100644 --- a/src/mame/includes/turrett.h +++ b/src/mame/includes/turrett.h @@ -118,7 +118,7 @@ protected: const address_space_config m_space_config; private: - direct_read_data *m_direct; + direct_read_data<0> *m_direct; sound_stream *m_stream; struct diff --git a/src/mame/includes/twincobr.h b/src/mame/includes/twincobr.h index d8c15b8dac6..e4bd3a4d6f8 100644 --- a/src/mame/includes/twincobr.h +++ b/src/mame/includes/twincobr.h @@ -30,7 +30,6 @@ public: optional_device<buffered_spriteram8_device> m_spriteram8; optional_device<buffered_spriteram16_device> m_spriteram16; - int m_toaplan_main_cpu; int32_t m_fg_rom_bank; int32_t m_bg_ram_bank; int m_intenable; @@ -70,13 +69,14 @@ public: DECLARE_READ16_MEMBER(fsharkbt_dsp_r); DECLARE_WRITE16_MEMBER(fsharkbt_dsp_w); DECLARE_READ_LINE_MEMBER(twincobr_BIO_r); - DECLARE_WRITE16_MEMBER(twincobr_control_w); - DECLARE_WRITE8_MEMBER(wardner_control_w); + DECLARE_WRITE_LINE_MEMBER(int_enable_w); + DECLARE_WRITE_LINE_MEMBER(dsp_int_w); + DECLARE_WRITE_LINE_MEMBER(coin_counter_1_w); + DECLARE_WRITE_LINE_MEMBER(coin_counter_2_w); + DECLARE_WRITE_LINE_MEMBER(coin_lockout_1_w); + DECLARE_WRITE_LINE_MEMBER(coin_lockout_2_w); DECLARE_READ16_MEMBER(twincobr_sharedram_r); DECLARE_WRITE16_MEMBER(twincobr_sharedram_w); - DECLARE_WRITE16_MEMBER(fshark_coin_dsp_w); - DECLARE_WRITE8_MEMBER(twincobr_coin_w); - DECLARE_WRITE8_MEMBER(wardner_coin_dsp_w); DECLARE_WRITE16_MEMBER(twincobr_txoffs_w); DECLARE_READ16_MEMBER(twincobr_txram_r); DECLARE_WRITE16_MEMBER(twincobr_txram_w); @@ -112,12 +112,11 @@ public: INTERRUPT_GEN_MEMBER(wardner_interrupt); void twincobr_restore_dsp(); void twincobr_create_tilemaps(); - void twincobr_display(int enable); - void twincobr_flipscreen(int flip); + DECLARE_WRITE_LINE_MEMBER(display_on_w); + DECLARE_WRITE_LINE_MEMBER(flipscreen_w); + DECLARE_WRITE_LINE_MEMBER(bg_ram_bank_w); + DECLARE_WRITE_LINE_MEMBER(fg_rom_bank_w); void twincobr_log_vram(); - void twincobr_dsp(int enable); - void toaplan0_control_w(int offset, int data); - void toaplan0_coin_dsp_w(address_space &space, int offset, int data); void twincobr_driver_savestate(); required_device<cpu_device> m_maincpu; required_device<cpu_device> m_dsp; diff --git a/src/mame/includes/vicdual.h b/src/mame/includes/vicdual.h index 7d106ddb885..29767683b96 100644 --- a/src/mame/includes/vicdual.h +++ b/src/mame/includes/vicdual.h @@ -86,6 +86,7 @@ public: DECLARE_READ8_MEMBER(headon_io_r); DECLARE_READ8_MEMBER(sspaceat_io_r); DECLARE_WRITE8_MEMBER(headon_io_w); + DECLARE_MACHINE_RESET(headon2); DECLARE_READ8_MEMBER(headon2_io_r); DECLARE_WRITE8_MEMBER(headon2_io_w); DECLARE_WRITE8_MEMBER(digger_io_w); @@ -93,6 +94,7 @@ public: DECLARE_WRITE8_MEMBER(invds_io_w); DECLARE_WRITE8_MEMBER(carhntds_io_w); DECLARE_WRITE8_MEMBER(sspacaho_io_w); + DECLARE_WRITE8_MEMBER(headonn_io_w); DECLARE_WRITE8_MEMBER(tranqgun_io_w); DECLARE_WRITE8_MEMBER(spacetrk_io_w); DECLARE_WRITE8_MEMBER(carnival_io_w); @@ -131,6 +133,9 @@ public: DECLARE_WRITE8_MEMBER( pulsar_audio_1_w ); DECLARE_WRITE8_MEMBER( pulsar_audio_2_w ); + /*----------- defined in audio/tranqgun.c -----------*/ + DECLARE_WRITE8_MEMBER( tranqgun_audio_w ); + DECLARE_CUSTOM_INPUT_MEMBER(read_coin_status); DECLARE_CUSTOM_INPUT_MEMBER(get_64v); DECLARE_CUSTOM_INPUT_MEMBER(get_vblank_comp); diff --git a/src/mame/includes/wecleman.h b/src/mame/includes/wecleman.h index 2fa3508c51c..35756625ed2 100644 --- a/src/mame/includes/wecleman.h +++ b/src/mame/includes/wecleman.h @@ -1,5 +1,9 @@ // license:BSD-3-Clause // copyright-holders:Luca Elia +#ifndef MAME_INCLUDES_WECLEMAN_H +#define MAME_INCLUDES_WECLEMAN_H + +#pragma once #include "machine/gen_latch.h" #include "machine/timer.h" @@ -68,8 +72,6 @@ public: int m_sound_hw_type; bool m_hotchase_sound_hs; pen_t m_black_pen; - struct sprite *m_sprite_list; - struct sprite **m_spr_ptr_list; DECLARE_READ16_MEMBER(wecleman_protection_r); DECLARE_WRITE16_MEMBER(wecleman_protection_w); DECLARE_WRITE16_MEMBER(irqctrl_w); @@ -114,8 +116,6 @@ public: void hotchase_sprite_decode( int num16_banks, int bank_size ); void get_sprite_info(); void sortsprite(int *idx_array, int *key_array, int size); - template<class _BitmapClass> void do_blit_zoom32(_BitmapClass &bitmap, const rectangle &cliprect, struct sprite *sprite); - template<class _BitmapClass> void sprite_draw(_BitmapClass &bitmap, const rectangle &cliprect); void wecleman_draw_road(bitmap_rgb32 &bitmap, const rectangle &cliprect, int priority); void hotchase_draw_road(bitmap_ind16 &bitmap, const rectangle &cliprect); K051316_CB_MEMBER(hotchase_zoom_callback_1); @@ -136,4 +136,30 @@ public: required_device<palette_device> m_palette; required_device<screen_device> m_screen; required_device<generic_latch_8_device> m_soundlatch; + +private: + struct sprite_t + { + sprite_t() { } + + uint8_t *pen_data = nullptr; /* points to top left corner of tile data */ + int line_offset = 0; + + const pen_t *pal_data = nullptr; + rgb_t pal_base; + + int x_offset = 0, y_offset = 0; + int tile_width = 0, tile_height = 0; + int total_width = 0, total_height = 0; /* in screen coordinates */ + int x = 0, y = 0; + int shadow_mode = 0, flags = 0; + }; + + template<class _BitmapClass> void do_blit_zoom32(_BitmapClass &bitmap, const rectangle &cliprect, const sprite_t &sprite); + template<class _BitmapClass> void sprite_draw(_BitmapClass &bitmap, const rectangle &cliprect); + + std::unique_ptr<sprite_t []> m_sprite_list; + sprite_t **m_spr_ptr_list; }; + +#endif // MAME_INCLUDES_WECLEMAN_H diff --git a/src/mame/includes/wgp.h b/src/mame/includes/wgp.h index 3acf66ef347..3c145529fac 100644 --- a/src/mame/includes/wgp.h +++ b/src/mame/includes/wgp.h @@ -16,9 +16,9 @@ class wgp_state : public driver_device public: enum { - TIMER_WGP_INTERRUPT4, - TIMER_WGP_INTERRUPT6, - TIMER_WGP_CPUB_INTERRUPT6 + TIMER_INTERRUPT4, + TIMER_INTERRUPT6, + TIMER_CPUB_INTERRUPT6 }; wgp_state(const machine_config &mconfig, device_type type, const char *tag) @@ -41,6 +41,39 @@ public: m_fake(*this, "FAKE") { } + DECLARE_WRITE8_MEMBER(coins_w); + DECLARE_WRITE16_MEMBER(cpua_ctrl_w); + DECLARE_READ16_MEMBER(lan_status_r); + DECLARE_WRITE16_MEMBER(rotate_port_w); + DECLARE_READ16_MEMBER(adinput_r); + DECLARE_WRITE16_MEMBER(adinput_w); + DECLARE_WRITE8_MEMBER(sound_bankswitch_w); + DECLARE_WRITE16_MEMBER(pivram_word_w); + DECLARE_WRITE16_MEMBER(piv_ctrl_word_w); + DECLARE_DRIVER_INIT(wgp); + DECLARE_DRIVER_INIT(wgp2); + DECLARE_VIDEO_START(wgp2); + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + INTERRUPT_GEN_MEMBER(cpub_interrupt); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + virtual void video_start() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +private: + TILE_GET_INFO_MEMBER(get_piv0_tile_info); + TILE_GET_INFO_MEMBER(get_piv1_tile_info); + TILE_GET_INFO_MEMBER(get_piv2_tile_info); + + void postload(); + inline void common_get_piv_tile_info(tile_data &tileinfo, int tile_index, int num); + void core_vh_start(int piv_xoffs, int piv_yoffs); + void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int y_offs); + void piv_layer_draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int flags, uint32_t priority); + void parse_control(); + /* memory pointers */ required_shared_ptr<uint16_t> m_spritemap; required_shared_ptr<uint16_t> m_spriteram; @@ -61,6 +94,8 @@ public: /* misc */ uint16_t m_cpua_ctrl; uint16_t m_port_sel; + emu_timer *m_int6_timer; + emu_timer *m_cpub_int6_timer; /* devices */ required_device<cpu_device> m_maincpu; @@ -75,38 +110,4 @@ public: optional_ioport m_steer; optional_ioport m_unknown; optional_ioport m_fake; - - DECLARE_WRITE8_MEMBER(coins_w); - DECLARE_WRITE16_MEMBER(cpua_ctrl_w); - DECLARE_READ16_MEMBER(lan_status_r); - DECLARE_WRITE16_MEMBER(rotate_port_w); - DECLARE_READ16_MEMBER(wgp_adinput_r); - DECLARE_WRITE16_MEMBER(wgp_adinput_w); - DECLARE_WRITE8_MEMBER(sound_bankswitch_w); - DECLARE_WRITE16_MEMBER(wgp_sound_w); - DECLARE_READ16_MEMBER(wgp_sound_r); - DECLARE_READ16_MEMBER(wgp_pivram_word_r); - DECLARE_WRITE16_MEMBER(wgp_pivram_word_w); - DECLARE_READ16_MEMBER(wgp_piv_ctrl_word_r); - DECLARE_WRITE16_MEMBER(wgp_piv_ctrl_word_w); - DECLARE_DRIVER_INIT(wgp); - DECLARE_DRIVER_INIT(wgp2); - TILE_GET_INFO_MEMBER(get_piv0_tile_info); - TILE_GET_INFO_MEMBER(get_piv1_tile_info); - TILE_GET_INFO_MEMBER(get_piv2_tile_info); - virtual void machine_start() override; - virtual void machine_reset() override; - virtual void video_start() override; - DECLARE_VIDEO_START(wgp2); - uint32_t screen_update_wgp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(wgp_cpub_interrupt); - void wgp_postload(); - inline void common_get_piv_tile_info( tile_data &tileinfo, int tile_index, int num ); - void wgp_core_vh_start( int piv_xoffs, int piv_yoffs ); - void draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int y_offs ); - void wgp_piv_layer_draw( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int flags, uint32_t priority ); - void parse_control(); - -protected: - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; }; diff --git a/src/mame/includes/zx.h b/src/mame/includes/zx.h index 46a18196e4b..0d31dbbb4fa 100644 --- a/src/mame/includes/zx.h +++ b/src/mame/includes/zx.h @@ -2,7 +2,7 @@ // copyright-holders:Juergen Buchmueller, Krzysztof Strzecha, Robbbert /***************************************************************************** * - * includes/zx.h + * ZX-80/ZX-81 and derivatives * ****************************************************************************/ @@ -43,7 +43,8 @@ public: m_io_row6(*this, "ROW6"), m_io_row7(*this, "ROW7"), m_io_config(*this, "CONFIG"), - m_screen(*this, "screen") { } + m_screen(*this, "screen") + { } uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); @@ -60,7 +61,6 @@ public: virtual void machine_reset() override; virtual void video_start() override; DECLARE_PALETTE_INIT(zx); - DECLARE_PALETTE_INIT(ts1000); void zx_tape_input(); void zx_ula_hsync(); diff --git a/src/mame/layout/bmiidx.lay b/src/mame/layout/bmiidx.lay new file mode 100644 index 00000000000..90a6b8a9282 --- /dev/null +++ b/src/mame/layout/bmiidx.lay @@ -0,0 +1,151 @@ +<?xml version="1.0"?> +<mamelayout version="2"> + <element name="spotlight0"><text string="spot 1" state="1"/></element> + <element name="spotlight1"><text string="spot 2" state="1"/></element> + <element name="spotlight2"><text string="spot 3" state="1"/></element> + <element name="spotlight3"><text string="spot 4" state="1"/></element> + <element name="spotlight4"><text string="spot 5" state="1"/></element> + <element name="spotlight5"><text string="spot 6" state="1"/></element> + <element name="spotlight6"><text string="spot 7" state="1"/></element> + <element name="spotlight7"><text string="spot 8" state="1"/></element> + <element name="key1-1"><text string="key 1-1" state="1"/></element> + <element name="key1-2"><text string="key 1-2" state="1"/></element> + <element name="key1-3"><text string="key 1-3" state="1"/></element> + <element name="key1-4"><text string="key 1-4" state="1"/></element> + <element name="key1-5"><text string="key 1-5" state="1"/></element> + <element name="key1-6"><text string="key 1-6" state="1"/></element> + <element name="key1-7"><text string="key 1-7" state="1"/></element> + <element name="key2-1"><text string="key 2-1" state="1"/></element> + <element name="key2-2"><text string="key 2-2" state="1"/></element> + <element name="key2-3"><text string="key 2-3" state="1"/></element> + <element name="key2-4"><text string="key 2-4" state="1"/></element> + <element name="key2-5"><text string="key 2-5" state="1"/></element> + <element name="key2-6"><text string="key 2-6" state="1"/></element> + <element name="key2-7"><text string="key 2-7" state="1"/></element> + <element name="unknown3"><text string="unknown3" state="1"/></element> + <element name="unknown4"><text string="unknown4" state="1"/></element> + <element name="1p"><text string="1p" state="1"/></element> + <element name="2p"><text string="2p" state="1"/></element> + <element name="effect"><text string="effect" state="1"/></element> + <element name="vefx"><text string="vefx" state="1"/></element> + <element name="credit"><text string="credit" state="1"/></element> + <element name="neonlamp"><text string="neon" state="1"/></element> + <element name="unknown1"><text string="unknown1" state="1"/></element> + <element name="unknown2"><text string="unknown2" state="1"/></element> + <element name="main_led0"><text string="main 1" state="1"/></element> + <element name="main_led1"><text string="main 2" state="1"/></element> + <element name="main_led2"><text string="main 3" state="1"/></element> + <element name="main_led3"><text string="main 4" state="1"/></element> + <element name="main_led4"><text string="main 5" state="1"/></element> + <element name="main_led5"><text string="main 6" state="1"/></element> + <element name="main_led6"><text string="main 7" state="1"/></element> + <element name="main_led7"><text string="main 8" state="1"/></element> + <element name="main_led8"><text string="main 9" state="1"/></element> + <element name="spu_led0"><text string="spu 1" state="1"/></element> + <element name="spu_led1"><text string="spu 2" state="1"/></element> + <element name="spu_led2"><text string="spu 3" state="1"/></element> + <element name="spu_led3"><text string="spu 4" state="1"/></element> + <element name="spu_led4"><text string="spu 5" state="1"/></element> + <element name="spu_led5"><text string="spu 6" state="1"/></element> + <element name="spu_led6"><text string="spu 7" state="1"/></element> + <element name="spu_led7"><text string="spu 8" state="1"/></element> + + <element name="led"> + <led16seg> + <color red="0" green="0.6" blue="1.0" /> + </led16seg> + </element> + + <view name="Lamps"> + <screen index="0"> + <bounds left="0" top="0" right="320" bottom="240"/> + </screen> + + <bezel name="1p" element="1p"><bounds x="0" y="240" width="48" height="16"/></bezel> + <bezel name="2p" element="2p"><bounds x="0" y="256" width="48" height="16"/></bezel> + <bezel name="effect" element="effect"><bounds x="0" y="272" width="48" height="16"/></bezel> + <bezel name="vefx" element="vefx"><bounds x="0" y="288" width="48" height="16"/></bezel> + + <bezel name="credit" element="credit"><bounds x="48" y="240" width="48" height="16"/></bezel> + <bezel name="neonlamp" element="neonlamp"><bounds x="48" y="256" width="48" height="16"/></bezel> + <bezel name="unknown1" element="neonlamp"><bounds x="48" y="272" width="48" height="16"/></bezel> + <bezel name="unknown2" element="neonlamp"><bounds x="48" y="288" width="48" height="16"/></bezel> + + <bezel name="spotlight0" element="spotlight0"><bounds x="96" y="240" width="48" height="16"/></bezel> + <bezel name="spotlight1" element="spotlight1"><bounds x="96" y="256" width="48" height="16"/></bezel> + <bezel name="spotlight2" element="spotlight2"><bounds x="96" y="272" width="48" height="16"/></bezel> + <bezel name="spotlight3" element="spotlight3"><bounds x="96" y="288" width="48" height="16"/></bezel> + + <bezel name="spotlight4" element="spotlight4"><bounds x="144" y="240" width="48" height="16"/></bezel> + <bezel name="spotlight5" element="spotlight5"><bounds x="144" y="256" width="48" height="16"/></bezel> + <bezel name="spotlight6" element="spotlight6"><bounds x="144" y="272" width="48" height="16"/></bezel> + <bezel name="spotlight7" element="spotlight7"><bounds x="144" y="288" width="48" height="16"/></bezel> + + <bezel name="led0" element="led" state="0"> + <bounds x="0" y="304" width="32" height="64"/> + </bezel> + <bezel name="led1" element="led" state="0"> + <bounds x="32" y="304" width="32" height="64"/> + </bezel> + <bezel name="led2" element="led" state="0"> + <bounds x="64" y="304" width="32" height="64"/> + </bezel> + <bezel name="led3" element="led" state="0"> + <bounds x="96" y="304" width="32" height="64"/> + </bezel> + <bezel name="led4" element="led" state="0"> + <bounds x="128" y="304" width="32" height="64"/> + </bezel> + <bezel name="led5" element="led" state="0"> + <bounds x="160" y="304" width="32" height="64"/> + </bezel> + <bezel name="led6" element="led" state="0"> + <bounds x="192" y="304" width="32" height="64"/> + </bezel> + <bezel name="led7" element="led" state="0"> + <bounds x="224" y="304" width="32" height="64"/> + </bezel> + <bezel name="led8" element="led" state="0"> + <bounds x="256" y="304" width="32" height="64"/> + </bezel> + + <bezel name="key1-1" element="key1-1"><bounds x="0" y="368" width="48" height="16"/></bezel> + <bezel name="key1-2" element="key1-2"><bounds x="0" y="384" width="48" height="16"/></bezel> + <bezel name="key1-3" element="key1-3"><bounds x="0" y="400" width="48" height="16"/></bezel> + <bezel name="key1-4" element="key1-4"><bounds x="0" y="416" width="48" height="16"/></bezel> + + <bezel name="key1-5" element="key1-5"><bounds x="48" y="368" width="48" height="16"/></bezel> + <bezel name="key1-6" element="key1-6"><bounds x="48" y="384" width="48" height="16"/></bezel> + <bezel name="key1-7" element="key1-7"><bounds x="48" y="400" width="48" height="16"/></bezel> + <bezel name="key2-1" element="key2-1"><bounds x="48" y="416" width="48" height="16"/></bezel> + + <bezel name="key2-2" element="key2-2"><bounds x="96" y="368" width="48" height="16"/></bezel> + <bezel name="key2-3" element="key2-3"><bounds x="96" y="384" width="48" height="16"/></bezel> + <bezel name="key2-4" element="key2-4"><bounds x="96" y="400" width="48" height="16"/></bezel> + <bezel name="key2-5" element="key2-5"><bounds x="96" y="416" width="48" height="16"/></bezel> + + <bezel name="key2-6" element="key2-6"><bounds x="144" y="368" width="48" height="16"/></bezel> + <bezel name="key2-7" element="key2-7"><bounds x="144" y="384" width="48" height="16"/></bezel> + <bezel name="unknown3" element="unknown3"><bounds x="144" y="400" width="48" height="16"/></bezel> + <bezel name="unknown4" element="unknown4"><bounds x="144" y="416" width="48" height="16"/></bezel> + + <bezel name="main_led0" element="main_led0"><bounds x="0" y="432" width="24" height="16"/></bezel> + <bezel name="main_led1" element="main_led1"><bounds x="24" y="432" width="24" height="16"/></bezel> + <bezel name="main_led2" element="main_led2"><bounds x="48" y="432" width="24" height="16"/></bezel> + <bezel name="main_led3" element="main_led3"><bounds x="72" y="432" width="24" height="16"/></bezel> + <bezel name="main_led4" element="main_led4"><bounds x="96" y="432" width="24" height="16"/></bezel> + <bezel name="main_led5" element="main_led5"><bounds x="120" y="432" width="24" height="16"/></bezel> + <bezel name="main_led6" element="main_led6"><bounds x="144" y="432" width="24" height="16"/></bezel> + <bezel name="main_led7" element="main_led7"><bounds x="168" y="432" width="24" height="16"/></bezel> + <bezel name="main_led8" element="main_led8"><bounds x="192" y="432" width="24" height="16"/></bezel> + + <bezel name="spu_led0" element="spu_led0"><bounds x="0" y="448" width="24" height="16"/></bezel> + <bezel name="spu_led1" element="spu_led1"><bounds x="24" y="448" width="24" height="16"/></bezel> + <bezel name="spu_led2" element="spu_led2"><bounds x="48" y="448" width="24" height="16"/></bezel> + <bezel name="spu_led3" element="spu_led3"><bounds x="72" y="448" width="24" height="16"/></bezel> + <bezel name="spu_led4" element="spu_led4"><bounds x="96" y="448" width="24" height="16"/></bezel> + <bezel name="spu_led5" element="spu_led5"><bounds x="120" y="448" width="24" height="16"/></bezel> + <bezel name="spu_led6" element="spu_led6"><bounds x="144" y="448" width="24" height="16"/></bezel> + <bezel name="spu_led7" element="spu_led7"><bounds x="168" y="448" width="24" height="16"/></bezel> + </view> +</mamelayout> diff --git a/src/mame/layout/et3400.lay b/src/mame/layout/et3400.lay index 07cf2423bc9..72e3d44a2be 100644 --- a/src/mame/layout/et3400.lay +++ b/src/mame/layout/et3400.lay @@ -1,42 +1,228 @@ <?xml version="1.0"?> <mamelayout version="2"> - <element name="digit" defstate="0"> - <led7seg> - <color red="0.75" green="0.0" blue="0.0" /> - </led7seg> - </element> - <element name="background"> - <rect> - <bounds left="0" top="0" right="1" bottom="1" /> - <color red="0.0" green="0.0" blue="0.0" /> - </rect> - </element> - - <view name="Default Layout"> - <!-- Black background --> - <bezel element="background"> - <bounds left="0" top="230" right="308" bottom="325" /> - </bezel> - <screen index="0"> - <bounds x="2" y="0" width="304" height="230" /> - </screen> - <bezel name="digit6" element="digit"> - <bounds x="10" y="240" width="48" height="80" /> - </bezel> - <bezel name="digit5" element="digit"> - <bounds x="58" y="240" width="48" height="80" /> - </bezel> - <bezel name="digit4" element="digit"> - <bounds x="106" y="240" width="48" height="80" /> - </bezel> - <bezel name="digit3" element="digit"> - <bounds x="154" y="240" width="48" height="80" /> - </bezel> - <bezel name="digit2" element="digit"> - <bounds x="202" y="240" width="48" height="80" /> - </bezel> - <bezel name="digit1" element="digit"> - <bounds x="250" y="240" width="48" height="80" /> - </bezel> + <element name="surround"><rect><color red="0.05" green="0.0" blue="0.0" /></rect></element> + <element name="beige"><rect><color red="0.93" green="0.92" blue="0.8" /></rect></element> + + <element name="digit" defstate="0"><led7seg><color red="0.75" green="0.0" blue="0.0" /></led7seg></element> + + <element name="label_h"><text string="H"><color red="1.0" green="1.0" blue="1.0" /></text></element> + <element name="label_i"><text string="I"><color red="1.0" green="1.0" blue="1.0" /></text></element> + <element name="label_n"><text string="N"><color red="1.0" green="1.0" blue="1.0" /></text></element> + <element name="label_z"><text string="Z"><color red="1.0" green="1.0" blue="1.0" /></text></element> + <element name="label_v"><text string="V"><color red="1.0" green="1.0" blue="1.0" /></text></element> + <element name="label_c"><text string="C"><color red="1.0" green="1.0" blue="1.0" /></text></element> + + <element name="btn_0"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="0"><bounds x="0.1" y="0.2" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_1"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="1"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="ACCA"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_2"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="2"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="ACCB"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_3"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="3"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="PC"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_4"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="4"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="INDEX"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_5"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="5"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="CC"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_6"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="6"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="SP"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_7"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="7"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="RTI"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_8"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="8"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="SS"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_9"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="9"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="BR"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_a"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="A"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="AUTO"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_b"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="B"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="BACK"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_c"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="C"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="CHAN"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_d"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="D"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="DO"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_e"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="E"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="EXAM"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_f"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="F"><bounds x="0.1" y="0.3" width="0.8" height="0.6" /><color red="1.0" green="1.0" blue="1.0" /></text> + <text string="FWD"><bounds x="0.1" y="0.1" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + <element name="btn_rst"> + <rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.1" green="0.1" blue="0.1" /></rect> + <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color red="0.2" green="0.2" blue="0.2" /></rect> + <rect><bounds x="0.1" y="0.1" width="0.8" height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect> + <text string="RESET"><bounds x="0.1" y="0.4" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text> + </element> + + <group name="displays"> + <cpanel element="surround"><bounds x="0" y="0" width="320" height="132" /></cpanel> + + <cpanel name="digit6" element="digit"><bounds x="16" y="16" width="48" height="80" /></cpanel> + <cpanel name="digit5" element="digit"><bounds x="64" y="16" width="48" height="80" /></cpanel> + <cpanel name="digit4" element="digit"><bounds x="112" y="16" width="48" height="80" /></cpanel> + <cpanel name="digit3" element="digit"><bounds x="160" y="16" width="48" height="80" /></cpanel> + <cpanel name="digit2" element="digit"><bounds x="208" y="16" width="48" height="80" /></cpanel> + <cpanel name="digit1" element="digit"><bounds x="256" y="16" width="48" height="80" /></cpanel> + + <cpanel element="label_h"><bounds x="48" y="100" width="16" height="16" /></cpanel> + <cpanel element="label_i"><bounds x="96" y="100" width="16" height="16" /></cpanel> + <cpanel element="label_n"><bounds x="144" y="100" width="16" height="16" /></cpanel> + <cpanel element="label_z"><bounds x="192" y="100" width="16" height="16" /></cpanel> + <cpanel element="label_v"><bounds x="240" y="100" width="16" height="16" /></cpanel> + <cpanel element="label_c"><bounds x="288" y="100" width="16" height="16" /></cpanel> + </group> + + <group name="keypad"> + <bounds x="0" y="0" width="3.5" height="6.5" /> + + <cpanel element="btn_d" inputtag="X0" inputmask="0x01"><bounds x="0.20" y="0.125" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_e" inputtag="X1" inputmask="0x01"><bounds x="1.25" y="0.125" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_f" inputtag="X2" inputmask="0x01"><bounds x="2.30" y="0.125" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_a" inputtag="X0" inputmask="0x02"><bounds x="0.20" y="1.175" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_b" inputtag="X1" inputmask="0x02"><bounds x="1.25" y="1.175" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_c" inputtag="X2" inputmask="0x02"><bounds x="2.30" y="1.175" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_7" inputtag="X0" inputmask="0x04"><bounds x="0.20" y="2.225" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_8" inputtag="X1" inputmask="0x04"><bounds x="1.25" y="2.225" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_9" inputtag="X2" inputmask="0x04"><bounds x="2.30" y="2.225" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_4" inputtag="X0" inputmask="0x08"><bounds x="0.20" y="3.275" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_5" inputtag="X1" inputmask="0x08"><bounds x="1.25" y="3.275" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_6" inputtag="X2" inputmask="0x08"><bounds x="2.30" y="3.275" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_1" inputtag="X0" inputmask="0x10"><bounds x="0.20" y="4.325" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_2" inputtag="X1" inputmask="0x10"><bounds x="1.25" y="4.325" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_3" inputtag="X2" inputmask="0x10"><bounds x="2.30" y="4.325" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_0" inputtag="X0" inputmask="0x20"><bounds x="0.725" y="5.375" width="1.0" height="1.0" /></cpanel> + <cpanel element="btn_rst" inputtag="RESET" inputmask="0x01"><bounds x="1.775" y="5.375" width="1.0" height="1.0" /></cpanel> + </group> + + <view name="LED Displays, Terminal and Keypad"> + <cpanel element="beige"><bounds x="320" y="0" width="172" height="372" /></cpanel> + <group ref="displays"><bounds x="0" y="0" width="320" height="132" /></group> + <group ref="keypad"><bounds x="336" y="16" width="140" height="260" /></group> + <screen index="0"><bounds x="0" y="132" width="320" height="240" /></screen> + </view> + + <view name="LED Displays and Terminal"> + <group ref="displays"><bounds x="0" y="0" width="320" height="132" /></group> + <screen index="0"><bounds x="0" y="132" width="320" height="240" /></screen> + </view> + + <view name="LED Displays and Keypad"> + <cpanel element="beige"><bounds x="0" y="0" width="320" height="424" /></cpanel> + <group ref="displays"><bounds x="0" y="0" width="320" height="132" /></group> + <group ref="keypad"><bounds x="164" y="148" width="140" height="260" /></group> + </view> + + <view name="LED Displays"> + <group ref="displays"><bounds x="0" y="0" width="320" height="132" /></group> </view> </mamelayout> diff --git a/src/mame/layout/fidel_desdis_68k.lay b/src/mame/layout/fidel_desdis_68k.lay new file mode 100644 index 00000000000..84b93b034fc --- /dev/null +++ b/src/mame/layout/fidel_desdis_68k.lay @@ -0,0 +1,459 @@ +<?xml version="1.0"?> +<mamelayout version="2"> + +<!-- define elements --> + + <element name="static_black"><rect><color red="0" green="0" blue="0" /></rect></element> + + <!-- our digit element is bright-on-dark, this means the lcd panel is the wrong colour here --> + + <element name="digit" defstate="0"> + <led7seg><color red="1.0" green="1.0" blue="1.0" /></led7seg> + </element> + <element name="ldot" defstate="0"> + <rect state="1"><color red="1.0" green="1.0" blue="1.0" /></rect> + <rect state="0"><color red="0.1" green="0.1" blue="0.1" /></rect> + </element> + + <element name="led" defstate="0"> + <disk state="1"><color red="1.0" green="0.1" blue="0.15" /></disk> + <disk state="0"><color red="0.1" green="0.01" blue="0.015" /></disk> + </element> + + <element name="hl" defstate="0"> + <text string=" "> + <bounds x="0.0" y="0.0" width="1.0" height="1.0" /> + <color red="0.0" green="0.0" blue="0.0" /> + </text> + <disk state="1"> + <bounds x="0.12" y="0.12" width="0.76" height="0.76" /> + <color red="1.0" green="1.0" blue="1.0" /> + </disk> + </element> + <element name="hlb" defstate="0"> + <text string=" "> + <bounds x="0.0" y="0.0" width="1.0" height="1.0" /> + <color red="0.0" green="0.0" blue="0.0" /> + </text> + <disk state="1"> + <bounds x="0.0" y="0.0" width="1.0" height="1.0" /> + <color red="1.0" green="1.0" blue="1.0" /> + </disk> + </element> + <element name="hlr" defstate="0"> + <text string=" "> + <bounds x="0" y="0" width="8" height="6" /> + <color red="0.0" green="0.0" blue="0.0" /> + </text> + <disk state="1"> + <bounds x="2" y="1" width="4" height="4" /> + <color red="1.0" green="1.0" blue="1.0" /> + </disk> + </element> + + <element name="black"><rect><color red="0.17" green="0.15" blue="0.15" /></rect></element> + <element name="white"><rect><color red="0.81" green="0.8" blue="0.79" /></rect></element> + <element name="redb"><rect><color red="0.81" green="0.3" blue="0.29" /></rect></element> + <element name="disk_black"><disk><color red="0.17" green="0.15" blue="0.15" /></disk></element> + <element name="disk_white"><disk><color red="0.81" green="0.8" blue="0.79" /></disk></element> + + <element name="text_1"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="1"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_2"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="2"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_3"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="3"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_4"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="4"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_5"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="5"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_6"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="6"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_7"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="7"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_8"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="8"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + + <element name="text_a"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="A"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_b"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="B"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_c"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="C"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_d"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="D"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_e"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="E"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_f"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="F"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_g"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="G"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_h"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="H"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + + <element name="text_white"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="WHITE"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_black"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="BLACK"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_clear"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="CLEAR"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_u1"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="VERIFY"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_u2"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="OPTION"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_u3"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="LEVEL"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_u4"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="TAKE BACK"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_u5"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="HINT"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + <element name="text_u6"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="MOVE"><color red="0.01" green="0.01" blue="0.01" /></text> + </element> + + <element name="text_shift"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="SHIFT"><color red="0.81" green="0.3" blue="0.29" /></text> + </element> + <element name="text_s1"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="PROBLEM"><color red="0.81" green="0.3" blue="0.29" /></text> + </element> + <element name="text_s2"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="TIME"><color red="0.81" green="0.3" blue="0.29" /></text> + </element> + <element name="text_s3"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="NEW"><color red="0.81" green="0.3" blue="0.29" /></text> + </element> + <element name="text_s4"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="REPLAY"><color red="0.81" green="0.3" blue="0.29" /></text> + </element> + <element name="text_s5"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="INFO"><color red="0.81" green="0.3" blue="0.29" /></text> + </element> + <element name="text_s6"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="ALTERNATE"><color red="0.81" green="0.3" blue="0.29" /></text> + </element> + + <element name="text_king"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="♚"><color red="0.17" green="0.15" blue="0.15" /></text> + </element> + <element name="text_queen"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="♛"><color red="0.17" green="0.15" blue="0.15" /></text> + </element> + <element name="text_rook"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="♜"><color red="0.17" green="0.15" blue="0.15" /></text> + </element> + <element name="text_bishop"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="♝"><color red="0.17" green="0.15" blue="0.15" /></text> + </element> + <element name="text_knight"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="♞"><color red="0.17" green="0.15" blue="0.15" /></text> + </element> + <element name="text_pawn"> + <rect><color red="0.81" green="0.8" blue="0.79" /></rect> + <text string="♟"><color red="0.17" green="0.15" blue="0.15" /></text> + </element> + + +<!-- build screen --> + + <view name="Internal Layout"> + <bounds left="-7" right="93" top="-2" bottom="103" /> + + <bezel element="white"><bounds x="-7.5" y="-2.5" width="101" height="106" /></bezel> + + <!-- chessboard coords --> + + <bezel element="text_8"><bounds x="-3.25" y="7" width="2" height="2" /></bezel> + <bezel element="text_7"><bounds x="-3.25" y="17" width="2" height="2" /></bezel> + <bezel element="text_6"><bounds x="-3.25" y="27" width="2" height="2" /></bezel> + <bezel element="text_5"><bounds x="-3.25" y="37" width="2" height="2" /></bezel> + <bezel element="text_4"><bounds x="-3.25" y="47" width="2" height="2" /></bezel> + <bezel element="text_3"><bounds x="-3.25" y="57" width="2" height="2" /></bezel> + <bezel element="text_2"><bounds x="-3.25" y="67" width="2" height="2" /></bezel> + <bezel element="text_1"><bounds x="-3.25" y="77" width="2" height="2" /></bezel> + + <bezel element="text_a"><bounds x="5" y="85" width="2" height="2" /></bezel> + <bezel element="text_b"><bounds x="15" y="85" width="2" height="2" /></bezel> + <bezel element="text_c"><bounds x="25" y="85" width="2" height="2" /></bezel> + <bezel element="text_d"><bounds x="35" y="85" width="2" height="2" /></bezel> + <bezel element="text_e"><bounds x="45" y="85" width="2" height="2" /></bezel> + <bezel element="text_f"><bounds x="55" y="85" width="2" height="2" /></bezel> + <bezel element="text_g"><bounds x="65" y="85" width="2" height="2" /></bezel> + <bezel element="text_h"><bounds x="75" y="85" width="2" height="2" /></bezel> + + <!-- chessboard leds --> + + <bezel name="0.7" element="led"><bounds x="-1" y="7.25" width="1.5" height="1.5" /></bezel> + <bezel name="0.6" element="led"><bounds x="-1" y="17.25" width="1.5" height="1.5" /></bezel> + <bezel name="0.5" element="led"><bounds x="-1" y="27.25" width="1.5" height="1.5" /></bezel> + <bezel name="0.4" element="led"><bounds x="-1" y="37.25" width="1.5" height="1.5" /></bezel> + <bezel name="0.3" element="led"><bounds x="-1" y="47.25" width="1.5" height="1.5" /></bezel> + <bezel name="0.2" element="led"><bounds x="-1" y="57.25" width="1.5" height="1.5" /></bezel> + <bezel name="0.1" element="led"><bounds x="-1" y="67.25" width="1.5" height="1.5" /></bezel> + <bezel name="0.0" element="led"><bounds x="-1" y="77.25" width="1.5" height="1.5" /></bezel> + + <bezel name="1.0" element="led"><bounds x="7.25" y="85.5" width="1.5" height="1.5" /></bezel> + <bezel name="1.1" element="led"><bounds x="17.25" y="85.5" width="1.5" height="1.5" /></bezel> + <bezel name="1.2" element="led"><bounds x="27.25" y="85.5" width="1.5" height="1.5" /></bezel> + <bezel name="1.3" element="led"><bounds x="37.25" y="85.5" width="1.5" height="1.5" /></bezel> + <bezel name="1.4" element="led"><bounds x="47.25" y="85.5" width="1.5" height="1.5" /></bezel> + <bezel name="1.5" element="led"><bounds x="57.25" y="85.5" width="1.5" height="1.5" /></bezel> + <bezel name="1.6" element="led"><bounds x="67.25" y="85.5" width="1.5" height="1.5" /></bezel> + <bezel name="1.7" element="led"><bounds x="77.25" y="85.5" width="1.5" height="1.5" /></bezel> + + <!-- chessboard bezel --> + + <bezel element="black"><bounds x="2" y="2" width="82" height="82" /></bezel> + <bezel element="white"><bounds x="3" y="3" width="80" height="80" /></bezel> + + <bezel element="black"><bounds x="13" y="2.5" width="10" height="10.5" /></bezel> + <bezel element="black"><bounds x="33" y="2.5" width="10" height="10.5" /></bezel> + <bezel element="black"><bounds x="53" y="2.5" width="10" height="10.5" /></bezel> + <bezel element="black"><bounds x="73" y="2.5" width="10.5" height="10.5" /></bezel> + + <bezel element="black"><bounds x="2.5" y="13" width="10.5" height="10" /></bezel> + <bezel element="black"><bounds x="23" y="13" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="43" y="13" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="63" y="13" width="10" height="10" /></bezel> + + <bezel element="black"><bounds x="13" y="23" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="33" y="23" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="53" y="23" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="73" y="23" width="10.5" height="10" /></bezel> + + <bezel element="black"><bounds x="2.5" y="33" width="10.5" height="10" /></bezel> + <bezel element="black"><bounds x="23" y="33" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="43" y="33" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="63" y="33" width="10" height="10" /></bezel> + + <bezel element="black"><bounds x="13" y="43" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="33" y="43" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="53" y="43" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="73" y="43" width="10.5" height="10" /></bezel> + + <bezel element="black"><bounds x="2.5" y="53" width="10.5" height="10" /></bezel> + <bezel element="black"><bounds x="23" y="53" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="43" y="53" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="63" y="53" width="10" height="10" /></bezel> + + <bezel element="black"><bounds x="13" y="63" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="33" y="63" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="53" y="63" width="10" height="10" /></bezel> + <bezel element="black"><bounds x="73" y="63" width="10.5" height="10" /></bezel> + + <bezel element="black"><bounds x="2.5" y="73" width="10.5" height="10.5" /></bezel> + <bezel element="black"><bounds x="23" y="73" width="10" height="10.5" /></bezel> + <bezel element="black"><bounds x="43" y="73" width="10" height="10.5" /></bezel> + <bezel element="black"><bounds x="63" y="73" width="10" height="10.5" /></bezel> + + <!-- chessboard sensors --> + + <bezel element="hl" inputtag="IN.0" inputmask="0x80"><bounds x="3" y="3" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.0" inputmask="0x40"><bounds x="13" y="3" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.0" inputmask="0x20"><bounds x="23" y="3" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.0" inputmask="0x10"><bounds x="33" y="3" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.0" inputmask="0x08"><bounds x="43" y="3" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.0" inputmask="0x04"><bounds x="53" y="3" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.0" inputmask="0x02"><bounds x="63" y="3" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.0" inputmask="0x01"><bounds x="73" y="3" width="10" height="10" /><color alpha="0.2" /></bezel> + + <bezel element="hl" inputtag="IN.1" inputmask="0x80"><bounds x="3" y="13" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.1" inputmask="0x40"><bounds x="13" y="13" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.1" inputmask="0x20"><bounds x="23" y="13" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.1" inputmask="0x10"><bounds x="33" y="13" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.1" inputmask="0x08"><bounds x="43" y="13" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.1" inputmask="0x04"><bounds x="53" y="13" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.1" inputmask="0x02"><bounds x="63" y="13" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.1" inputmask="0x01"><bounds x="73" y="13" width="10" height="10" /><color alpha="0.4" /></bezel> + + <bezel element="hl" inputtag="IN.2" inputmask="0x80"><bounds x="3" y="23" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.2" inputmask="0x40"><bounds x="13" y="23" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.2" inputmask="0x20"><bounds x="23" y="23" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.2" inputmask="0x10"><bounds x="33" y="23" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.2" inputmask="0x08"><bounds x="43" y="23" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.2" inputmask="0x04"><bounds x="53" y="23" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.2" inputmask="0x02"><bounds x="63" y="23" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.2" inputmask="0x01"><bounds x="73" y="23" width="10" height="10" /><color alpha="0.2" /></bezel> + + <bezel element="hl" inputtag="IN.3" inputmask="0x80"><bounds x="3" y="33" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.3" inputmask="0x40"><bounds x="13" y="33" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.3" inputmask="0x20"><bounds x="23" y="33" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.3" inputmask="0x10"><bounds x="33" y="33" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.3" inputmask="0x08"><bounds x="43" y="33" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.3" inputmask="0x04"><bounds x="53" y="33" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.3" inputmask="0x02"><bounds x="63" y="33" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.3" inputmask="0x01"><bounds x="73" y="33" width="10" height="10" /><color alpha="0.4" /></bezel> + + <bezel element="hl" inputtag="IN.4" inputmask="0x80"><bounds x="3" y="43" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.4" inputmask="0x40"><bounds x="13" y="43" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.4" inputmask="0x20"><bounds x="23" y="43" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.4" inputmask="0x10"><bounds x="33" y="43" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.4" inputmask="0x08"><bounds x="43" y="43" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.4" inputmask="0x04"><bounds x="53" y="43" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.4" inputmask="0x02"><bounds x="63" y="43" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.4" inputmask="0x01"><bounds x="73" y="43" width="10" height="10" /><color alpha="0.2" /></bezel> + + <bezel element="hl" inputtag="IN.5" inputmask="0x80"><bounds x="3" y="53" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.5" inputmask="0x40"><bounds x="13" y="53" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.5" inputmask="0x20"><bounds x="23" y="53" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.5" inputmask="0x10"><bounds x="33" y="53" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.5" inputmask="0x08"><bounds x="43" y="53" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.5" inputmask="0x04"><bounds x="53" y="53" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.5" inputmask="0x02"><bounds x="63" y="53" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.5" inputmask="0x01"><bounds x="73" y="53" width="10" height="10" /><color alpha="0.4" /></bezel> + + <bezel element="hl" inputtag="IN.6" inputmask="0x80"><bounds x="3" y="63" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.6" inputmask="0x40"><bounds x="13" y="63" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.6" inputmask="0x20"><bounds x="23" y="63" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.6" inputmask="0x10"><bounds x="33" y="63" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.6" inputmask="0x08"><bounds x="43" y="63" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.6" inputmask="0x04"><bounds x="53" y="63" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.6" inputmask="0x02"><bounds x="63" y="63" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.6" inputmask="0x01"><bounds x="73" y="63" width="10" height="10" /><color alpha="0.2" /></bezel> + + <bezel element="hl" inputtag="IN.7" inputmask="0x80"><bounds x="3" y="73" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.7" inputmask="0x40"><bounds x="13" y="73" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.7" inputmask="0x20"><bounds x="23" y="73" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.7" inputmask="0x10"><bounds x="33" y="73" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.7" inputmask="0x08"><bounds x="43" y="73" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.7" inputmask="0x04"><bounds x="53" y="73" width="10" height="10" /><color alpha="0.4" /></bezel> + <bezel element="hl" inputtag="IN.7" inputmask="0x02"><bounds x="63" y="73" width="10" height="10" /><color alpha="0.2" /></bezel> + <bezel element="hl" inputtag="IN.7" inputmask="0x01"><bounds x="73" y="73" width="10" height="10" /><color alpha="0.4" /></bezel> + + <!-- bottom side --> + + <bezel element="text_white"><bounds x="33" y="87.5" width="10" height="2" /></bezel> + <bezel element="text_black"><bounds x="43" y="87.5" width="10" height="2" /></bezel> + + <bezel element="text_s1"><bounds x="3" y="89.7" width="10" height="1.8" /></bezel> + <bezel element="text_s2"><bounds x="12" y="89.7" width="10" height="1.8" /></bezel> + <bezel element="text_s3"><bounds x="21" y="89.7" width="10" height="1.8" /></bezel> + <bezel element="text_s4"><bounds x="55" y="89.7" width="10" height="1.8" /></bezel> + <bezel element="text_s5"><bounds x="64" y="89.7" width="10" height="1.8" /></bezel> + <bezel element="text_s6"><bounds x="73" y="89.7" width="10" height="1.8" /></bezel> + + <bezel element="text_u1"><bounds x="3" y="96.3" width="10" height="1.8" /></bezel> + <bezel element="text_u2"><bounds x="12" y="96.3" width="10" height="1.8" /></bezel> + <bezel element="text_u3"><bounds x="21" y="96.3" width="10" height="1.8" /></bezel> + <bezel element="text_u4"><bounds x="55" y="96.3" width="10" height="1.8" /></bezel> + <bezel element="text_u5"><bounds x="64" y="96.3" width="10" height="1.8" /></bezel> + <bezel element="text_u6"><bounds x="73" y="96.3" width="10" height="1.8" /></bezel> + + <bezel element="text_king"><bounds x="3" y="98" width="10" height="4" /></bezel> + <bezel element="text_queen"><bounds x="12" y="98" width="10" height="4" /></bezel> + <bezel element="text_rook"><bounds x="21" y="98" width="10" height="4" /></bezel> + <bezel element="text_bishop"><bounds x="55" y="98" width="10" height="4" /></bezel> + <bezel element="text_knight"><bounds x="64" y="98" width="10" height="4" /></bezel> + <bezel element="text_pawn"><bounds x="73" y="98" width="10" height="4" /></bezel> + + <bezel element="disk_black"><bounds x="6" y="92" width="4" height="4" /></bezel> + <bezel element="disk_black"><bounds x="15" y="92" width="4" height="4" /></bezel> + <bezel element="disk_black"><bounds x="24" y="92" width="4" height="4" /></bezel> + <bezel element="disk_black"><bounds x="58" y="92" width="4" height="4" /></bezel> + <bezel element="disk_black"><bounds x="67" y="92" width="4" height="4" /></bezel> + <bezel element="disk_black"><bounds x="76" y="92" width="4" height="4" /></bezel> + + <bezel element="disk_white"><bounds x="6.5" y="92.5" width="3" height="3" /></bezel> + <bezel element="disk_white"><bounds x="15.5" y="92.5" width="3" height="3" /></bezel> + <bezel element="disk_white"><bounds x="24.5" y="92.5" width="3" height="3" /></bezel> + <bezel element="disk_white"><bounds x="58.5" y="92.5" width="3" height="3" /></bezel> + <bezel element="disk_white"><bounds x="67.5" y="92.5" width="3" height="3" /></bezel> + <bezel element="disk_white"><bounds x="76.5" y="92.5" width="3" height="3" /></bezel> + + <bezel element="hlb" inputtag="IN.8" inputmask="0x40"><bounds x="6" y="92" width="4" height="4" /><color alpha="0.3" /></bezel> + <bezel element="hlb" inputtag="IN.8" inputmask="0x20"><bounds x="15" y="92" width="4" height="4" /><color alpha="0.3" /></bezel> + <bezel element="hlb" inputtag="IN.8" inputmask="0x10"><bounds x="24" y="92" width="4" height="4" /><color alpha="0.3" /></bezel> + <bezel element="hlb" inputtag="IN.8" inputmask="0x08"><bounds x="58" y="92" width="4" height="4" /><color alpha="0.3" /></bezel> + <bezel element="hlb" inputtag="IN.8" inputmask="0x04"><bounds x="67" y="92" width="4" height="4" /><color alpha="0.3" /></bezel> + <bezel element="hlb" inputtag="IN.8" inputmask="0x02"><bounds x="76" y="92" width="4" height="4" /><color alpha="0.3" /></bezel> + + <bezel element="redb"><bounds x="-5" y="91" width="8" height="6" /></bezel> + <bezel element="white"><bounds x="-4.25" y="91.75" width="6.5" height="4.5" /></bezel> + <bezel element="text_shift"><bounds x="-4" y="93" width="6" height="2" /></bezel> + <bezel name="1.8" element="led"><bounds x="0.65" y="94.65" width="1.5" height="1.5" /></bezel> + <bezel element="hlr" inputtag="IN.8" inputmask="0x80"><bounds x="-5" y="91" width="8" height="6" /><color alpha="0.3" /></bezel> + + <bezel element="black"><bounds x="83" y="91" width="8" height="6" /></bezel> + <bezel element="white"><bounds x="83.75" y="91.75" width="6.5" height="4.5" /></bezel> + <bezel element="text_clear"><bounds x="84" y="93" width="6" height="2" /></bezel> + <bezel element="hlr" inputtag="IN.8" inputmask="0x01"><bounds x="83" y="91" width="8" height="6" /><color alpha="0.3" /></bezel> + + <!-- lcd panel --> + + <bezel element="static_black"><bounds x="30.5" y="90" width="25" height="8" /></bezel> + + <bezel name="digit2" element="digit"><bounds x="32" y="91" width="4" height="6" /></bezel> + <bezel name="digit3" element="digit"><bounds x="38" y="91" width="4" height="6" /></bezel> + <bezel name="digit4" element="digit"><bounds x="44" y="91" width="4" height="6" /></bezel> + <bezel name="digit5" element="digit"><bounds x="50" y="91" width="4" height="6" /></bezel> + + <bezel name="2.7" element="ldot"><bounds x="36.5" y="96.5" width="0.6" height="0.6" /></bezel> + <bezel name="3.7" element="ldot"><bounds x="42.5" y="96.5" width="0.6" height="0.6" /></bezel> + <bezel name="4.7" element="ldot"><bounds x="48.5" y="96.5" width="0.6" height="0.6" /></bezel> + + <bezel name="5.7" element="ldot"><bounds x="42.9" y="92.8" width="0.6" height="0.6" /></bezel> + <bezel name="5.7" element="ldot"><bounds x="42.7" y="94.65" width="0.6" height="0.6" /></bezel> + + </view> +</mamelayout> diff --git a/src/mame/machine/3do.cpp b/src/mame/machine/3do.cpp index 62d245151ef..f2f35b21034 100644 --- a/src/mame/machine/3do.cpp +++ b/src/mame/machine/3do.cpp @@ -121,7 +121,7 @@ void _3do_state::m_3do_request_fiq(uint32_t irq_req, uint8_t type) if((m_clio.irq0 & m_clio.irq0_enable) || (m_clio.irq1 & m_clio.irq1_enable)) { //printf("Go irq %08x & %08x %08x & %08x\n",m_clio.irq0, m_clio.irq0_enable, m_clio.irq1, m_clio.irq1_enable); - generic_pulse_irq_line(*m_maincpu, ARM7_FIRQ_LINE, 1); + m_maincpu->pulse_input_line(ARM7_FIRQ_LINE, m_maincpu->minimum_quantum_time()); } } diff --git a/src/mame/machine/apollo.cpp b/src/mame/machine/apollo.cpp index 61a635e0f1e..d13aa342fc2 100644 --- a/src/mame/machine/apollo.cpp +++ b/src/mame/machine/apollo.cpp @@ -713,9 +713,8 @@ TIMER_CALLBACK_MEMBER( apollo_state::apollo_rtc_timer ) #define VERBOSE 0 apollo_sio::apollo_sio(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - mc68681_base_device(mconfig, APOLLO_SIO, tag, owner, clock), - m_csrb(0), - m_ip6(0) + duart_base_device(mconfig, APOLLO_SIO, tag, owner, clock), + m_csrb(0) { } @@ -728,10 +727,7 @@ void apollo_sio::device_reset() ip3_w((input_data & 0x08) ? ASSERT_LINE : CLEAR_LINE); ip4_w((input_data & 0x10) ? ASSERT_LINE : CLEAR_LINE); ip5_w((input_data & 0x20) ? ASSERT_LINE : CLEAR_LINE); -// ip6_w((input_data & 0x40) ? ASSERT_LINE : CLEAR_LINE); - - // MC2681 has IP[6] (instead of /IACK on MC68681) - m_ip6 = (input_data & 0x40) ? ASSERT_LINE : CLEAR_LINE; + ip6_w((input_data & 0x40) ? ASSERT_LINE : CLEAR_LINE); } READ8_MEMBER( apollo_sio::read ) @@ -744,7 +740,7 @@ READ8_MEMBER( apollo_sio::read ) "1X/16X Test", "RHRB", "IVR", "Input Ports", "Start Counter", "Stop Counter" }; - int data = mc68681_base_device::read(space, offset/2, mem_mask); + int data = duart_base_device::read(space, offset/2, mem_mask); switch (offset / 2) { @@ -761,10 +757,6 @@ READ8_MEMBER( apollo_sio::read ) data = 0xff; } break; - case 0x0d: /* IP */ - // MC2681 has IP[6] (instead of /IACK on MC68681) - data = (data & ~0x40) | (m_ip6 ? 0x40 : 0); - break; } // omit logging if sio is being polled from the boot rom @@ -804,11 +796,11 @@ WRITE8_MEMBER( apollo_sio::write ) break; #endif } - mc68681_base_device::write(space, offset/2, data, mem_mask); + duart_base_device::write(space, offset/2, data, mem_mask); } // device type definition -DEFINE_DEVICE_TYPE(APOLLO_SIO, apollo_sio, "apollo_sio", "DN3000/DS3500 SIO") +DEFINE_DEVICE_TYPE(APOLLO_SIO, apollo_sio, "apollo_sio", "DN3000/DS3500 SIO (MC2681)") WRITE_LINE_MEMBER(apollo_state::sio_irq_handler) { diff --git a/src/mame/machine/apollo_dbg.cpp b/src/mame/machine/apollo_dbg.cpp index 63b05d162c5..208a563b7c3 100644 --- a/src/mame/machine/apollo_dbg.cpp +++ b/src/mame/machine/apollo_dbg.cpp @@ -11,6 +11,7 @@ #define VERBOSE 1 #include "emu.h" +#include "debug/debugbuf.h" #include "includes/apollo.h" #include "cpu/m68000/m68kcpu.h" @@ -1034,11 +1035,10 @@ static const char* get_svc_call(m68000_base_device *m68k, int trap_no, return sb; } +// WTF? static const std::string &disassemble(m68000_base_device *m68k, offs_t pc, std::string& sb) { - uint8_t oprom[10]; - uint8_t opram[10]; - uint32_t options = 0; + debug_disasm_buffer buffer(*m68k); // remember bus error state uint32_t tmp_buserror_occurred = m68k->mmu_tmp_buserror_occurred; @@ -1047,25 +1047,9 @@ static const std::string &disassemble(m68000_base_device *m68k, offs_t pc, std:: m68k->mmu_tmp_buserror_occurred = 0; m68k->mmu_tmp_rw = 1; - int i; - for (i = 0; i < sizeof(oprom); i++) - { - oprom[i] = opram[i] = m68k->read8(pc + i); - if (m68k->mmu_tmp_buserror_occurred) - { - sb = string_format("- (apollo_disassemble failed at %08x)", pc + i); - - // restore previous bus error state - m68k->mmu_tmp_buserror_occurred = tmp_buserror_occurred; - m68k->mmu_tmp_buserror_address = tmp_buserror_address; - - return sb; - } - } - - std::ostringstream stream; - m68k->disassemble(stream, pc, oprom, opram, options); - sb = stream.str(); + offs_t next_pc, size; + u32 info; + buffer.disassemble(pc, sb, next_pc, size, info); // restore previous bus error state m68k->mmu_tmp_buserror_occurred = tmp_buserror_occurred; diff --git a/src/mame/machine/archimds.cpp b/src/mame/machine/archimds.cpp index a2f610b4af5..8868f485f1a 100644 --- a/src/mame/machine/archimds.cpp +++ b/src/mame/machine/archimds.cpp @@ -67,7 +67,7 @@ void archimedes_state::archimedes_request_fiq(int mask) if (m_ioc_regs[FIQ_STATUS] & m_ioc_regs[FIQ_MASK]) { - generic_pulse_irq_line(*m_maincpu, ARM_FIRQ_LINE, 1); + m_maincpu->pulse_input_line(ARM_FIRQ_LINE, m_maincpu->minimum_quantum_time()); //m_maincpu->set_input_line(ARM_FIRQ_LINE, CLEAR_LINE); //m_maincpu->set_input_line(ARM_FIRQ_LINE, ASSERT_LINE); diff --git a/src/mame/machine/bbc.cpp b/src/mame/machine/bbc.cpp index ab69a413c34..6a99a712bb2 100644 --- a/src/mame/machine/bbc.cpp +++ b/src/mame/machine/bbc.cpp @@ -346,6 +346,9 @@ WRITE8_MEMBER(bbc_state::page_selectbm_w) m_pagedRAM = (data & 0x80) >> 7; m_rombank = data & 0x0f; + if (m_lk19_ic37_paged_rom && (m_rombank == 4 || m_rombank == 5)) m_pagedRAM = 0; + if (m_lk18_ic41_paged_rom && (m_rombank == 6 || m_rombank == 7)) m_pagedRAM = 0; + if (m_pagedRAM) { m_bank4->set_entry(0x10); @@ -359,14 +362,12 @@ WRITE8_MEMBER(bbc_state::page_selectbm_w) } - WRITE8_MEMBER(bbc_state::bbc_memorybm1_w) { m_region_maincpu->base()[offset] = data; } - WRITE8_MEMBER(bbc_state::bbc_memorybm2_w) { uint8_t *RAM = m_region_maincpu->base(); @@ -387,11 +388,6 @@ WRITE8_MEMBER(bbc_state::bbc_memorybm2_w) } } -static const unsigned short bbc_master_sideways_ram_banks[16]= -{ - 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0 -}; - WRITE8_MEMBER(bbc_state::bbc_memorybm4_w) { @@ -401,7 +397,7 @@ WRITE8_MEMBER(bbc_state::bbc_memorybm4_w) } else { - if (bbc_master_sideways_ram_banks[m_rombank]) + if ((!m_lk18_ic41_paged_rom && (m_rombank == 6 || m_rombank == 7)) || (!m_lk19_ic37_paged_rom && (m_rombank == 4 || m_rombank == 5))) { m_region_opt->base()[offset+(m_rombank<<14)] = data; } @@ -411,9 +407,9 @@ WRITE8_MEMBER(bbc_state::bbc_memorybm4_w) WRITE8_MEMBER(bbc_state::bbc_memorybm5_w) { - if (bbc_master_sideways_ram_banks[m_rombank]) + if ((!m_lk18_ic41_paged_rom && (m_rombank == 6 || m_rombank == 7)) || (!m_lk19_ic37_paged_rom && (m_rombank == 4 || m_rombank == 5))) { - m_region_opt->base()[offset+(m_rombank<<14)+0x1000] = data; + m_region_opt->base()[offset+(m_rombank<<14) + 0x1000] = data; } } @@ -488,8 +484,7 @@ READ8_MEMBER(bbc_state::bbcm_r) myo = offset-0x200; if ((myo>=0x00) && (myo<=0x06) && (myo+0x01) & 1) return m_hd6845->status_r(space, myo-0x00); /* Video controller */ if ((myo>=0x01) && (myo<=0x07) && (myo & 1)) return m_hd6845->register_r(space, myo-0x01); - if ((myo>=0x08) && (myo<=0x0e) && (myo+0x01) & 1) return m_acia ? m_acia->status_r(space, myo-0x08) : 0xfe; /* Serial controller */ - if ((myo>=0x09) && (myo<=0x0f) && (myo & 1)) return m_acia ? m_acia->data_r(space, myo-0x09) : 0xfe; + if ((myo>=0x08) && (myo<=0x0f)) return m_acia ? m_acia->read(space, myo & 0x01) : 0xfe; /* Serial controller */ if ((myo>=0x10) && (myo<=0x17)) return 0xfe; /* Serial System Chip */ if ((myo>=0x18) && (myo<=0x1f)) return m_upd7002 ? m_upd7002->read(space, myo-0x18) : 0xfe; /* A to D converter */ if ((myo>=0x20) && (myo<=0x23)) return 0xfe; /* VideoULA */ @@ -505,7 +500,11 @@ READ8_MEMBER(bbc_state::bbcm_r) if ((myo>=0x80) && (myo<=0x9f)) return 0xfe; if ((myo>=0xa0) && (myo<=0xbf)) return m_adlc ? m_adlc->read(space, myo & 0x03) : 0xfe; if ((myo>=0xc0) && (myo<=0xdf)) return 0xff; - if ((myo>=0xe0) && (myo<=0xff)) return m_intube ? m_intube->host_r(space, myo-0xe0) : 0xff; + if ((myo>=0xe0) && (myo<=0xff)) + { + if (m_intube && m_ACCCON_ITU) return m_intube->host_r(space, myo-0xe0); /* Internal TUBE */ + if (m_extube && !m_ACCCON_ITU) return m_extube->host_r(space, myo-0xe0); /* External TUBE */ + } } return 0xfe; } @@ -519,8 +518,7 @@ WRITE8_MEMBER(bbc_state::bbcm_w) myo=offset-0x200; if ((myo>=0x00) && (myo<=0x06) && (myo+0x01) & 1) m_hd6845->address_w(space, myo-0x00, data); /* Video Controller */ if ((myo>=0x01) && (myo<=0x07) && (myo & 1)) m_hd6845->register_w(space, myo-0x01, data); - if ((myo>=0x08) && (myo<=0x0e) && (myo+0x01) & 1) if (m_acia) m_acia->control_w(space, myo-0x08, data); /* Serial controller */ - if ((myo>=0x09) && (myo<=0x0f) && (myo & 1)) if (m_acia) m_acia->data_w(space, myo-0x09, data); + if ((myo>=0x08) && (myo<=0x0f)) if (m_acia) m_acia->write(space, myo & 0x01, data); /* Serial controller */ if ((myo>=0x10) && (myo<=0x17)) bbc_SerialULA_w(space, myo-0x10, data); /* Serial System Chip */ if ((myo>=0x18) && (myo<=0x1f) && (m_upd7002)) m_upd7002->write(space, myo-0x18, data); /* A to D converter */ if ((myo>=0x20) && (myo<=0x23)) bbc_videoULA_w(space, myo-0x20, data); /* VideoULA */ @@ -536,7 +534,11 @@ WRITE8_MEMBER(bbc_state::bbcm_w) //if ((myo>=0x80) && (myo<=0x9f)) if ((myo>=0xa0) && (myo<=0xbf) && (m_adlc)) m_adlc->write(space, myo & 0x03, data); //if ((myo>=0xc0) && (myo<=0xdf)) - if ((myo>=0xe0) && (myo<=0xff) && (m_intube)) m_intube->host_w(space, myo-0xe0, data); + if ((myo>=0xe0) && (myo<=0xff)) + { + if (m_intube && m_ACCCON_ITU) m_intube->host_w(space, myo-0xe0, data); /* Internal TUBE */ + if (m_extube && !m_ACCCON_ITU) m_extube->host_w(space, myo-0xe0, data); /* External TUBE */ + } } } @@ -1759,6 +1761,9 @@ MACHINE_START_MEMBER(bbc_state, bbcm) m_machinetype = MASTER; m_mc6850_clock = 0; + m_lk18_ic41_paged_rom = false; /* Link set for RAM in slots 6 and 7 */ + m_lk19_ic37_paged_rom = false; /* Link set for RAM in slots 4 and 5 */ + bbcm_setup_banks(m_bank4, 16, 0, 0x1000); m_bank4->configure_entries(16, 1, m_region_maincpu->base() + 0x8000, 0x1000); // additional bank for paged ram bbcm_setup_banks(m_bank5, 16, 0x1000, 0x3000); @@ -1816,3 +1821,12 @@ MACHINE_RESET_MEMBER(bbc_state, ltmpm) m_Speech = 0; m_SWRAMtype = 0; } + + +MACHINE_START_MEMBER(bbc_state, cfa3000) +{ + MACHINE_START_CALL_MEMBER(bbcm); + + m_lk18_ic41_paged_rom = true; /* Link set for ROM in slots 6 and 7 */ + m_lk19_ic37_paged_rom = true; /* Link set for ROM in slots 4 and 5 */ +} diff --git a/src/mame/machine/c117.cpp b/src/mame/machine/c117.cpp index 421974254a3..94576cf9832 100644 --- a/src/mame/machine/c117.cpp +++ b/src/mame/machine/c117.cpp @@ -79,8 +79,8 @@ void namco_c117_device::device_start() m_cpuexec[0] = maincpu; m_cpuexec[1] = subcpu; - m_cpudirect[0] = &maincpu->space(AS_PROGRAM).direct(); - m_cpudirect[1] = &subcpu->space(AS_PROGRAM).direct(); + m_cpudirect[0] = maincpu->space(AS_PROGRAM).direct<0>(); + m_cpudirect[1] = subcpu->space(AS_PROGRAM).direct<0>(); memset(&m_offsets, 0, sizeof(m_offsets)); m_subres = m_wdog = 0; diff --git a/src/mame/machine/c117.h b/src/mame/machine/c117.h index cd35155823c..0e26b8aba0d 100644 --- a/src/mame/machine/c117.h +++ b/src/mame/machine/c117.h @@ -74,7 +74,7 @@ private: // cpu interfaces device_execute_interface * m_cpuexec[2]; - direct_read_data * m_cpudirect[2]; + direct_read_data<0> * m_cpudirect[2]; // configuration const char * m_maincpu_tag; diff --git a/src/mame/machine/cammu.cpp b/src/mame/machine/cammu.cpp index 4e1d86b2076..5686cfa7d2e 100644 --- a/src/mame/machine/cammu.cpp +++ b/src/mame/machine/cammu.cpp @@ -2,28 +2,43 @@ // copyright-holders:Patrick Mackinlay /* - * An implementation of the Fairchild/Intergraph Cache and Memory Management Unit (CAMMU) designed for use with the CLIPPER CPU family. + * An implementation of the Fairchild/Intergraph Cache and Memory Management + * Unit (CAMMU) designed for use with the CLIPPER CPU family. * - * Primary reference: http://bitsavers.trailing-edge.com/pdf/fairchild/clipper/CLIPPER%20C300%2032-Bit%20Compute%20Engine.pdf - * Another reference: http://www.eecs.berkeley.edu/Pubs/TechRpts/1986/CSD-86-289.pdf + * The C100 and C300 designs used a pair of identical CAMMU devices, each + * containing a cache, TLB and dynamic translation unit. One device was + * configured and used for instruction memory, the other for data. It is + * possible to write to multiple CAMMU devices sharing a common system bus by + * using "global" register addresses. + * + * C400 designs initially implemented the memory management and cache functions + * using discrete logic, later using a more highly integrated memory management + * implementation, but still using discrete cache memory. In these systems, the + * mmu is consolidated into a single logical unit handling both instruction and + * data memory, with distinctly different program-visible architectures on the + * C4I and C4E/T devices. Almost no documentation for these has been located. * - * This implementation is currently at a very early stage, and is only sufficient to handle the bare minimum of boot/diagnostic code. + * Primary reference: http://bitsavers.org/pdf/fairchild/clipper/CLIPPER%20C300%2032-Bit%20Compute%20Engine.pdf + * Another reference: http://www.eecs.berkeley.edu/Pubs/TechRpts/1986/CSD-86-289.pdf * * TODO - * - almost everything - * - refactor hardware tlb - * - faults - * - tlb + * - fault register values + * - alignment faults + * - c3 protection faults + * - hard-wired and dynamic tlb * - cache * - bus errors */ #include "emu.h" +#include "cammu.h" -#define VERBOSE 0 -#define DTU 1 // enable preliminary/incomplete address translation +#define LOG_GENERAL (1U << 0) +#define LOG_ACCESS (1U << 1) +#define LOG_DTU (1U << 2) -#include "cammu.h" +//#define VERBOSE (LOG_GENERAL | LOG_ACCESS | LOG_DTU) +#include "logmacro.h" // each variant of the cammu has different registers and a different addressing map DEVICE_ADDRESS_MAP_START(map, 32, cammu_c4t_device) @@ -75,28 +90,21 @@ DEVICE_ADDRESS_MAP_START(map, 32, cammu_c4i_device) ADDRESS_MAP_END DEVICE_ADDRESS_MAP_START(map, 32, cammu_c3_device) - // the first AM_NOP in each range is in fact the TLB in the C3 CAMMU - - AM_RANGE(0x800, 0x8ff) AM_NOP - AM_RANGE(0x904, 0x907) AM_READWRITE(d_s_pdo_r, d_s_pdo_w) - AM_RANGE(0x908, 0x90b) AM_READWRITE(d_u_pdo_r, d_u_pdo_w) - AM_RANGE(0x910, 0x913) AM_READWRITE(d_fault_r, d_fault_w) - AM_RANGE(0x940, 0x943) AM_READWRITE(d_control_r, d_control_w) - AM_RANGE(0x980, 0x983) AM_READWRITE(d_reset_r, d_reset_w) - - AM_RANGE(0xa00, 0xaff) AM_NOP - AM_RANGE(0xb04, 0xb07) AM_READWRITE(i_s_pdo_r, i_s_pdo_w) - AM_RANGE(0xb08, 0xb0b) AM_READWRITE(i_u_pdo_r, i_u_pdo_w) - AM_RANGE(0xb10, 0xb13) AM_READWRITE(i_fault_r, i_fault_w) - AM_RANGE(0xb40, 0xb43) AM_READWRITE(i_control_r, i_control_w) - AM_RANGE(0xb80, 0xb83) AM_READWRITE(i_reset_r, i_reset_w) - - AM_RANGE(0xc00, 0xcff) AM_NOP - AM_RANGE(0xd04, 0xd07) AM_WRITE(g_s_pdo_w) - AM_RANGE(0xd08, 0xd0b) AM_WRITE(g_u_pdo_w) - AM_RANGE(0xd10, 0xd13) AM_WRITE(g_fault_w) - AM_RANGE(0xd40, 0xd43) AM_WRITE(g_control_w) - AM_RANGE(0xd80, 0xd83) AM_WRITE(g_reset_w) + AM_RANGE(0x000, 0x0ff) AM_NOP // tlb + AM_RANGE(0x104, 0x107) AM_READWRITE(s_pdo_r, s_pdo_w) + AM_RANGE(0x108, 0x10b) AM_READWRITE(u_pdo_r, u_pdo_w) + AM_RANGE(0x110, 0x113) AM_READWRITE(fault_r, fault_w) + AM_RANGE(0x140, 0x143) AM_READWRITE(control_r, control_w) + AM_RANGE(0x180, 0x183) AM_READWRITE(reset_r, reset_w) +ADDRESS_MAP_END + +DEVICE_ADDRESS_MAP_START(map_global, 32, cammu_c3_device) + AM_RANGE(0x000, 0x0ff) AM_NOP // global tlb + AM_RANGE(0x104, 0x107) AM_WRITE(g_s_pdo_w) + AM_RANGE(0x108, 0x10b) AM_WRITE(g_u_pdo_w) + AM_RANGE(0x110, 0x113) AM_WRITE(g_fault_w) + AM_RANGE(0x140, 0x143) AM_WRITE(g_control_w) + AM_RANGE(0x180, 0x183) AM_WRITE(g_reset_w) ADDRESS_MAP_END DEFINE_DEVICE_TYPE(CAMMU_C4T, cammu_c4t_device, "c4t", "C4E/C4T CAMMU") @@ -104,41 +112,62 @@ DEFINE_DEVICE_TYPE(CAMMU_C4I, cammu_c4i_device, "c4i", "C4I CAMMU") DEFINE_DEVICE_TYPE(CAMMU_C3, cammu_c3_device, "c3", "C1/C3 CAMMU") cammu_c4t_device::cammu_c4t_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : cammu_c4_device(mconfig, CAMMU_C4T, tag, owner, clock) + : cammu_c4_device(mconfig, CAMMU_C4T, tag, owner, clock, CID_C4T) { } cammu_c4i_device::cammu_c4i_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : cammu_c4_device(mconfig, CAMMU_C4I, tag, owner, clock) + : cammu_c4_device(mconfig, CAMMU_C4I, tag, owner, clock, CID_C4I) { } -cammu_c4_device::cammu_c4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +cammu_c4_device::cammu_c4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, u32 cammu_id) : cammu_device(mconfig, type, tag, owner, clock) + , m_control(cammu_id) { } cammu_c3_device::cammu_c3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : cammu_device(mconfig, CAMMU_C3, tag, owner, clock) + , m_control(CID_C3) + , m_linked{ this } { } cammu_device::cammu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) - , device_memory_interface(mconfig, *this), - m_main_space_config("main", ENDIANNESS_LITTLE, 32, 32, 0), - m_io_space_config("io", ENDIANNESS_LITTLE, 32, 32, 0), - m_boot_space_config("boot", ENDIANNESS_LITTLE, 32, 32, 0), - m_main_space(nullptr), - m_io_space(nullptr), - m_boot_space(nullptr), - m_ssw_func(*this) + , device_memory_interface(mconfig, *this) + , m_main_space_config("main", ENDIANNESS_LITTLE, 32, 32, 0) + , m_io_space_config("io", ENDIANNESS_LITTLE, 32, 32, 0) + , m_boot_space_config("boot", ENDIANNESS_LITTLE, 32, 32, 0) + , m_main_space(nullptr) + , m_io_space(nullptr) + , m_boot_space(nullptr) + , m_ssw_func(*this) + , m_exception_func(*this) +{ +} + +device_memory_interface::space_config_vector cammu_device::memory_space_config() const { + return space_config_vector { + std::make_pair(0, &m_main_space_config), + std::make_pair(1, &m_io_space_config), + std::make_pair(2, &m_boot_space_config) + }; +} + +void cammu_c3_device::static_add_linked(device_t &device, const char *const tag) +{ + cammu_c3_device &parent = downcast<cammu_c3_device &>(device); + + parent.m_linked.push_back(downcast<cammu_c3_device *>(parent.siblingdevice(tag))); } void cammu_device::device_start() { m_ssw_func.resolve(); + m_exception_func.resolve(); m_main_space = &space(0); m_io_space = &space(1); @@ -149,268 +178,321 @@ void cammu_device::device_reset() { } -device_memory_interface::space_config_vector cammu_device::memory_space_config() const +void cammu_c4_device::device_start() { - return space_config_vector { - std::make_pair(0, &m_main_space_config), - std::make_pair(1, &m_io_space_config), - std::make_pair(2, &m_boot_space_config) - }; + cammu_device::device_start(); + + save_item(NAME(m_s_pdo)); + save_item(NAME(m_u_pdo)); + save_item(NAME(m_control)); + + save_item(NAME(m_i_fault)); + save_item(NAME(m_fault_address_1)); + save_item(NAME(m_fault_address_2)); + save_item(NAME(m_fault_data_1_lo)); + save_item(NAME(m_fault_data_1_hi)); + save_item(NAME(m_fault_data_2_lo)); + save_item(NAME(m_fault_data_2_hi)); } -READ32_MEMBER(cammu_device::insn_r) +void cammu_c4i_device::device_start() { - u32 ssw = m_ssw_func(); - u32 va = offset << 2; + cammu_c4_device::device_start(); + + save_item(NAME(m_reset)); + save_item(NAME(m_clr_s_data_tlb)); + save_item(NAME(m_clr_u_data_tlb)); + save_item(NAME(m_clr_s_insn_tlb)); + save_item(NAME(m_clr_u_insn_tlb)); + save_item(NAME(m_test_data)); + save_item(NAME(m_test_address)); +} - // in supervisor mode, the first 8 pages are always mapped via the hard-wired tlb - if ((ssw & 0x40000000) == 0 && (va & ~0x7fff) == 0) - { - switch (va & 0xf000) - { - case 0x0000: - case 0x1000: - case 0x2000: - case 0x3000: - // pages 0-3: main space pages 0-3 - return m_main_space->read_dword(va, mem_mask); +void cammu_c4t_device::device_start() +{ + cammu_c4_device::device_start(); + + save_item(NAME(m_ram_line)); + save_item(NAME(m_htlb_offset)); + save_item(NAME(m_c4_bus_poll)); + save_item(NAME(m_bio_control)); + save_item(NAME(m_bio_address_tag)); + + save_item(NAME(m_cache_data_lo)); + save_item(NAME(m_cache_data_hi)); + save_item(NAME(m_cache_cpu_tag)); + save_item(NAME(m_cache_system_tag_valid)); + save_item(NAME(m_cache_system_tag)); + save_item(NAME(m_tlb_va_line)); + save_item(NAME(m_tlb_ra_line)); +} - case 0x4000: - case 0x5000: - // pages 4-5: i/o space pages 0-1 - return m_io_space->read_dword(va & 0x1fff, mem_mask); +void cammu_c3_device::device_start() +{ + cammu_device::device_start(); - case 0x6000: - case 0x7000: - // pages 6-7: boot space pages 0-1 - return m_boot_space->read_dword(va & 0x1fff, mem_mask); - } - } + save_item(NAME(m_s_pdo)); + save_item(NAME(m_u_pdo)); + save_item(NAME(m_fault)); + save_item(NAME(m_control)); + save_item(NAME(m_reset)); +} - // if not in mapped mode, default to main memory space - if ((ssw & 0x04000000) == 0) - return m_main_space->read_dword(va); +void cammu_c3_device::device_reset() +{ + cammu_device::device_reset(); -#if DTU - // get the page table entry - u32 pte = get_pte(va, ssw & 0x40000000, false); + m_control = (m_control & CNTL_CID) | (CNTL_ATE | UST_3 | CNTL_EWIR | CNTL_EWIW | CNTL_EWCW | CNTL_EP); + m_reset = 0; +} - // translate the address - u32 ra = (pte & 0xfffff000) | (va & 0xfff); +READ32_MEMBER(cammu_device::read) +{ + const u32 virtual_address = (offset << 2) | ( + (mem_mask & 0x00ffffff) == 0 ? 0x3 : + (mem_mask & 0x0000ffff) == 0 ? 0x2 : + (mem_mask & 0x000000ff) == 0 ? 0x1 : 0x0); + offs_t physical_address; - // execute the read based on the system tag - switch ((pte & 0xe00) >> 9) - { - case 0: - case 1: - case 2: - case 3: - return m_main_space->read_dword(ra, mem_mask); + LOGMASKED(LOG_ACCESS, "%s read address 0x%08x mem_mask 0x%08x (%s)\n", + space.name(), virtual_address, mem_mask, machine().describe_context()); - case 4: - return m_io_space->read_dword(ra, mem_mask); + address_space *physical_space = translate_address(virtual_address, space.spacenum() == AS_PROGRAM ? ACCESS_X : ACCESS_R, &physical_address); - case 5: - return m_boot_space->read_dword(ra, mem_mask); + if (physical_space != nullptr) + return physical_space->read_dword(physical_address, mem_mask); + else + return space.unmap(); +} - case 6: // cache purge - case 7: // main memory, slave mode - fatalerror("system tag %d not supported %s\n", (pte & 0xe00) >> 9, machine().describe_context().c_str()); - } +WRITE32_MEMBER(cammu_device::write) +{ + const u32 virtual_address = (offset << 2) | ( + (mem_mask & 0x00ffffff) == 0 ? 0x3 : + (mem_mask & 0x0000ffff) == 0 ? 0x2 : + (mem_mask & 0x000000ff) == 0 ? 0x1 : 0x0); + offs_t physical_address; - return 0; -#else - // FIXME: currently maps addresses with upper bits 0x00 or 0x7f1 to main memory and everything else to I/O - if ((va & 0xff000000) == 0x00000000 || (va & 0xfff00000) == 0x7f100000) - return m_main_space->read_dword(va, mem_mask); - else - return m_io_space->read_dword(va, mem_mask); -#endif + LOGMASKED(LOG_ACCESS, "%s write address 0x%08x data 0x%08x mem_mask 0x%08x (%s)\n", + space.name(), virtual_address, data, mem_mask, machine().describe_context()); + + address_space *physical_space = translate_address(virtual_address, ACCESS_W, &physical_address); + + if (physical_space != nullptr) + physical_space->write_dword(physical_address, data, mem_mask); } -READ32_MEMBER(cammu_device::data_r) +address_space *cammu_device::translate_address(const offs_t virtual_address, const access_t mode, offs_t *physical_address) { - u32 ssw = m_ssw_func(); - u32 va = offset << 2; + // get ssw and user/supervisor mode + const u32 ssw = m_ssw_func(); + const bool user = mode == ACCESS_X ? ssw & SSW_U : ssw & (SSW_U | SSW_UU); + + // TODO: check for alignment faults - // in supervisor mode (and not user data mode), the first 8 pages are always mapped via the hard-wired tlb - if (((ssw & 0x50000000) == 0) && ((va & ~0x7fff) == 0)) + // in supervisor mode, the first 8 pages are always mapped via the hard-wired tlb + if (!user && (virtual_address & ~0x7fff) == 0) { - switch (va & 0xf000) + switch (virtual_address & 0x7000) { case 0x0000: case 0x1000: case 0x2000: case 0x3000: // pages 0-3: main space pages 0-3 - return m_main_space->read_dword(va, mem_mask); + *physical_address = virtual_address & 0x3fff; + return m_main_space; case 0x4000: case 0x5000: // pages 4-5: i/o space pages 0-1 - return m_io_space->read_dword(va & 0x1fff, mem_mask); + *physical_address = virtual_address & 0x1fff; + return m_io_space; case 0x6000: case 0x7000: // pages 6-7: boot space pages 0-1 - return m_boot_space->read_dword(va & 0x1fff, mem_mask); + *physical_address = virtual_address & 0x1fff; + return m_boot_space; } } - // if not in mapped mode, default to main memory space - if ((ssw & 0x04000000) == 0) - return m_main_space->read_dword(va); + // if not in mapped mode, use unmapped system tag + if ((ssw & SSW_M) == 0) + { + *physical_address = virtual_address; + + return get_ust_space(); + } -#if DTU // get the page table entry - u32 pte = get_pte(va, ssw & 0x50000000, space.spacenum() == AS_DATA); + const u32 pte = get_pte(virtual_address, user); - // translate the address - u32 ra = (pte & 0xfffff000) | (va & 0xfff); + // check for page faults + if (pte & PTE_F) + { + if (!machine().side_effect_disabled()) + { + LOG("%s page fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n", + mode == ACCESS_X ? "instruction" : "data", + virtual_address, ssw, pte, machine().describe_context()); + + set_fault_address(virtual_address); + m_exception_func(mode == ACCESS_X ? EXCEPTION_I_PAGE_FAULT : EXCEPTION_D_PAGE_FAULT); + } + + return nullptr; + } - // execute the read based on the system tag - switch ((pte & 0xe00) >> 9) + // check for protection level faults + if (!machine().side_effect_disabled() && !get_access(mode, pte, ssw)) { - case 0: - case 1: - case 2: - case 3: - return m_main_space->read_dword(ra, mem_mask); + LOG("%s protection fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n", + mode == ACCESS_X ? "execute" : mode == ACCESS_R ? "read" : "write", + virtual_address, ssw, pte, machine().describe_context()); + + set_fault_address(virtual_address); + m_exception_func( + mode == ACCESS_X ? EXCEPTION_I_EXECUTE_PROTECT_FAULT : + mode == ACCESS_R ? EXCEPTION_D_READ_PROTECT_FAULT : + EXCEPTION_D_WRITE_PROTECT_FAULT); - case 4: - return m_io_space->read_dword(ra, mem_mask); + return nullptr; + } - case 5: - return m_boot_space->read_dword(ra, mem_mask); + // translate the address + *physical_address = (pte & ~CAMMU_PAGE_MASK) | (virtual_address & CAMMU_PAGE_MASK); + LOGMASKED(LOG_DTU, "%s address translated 0x%08x\n", mode == ACCESS_X ? "instruction" : "data", *physical_address); - case 6: // cache purge - case 7: // main memory, slave mode - fatalerror("data_r: system tag %d not supported at %s\n", (pte & 0xe00) >> 9, machine().describe_context().c_str()); + // return the physical space based on the system tag + switch (pte & PTE_ST) + { + case ST_0: + case ST_1: + case ST_2: + case ST_3: + // main memory space + return m_main_space; + + case ST_4: + // i/o space + return m_io_space; + + case ST_5: + // boot space + return m_boot_space; + + case ST_6: + // cache purge + case ST_7: + // main memory, slave mode + if (!machine().side_effect_disabled()) + fatalerror("%s page table entry system tag %d not supported\n", + mode == ACCESS_X ? "instruction" : "data", (pte & PTE_ST) >> 9); + break; } - return 0; -#else - // FIXME: currently maps addresses with upper bits 0x00 or 0x7f1 to main memory and everything else to I/O - if ((va & 0xff000000) == 0x00000000 || (va & 0xfff00000) == 0x7f100000) - return m_main_space->read_dword(va, mem_mask); - else - return m_io_space->read_dword(va, mem_mask); -#endif + return nullptr; } -WRITE32_MEMBER(cammu_device::data_w) +// return the page table entry for a given virtual address +u32 cammu_device::get_pte(const u32 va, const bool user) { - u32 ssw = m_ssw_func(); - u32 va = offset << 2; - - // in supervisor mode (and not user data mode), the first 8 pages are always mapped via the hard-wired tlb - if (((ssw & 0x50000000) == 0) && ((va & ~0x7fff) == 0)) + const u32 tlb_index = user ? 1 : 0; + if ((va & ~CAMMU_PAGE_MASK) != m_tlb[tlb_index].va) { - switch (va & 0xf000) - { - case 0x0000: - case 0x1000: - case 0x2000: - case 0x3000: - // pages 0-3: main space pages 0-3 - m_main_space->write_dword(va, data, mem_mask); - return; + // get page table directory origin from user or supervisor pdo register + const u32 pdo = get_pdo(user); - case 0x4000: - case 0x5000: - // pages 4-5: i/o space pages 0-1 - m_io_space->write_dword(va & 0x1fff, data, mem_mask); - return; + // get page table directory index from top 12 bits of virtual address + const u32 ptdi = (va & VA_PTDI) >> 20; - case 0x6000: - case 0x7000: - // pages 6-7: boot space pages 0-1 - m_boot_space->write_dword(va & 0x1fff, data, mem_mask); - return; - } - } + // fetch page table directory entry + const u32 ptde = m_main_space->read_dword(pdo | ptdi); - // if not in mapped mode, default to main memory space - if ((ssw & 0x04000000) == 0) - { - m_main_space->write_dword(va, data, mem_mask); - return; - } + LOGMASKED(LOG_DTU, "get_pte pdo 0x%08x ptdi 0x%08x ptde 0x%08x\n", pdo, ptdi, ptde); -#if DTU - // get the page table entry - u32 pte = get_pte(va, ssw & 0x50000000, space.spacenum() == AS_DATA); + // check for page table directory entry fault + if (ptde & PTDE_F) + return PTE_F; - // translate the address - u32 ra = (pte & 0xfffff000) | (va & 0xfff); + // get the page table origin from the page table directory entry + const u32 pto = ptde & PTDE_PTO; - // execute the read based on the system tag - switch ((pte & 0xe00) >> 9) - { - case 0: - case 1: - case 2: - case 3: - m_main_space->write_dword(ra, data, mem_mask); - break; + // get the page table index from the middle 12 bits of the virtual address + const u32 pti = (va & VA_PTI) >> 10; - case 4: - m_io_space->write_dword(ra, data, mem_mask); - break; + // fetch page table entry + const u32 pte = m_main_space->read_dword(pto | pti); - case 5: - m_boot_space->write_dword(ra, data, mem_mask); - break; + LOGMASKED(LOG_DTU, "get_pte pto 0x%08x pti 0x%08x pte 0x%08x\n", pto, pti, pte); - case 6: // cache purge - case 7: // main memory, slave mode - fatalerror("data_w: system tag %d not supported at %s\n", (pte & 0xe00) >> 9, machine().describe_context().c_str()); - break; + // check for page table entry fault + if (pte & PTE_F) + return PTE_F; + + // add the pte to the tlb + m_tlb[tlb_index].va = va & ~CAMMU_PAGE_MASK; + m_tlb[tlb_index].pte = pte; + + LOGMASKED(LOG_DTU, "get_pte address 0x%08x pte 0x%08x (%s)\n", va, pte, machine().describe_context()); } -#else - // FIXME: currently maps addresses with upper bits 0x00 or 0x7f1 to main memory and everything else to I/O - if ((va & 0xff000000) == 0x00000000 || (va & 0xfff00000) == 0x7f100000) - m_main_space->write_dword(va, data, mem_mask); - else - m_io_space->write_dword(va, data, mem_mask); -#endif + + return m_tlb[tlb_index].pte; } -u32 cammu_c4_device::get_pte(u32 va, int user, bool data) +address_space *cammu_c4i_device::get_ust_space() const { - u32 tlb_index = (user ? 2 : 0) + (data ? 1 : 0); - if ((va & 0xfffff000) != m_tlb[tlb_index].va) + switch (m_control & CNTL_UMM) { - // return the page table entry for a given virtual address - u32 pdo = user ? m_u_pdo : m_s_pdo; - - u32 pto = m_main_space->read_dword(pdo | (va & 0xffc00000) >> 20); - if (pto & 0x1) - fatalerror("can't deal with pto faults va 0x%08x %s\n", va, machine().describe_context().c_str()); + case UMM_MM: return m_main_space; + case UMM_MMRIO: return m_main_space; // FIXME: what determines main or i/o? + case UMM_IO: return m_io_space; + } - u32 pte = m_main_space->read_dword((pto & 0xfffff000) | (va & 0x003ff000) >> 10); - if (pte & 0x1) - fatalerror("can't deal with pte faults va 0x%08x %s\n", va, machine().describe_context().c_str()); + return m_main_space; +} - m_tlb[tlb_index].va = va & 0xfffff000; - m_tlb[tlb_index].pte = pte; +bool cammu_c4_device::get_access(const access_t mode, const u32 pte, const u32 ssw) const +{ + switch (mode) + { + case ACCESS_R: return pte & 0x20; + case ACCESS_W: return pte & 0x10; + case ACCESS_X: return pte & 0x08; } - return m_tlb[tlb_index].pte; + return false; } -u32 cammu_c3_device::get_pte(u32 va, int user, bool data) +bool cammu_c3_device::get_access(const access_t mode, const u32 pte, const u32 ssw) const { - // return the page table entry for a given virtual address - u32 pdo = user ? (data ? m_d_u_pdo : m_i_u_pdo) : (data ? m_d_s_pdo : m_i_s_pdo); + // FIXME: logic is not correct yet + return true; - u32 pto = m_main_space->read_dword(pdo | (va & 0xffc00000) >> 20); - if (pto & 0x1) - fatalerror("can't deal with pto faults va 0x%08x %s\n", va, machine().describe_context().c_str()); + const u8 column = (mode == ACCESS_X ? i_cammu_column : d_cammu_column)[(ssw & SSW_PL) >> 9]; + const u8 access = cammu_matrix[column][(pte & PTE_PL) >> 3]; - u32 pte = m_main_space->read_dword((pto & 0xfffff000) | (va & 0x003ff000) >> 10); - if (pte & 0x1) - fatalerror("can't deal with pte faults va 0x%08x %s\n", va, machine().describe_context().c_str()); + switch (mode) + { + case ACCESS_R: return access & R; + case ACCESS_W: return access & W; + case ACCESS_X: return access & E; + } - return pte; + return false; } + +// C100/C300 CAMMU protection level matrix +const u8 cammu_c3_device::i_cammu_column[] = { 1, 1, 0, 0, 1, 1, 0, 0, 3, 3, 2, 2, 3, 3, 2, 2 }; +const u8 cammu_c3_device::d_cammu_column[] = { 1, 1, 0, 0, 3, 2, 3, 2, 3, 3, 2, 2, 3, 3, 2, 2 }; + +const cammu_c3_device::c3_access_t cammu_c3_device::cammu_matrix[][16] = +{ + { RW, RW, RW, RW, RW, RW, RW, RWE, RE, R, R, R, N, N, N, N }, + { N, RW, RW, RW, RW, RW, R, RWE, N, RE, R, R, RE, N, N, N }, + { N, N, RW, RW, RW, R, R, RWE, N, N, RE, RE, N, RE, N, N }, + { N, N, N, RW, R, R, R, RWE, N, N, N, RE, RE, N, RE, N } +}; + + diff --git a/src/mame/machine/cammu.h b/src/mame/machine/cammu.h index 9ea301f6896..28eb32f07ad 100644 --- a/src/mame/machine/cammu.h +++ b/src/mame/machine/cammu.h @@ -9,17 +9,99 @@ #define MCFG_CAMMU_SSW_CB(_sswcb) \ devcb = &cammu_device::static_set_ssw_callback(*device, DEVCB_##_sswcb); +#define MCFG_CAMMU_EXCEPTION_CB(_exceptioncb) \ + devcb = &cammu_device::static_set_exception_callback(*device, DEVCB_##_exceptioncb); + +#define MCFG_CAMMU_LINK(_tag) \ + cammu_c3_device::static_add_linked(*device, _tag); + class cammu_device : public device_t, public device_memory_interface { public: template <class Object> static devcb_base &static_set_ssw_callback(device_t &device, Object &&cb) { return downcast<cammu_device &>(device).m_ssw_func.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &static_set_exception_callback(device_t &device, Object &&cb) { return downcast<cammu_device &>(device).m_exception_func.set_callback(std::forward<Object>(cb)); } - virtual DECLARE_ADDRESS_MAP(map, 32) = 0; + static const u32 CAMMU_PAGE_SIZE = 0x1000; + static const u32 CAMMU_PAGE_MASK = (CAMMU_PAGE_SIZE - 1); + + enum ssw_mask : u32 + { + SSW_M = 0x04000000, // mapped mode + SSW_KU = 0x08000000, // user protect key + SSW_UU = 0x10000000, // user data mode + SSW_K = 0x20000000, // protect key + SSW_U = 0x40000000, // user mode + + SSW_PL = 0x78000000 // protection level relevant bits + }; + + enum exception_vectors : u16 + { + // data memory trap group + EXCEPTION_D_CORRECTED_MEMORY_ERROR = 0x108, + EXCEPTION_D_UNCORRECTABLE_MEMORY_ERROR = 0x110, + EXCEPTION_D_ALIGNMENT_FAULT = 0x120, + EXCEPTION_D_PAGE_FAULT = 0x128, + EXCEPTION_D_READ_PROTECT_FAULT = 0x130, + EXCEPTION_D_WRITE_PROTECT_FAULT = 0x138, + + // instruction memory trap group + EXCEPTION_I_CORRECTED_MEMORY_ERROR = 0x288, + EXCEPTION_I_UNCORRECTABLE_MEMORY_ERROR = 0x290, + EXCEPTION_I_ALIGNMENT_FAULT = 0x2a0, + EXCEPTION_I_PAGE_FAULT = 0x2a8, + EXCEPTION_I_EXECUTE_PROTECT_FAULT = 0x2b0, + }; + + enum pdo_mask : u32 + { + PDO_MASK = 0xfffff000 + }; - DECLARE_READ32_MEMBER(insn_r); + enum ptde_mask : u32 + { + PTDE_F = 0x00000001, // page fault + PTDE_PTO = 0xfffff000 // page table origin + }; - DECLARE_READ32_MEMBER(data_r); - DECLARE_WRITE32_MEMBER(data_w); + enum pte_mask : u32 + { + PTE_F = 0x00000001, // page fault + PTE_R = 0x00000002, // referenced flag + PTE_D = 0x00000004, // dirty flag + PTE_PL = 0x00000078, // protection level + PTE_S = 0x00000180, // system reserved + PTE_ST = 0x00000e00, // system tag + PTE_RA = 0xfffff000, // real address + + PTE_CW = 0x00000040, // copy on write (c400) + PTE_NDREF = 0x00000080, // secondary reference (software) / copy on write (fault)? + PTE_LOCK = 0x00000100 // page lock (software) + }; + + enum pte_st_mask : u32 + { + ST_0 = 0x00000000, // private, write-through, main memory space + ST_1 = 0x00000200, // shared, write-through, main memory space + ST_2 = 0x00000400, // private, copy-back, main memory space + ST_3 = 0x00000600, // noncacheable, main memory space + ST_4 = 0x00000800, // noncacheable, i/o space + ST_5 = 0x00000a00, // noncacheable, boot space + ST_6 = 0x00000c00, // cache purge + ST_7 = 0x00000e00 // slave i/o + }; + + enum va_mask : u32 + { + VA_POFS = 0x00000fff, // page offset + VA_PTI = 0x003ff000, // page table index + VA_PTDI = 0xffc00000 // page table directory index + }; + + virtual DECLARE_ADDRESS_MAP(map, 32) = 0; + + DECLARE_READ32_MEMBER(read); + DECLARE_WRITE32_MEMBER(write); protected: cammu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); @@ -30,59 +112,82 @@ protected: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; + //virtual bool memory_translate(int spacenum, int intention, offs_t &address) override; - virtual u32 get_pte(u32 va, int user, bool data) = 0; + enum access_t + { + ACCESS_R = 1, + ACCESS_W = 2, + ACCESS_X = 3 + }; + + address_space *translate_address(const offs_t virtual_address, const access_t mode, offs_t *physical_address); + + u32 get_pte(const u32 va, const bool user); + + virtual bool get_access(const access_t mode, const u32 pte, const u32 ssw) const = 0; + virtual bool get_alignment() const = 0; + virtual u32 get_pdo(const bool user) const = 0; + virtual address_space *get_ust_space() const = 0; + + virtual void set_fault_address(const u32 va) = 0; -private: address_space_config m_main_space_config; address_space_config m_io_space_config; address_space_config m_boot_space_config; -protected: address_space *m_main_space; address_space *m_io_space; address_space *m_boot_space; + devcb_read32 m_ssw_func; + devcb_write16 m_exception_func; + struct { u32 va; u32 pte; - } m_tlb[4]; + } + m_tlb[2]; private: - devcb_read32 m_ssw_func; }; class cammu_c4_device : public cammu_device { public: - cammu_c4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); - - DECLARE_READ32_MEMBER(s_pdo_r) { return m_s_pdo; } - DECLARE_WRITE32_MEMBER(s_pdo_w) { m_s_pdo = data; } - DECLARE_READ32_MEMBER(u_pdo_r) { return m_u_pdo; } - DECLARE_WRITE32_MEMBER(u_pdo_w) { m_u_pdo = data; } + DECLARE_READ32_MEMBER(s_pdo_r) const { return m_s_pdo; } + DECLARE_WRITE32_MEMBER(s_pdo_w) { m_s_pdo = ((m_s_pdo & ~mem_mask) | (data & mem_mask)) & PDO_MASK; } + DECLARE_READ32_MEMBER(u_pdo_r) const { return m_u_pdo; } + DECLARE_WRITE32_MEMBER(u_pdo_w) { m_u_pdo = ((m_u_pdo & ~mem_mask) | (data & mem_mask)) & PDO_MASK; } - virtual DECLARE_READ32_MEMBER(control_r) = 0; + virtual DECLARE_READ32_MEMBER(control_r) const = 0; virtual DECLARE_WRITE32_MEMBER(control_w) = 0; - DECLARE_READ32_MEMBER(i_fault_r) { return m_i_fault; } + DECLARE_READ32_MEMBER(i_fault_r) const { return m_i_fault; } DECLARE_WRITE32_MEMBER(i_fault_w) { m_i_fault = data; } - DECLARE_READ32_MEMBER(fault_address_1_r) { return m_fault_address_1; } + DECLARE_READ32_MEMBER(fault_address_1_r) const { return m_fault_address_1; } DECLARE_WRITE32_MEMBER(fault_address_1_w) { m_fault_address_1 = data; } - DECLARE_READ32_MEMBER(fault_address_2_r) { return m_fault_address_2; } + DECLARE_READ32_MEMBER(fault_address_2_r) const { return m_fault_address_2; } DECLARE_WRITE32_MEMBER(fault_address_2_w) { m_fault_address_2 = data; } - DECLARE_READ32_MEMBER(fault_data_1_lo_r) { return m_fault_data_1_lo; } + DECLARE_READ32_MEMBER(fault_data_1_lo_r) const { return m_fault_data_1_lo; } DECLARE_WRITE32_MEMBER(fault_data_1_lo_w) { m_fault_data_1_lo = data; } - DECLARE_READ32_MEMBER(fault_data_1_hi_r) { return m_fault_data_1_hi; } + DECLARE_READ32_MEMBER(fault_data_1_hi_r) const { return m_fault_data_1_hi; } DECLARE_WRITE32_MEMBER(fault_data_1_hi_w) { m_fault_data_1_hi = data; } - DECLARE_READ32_MEMBER(fault_data_2_lo_r) { return m_fault_data_2_lo; } + DECLARE_READ32_MEMBER(fault_data_2_lo_r) const { return m_fault_data_2_lo; } DECLARE_WRITE32_MEMBER(fault_data_2_lo_w) { m_fault_data_2_lo = data; } - DECLARE_READ32_MEMBER(fault_data_2_hi_r) { return m_fault_data_2_hi; } + DECLARE_READ32_MEMBER(fault_data_2_hi_r) const { return m_fault_data_2_hi; } DECLARE_WRITE32_MEMBER(fault_data_2_hi_w) { m_fault_data_2_hi = data; } protected: - u32 get_pte(u32 va, int user, bool data) override; + cammu_c4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, u32 cammu_id); + + virtual void device_start() override; + + virtual bool get_access(const access_t mode, const u32 pte, const u32 ssw) const override; + virtual u32 get_pdo(const bool user) const override { return user ? m_u_pdo : m_s_pdo; } + + virtual void set_fault_address(const u32 va) override { m_fault_address_1 = va; } u32 m_s_pdo; u32 m_u_pdo; @@ -104,36 +209,73 @@ public: virtual DECLARE_ADDRESS_MAP(map, 32) override; - DECLARE_READ32_MEMBER(ram_line_r) { return m_ram_line; } + DECLARE_READ32_MEMBER(ram_line_r) const { return m_ram_line; } DECLARE_WRITE32_MEMBER(ram_line_w) { m_ram_line = data; } - DECLARE_READ32_MEMBER(htlb_offset_r) { return m_htlb_offset; } + DECLARE_READ32_MEMBER(htlb_offset_r) const { return m_htlb_offset; } DECLARE_WRITE32_MEMBER(htlb_offset_w) { m_htlb_offset = data; } - DECLARE_READ32_MEMBER(c4_bus_poll_r) { return m_c4_bus_poll; } + DECLARE_READ32_MEMBER(c4_bus_poll_r) const { return m_c4_bus_poll; } DECLARE_WRITE32_MEMBER(c4_bus_poll_w) { m_c4_bus_poll = data; } - virtual DECLARE_READ32_MEMBER(control_r) override { return m_control | 0x00000000; } - virtual DECLARE_WRITE32_MEMBER(control_w) override { m_control = data & 0x00ffffff; } - DECLARE_READ32_MEMBER(bio_control_r) { return m_bio_control; } + + enum control_mask : u32 + { + CNTL_RUV = 0x00000001, // reset user valid + CNTL_RSV = 0x00000002, // reset supervisor valid + CNTL_DBWR = 0x00000004, // disable bus watch read + CNTL_ATD = 0x00000008, // alignment trap disable + CNTL_UST = 0x00000030, // unmapped system tag + CNTL_IOTS = 0x00000040, // i/o tag select + CNTL_UVS = 0x00000080, // user valid status + CNTL_PB = 0x00000100, // purge busy + CNTL_CICT = 0x00000200, // clear i-side cache tags + CNTL_CFR = 0x00000400, // clear trap registers + CNTL_HTLBD = 0x00000800, // htlb disable + CNTL_CDCT = 0x00001000, // clear d-side cache tags + CNTL_CID = 0xff000000 // cammu id + }; + + enum control_ust_mask : u32 + { + UST_NCA = 0x00, // unmapped system tag, noncacheable + UST_PWT = 0x10, // unmapped system tag, write through + UST_PCB = 0x20, // unmapped system tag, copy back + UST_PGE = 0x30 // unmapped system tag, purge mode + }; + + enum control_cid_mask : u32 + { + CID_C4T = 0x00000000 // unknown + }; + + virtual DECLARE_READ32_MEMBER(control_r) const override { return m_control; } + virtual DECLARE_WRITE32_MEMBER(control_w) override { m_control = ((m_control & (~mem_mask | CNTL_CID)) | (data & (mem_mask & ~CNTL_CID))); } + DECLARE_READ32_MEMBER(bio_control_r) const { return m_bio_control; } DECLARE_WRITE32_MEMBER(bio_control_w) { m_bio_control = data; } - DECLARE_READ32_MEMBER(bio_address_tag_r) { return m_bio_address_tag; } + DECLARE_READ32_MEMBER(bio_address_tag_r) const { return m_bio_address_tag; } DECLARE_WRITE32_MEMBER(bio_address_tag_w) { m_bio_address_tag = data; } - DECLARE_READ32_MEMBER(cache_data_lo_r) { return m_cache_data_lo; } + DECLARE_READ32_MEMBER(cache_data_lo_r) const { return m_cache_data_lo; } DECLARE_WRITE32_MEMBER(cache_data_lo_w) { m_cache_data_lo = data; } - DECLARE_READ32_MEMBER(cache_data_hi_r) { return m_cache_data_hi; } + DECLARE_READ32_MEMBER(cache_data_hi_r) const { return m_cache_data_hi; } DECLARE_WRITE32_MEMBER(cache_data_hi_w) { m_cache_data_hi = data; } - DECLARE_READ32_MEMBER(cache_cpu_tag_r) { return m_cache_cpu_tag; } + DECLARE_READ32_MEMBER(cache_cpu_tag_r) const { return m_cache_cpu_tag; } DECLARE_WRITE32_MEMBER(cache_cpu_tag_w) { m_cache_cpu_tag = data; } - DECLARE_READ32_MEMBER(cache_system_tag_valid_r) { return m_cache_system_tag_valid; } + DECLARE_READ32_MEMBER(cache_system_tag_valid_r) const { return m_cache_system_tag_valid; } DECLARE_WRITE32_MEMBER(cache_system_tag_valid_w) { m_cache_system_tag_valid = data; } - DECLARE_READ32_MEMBER(cache_system_tag_r) { return m_cache_system_tag; } + DECLARE_READ32_MEMBER(cache_system_tag_r) const { return m_cache_system_tag; } DECLARE_WRITE32_MEMBER(cache_system_tag_w) { m_cache_system_tag = data; } - DECLARE_READ32_MEMBER(tlb_va_line_r) { return m_tlb_va_line; } + DECLARE_READ32_MEMBER(tlb_va_line_r) const { return m_tlb_va_line; } DECLARE_WRITE32_MEMBER(tlb_va_line_w) { m_tlb_va_line = data; } - DECLARE_READ32_MEMBER(tlb_ra_line_r) { return m_tlb_ra_line; } + DECLARE_READ32_MEMBER(tlb_ra_line_r) const { return m_tlb_ra_line; } DECLARE_WRITE32_MEMBER(tlb_ra_line_w) { m_tlb_ra_line = data; } +protected: + virtual void device_start() override; + + virtual bool get_alignment() const override { return (m_control & CNTL_ATD) == 0; } + virtual address_space *get_ust_space() const override { return (m_control & CNTL_IOTS) ? m_io_space : m_main_space; } + private: u32 m_ram_line; u32 m_htlb_offset; @@ -157,27 +299,83 @@ public: virtual DECLARE_ADDRESS_MAP(map, 32) override; - virtual DECLARE_READ32_MEMBER(control_r) override { return m_control | 0x02000000; } - virtual DECLARE_WRITE32_MEMBER(control_w) override { m_control = data & 0x00ffffff; } + enum control_mask : u32 + { + CNTL_LRAS = 0x00000001, // tlb line replacement + CNTL_BWWD = 0x00000002, // buswatch write disable + CNTL_BWRD = 0x00000004, // buswatch read disable + CNTL_FSR = 0x00000010, // fake system response + CNTL_ATD = 0x00000100, // alignment trap disable + CNTL_UMM = 0x00003000, // unmapped mode address space select + CNTL_POLL = 0x00030000, // poll bus signals + CNTL_BM = 0x00040000, // burst mode address space select + CNTL_PZBS = 0x00080000, // page 0 boot select + CNTL_CRR = 0x00700000, // cache memory refresh rate + CNTL_CID = 0xff000000 // cammu identification + }; + + enum control_umm_mask : u32 + { + UMM_MM = 0x00000000, // mm space, noncacheable + UMM_MMRIO = 0x00001000, // mm or i/o space, noncacheable + UMM_IO = 0x00002000 // i/o space noncacheable + }; + + enum control_crr_mask : u32 + { + CRR_GT131 = 0x00000000, // clock rate over 131 MHz + CRR_GT66 = 0x00100000, // clock rate over 66 MHz + CRR_GT33 = 0x00200000, // clock rate over 33 MHz + CRR_GT8 = 0x00300000, // clock rate over 8 MHz + CRR_GT2 = 0x00400000, // clock rate over 2 MHz + CRR_GT1 = 0x00500000, // clock rate over 1 MHz + CRR_GTHALF = 0x00600000, // clock rate over 0.5 MHz + CRR_OFF = 0x00700000, // refresh off + }; + + enum control_cid_mask : u32 + { + CID_C4I = 0x02000000 // c4i cammu identification + }; + + virtual DECLARE_READ32_MEMBER(control_r) const override { return m_control; } + virtual DECLARE_WRITE32_MEMBER(control_w) override { m_control = ((m_control & (~mem_mask | CNTL_CID)) | (data & (mem_mask & ~CNTL_CID))); } - DECLARE_READ32_MEMBER(reset_r) { return m_reset; } + enum reset_mask : u32 + { + RESET_CDCT = 0x00000001, // clear data cache tags + RESET_RDUV = 0x00000100, // reset all d-side uv flags + RESET_RDSV = 0x00001000, // reset all d-side sv flags + RESET_CICT = 0x00010000, // clear ins. cache tags + RESET_RIUV = 0x01000000, // reset all i-side uv flags + RESET_RISV = 0x10000000, // reset all i-side sv flags + RESET_FLUSH = 0x40000000, // flush out burst io buffer + RESET_CFR = 0x80000000 // clear fault registers + }; + DECLARE_READ32_MEMBER(reset_r) const { return m_reset; } DECLARE_WRITE32_MEMBER(reset_w) { m_reset = data; } - DECLARE_READ32_MEMBER(clr_s_data_tlb_r) { return m_clr_s_data_tlb; } + DECLARE_READ32_MEMBER(clr_s_data_tlb_r) const { return m_clr_s_data_tlb; } DECLARE_WRITE32_MEMBER(clr_s_data_tlb_w) { m_clr_s_data_tlb = data; } - DECLARE_READ32_MEMBER(clr_u_data_tlb_r) { return m_clr_u_data_tlb; } + DECLARE_READ32_MEMBER(clr_u_data_tlb_r) const { return m_clr_u_data_tlb; } DECLARE_WRITE32_MEMBER(clr_u_data_tlb_w) { m_clr_u_data_tlb = data; } - DECLARE_READ32_MEMBER(clr_s_insn_tlb_r) { return m_clr_s_insn_tlb; } + DECLARE_READ32_MEMBER(clr_s_insn_tlb_r) const { return m_clr_s_insn_tlb; } DECLARE_WRITE32_MEMBER(clr_s_insn_tlb_w) { m_clr_s_insn_tlb = data; } - DECLARE_READ32_MEMBER(clr_u_insn_tlb_r) { return m_clr_u_insn_tlb; } + DECLARE_READ32_MEMBER(clr_u_insn_tlb_r) const { return m_clr_u_insn_tlb; } DECLARE_WRITE32_MEMBER(clr_u_insn_tlb_w) { m_clr_u_insn_tlb = data; } - DECLARE_READ32_MEMBER(test_data_r) { return m_test_data; } + DECLARE_READ32_MEMBER(test_data_r) const { return m_test_data; } DECLARE_WRITE32_MEMBER(test_data_w) { m_test_data = data; } - DECLARE_READ32_MEMBER(test_address_r) { return m_test_address; } + DECLARE_READ32_MEMBER(test_address_r) const { return m_test_address; } DECLARE_WRITE32_MEMBER(test_address_w) { m_test_address = data; } +protected: + virtual void device_start() override; + + virtual bool get_alignment() const override { return (m_control & CNTL_ATD) == 0; } + virtual address_space *get_ust_space() const override; + private: u32 m_reset; u32 m_clr_s_data_tlb; @@ -193,50 +391,88 @@ class cammu_c3_device : public cammu_device public: cammu_c3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + static void static_add_linked(device_t &device, const char *const tag); + virtual DECLARE_ADDRESS_MAP(map, 32) override; + virtual DECLARE_ADDRESS_MAP(map_global, 32); - DECLARE_READ32_MEMBER(d_s_pdo_r) { return m_d_s_pdo; } - DECLARE_WRITE32_MEMBER(d_s_pdo_w) { m_d_s_pdo = data; } - DECLARE_READ32_MEMBER(d_u_pdo_r) { return m_d_u_pdo; } - DECLARE_WRITE32_MEMBER(d_u_pdo_w) { m_d_u_pdo = data; } - DECLARE_READ32_MEMBER(d_fault_r) { return m_d_fault; } - DECLARE_WRITE32_MEMBER(d_fault_w) { m_d_fault = data; } - DECLARE_READ32_MEMBER(d_control_r) { return m_d_control; } - DECLARE_WRITE32_MEMBER(d_control_w) { m_d_control = data; } - DECLARE_READ32_MEMBER(d_reset_r) { return m_d_reset; } - DECLARE_WRITE32_MEMBER(d_reset_w) { m_d_reset = data; } - - DECLARE_READ32_MEMBER(i_s_pdo_r) { return m_i_s_pdo; } - DECLARE_WRITE32_MEMBER(i_s_pdo_w) { m_i_s_pdo = data; } - DECLARE_READ32_MEMBER(i_u_pdo_r) { return m_i_u_pdo; } - DECLARE_WRITE32_MEMBER(i_u_pdo_w) { m_i_u_pdo = data; } - DECLARE_READ32_MEMBER(i_fault_r) { return m_i_fault; } - DECLARE_WRITE32_MEMBER(i_fault_w) { m_i_fault = data; } - DECLARE_READ32_MEMBER(i_control_r) { return m_i_control; } - DECLARE_WRITE32_MEMBER(i_control_w) { m_i_control = data; } - DECLARE_READ32_MEMBER(i_reset_r) { return m_i_reset; } - DECLARE_WRITE32_MEMBER(i_reset_w) { m_i_reset = data; } + enum control_mask : u32 + { + CNTL_EP = 0x00000001, // enable prefetch + CNTL_EWCW = 0x00000002, // enable watch cpu writes + CNTL_EWIW = 0x00000004, // enable watch i/o writes + CNTL_EWIR = 0x00000008, // enable watch i/o reads + CNTL_UST = 0x00000030, // unmapped system tag + CNTL_CV = 0x00000100, // clear valid + CNTL_ATE = 0x00000200, // alignment trap enable + CNTL_CID = 0xff000000 // cammu id + }; + + enum ust_mask : u32 + { + UST_0 = 0x00000000, // private, write-through, main memory space + UST_1 = 0x00000010, // shared, write-through, main memory space + UST_2 = 0x00000020, // private, copy-back, main memory space + UST_3 = 0x00000030 // noncacheable, main memory space + }; + + enum control_cid_mask : u32 + { + CID_C3 = 0x00000000 // unknown + }; + + DECLARE_READ32_MEMBER(s_pdo_r) const { return m_s_pdo; } + DECLARE_WRITE32_MEMBER(s_pdo_w) { m_s_pdo = ((m_s_pdo & ~mem_mask) | (data & mem_mask)) & PDO_MASK; } + DECLARE_READ32_MEMBER(u_pdo_r) const { return m_u_pdo; } + DECLARE_WRITE32_MEMBER(u_pdo_w) { m_u_pdo = ((m_u_pdo & ~mem_mask) | (data & mem_mask)) & PDO_MASK; } + DECLARE_READ32_MEMBER(fault_r) const { return m_fault; } + DECLARE_WRITE32_MEMBER(fault_w) { m_fault = data; } + DECLARE_READ32_MEMBER(control_r) const { return m_control; } + DECLARE_WRITE32_MEMBER(control_w) { m_control = ((m_control & (~mem_mask | CNTL_CID)) | (data & (mem_mask & ~CNTL_CID))); } + DECLARE_READ32_MEMBER(reset_r) const { return m_reset; } + DECLARE_WRITE32_MEMBER(reset_w) { m_reset = data; } - DECLARE_WRITE32_MEMBER(g_s_pdo_w) { d_s_pdo_w(space, offset, data, mem_mask); i_s_pdo_w(space, offset, data, mem_mask); } - DECLARE_WRITE32_MEMBER(g_u_pdo_w) { d_u_pdo_w(space, offset, data, mem_mask); i_u_pdo_w(space, offset, data, mem_mask); } - DECLARE_WRITE32_MEMBER(g_fault_w) { d_fault_w(space, offset, data, mem_mask); i_fault_w(space, offset, data, mem_mask); } - DECLARE_WRITE32_MEMBER(g_control_w) { d_control_w(space, offset, data, mem_mask); i_control_w(space, offset, data, mem_mask); } - DECLARE_WRITE32_MEMBER(g_reset_w) { d_reset_w(space, offset, data, mem_mask); i_reset_w(space, offset, data, mem_mask); } + // global methods - relay to each linked device + DECLARE_WRITE32_MEMBER(g_s_pdo_w) { for (cammu_c3_device *dev : m_linked) dev->s_pdo_w(space, offset, data, mem_mask); } + DECLARE_WRITE32_MEMBER(g_u_pdo_w) { for (cammu_c3_device *dev : m_linked) dev->u_pdo_w(space, offset, data, mem_mask); } + DECLARE_WRITE32_MEMBER(g_fault_w) { for (cammu_c3_device *dev : m_linked) dev->fault_w(space, offset, data, mem_mask); } + DECLARE_WRITE32_MEMBER(g_control_w) { for (cammu_c3_device *dev : m_linked) dev->control_w(space, offset, data, mem_mask); } + DECLARE_WRITE32_MEMBER(g_reset_w) { for (cammu_c3_device *dev : m_linked) dev->reset_w(space, offset, data, mem_mask); } protected: - u32 get_pte(u32 va, int user, bool data) override; + virtual void device_reset() override; + virtual void device_start() override; + + virtual bool get_access(const access_t mode, const u32 pte, const u32 ssw) const override; + virtual bool get_alignment() const override { return m_control & CNTL_ATE; } + virtual u32 get_pdo(const bool user) const override { return user ? m_u_pdo : m_s_pdo; } + virtual address_space *get_ust_space() const override { return m_main_space; } + + virtual void set_fault_address(const u32 va) override { m_fault = va; } private: - u32 m_d_s_pdo; - u32 m_d_u_pdo; - u32 m_d_fault; - u32 m_d_control; - u32 m_d_reset; - u32 m_i_s_pdo; - u32 m_i_u_pdo; - u32 m_i_fault; - u32 m_i_control; - u32 m_i_reset; + enum c3_access_t : u8 + { + N = 0, // no access + R = 1, // read permitted + W = 2, // write permitted + RW = 3, // read and write permitted + E = 4, // execute permitted + RE = 5, // read and execute permitted + RWE = 7 // read, write and execute permitted + }; + + static const u8 i_cammu_column[]; + static const u8 d_cammu_column[]; + static const c3_access_t cammu_matrix[][16]; + + u32 m_s_pdo; + u32 m_u_pdo; + u32 m_fault; + u32 m_control; + u32 m_reset; + + std::vector<cammu_c3_device *> m_linked; }; // device type definitions diff --git a/src/mame/machine/cedar_magnet_sprite.cpp b/src/mame/machine/cedar_magnet_sprite.cpp index 0745fdc37d7..87c1fb4a3b7 100644 --- a/src/mame/machine/cedar_magnet_sprite.cpp +++ b/src/mame/machine/cedar_magnet_sprite.cpp @@ -228,8 +228,8 @@ MACHINE_CONFIG_MEMBER( cedar_magnet_sprite_device::device_add_mconfig ) MCFG_DEVICE_ADD("sp_sub_ram", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(cedar_magnet_sprite_sub_ram_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x10000) MACHINE_CONFIG_END diff --git a/src/mame/machine/coco.cpp b/src/mame/machine/coco.cpp index 6de238dadbc..6750d1403c7 100644 --- a/src/mame/machine/coco.cpp +++ b/src/mame/machine/coco.cpp @@ -1399,16 +1399,16 @@ static const char *const os9syscalls[] = // os9_dasm_override //------------------------------------------------- -offs_t coco_state::os9_dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options) +offs_t coco_state::os9_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms) { unsigned call; offs_t result = 0; // Microware OS-9 (on the CoCo) and a number of other 6x09 based systems used the SWI2 // instruction for syscalls. This checks for a SWI2 and looks up the syscall as appropriate - if ((oprom[0] == 0x10) && (oprom[1] == 0x3F)) + if ((opcodes.r8(pc) == 0x10) && (opcodes.r8(pc+1) == 0x3F)) { - call = oprom[2]; + call = opcodes.r8(pc+2); if ((call < ARRAY_LENGTH(os9syscalls)) && (os9syscalls[call] != nullptr)) { util::stream_format(stream, "OS9 %s", os9syscalls[call]); @@ -1419,7 +1419,7 @@ offs_t coco_state::os9_dasm_override(device_t &device, std::ostream &stream, off } -offs_t coco_state::dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options) +offs_t coco_state::dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms) { - return os9_dasm_override(device, stream, pc, oprom, opram, options); + return os9_dasm_override(stream, pc, opcodes, params); } diff --git a/src/mame/machine/dec0.cpp b/src/mame/machine/dec0.cpp index 0dc090e32be..20399c58776 100644 --- a/src/mame/machine/dec0.cpp +++ b/src/mame/machine/dec0.cpp @@ -366,14 +366,10 @@ DRIVER_INIT_MEMBER(dec0_state,hippodrm) DRIVER_INIT_MEMBER(dec0_state,slyspy) { - uint8_t *RAM = memregion("audiocpu")->base(); h6280_decrypt("audiocpu"); - /* Slyspy sound cpu has some protection */ - RAM[0xf2d] = 0xea; - RAM[0xf2e] = 0xea; - save_item(NAME(m_slyspy_state)); + save_item(NAME(m_slyspy_sound_state)); } DRIVER_INIT_MEMBER(dec0_state,robocop) diff --git a/src/mame/machine/deco222.cpp b/src/mame/machine/deco222.cpp index 50478cc48bc..5be4df0bb60 100644 --- a/src/mame/machine/deco222.cpp +++ b/src/mame/machine/deco222.cpp @@ -34,7 +34,20 @@ uint8_t deco_222_device::mi_decrypt::read_sync(uint16_t adr) return BITSWAP8(direct->read_byte(adr) ,7,5,6,4,3,2,1,0); } +util::disasm_interface *deco_222_device::create_disassembler() +{ + return new disassembler; +} + +u32 deco_222_device::disassembler::interface_flags() const +{ + return SPLIT_DECRYPTION; +} +u8 deco_222_device::disassembler::decrypt8(u8 value, offs_t pc, bool opcode) const +{ + return opcode ? BITSWAP8(value,7,5,6,4,3,2,1,0) : value; +} deco_c10707_device::deco_c10707_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : m6502_device(mconfig, DECO_C10707, tag, owner, clock) @@ -57,3 +70,18 @@ uint8_t deco_c10707_device::mi_decrypt::read_sync(uint16_t adr) { return BITSWAP8(direct->read_byte(adr) ,7,5,6,4,3,2,1,0); } + +util::disasm_interface *deco_c10707_device::create_disassembler() +{ + return new disassembler; +} + +u32 deco_c10707_device::disassembler::interface_flags() const +{ + return SPLIT_DECRYPTION; +} + +u8 deco_c10707_device::disassembler::decrypt8(u8 value, offs_t pc, bool opcode) const +{ + return opcode ? BITSWAP8(value,7,5,6,4,3,2,1,0) : value; +} diff --git a/src/mame/machine/deco222.h b/src/mame/machine/deco222.h index c7bf940acac..a633aec519c 100644 --- a/src/mame/machine/deco222.h +++ b/src/mame/machine/deco222.h @@ -5,6 +5,7 @@ #pragma once +#include "cpu/m6502/m6502d.h" #include "cpu/m6502/m6502.h" class deco_222_device : public m6502_device { @@ -20,9 +21,17 @@ protected: virtual uint8_t read_sync(uint16_t adr) override; }; + class disassembler : public m6502_disassembler { + public: + disassembler() = default; + virtual ~disassembler() = default; + virtual u32 interface_flags() const override; + virtual u8 decrypt8(u8 value, offs_t pc, bool opcode) const override; + }; + virtual void device_start() override; virtual void device_reset() override; - + virtual util::disasm_interface *create_disassembler() override; }; @@ -40,9 +49,18 @@ protected: virtual uint8_t read_sync(uint16_t adr) override; }; + + class disassembler : public m6502_disassembler { + public: + disassembler() = default; + virtual ~disassembler() = default; + virtual u32 interface_flags() const override; + virtual u8 decrypt8(u8 value, offs_t pc, bool opcode) const override; + }; + virtual void device_start() override; virtual void device_reset() override; - + virtual util::disasm_interface *create_disassembler() override; }; diff --git a/src/mame/machine/decocpu6.cpp b/src/mame/machine/decocpu6.cpp index 3d855e2864d..9e068e73adb 100644 --- a/src/mame/machine/decocpu6.cpp +++ b/src/mame/machine/decocpu6.cpp @@ -35,3 +35,18 @@ uint8_t deco_cpu6_device::mi_decrypt::read_sync(uint16_t adr) else return direct->read_byte(adr); } + +util::disasm_interface *deco_cpu6_device::create_disassembler() +{ + return new disassembler; +} + +u32 deco_cpu6_device::disassembler::interface_flags() const +{ + return SPLIT_DECRYPTION; +} + +u8 deco_cpu6_device::disassembler::decrypt8(u8 value, offs_t pc, bool opcode) const +{ + return opcode && (pc & 1) ? BITSWAP8(value,6,4,7,5,3,2,1,0) : value; +} diff --git a/src/mame/machine/decocpu6.h b/src/mame/machine/decocpu6.h index 21e649ed5ac..a4c5002ab40 100644 --- a/src/mame/machine/decocpu6.h +++ b/src/mame/machine/decocpu6.h @@ -5,6 +5,7 @@ #pragma once +#include "cpu/m6502/m6502d.h" #include "cpu/m6502/m6502.h" class deco_cpu6_device : public m6502_device { @@ -17,10 +18,17 @@ protected: virtual ~mi_decrypt() {} virtual uint8_t read_sync(uint16_t adr) override; }; + class disassembler : public m6502_disassembler { + public: + disassembler() = default; + virtual ~disassembler() = default; + virtual u32 interface_flags() const override; + virtual u8 decrypt8(u8 value, offs_t pc, bool opcode) const override; + }; virtual void device_start() override; virtual void device_reset() override; - + virtual util::disasm_interface *create_disassembler() override; }; DECLARE_DEVICE_TYPE(DECO_CPU6, deco_cpu6_device) diff --git a/src/mame/machine/decocpu7.cpp b/src/mame/machine/decocpu7.cpp index 332cea3ac45..50144063bb4 100644 --- a/src/mame/machine/decocpu7.cpp +++ b/src/mame/machine/decocpu7.cpp @@ -40,3 +40,22 @@ void deco_cpu7_device::mi_decrypt::write(uint16_t adr, uint8_t val) program->write_byte(adr, val); had_written = true; } + +util::disasm_interface *deco_cpu7_device::create_disassembler() +{ + return new disassembler(static_cast<mi_decrypt *>(mintf)); +} + +deco_cpu7_device::disassembler::disassembler(mi_decrypt *mi) : mintf(mi) +{ +} + +u32 deco_cpu7_device::disassembler::interface_flags() const +{ + return SPLIT_DECRYPTION; +} + +u8 deco_cpu7_device::disassembler::decrypt8(u8 value, offs_t pc, bool opcode) const +{ + return opcode && mintf->had_written && ((pc & 0x104) == 0x104) ? BITSWAP8(value,6,5,3,4,2,7,1,0) : value; +} diff --git a/src/mame/machine/decocpu7.h b/src/mame/machine/decocpu7.h index 4f854816f21..404ed43c466 100644 --- a/src/mame/machine/decocpu7.h +++ b/src/mame/machine/decocpu7.h @@ -5,6 +5,7 @@ #pragma once +#include "cpu/m6502/m6502d.h" #include "cpu/m6502/m6502.h" class deco_cpu7_device : public m6502_device { @@ -21,9 +22,19 @@ protected: virtual void write(uint16_t adr, uint8_t val) override; }; + class disassembler : public m6502_disassembler { + public: + mi_decrypt *mintf; + + disassembler(mi_decrypt *m); + virtual ~disassembler() = default; + virtual u32 interface_flags() const override; + virtual u8 decrypt8(u8 value, offs_t pc, bool opcode) const override; + }; + virtual void device_start() override; virtual void device_reset() override; - + virtual util::disasm_interface *create_disassembler() override; }; DECLARE_DEVICE_TYPE(DECO_CPU7, deco_cpu7_device) diff --git a/src/mame/machine/dgn_beta.cpp b/src/mame/machine/dgn_beta.cpp index dab45919b06..e15f23ffe0f 100644 --- a/src/mame/machine/dgn_beta.cpp +++ b/src/mame/machine/dgn_beta.cpp @@ -946,9 +946,9 @@ void dgn_beta_state::machine_start() OS9 Syscalls for disassembly ****************************************************************************/ -offs_t dgn_beta_state::dgnbeta_dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options) +offs_t dgn_beta_state::dgnbeta_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms) { - return coco_state::os9_dasm_override(device, stream, pc, oprom, opram, options); + return coco_state::os9_dasm_override(stream, pc, opcodes, params); } void dgn_beta_state::execute_beta_dat_log(int ref, const std::vector<std::string> ¶ms) diff --git a/src/mame/machine/einstein.cpp b/src/mame/machine/einstein.cpp deleted file mode 100644 index 9e2c31d8074..00000000000 --- a/src/mame/machine/einstein.cpp +++ /dev/null @@ -1,208 +0,0 @@ -// license:GPL-2.0+ -// copyright-holders:Kevin Thacker, Dirk Best, Phill Harvey-Smith -/*************************************************************************** - - Tatung Einstein - - -***************************************************************************/ - -#include "emu.h" -#include "includes/einstein.h" - -/**************************************************************** - EINSTEIN NON-Z80 DEVICES DAISY CHAIN SUPPORT -****************************************************************/ - - -DEFINE_DEVICE_TYPE(EINSTEIN_KEYBOARD_DAISY, einstein_keyboard_daisy_device, "einstein_keyboard", "Einstein keyboard daisy chain") - - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// z80ctc_device - constructor -//------------------------------------------------- - -einstein_keyboard_daisy_device::einstein_keyboard_daisy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, EINSTEIN_KEYBOARD_DAISY, tag, owner, clock) - , device_z80daisy_interface(mconfig, *this) -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void einstein_keyboard_daisy_device::device_start() -{ -} - -//************************************************************************** -// DAISY CHAIN INTERFACE -//************************************************************************** - -//------------------------------------------------- -// z80daisy_irq_state - return the overall IRQ -// state for this device -//------------------------------------------------- - -int einstein_keyboard_daisy_device::z80daisy_irq_state() -{ - einstein_state *einstein = device().machine().driver_data<einstein_state>(); - - if (einstein->m_interrupt & einstein->m_interrupt_mask & EINSTEIN_KEY_INT) - return Z80_DAISY_INT; - - return 0; -} - - -//------------------------------------------------- -// z80daisy_irq_ack - acknowledge an IRQ and -// return the appropriate vector -//------------------------------------------------- - -int einstein_keyboard_daisy_device::z80daisy_irq_ack() -{ - return 0xf7; -} - -//------------------------------------------------- -// z80daisy_irq_reti - clear the interrupt -// pending state to allow other interrupts through -//------------------------------------------------- - -void einstein_keyboard_daisy_device::z80daisy_irq_reti() -{ -} - -DEFINE_DEVICE_TYPE(EINSTEIN_ADC_DAISY, einstein_adc_daisy_device, "einstein_adc", "Einstein ADC daisy chain") - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// z80ctc_device - constructor -//------------------------------------------------- - -einstein_adc_daisy_device::einstein_adc_daisy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, EINSTEIN_ADC_DAISY, tag, owner, clock) - , device_z80daisy_interface(mconfig, *this) -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void einstein_adc_daisy_device::device_start() -{ -} - -//************************************************************************** -// DAISY CHAIN INTERFACE -//************************************************************************** - -//------------------------------------------------- -// z80daisy_irq_state - return the overall IRQ -// state for this device -//------------------------------------------------- - -int einstein_adc_daisy_device::z80daisy_irq_state() -{ - einstein_state *einstein = device().machine().driver_data<einstein_state>(); - - if (einstein->m_interrupt & einstein->m_interrupt_mask & EINSTEIN_ADC_INT) - return Z80_DAISY_INT; - - return 0; -} - - -//------------------------------------------------- -// z80daisy_irq_ack - acknowledge an IRQ and -// return the appropriate vector -//------------------------------------------------- - -int einstein_adc_daisy_device::z80daisy_irq_ack() -{ - return 0xfb; -} - -//------------------------------------------------- -// z80daisy_irq_reti - clear the interrupt -// pending state to allow other interrupts through -//------------------------------------------------- - -void einstein_adc_daisy_device::z80daisy_irq_reti() -{ -} - - -DEFINE_DEVICE_TYPE(EINSTEIN_FIRE_DAISY, einstein_fire_daisy_device, "einstein_fire", "Einstein fire button daisy chain") - - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// z80ctc_device - constructor -//------------------------------------------------- - -einstein_fire_daisy_device::einstein_fire_daisy_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, EINSTEIN_FIRE_DAISY, tag, owner, clock) - , device_z80daisy_interface(mconfig, *this) -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void einstein_fire_daisy_device::device_start() -{ -} - -//************************************************************************** -// DAISY CHAIN INTERFACE -//************************************************************************** - -//------------------------------------------------- -// z80daisy_irq_state - return the overall IRQ -// state for this device -//------------------------------------------------- - -int einstein_fire_daisy_device::z80daisy_irq_state() -{ - einstein_state *einstein = device().machine().driver_data<einstein_state>(); - - if (einstein->m_interrupt & einstein->m_interrupt_mask & EINSTEIN_FIRE_INT) - return Z80_DAISY_INT; - - return 0; -} - - -//------------------------------------------------- -// z80daisy_irq_ack - acknowledge an IRQ and -// return the appropriate vector -//------------------------------------------------- - -int einstein_fire_daisy_device::z80daisy_irq_ack() -{ - return 0xfd; -} - -//------------------------------------------------- -// z80daisy_irq_reti - clear the interrupt -// pending state to allow other interrupts through -//------------------------------------------------- - -void einstein_fire_daisy_device::z80daisy_irq_reti() -{ -} diff --git a/src/mame/machine/electron.cpp b/src/mame/machine/electron.cpp index 1bdfdebb88e..008cb662965 100644 --- a/src/mame/machine/electron.cpp +++ b/src/mame/machine/electron.cpp @@ -172,8 +172,9 @@ WRITE8_MEMBER(electron_state::electron_mem_w) READ8_MEMBER(electron_state::electron_fred_r) { + /* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xfc */ logerror("FRED: read fc%02x\n", offset); - return 0xff; + return 0xfc; } WRITE8_MEMBER(electron_state::electron_fred_w) @@ -182,8 +183,9 @@ WRITE8_MEMBER(electron_state::electron_fred_w) READ8_MEMBER(electron_state::electron_jim_r) { + /* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xfd */ logerror("JIM: read fd%02x\n", offset); - return 0xff; + return 0xfd; } WRITE8_MEMBER(electron_state::electron_jim_w) @@ -192,7 +194,9 @@ WRITE8_MEMBER(electron_state::electron_jim_w) READ8_MEMBER(electron_state::electron_sheila_r) { - uint8_t data = ((uint8_t *)memregion("user1")->base())[0x43E00 + offset]; + /* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xfe */ + uint8_t data = 0xfe; + switch ( offset & 0x0f ) { case 0x00: /* Interrupt status */ @@ -311,6 +315,7 @@ WRITE8_MEMBER(electron_state::electron_sheila_w) m_ula.cassette_motor_mode = ( data >> 6 ) & 0x01; m_cassette->change_state(m_ula.cassette_motor_mode ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MOTOR_DISABLED ); m_ula.capslock_mode = ( data >> 7 ) & 0x01; + output().set_value("capslock_led", m_ula.capslock_mode); break; case 0x08: case 0x0A: case 0x0C: case 0x0E: // video_update @@ -379,23 +384,7 @@ void electron_state::machine_reset() void electron_state::machine_start() { - uint8_t *lo_rom, *up_rom; - std::string region_tag; - memory_region *cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str()); - - if (cart_rom) - up_rom = cart_rom->base(); - else - up_rom = memregion("user1")->base() + 12 * 0x4000; - if (cart_rom && cart_rom->bytes() > 0x4000) - lo_rom = cart_rom->base() + 0x4000; - else - lo_rom = memregion("user1")->base(); - - membank("bank2")->configure_entries(0, 1, lo_rom, 0x4000); - membank("bank2")->configure_entries(1, 1, up_rom, 0x4000); - - for (int page = 2; page < 16; page++) + for (int page = 0; page < 16; page++) membank("bank2")->configure_entries(page, 1, memregion("user1")->base() + page * 0x4000, 0x4000); m_ula.interrupt_status = 0x82; @@ -403,48 +392,3 @@ void electron_state::machine_start() timer_set(attotime::zero, TIMER_SETUP_BEEP); m_tape_timer = timer_alloc(TIMER_TAPE_HANDLER); } - -DEVICE_IMAGE_LOAD_MEMBER( electron_state, electron_cart ) -{ - if (!image.loaded_through_softlist()) - { - uint32_t filesize = image.length(); - - if (filesize != 16384) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only size 16384 is supported"); - return image_init_result::FAIL; - } - - m_cart->rom_alloc(filesize, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - image.fread(m_cart->get_rom_base(), filesize); - return image_init_result::PASS; - } - else - { - int upsize = image.get_software_region_length("uprom"); - int losize = image.get_software_region_length("lorom"); - - if (upsize != 16384 && upsize != 0) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for uprom"); - return image_init_result::FAIL; - } - - if (losize != 16384 && losize != 0) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for lorom"); - return image_init_result::FAIL; - } - - m_cart->rom_alloc(upsize + losize, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - - if (upsize) - memcpy(m_cart->get_rom_base(), image.get_software_region("uprom"), upsize); - - if (losize) - memcpy(m_cart->get_rom_base() + upsize, image.get_software_region("lorom"), losize); - - return image_init_result::PASS; - } -} diff --git a/src/mame/machine/galaxold.cpp b/src/mame/machine/galaxold.cpp index 9b40b213a0d..165830bd07b 100644 --- a/src/mame/machine/galaxold.cpp +++ b/src/mame/machine/galaxold.cpp @@ -171,7 +171,7 @@ DRIVER_INIT_MEMBER(galaxold_state,4in1) INTERRUPT_GEN_MEMBER(galaxold_state::hunchbks_vh_interrupt) { - generic_pulse_irq_line_and_vector(device.execute(),0,0x03,1); + device.execute().pulse_input_line_and_vector(0, 0x03, device.execute().minimum_quantum_time()); } DRIVER_INIT_MEMBER(galaxold_state,bullsdrtg) diff --git a/src/mame/machine/igs036crypt.cpp b/src/mame/machine/igs036crypt.cpp index f57a996d9b2..cc88b85273e 100644 --- a/src/mame/machine/igs036crypt.cpp +++ b/src/mame/machine/igs036crypt.cpp @@ -487,3 +487,40 @@ const uint16_t ddpdoj_key[0x100] = { 0xd1d0, 0x9193, 0xc1e0, 0xc9c1, 0x0014, 0x0830, 0x4050, 0x4961, 0x103a, 0xc9e9, 0x1118, 0x1111, 0x404e, 0x8898, 0x0024, 0x0020, }; + +// WRONG + +const uint16_t kof98umh_key[0x100] = { + 0x9202, 0x0000, 0x0220, 0x3b01, 0x2004, 0x00a0, 0x0000, 0x0905, + 0x830a, 0x8000, 0x8228, 0xa20a, 0x8206, 0x0000, 0x0020, 0x8808, + 0x9212, 0x0800, 0x0000, 0x0301, 0x0020, 0x0a02, 0x0000, 0x0105, + 0x020a, 0x0000, 0x0000, 0x1111, 0x021a, 0x0121, 0x0000, 0x8111, + 0x8020, 0x0802, 0xb120, 0xb901, 0x8326, 0x0800, 0x0000, 0xa101, + 0x922a, 0x0000, 0x1200, 0x9022, 0x0128, 0x0800, 0x0020, 0xaa0c, + 0x0202, 0x0800, 0x8000, 0x1b31, 0x8024, 0x8804, 0x0000, 0x8111, + 0x8120, 0x8000, 0x0080, 0x9030, 0x032e, 0x083c, 0x0000, 0x893d, + 0xe342, 0x0800, 0x0120, 0x7b41, 0xa000, 0x00a0, 0x0000, 0x4141, + 0x130a, 0x0000, 0x8320, 0xdb49, 0x010c, 0x0000, 0x0020, 0xc84c, + 0x0202, 0x0000, 0x0000, 0x1911, 0x0014, 0x0b13, 0x0000, 0x8a10, + 0x434a, 0x0020, 0x0000, 0x5250, 0xc050, 0x0034, 0x0000, 0xc355, + 0x7242, 0x0002, 0x9000, 0xcb61, 0x8120, 0x0020, 0x0000, 0x0921, + 0x4068, 0x0000, 0x6068, 0x922a, 0xc36e, 0x0020, 0x0020, 0x280c, + 0x0322, 0x0800, 0x8020, 0x9810, 0xc060, 0x4b73, 0x0000, 0x4870, + 0xd050, 0x0020, 0x0000, 0x1b39, 0xc26e, 0x0121, 0x0000, 0x4375, + 0x2202, 0x0000, 0x0120, 0xb0a0, 0x2202, 0x2020, 0x2000, 0x8280, + 0x838a, 0x0080, 0x81a0, 0xb082, 0x2004, 0x0000, 0x0020, 0xa385, + 0x8080, 0x0080, 0x0000, 0x9191, 0x80a0, 0x0004, 0x0000, 0x8280, + 0x9098, 0x0020, 0x0080, 0x0808, 0x030e, 0x0337, 0x0000, 0x8290, + 0xb382, 0x0002, 0x0000, 0x1220, 0x2004, 0x0000, 0x0080, 0x2301, + 0x81a8, 0x0000, 0x0228, 0x1121, 0x230a, 0x2000, 0x0000, 0x80a0, + 0x1232, 0x0020, 0x0020, 0x9b91, 0x0114, 0x8185, 0x0080, 0x0010, + 0x82aa, 0x0000, 0x0080, 0x98b8, 0x0226, 0x0a2e, 0x0000, 0x80b4, + 0x1100, 0x0000, 0xa1a0, 0xf2e0, 0x6144, 0x0020, 0x0000, 0x4145, + 0x1108, 0x0000, 0xb280, 0x9a8a, 0xa084, 0x0000, 0x0020, 0x4044, + 0x9190, 0x0000, 0x0000, 0x0a00, 0x4266, 0x0814, 0x0080, 0x8b91, + 0x434a, 0x00a0, 0x0080, 0x0808, 0x4352, 0x83a3, 0x0000, 0xc3c5, + 0x3302, 0x0002, 0xd1c0, 0xf3c1, 0xa080, 0x00a0, 0x0000, 0x0b25, + 0x0128, 0x0000, 0xb288, 0x3b09, 0x200c, 0x2000, 0x0020, 0xeac8, + 0xd1f0, 0x0000, 0x0020, 0x83a1, 0xc3f2, 0xc8d0, 0x0000, 0x8b91, + 0x5272, 0x0080, 0x0000, 0x0b29, 0x4376, 0x0828, 0x0000, 0x8ab8, +}; diff --git a/src/mame/machine/igs036crypt.h b/src/mame/machine/igs036crypt.h index 915c012dbb2..903cc558f1a 100644 --- a/src/mame/machine/igs036crypt.h +++ b/src/mame/machine/igs036crypt.h @@ -32,5 +32,6 @@ extern const uint16_t cjdh2_key[0x100]; extern const uint16_t kov3_key[0x100]; extern const uint16_t kov2_key[0x100]; extern const uint16_t ddpdoj_key[0x100]; +extern const uint16_t kof98umh_key[0x100]; #endif diff --git a/src/mame/machine/inder_vid.cpp b/src/mame/machine/inder_vid.cpp index 1ed764cfa58..3b7cd017c17 100644 --- a/src/mame/machine/inder_vid.cpp +++ b/src/mame/machine/inder_vid.cpp @@ -57,18 +57,18 @@ TMS340X0_TO_SHIFTREG_CB_MEMBER(inder_vid_device::to_shiftreg) { if (m_shiftfull == 0) { - //printf("read to shift regs address %08x (%08x)\n", address, TOWORD(address) * 2); + //printf("read to shift regs address %08x\n", address); - memcpy(shiftreg, &m_vram[TOWORD(address) & ~TOWORD(0x1fff)], TOBYTE(0x2000)); // & ~TOWORD(0x1fff) is needed for round 6 + memcpy(shiftreg, &m_vram[(address & ~0x1fff) >> 4], 0x400); // & ~0x1fff is needed for round 6 m_shiftfull = 1; } } TMS340X0_FROM_SHIFTREG_CB_MEMBER(inder_vid_device::from_shiftreg) { -// printf("write from shift regs address %08x (%08x)\n", address, TOWORD(address) * 2); +// printf("write from shift regs address %08x\n", address); - memcpy(&m_vram[TOWORD(address) & ~TOWORD(0x1fff)], shiftreg, TOBYTE(0x2000)); + memcpy(&m_vram[(address & ~0x1fff) >> 4], shiftreg, 0x400); m_shiftfull = 0; } diff --git a/src/mame/machine/interpro_ioga.cpp b/src/mame/machine/interpro_ioga.cpp index e790a3ab269..0d6a0dccfbb 100644 --- a/src/mame/machine/interpro_ioga.cpp +++ b/src/mame/machine/interpro_ioga.cpp @@ -165,6 +165,7 @@ DEFINE_DEVICE_TYPE(SAPPHIRE_IOGA, sapphire_ioga_device, "ioga_s", "I/O Gate Arra interpro_ioga_device::interpro_ioga_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) + , m_memory_tag(nullptr) , m_memory_space(nullptr) , m_out_nmi_func(*this) , m_out_irq_func(*this) @@ -192,13 +193,22 @@ sapphire_ioga_device::sapphire_ioga_device(const machine_config &mconfig, const { } +void interpro_ioga_device::static_set_memory(device_t &device, const char *const tag, const int spacenum) +{ + interpro_ioga_device &ioga = dynamic_cast<interpro_ioga_device &>(device); + + ioga.m_memory_tag = tag; + ioga.m_memory_spacenum = spacenum; +} + void interpro_ioga_device::device_start() { - // TODO: parameterise the cammu name and space number - // grab the main memory space from the mmu so we can do DMA to/from it - device_memory_interface *mmu; - siblingdevice("mmu")->interface(mmu); - m_memory_space = &mmu->space(0); + assert_always(m_memory_tag != nullptr, "memory tag and address space number must be configured"); + + // get the memory space + device_memory_interface *memory; + siblingdevice(m_memory_tag)->interface(memory); + m_memory_space = &memory->space(m_memory_spacenum); // resolve callbacks m_out_nmi_func.resolve(); diff --git a/src/mame/machine/interpro_ioga.h b/src/mame/machine/interpro_ioga.h index 55573a1d6ee..3d7795cd259 100644 --- a/src/mame/machine/interpro_ioga.h +++ b/src/mame/machine/interpro_ioga.h @@ -29,7 +29,8 @@ #define MCFG_INTERPRO_IOGA_ETH_CA_CB(_ca) \ devcb = &interpro_ioga_device::static_set_eth_ca_callback(*device, DEVCB_##_ca); -#define MCFG_INTERPRO_IOGA_DMA_BUS(_mmu, _space) +#define MCFG_INTERPRO_IOGA_MEMORY(_tag, _spacenum) \ + interpro_ioga_device::static_set_memory(*device, _tag, _spacenum); class interpro_ioga_device : public device_t { @@ -115,6 +116,8 @@ public: template<class _Object> static devcb_base &static_set_fdc_tc_callback(device_t &device, _Object object) { return downcast<interpro_ioga_device &>(device).m_fdc_tc_func.set_callback(object); } template<class _Object> static devcb_base &static_set_eth_ca_callback(device_t &device, _Object object) { return downcast<interpro_ioga_device &>(device).m_eth_ca_func.set_callback(object); } + static void static_set_memory(device_t &device, const char *const tag, const int spacenum); + virtual DECLARE_ADDRESS_MAP(map, 32) = 0; // interrupt request lines @@ -317,6 +320,8 @@ protected: virtual void device_reset() override; virtual ioport_constructor device_input_ports() const override; + const char *m_memory_tag; + int m_memory_spacenum; address_space *m_memory_space; // callbacks diff --git a/src/mame/machine/isbc_215g.cpp b/src/mame/machine/isbc_215g.cpp index cfb600e4730..f60eabdc3ec 100644 --- a/src/mame/machine/isbc_215g.cpp +++ b/src/mame/machine/isbc_215g.cpp @@ -354,7 +354,7 @@ MACHINE_CONFIG_MEMBER( isbc_215g_device::device_add_mconfig ) MCFG_CPU_ADD("u84", I8089, XTAL_15MHz / 3) MCFG_CPU_PROGRAM_MAP(isbc_215g_mem) MCFG_CPU_IO_MAP(isbc_215g_io) - MCFG_I8089_DATABUS_WIDTH(16) + MCFG_I8089_DATA_WIDTH(16) MCFG_HARDDISK_ADD("drive0") MCFG_HARDDISK_ADD("drive1") diff --git a/src/mame/machine/kay_kbd.cpp b/src/mame/machine/kay_kbd.cpp index de2ee0935fc..a4f5e76f835 100644 --- a/src/mame/machine/kay_kbd.cpp +++ b/src/mame/machine/kay_kbd.cpp @@ -11,6 +11,14 @@ #include "emu.h" #include "machine/kay_kbd.h" +#define LOG_GENERAL (1U << 0) +#define LOG_TXD (1U << 1) + +//#define VERBOSE (LOG_GENERAL | LOG_TXD) +#include "logmacro.h" + +#define LOGTXD(...) LOGMASKED(LOG_TXD, __VA_ARGS__) + /* * The KAYPRO keyboard has roughly the following layout: @@ -63,7 +71,7 @@ P1 is connected to the key matrix columns. P2.1, P2.2 and P2.3 are CTRL, CAPS LOCK, and SHIFT inputs. -P2.6 drives the speaker (1.5625kHz tone generated using timer/counter). +P2.5 drives the speaker (1.5625kHz tone generated using timer/counter). P2.7 is the serial data output to the host. @@ -91,9 +99,10 @@ due to bugs it omits the first byte of each page (0x000, 0x100, 0x200, The serial command processing is quite lax in what it accepts: xxxx xxx1 ignored -xxxx xx10 short beep -xxxx x100 long beep -xxx1 x000 answer back with 0xAA? +xxxx Mx10 short beep, set keyclick mute to M +xxxx M100 long beep, set keyclick mute to M +xxx1 M000 answer back with 0xAA?, set keyclick mute to M +xxx0 M000 set keyclick mute to M The Kaypro II was sold with a different keyboard using an 8751 (MCS-51) MCU, but we don't have a dump for it. @@ -113,7 +122,7 @@ ROM_START(kaypro_10_keyboard) ROM_END INPUT_PORTS_START(kaypro_keyboard_typewriter) - PORT_START("ROW.0") + PORT_START("ROW.0") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR(UCHAR_MAMEKEY(0_PAD)) PORT_NAME("Pad 0") PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') @@ -123,7 +132,7 @@ INPUT_PORTS_START(kaypro_keyboard_typewriter) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_CHAR(UCHAR_MAMEKEY(9_PAD)) PORT_NAME("Pad 9") PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xf8 - PORT_START("ROW.1") + PORT_START("ROW.1") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xa5 PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R') @@ -133,7 +142,7 @@ INPUT_PORTS_START(kaypro_keyboard_typewriter) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_CHAR(UCHAR_MAMEKEY(8_PAD)) PORT_NAME("Pad 8") PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xf7 - PORT_START("ROW.2") + PORT_START("ROW.2") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xa4 PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T') @@ -143,7 +152,7 @@ INPUT_PORTS_START(kaypro_keyboard_typewriter) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_CHAR(UCHAR_MAMEKEY(7_PAD)) PORT_NAME("Pad 7") PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xf6 - PORT_START("ROW.3") + PORT_START("ROW.3") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RALT) PORT_CHAR(10) PORT_NAME("LINE FEED") PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y') @@ -153,7 +162,7 @@ INPUT_PORTS_START(kaypro_keyboard_typewriter) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xe0 PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xf5 - PORT_START("ROW.4") + PORT_START("ROW.4") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xa3 PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U') @@ -163,7 +172,7 @@ INPUT_PORTS_START(kaypro_keyboard_typewriter) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) PORT_NAME("BACK SPACE") PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_START("ROW.5") + PORT_START("ROW.5") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') @@ -173,7 +182,7 @@ INPUT_PORTS_START(kaypro_keyboard_typewriter) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_START("ROW.6") + PORT_START("ROW.6") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I') @@ -183,7 +192,7 @@ INPUT_PORTS_START(kaypro_keyboard_typewriter) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_START("ROW.7") + PORT_START("ROW.7") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xa2 PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O') @@ -193,7 +202,7 @@ INPUT_PORTS_START(kaypro_keyboard_typewriter) PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+') PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) - PORT_START("ROW.8") + PORT_START("ROW.8") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_UNKNOWN) // 0xa1 PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@') PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') @@ -323,8 +332,9 @@ kaypro_10_keyboard_device::kaypro_10_keyboard_device( machine_config const &mconfig, char const *tag, device_t *owner, - uint32_t clock) + std::uint32_t clock) : device_t(mconfig, KAYPRO_10_KEYBOARD, tag, owner, clock) + , m_mcu(*this, "mcu") , m_bell(*this, "bell") , m_matrix(*this, "ROW.%X", 0) , m_modifiers(*this, "MOD") @@ -355,7 +365,7 @@ MACHINE_CONFIG_END ioport_constructor kaypro_10_keyboard_device::device_input_ports() const { - (void)INPUT_PORTS_NAME(kaypro_keyboard_bitshift); + (void)&INPUT_PORTS_NAME(kaypro_keyboard_bitshift); return INPUT_PORTS_NAME(kaypro_keyboard_typewriter); } @@ -379,7 +389,25 @@ READ8_MEMBER(kaypro_10_keyboard_device::p2_r) WRITE8_MEMBER(kaypro_10_keyboard_device::p2_w) { - m_bell->level_w(BIT(data, 6)); + if ((VERBOSE & LOG_TXD) && (0x0014U >= static_cast<device_state_interface *>(m_mcu)->safe_pc())) + { + auto const suppressor(machine().disable_side_effect()); + address_space &mcu_ram(m_mcu->space(AS_DATA)); + std::uint8_t const txd_time(mcu_ram.read_byte(0x1cU)); + std::uint8_t const serial_flags(mcu_ram.read_byte(0x1eU)); + bool const txd_active(BIT(serial_flags, 6)); + if ((21U == txd_time) && txd_active) + { + std::uint8_t const txd_bit(mcu_ram.read_byte(0x1bU)); + LOGTXD( + (9U == txd_bit) ? "serial transmit: start bit = %1$u (cycles = %3$u)\n" : "serial transmit: bit %2$u = %1$u (cycles = %3$u)\n", + BIT(data, 7), + 8U - txd_bit, + m_mcu->total_cycles()); + } + } + + m_bell->level_w(BIT(data, 5)); m_rxd_cb(BIT(data, 7)); } diff --git a/src/mame/machine/kay_kbd.h b/src/mame/machine/kay_kbd.h index 22edbaf207b..95a1128625e 100644 --- a/src/mame/machine/kay_kbd.h +++ b/src/mame/machine/kay_kbd.h @@ -19,7 +19,7 @@ public: machine_config const &mconfig, char const *tag, device_t *owner, - uint32_t clock); + std::uint32_t clock); template <class Object> static devcb_base &set_rxd_cb(device_t &device, Object &&cb) { return downcast<kaypro_10_keyboard_device &>(device).m_rxd_cb.set_callback(std::forward<Object>(cb)); } @@ -36,10 +36,11 @@ protected: DECLARE_READ8_MEMBER(p2_r); DECLARE_WRITE8_MEMBER(p2_w); DECLARE_READ_LINE_MEMBER(t1_r); - DECLARE_READ8_MEMBER(bus_r); - DECLARE_WRITE8_MEMBER(bus_w); + DECLARE_READ8_MEMBER(bus_r); + DECLARE_WRITE8_MEMBER(bus_w); private: + required_device<cpu_device> m_mcu; required_device<speaker_sound_device> m_bell; required_ioport_array<16> m_matrix; required_ioport m_modifiers; diff --git a/src/mame/machine/kaypro.cpp b/src/mame/machine/kaypro.cpp index 1059aeb8112..f41a81b823a 100644 --- a/src/mame/machine/kaypro.cpp +++ b/src/mame/machine/kaypro.cpp @@ -72,7 +72,7 @@ WRITE8_MEMBER( kaypro_state::kayproii_pio_system_w ) m_system_port = data; } -WRITE8_MEMBER( kaypro_state::kaypro4_pio_system_w ) +WRITE8_MEMBER( kaypro_state::kayproiv_pio_system_w ) { kayproii_pio_system_w(space, offset, data); @@ -82,19 +82,19 @@ WRITE8_MEMBER( kaypro_state::kaypro4_pio_system_w ) /*********************************************************** - KAYPRO2X SYSTEM PORT + KAYPRO484 SYSTEM PORT The PIOs were replaced by a few standard 74xx chips ************************************************************/ -READ8_MEMBER( kaypro_state::kaypro2x_system_port_r ) +READ8_MEMBER( kaypro_state::kaypro484_system_port_r ) { uint8_t data = m_centronics_busy << 6; return (m_system_port & 0xbf) | data; } -WRITE8_MEMBER( kaypro_state::kaypro2x_system_port_w ) +WRITE8_MEMBER( kaypro_state::kaypro484_system_port_w ) { /* d7 bank select d6 alternate character set (write only) @@ -138,7 +138,7 @@ WRITE8_MEMBER( kaypro_state::kaypro2x_system_port_w ) SIO - On Kaypro2x, Channel B on both SIOs is hardwired to 300 baud. + On Kaypro484, Channel B on both SIOs is hardwired to 300 baud. Both devices on sio2 (printer and modem) are not emulated. diff --git a/src/mame/machine/m3comm.cpp b/src/mame/machine/m3comm.cpp index 42f16b2c258..929d13f5b19 100644 --- a/src/mame/machine/m3comm.cpp +++ b/src/mame/machine/m3comm.cpp @@ -82,6 +82,9 @@ SEGA 1998 #include "emuopts.h" #include "machine/m3comm.h" +//#define VERBOSE 1 +#include "logmacro.h" + #define M68K_TAG "m3commcpu" //////// Model 3 (main CPU @ C00xxxxx) and Hikaru (MMctrl bank 0E) interface @@ -206,7 +209,7 @@ READ16_MEMBER(m3comm_device::ctrl_r) case 0x00 / 2: return m_commbank; default: - logerror("M3COMM CtrlRead from %04x mask %04x unimplemented!\n", offset * 2, mem_mask); + LOG("M3COMM CtrlRead from %04x mask %04x unimplemented!\n", offset * 2, mem_mask); return 0; } } @@ -228,7 +231,7 @@ WRITE16_MEMBER(m3comm_device::ctrl_w) case 0xE0 / 2: // unknown, conditionally cleared in IRQ6 (receive complete) handler break; default: - logerror("M3COMM CtrlWrite to %04x %04x mask %04x\n", offset * 2, data, mem_mask); + LOG("M3COMM CtrlWrite to %04x %04x mask %04x\n", offset * 2, data, mem_mask); } } @@ -249,7 +252,7 @@ READ16_MEMBER(m3comm_device::ioregs_r) case 0x8A / 2: return m_status1; default: - logerror("M3COMM IOread from %02x mask %04x\n", offset * 2, mem_mask); + LOG("M3COMM IOread from %02x mask %04x\n", offset * 2, mem_mask); return 0; } } @@ -262,11 +265,11 @@ WRITE16_MEMBER(m3comm_device::ioregs_w) break; // it seems one of these ^v is IRQ6 ON/ACK, another is data transfer enable case 0x16 / 2: // written 8C at data receive enable, 0 at IRQ6 handler if ((data & 0xFF) == 0x8C) { - logerror("M3COMM Receive offs %04x size %04x\n", recv_offset, recv_size); + LOG("M3COMM Receive offs %04x size %04x\n", recv_offset, recv_size); /* if (!m_line_rx.is_open()) { - logerror("M3COMM: listen on %s\n", m_localhost); + LOG("M3COMM: listen on %s\n", m_localhost); m_line_rx.open(m_localhost); } if (m_line_rx.is_open()) @@ -282,11 +285,11 @@ WRITE16_MEMBER(m3comm_device::ioregs_w) break; // it seems one of these ^v is IRQ4 ON/ACK, another is data transfer enable case 0x1C / 2: // written 8C at data transmit enable, 0 at IRQ4 handler if ((data & 0xFF) == 0x8C) { - logerror("M3COMM Send offs %04x size %04x\n", send_offset, send_size); + LOG("M3COMM Send offs %04x size %04x\n", send_offset, send_size); /* if (!m_line_tx.is_open()) { - logerror("M3COMM: connect to %s\n", m_remotehost); + LOG("M3COMM: connect to %s\n", m_remotehost); m_line_tx.open(m_remotehost); } if (m_line_tx.is_open()) @@ -320,7 +323,7 @@ WRITE16_MEMBER(m3comm_device::ioregs_w) m_commcpu->set_input_line(INPUT_LINE_RESET, data ? CLEAR_LINE : ASSERT_LINE); break; default: - logerror("M3COMM IOwrite to %02x %04x mask %04x\n", offset * 2, data, mem_mask); + LOG("M3COMM IOwrite to %02x %04x mask %04x\n", offset * 2, data, mem_mask); return; } } @@ -373,7 +376,7 @@ READ16_MEMBER(m3comm_device::naomi_r) return naomi_offset; case 2: // 5F7020 { -// logerror("M3COMM read @ %08x\n", (naomi_control << 16) | naomi_offset); +// LOG("M3COMM read @ %08x\n", (naomi_control << 16) | naomi_offset); uint16_t value; if (naomi_control & 1) value = m68k_ram[naomi_offset / 2]; // FIXME endian @@ -405,7 +408,7 @@ WRITE16_MEMBER(m3comm_device::naomi_w) // bit 7: ??? // bit 14: G1 DMA bus master 0 - active / 1 - disabled // bit 15: 0 - enable / 1 - disable this device ??? -// logerror("M3COMM control write %04x\n", data); +// LOG("M3COMM control write %04x\n", data); naomi_control = data; m_commcpu->set_input_line(INPUT_LINE_RESET, (naomi_control & 0x20) ? CLEAR_LINE : ASSERT_LINE); break; @@ -413,7 +416,7 @@ WRITE16_MEMBER(m3comm_device::naomi_w) naomi_offset = data; break; case 2: // 5F7020 -// logerror("M3COMM write @ %08x %04x\n", (naomi_control << 16) | naomi_offset, data); +// LOG("M3COMM write @ %08x %04x\n", (naomi_control << 16) | naomi_offset, data); if (naomi_control & 1) m68k_ram[naomi_offset / 2] = data; // FIXME endian else { diff --git a/src/mame/machine/mac.cpp b/src/mame/machine/mac.cpp index 41b6546655a..57a9bed5901 100644 --- a/src/mame/machine/mac.cpp +++ b/src/mame/machine/mac.cpp @@ -3190,20 +3190,20 @@ const char *lookup_trap(uint16_t opcode) -offs_t mac_state::mac_dasm_override(device_t &device, std::ostream &stream, offs_t pc, const uint8_t *oprom, const uint8_t *opram, int options) +offs_t mac_state::mac_dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms) { uint16_t opcode; unsigned result = 0; const char *trap; - opcode = oprom[0]<<8 | oprom[1]; + opcode = opcodes.r16(pc); if ((opcode & 0xF000) == 0xA000) { trap = lookup_trap(opcode); if (trap != nullptr) { stream << trap; - result = 2; + result = 2 | util::disasm_interface::SUPPORTED; } } return result; diff --git a/src/mame/machine/mc80.cpp b/src/mame/machine/mc80.cpp deleted file mode 100644 index 2b6423ec25d..00000000000 --- a/src/mame/machine/mc80.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Miodrag Milanovic -/*************************************************************************** - - MC-80.xx by Miodrag Milanovic - - 15/05/2009 Initial implementation - 12/05/2009 Skeleton driver. - -****************************************************************************/ - -#include "emu.h" -#include "includes/mc80.h" - -/*****************************************************************************/ -/* Implementation for MC80.2x */ -/*****************************************************************************/ - -IRQ_CALLBACK_MEMBER(mc80_state::mc8020_irq_callback) -{ - return 0x00; -} - -MACHINE_RESET_MEMBER(mc80_state,mc8020) -{ -} - -WRITE_LINE_MEMBER( mc80_state::ctc_z0_w ) -{ -} - -WRITE_LINE_MEMBER( mc80_state::ctc_z1_w ) -{ -} - -WRITE_LINE_MEMBER(mc80_state::ctc_z2_w) -{ - downcast<z80ctc_device *>(machine().device("z80ctc"))->trg0(state); - downcast<z80ctc_device *>(machine().device("z80ctc"))->trg1(state); -} - -READ8_MEMBER( mc80_state::mc80_port_b_r ) -{ - return 0; -} - -READ8_MEMBER( mc80_state::mc80_port_a_r ) -{ - return 0; -} - -WRITE8_MEMBER( mc80_state::mc80_port_a_w ) -{ -} - -WRITE8_MEMBER( mc80_state::mc80_port_b_w ) -{ -} - -/*****************************************************************************/ -/* Implementation for MC80.3x */ -/*****************************************************************************/ - -WRITE8_MEMBER( mc80_state::mc8030_zve_write_protect_w ) -{ -} - -WRITE8_MEMBER( mc80_state::mc8030_vis_w ) -{ - // reg C - // 7 6 5 4 -- module - // 3 - 0 left half, 1 right half - // 2 1 0 - // ===== - // 0 0 0 - dark - // 0 0 1 - light - // 0 1 0 - in reg pixel - // 0 1 1 - negate in reg pixel - // 1 0 x - operation code in B reg - // reg B - // - uint16_t addr = ((offset & 0xff00) >> 2) | ((offset & 0x08) << 2) | (data >> 3); - static const uint8_t val[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 }; - int c = offset & 1; - m_p_videoram[addr] = m_p_videoram[addr] | (val[data & 7]*c); -} - -WRITE8_MEMBER( mc80_state::mc8030_eprom_prog_w ) -{ -} - -IRQ_CALLBACK_MEMBER(mc80_state::mc8030_irq_callback ) -{ - return 0x20; -} - -MACHINE_RESET_MEMBER(mc80_state,mc8030) -{ -} - -READ8_MEMBER( mc80_state::zve_port_a_r ) -{ - return 0xff; -} - -READ8_MEMBER( mc80_state::zve_port_b_r ) -{ - return 0xff; -} - -WRITE8_MEMBER( mc80_state::zve_port_a_w ) -{ -} - -WRITE8_MEMBER( mc80_state::zve_port_b_w ) -{ -} - -READ8_MEMBER( mc80_state::asp_port_a_r ) -{ - return 0xff; -} - -READ8_MEMBER( mc80_state::asp_port_b_r ) -{ - return 0xff; -} - -WRITE8_MEMBER( mc80_state::asp_port_a_w ) -{ -} - -WRITE8_MEMBER( mc80_state::asp_port_b_w ) -{ -} diff --git a/src/mame/machine/micro3d.cpp b/src/mame/machine/micro3d.cpp index 512a9483b53..dbc18a3018a 100644 --- a/src/mame/machine/micro3d.cpp +++ b/src/mame/machine/micro3d.cpp @@ -34,7 +34,7 @@ WRITE_LINE_MEMBER(micro3d_state::duart_irq_handler) { - m_maincpu->set_input_line_and_vector(3, state, m_duart68681->get_irq_vector()); + m_maincpu->set_input_line_and_vector(3, state, m_duart->get_irq_vector()); } WRITE_LINE_MEMBER(micro3d_state::duart_txb) @@ -52,7 +52,7 @@ READ8_MEMBER(micro3d_state::data_to_i8031) WRITE8_MEMBER(micro3d_state::data_from_i8031) { - m_duart68681->rx_b_w(data); + m_duart->rx_b_w(data); } /* @@ -84,131 +84,24 @@ WRITE8_MEMBER(micro3d_state::duart_output_w) * *************************************/ -enum +READ8_MEMBER( micro3d_state::vgb_uart_r ) { - RX, TX, STATUS, SYN1, SYN2, DLE, MODE1, MODE2, COMMAND -}; + // the mode and sync registers switched places? + if (offset == 1 || offset == 2) + offset ^= 3; - -WRITE16_MEMBER(micro3d_state::micro3d_ti_uart_w) -{ - switch (offset) - { - case 0x0: - { - m_ti_uart[TX] = data; -#if VGB_MONITOR_DISPLAY - mame_debug_printf("%c",data); -#endif - m_ti_uart[STATUS] |= 1; - break; - } - case 0x1: - { - if (m_ti_uart_mode_cycle == 0) - { - m_ti_uart[MODE1] = data; - m_ti_uart_mode_cycle = 1; - } - else - { - m_ti_uart[MODE2] = data; - m_ti_uart_mode_cycle = 0; - } - break; - } - case 0x2: - { - if (m_ti_uart_sync_cycle == 0) - { - m_ti_uart[SYN1] = data; - m_ti_uart_mode_cycle = 1; - } - else if (m_ti_uart_sync_cycle == 1) - { - m_ti_uart[SYN2] = data; - m_ti_uart_mode_cycle = 2; - } - else - { - m_ti_uart[DLE] = data; - m_ti_uart_mode_cycle = 0; - } - break; - } - case 0x3: - { - m_ti_uart[COMMAND] = data; - m_ti_uart_mode_cycle = 0; - m_ti_uart_sync_cycle = 0; - break; - } - } + return m_vgb_uart->read(space, offset); } -READ16_MEMBER(micro3d_state::micro3d_ti_uart_r) +WRITE8_MEMBER( micro3d_state::vgb_uart_w ) { - switch (offset) - { - case 0x0: - { - m_ti_uart[STATUS] ^= 2; - return m_ti_uart[RX]; - } - case 0x1: - { - if (m_ti_uart_mode_cycle == 0) - { - m_ti_uart_mode_cycle = 1; - return m_ti_uart[MODE1]; - } - else - { - m_ti_uart_mode_cycle = 0; - return m_ti_uart[MODE2]; - } - } - case 0x2: - { - return m_ti_uart[STATUS]; - } - case 0x3: - { - m_ti_uart_mode_cycle = m_ti_uart_sync_cycle = 0; - return m_ti_uart[COMMAND]; - } - default: - { - logerror("Unknown TI UART access.\n"); - return 0; - } - } -} - + // the mode and sync registers switched places? + if (offset == 1 || offset == 2) + offset ^= 3; -/************************************* - * - * Z8530 SCC (Am29000) - * - *************************************/ - -WRITE32_MEMBER(micro3d_state::micro3d_scc_w) -{ -#if DRMATH_MONITOR_DISPLAY - if (offset == 1) - osd_printf_debug("%c", data); -#endif + m_vgb_uart->write(space, offset, data); } -READ32_MEMBER(micro3d_state::micro3d_scc_r) -{ - if (offset == 1) - return 0xd; - else - return 5; -} - - /************************************* * @@ -239,9 +132,6 @@ void micro3d_state::device_timer(emu_timer &timer, device_timer_id id, int param case TIMER_MAC_DONE: mac_done_callback(ptr, param); break; - case TIMER_ADC_DONE: - adc_done_callback(ptr, param); - break; default: assert_always(false, "Unknown id in micro3d_state::device_timer"); } @@ -483,36 +373,9 @@ READ16_MEMBER(micro3d_state::micro3d_encoder_l_r) return ((y_encoder & 0xff) << 8) | (x_encoder & 0xff); } -TIMER_CALLBACK_MEMBER(micro3d_state::adc_done_callback) +READ8_MEMBER( micro3d_state::adc_volume_r ) { - switch (param) - { - case 0: m_adc_val = m_throttle.read_safe(0); - break; - case 1: m_adc_val = (uint8_t)((255.0/100.0) * m_volume->read() + 0.5); - break; - case 2: break; - case 3: break; - } - -// mc68901_int_gen(machine(), GPIP3); -} - -READ16_MEMBER(micro3d_state::micro3d_adc_r) -{ - return m_adc_val; -} - -WRITE16_MEMBER(micro3d_state::micro3d_adc_w) -{ - /* Only handle single-ended mode */ - if (data < 4 || data > 7) - { - logerror("ADC0844 unhandled MUX mode: %x\n", data); - return; - } - - timer_set(attotime::from_usec(40), TIMER_ADC_DONE, data & ~4); + return (uint8_t)((255.0/100.0) * m_volume->read() + 0.5); } CUSTOM_INPUT_MEMBER(micro3d_state::botss_hwchk_r) @@ -682,8 +545,6 @@ DRIVER_INIT_MEMBER(micro3d_state,botss) void micro3d_state::machine_reset() { - m_ti_uart[STATUS] = 1; - m_vgb->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); m_drmath->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); m_audiocpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); diff --git a/src/mame/machine/midtunit.cpp b/src/mame/machine/midtunit.cpp index 283ccdca76a..7c03273ab9f 100644 --- a/src/mame/machine/midtunit.cpp +++ b/src/mame/machine/midtunit.cpp @@ -298,35 +298,35 @@ WRITE16_MEMBER(midtunit_state::jdredd_prot_w) switch (offset) { - case TOWORD(0x10740): + case 0x1074: m_jdredd_prot_index = 0; m_jdredd_prot_table = jdredd_prot_values_10740; m_jdredd_prot_max = sizeof(jdredd_prot_values_10740); logerror("-- reset prot table 10740\n"); break; - case TOWORD(0x13240): + case 0x1324: m_jdredd_prot_index = 0; m_jdredd_prot_table = jdredd_prot_values_13240; m_jdredd_prot_max = sizeof(jdredd_prot_values_13240); logerror("-- reset prot table 13240\n"); break; - case TOWORD(0x76540): + case 0x7654: m_jdredd_prot_index = 0; m_jdredd_prot_table = jdredd_prot_values_76540; m_jdredd_prot_max = sizeof(jdredd_prot_values_76540); logerror("-- reset prot table 76540\n"); break; - case TOWORD(0x77760): + case 0x7776: m_jdredd_prot_index = 0; m_jdredd_prot_table = jdredd_prot_values_77760; m_jdredd_prot_max = sizeof(jdredd_prot_values_77760); logerror("-- reset prot table 77760\n"); break; - case TOWORD(0x80020): + case 0x8002: m_jdredd_prot_index = 0; m_jdredd_prot_table = jdredd_prot_values_80020; m_jdredd_prot_max = sizeof(jdredd_prot_values_80020); diff --git a/src/mame/machine/midxunit.cpp b/src/mame/machine/midxunit.cpp index a23c8208abb..49bd7d4ca1e 100644 --- a/src/mame/machine/midxunit.cpp +++ b/src/mame/machine/midxunit.cpp @@ -26,9 +26,9 @@ void midxunit_state::register_state_saving() save_item(NAME(m_cmos_write_enable)); save_item(NAME(m_iodata)); save_item(NAME(m_ioshuffle)); - save_item(NAME(m_analog_port)); save_item(NAME(m_uart)); save_item(NAME(m_security_bits)); + save_item(NAME(m_adc_int)); } @@ -103,6 +103,12 @@ WRITE16_MEMBER(midxunit_state::midxunit_unknown_w) } +WRITE_LINE_MEMBER(midxunit_state::adc_int_w) +{ + m_adc_int = (state != CLEAR_LINE); +} + + /************************************* * @@ -110,47 +116,10 @@ WRITE16_MEMBER(midxunit_state::midxunit_unknown_w) * *************************************/ -READ16_MEMBER(midxunit_state::midxunit_io_r) -{ - static const char *const portnames[] = { "IN0", "IN1", "IN2", "DSW" }; - - offset = (offset / 2) % 8; - - switch (offset) - { - case 0: - case 1: - case 2: - case 3: - return ioport(portnames[offset])->read(); - - default: - logerror("%08X:Unknown I/O read from %d\n", space.device().safe_pc(), offset); - break; - } - return ~0; -} - - -READ16_MEMBER(midxunit_state::midxunit_analog_r) -{ - static const char *const portnames[] = { "AN0", "AN1", "AN2", "AN3", "AN4", "AN5" }; - - return ioport(portnames[m_analog_port])->read(); -} - - -WRITE16_MEMBER(midxunit_state::midxunit_analog_select_w) -{ - if (offset == 0 && ACCESSING_BITS_0_7) - m_analog_port = data - 8; -} - - READ16_MEMBER(midxunit_state::midxunit_status_r) { /* low bit indicates whether the ADC is done reading the current input */ - return (m_midway_serial_pic->status_r(space,0) << 1) | 1; + return (m_midway_serial_pic->status_r(space,0) << 1) | (m_adc_int ? 1 : 0); } diff --git a/src/mame/machine/midyunit.cpp b/src/mame/machine/midyunit.cpp index 3ca36e5a485..d35a1f23b06 100644 --- a/src/mame/machine/midyunit.cpp +++ b/src/mame/machine/midyunit.cpp @@ -69,7 +69,7 @@ WRITE16_MEMBER(midyunit_state::midyunit_cmos_enable_w) { if (data == 0x500) { - m_prot_result = space.read_word(TOBYTE(0x10a4390)) << 4; + m_prot_result = space.read_word(0x8521c80) << 4; logerror(" desired result = %04X\n", m_prot_result); } } @@ -130,14 +130,7 @@ READ16_MEMBER(midyunit_state::term2_input_r) if (offset != 2) return m_ports[offset]->read(); - switch (m_term2_analog_select) - { - default: - case 0: return ioport("STICK0_X")->read(); - case 1: return ioport("STICK0_Y")->read(); - case 2: return ioport("STICK1_X")->read(); - case 3: return ioport("STICK1_Y")->read(); - } + return m_term2_adc->read(space, 0) | 0xff00; } WRITE16_MEMBER(midyunit_state::term2_sound_w) @@ -167,7 +160,7 @@ WRITE16_MEMBER(midyunit_state::term2_sound_w) } if (offset == 0) - m_term2_analog_select = (data >> 12) & 3; + m_term2_adc->write(space, 0, ((data >> 12) & 3) | 4); m_adpcm_sound->reset_write((~data & 0x100) >> 1); m_adpcm_sound->write(space, offset, data); diff --git a/src/mame/machine/mtx.cpp b/src/mame/machine/mtx.cpp index 11a4eb3d76a..5c081036b0a 100644 --- a/src/mame/machine/mtx.cpp +++ b/src/mame/machine/mtx.cpp @@ -36,6 +36,31 @@ READ8_MEMBER(mtx_state::mtx_strobe_r) } /*------------------------------------------------- + mtx_subpage_w - rom2 subpages +-------------------------------------------------*/ + +/* + The original ROM card supported 4 8KB ROM chips. These appeared in + ROM slot 2 in subpages 0 to 3. The subpage register starts as 0, but + is changed by attempting to write to 0x0000-0x1fff whilst in RELCPMH=0 + mode (ie. attempting to write to the OS ROM). Videowalls could use a + later ROM card with 4 32KB ROMs. These also appeared in ROM slot 2 + in subpages 0 to 15. +*/ + +WRITE8_MEMBER(mtx_state::mtx_subpage_w) +{ + if (m_extrom->exists()) + { + if ((data * 0x2000) < m_extrom->get_rom_size()) + membank("rommap_bank1")->configure_entry(2, m_extrom->get_rom_base() + 0x2000 * data); + else + membank("rommap_bank1")->configure_entry(2, memregion("user2")->base() + 0x4000); + membank("rommap_bank1")->set_entry(2); + } +} + +/*------------------------------------------------- mtx_bankswitch_w - bankswitch -------------------------------------------------*/ @@ -73,33 +98,74 @@ void mtx_state::bankswitch(uint8_t data) */ address_space &program = m_maincpu->space(AS_PROGRAM); - ram_device *messram = m_ram; - -// uint8_t cbm_mode = data >> 7 & 0x01; - uint8_t rom_page = data >> 4 & 0x07; - uint8_t ram_page = data >> 0 & 0x0f; - /* set rom bank (switches between basic and assembler rom or cartridges) */ - membank("bank2")->set_entry(rom_page); + uint8_t cbm_mode = (data >> 7) & 0x01; + uint8_t rom_page = (data >> 4) & 0x07; + uint8_t ram_page = (data >> 0) & 0x0f; - /* set ram bank, for invalid pages a nop-handler will be installed */ - if (ram_page >= messram->size()/0x8000) + if (cbm_mode) { - program.nop_readwrite(0x4000, 0x7fff); - program.nop_readwrite(0x8000, 0xbfff); - } - else if (ram_page + 1 == messram->size()/0x8000) - { - program.nop_readwrite(0x4000, 0x7fff); - program.install_readwrite_bank(0x8000, 0xbfff, "bank4"); - membank("bank4")->set_entry(ram_page); + /* ram based memory map */ + program.install_readwrite_bank(0x0000, 0x3fff, "rammap_bank1"); + program.install_readwrite_bank(0x4000, 0x7fff, "rammap_bank2"); + program.install_readwrite_bank(0x8000, 0xbfff, "rammap_bank3"); + + /* set ram bank, for invalid pages a nop-handler will be installed */ + switch (ram_page) + { + case 0: + if (ram_page * 0xc000 + 0x10000 <= m_ram->size()) + membank("rammap_bank1")->set_entry(ram_page); + else + program.nop_readwrite(0x0000, 0x3fff); + if (ram_page * 0xc000 + 0xc000 <= m_ram->size()) + membank("rammap_bank2")->set_entry(ram_page); + else + program.nop_readwrite(0x4000, 0x7fff); + if (ram_page * 0xc000 + 0x8000 <= m_ram->size()) + membank("rammap_bank3")->set_entry(ram_page); + else + program.nop_readwrite(0x8000, 0xbfff); + break; + + default: + if (ram_page * 0xc000 + 0x8000 <= m_ram->size()) + membank("rammap_bank1")->set_entry(ram_page); + else + program.nop_readwrite(0x0000, 0x3fff); + if (ram_page * 0xc000 + 0xc000 <= m_ram->size()) + membank("rammap_bank2")->set_entry(ram_page); + else + program.nop_readwrite(0x4000, 0x7fff); + if (ram_page * 0xc000 + 0x10000 <= m_ram->size()) + membank("rammap_bank3")->set_entry(ram_page); + else + program.nop_readwrite(0x8000, 0xbfff); + break; + } } else { - program.install_readwrite_bank(0x4000, 0x7fff, "bank3"); - program.install_readwrite_bank(0x8000, 0xbfff, "bank4"); - membank("bank3")->set_entry(ram_page); - membank("bank4")->set_entry(ram_page); + /* rom based memory map */ + program.install_rom(0x0000, 0x1fff, memregion("user1")->base()); + program.install_write_handler(0x0000, 0x1fff, write8_delegate(FUNC(mtx_state::mtx_subpage_w), this)); + program.install_read_bank(0x2000, 0x3fff, "rommap_bank1"); + program.unmap_write(0x2000, 0x3fff); + program.install_readwrite_bank(0x4000, 0x7fff, "rommap_bank2"); + program.install_readwrite_bank(0x8000, 0xbfff, "rommap_bank3"); + + /* set rom bank (switches between basic and assembler rom or cartridges) */ + membank("rommap_bank1")->set_entry(rom_page); + + /* set ram bank, for invalid pages a nop-handler will be installed */ + if (ram_page * 0x8000 + 0xc000 <= m_ram->size()) + membank("rommap_bank2")->set_entry(ram_page); + else + program.nop_readwrite(0x4000, 0x7fff); + if (ram_page * 0x8000 + 0x8000 <= m_ram->size()) + membank("rommap_bank3")->set_entry(ram_page); + else + program.nop_readwrite(0x8000, 0xbfff); } } @@ -137,6 +203,15 @@ WRITE8_MEMBER(mtx_state::mtx_cst_w) } /*------------------------------------------------- + mtx_cst_motor_w - cassette motor +-------------------------------------------------*/ + +WRITE8_MEMBER(mtx_state::mtx_cst_motor_w) +{ + m_cassette->change_state(data ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR); +} + +/*------------------------------------------------- mtx_prt_r - centronics status -------------------------------------------------*/ @@ -330,6 +405,46 @@ WRITE8_MEMBER(mtx_state::hrx_attr_w) } /*************************************************************************** + EXTENSION BOARD ROMS +***************************************************************************/ + +DEVICE_IMAGE_LOAD_MEMBER( mtx_state, extrom_load ) +{ + uint32_t size = m_extrom->common_get_size("rom"); + + if (size > 0x80000) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported rom size"); + return image_init_result::FAIL; + } + + m_extrom->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); + m_extrom->common_load_rom(m_extrom->get_rom_base(), size, "rom"); + + return image_init_result::PASS; +} + +/*************************************************************************** + ROMPAK ROMS +***************************************************************************/ + +DEVICE_IMAGE_LOAD_MEMBER( mtx_state, rompak_load ) +{ + uint32_t size = m_rompak->common_get_size("rom"); + + if (size > 0x2000) + { + image.seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); + return image_init_result::FAIL; + } + + m_rompak->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); + m_rompak->common_load_rom(m_rompak->get_rom_base(), size, "rom"); + + return image_init_result::PASS; +} + +/*************************************************************************** SNAPSHOT ***************************************************************************/ @@ -396,18 +511,40 @@ SNAPSHOT_LOAD_MEMBER( mtx_state, mtx ) MACHINE_START( mtx512 ) -------------------------------------------------*/ -MACHINE_START_MEMBER(mtx_state,mtx512) +MACHINE_START_MEMBER(mtx_state, mtx512) { - ram_device *messram = m_ram; + address_space &program = m_maincpu->space(AS_PROGRAM); - /* configure memory */ - membank("bank1")->set_base(memregion("user1")->base()); - membank("bank2")->configure_entries(0, 8, memregion("user2")->base(), 0x2000); - membank("bank3")->configure_entries(0, messram->size()/0x4000/2, messram->pointer(), 0x4000); - membank("bank4")->configure_entries(0, messram->size()/0x4000/2, messram->pointer() + messram->size()/2, 0x4000); + /* setup banks for rom based memory map */ + program.install_read_bank(0x2000, 0x3fff, "rommap_bank1"); + program.install_readwrite_bank(0x4000, 0x7fff, "rommap_bank2"); + program.install_readwrite_bank(0x8000, 0xbfff, "rommap_bank3"); + + membank("rommap_bank1")->configure_entries(0, 8, memregion("user2")->base(), 0x2000); + if (m_extrom->exists()) + membank("rommap_bank1")->configure_entry(2, m_extrom->get_rom_base()); + if (m_rompak->exists()) + membank("rommap_bank1")->configure_entry(7, m_rompak->get_rom_base()); + membank("rommap_bank2")->configure_entries(0, 16, m_ram->pointer() + 0x8000, 0x8000); + membank("rommap_bank3")->configure_entries(0, 16, m_ram->pointer() + 0x4000, 0x8000); + + /* setup banks for ram based memory map */ + program.install_readwrite_bank(0x0000, 0x3fff, "rammap_bank1"); + program.install_readwrite_bank(0x4000, 0x7fff, "rammap_bank2"); + program.install_readwrite_bank(0x8000, 0xbfff, "rammap_bank3"); + + membank("rammap_bank1")->configure_entry(0, m_ram->pointer() + 0xc000); + membank("rammap_bank1")->configure_entries(1, 15, m_ram->pointer() + 0x10000, 0xc000); + membank("rammap_bank2")->configure_entry(0, m_ram->pointer() + 0x8000); + membank("rammap_bank2")->configure_entries(1, 15, m_ram->pointer() + 0x14000, 0xc000); + membank("rammap_bank3")->configure_entry(0, m_ram->pointer() + 0x4000); + membank("rammap_bank3")->configure_entries(1, 15, m_ram->pointer() + 0x18000, 0xc000); + + /* install 4000h bytes common block */ + program.install_ram(0xc000, 0xffff, m_ram->pointer()); } -MACHINE_RESET_MEMBER(mtx_state,mtx512) +MACHINE_RESET_MEMBER(mtx_state, mtx512) { /* bank switching */ bankswitch(0); diff --git a/src/mame/machine/namcos2.cpp b/src/mame/machine/namcos2.cpp index 876b79fc799..eb055be1911 100644 --- a/src/mame/machine/namcos2.cpp +++ b/src/mame/machine/namcos2.cpp @@ -504,7 +504,7 @@ WRITE8_MEMBER( namcos2_shared_state::namcos2_mcu_analog_ctrl_w ) /* If the interrupt enable bit is set trigger an A/D IRQ */ if(data & 0x20) { - generic_pulse_irq_line(*m_mcu, HD63705_INT_ADCONV, 1); + m_mcu->pulse_input_line(HD63705_INT_ADCONV, m_mcu->minimum_quantum_time()); } } } diff --git a/src/mame/machine/osborne1.cpp b/src/mame/machine/osborne1.cpp index f535aaf2383..29e00df8dfb 100644 --- a/src/mame/machine/osborne1.cpp +++ b/src/mame/machine/osborne1.cpp @@ -53,8 +53,7 @@ READ8_MEMBER( osborne1_state::bank_2xxx_3xxx_r ) } if ((offset & 0xA00) == 0xA00) // Serial { - if (offset & 0x01) data &= m_acia->data_r(space, 0); - else data &= m_acia->status_r(space, 0); + data &= m_acia->read(space, offset & 0x01); } if ((offset & 0xC00) == 0x400) // SCREEN-PAC { @@ -80,8 +79,7 @@ WRITE8_MEMBER( osborne1_state::bank_2xxx_3xxx_w ) m_pia0->write(space, offset & 0x03, data); if ((offset & 0xA00) == 0xA00) // Serial { - if (offset & 0x01) m_acia->data_w(space, 0, data); - else m_acia->control_w(space, 0, data); + m_acia->write(space, offset & 0x01, data); } if ((offset & 0xC00) == 0x400) // SCREEN-PAC { diff --git a/src/mame/machine/pgmprot_igs027a_type3.cpp b/src/mame/machine/pgmprot_igs027a_type3.cpp index 9bfcbded9d9..5dd50881dfb 100644 --- a/src/mame/machine/pgmprot_igs027a_type3.cpp +++ b/src/mame/machine/pgmprot_igs027a_type3.cpp @@ -90,7 +90,7 @@ READ16_MEMBER(pgm_arm_type3_state::svg_68k_nmi_r ) WRITE16_MEMBER(pgm_arm_type3_state::svg_68k_nmi_w ) { - generic_pulse_irq_line(*m_prot, ARM7_FIRQ_LINE, 1); + m_prot->pulse_input_line(ARM7_FIRQ_LINE, m_prot->minimum_quantum_time()); } WRITE16_MEMBER(pgm_arm_type3_state::svg_latch_68k_w ) diff --git a/src/mame/machine/scramble.cpp b/src/mame/machine/scramble.cpp index 5fffd91625c..2a6f978276b 100644 --- a/src/mame/machine/scramble.cpp +++ b/src/mame/machine/scramble.cpp @@ -2,7 +2,7 @@ // copyright-holders:Nicola Salmoria /*************************************************************************** - machine.c + machine/scramble.cpp Functions to emulate general aspects of the machine (RAM, ROM, interrupts, I/O ports) @@ -571,10 +571,6 @@ DRIVER_INIT_MEMBER(scramble_state,mrkougar) DRIVER_INIT_CALL(devilfsh); } -DRIVER_INIT_MEMBER(scramble_state,mrkougb) -{ -} - DRIVER_INIT_MEMBER(scramble_state,ad2083) { uint8_t c; diff --git a/src/mame/machine/slapstic.cpp b/src/mame/machine/slapstic.cpp index cffbaa13d91..28f12fb7821 100644 --- a/src/mame/machine/slapstic.cpp +++ b/src/mame/machine/slapstic.cpp @@ -835,7 +835,7 @@ int atari_slapstic_device::alt2_kludge(address_space &space, offs_t offset) if (MATCHES_MASK_VALUE(space.device().safe_pc() >> 1, slapstic.alt1)) { /* now look for a move.w (An),(An) or cmpm.w (An)+,(An)+ */ - uint16_t opcode = space.direct().read_word(space.device().safe_pcbase() & 0xffffff); + uint16_t opcode = space.read_word(space.device().safe_pcbase() & 0xffffff); if ((opcode & 0xf1f8) == 0x3090 || (opcode & 0xf1f8) == 0xb148) { /* fetch the value of the register for the second operand, and see */ diff --git a/src/mame/machine/swtpc09.cpp b/src/mame/machine/swtpc09.cpp index 9e7773a09fb..e41dbb8e305 100644 --- a/src/mame/machine/swtpc09.cpp +++ b/src/mame/machine/swtpc09.cpp @@ -150,9 +150,8 @@ WRITE8_MEMBER ( swtpc09_state::dmf2_control_reg_w ) /* FDC controller dma transfer */ void swtpc09_state::swtpc09_fdc_dma_transfer() { - uint8_t *RAM = memregion("maincpu")->base(); uint32_t offset; - address_space &space = m_maincpu->space(AS_PROGRAM); + address_space &space = *m_banked_space; offset = (m_fdc_dma_address_reg & 0x0f)<<16; @@ -163,11 +162,11 @@ void swtpc09_state::swtpc09_fdc_dma_transfer() uint8_t data = m_fdc->data_r(space, 0); LOG(("swtpc09_dma_write_mem %05X %02X\n", m_m6844_channel[0].address + offset, data)); - RAM[m_m6844_channel[0].address + offset] = data; + space.write_byte(m_m6844_channel[0].address + offset, data); } else { - uint8_t data = RAM[m_m6844_channel[0].address + offset]; + uint8_t data = space.read_byte(m_m6844_channel[0].address + offset); m_fdc->data_w(space, 0, data); //LOG(("swtpc09_dma_read_mem %04X %02X\n", m_m6844_channel[0].address, data)); @@ -453,128 +452,20 @@ WRITE8_MEMBER( swtpc09_state::piaide_b_w ) /* memory map is created based on system_type flag */ /* this is accommodate the different cards installed */ -WRITE8_MEMBER(swtpc09_state::dat_w) +offs_t swtpc09_state::dat_translate(offs_t offset) const { - uint8_t a16_to_a19, a12_to_a15; - uint8_t *RAM = memregion("maincpu")->base(); - uint32_t physical_address, logical_address; - - address_space &mem = m_maincpu->space(AS_PROGRAM); - - fd1793_device *fdc = machine().device<fd1793_device>("fdc"); - pia6821_device *pia = machine().device<pia6821_device>("pia"); - ptm6840_device *ptm = machine().device<ptm6840_device>("ptm"); - acia6850_device *acia = machine().device<acia6850_device>("acia"); - via6522_device *via = machine().device<via6522_device>("via"); - pia6821_device *piaide = machine().device<pia6821_device>("piaide"); - - a16_to_a19 = data & 0xf0; - a12_to_a15 = ~data & 0x0f; //lower 4 bits are inverted - physical_address = ((a16_to_a19 + a12_to_a15) << 12); - logical_address = offset << 12; - LOG(("swtpc09_dat_bank_unmap Logical address:%04X\n", offset << 12 )); - LOG(("swtpc09_dat_bank_set dat:%02X Logical address:%04X Physical address:%05X\n", data, offset << 12, physical_address )); - - - // unmap page to be changed - mem.unmap_readwrite(offset << 12, (offset << 12)+0x0fff); - - // map in new page - if (a12_to_a15 == 0x0e) // 0xE000 address range to be mapped in at this page - { - if (m_system_type == FLEX_DMF2) // if flex/sbug, map in acia at 0xE004 - { - mem.nop_readwrite(logical_address+0x000, logical_address+0x003); - mem.install_readwrite_handler(logical_address+0x004, logical_address+0x004, read8_delegate(FUNC(acia6850_device::status_r), acia), write8_delegate(FUNC(acia6850_device::control_w),acia)); - mem.install_readwrite_handler(logical_address+0x005, logical_address+0x005, read8_delegate(FUNC(acia6850_device::data_r), acia), write8_delegate(FUNC(acia6850_device::data_w),acia)); - mem.nop_readwrite(logical_address+0x006, logical_address+0x07f); - mem.install_readwrite_handler(logical_address+0x080, logical_address+0x08f, read8_delegate(FUNC(pia6821_device::read), pia), write8_delegate(FUNC(pia6821_device::write), pia)); - mem.install_readwrite_handler(logical_address+0x090, logical_address+0x09f, read8_delegate(FUNC(ptm6840_device::read), ptm), write8_delegate(FUNC(ptm6840_device::write), ptm)); - mem.nop_readwrite(logical_address+0x0a0, logical_address+0xfff); - } - else if (m_system_type == FLEX_DC4_PIAIDE) // if flex/sbug and dc4 and piaide - { - mem.nop_readwrite(logical_address+0x000, logical_address+0x003); - mem.install_readwrite_handler(logical_address+0x004, logical_address+0x004, read8_delegate(FUNC(acia6850_device::status_r), acia), write8_delegate(FUNC(acia6850_device::control_w),acia)); - mem.install_readwrite_handler(logical_address+0x005, logical_address+0x005, read8_delegate(FUNC(acia6850_device::data_r), acia), write8_delegate(FUNC(acia6850_device::data_w),acia)); - mem.install_write_handler(logical_address+0x014, logical_address+0x014, write8_delegate(FUNC(swtpc09_state::dc4_control_reg_w),this)); - mem.install_readwrite_handler(logical_address+0x018, logical_address+0x01b, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); - //mem.nop_readwrite(logical_address+0x01c, logical_address+0x05f); - mem.install_readwrite_handler(logical_address+0x060, logical_address+0x06f, read8_delegate(FUNC(pia6821_device::read), piaide), write8_delegate(FUNC(pia6821_device::write), piaide)); - //mem.nop_readwrite(logical_address+0x070, logical_address+0x07f); - mem.install_readwrite_handler(logical_address+0x080, logical_address+0x08f, read8_delegate(FUNC(pia6821_device::read), pia), write8_delegate(FUNC(pia6821_device::write), pia)); - mem.install_readwrite_handler(logical_address+0x090, logical_address+0x09f, read8_delegate(FUNC(ptm6840_device::read), ptm), write8_delegate(FUNC(ptm6840_device::write), ptm)); - //mem.nop_readwrite(logical_address+0x0a0, logical_address+0x7ff); - mem.install_rom(logical_address+0x800, logical_address+0xfff, &RAM[0xe800]); //piaide rom - } - else // assume unibug, map in acia at 0xE000 - { - mem.install_readwrite_handler(logical_address+0x000, logical_address+0x000, read8_delegate(FUNC(acia6850_device::status_r), acia), write8_delegate(FUNC(acia6850_device::control_w), acia)); - mem.install_readwrite_handler(logical_address+0x001, logical_address+0x001, read8_delegate(FUNC(acia6850_device::data_r), acia), write8_delegate(FUNC(acia6850_device::data_w), acia)); - mem.nop_readwrite(logical_address+0x002, logical_address+0x07f); - mem.install_readwrite_handler(logical_address+0x080, logical_address+0x08f, read8_delegate(FUNC(pia6821_device::read), pia), write8_delegate(FUNC(pia6821_device::write), pia)); - mem.install_readwrite_handler(logical_address+0x090, logical_address+0x09f, read8_delegate(FUNC(ptm6840_device::read), ptm), write8_delegate(FUNC(ptm6840_device::write), ptm)); - mem.nop_readwrite(logical_address+0x0a0, logical_address+0xfff); - } - } - else if (a12_to_a15 == 0x0f) // 0xF000 address range to be mapped in at this page - { - if (m_system_type == UNIFLEX_DMF2 || m_system_type == FLEX_DMF2) // if DMF2 conroller this is the map - { - mem.install_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this)); - mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); - mem.install_readwrite_handler(logical_address+0x024, logical_address+0x03f, read8_delegate(FUNC(swtpc09_state::dmf2_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_control_reg_w),this)); - mem.install_readwrite_handler(logical_address+0x040, logical_address+0x041, read8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_w),this)); - //mem.nop_readwrite(logical_address+0x042, logical_address+0x7ff); - mem.install_rom(logical_address+0x800, logical_address+0xfff, &RAM[0xf800]); - mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); - } - else if (m_system_type == FLEX_DC4_PIAIDE) // 2k ram for piaide on s09 board - { - //mem.install_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this)); - //mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); - //mem.install_readwrite_handler(logical_address+0x024, logical_address+0x03f, read8_delegate(FUNC(swtpc09_state::dmf2_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_control_reg_w),this)); - //mem.install_readwrite_handler(logical_address+0x040, logical_address+0x041, read8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf2_dma_address_reg_w),this)); - mem.install_ram(logical_address+0x000, logical_address+0x7ff, &RAM[0xf000]); - mem.install_rom(logical_address+0x800, logical_address+0xfff, &RAM[0xf800]); - mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); - } - else // assume DMF3 controller - { - mem.install_readwrite_handler(logical_address+0x000, logical_address+0x01f, read8_delegate(FUNC(swtpc09_state::m6844_r),this), write8_delegate(FUNC(swtpc09_state::m6844_w),this)); - mem.install_readwrite_handler(logical_address+0x020, logical_address+0x023, read8_delegate(FUNC(fd1793_device::read), fdc), write8_delegate(FUNC(fd1793_device::write),fdc)); - mem.install_readwrite_handler(logical_address+0x024, logical_address+0x024, read8_delegate(FUNC(swtpc09_state::dmf3_control_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf3_control_reg_w),this)); - mem.install_readwrite_handler(logical_address+0x025, logical_address+0x025, read8_delegate(FUNC(swtpc09_state::dmf3_dma_address_reg_r),this), write8_delegate(FUNC(swtpc09_state::dmf3_dma_address_reg_w),this)); - //mem.nop_readwrite(logical_address+0x030, logical_address+0x03f); - mem.install_readwrite_handler(logical_address+0x040, logical_address+0x04f, read8_delegate(FUNC(via6522_device::read), via), write8_delegate(FUNC(via6522_device::write), via)); - //mem.nop_readwrite(logical_address+0x050, logical_address+0x7ff); - mem.install_rom(logical_address+0x800, logical_address+0xfff, &RAM[0xf800]); - mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); - } - } - else if (offset==0x0f) // then we need to leave in top part of ram and dat write - { - mem.install_ram(logical_address, logical_address+0x0eff, &RAM[physical_address]); - mem.install_rom(logical_address+0xf00, logical_address+0xfff, &RAM[0xff00]); - mem.install_write_handler(logical_address+0xff0, logical_address+0xfff, write8_delegate(FUNC(swtpc09_state::dat_w),this)); - - } - else // all the rest is treated as ram, 1MB ram emulated - { - mem.install_ram(logical_address, logical_address+0x0fff, &RAM[physical_address]); - } + // lower 4 bits are inverted + return offs_t(m_dat[offset >> 12] ^ 0x0f) << 12 | (offset & 0x0fff); +} -// unused code to limit to 256k ram -// else if (!(a12_to_a15 & 0x0c) ) // limit ram to 256k || a12_to_a15 == 0x02 -// { -// memory_install_ram(space, logical_address, logical_address+0x0fff, 0, 0, &RAM[physical_address]); -// } -// -// else // all the rest is treated as unallocated -// { -// memory_nop_readwrite(space, logical_address, logical_address+0x0fff, 0, 0); -// } +READ8_MEMBER(swtpc09_state::main_r) +{ + return m_banked_space->read_byte(dat_translate(offset)); +} +WRITE8_MEMBER(swtpc09_state::main_w) +{ + m_banked_space->write_byte(dat_translate(offset), data); } /* MC6844 DMA controller I/O */ @@ -771,18 +662,16 @@ WRITE8_MEMBER( swtpc09_state::m6844_w ) } -DRIVER_INIT_MEMBER( swtpc09_state, swtpc09 ) +void swtpc09_state::machine_start() { - int i; m_pia_counter = 0; // init ptm/pia counter to 0 m_term_data = 0; // terminal keyboard input m_fdc_status = 0; // for floppy controller - m_system_type = FLEX_DMF2; m_interrupt = 0; m_active_interrupt = false; - /* reset the 6844 */ - for (i = 0; i < 4; i++) + // reset the 6844 + for (int i = 0; i < 4; i++) { m_m6844_channel[i].active = 0; m_m6844_channel[i].control = 0x00; @@ -791,72 +680,29 @@ DRIVER_INIT_MEMBER( swtpc09_state, swtpc09 ) m_m6844_interrupt = 0x00; m_m6844_chain = 0x00; + m_banked_space = &subdevice<address_map_bank_device>("bankdev")->space(AS_PROGRAM); + + m_brg->rsa_w(0); + m_brg->rsb_w(1); +} + +DRIVER_INIT_MEMBER( swtpc09_state, swtpc09 ) +{ + m_system_type = FLEX_DMF2; } DRIVER_INIT_MEMBER( swtpc09_state, swtpc09i ) { - int i; - m_pia_counter = 0; // init ptm/pia counter to 0 - m_term_data = 0; // terminal keyboard input - m_fdc_status = 0; // for floppy controller m_system_type = FLEX_DC4_PIAIDE; - m_interrupt = 0; - m_active_interrupt = false; - - /* reset the 6844 */ - for (i = 0; i < 4; i++) - { - m_m6844_channel[i].active = 0; - m_m6844_channel[i].control = 0x00; - } - m_m6844_priority = 0x00; - m_m6844_interrupt = 0x00; - m_m6844_chain = 0x00; - } DRIVER_INIT_MEMBER( swtpc09_state, swtpc09u ) { - int i; - m_pia_counter = 0; //init ptm/pia counter to 0 - m_term_data = 0; //terminal keyboard input - m_fdc_status = 0; // for floppy controller m_system_type = UNIFLEX_DMF2; - m_interrupt = 0; - m_active_interrupt = false; - - /* reset the 6844 */ - for (i = 0; i < 4; i++) - { - m_m6844_channel[i].active = 0; - m_m6844_channel[i].control = 0x00; - } - m_m6844_priority = 0x00; - m_m6844_interrupt = 0x00; - m_m6844_chain = 0x00; - } DRIVER_INIT_MEMBER( swtpc09_state, swtpc09d3 ) { - int i; - m_pia_counter = 0; //init ptm/pia counter to 0 - m_term_data = 0; //terminal keyboard input - m_fdc_status = 0; // for floppy controller m_via_ca1_input = 0; m_system_type = UNIFLEX_DMF3; - m_interrupt = 0; - m_active_interrupt = false; - - - /* reset the 6844 */ - for (i = 0; i < 4; i++) - { - m_m6844_channel[i].active = 0; - m_m6844_channel[i].control = 0x00; - } - m_m6844_priority = 0x00; - m_m6844_interrupt = 0x00; - m_m6844_chain = 0x00; - } diff --git a/src/mame/machine/taitocchip.cpp b/src/mame/machine/taitocchip.cpp index dfd85aa29fa..8b91b163508 100644 --- a/src/mame/machine/taitocchip.cpp +++ b/src/mame/machine/taitocchip.cpp @@ -167,8 +167,8 @@ MACHINE_CONFIG_MEMBER( taito_cchip_device::device_add_mconfig ) MCFG_DEVICE_ADD("upd4464_bank", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(cchip_ram_bank) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(13) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(13) MCFG_ADDRESS_MAP_BANK_STRIDE(0x400) MACHINE_CONFIG_END diff --git a/src/mame/machine/thomson.cpp b/src/mame/machine/thomson.cpp index 5147e0418fa..a5c958f1eb6 100644 --- a/src/mame/machine/thomson.cpp +++ b/src/mame/machine/thomson.cpp @@ -226,100 +226,13 @@ WRITE_LINE_MEMBER( thomson_state::mo5_set_cassette_motor ) /* ------------ IRQs ------------ */ -void thomson_state::thom_set_irq( int line, int state ) -{ - int old = m_thom_irq; - - if ( state ) - m_thom_irq |= 1 << line; - else - m_thom_irq &= ~(1 << line); - - if ( !old && m_thom_irq ) - LOG_IRQ(( "%f thom_set_irq: irq line up %i\n", machine().time().as_double(), line )); - if ( old && !m_thom_irq ) - LOG_IRQ(( "%f thom_set_irq: irq line down %i\n", machine().time().as_double(), line )); - - m_maincpu->set_input_line(M6809_IRQ_LINE, m_thom_irq ? ASSERT_LINE : CLEAR_LINE); -} - - - -void thomson_state::thom_set_firq ( int line, int state ) -{ - int old = m_thom_firq; - - if ( state ) - m_thom_firq |= 1 << line; - else - m_thom_firq &= ~(1 << line); - - if ( !old && m_thom_firq ) - LOG_IRQ(( "%f thom_set_firq: firq line up %i\n", machine().time().as_double(), line )); - if ( old && !m_thom_firq ) - LOG_IRQ(( "%f thom_set_firq: firq line down %i\n", machine().time().as_double(), line )); - - m_maincpu->set_input_line(M6809_FIRQ_LINE, m_thom_firq ? ASSERT_LINE : CLEAR_LINE); -} - - - void thomson_state::thom_irq_reset() { - m_thom_irq = 0; - m_thom_firq = 0; - m_maincpu->set_input_line(M6809_IRQ_LINE, CLEAR_LINE ); - m_maincpu->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE ); -} - - - -void thomson_state::thom_irq_init() -{ - save_item(NAME(m_thom_irq)); - save_item(NAME(m_thom_firq)); -} - - - -void thomson_state::thom_irq_0( int state ) -{ - thom_set_irq( 0, state ); -} - -WRITE_LINE_MEMBER( thomson_state::thom_dev_irq_0 ) -{ - thom_irq_0( state ); + m_mainfirq->in_w<2>(0); } -WRITE_LINE_MEMBER( thomson_state::thom_irq_1 ) -{ - thom_set_irq ( 1, state ); -} - -void thomson_state::thom_irq_3( int state ) -{ - thom_set_irq ( 3, state ); -} - -WRITE_LINE_MEMBER( thomson_state::thom_firq_1 ) -{ - thom_set_firq ( 1, state ); -} - -void thomson_state::thom_firq_2( int state ) -{ - thom_set_firq ( 2, state ); -} - -void thomson_state::thom_irq_4( int state ) -{ - thom_set_irq ( 4, state ); -} - - /* current IRQ usage: @@ -614,8 +527,8 @@ MACHINE_CONFIG_MEMBER( to7_io_line_device::device_add_mconfig ) MCFG_PIA_WRITEPA_HANDLER(WRITE8(to7_io_line_device, porta_out)) MCFG_PIA_WRITEPB_HANDLER(DEVWRITE8("cent_data_out", output_latch_device, write)) MCFG_PIA_CB2_HANDLER(DEVWRITELINE("centronics", centronics_device, write_strobe)) - MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("^", thomson_state, thom_firq_1)) - MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("^", thomson_state, thom_firq_1)) + MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("^mainfirq", input_merger_device, in_w<1>)) + MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("^mainfirq", input_merger_device, in_w<1>)) MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr) MCFG_RS232_RXD_HANDLER(WRITELINE(to7_io_line_device, write_rxd)) @@ -769,10 +682,8 @@ READ8_MEMBER( thomson_state::to7_modem_mea8000_r ) switch (offset) { case 0: - return m_acia->status_r(space, offset ); - case 1: - return m_acia->data_r(space, offset ); + return m_acia->read(space, offset & 1); default: return 0; @@ -793,11 +704,8 @@ WRITE8_MEMBER( thomson_state::to7_modem_mea8000_w ) switch (offset) { case 0: - m_acia->control_w( space, offset, data ); - break; - case 1: - m_acia->data_w( space, offset, data ); + m_acia->write(space, offset & 1, data); break; } } @@ -1087,7 +995,6 @@ MACHINE_START_MEMBER( thomson_state, to7 ) LOG (( "to7: machine start called\n" )); /* subsystems */ - thom_irq_init(); to7_game_init(); to7_floppy_init(mem + 0x20000); to7_modem_init(); @@ -1311,7 +1218,6 @@ MACHINE_START_MEMBER( thomson_state, to770 ) LOG (( "to770: machine start called\n" )); /* subsystems */ - thom_irq_init(); to7_game_init(); to7_floppy_init( mem + 0x20000 ); to7_modem_init(); @@ -1692,7 +1598,6 @@ MACHINE_START_MEMBER( thomson_state, mo5 ) LOG (( "mo5: machine start called\n" )); /* subsystems */ - thom_irq_init(); to7_game_init(); to7_floppy_init( mem + 0x20000 ); to7_modem_init(); @@ -2155,7 +2060,7 @@ void thomson_state::to9_kbd_update_irq() if ( (m_to9_kbd_intr & 3) == 1 && (m_to9_kbd_status & ACIA_6850_TDRE) ) m_to9_kbd_status |= ACIA_6850_irq; /* ready to transmit interrupt */ - thom_irq_3( m_to9_kbd_status & ACIA_6850_irq ); + m_mainirq->in_w<3>( m_to9_kbd_status & ACIA_6850_irq ); } @@ -2635,7 +2540,6 @@ MACHINE_START_MEMBER( thomson_state, to9 ) LOG (( "to9: machine start called\n" )); /* subsystems */ - thom_irq_init(); to7_game_init(); to9_floppy_init( mem + 0xe000, mem + 0x40000 ); to9_kbd_init(); @@ -3332,7 +3236,7 @@ READ8_MEMBER( thomson_state::to8_gatearray_r ) { if ( !machine().side_effect_disabled() ) { - thom_firq_2( 0 ); + m_mainfirq->in_w<2>(0); m_to8_lightpen_intr = 0; } res = count & 0xff; @@ -3579,7 +3483,7 @@ void thomson_state::to8_lightpen_cb( int step ) if ( ! m_to7_lightpen ) return; - thom_firq_2( 1 ); + m_mainfirq->in_w<2>(1); m_to7_lightpen_step = step; m_to8_lightpen_intr = 1; } @@ -3646,7 +3550,6 @@ MACHINE_START_MEMBER( thomson_state, to8 ) LOG (( "to8: machine start called\n" )); /* subsystems */ - thom_irq_init(); to7_game_init(); to8_floppy_init(); to8_kbd_init(); @@ -3797,7 +3700,6 @@ MACHINE_START_MEMBER( thomson_state, to9p ) LOG (( "to9p: machine start called\n" )); /* subsystems */ - thom_irq_init(); to7_game_init(); to8_floppy_init(); to9_kbd_init(); @@ -4287,7 +4189,7 @@ READ8_MEMBER( thomson_state::mo6_gatearray_r ) { if ( !machine().side_effect_disabled() ) { - thom_firq_2( 0 ); + m_mainfirq->in_w<2>(0); m_to8_lightpen_intr = 0; } res = count & 0xff; @@ -4483,7 +4385,6 @@ MACHINE_START_MEMBER( thomson_state, mo6 ) LOG (( "mo6: machine start called\n" )); /* subsystems */ - thom_irq_init(); mo6_game_init(); to7_floppy_init( mem + 0x30000 ); to9_palette_init(); @@ -4707,7 +4608,6 @@ MACHINE_START_MEMBER( thomson_state, mo5nr ) LOG (( "mo5nr: machine start called\n" )); /* subsystems */ - thom_irq_init(); mo5nr_game_init(); to7_floppy_init( mem + 0x30000 ); to9_palette_init(); diff --git a/src/mame/machine/trs80.cpp b/src/mame/machine/trs80.cpp index 6b12bb3ab26..39b804a7bbd 100644 --- a/src/mame/machine/trs80.cpp +++ b/src/mame/machine/trs80.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Robbbert and unknown others +// copyright-holders:Robbbert,FSanches and unknown others /*************************************************************************** machine.c @@ -204,6 +204,23 @@ READ8_MEMBER( trs80_state::trs80m4_ff_r ) return m_port_ec | m_cassette_data; } +READ8_MEMBER( trs80_state::cp500_a11_flipflop_toggle ) +{ + /* The A11 flipflop is used for enabling access to + the system monitor code at the EPROM address range 3800-3fff */ + uint8_t *rom = memregion("maincpu")->base(); + uint8_t *bootrom = memregion("bootrom")->base(); + int block; + + m_a11_flipflop ^= 1; //toggle the flip-flop at every read at io addresses 0xf4-f7 + + for (block=0; block<8; block++){ + memcpy(&rom[block * 0x800], &bootrom[(block | m_a11_flipflop) * 0x800], 0x800); + } + + return 0x00; //really?! +} + WRITE8_MEMBER( trs80_state::trs80m4_84_w ) { @@ -841,6 +858,12 @@ MACHINE_RESET_MEMBER(trs80_state,lnw80) lnw80_fe_w(space, 0, 0); } +MACHINE_RESET_MEMBER(trs80_state,cp500) +{ + m_a11_flipflop = 0; + MACHINE_RESET_CALL_MEMBER( trs80m4 ); +} + /*************************************************************************** PARAMETERS diff --git a/src/mame/machine/twincobr.cpp b/src/mame/machine/twincobr.cpp index 8f8c9ae783e..06567272092 100644 --- a/src/mame/machine/twincobr.cpp +++ b/src/mame/machine/twincobr.cpp @@ -13,7 +13,6 @@ #define LOG_DSP_CALLS 0 #define LOG(x) do { if (LOG_DSP_CALLS) logerror x; } while (0) -static const int toaplan_port_type[2] = { 0x7800c, 0x5c }; INTERRUPT_GEN_MEMBER(twincobr_state::twincobr_interrupt) @@ -176,64 +175,55 @@ READ_LINE_MEMBER(twincobr_state::twincobr_BIO_r) } -void twincobr_state::twincobr_dsp(int enable) +WRITE_LINE_MEMBER(twincobr_state::int_enable_w) { - m_dsp_on = enable; - if (enable) { + m_intenable = state; +} + +WRITE_LINE_MEMBER(twincobr_state::dsp_int_w) +{ + m_dsp_on = state; + if (state) + { + // assert the INT line to the DSP LOG(("Turning DSP on and main CPU off\n")); m_dsp->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); - m_dsp->set_input_line(0, ASSERT_LINE); /* TMS32010 INT */ + m_dsp->set_input_line(0, ASSERT_LINE); // TMS32010 INT m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); } - else { + else + { + // inhibit the INT line to the DSP LOG(("Turning DSP off\n")); - m_dsp->set_input_line(0, CLEAR_LINE); /* TMS32010 INT */ + m_dsp->set_input_line(0, CLEAR_LINE); // TMS32010 INT m_dsp->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); } } void twincobr_state::twincobr_restore_dsp() { - twincobr_dsp(m_dsp_on); + dsp_int_w(m_dsp_on); } -void twincobr_state::toaplan0_control_w(int offset, int data) +WRITE_LINE_MEMBER(twincobr_state::coin_counter_1_w) { - LOG(("%s:Writing %08x to %08x.\n",machine().describe_context(),data,toaplan_port_type[m_toaplan_main_cpu] - offset)); - - if (m_toaplan_main_cpu == 1) { - if (data == 0x0c) { data = 0x1c; } /* Z80 ? */ - if (data == 0x0d) { data = 0x1d; } /* Z80 ? */ - } + machine().bookkeeping().coin_counter_w(0, state); +} - switch (data) { - case 0x0004: m_intenable = 0; break; - case 0x0005: m_intenable = 1; break; - case 0x0006: twincobr_flipscreen(0); break; - case 0x0007: twincobr_flipscreen(1); break; - case 0x0008: m_bg_ram_bank = 0x0000; break; - case 0x0009: m_bg_ram_bank = 0x1000; break; - case 0x000a: m_fg_rom_bank = 0x0000; break; - case 0x000b: m_fg_rom_bank = 0x1000; break; - case 0x000c: twincobr_dsp(1); break; /* Enable the INT line to the DSP */ - case 0x000d: twincobr_dsp(0); break; /* Inhibit the INT line to the DSP */ - case 0x000e: twincobr_display(0); break; /* Turn display off */ - case 0x000f: twincobr_display(1); break; /* Turn display on */ - } +WRITE_LINE_MEMBER(twincobr_state::coin_counter_2_w) +{ + machine().bookkeeping().coin_counter_w(1, state); } -WRITE16_MEMBER(twincobr_state::twincobr_control_w) +WRITE_LINE_MEMBER(twincobr_state::coin_lockout_1_w) { - if (ACCESSING_BITS_0_7) - { - toaplan0_control_w(offset, data & 0xff); - } + machine().bookkeeping().coin_counter_w(0, !state); } -WRITE8_MEMBER(twincobr_state::wardner_control_w) +WRITE_LINE_MEMBER(twincobr_state::coin_lockout_2_w) { - toaplan0_control_w(offset, data); + machine().bookkeeping().coin_counter_w(1, !state); } @@ -251,59 +241,8 @@ WRITE16_MEMBER(twincobr_state::twincobr_sharedram_w) } -void twincobr_state::toaplan0_coin_dsp_w(address_space &space, int offset, int data) -{ - if (data > 1) - LOG(("%s:Writing %08x to %08x.\n",machine().describe_context(),data,toaplan_port_type[m_toaplan_main_cpu] - offset)); - switch (data) { - case 0x08: machine().bookkeeping().coin_counter_w(0,0); break; - case 0x09: machine().bookkeeping().coin_counter_w(0,1); break; - case 0x0a: machine().bookkeeping().coin_counter_w(1,0); break; - case 0x0b: machine().bookkeeping().coin_counter_w(1,1); break; - case 0x0c: machine().bookkeeping().coin_lockout_w(0,1); break; - case 0x0d: machine().bookkeeping().coin_lockout_w(0,0); break; - case 0x0e: machine().bookkeeping().coin_lockout_w(1,1); break; - case 0x0f: machine().bookkeeping().coin_lockout_w(1,0); break; - /****** The following apply to Flying Shark/Wardner only ******/ - case 0x00: /* This means assert the INT line to the DSP */ - LOG(("Turning DSP on and main CPU off\n")); - m_dsp->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); - m_dsp->set_input_line(0, ASSERT_LINE); /* TMS32010 INT */ - m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); - break; - case 0x01: /* This means inhibit the INT line to the DSP */ - LOG(("Turning DSP off\n")); - m_dsp->set_input_line(0, CLEAR_LINE); /* TMS32010 INT */ - m_dsp->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); - break; - } -} - - -WRITE16_MEMBER(twincobr_state::fshark_coin_dsp_w) -{ - if (ACCESSING_BITS_0_7) - { - toaplan0_coin_dsp_w(space, offset, data & 0xff); - } -} - -WRITE8_MEMBER(twincobr_state::twincobr_coin_w) -{ - toaplan0_coin_dsp_w(space, offset, data); -} - -WRITE8_MEMBER(twincobr_state::wardner_coin_dsp_w) -{ - toaplan0_coin_dsp_w(space, offset, data); -} - - MACHINE_RESET_MEMBER(twincobr_state,twincobr) { - m_toaplan_main_cpu = 0; /* 68000 */ - twincobr_display(0); - m_intenable = 0; m_dsp_addr_w = 0; m_main_ram_seg = 0; m_dsp_execute = 0; @@ -313,7 +252,6 @@ MACHINE_RESET_MEMBER(twincobr_state,twincobr) void twincobr_state::twincobr_driver_savestate() { - save_item(NAME(m_toaplan_main_cpu)); save_item(NAME(m_intenable)); save_item(NAME(m_dsp_on)); save_item(NAME(m_dsp_addr_w)); diff --git a/src/mame/mame.lst b/src/mame/mame.lst index ac6830cff0e..a3adca7212a 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -1079,7 +1079,9 @@ asma2k // asmapro // @source:alphatpx.cpp +alphatp2 alphatp3 // 1982 Triumph-Adler +alphatp30 @source:alphatro.cpp alphatro // @@ -1087,9 +1089,15 @@ alphatro // @source:altair.cpp al8800bt // +@source:alto1.cpp +alto1 // 1973 Xerox Alto I + @source:alto2.cpp alto2 // +@source:altos2.cpp +altos2 // Altos II terminal + @source:altos5.cpp altos5 // @@ -1181,6 +1189,9 @@ sigma2k // (c) 2000 Sigma sigmapkr // (c) 1995 Sigma videomat // 1990 bootleg +@source:ampex.cpp +dialog80 // Ampex Dialogue 80 + @source:ampro.cpp ampro // @@ -1520,7 +1531,6 @@ mammothm // (c) 1997 marmagic // (c) 2000 marmagicu // (c) 2000 marmagicua // (c) 2000 -marmagicub // (c) 2000 minemine // (c) 1996 minemineu // (c) 1996 monmouse // (c) 1997 @@ -2274,7 +2284,11 @@ at486 // 19?? IBM AT 486 atvga // 19?? AT VGA at386sx // 19?? AT VGA 386sx c386sx16 // 1990 Commodore 386SX-16 -cmdpc30 // +pc30iii // Commodore PC 30-III +pc40iii // Commodore PC 40-III +mbc28 // Sanyo MBC-28 +comportiii // Compaq Portable III +pcd2 // Siemens PCD-2 ct386sx // ec1842 // ec1849 // @@ -2567,8 +2581,12 @@ tajmah // Tajmahal @source:att4425.cpp att4425 // +@source:att630.cpp +att630 // + @source:attache.cpp -attache // +attache // (c) 1982 Otrona +attache816 // (c) 1983 Otrona @source:attckufo.cpp attckufo // (c) 1980 Ryoto Electric Co. @@ -2649,6 +2667,7 @@ cshift // (c) 1984 gghost // (c) 1984 gimeabrk // (c) 1985 grudge // prototype - Bally/Midway +grudgep // hattrick // (c) 1984 teamht // minigolf // (c) 1985 @@ -8793,10 +8812,12 @@ blockoutj // TA-0029 (c) 1989 + California Dreams (Japan) @source:bloodbro.cpp bloodbro // (c) 1990 Tad -bloodbroa // (c) 1990 Tad -bloodbrob // (c) 1990 Tad +bloodbroj // (c) 1990 Tad +bloodbroja // (c) 1990 Tad +bloodbrou // (c) 1990 Tad + Fabtek license skysmash // (c) 1990 Nihon System Inc. -weststry // bootleg +weststory // bootleg +weststorya // bootleg @source:blstroid.cpp blstroid // 136057 (c) 1987 @@ -9323,6 +9344,7 @@ mazinger // (c) 1994 Banpresto (country is in EEPROM) mazingerj // (c) 1994 Banpresto (country is in EEPROM) metmqstr // (c) 1995 Banpresto / Pandorabox nmaster // (c) 1995 Banpresto / Pandorabox +paceight // (c) 1996 Namco pacslot // (c) 1996 Namco plegends // (c) 1994 Atlus plegendsj // (c) 1994 Atlus @@ -9526,8 +9548,8 @@ champbasj // (c) 1983 Alpha Denshi Co. champbasja // (c) 1983 Alpha Denshi Co. champbasjb // (c) 1983 Alpha Denshi Co. champbb2 // (c) 1983 Sega -champbb2a // (c) 1983 ? champbb2j // (c) 1983 ? +tbasebal // (c) 1983 ? exctscc2 // (c) 1984 Alpha Denshi Co. exctsccr // (c) 1983 Alpha Denshi Co. exctsccra // (c) 1983 Alpha Denshi Co. @@ -9700,6 +9722,9 @@ f1gpstr2 // (c) 1993 Jaleco scudhamm // (c) 1994 Jaleco wildplt // (c) 1992 Jaleco +@source:cit220.cpp +cit220p // (c) 1984 C. Itoh + @source:citycon.cpp citycon // (c) 1985 Jaleco citycona // (c) 1985 Jaleco @@ -9789,9 +9814,11 @@ coco // Color Computer coco2 // Color Computer 2 coco2b // Color Computer 2B (uses M6847T1 video chip) cocoe // Color Computer (Extended BASIC 1.0) -cp400 // Prologica CP400 -lzcolor64 // Digiponto LZ Color64 +cp400 // Prológica CP400 +cp400c2 // Prológica CP400 Color II +lzcolor64 // Novo Tempo / LZ Equipamentos Color64 mx1600 // Dynacom MX-1600 +cd6809 // Codimex CD-6809 t4426 // Terco 4426 CNC programming station @source:coco3.cpp @@ -10621,6 +10648,7 @@ tsarevna // tsarevnaa // @source:cv1k.cpp +akatana // (c) 2010 Cave (AMI license) - 2010/ 8/13 MASTER VER. ddpdfk // (c) 2008 Cave (AMI license) - 2008/06/23 MASTER VER 1.5 ddpdfk10 // (c) 2008 Cave (AMI license) - 2008/05/16 MASTER VER deathsml // (c) 2007 Cave (AMI license) - 2007/10/09 MASTER VER @@ -10708,6 +10736,9 @@ skydest // PD0 (c) 1985 Taito Corporation @source:czk80.cpp czk80 // +@source:d400.cpp +d461 // + @source:d6800.cpp d6800 // Dream 6800 @@ -12221,6 +12252,10 @@ espial // (c) 1983 Thunderbolt, Orca logo is hidden in espialu // (c) 1983 Thunderbolt, Orca logo is hidden in title screen netwars // (c) 1983 Orca + Esco Trading Co license +@source:esprit.cpp +esprit // Hazeltine Esprit +esprit3 // Hazeltine Esprit III + @source:esq1.cpp esq1 // 1986 ESQ-1 Digital Wave Synthesizer esqm // 1986 ESQ-M rack-mount ESQ-1 @@ -12567,6 +12602,7 @@ super9ccg // * German super9ccsp // * Spanish @source:fidel68k.cpp +fdes2265 // feagv10 // feagv11 // feagv2 // @@ -13596,6 +13632,7 @@ pwrflip // (c) 1994 Excellent System amuse // (c) 1982 Greyhound Electronics amuse1 // (c) 1982 Greyhound Electronics amuse1a // (c) 1983 Greyhound Electronics +bigjoke // (c) 1987 Greyhound Electronics findout // (c) 1987 [Elettronolo] geimulti // (c) 1992 Grayhound Electronics gepoker // (c) 1984 Greyhound Electronics @@ -14740,6 +14777,7 @@ tbreakup // Tomy tc4 // Coleco tcfball // Tandy Radio Shack tcfballa // Tandy Radio Shack +xl25 // Vulcan zodiac // Coleco @source:hh_ucom4.cpp @@ -14845,6 +14883,8 @@ holeland2 // (c) 1984 @source:homedata.cpp battlcry // (c) 1991 Home Data +battlcryc // (c) 1989 Home Data +battlcryp // (c) 1989 Home Data hourouki // (c) 1987 Home Data jogakuen // (c) 1992 Windom corporation lemnangl // (c) 1990 Home Data @@ -14910,6 +14950,9 @@ hp1650b // hp1651b // hp165ka0 // +@source:hp2100.cpp +hp2100 // HP 2100 and HP 1000 + @source:hp48.cpp hp38g // hp39g // @@ -15495,7 +15538,7 @@ jackie // (c) 1993 IGS jackpool // (c) 1997 Electronic Projects @source:jade.cpp -jade // +jgz80 // Jade JGZ-80 @source:jaguar.cpp a51mxr3k // ?? (c) 1998 @@ -17128,12 +17171,18 @@ wndrplnt // (c) 1987 Data East Corporation (Japan) kas89 // 1989, SFC S.R.L. @source:kaypro.cpp -kaypro10 // Kaypro 10 -kaypro2x // Kaypro 2 - 2/84 -kaypro4 // Kaypro 4 - 4/83 -kaypro4a // Kaypro 4 - 4/84 -kaypro4p88 // Kaypro 4 - 4/83 w/plus88 board installed +kaypro1 // Kaypro 1 +kaypro10 // Kaypro 10/83 +kaypro1084 // Kaypro 10/84 +kaypro2x // Kaypro 2x +kaypro4x // Kaypro 4x +kaypro284 // Kaypro 2 - 2/84 +kaypro484 // Kaypro 4 - 4/84 +kayproiip88 // Kaypro II - 4/83 w/plus88 board installed +kaypro484p88 // Kaypro 4/84 - 4/84 w/plus88 board installed kayproii // Kaypro II - 2/83 +kayproiv // Kaypro IV - 4/83 +kaypronew2 // Kaypro new 2 omni2 // Omni II omni4 // Omni 4 robie // Kaypro Robie @@ -17464,6 +17513,7 @@ trsm100 // @source:kyugo.cpp 99lstwar // (c) 1985 Proma 99lstwara // (c) 1985 Proma +99lstwarb // bootleg 99lstwark // (c) 1985 Kyugo airwolf // (c) 1987 Kyugo airwolfa // (c) 1987 Kyugo @@ -17867,6 +17917,9 @@ m40 // m24 // m240 // +@source:m3.cpp +m3 // + @source:m5.cpp m5 // m5p // @@ -20211,8 +20264,10 @@ mc1000 // mc1502 // pk88 // -@source:mc80.cpp +@source:mc8020.cpp mc8020 // MC 80.2x + +@source:mc8030.cpp mc8030 // MC 80.3x @source:mcatadv.cpp @@ -20690,7 +20745,11 @@ mhavocp // 136025 (c) 1983 mhavocrv // (hack) @source:mice.cpp -mice // +mice_6502 // (c) 1981 Microtek International, Inc. +mice2_z80 // (c) 1986 Microtek International, Inc. +mice2_6502 // (c) 1986 Microtek International, Inc. +mice2_8085 // (c) 1986 Microtek International, Inc. +mice2_6809 // (c) 1986 Microtek International, Inc. @source:micral.cpp micral // @@ -20722,6 +20781,10 @@ pentacup2 // @source:microtan.cpp microtan // 1979 Microtan 65 +@source:microterm.cpp +mt420 // +mt5510 // + @source:microvsn.cpp microvsn // Milton Bradley @@ -20869,6 +20932,9 @@ mk4b // (c) 1997 Midway (v1.0) thegrid // (c) 2001 Midway (v1.2) Latest offical release thegrida // (c) 2001 Midway (v1.1) +@source:mightyframe.cpp +mightyframe // Convergent + @source:mikie.cpp mikie // GX469 (c) 1984 mikiehs // GX469 (c) 1984 @@ -20895,6 +20961,9 @@ mil4000b // (c) 2000 Sure Milano mil4000c // (c) 2000 Sure Milano top21 // (c) 200? Assogiochi Assago (Mi) +@source:milwaukee.cpp +mc1200 // + @source:mini2440.cpp mini2440 // @@ -21202,6 +21271,7 @@ monzagpb // bootleg @source:moo.cpp bucky // GX173 (c) 1992 (World) +buckyaa // GX173 (c) 1992 (Asia) buckyaab // GX173 (c) 1992 (Asia) buckyea // GX173 (c) 1992 (World) buckyjaa // GX173 (c) 1992 (Japan) @@ -28532,6 +28602,7 @@ chocovdr // 2002.10 Uchuu Daisakusen : Chocovader Contact gamshara // 2002.08 Gamshara (10021 Ver.A) gamsharaj // 2002.08 Gamshara (10021 Ver.A) gjspace // 2001.12 Gekitoride-Jong Space (10011 Ver.A) +g13jnc // 2001.?? Golgo 13: Juusei no Chinkonka (Japan, GLT1 VER.A) gunbalina // 2000.12 Gunbalina (GNN1 Ver.A) knpuzzle // 2001.12 Kotoba no Puzzle Mojipittan (KPM1 Ver.A) konotako // 2003.?? Kono Tako (10021 Ver.A) @@ -28915,11 +28986,12 @@ moeru // 2002.12 Moeru Casinyo mok // 2002.03.06 The Maze of the Kings monkeyba // 2001.05 Monkey Ball mslug6 // 2006.02 Metal Slug 6 -mtkob2 // 2003.02 MushiKing The King Of Beetle (World) mushi2k4 // 2004.?? MushiKing The King Of Beetles 2004 Second (Japan) mushi2k5 // 2005.?? MushiKing The King Of Beetles 2005 First (Japan) +mushike // 2004.?? MushiKing The King Of Beetle (World) mushi2eo // 2005.?? Mushiking The King Of Beetles II / III / III+ (Ver. 1.001) (World) mushik2e // 2005.?? Mushiking The King Of Beetles II / III / III+ (Ver. 2.001) (World) +mushik4e // 2007.?? Mushiking The King Of Beetles IV / V / VI (World) mvsc2 // 2000.03 Marvel Vs. Capcom 2 New Age of Heroes (Export, Korea) (Rev A) mvsc2u // 2000.03 Marvel Vs. Capcom 2 New Age of Heroes (USA) (Rev A) naomi // 1998.?? Naomi BIOS @@ -29752,6 +29824,7 @@ tdragon // (c) 1991 NMK / Tecmo tdragon1 // (c) 1991 NMK / Tecmo tdragon2 // UPL-93091 (c) 1993 NMK tdragon2a // UPL-93091 (c) 1993 NMK +tdragon3h tdragonb // bootleg tharrier // UPL-89053 (c) 1989 UPL tharrieru // UPL-89053 (c) 1989 UPL + American Sammy license @@ -29945,6 +30018,7 @@ onetwo // (c) 1997 Barko onetwoe // (c) 1997 Barko @source:onyx.cpp +c5000 // 1981 c8002 // @source:opwolf.cpp @@ -30781,6 +30855,7 @@ peps0090 // (c) 1996 IGT - International Game Technology peps0092 // (c) 1996 IGT - International Game Technology peps0206 // (c) 1996 IGT - International Game Technology peps0207 // (c) 1996 IGT - International Game Technology +peps0239 // (c) 1996 IGT - International Game Technology peps0296 // (c) 1996 IGT - International Game Technology peps0298 // (c) 1996 IGT - International Game Technology peps0308 // (c) 1996 IGT - International Game Technology @@ -31168,6 +31243,7 @@ martmast // (c) 2001 Martial Masters martmastc // martmastc103 // martmastc102 // +martmasttw // olds // (c) 1999 Oriental Legend Super / Special olds100 // olds100a // @@ -31201,14 +31277,15 @@ thegladpcb // @source:pgm2.cpp ddpdojh // kov2nl // (c) 2008 -kov2nlo // -kov2nloa // +kov2nl_301 // +kov2nl_300 // kov3 // kov3_102 // kov3_100 // orleg2 // (c) 2007 -orleg2o // -orleg2oa // +orleg2_103 // +orleg2_101 // +kof98umh // (c) 2009 @source:pgm3.cpp kov3hd @@ -31278,6 +31355,9 @@ photoply // @source:phunsy.cpp phunsy // +@source:picno.cpp +picno // Konami Picno (1993) + @source:piggypas.cpp 3lilpigs // dumpump // @@ -31953,6 +32033,9 @@ i8555081 // IBM PS/2 8550-081 (Model 55SX) i8580071 // IBM PS/2 8580-071 (Model 80) i8580111 // IBM PS/2 8580-111 (Model 80) +@source:ps2sony.cpp +ps2 // Sony Playstation 2 + @source:pse.cpp bazooka // (c) 1976 PSE bazookabr // (c) 1977 Taito do Brasil @@ -32314,7 +32397,8 @@ rbislande // B39 (c) 1988 Taito Corporation rbislando // B22 (c) 1987 Taito Corporation @source:rbmk.cpp -rbmk // (c) 1995 GMS +rbmk // (c) 1998 GMS +rbspm // (c) 1998 GMS @source:rc702.cpp rc702 // 1979 RC702 @@ -33143,6 +33227,7 @@ newsin7 // (c) 1983 ATW USA, Inc. newsin7a // (c) 1982 ATW USA, Inc. triplep // (c) 1982 KKI / made by Sanritsu? triplepa // (c) 1982 KKI / made by Sanritsu? +troopy // bootleg @source:scregg.cpp dommy // TA-00?? (c) 1983 (Arcade TV Game List - P.90, Left, 13 from top) @@ -33210,7 +33295,7 @@ vaportrxp // (c) 1998 Atari Games wg3dh // (c) 1996 Atari Games @source:seattlecmp.cpp -seattle // +scp300f // Seattle SCP-300F @source:sega_sawatte.cpp sawatte // @@ -33371,6 +33456,10 @@ segapm // 1996 Sega Picture Magic (32x type hardware) @source:segas16a.cpp aceattaca // (c) 1988 (FD1094) afighter // (c) 1986 (FD1089A) +afightera +afighterb +afighterc +afighterd alexkidd // (c) 1986 (Unprotected) alexkidd1 // (c) 1986 (FD1089A) aliensyn2 // (c) 1987 (FD1089A) @@ -33408,6 +33497,10 @@ wb35d // @source:segas16b.cpp aceattac // (c) 1988 (FD1094) +afightere +afighterf +afighterg +afighterh aliensyn // (c) 1987 (Unprotected) aliensyn3 // (c) 1987 (FD1089A) aliensyn7 // (c) 1987 (MC-8123B) @@ -35483,6 +35576,7 @@ svmu // 1998 Sega Visual Memory Unit @source:swtpc.cpp swtpc // +swtpcm // @source:swtpc09.cpp swtpc09 // S09, DMF2 Floppy SBUG rom - FLEX @@ -36079,6 +36173,7 @@ batlgear // E68 (c) 1999 Taito batlgr2 // E87 (c) 2000 Taito (2.04J) batlgr2a // E87 (c) 2000 Taito (2.01J) landhigh // E82 (c) 1999 Taito +landhigha // E82 (c) 1999 Taito pwrshovl // E74 (c) 1999 Taito pwrshovla // raizpin // F14 (c) 2002 Taito @@ -36246,6 +36341,24 @@ terak // @source:terco.cpp t4490 // Terco 4490 Mill CNC Control (c) 1986 +@source:terminals.cpp +aaa +hp700_92 +hp2622a +qvt70 +qvt102 +qvt103 +qvt190 +qvt201 +tr175 +tv912c +tv955 +tv965 +v100 +v102 +vt420 +zephyr + @source:terracre.cpp amatelas // (c) 1986 amazon // (c) 1986 @@ -36919,6 +37032,7 @@ trs80l2 // TRS-80 Model I - Level II BASIC trs80m3 // TRS-80 Model III - Radio Shack/Tandy trs80m4 // trs80m4p // +cp500 // Prologica CP500 @source:trs80dt1.cpp trs80dt1 // TRS-80 Data Terminal 1 @@ -36966,6 +37080,7 @@ m660j // ??? (c) 1986 Taito Corporation (Japan) nunchaku // ??? (c) 1985 Taito ringfgt // (c) 1984 Taito ringfgt2 // (c) 1984 Taito +the26thz // A72 (c) 1986 Taito tsamurai // A35 (c) 1985 Taito tsamurai2 // A35 (c) 1985 Taito tsamuraih // bootleg @@ -36980,6 +37095,9 @@ prose2ko // ttchamp // ttchampa // +@source:tti.cpp +tti // + @source:tubep.cpp rjammer // (c) 1984 + Alice tubep // (c) 1984 + Fujitek @@ -37319,6 +37437,9 @@ vector4 // raaspec // (c) Roy Abel & Associates 1984 vectrex // General Consumer Electric Vectrex - 1982-1984 +@source:vectrix.cpp +vectrix // (c) 19?? Olympia? + @source:vega.cpp vega // (c) 19?? Olympia? @@ -37395,6 +37516,7 @@ headon1 // 163-167/192-193 (c) Gremlin headon2 // ???-??? (c) 1979 Sega headon2s // Sidam bootleg headonmz // bootleg +headonn // (c) Nintendo headons // Sidam bootleg headonsa // Sidam bootleg heiankyo // (c) [1979?] Denki Onkyo @@ -37566,6 +37688,12 @@ specfrce // (c) 2002 ICE/Play Mechanix specfrceo // (c) 2002 ICE/Play Mechanix zoofari // (c) 2006 ICE/Play Mechanix +@source:vp122.cpp +vp122 // + +@source:vp60.cpp +vp60 // + @source:vpoker.cpp 5acespkr // (c) 198? vpoker // (c) 198? @@ -38506,7 +38634,13 @@ wwfsstaru6 // TA-0024 (c) 1989 (US) wwfsstaru4 // TA-0024 (c) 1989 (US) @source:wyse.cpp -wyse // +wy50 // WY-50 +wy55 // WY-55 +wy60 // WY-60 +wy85 // WY-85 +wy150 // WY-150 +wy160 // WY-160 +wy30p // WY-30+ @source:wyvernf0.cpp wyvernf0 // A39 (c) 1985 Taito Corporation (Japan) @@ -38899,6 +39033,9 @@ zrt80 // @source:zsbc3.cpp zsbc3 // +@source:zt8802.cpp +zt8802 // (c) 19?? Olympia? + @source:zwackery.cpp zwackery // (c) 1984 diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 998206e54c5..d1759860f8e 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -30,12 +30,15 @@ alphasma.cpp alphatpx.cpp alphatro.cpp altair.cpp +alto1.cpp alto2.cpp +altos2.cpp altos5.cpp altos486.cpp altos8600.cpp amico2k.cpp amiga.cpp +ampex.cpp ampro.cpp ampscarp.cpp amstr_pc.cpp @@ -69,6 +72,7 @@ atm.cpp atom.cpp atpci.cpp att4425.cpp +att630.cpp attache.cpp aussiebyte.cpp avigo.cpp @@ -122,6 +126,7 @@ channelf.cpp chaos.cpp chessmst.cpp chesstrv.cpp +cit220.cpp clcd.cpp cm1800.cpp cmi.cpp @@ -147,6 +152,7 @@ cxgz80.cpp cxhumax.cpp cybiko.cpp czk80.cpp +d400.cpp d6800.cpp d6809.cpp dai.cpp @@ -185,6 +191,7 @@ elf.cpp elwro800.cpp enmirage.cpp ep64.cpp +esprit.cpp esq1.cpp esq5505.cpp esqasr.cpp @@ -259,6 +266,7 @@ homez80.cpp horizon.cpp hp_ipc.cpp hp16500.cpp +hp2100.cpp hp48.cpp hp49gp.cpp hp64k.cpp @@ -340,6 +348,7 @@ lwriter.cpp lynx.cpp m20.cpp m24.cpp +m3.cpp m5.cpp m6805evs.cpp m68705prg.cpp @@ -354,7 +363,8 @@ mbee.cpp mc10.cpp mc1000.cpp mc1502.cpp -mc80.cpp +mc8020.cpp +mc8030.cpp mcb216.cpp mccpm.cpp megadriv.cpp @@ -370,10 +380,13 @@ microdec.cpp microkit.cpp micronic.cpp microtan.cpp +microterm.cpp microvsn.cpp mikro80.cpp mikromik.cpp mikrosha.cpp +mightyframe.cpp +milwaukee.cpp mini2440.cpp minicom.cpp miniforce.cpp @@ -495,6 +508,7 @@ phc25.cpp phunsy.cpp pimps.cpp pipbug.cpp +picno.cpp pitagjr.cpp pk8000.cpp pk8020.cpp @@ -524,6 +538,7 @@ prof80.cpp prophet600.cpp proteus3.cpp ps2.cpp +ps2sony.cpp psion.cpp psx.cpp pt68k4.cpp @@ -643,6 +658,7 @@ tek440x.cpp tekxp33x.cpp terak.cpp terco.cpp +terminals.cpp test_t400.cpp testconsole.cpp tg100.cpp @@ -683,6 +699,7 @@ ts803.cpp ts816.cpp ts3000.cpp tsispch.cpp +tti.cpp tutor.cpp tv910.cpp tv950.cpp @@ -707,6 +724,7 @@ vcs80.cpp vector06.cpp vector4.cpp vectrex.cpp +vectrix.cpp vg5k.cpp vic10.cpp vic20.cpp @@ -719,6 +737,8 @@ vixen.cpp vk100.cpp votrpss.cpp votrtnt.cpp +vp122.cpp +vp60.cpp vsmilepro.cpp vt100.cpp vt220.cpp @@ -753,6 +773,7 @@ zexall.cpp zorba.cpp zrt80.cpp zsbc3.cpp +zt8802.cpp zx.cpp //exceptions + to add - to remove from imported list //3do.cpp diff --git a/src/mame/video/artmagic.cpp b/src/mame/video/artmagic.cpp index b755f15932b..d15d3925c5e 100644 --- a/src/mame/video/artmagic.cpp +++ b/src/mame/video/artmagic.cpp @@ -24,7 +24,7 @@ inline uint16_t *artmagic_state::address_to_vram(offs_t *address) { offs_t original = *address; - *address = TOWORD(original & 0x001fffff); + *address = (original & 0x001fffff) >> 4; if (original < 0x001fffff) return m_vram0; else if (original >= 0x00400000 && original < 0x005fffff) @@ -63,7 +63,7 @@ TMS340X0_TO_SHIFTREG_CB_MEMBER(artmagic_state::to_shiftreg) { uint16_t *vram = address_to_vram(&address); if (vram) - memcpy(shiftreg, &vram[address], TOBYTE(0x2000)); + memcpy(shiftreg, &vram[address], 0x400); } @@ -71,7 +71,7 @@ TMS340X0_FROM_SHIFTREG_CB_MEMBER(artmagic_state::from_shiftreg) { uint16_t *vram = address_to_vram(&address); if (vram) - memcpy(&vram[address], shiftreg, TOBYTE(0x2000)); + memcpy(&vram[address], shiftreg, 0x400); } @@ -194,7 +194,7 @@ void artmagic_state::execute_blit() { if (sy >= 0 && sy < 256) { - int tsy = sy * TOWORD(0x2000); + int tsy = sy * 0x200; sx = x; /* The first pixel of every line doesn't have a previous pixel diff --git a/src/mame/video/btoads.cpp b/src/mame/video/btoads.cpp index cfe472773c8..d2bdf140454 100644 --- a/src/mame/video/btoads.cpp +++ b/src/mame/video/btoads.cpp @@ -267,19 +267,19 @@ TMS340X0_TO_SHIFTREG_CB_MEMBER(btoads_state::to_shiftreg) /* reads from this first region are usual shift register reads */ if (address >= 0xa0000000 && address <= 0xa3ffffff) - memcpy(shiftreg, &m_vram_fg_display[TOWORD(address & 0x3fffff)], TOBYTE(0x1000)); + memcpy(shiftreg, &m_vram_fg_display[(address & 0x3fffff) >> 4], 0x200); /* reads from this region set the sprite destination address */ else if (address >= 0xa4000000 && address <= 0xa7ffffff) { - m_sprite_dest_base = &m_vram_fg_draw[TOWORD(address & 0x3fc000)]; + m_sprite_dest_base = &m_vram_fg_draw[(address & 0x3fc000) >> 4]; m_sprite_dest_offs = (address & 0x003fff) >> 5; } /* reads from this region set the sprite source address */ else if (address >= 0xa8000000 && address <= 0xabffffff) { - memcpy(shiftreg, &m_vram_fg_data[TOWORD(address & 0x7fc000)], TOBYTE(0x2000)); + memcpy(shiftreg, &m_vram_fg_data[(address & 0x7fc000) >> 4], 0x400); m_sprite_source_offs = (address & 0x003fff) >> 3; } @@ -294,7 +294,7 @@ TMS340X0_FROM_SHIFTREG_CB_MEMBER(btoads_state::from_shiftreg) /* writes to this first region are usual shift register writes */ if (address >= 0xa0000000 && address <= 0xa3ffffff) - memcpy(&m_vram_fg_display[TOWORD(address & 0x3fc000)], shiftreg, TOBYTE(0x1000)); + memcpy(&m_vram_fg_display[(address & 0x3fc000) >> 4], shiftreg, 0x200); /* writes to this region are ignored for our purposes */ else if (address >= 0xa4000000 && address <= 0xa7ffffff) @@ -302,7 +302,7 @@ TMS340X0_FROM_SHIFTREG_CB_MEMBER(btoads_state::from_shiftreg) /* writes to this region copy standard data */ else if (address >= 0xa8000000 && address <= 0xabffffff) - memcpy(&m_vram_fg_data[TOWORD(address & 0x7fc000)], shiftreg, TOBYTE(0x2000)); + memcpy(&m_vram_fg_data[(address & 0x7fc000) >> 4], shiftreg, 0x400); /* writes to this region render the current sprite data */ else if (address >= 0xac000000 && address <= 0xafffffff) diff --git a/src/mame/video/cave.cpp b/src/mame/video/cave.cpp index b77c6553450..75d32eafeb2 100644 --- a/src/mame/video/cave.cpp +++ b/src/mame/video/cave.cpp @@ -506,7 +506,7 @@ void cave_state::get_sprite_info_cave(int chip) uint16_t *source; uint16_t *finish; - struct sprite_cave *sprite = m_sprite[chip]; + sprite_cave *sprite = m_sprite[chip].get(); int glob_flipx = m_videoregs[chip][0] & 0x8000; int glob_flipy = m_videoregs[chip][1] & 0x8000; @@ -623,7 +623,7 @@ void cave_state::get_sprite_info_cave(int chip) sprite++; } - m_num_sprites[chip] = sprite - m_sprite[chip]; + m_num_sprites[chip] = sprite - m_sprite[chip].get(); } void cave_state::get_sprite_info_donpachi(int chip) @@ -636,7 +636,7 @@ void cave_state::get_sprite_info_donpachi(int chip) uint16_t *source; uint16_t *finish; - struct sprite_cave *sprite = m_sprite[chip]; + sprite_cave *sprite = m_sprite[chip].get(); int glob_flipx = m_videoregs[chip][0] & 0x8000; int glob_flipy = m_videoregs[chip][1] & 0x8000; @@ -709,7 +709,7 @@ void cave_state::get_sprite_info_donpachi(int chip) sprite++; } - m_num_sprites[chip] = sprite - m_sprite[chip]; + m_num_sprites[chip] = sprite - m_sprite[chip].get(); } @@ -732,8 +732,10 @@ void cave_state::sprite_init_cave() for (int chip = 0; chip < 4; chip++) { m_num_sprites[chip] = m_spriteram[chip].bytes() / 0x10 / 2; - m_sprite[chip] = auto_alloc_array_clear(machine(), struct sprite_cave, m_num_sprites[chip]); - memset(m_sprite_table, 0, sizeof(m_sprite_table)); + m_sprite[chip] = std::make_unique<sprite_cave []>(m_num_sprites[chip]); + for (auto &prio : m_sprite_table[chip]) + for (sprite_cave *&spr : prio) + spr = nullptr; m_spriteram_bank[chip] = m_spriteram_bank_delay[chip] = 0; } @@ -768,8 +770,8 @@ void cave_state::cave_sprite_check(int chip, screen_device &screen, const rectan } { /* check priority & sprite type */ - struct sprite_cave *sprite = m_sprite[chip]; - const struct sprite_cave *finish = &sprite[m_num_sprites[chip]]; + sprite_cave *sprite = m_sprite[chip].get(); + const sprite_cave *const finish = &sprite[m_num_sprites[chip]]; int i[4] = {0,0,0,0}; int priority_check = 0; int spritetype = m_spritetype[1]; @@ -829,7 +831,7 @@ void cave_state::cave_sprite_check(int chip, screen_device &screen, const rectan } } -void cave_state::do_blit_zoom32_cave( int chip, const struct sprite_cave *sprite ) +void cave_state::do_blit_zoom32_cave( int chip, const sprite_cave *sprite ) { /* assumes SPRITE_LIST_RAW_DATA flag is set */ int x1, x2, y1, y2, dx, dy; @@ -961,7 +963,7 @@ void cave_state::do_blit_zoom32_cave( int chip, const struct sprite_cave *sprite } -void cave_state::do_blit_zoom32_cave_zb( int chip, const struct sprite_cave *sprite ) +void cave_state::do_blit_zoom32_cave_zb( int chip, const sprite_cave *sprite ) { /* assumes SPRITE_LIST_RAW_DATA flag is set */ int x1, x2, y1, y2, dx, dy; @@ -1059,7 +1061,7 @@ void cave_state::do_blit_zoom32_cave_zb( int chip, const struct sprite_cave *spr uint32_t *dest = (uint32_t *)(m_blit.baseaddr + m_blit.line_offset * y1); int pitchz = m_blit.line_offset_zbuf * dy / 2; uint16_t *zbf = (uint16_t *)(m_blit.baseaddr_zbuf + m_blit.line_offset_zbuf * y1); - uint16_t pri_sp = (uint16_t)(sprite - m_sprite[chip]) + m_sprite_zbuf_baseval; + uint16_t pri_sp = (uint16_t)(sprite - m_sprite[chip].get()) + m_sprite_zbuf_baseval; int ycount = ycount0; for (y = y1; y != y2; y += dy) @@ -1096,7 +1098,7 @@ void cave_state::do_blit_zoom32_cave_zb( int chip, const struct sprite_cave *spr } } -void cave_state::do_blit_32_cave( int chip, const struct sprite_cave *sprite ) +void cave_state::do_blit_32_cave( int chip, const sprite_cave *sprite ) { /* assumes SPRITE_LIST_RAW_DATA flag is set */ int x1, x2, y1, y2, dx, dy; @@ -1191,7 +1193,7 @@ void cave_state::do_blit_32_cave( int chip, const struct sprite_cave *sprite ) } -void cave_state::do_blit_32_cave_zb( int chip, const struct sprite_cave *sprite ) +void cave_state::do_blit_32_cave_zb( int chip, const sprite_cave *sprite ) { /* assumes SPRITE_LIST_RAW_DATA flag is set */ int x1, x2, y1, y2, dx, dy; @@ -1269,7 +1271,7 @@ void cave_state::do_blit_32_cave_zb( int chip, const struct sprite_cave *sprite uint32_t *dest = (uint32_t *)(m_blit.baseaddr + m_blit.line_offset * y1); int pitchz = m_blit.line_offset_zbuf * dy / 2; uint16_t *zbf = (uint16_t *)(m_blit.baseaddr_zbuf + m_blit.line_offset_zbuf * y1); - uint16_t pri_sp = (uint16_t)(sprite - m_sprite[chip]) + m_sprite_zbuf_baseval; + uint16_t pri_sp = (uint16_t)(sprite - m_sprite[chip].get()) + m_sprite_zbuf_baseval; pen_data += sprite->line_offset * ycount0 + xcount0; for (y = y1; y != y2; y += dy) @@ -1299,7 +1301,7 @@ void cave_state::sprite_draw_cave( int chip, int priority ) int i = 0; while (m_sprite_table[chip][priority][i]) { - const struct sprite_cave *sprite = m_sprite_table[chip][priority][i++]; + const sprite_cave *sprite = m_sprite_table[chip][priority][i++]; if ((sprite->tile_width == sprite->total_width) && (sprite->tile_height == sprite->total_height)) do_blit_32_cave(chip, sprite); else @@ -1312,7 +1314,7 @@ void cave_state::sprite_draw_cave_zbuf( int chip, int priority ) int i = 0; while (m_sprite_table[chip][priority][i]) { - const struct sprite_cave *sprite = m_sprite_table[chip][priority][i++]; + const sprite_cave *sprite = m_sprite_table[chip][priority][i++]; if ((sprite->tile_width == sprite->total_width) && (sprite->tile_height == sprite->total_height)) do_blit_32_cave_zb(chip, sprite); else diff --git a/src/mame/video/exterm.cpp b/src/mame/video/exterm.cpp index 5327fcbd1db..331a62e627a 100644 --- a/src/mame/video/exterm.cpp +++ b/src/mame/video/exterm.cpp @@ -35,25 +35,25 @@ PALETTE_INIT_MEMBER(exterm_state, exterm) TMS340X0_TO_SHIFTREG_CB_MEMBER(exterm_state::to_shiftreg_master) { - memcpy(shiftreg, &m_master_videoram[TOWORD(address)], 256 * sizeof(uint16_t)); + memcpy(shiftreg, &m_master_videoram[address >> 4], 256 * sizeof(uint16_t)); } TMS340X0_FROM_SHIFTREG_CB_MEMBER(exterm_state::from_shiftreg_master) { - memcpy(&m_master_videoram[TOWORD(address)], shiftreg, 256 * sizeof(uint16_t)); + memcpy(&m_master_videoram[address >> 4], shiftreg, 256 * sizeof(uint16_t)); } TMS340X0_TO_SHIFTREG_CB_MEMBER(exterm_state::to_shiftreg_slave) { - memcpy(shiftreg, &m_slave_videoram[TOWORD(address)], 256 * 2 * sizeof(uint8_t)); + memcpy(shiftreg, &m_slave_videoram[address >> 4], 256 * 2 * sizeof(uint8_t)); } TMS340X0_FROM_SHIFTREG_CB_MEMBER(exterm_state::from_shiftreg_slave) { - memcpy(&m_slave_videoram[TOWORD(address)], shiftreg, 256 * 2 * sizeof(uint8_t)); + memcpy(&m_slave_videoram[address >> 4], shiftreg, 256 * 2 * sizeof(uint8_t)); } diff --git a/src/mame/video/fmtowns.cpp b/src/mame/video/fmtowns.cpp index e8e5464f287..9cb02b6cbb4 100644 --- a/src/mame/video/fmtowns.cpp +++ b/src/mame/video/fmtowns.cpp @@ -60,16 +60,20 @@ * * Video registers: * - * 0: Graphic layer(s) type: (others likely exist) - * bit 4 = 2 layers + * 0: Control register: + * bit 4 = PMODE - enable 2 layers * bits 2-3 = layer 1 mode * bits 0-1 = layer 0 mode - * mode: 1 = 16 colours, 2 = 256 colours, 3 = highcolour (16-bit) - * 0 = disabled? + * mode: 1 = 16 colours (PMODE=1 only), 2 = 256 colours (PMODE=0 only), + * 3 = highcolour (16-bit), 0 = display off * - * 1: Layer reverse (priority?) (bit 0) - * YM (bit 2) - unknown - * peltype (bits 4 and 5) + * 1: Priority register (bit 0) + * bit 0: PR1 - layer priority (0 = layer 0 before) + * bit 2: YM - screen brightness (0 = high brightness) + * bit 3: YS - 0 = valid. Used for 256 colour external sync + * bits 4-5: Palette select + * 0 = layer 0, 16 colours, 1 or 3 = 256 colours + * 2 = layer 1, 16 colours * * * Sprite registers: @@ -228,11 +232,11 @@ void towns_state::towns_update_kanji_offset() } else if(m_video.towns_kanji_code_h < 0x70) { - m_video.towns_kanji_offset = ((m_video.towns_kanji_code_l & 0x1f) << 4) - + (((m_video.towns_kanji_code_l - 0x20) & 0x60) << 8) - + ((m_video.towns_kanji_code_h & 0x0f) << 9) + m_video.towns_kanji_offset = (((m_video.towns_kanji_code_l & 0x1f) << 5) + + (((m_video.towns_kanji_code_l - 0x20) & 0x60) << 9) + + ((m_video.towns_kanji_code_h & 0x0f) << 10) + (((m_video.towns_kanji_code_h - 0x30) & 0x70) * 0xc00) - + 0x8000; + + 0x8000) >> 1; } else { @@ -244,6 +248,7 @@ void towns_state::towns_update_kanji_offset() } } + READ8_MEMBER( towns_state::towns_video_cff80_r ) { uint8_t* ROM = m_user->base(); @@ -486,31 +491,50 @@ void towns_state::towns_update_palette() uint8_t r = m_video.towns_palette_r[entry]; uint8_t g = m_video.towns_palette_g[entry]; uint8_t b = m_video.towns_palette_b[entry]; - m_palette->set_pen_color(entry, r, g, b); + switch(m_video.towns_video_reg[1] & 0x30) // Palette select + { + case 0x00: + m_palette16_0->set_pen_color(entry, r, g, b); + break; + case 0x20: + m_palette16_1->set_pen_color(entry, r, g, b); + break; + case 0x10: + case 0x30: + m_palette->set_pen_color(entry, r, g, b); + break; + } } /* Video/CRTC * * 0xfd90 - palette colour select * 0xfd92/4/6 - BRG value - * 0xfd98-9f - degipal(?) + * 0xfd98-9f - Digital palette registers (FMR-50 compatibility) */ READ8_MEMBER(towns_state::towns_video_fd90_r) { uint8_t ret = 0; uint16_t xpos; + palette_device* pal; + if(m_video.towns_video_reg[1] & 0x10) + pal = m_palette; + else if(m_video.towns_video_reg[1] & 0x20) + pal = m_palette16_1; + else + pal = m_palette16_0; // if(LOG_VID) logerror("VID: read port %04x\n",offset+0xfd90); switch(offset) { case 0x00: return m_video.towns_palette_select; case 0x02: - return m_video.towns_palette_b[m_video.towns_palette_select]; + return pal->pen_color(m_video.towns_palette_select).b(); case 0x04: - return m_video.towns_palette_r[m_video.towns_palette_select]; + return pal->pen_color(m_video.towns_palette_select).r(); case 0x06: - return m_video.towns_palette_g[m_video.towns_palette_select]; + return pal->pen_color(m_video.towns_palette_select).g(); case 0x08: case 0x09: case 0x0a: @@ -934,8 +958,8 @@ void towns_state::towns_crtc_draw_scan_layer_hicolour(bitmap_rgb32 &bitmap,const scroll = ((m_video.towns_crtc_reg[21] & 0xfc00) << 2) | (((m_video.towns_crtc_reg[21] & 0x3ff) << 2)); off += scroll; } - off += (m_video.towns_crtc_reg[11] - m_video.towns_crtc_reg[22]); hzoom = ((m_video.towns_crtc_reg[27] & 0x0f00) >> 8) + 1; + off += (m_video.towns_crtc_reg[11] - m_video.towns_crtc_reg[22]) / hzoom; } else { @@ -946,8 +970,8 @@ void towns_state::towns_crtc_draw_scan_layer_hicolour(bitmap_rgb32 &bitmap,const scroll = ((m_video.towns_crtc_reg[17] & 0xfc00) << 2) | (((m_video.towns_crtc_reg[17] & 0x3ff) << 2)); off += scroll; } - off += (m_video.towns_crtc_reg[9] - m_video.towns_crtc_reg[18]); hzoom = (m_video.towns_crtc_reg[27] & 0x000f) + 1; + off += (m_video.towns_crtc_reg[9] - m_video.towns_crtc_reg[18]) / hzoom; } off += line * linesize; @@ -1126,8 +1150,8 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect scroll = ((m_video.towns_crtc_reg[21] & 0xfc00) << 3) | (((m_video.towns_crtc_reg[21] & 0x3ff) << 3)); off += scroll; } - off += (m_video.towns_crtc_reg[11] - m_video.towns_crtc_reg[22]); hzoom = ((m_video.towns_crtc_reg[27] & 0x0f00) >> 8) + 1; + off += (m_video.towns_crtc_reg[11] - m_video.towns_crtc_reg[22]) / hzoom; } else { @@ -1138,8 +1162,8 @@ void towns_state::towns_crtc_draw_scan_layer_256(bitmap_rgb32 &bitmap,const rect scroll = ((m_video.towns_crtc_reg[17] & 0xfc00) << 3) | (((m_video.towns_crtc_reg[17] & 0x3ff) << 3)); off += scroll; } - off += (m_video.towns_crtc_reg[9] - m_video.towns_crtc_reg[18]); hzoom = (m_video.towns_crtc_reg[27] & 0x000f) + 1; + off += (m_video.towns_crtc_reg[9] - m_video.towns_crtc_reg[18]) / hzoom; } off += line * linesize; @@ -1248,6 +1272,7 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta int hzoom = 1; int linesize; uint32_t scroll; + palette_device* pal = (layer == 0) ? m_palette16_0 : m_palette16_1; if(m_video.towns_display_page_sel != 0) off = 0x20000; @@ -1265,26 +1290,26 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta if(!(m_video.towns_video_reg[0] & 0x10)) return; if(!(m_video.towns_crtc_reg[28] & 0x10)) - off += m_video.towns_crtc_reg[21]; // initial offset + off += m_video.towns_crtc_reg[21] << 2; // initial offset else { scroll = ((m_video.towns_crtc_reg[21] & 0xfc00)<<2) | (((m_video.towns_crtc_reg[21] & 0x3ff)<<2)); off += scroll; } - off += (m_video.towns_crtc_reg[11] - m_video.towns_crtc_reg[22]); hzoom = ((m_video.towns_crtc_reg[27] & 0x0f00) >> 8) + 1; + off += (m_video.towns_crtc_reg[11] - m_video.towns_crtc_reg[22]) / (hzoom * 2); } else { if(!(m_video.towns_crtc_reg[28] & 0x20)) - off += m_video.towns_crtc_reg[17]; // initial offset + off += m_video.towns_crtc_reg[17] << 2; // initial offset else { scroll = ((m_video.towns_crtc_reg[17] & 0xfc00)<<2) | (((m_video.towns_crtc_reg[17] & 0x3ff)<<2)); off += scroll; } - off += (m_video.towns_crtc_reg[9] - m_video.towns_crtc_reg[18]); hzoom = (m_video.towns_crtc_reg[27] & 0x000f) + 1; + off += (m_video.towns_crtc_reg[9] - m_video.towns_crtc_reg[18]) / (hzoom * 2); } off += line * linesize; @@ -1300,12 +1325,12 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; if(colour != 0) { - bitmap.pix32(scanline, x+1) = m_palette->pen(colour); + bitmap.pix32(scanline, x+1) = pal->pen(colour); } colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; if(colour != 0) { - bitmap.pix32(scanline, x) = m_palette->pen(colour); + bitmap.pix32(scanline, x) = pal->pen(colour); } off++; } @@ -1322,14 +1347,14 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; if(colour != 0) { - bitmap.pix32(scanline, x+2) = m_palette->pen(colour); - bitmap.pix32(scanline, x+3) = m_palette->pen(colour); + bitmap.pix32(scanline, x+2) = pal->pen(colour); + bitmap.pix32(scanline, x+3) = pal->pen(colour); } colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; if(colour != 0) { - bitmap.pix32(scanline, x) = m_palette->pen(colour); - bitmap.pix32(scanline, x+1) = m_palette->pen(colour); + bitmap.pix32(scanline, x) = pal->pen(colour); + bitmap.pix32(scanline, x+1) = pal->pen(colour); } off++; } @@ -1346,16 +1371,16 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; if(colour != 0) { - bitmap.pix32(scanline, x+3) = m_palette->pen(colour); - bitmap.pix32(scanline, x+4) = m_palette->pen(colour); - bitmap.pix32(scanline, x+5) = m_palette->pen(colour); + bitmap.pix32(scanline, x+3) = pal->pen(colour); + bitmap.pix32(scanline, x+4) = pal->pen(colour); + bitmap.pix32(scanline, x+5) = pal->pen(colour); } colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; if(colour != 0) { - bitmap.pix32(scanline, x) = m_palette->pen(colour); - bitmap.pix32(scanline, x+1) = m_palette->pen(colour); - bitmap.pix32(scanline, x+2) = m_palette->pen(colour); + bitmap.pix32(scanline, x) = pal->pen(colour); + bitmap.pix32(scanline, x+1) = pal->pen(colour); + bitmap.pix32(scanline, x+2) = pal->pen(colour); } off++; } @@ -1372,18 +1397,18 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; if(colour != 0) { - bitmap.pix32(scanline, x+4) = m_palette->pen(colour); - bitmap.pix32(scanline, x+5) = m_palette->pen(colour); - bitmap.pix32(scanline, x+6) = m_palette->pen(colour); - bitmap.pix32(scanline, x+7) = m_palette->pen(colour); + bitmap.pix32(scanline, x+4) = pal->pen(colour); + bitmap.pix32(scanline, x+5) = pal->pen(colour); + bitmap.pix32(scanline, x+6) = pal->pen(colour); + bitmap.pix32(scanline, x+7) = pal->pen(colour); } colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; if(colour != 0) { - bitmap.pix32(scanline, x) = m_palette->pen(colour); - bitmap.pix32(scanline, x+1) = m_palette->pen(colour); - bitmap.pix32(scanline, x+2) = m_palette->pen(colour); - bitmap.pix32(scanline, x+3) = m_palette->pen(colour); + bitmap.pix32(scanline, x) = pal->pen(colour); + bitmap.pix32(scanline, x+1) = pal->pen(colour); + bitmap.pix32(scanline, x+2) = pal->pen(colour); + bitmap.pix32(scanline, x+3) = pal->pen(colour); } off++; } @@ -1400,20 +1425,20 @@ void towns_state::towns_crtc_draw_scan_layer_16(bitmap_rgb32 &bitmap,const recta colour = m_towns_gfxvram[off+(layer*0x40000)] >> 4; if(colour != 0) { - bitmap.pix32(scanline, x+5) = m_palette->pen(colour); - bitmap.pix32(scanline, x+6) = m_palette->pen(colour); - bitmap.pix32(scanline, x+7) = m_palette->pen(colour); - bitmap.pix32(scanline, x+8) = m_palette->pen(colour); - bitmap.pix32(scanline, x+9) = m_palette->pen(colour); + bitmap.pix32(scanline, x+5) = pal->pen(colour); + bitmap.pix32(scanline, x+6) = pal->pen(colour); + bitmap.pix32(scanline, x+7) = pal->pen(colour); + bitmap.pix32(scanline, x+8) = pal->pen(colour); + bitmap.pix32(scanline, x+9) = pal->pen(colour); } colour = m_towns_gfxvram[off+(layer*0x40000)] & 0x0f; if(colour != 0) { - bitmap.pix32(scanline, x) = m_palette->pen(colour); - bitmap.pix32(scanline, x+1) = m_palette->pen(colour); - bitmap.pix32(scanline, x+2) = m_palette->pen(colour); - bitmap.pix32(scanline, x+3) = m_palette->pen(colour); - bitmap.pix32(scanline, x+4) = m_palette->pen(colour); + bitmap.pix32(scanline, x) = pal->pen(colour); + bitmap.pix32(scanline, x+1) = pal->pen(colour); + bitmap.pix32(scanline, x+2) = pal->pen(colour); + bitmap.pix32(scanline, x+3) = pal->pen(colour); + bitmap.pix32(scanline, x+4) = pal->pen(colour); } off++; } diff --git a/src/mame/video/gladiatr.cpp b/src/mame/video/gladiatr.cpp index 02c2ab24fcc..03702a38cb9 100644 --- a/src/mame/video/gladiatr.cpp +++ b/src/mame/video/gladiatr.cpp @@ -252,6 +252,12 @@ void gladiatr_state_base::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cl color, xflip, yflip, sx+x*16, sy+y*16,0); + // wraparound, used by Ping Pong King when scrolling from right to left + m_gfxdecode->gfx(2)->transpen(bitmap,cliprect, + t, + color, + xflip, yflip, + sx+x*16, sy+y*16+256,0); } } } diff --git a/src/mame/video/hyprduel.cpp b/src/mame/video/hyprduel.cpp index bff54803a75..a5dfa1b7417 100644 --- a/src/mame/video/hyprduel.cpp +++ b/src/mame/video/hyprduel.cpp @@ -378,15 +378,11 @@ VIDEO_START_MEMBER(hyprduel_state,common_14220) VIDEO_START_MEMBER(hyprduel_state,hyprduel_14220) { - m_sprite_yoffs_sub = 2; - VIDEO_START_CALL_MEMBER(common_14220); } VIDEO_START_MEMBER(hyprduel_state,magerror_14220) { - m_sprite_yoffs_sub = 0; - VIDEO_START_CALL_MEMBER(common_14220); } @@ -453,8 +449,8 @@ void hyprduel_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, uint8_t *base_gfx8 = memregion("gfx1")->base(); uint32_t gfx_size = memregion("gfx1")->bytes(); - int max_x = m_screen->width(); - int max_y = m_screen->height(); + int max_x = (m_spriteregs[1]+1) * 2; + int max_y = (m_spriteregs[0]+1) * 2; int max_sprites = m_spriteram.bytes() / 8; int sprites = m_videoregs[0x00 / 2] % max_sprites; @@ -682,8 +678,8 @@ uint32_t hyprduel_state::screen_update(screen_device &screen, bitmap_ind16 &bitm } } - m_sprite_xoffs = m_videoregs[0x06 / 2] - screen.width() / 2; - m_sprite_yoffs = m_videoregs[0x04 / 2] - screen.height() / 2 - m_sprite_yoffs_sub; + m_sprite_xoffs = m_videoregs[0x06 / 2] - (m_spriteregs[1]+1); + m_sprite_yoffs = m_videoregs[0x04 / 2] - (m_spriteregs[0]+1); /* The background color is selected by a register */ screen.priority().fill(0, cliprect); diff --git a/src/mame/video/jpmimpct.cpp b/src/mame/video/jpmimpct.cpp index 3df9527c011..8d68a44bd49 100644 --- a/src/mame/video/jpmimpct.cpp +++ b/src/mame/video/jpmimpct.cpp @@ -90,12 +90,12 @@ READ16_MEMBER(jpmimpct_state::jpmimpct_bt477_r) TMS340X0_TO_SHIFTREG_CB_MEMBER(jpmimpct_state::to_shiftreg) { - memcpy(shiftreg, &m_vram[TOWORD(address)], 512 * sizeof(uint16_t)); + memcpy(shiftreg, &m_vram[address >> 4], 512 * sizeof(uint16_t)); } TMS340X0_FROM_SHIFTREG_CB_MEMBER(jpmimpct_state::from_shiftreg) { - memcpy(&m_vram[TOWORD(address)], shiftreg, 512 * sizeof(uint16_t)); + memcpy(&m_vram[address >> 4], shiftreg, 512 * sizeof(uint16_t)); } diff --git a/src/mame/video/k051960.cpp b/src/mame/video/k051960.cpp index cc90a4d4619..3252101f929 100644 --- a/src/mame/video/k051960.cpp +++ b/src/mame/video/k051960.cpp @@ -38,6 +38,7 @@ memory map: 001 W Devastators sets bit 1, function unknown. Ultraman sets the register to 0x0f. None of the other games I tested seem to set this register to other than 0. + Update: Chequered Flag sets bit 0 when background should be dimmed (palette control?) 002-003 W selects the portion of the gfx ROMs to be read. 004 W Aliens uses this to select the ROM bank to be read, but Punk Shot and TMNT don't, they use another bit of the registers above. Many @@ -136,6 +137,7 @@ k051960_device::k051960_device(const machine_config &mconfig, const char *tag, d , m_irq_handler(*this) , m_firq_handler(*this) , m_nmi_handler(*this) + , m_vreg_contrast_handler(*this) , m_romoffset(0) , m_spriteflip(0) , m_readroms(0) @@ -207,6 +209,7 @@ void k051960_device::device_start() m_irq_handler.resolve_safe(); m_firq_handler.resolve_safe(); m_nmi_handler.resolve_safe(); + m_vreg_contrast_handler.resolve_safe(); // register for save states save_item(NAME(m_romoffset)); @@ -330,6 +333,10 @@ WRITE8_MEMBER( k051960_device::k051937_w ) } else if (offset == 1) { + //popmessage("%04x: write %02x to 051937 address %x", space.device().safe_pc(), data, offset); + // Chequered Flag uses this bit to enable background palette dimming + // TODO: use a callback here for now, pending further investigation over this bit + m_vreg_contrast_handler(BIT(data,0)); // unknown, Devastators writes 02 here in game if (0) logerror("%s: %02x to 051937 address %x\n", machine().describe_context(), data, offset); diff --git a/src/mame/video/k051960.h b/src/mame/video/k051960.h index c9b83843311..5f7d7f6b51f 100644 --- a/src/mame/video/k051960.h +++ b/src/mame/video/k051960.h @@ -33,6 +33,9 @@ typedef device_delegate<void (int *code, int *color, int *priority, int *shadow) #define MCFG_K051960_NMI_HANDLER(_devcb) \ devcb = &k051960_device::set_nmi_handler(*device, DEVCB_##_devcb); +#define MCFG_K051960_VREG_CONTRAST_HANDLER(_devcb) \ + devcb = &k051960_device::set_vreg_contrast_handler(*device, DEVCB_##_devcb); + class k051960_device : public device_t, public device_gfx_interface { @@ -52,6 +55,10 @@ public: template <class Object> static devcb_base &set_nmi_handler(device_t &device, Object &&cb) { return downcast<k051960_device &>(device).m_nmi_handler.set_callback(std::forward<Object>(cb)); } + template <class Object> static devcb_base &set_vreg_contrast_handler(device_t &device, Object &&cb) + { return downcast<k051960_device &>(device).m_vreg_contrast_handler.set_callback(std::forward<Object>(cb)); } + + // static configuration static void set_k051960_callback(device_t &device, k051960_cb_delegate callback) { downcast<k051960_device &>(device).m_k051960_cb = callback; } static void set_plane_order(device_t &device, int order); @@ -98,8 +105,10 @@ private: k051960_cb_delegate m_k051960_cb; devcb_write_line m_irq_handler; + // TODO: is this even used by anything? devcb_write_line m_firq_handler; devcb_write_line m_nmi_handler; + devcb_write_line m_vreg_contrast_handler; uint8_t m_spriterombank[3]; int m_romoffset; diff --git a/src/mame/video/kaypro.cpp b/src/mame/video/kaypro.cpp index 5ed14cf2875..d8ecc2a81bf 100644 --- a/src/mame/video/kaypro.cpp +++ b/src/mame/video/kaypro.cpp @@ -115,14 +115,14 @@ uint32_t kaypro_state::screen_update_omni2(screen_device &screen, bitmap_ind16 & return 0; } -uint32_t kaypro_state::screen_update_kaypro2x(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +uint32_t kaypro_state::screen_update_kaypro484(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { m_framecnt++; m_crtc->screen_update(screen, bitmap, cliprect); return 0; } -/* bit 6 of kaypro2x_system_port selects alternate characters (A12 on character generator rom). +/* bit 6 of kaypro484_system_port selects alternate characters (A12 on character generator rom). The diagram specifies a 2732 with 28 pins, and more address pins. Possibly a 2764 or 27128. Since our dump only goes up to A11, the alternate character set doesn't exist. @@ -135,7 +135,7 @@ uint32_t kaypro_state::screen_update_kaypro2x(screen_device &screen, bitmap_rgb3 Not sure how the attributes interact, for example does an underline blink? */ -MC6845_UPDATE_ROW( kaypro_state::kaypro2x_update_row ) +MC6845_UPDATE_ROW( kaypro_state::kaypro484_update_row ) { const rgb_t *palette = m_palette->palette()->entry_list_raw(); uint32_t *p = &bitmap.pix32(y); @@ -253,20 +253,20 @@ void kaypro_state::mc6845_screen_configure() /**************************** I/O PORTS *****************************************************************/ -READ8_MEMBER( kaypro_state::kaypro2x_status_r ) +READ8_MEMBER( kaypro_state::kaypro484_status_r ) { /* Need bit 7 high or computer hangs */ return 0x80 | m_crtc->register_r(space, 0); } -WRITE8_MEMBER( kaypro_state::kaypro2x_index_w ) +WRITE8_MEMBER( kaypro_state::kaypro484_index_w ) { m_mc6845_ind = data & 0x1f; m_crtc->address_w( space, 0, data ); } -WRITE8_MEMBER( kaypro_state::kaypro2x_register_w ) +WRITE8_MEMBER( kaypro_state::kaypro484_register_w ) { static const uint8_t mcmask[32]={0xff,0xff,0xff,0x0f,0x7f,0x1f,0x7f,0x7f,3,0x1f,0x7f,0x1f,0x3f,0xff,0x3f,0xff,0,0}; @@ -297,12 +297,12 @@ WRITE8_MEMBER( kaypro_state::kaypro_videoram_w ) m_p_videoram[offset] = data; } -READ8_MEMBER( kaypro_state::kaypro2x_videoram_r ) +READ8_MEMBER( kaypro_state::kaypro484_videoram_r ) { return m_p_videoram[m_mc6845_video_address]; } -WRITE8_MEMBER( kaypro_state::kaypro2x_videoram_w ) +WRITE8_MEMBER( kaypro_state::kaypro484_videoram_w ) { m_p_videoram[m_mc6845_video_address] = data; } diff --git a/src/mame/video/kyugo.cpp b/src/mame/video/kyugo.cpp index 5e3edcac2fb..f482b2027b3 100644 --- a/src/mame/video/kyugo.cpp +++ b/src/mame/video/kyugo.cpp @@ -62,41 +62,41 @@ void kyugo_state::video_start() * *************************************/ -WRITE8_MEMBER(kyugo_state::kyugo_fgvideoram_w) +WRITE8_MEMBER(kyugo_state::fgvideoram_w) { m_fgvideoram[offset] = data; m_fg_tilemap->mark_tile_dirty(offset); } -WRITE8_MEMBER(kyugo_state::kyugo_bgvideoram_w) +WRITE8_MEMBER(kyugo_state::bgvideoram_w) { m_bgvideoram[offset] = data; m_bg_tilemap->mark_tile_dirty(offset); } -WRITE8_MEMBER(kyugo_state::kyugo_bgattribram_w) +WRITE8_MEMBER(kyugo_state::bgattribram_w) { m_bgattribram[offset] = data; m_bg_tilemap->mark_tile_dirty(offset); } -READ8_MEMBER(kyugo_state::kyugo_spriteram_2_r) +READ8_MEMBER(kyugo_state::spriteram_2_r) { // only the lower nibble is connected return m_spriteram_2[offset] | 0xf0; } -WRITE8_MEMBER(kyugo_state::kyugo_scroll_x_lo_w) +WRITE8_MEMBER(kyugo_state::scroll_x_lo_w) { m_scroll_x_lo = data; } -WRITE8_MEMBER(kyugo_state::kyugo_gfxctrl_w) +WRITE8_MEMBER(kyugo_state::gfxctrl_w) { /* bit 0 is scroll MSB */ m_scroll_x_hi = data & 0x01; @@ -121,7 +121,7 @@ WRITE8_MEMBER(kyugo_state::kyugo_gfxctrl_w) } -WRITE8_MEMBER(kyugo_state::kyugo_scroll_y_w) +WRITE8_MEMBER(kyugo_state::scroll_y_w) { m_scroll_y = data; } @@ -139,7 +139,7 @@ WRITE_LINE_MEMBER(kyugo_state::flipscreen_w) * *************************************/ -void kyugo_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect ) +void kyugo_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) { /* sprite information is scattered through memory */ /* and uses a portion of the text layer memory (outside the visible area) */ @@ -197,7 +197,7 @@ void kyugo_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect } -uint32_t kyugo_state::screen_update_kyugo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t kyugo_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { if (flip_screen()) m_bg_tilemap->set_scrollx(0, -(m_scroll_x_lo + (m_scroll_x_hi * 256))); diff --git a/src/mame/video/lasso.cpp b/src/mame/video/lasso.cpp index fab43088227..ab49ebd86da 100644 --- a/src/mame/video/lasso.cpp +++ b/src/mame/video/lasso.cpp @@ -92,9 +92,10 @@ PALETTE_INIT_MEMBER(lasso_state,wwjgtin) for (i = 0x40; i < 0x140; i++) { uint8_t ctabentry; + int raw_pen = i - 0x40; - if ((i - 0x40) & 0x03) - ctabentry = ((((i - 0x40) & 0xf0) >> 2) + ((i - 0x40) & 0x0f)) & 0x3f; + if (raw_pen & 0x03) + ctabentry = (((raw_pen & 0xf0) >> 2) + (raw_pen & 0x03)) & 0x3f; else ctabentry = 0; diff --git a/src/mame/video/mainevt.cpp b/src/mame/video/mainevt.cpp index 4189bc0c863..08aee6f1a7d 100644 --- a/src/mame/video/mainevt.cpp +++ b/src/mame/video/mainevt.cpp @@ -66,6 +66,9 @@ K051960_CB_MEMBER(mainevt_state::dv_sprite_callback) { enum { sprite_colorbase = 128 / 16 }; + // enable shadow if upper bits are 0 + *shadow = ((*color & 0xe0) >> 5) == 0; + /* TODO: the priority/shadow handling (bits 5-7) seems to be quite complex (see PROM) */ *color = sprite_colorbase + (*color & 0x07); } diff --git a/src/mame/video/mc80.cpp b/src/mame/video/mc80.cpp deleted file mode 100644 index e5ae4999e4e..00000000000 --- a/src/mame/video/mc80.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// license:BSD-3-Clause -// copyright-holders:Miodrag Milanovic -/*************************************************************************** - - MC-80.xx video by Miodrag Milanovic - - 15/05/2009 Initial implementation - 12/05/2009 Skeleton driver. - -****************************************************************************/ - -#include "emu.h" -#include "includes/mc80.h" - -// This is not a content of U402 510 -// but order is fine - -static const uint8_t prom[] = { - 0x0c,0x11,0x13,0x15,0x17,0x10,0x0e,0x00, // @ - 0x04,0x0a,0x11,0x11,0x1f,0x11,0x11,0x00, // A - 0x1e,0x11,0x11,0x1e,0x11,0x11,0x1e,0x00, // B - 0x0e,0x11,0x10,0x10,0x10,0x11,0x0e,0x00, // C - 0x1e,0x09,0x09,0x09,0x09,0x09,0x1e,0x00, // D - 0x1f,0x10,0x10,0x1e,0x10,0x10,0x1f,0x00, // E - 0x1f,0x10,0x10,0x1e,0x10,0x10,0x10,0x00, // F - 0x0e,0x11,0x10,0x10,0x13,0x11,0x0f,0x00, // G - - 0x11,0x11,0x11,0x1f,0x11,0x11,0x11,0x00, // H - 0x0e,0x04,0x04,0x04,0x04,0x04,0x0e,0x00, // I - 0x01,0x01,0x01,0x01,0x11,0x11,0x0e,0x00, // J - 0x11,0x12,0x14,0x18,0x14,0x12,0x11,0x00, // K - 0x10,0x10,0x10,0x10,0x10,0x10,0x1f,0x00, // L - 0x11,0x1b,0x15,0x15,0x11,0x11,0x11,0x00, // M - 0x11,0x11,0x19,0x15,0x13,0x11,0x11,0x00, // N - 0x0e,0x11,0x11,0x11,0x11,0x11,0x0e,0x00, // O - - 0x1e,0x11,0x11,0x1e,0x10,0x10,0x10,0x00, // P - 0x0e,0x11,0x11,0x11,0x15,0x12,0x0d,0x00, // Q - 0x1e,0x11,0x11,0x1e,0x14,0x12,0x11,0x00, // R - 0x0e,0x11,0x10,0x0e,0x01,0x11,0x0e,0x00, // S - 0x1f,0x04,0x04,0x04,0x04,0x04,0x04,0x00, // T - 0x11,0x11,0x11,0x11,0x11,0x11,0x0e,0x00, // U - 0x11,0x11,0x11,0x0a,0x0a,0x04,0x04,0x00, // V - 0x11,0x11,0x11,0x15,0x15,0x15,0x0a,0x00, // W - - 0x11,0x11,0x0a,0x04,0x0a,0x11,0x11,0x00, // X - 0x11,0x11,0x0a,0x04,0x04,0x04,0x04,0x00, // Y - 0x1f,0x01,0x02,0x04,0x08,0x10,0x1f,0x00, // Z - 0x1c,0x10,0x10,0x10,0x10,0x10,0x1c,0x00, // [ - 0x00,0x10,0x08,0x04,0x02,0x01,0x00,0x00, // backslash - 0x07,0x01,0x01,0x01,0x01,0x01,0x07,0x00, // ] - 0x0e,0x11,0x00,0x00,0x00,0x00,0x00,0x00, // ^ - 0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00, // _ - - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // - 0x04,0x04,0x04,0x04,0x04,0x00,0x04,0x00, // ! - 0x0a,0x0a,0x0a,0x00,0x00,0x00,0x00,0x00, // " - 0x0a,0x0a,0x1f,0x0a,0x1f,0x0a,0x0a,0x00, // # - 0x00,0x11,0x0e,0x0a,0x0e,0x11,0x00,0x00, // [] - 0x18,0x19,0x02,0x04,0x08,0x13,0x03,0x00, // % - 0x04,0x0a,0x0a,0x0c,0x15,0x12,0x0d,0x00, // & - 0x04,0x04,0x08,0x00,0x00,0x00,0x00,0x00, // ' - - 0x02,0x04,0x08,0x08,0x08,0x04,0x02,0x00, // ( - 0x08,0x04,0x02,0x02,0x02,0x04,0x08,0x00, // ) - 0x00,0x04,0x15,0x0e,0x15,0x04,0x00,0x00, // * - 0x00,0x04,0x04,0x1f,0x04,0x04,0x00,0x00, // + - 0x00,0x00,0x00,0x00,0x08,0x08,0x10,0x00, // , - 0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x00, // - - 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00, // . - 0x00,0x01,0x02,0x04,0x08,0x10,0x00,0x00, // / - - 0x0e,0x11,0x13,0x15,0x19,0x11,0x0e,0x00, // 0 - 0x04,0x0c,0x04,0x04,0x04,0x04,0x0e,0x00, // 1 - 0x0e,0x11,0x01,0x06,0x08,0x10,0x1f,0x00, // 2 - 0x1f,0x01,0x02,0x06,0x01,0x11,0x0e,0x00, // 3 - 0x02,0x06,0x0a,0x12,0x1f,0x02,0x02,0x00, // 4 - 0x1f,0x10,0x1e,0x01,0x01,0x11,0x0e,0x00, // 5 - 0x07,0x08,0x10,0x1e,0x11,0x11,0x0e,0x00, // 6 - 0x1f,0x01,0x02,0x04,0x08,0x08,0x08,0x00, // 7 - - 0x0e,0x11,0x11,0x0e,0x11,0x11,0x0e,0x00, // 8 - 0x0e,0x11,0x11,0x0f,0x01,0x02,0x1c,0x00, // 9 - 0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00, // : - 0x00,0x00,0x04,0x00,0x04,0x04,0x08,0x00, // ; - 0x02,0x04,0x08,0x10,0x08,0x04,0x02,0x00, // < - 0x00,0x00,0x1f,0x00,0x1f,0x00,0x00,0x00, // = - 0x08,0x04,0x02,0x01,0x02,0x04,0x08,0x00, // > - 0x0e,0x11,0x01,0x02,0x04,0x00,0x04,0x00 // ? -}; - -/*****************************************************************************/ -/* Implementation for MC80.2x */ -/*****************************************************************************/ - - - -VIDEO_START_MEMBER(mc80_state,mc8020) -{ -} - -uint32_t mc80_state::screen_update_mc8020(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - uint8_t y,ra,chr,gfx; - uint16_t sy=0,ma=0,x; - - for(y = 0; y < 8; y++ ) - { - for (ra = 0; ra < 16; ra++) - { - uint16_t *p = &bitmap.pix16(sy++); - - for (x = ma; x < ma + 32; x++) - { - if (ra > 3 && ra < 12) - { - chr = m_p_videoram[x]; - gfx = prom[(chr<<3) | (ra-4)]; - } - else - gfx = 0; - - /* Display a scanline of a character */ - *p++ = BIT(gfx, 5); - *p++ = BIT(gfx, 4); - *p++ = BIT(gfx, 3); - *p++ = BIT(gfx, 2); - *p++ = BIT(gfx, 1); - *p++ = BIT(gfx, 0); - } - } - ma+=32; - } - return 0; -} - -/*****************************************************************************/ -/* Implementation for MC80.3x */ -/*****************************************************************************/ - - -VIDEO_START_MEMBER(mc80_state,mc8030) -{ - m_p_videoram.set_target(memregion("vram")->base(),m_p_videoram.bytes()); -} - -uint32_t mc80_state::screen_update_mc8030(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - uint8_t gfx; - uint16_t y=0,ma=0,x; - - for(y = 0; y < 256; y++ ) - { - uint16_t *p = &bitmap.pix16(y); - { - for (x = ma; x < ma + 64; x++) - { - gfx = m_p_videoram[x^0x3fff]; - - /* Display a scanline of a character */ - *p++ = BIT(gfx, 7); - *p++ = BIT(gfx, 6); - *p++ = BIT(gfx, 5); - *p++ = BIT(gfx, 4); - *p++ = BIT(gfx, 3); - *p++ = BIT(gfx, 2); - *p++ = BIT(gfx, 1); - *p++ = BIT(gfx, 0); - } - } - ma+=64; - } - return 0; -} diff --git a/src/mame/video/metro.cpp b/src/mame/video/metro.cpp index 663fa3ee61d..cd223c00496 100644 --- a/src/mame/video/metro.cpp +++ b/src/mame/video/metro.cpp @@ -2,54 +2,8 @@ // copyright-holders:Luca Elia, David Haywood /*************************************************************************** - -= Metro Games =- - - driver by Luca Elia (l.elia@tin.it) - - -Note: if MAME_DEBUG is defined, pressing Z with: - - Q Shows Layer 0 - W Shows Layer 1 - E Shows Layer 2 - A Shows Sprites - - Keys can be used together! - - - [ 3 Scrolling Layers ] - - There is memory for a huge layer, but the actual tilemap - is a smaller window (of fixed size) carved from anywhere - inside that layer. - - Tile Size: 8 x 8 x 4 - (later games can switch to 8 x 8 x 8, 16 x 16 x 4/8 at run time) - - Big Layer Size: 2048 x 2048 (8x8 tiles) or 4096 x 4096 (16x16 tiles) - - Tilemap Window Size: 512 x 256 (8x8 tiles) or 1024 x 512 (16x16 tiles) - - The tile codes in memory do not map directly to tiles. They - are indexes into a table (with 0x200 entries) that defines - a virtual set of tiles for the 3 layers. Each entry in that - table adds 16 tiles to the set of available tiles, and decides - their color code. - - Tile code with their msbit set are different as they mean: - draw a tile filled with a single color (0-fff) - - - [ 512 Zooming Sprites ] - - The sprites are NOT tile based: the "tile" size can vary from - 8 to 64 (independently for width and height) with an 8 pixel - granularity. The "tile" address is a multiple of 8x8 pixels. - - Each sprite can be shrinked to ~1/4 or enlarged to ~32x following - an exponential curve of sizes (with one zoom value for both width - and height) - + (legacy metro.cpp, currently contains Blazing Tornado overrides, + to be moved into its own driver file!) ***************************************************************************/ @@ -95,626 +49,30 @@ TILEMAP_MAPPER_MEMBER(metro_state::tilemap_scan_gstrik2) return val; } - - -/*************************************************************************** - - Tilemaps: Tiles Set & Window - - Each entry in the Tiles Set RAM uses 2 words to specify a starting - tile code and a color code. This adds 16 consecutive tiles with - that color code to the set of available tiles. - - Offset: Bits: Value: - - 0.w fedc ---- ---- ---- - ---- ba98 7654 ---- Color Code* - ---- ---- ---- 3210 Code High Bits - - 2.w Code Low Bits - -* 00-ff, but on later chips supporting it, xf means 256 color tile and palette x - -***************************************************************************/ - - -/*************************************************************************** - - - Tilemaps: Rendering - - -***************************************************************************/ - -// A 2048 x 2048 virtual tilemap -#define BIG_NX (0x100) -#define BIG_NY (0x100) - -// A smaller 512 x 256 window defines the actual tilemap - -#define WIN_NX (0x40) -#define WIN_NY (0x20) - -/* This looks up a single pixel in a tile, given the tile code. - The Metro hardware has an indirection table, which is used here. - Returns if to draw the pixel or not, pixel colour is placed in pix */ -inline uint8_t metro_state::get_tile_pix( uint16_t code, uint8_t x, uint8_t y, int big, uint16_t *pix ) -{ - int table_index; - uint32_t tile; - - // Use code as an index into the tiles set table - table_index = ((code & 0x1ff0) >> 4) * 2; - tile = (m_tiletable[table_index + 0] << 16) + m_tiletable[table_index + 1]; - - if (code & 0x8000) // Special: draw a tile of a single color (i.e. not from the gfx ROMs) - { - *pix = code & 0x0fff; - - if ((*pix & 0xf) != 0xf) - return 1; - else - return 0; - } - else if (((tile & 0x00f00000) == 0x00f00000) && (m_support_8bpp)) /* draw tile as 8bpp (e.g. balcube bg) */ - { - gfx_element *gfx1 = m_gfxdecode->gfx(big?3:1); - uint32_t tile2 = big ? ((tile & 0xfffff) + 8*(code & 0xf)) : - ((tile & 0xfffff) + 2*(code & 0xf)); - const uint8_t* data; - uint8_t flipxy = (code & 0x6000) >> 13; - - if (tile2 < gfx1->elements()) - data = gfx1->get_data(tile2); - else - { - *pix = 0; - return 0; - } - - switch (flipxy) - { - default: - case 0x0: *pix = data[(y * (big?16:8)) + x]; break; - case 0x1: *pix = data[(((big?15:7)-y) * (big?16:8)) + x]; break; - case 0x2: *pix = data[(y * (big?16:8)) + ((big?15:7)-x)]; break; - case 0x3: *pix = data[(((big?15:7)-y) * (big?16:8)) + ((big?15:7)-x)]; break; - } - - *pix |= ((tile & 0x0f000000) >> 24) * 0x100; - - if ((*pix & 0xff) != 0xff) - return 1; - else - return 0; - } - else - { - gfx_element *gfx1 = m_gfxdecode->gfx(big?2:0); - uint32_t tile2 = big ? ((tile & 0xfffff) + 4*(code & 0xf)) : - ((tile & 0xfffff) + (code & 0xf)); - const uint8_t* data; - uint8_t flipxy = (code & 0x6000) >> 13; - - if (tile2 < gfx1->elements()) - data = gfx1->get_data(tile2); - else - { - *pix = 0; - return 0; - } - - switch (flipxy) - { - default: - case 0x0: *pix = data[(y * (big?16:8)) + x]; break; - case 0x1: *pix = data[(((big?15:7)-y) * (big?16:8)) + x]; break; - case 0x2: *pix = data[(y * (big?16:8)) + ((big?15:7)-x)]; break; - case 0x3: *pix = data[(((big?15:7)-y) * (big?16:8)) + ((big?15:7)-x)]; break; - } - - *pix |= (((tile & 0x0ff00000) >> 20)) * 0x10; - - if ((*pix & 0xf) != 0xf) - return 1; - else - return 0; - } -} - - -inline void metro_state::metro_vram_w( offs_t offset, uint16_t data, uint16_t mem_mask, int layer, uint16_t *vram ) -{ - COMBINE_DATA(&vram[offset]); -} - -WRITE16_MEMBER(metro_state::metro_vram_0_w){ metro_vram_w(offset, data, mem_mask, 0, m_vram_0); } -WRITE16_MEMBER(metro_state::metro_vram_1_w){ metro_vram_w(offset, data, mem_mask, 1, m_vram_1); } -WRITE16_MEMBER(metro_state::metro_vram_2_w){ metro_vram_w(offset, data, mem_mask, 2, m_vram_2); } - - - -WRITE16_MEMBER(metro_state::metro_window_w) -{ - COMBINE_DATA(&m_window[offset]); -} - - - -/*************************************************************************** - - - Video Init Routines - - -***************************************************************************/ - -/* - Sprites are not tile based, so we decode their graphics at runtime. -*/ - -void metro_state::expand_gfx1() -{ - uint8_t *base_gfx = memregion("gfx1")->base(); - uint32_t length = memregion("gfx1")->bytes() * 2; - - m_expanded_gfx1 = std::make_unique<uint8_t[]>(length); - - for (int i = 0; i < length; i += 2) - { - uint8_t src = base_gfx[i / 2]; - - m_expanded_gfx1[i + 0] = src & 0xf; - m_expanded_gfx1[i + 1] = src >> 4; - } -} - -VIDEO_START_MEMBER(metro_state,metro_i4100) -{ - expand_gfx1(); - - m_support_8bpp = 0; - m_support_16x16 = 0; - m_has_zoom = 0; - - m_tilemap_scrolldx[0] = 0; - m_tilemap_scrolldx[1] = 0; - m_tilemap_scrolldx[2] = 0; - - m_sprite_xoffs_dx = 0; -} - -VIDEO_START_MEMBER(metro_state,metro_i4220) -{ - VIDEO_START_CALL_MEMBER(metro_i4100); - - m_support_8bpp = 1; // balcube - m_support_16x16 = 1; // vmetal -} -VIDEO_START_MEMBER(metro_state,metro_i4220_dx_tmap) -{ - VIDEO_START_CALL_MEMBER(metro_i4220); - - m_tilemap_scrolldx[0] = -2; - m_tilemap_scrolldx[1] = -2; - m_tilemap_scrolldx[2] = -2; -} -VIDEO_START_MEMBER(metro_state,metro_i4220_dx_sprite) -{ - VIDEO_START_CALL_MEMBER(metro_i4220); - - m_sprite_xoffs_dx = 8; -} - -VIDEO_START_MEMBER(metro_state,metro_i4300) -{ - VIDEO_START_CALL_MEMBER(metro_i4220); - - // any additional feature? -} - VIDEO_START_MEMBER(metro_state,blzntrnd) { - VIDEO_START_CALL_MEMBER(metro_i4220); - - m_has_zoom = 1; - m_k053936_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(metro_state::metro_k053936_get_tile_info),this), TILEMAP_SCAN_ROWS, 8, 8, 256, 512); - m_tilemap_scrolldx[0] = 8; - m_tilemap_scrolldx[1] = 8; - m_tilemap_scrolldx[2] = 8; + m_screen->register_screen_bitmap(m_vdp_bitmap); } VIDEO_START_MEMBER(metro_state,gstrik2) { - VIDEO_START_CALL_MEMBER(metro_i4220); - - m_has_zoom = 1; - m_k053936_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(metro_state::metro_k053936_gstrik2_get_tile_info),this), tilemap_mapper_delegate(FUNC(metro_state::tilemap_scan_gstrik2),this), 16, 16, 128, 256); - m_tilemap_scrolldx[0] = 8; - m_tilemap_scrolldx[1] = 0; - m_tilemap_scrolldx[2] = 8; + m_screen->register_screen_bitmap(m_vdp_bitmap); } -/*************************************************************************** - - Video Registers - - - Offset: Bits: Value: - - 0.w Number Of Sprites To Draw - 2.w f--- ---- ---- ---- Disable Sprites Layer Priority - -edc ---- ---- ---- - ---- ba-- ---- ---- Sprites Masked Layer - ---- --98 ---- ---- Sprites Priority - ---- ---- 765- ---- - ---- ---- ---4 3210 Sprites Masked Number - 4.w Sprites Y Offset - 6.w Sprites X Offset - 8.w Sprites Color Codes Start - - - - - 10.w fedc ba98 76-- ---- - ---- ---- --54 ---- Layer 2 Priority (3 backmost, 0 frontmost) - ---- ---- ---- 32-- Layer 1 Priority - ---- ---- ---- --10 Layer 0 Priority - - 12.w Backround Color - - -***************************************************************************/ - - - -/*************************************************************************** - - - Sprites Drawing - - - Offset: Bits: Value: - - 0.w fedc b--- ---- ---- Priority (0 = Max) - ---- -a98 7654 3210 X - - 2.w fedc ba-- ---- ---- Zoom (Both X & Y) - ---- --98 7654 3210 Y - - 4.w f--- ---- ---- ---- Flip X - -e-- ---- ---- ---- Flip Y - --dc b--- ---- ---- Size X * - ---- -a98 ---- ---- Size Y * - ---- ---- 7654 ---- Color - ---- ---- ---- 3210 Code High Bits ** - - 6.w Code Low Bits ** - -* 8 pixel increments -** 8x8 pixel increments - -***************************************************************************/ - -void metro_state::metro_draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) +uint32_t metro_state::screen_update_psac_vdp2_mix(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - uint8_t *base_gfx4 = m_expanded_gfx1.get(); - uint8_t *base_gfx8 = memregion("gfx1")->base(); - uint32_t gfx_size = memregion("gfx1")->bytes(); - - int max_x = m_screen->width(); - int max_y = m_screen->height(); - - int max_sprites = m_spriteram.bytes() / 8; - int sprites = m_videoregs[0x00/2] % max_sprites; - - int color_start = (m_videoregs[0x08/2] & 0x0f) << 4; - - int i, j, pri; - static const int primask[4] = { 0x0000, 0xff00, 0xff00 | 0xf0f0, 0xff00 | 0xf0f0 | 0xcccc }; - - uint16_t *src; - int inc; - - if (sprites == 0) - return; - - for (i = 0; i < 0x20; i++) - { - if (!(m_videoregs[0x02/2] & 0x8000)) - { - src = m_spriteram + (sprites - 1) * (8 / 2); - inc = -(8 / 2); - } else { - src = m_spriteram; - inc = (8 / 2); - } - - for (j = 0; j < sprites; j++) - { - int x, y, attr, code, color, flipx, flipy, zoom, curr_pri, width, height; - - // Exponential zoom table extracted from daitoride - static const int zoomtable[0x40] = - { 0xAAC,0x800,0x668,0x554,0x494,0x400,0x390,0x334, - 0x2E8,0x2AC,0x278,0x248,0x224,0x200,0x1E0,0x1C8, - 0x1B0,0x198,0x188,0x174,0x164,0x154,0x148,0x13C, - 0x130,0x124,0x11C,0x110,0x108,0x100,0x0F8,0x0F0, - 0x0EC,0x0E4,0x0DC,0x0D8,0x0D4,0x0CC,0x0C8,0x0C4, - 0x0C0,0x0BC,0x0B8,0x0B4,0x0B0,0x0AC,0x0A8,0x0A4, - 0x0A0,0x09C,0x098,0x094,0x090,0x08C,0x088,0x080, - 0x078,0x070,0x068,0x060,0x058,0x050,0x048,0x040 }; - - x = src[0]; - curr_pri = (x & 0xf800) >> 11; - - if ((curr_pri == 0x1f) || (curr_pri != i)) - { - src += inc; - continue; - } - - pri = (m_videoregs[0x02/2] & 0x0300) >> 8; - - if (!(m_videoregs[0x02/2] & 0x8000)) - { - if (curr_pri > (m_videoregs[0x02/2] & 0x1f)) - pri = (m_videoregs[0x02/2] & 0x0c00) >> 10; - } - - y = src[1]; - attr = src[2]; - code = src[3]; - - flipx = attr & 0x8000; - flipy = attr & 0x4000; - color = (attr & 0xf0) >> 4; - - zoom = zoomtable[(y & 0xfc00) >> 10] << (16 - 8); - - x = (x & 0x07ff) - m_sprite_xoffs; - y = (y & 0x03ff) - m_sprite_yoffs; - - width = (((attr >> 11) & 0x7) + 1) * 8; - height = (((attr >> 8) & 0x7) + 1) * 8; - - uint32_t gfxstart = (8 * 8 * 4 / 8) * (((attr & 0x000f) << 16) + code); - - if (m_flip_screen) - { - flipx = !flipx; x = max_x - x - width; - flipy = !flipy; y = max_y - y - height; - } - - if (m_support_8bpp && color == 0xf) /* 8bpp */ - { - /* Bounds checking */ - if ((gfxstart + width * height - 1) >= gfx_size) - continue; - - gfx_element gfx(m_palette, base_gfx8 + gfxstart, width, height, width, m_palette->entries(), 0, 256); - - gfx.prio_zoom_transpen(bitmap,cliprect, - 0, - color_start >> 4, - flipx, flipy, - x, y, - zoom, zoom, - screen.priority(),primask[pri], 255); - } - else - { - /* Bounds checking */ - if ((gfxstart + width / 2 * height - 1) >= gfx_size) - continue; - - gfx_element gfx(m_palette, base_gfx4 + 2 * gfxstart, width, height, width, m_palette->entries(),0, 16); - - gfx.prio_zoom_transpen(bitmap,cliprect, - 0, - color + color_start, - flipx, flipy, - x, y, - zoom, zoom, - screen.priority(),primask[pri], 15); - } -#if 0 -{ /* Display priority + zoom on each sprite */ - char buf[80]; - sprintf(buf, "%02X %02X", ((src[0] & 0xf800) >> 11) ^ 0x1f, ((src[1] & 0xfc00) >> 10)); - ui_draw_text(buf, x, y); -} -#endif - src += inc; - } - } -} - - - -/*************************************************************************** - - - Screen Drawing - - -***************************************************************************/ - -// Copy a 'window' from the large 2048x2048 (or 4096x4096 for 16x16 tiles) tilemap - -void metro_state::draw_tilemap( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, uint32_t flags, uint32_t pcode, - int sx, int sy, int wx, int wy, int big, uint16_t *tilemapram, int layer ) -{ - int y; - - bitmap_ind8 &priority_bitmap = m_screen->priority(); - - int width = big ? 4096 : 2048; - int height = big ? 4096 : 2048; - - int scrwidth = bitmap.width(); - int scrheight = bitmap.height(); - - int windowwidth = width >> 2; - int windowheight = height >> 3; - - sx += m_tilemap_scrolldx[layer] * (m_flip_screen ? 1 : -1); - - for (y = 0; y < scrheight; y++) - { - int scrolly = (sy+y-wy)&(windowheight-1); - int x; - uint16_t *dst; - uint8_t *priority_baseaddr; - int srcline = (wy+scrolly)&(height-1); - int srctilerow = srcline >> (big ? 4 : 3); - - if (!m_flip_screen) - { - dst = &bitmap.pix16(y); - priority_baseaddr = &priority_bitmap.pix8(y); - - for (x = 0; x < scrwidth; x++) - { - int scrollx = (sx+x-wx)&(windowwidth-1); - int srccol = (wx+scrollx)&(width-1); - int srctilecol = srccol >> (big ? 4 : 3); - int tileoffs = srctilecol + srctilerow * BIG_NX; - - uint16_t dat = 0; - - uint16_t tile = tilemapram[tileoffs]; - uint8_t draw = get_tile_pix(tile, big ? (srccol&0xf) : (srccol&0x7), big ? (srcline&0xf) : (srcline&0x7), big, &dat); - - if (draw) - { - dst[x] = dat; - priority_baseaddr[x] = (priority_baseaddr[x] & (pcode >> 8)) | pcode; - } - } - } - else // flipped case - { - dst = &bitmap.pix16(scrheight-y-1); - priority_baseaddr = &priority_bitmap.pix8(scrheight-y-1); - - for (x = 0; x < scrwidth; x++) - { - int scrollx = (sx+x-wx)&(windowwidth-1); - int srccol = (wx+scrollx)&(width-1); - int srctilecol = srccol >> (big ? 4 : 3); - int tileoffs = srctilecol + srctilerow * BIG_NX; - - uint16_t dat = 0; - - uint16_t tile = tilemapram[tileoffs]; - uint8_t draw = get_tile_pix(tile, big ? (srccol&0xf) : (srccol&0x7), big ? (srcline&0xf) : (srcline&0x7), big, &dat); - - if (draw) - { - dst[scrwidth-x-1] = dat; - priority_baseaddr[scrwidth-x-1] = (priority_baseaddr[scrwidth-x-1] & (pcode >> 8)) | pcode; - } - } - } - } -} - -// Draw all the layers that match the given priority - -void metro_state::draw_layers( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int pri, int layers_ctrl ) -{ - uint16_t layers_pri = m_videoregs[0x10 / 2]; - int layer; - - // Draw all the layers with priority == pri - for (layer = 2; layer >= 0; layer--) - { - if (pri == ((layers_pri >> (layer * 2)) & 3)) - { - // Scroll and Window values - uint16_t sy = m_scroll[layer * 2 + 0]; uint16_t sx = m_scroll[layer * 2 + 1]; - uint16_t wy = m_window[layer * 2 + 0]; uint16_t wx = m_window[layer * 2 + 1]; - - if (BIT(layers_ctrl, layer)) // for debug - { - uint16_t *tilemapram = nullptr; - - switch (layer) - { - case 0: tilemapram = m_vram_0; break; - case 1: tilemapram = m_vram_1; break; - case 2: tilemapram = m_vram_2; break; - } - - int big = m_support_16x16 && (*m_screenctrl & (0x0020 << layer)); - - draw_tilemap(screen, bitmap, cliprect, 0, 1 << (3 - pri), sx, sy, wx, wy, big, tilemapram, layer); - } - } - } -} - - -uint32_t metro_state::screen_update_metro(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - int pri, layers_ctrl = -1; - uint16_t screenctrl = *m_screenctrl; - - m_sprite_xoffs = m_videoregs[0x06 / 2] - screen.width() / 2 + m_sprite_xoffs_dx; - m_sprite_yoffs = m_videoregs[0x04 / 2] - screen.height() / 2; - - screen.priority().fill(0, cliprect); - - // The background color is selected by a register - bitmap.fill(m_videoregs[0x12/2] & 0x0fff, cliprect); - - /* Screen Control Register: - - f--- ---- ---- ---- ? - -edc b--- ---- ---- - ---- -a98 ---- ---- ? Leds (see gakusai attract) - ---- ---- 765- ---- 16x16 Tiles (Layer 2-1-0) - ---- ---- ---4 32-- - ---- ---- ---- --1- Blank Screen - ---- ---- ---- ---0 Flip Screen */ - if (screenctrl & 2) - return 0; - - m_flip_screen = screenctrl & 1; - -#ifdef MAME_DEBUG -if (machine().input().code_pressed(KEYCODE_Z)) -{ - int msk = 0; - if (machine().input().code_pressed(KEYCODE_Q)) msk |= 1; - if (machine().input().code_pressed(KEYCODE_W)) msk |= 2; - if (machine().input().code_pressed(KEYCODE_E)) msk |= 4; - if (machine().input().code_pressed(KEYCODE_A)) msk |= 8; - if (msk != 0) - { - bitmap.fill(m_palette->black_pen(), cliprect); - layers_ctrl &= msk; - } - - popmessage( "lyr: %x-%x-%x spr: %04x clr: %04x scr: %04x", - (m_videoregs[0x10/2] & 0x30) >> 4, (m_videoregs[0x10/2] & 0xc) >> 2, m_videoregs[0x10/2] & 3, - m_videoregs[0x02/2], m_videoregs[0x12/2], - *m_screenctrl); -} -#endif - - if (m_has_zoom) - m_k053936->zoom_draw(screen, bitmap, cliprect, m_k053936_tilemap, 0, 0, 1); - - for (pri = 3; pri >= 0; pri--) - draw_layers(screen, bitmap, cliprect, pri, layers_ctrl); + /* TODO: bit 5 of reg 7 is off when ROZ is supposed to be disabled + * (Blazing Tornado title screen/character select/ending and Grand Striker 2 title/how to play transition) + */ - if (layers_ctrl & 0x08) - metro_draw_sprites(screen, bitmap, cliprect); + bitmap.fill(m_vdp2->get_background_pen(), cliprect); + m_k053936->zoom_draw(screen, bitmap, cliprect, m_k053936_tilemap, 0, 0, 1); + m_vdp2->screen_update(screen, m_vdp_bitmap, cliprect); + copybitmap_trans(bitmap, m_vdp_bitmap, 0, 0, 0, 0, cliprect, m_vdp2->get_background_pen()); return 0; } diff --git a/src/mame/video/midvunit.cpp b/src/mame/video/midvunit.cpp index 3c2fd31ffb9..254085185ee 100644 --- a/src/mame/video/midvunit.cpp +++ b/src/mame/video/midvunit.cpp @@ -40,9 +40,6 @@ void midvunit_state::device_timer(emu_timer &timer, device_timer_id id, int para { switch (id) { - case TIMER_ADC_READY: - m_maincpu->set_input_line(3, ASSERT_LINE); - break; case TIMER_SCANLINE: scanline_timer_cb(ptr, param); break; diff --git a/src/mame/video/mystston.cpp b/src/mame/video/mystston.cpp index e592668a459..f802cf64ab4 100644 --- a/src/mame/video/mystston.cpp +++ b/src/mame/video/mystston.cpp @@ -25,14 +25,15 @@ * Video timing constants * *************************************/ - -#define PIXEL_CLOCK (MYSTSTON_MASTER_CLOCK / 2) -#define HTOTAL (0x180) -#define HBEND (0x000) -#define HBSTART (0x100) -#define VTOTAL (0x110) /* counts from 0x08-0xff, then from 0xe8-0xff */ -#define VBEND (0x008) -#define VBSTART (0x0f8) +// HMC20 +// MCFG_SCREEN_RAW_PARAMS(XTAL_12MHz/2,384,0,256,272,8,248) +#define PIXEL_CLOCK (XTAL_12MHz / 2) +#define HTOTAL (384) +#define HBEND (0) +#define HBSTART (256) +#define VTOTAL (272) /* counts from 0x08-0xff, then from 0xe8-0xff */ +#define VBEND (8) +#define VBSTART (248) #define FIRST_INT_VPOS (0x008) #define INT_HPOS (0x100) diff --git a/src/mame/video/pacland.cpp b/src/mame/video/pacland.cpp index 2a2b5332666..065bd733cd5 100644 --- a/src/mame/video/pacland.cpp +++ b/src/mame/video/pacland.cpp @@ -189,6 +189,8 @@ TILE_GET_INFO_MEMBER(pacland_state::get_fg_tile_info) void pacland_state::video_start() { + m_screen->register_screen_bitmap(m_sprite_bitmap); + m_screen->register_screen_bitmap(m_fg_bitmap); m_fg_bitmap.fill(0xffff); @@ -301,7 +303,7 @@ void pacland_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, co } sy -= 16 * sizey; - sy = (sy & 0xff) - 32; // fix wraparound + sy = (sy & 0xff) - 32; // fix wraparound for (y = 0;y <= sizey;y++) { @@ -382,7 +384,21 @@ uint32_t pacland_state::screen_update(screen_device &screen, bitmap_ind16 &bitma /* draw high priority fg tiles */ draw_fg(screen, bitmap, cliprect, 1); - /* draw sprite pixels with colortable values >= 0xf0, which have priority over everything */ - draw_sprites(screen, bitmap, cliprect, flip, 2); + /* draw sprite pixels with colortable values >= 0xf0, which have priority over all fg tiles */ + m_sprite_bitmap.fill(0, cliprect); + draw_sprites(screen, m_sprite_bitmap, cliprect, flip, 2); + for (int y = cliprect.min_y; y <= cliprect.max_y; y++) + { + uint16_t *src = &m_sprite_bitmap.pix16(y); + uint16_t *dst = &bitmap.pix16(y); + + for (int x = cliprect.min_x; x <= cliprect.max_x; x++) + { + uint16_t pix = src[x]; + if (pix != 0 && dst[x] < 0x800) + dst[x] = pix; + } + } + return 0; } diff --git a/src/mame/video/pc_t1t.cpp b/src/mame/video/pc_t1t.cpp index 8f4ee89f3db..1a646c54a80 100644 --- a/src/mame/video/pc_t1t.cpp +++ b/src/mame/video/pc_t1t.cpp @@ -133,8 +133,8 @@ MACHINE_CONFIG_MEMBER( pcvideo_t1000_device::device_add_mconfig ) MCFG_DEVICE_ADD("vram", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vram_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MACHINE_CONFIG_END @@ -156,8 +156,8 @@ MACHINE_CONFIG_MEMBER( pcvideo_pcjr_device::device_add_mconfig ) MCFG_DEVICE_ADD("vram", ADDRESS_MAP_BANK, 0) MCFG_DEVICE_PROGRAM_MAP(vram_map) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) - MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(18) + MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(18) MCFG_ADDRESS_MAP_BANK_STRIDE(0x4000) MACHINE_CONFIG_END diff --git a/src/mame/video/pcd.cpp b/src/mame/video/pcd.cpp index 670f86e31ac..19ad4b1a907 100644 --- a/src/mame/video/pcd.cpp +++ b/src/mame/video/pcd.cpp @@ -115,7 +115,7 @@ MACHINE_CONFIG_MEMBER( pcd_video_device::device_add_mconfig ) MCFG_PALETTE_ADD("palette", 3) MCFG_PALETTE_INIT_OWNER(pcdx_video_device, pcdx) - MCFG_SCN2674_VIDEO_ADD("crtc", 0, NOOP); + MCFG_DEVICE_ADD("crtc", SCN2674, 0) MCFG_SCN2674_TEXT_CHARACTER_WIDTH(8) MCFG_SCN2674_GFX_CHARACTER_WIDTH(16) MCFG_SCN2674_DRAW_CHARACTER_CALLBACK_OWNER(pcd_video_device, display_pixels) @@ -157,7 +157,8 @@ MACHINE_CONFIG_MEMBER( pcx_video_device::device_add_mconfig ) MCFG_PALETTE_ADD_MONOCHROME("palette") - MCFG_SCN2674_VIDEO_ADD("crtc", 0, INPUTLINE("graphics", MCS51_INT0_LINE)); + MCFG_DEVICE_ADD("crtc", SCN2674, 0) + MCFG_SCN2674_INTR_CALLBACK(INPUTLINE("graphics", MCS51_INT0_LINE)) MCFG_SCN2674_TEXT_CHARACTER_WIDTH(8) MCFG_SCN2674_GFX_CHARACTER_WIDTH(16) MCFG_SCN2674_DRAW_CHARACTER_CALLBACK_OWNER(pcx_video_device, display_pixels) diff --git a/src/mame/video/pgm2.cpp b/src/mame/video/pgm2.cpp new file mode 100644 index 00000000000..c036d92080b --- /dev/null +++ b/src/mame/video/pgm2.cpp @@ -0,0 +1,340 @@ +// license:BSD-3-Clause +// copyright-holders:David Haywood + +#include "includes/pgm2.h" + +inline void pgm2_state::draw_sprite_pixel(const rectangle &cliprect, int palette_offset, int realx, int realy, int pal) +{ + if (cliprect.contains(realx, realy)) + { + uint16_t pix = m_sprites_colour[palette_offset] & 0x3f; // there are some stray 0xff bytes in some roms, so mask + uint16_t pendat = pix + (pal * 0x40); + uint16_t* dstptr_bitmap = &m_sprite_bitmap.pix16(realy); + dstptr_bitmap[realx] = pendat; + } +} + +inline void pgm2_state::draw_sprite_chunk(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw, int realdraw_inc, int palette_inc) +{ + for (int xchunk = 0; xchunk < 32; xchunk++) + { + int pix, xzoombit; + if (palette_inc == -1) + { + pix = (maskdata >> xchunk) & 1; + xzoombit = (zoomx_bits >> xchunk) & 1; + } + else + { + pix = (maskdata >> (31 - xchunk)) & 1; + xzoombit = (zoomx_bits >> (31 - xchunk)) & 1; + } + + if (growx) + { + if (pix) + { + draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal); + realxdraw += realdraw_inc; + + if (xzoombit) + { + draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal); + realxdraw += realdraw_inc; + } + + palette_offset += palette_inc; + palette_offset &= m_sprites_colour_mask; + } + else + { + realxdraw += realdraw_inc; + if (xzoombit) realxdraw += realdraw_inc; + } + } + else + { + if (pix) + { + if (xzoombit) draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal); + + palette_offset += palette_inc; + palette_offset &= m_sprites_colour_mask; + } + + if (xzoombit) realxdraw += realdraw_inc; + } + } +} + +inline void pgm2_state::skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int reverse) +{ + int bits = population_count_32(maskdata); + + if (!reverse) + { + palette_offset+=bits; + } + else + { + palette_offset-=bits; + } + + palette_offset &= m_sprites_colour_mask; + +} + +inline void pgm2_state::draw_sprite_line(const rectangle &cliprect, int &mask_offset, int &palette_offset, int x, int realy, int flipx, int reverse, int sizex, int pal, int zoomybit, int zoomx_bits, int growx) +{ + int realxdraw = 0; + + if (flipx ^ reverse) + realxdraw = (population_count_32(zoomx_bits) * sizex) - 1; + + for (int xdraw = 0; xdraw < sizex; xdraw++) + { + uint32_t maskdata = m_sprites_mask[mask_offset + 0] << 24; + maskdata |= m_sprites_mask[mask_offset + 1] << 16; + maskdata |= m_sprites_mask[mask_offset + 2] << 8; + maskdata |= m_sprites_mask[mask_offset + 3] << 0; + + if (reverse) + { + mask_offset -= 4; + } + else if (!reverse) + { + mask_offset += 4; + } + + + mask_offset &= m_sprites_mask_mask; + + if (zoomybit) + { + if (!flipx) + { + if (!reverse) draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw, 1, 1); + else draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw, -1, -1); + } + else + { + if (!reverse) draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw, -1, 1); + else draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw, 1, -1); + + } + } + else skip_sprite_chunk(palette_offset, maskdata, reverse); + } +} + +void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect, uint32_t* spriteram) +{ + m_sprite_bitmap.fill(0x8000, cliprect); + + int endoflist = -1; + + //printf("frame\n"); + + for (int i = 0;i < 0x2000 / 4;i++) + { + if (spriteram[i] == 0x80000000) + { + endoflist = i; + break; + } + } + + if (endoflist != -1) + { + for (int i = 0; i < endoflist-2; i += 4) + { + //printf("sprite with %08x %08x %08x %08x\n", spriteram[i + 0], spriteram[i + 1], spriteram[i + 2], spriteram[i + 3]); + + int x = (spriteram[i + 0] & 0x000007ff) >> 0; + int y = (spriteram[i + 0] & 0x003ff800) >> 11; + int pal = (spriteram[i + 0] & 0x0fc00000) >> 22; + int pri = (spriteram[i + 0] & 0x80000000) >> 31; + + int unk0 = (spriteram[i + 0] & 0x70000000) >> 0; + + int sizex = (spriteram[i + 1] & 0x0000003f) >> 0; + int sizey = (spriteram[i + 1] & 0x00007fc0) >> 6; + int flipx = (spriteram[i + 1] & 0x00800000) >> 23; + int reverse = (spriteram[i + 1] & 0x80000000) >> 31; // more of a 'reverse entire drawing' flag than y-flip, but used for that purpose + int zoomx = (spriteram[i + 1] & 0x001f0000) >> 16; + int growx = (spriteram[i + 1] & 0x00200000) >> 21; + int zoomy = (spriteram[i + 1] & 0x1f000000) >> 24; + int growy = (spriteram[i + 1] & 0x20000000) >> 29; + int unk1 = (spriteram[i + 1] & 0x40408000) >> 0; + + if (unk0 || unk1) + { + // unk0 & 0x40000000 set during gameplay on kov2nl, why? more pri bits? + //popmessage("sprite rendering unused bits set unk0 %08x unk1 %08x\n", unk0, unk1); + } + + int mask_offset = (spriteram[i + 2]<<1); + int palette_offset = (spriteram[i + 3]); + + uint32_t zoomy_bits = m_sp_zoom[zoomy]; + uint32_t zoomx_bits = m_sp_zoom[zoomx]; + + if (x & 0x400) x -=0x800; + if (y & 0x400) y -=0x800; + + if (reverse) + mask_offset -= 2; + + mask_offset &= m_sprites_mask_mask; + palette_offset &= m_sprites_colour_mask; + + pal |= (pri << 6); // encode priority with the palette for manual mixing later + + int realy = y; + + int sourceline = 0; + for (int ydraw = 0; ydraw < sizey;sourceline++) + { + int zoomy_bit = (zoomy_bits >> (sourceline & 0x1f)) & 1; + + // store these for when we need to draw a line twice + uint32_t pre_palette_offset = palette_offset; + uint32_t pre_mask_offset = mask_offset; + + if (!growy) // skipping lines + { + draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, zoomy_bit, zoomx_bits, growx); + if (zoomy_bit) realy++; + + ydraw++; + } + else // doubling lines + { + draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, growx); + realy++; + + if (zoomy_bit) + { + palette_offset = pre_palette_offset; + mask_offset = pre_mask_offset; + } + else ydraw++; + } + } + } + + } +} + +void pgm2_state::copy_sprites_from_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri) +{ + pri <<= 12; + + const pen_t *paldata = m_sp_palette->pens(); + uint16_t* srcptr_bitmap; + uint32_t* dstptr_bitmap; + + for (int y = cliprect.min_y; y <= cliprect.max_y; y++) + { + srcptr_bitmap = &m_sprite_bitmap.pix16(y); + dstptr_bitmap = &bitmap.pix32(y); + + for (int x = cliprect.min_x; x <= cliprect.max_x; x++) + { + uint16_t pix = srcptr_bitmap[x]; + + if (pix != 0x8000) + { + if ((pix&0x1000) == pri) + dstptr_bitmap[x] = paldata[pix & 0xfff]; + } + } + + } +} + +uint32_t pgm2_state::screen_update_pgm2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + m_bg_tilemap->set_scrolly(0, (m_bgscroll[0x0/4] & 0xffff0000)>>16 ); + + for (int y = 0; y < 224; y++) + { + uint16_t linescroll = (y & 1) ? ((m_lineram[(y >> 1)] & 0xffff0000) >> 16) : (m_lineram[(y >> 1)] & 0x0000ffff); + m_bg_tilemap->set_scrollx((y + ((m_bgscroll[0x0 / 4] & 0xffff0000) >> 16)) & 0x3ff, ((m_bgscroll[0x0 / 4] & 0x0000ffff) >> 0) + linescroll); + } + + const pen_t *paldata = m_bg_palette->pens(); + + bitmap.fill(paldata[0], cliprect); // are there any places bg pen is showing so we know what it should be? + + draw_sprites(screen, cliprect, m_spritebufferram.get()); + + copy_sprites_from_bitmap(screen, bitmap, cliprect, 1); + + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + copy_sprites_from_bitmap(screen, bitmap, cliprect, 0); + + m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + return 0; +} + +WRITE_LINE_MEMBER(pgm2_state::screen_vblank_pgm2) +{ + // rising edge + if (state) + { + memcpy(m_spritebufferram.get(), m_sp_videoram, 0x2000); + } +} + +WRITE32_MEMBER(pgm2_state::fg_videoram_w) +{ + COMBINE_DATA(&m_fg_videoram[offset]); + m_fg_tilemap->mark_tile_dirty(offset); +} + +TILE_GET_INFO_MEMBER(pgm2_state::get_fg_tile_info) +{ + int tileno = (m_fg_videoram[tile_index] & 0x0003ffff) >> 0; + int colour = (m_fg_videoram[tile_index] & 0x007c0000) >> 18; // 5 bits + int flipxy = (m_fg_videoram[tile_index] & 0x01800000) >> 23; + + SET_TILE_INFO_MEMBER(0, tileno, colour, TILE_FLIPXY(flipxy)); +} + +WRITE32_MEMBER(pgm2_state::bg_videoram_w) +{ + COMBINE_DATA(&m_bg_videoram[offset]); + m_bg_tilemap->mark_tile_dirty(offset); +} + +TILE_GET_INFO_MEMBER(pgm2_state::get_bg_tile_info) +{ + int tileno = (m_bg_videoram[tile_index] & 0x0003ffff) >> 0; + int colour = (m_bg_videoram[tile_index] & 0x003c0000) >> 18; // 4 bits + int flipxy = (m_bg_videoram[tile_index] & 0x01800000) >> 23; + + SET_TILE_INFO_MEMBER(0, tileno, colour, TILE_FLIPXY(flipxy)); +} + +void pgm2_state::video_start() +{ + m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode2, tilemap_get_info_delegate(FUNC(pgm2_state::get_fg_tile_info), this), TILEMAP_SCAN_ROWS, 8, 8, 96, 48); // 0x4800 bytes + m_fg_tilemap->set_transparent_pen(0); + + m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode3, tilemap_get_info_delegate(FUNC(pgm2_state::get_bg_tile_info), this), TILEMAP_SCAN_ROWS, 32, 32, 64, 32); // 0x2000 bytes + m_bg_tilemap->set_transparent_pen(0); + m_bg_tilemap->set_scroll_rows(32 * 32); + + m_spritebufferram = make_unique_clear<uint32_t[]>(0x2000 / 4); + + m_screen->register_screen_bitmap(m_sprite_bitmap); + + save_pointer(NAME(m_spritebufferram.get()), 0x2000 / 4); + + m_sprites_mask_mask = memregion("sprites_mask")->bytes() - 1; + m_sprites_colour_mask = memregion("sprites_colour")->bytes() - 1; +} + diff --git a/src/mame/video/ssozumo.cpp b/src/mame/video/ssozumo.cpp index ab391b6b121..06ba66b7a8d 100644 --- a/src/mame/video/ssozumo.cpp +++ b/src/mame/video/ssozumo.cpp @@ -108,6 +108,8 @@ WRITE8_MEMBER(ssozumo_state::scroll_w) WRITE8_MEMBER(ssozumo_state::flipscreen_w) { flip_screen_set(data & 0x80); + m_color_bank = data & 3; + m_fg_tilemap->mark_all_dirty(); } TILE_GET_INFO_MEMBER(ssozumo_state::get_bg_tile_info) @@ -122,9 +124,8 @@ TILE_GET_INFO_MEMBER(ssozumo_state::get_bg_tile_info) TILE_GET_INFO_MEMBER(ssozumo_state::get_fg_tile_info) { int code = m_videoram2[tile_index] + 256 * (m_colorram2[tile_index] & 0x07); - int color = (m_colorram2[tile_index] & 0x30) >> 4; - SET_TILE_INFO_MEMBER(0, code, color, 0); + SET_TILE_INFO_MEMBER(0, code, m_color_bank, 0); } void ssozumo_state::video_start() diff --git a/src/mame/video/tmc600.cpp b/src/mame/video/tmc600.cpp index ac1e739476e..98d57b6eec9 100644 --- a/src/mame/video/tmc600.cpp +++ b/src/mame/video/tmc600.cpp @@ -5,50 +5,24 @@ WRITE8_MEMBER( tmc600_state::vismac_register_w ) { - m_vismac_reg_latch = data; + m_vismac_reg_latch = data >> 4; } WRITE8_MEMBER( tmc600_state::vismac_data_w ) { uint16_t ma = m_maincpu->get_memory_address(); - switch (m_vismac_reg_latch) + switch (m_vismac_reg_latch & 0x07) { - case 0x20: - // character color latch - m_vismac_color_latch = data; - break; - - case 0x30: - // background color latch - m_vismac_bkg_latch = data & 0x07; - - m_vis->out3_w(space, ma, data); - break; - - case 0x40: - m_vis->out4_w(space, ma, data); - break; - - case 0x50: - m_vis->out5_w(space, ma, data); - break; - - case 0x60: - m_vis->out6_w(space, ma, data); - break; - - case 0x70: - m_vis->out7_w(space, ma, data); - break; + case 2: m_vismac_color_latch = data & 0x0f; break; + case 3: m_vis->out3_w(space, ma, data); break; + case 4: m_vis->out4_w(space, ma, data); break; + case 5: m_vis->out5_w(space, ma, data); break; + case 6: m_vis->out6_w(space, ma, data); break; + case 7: m_vis->out7_w(space, ma, data); break; } } -TIMER_DEVICE_CALLBACK_MEMBER(tmc600_state::blink_tick) -{ - m_blink = !m_blink; -} - uint8_t tmc600_state::get_color(uint16_t pma) { uint16_t pageaddr = pma & TMC600_PAGE_RAM_MASK; @@ -56,7 +30,7 @@ uint8_t tmc600_state::get_color(uint16_t pma) if (BIT(color, 3) && m_blink) { - color = m_vismac_bkg_latch; + color ^= 0x07; } return color; @@ -93,15 +67,34 @@ CDP1869_PCB_READ_MEMBER( tmc600_state::tmc600_pcb_r ) return BIT(color, 0); } +WRITE_LINE_MEMBER( tmc600_state::prd_w ) +{ + if (!state) { + m_frame++; + + switch (m_frame) { + case 8: + m_maincpu->int_w(CLEAR_LINE); + break; + + case 16: + m_maincpu->int_w(m_rtc_int); + m_blink = !m_blink; + m_frame = 0; + break; + } + } +} + void tmc600_state::video_start() { // allocate memory m_color_ram.allocate(TMC600_PAGE_RAM_SIZE); - // register for state saving + // state saving save_item(NAME(m_vismac_reg_latch)); save_item(NAME(m_vismac_color_latch)); - save_item(NAME(m_vismac_bkg_latch)); + save_item(NAME(m_frame)); save_item(NAME(m_blink)); } @@ -125,7 +118,6 @@ GFXDECODE_END MACHINE_CONFIG_START( tmc600_video ) // video hardware MCFG_CDP1869_SCREEN_PAL_ADD(CDP1869_TAG, SCREEN_TAG, cdp1869_device::DOT_CLK_PAL) - MCFG_TIMER_DRIVER_ADD_PERIODIC("blink", tmc600_state, blink_tick, attotime::from_hz(2)) MCFG_GFXDECODE_ADD("gfxdecode", CDP1869_TAG":palette", tmc600) @@ -136,6 +128,7 @@ MACHINE_CONFIG_START( tmc600_video ) MCFG_CDP1869_CHAR_PCB_READ_OWNER(tmc600_state, tmc600_pcb_r) MCFG_CDP1869_CHAR_RAM_READ_OWNER(tmc600_state, tmc600_char_ram_r) MCFG_CDP1869_PAL_NTSC_CALLBACK(VCC) + MCFG_CDP1869_PRD_CALLBACK(WRITELINE(tmc600_state, prd_w)) MCFG_VIDEO_SET_SCREEN(SCREEN_TAG) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) MACHINE_CONFIG_END diff --git a/src/mame/video/twincobr.cpp b/src/mame/video/twincobr.cpp index beff38e63e9..dafed1b7c30 100644 --- a/src/mame/video/twincobr.cpp +++ b/src/mame/video/twincobr.cpp @@ -122,14 +122,24 @@ VIDEO_START_MEMBER(twincobr_state,toaplan0) Video I/O interface ***************************************************************************/ -void twincobr_state::twincobr_display(int enable) +WRITE_LINE_MEMBER(twincobr_state::display_on_w) { - m_display_on = enable; + m_display_on = state; } -void twincobr_state::twincobr_flipscreen(int flip) +WRITE_LINE_MEMBER(twincobr_state::flipscreen_w) { - machine().tilemap().set_flip_all((flip ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0)); + machine().tilemap().set_flip_all((state ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0)); +} + +WRITE_LINE_MEMBER(twincobr_state::bg_ram_bank_w) +{ + m_bg_ram_bank = state ? 0x1000 : 0x0000; +} + +WRITE_LINE_MEMBER(twincobr_state::fg_rom_bank_w) +{ + m_fg_rom_bank = state ? 0x1000 : 0x0000; } diff --git a/src/mame/video/wecleman.cpp b/src/mame/video/wecleman.cpp index 3e74180e665..0eec8fcfb88 100644 --- a/src/mame/video/wecleman.cpp +++ b/src/mame/video/wecleman.cpp @@ -23,21 +23,6 @@ #define SPRITE_FLIPY 0x02 #define NUM_SPRITES 256 -struct sprite -{ - uint8_t *pen_data; /* points to top left corner of tile data */ - int line_offset; - - const pen_t *pal_data; - rgb_t pal_base; - - int x_offset, y_offset; - int tile_width, tile_height; - int total_width, total_height; /* in screen coordinates */ - int x, y; - int shadow_mode, flags; -}; - /*************************************************************************** @@ -82,12 +67,12 @@ void wecleman_state::get_sprite_info() uint16_t *source = m_spriteram; - struct sprite *sprite = m_sprite_list; - struct sprite *finish = m_sprite_list + NUM_SPRITES; + sprite_t *sprite = m_sprite_list.get(); + sprite_t *const finish = sprite + NUM_SPRITES; int bank, code, gfx, zoom; - for (m_spr_count=0; sprite<finish; source+=0x10/2, sprite++) + for (m_spr_count = 0; sprite < finish; source += 0x10/2, sprite++) { if (source[0x00/2] == 0xffff) break; @@ -170,7 +155,7 @@ void wecleman_state::sortsprite(int *idx_array, int *key_array, int size) // draws a 8bpp palette sprites on a 16bpp direct RGB target (sub-par implementation) template<class _BitmapClass> -void wecleman_state::do_blit_zoom32(_BitmapClass &bitmap, const rectangle &cliprect, struct sprite *sprite) +void wecleman_state::do_blit_zoom32(_BitmapClass &bitmap, const rectangle &cliprect, const sprite_t &sprite) { #define PRECISION_X 20 #define PRECISION_Y 20 @@ -181,10 +166,10 @@ void wecleman_state::do_blit_zoom32(_BitmapClass &bitmap, const rectangle &clipr int x1, x2, y1, y2, dx, dy, sx, sy; int xcount0=0, ycount0=0; - if (sprite->flags & SPRITE_FLIPX) + if (sprite.flags & SPRITE_FLIPX) { - x2 = sprite->x; - x1 = x2 + sprite->total_width; + x2 = sprite.x; + x1 = x2 + sprite.total_width; dx = -1; if (x2 < cliprect.min_x) x2 = cliprect.min_x; if (x1 > cliprect.max_x ) @@ -197,8 +182,8 @@ void wecleman_state::do_blit_zoom32(_BitmapClass &bitmap, const rectangle &clipr } else { - x1 = sprite->x; - x2 = x1 + sprite->total_width; + x1 = sprite.x; + x2 = x1 + sprite.total_width; dx = 1; if (x1 < cliprect.min_x ) { @@ -209,10 +194,10 @@ void wecleman_state::do_blit_zoom32(_BitmapClass &bitmap, const rectangle &clipr if (x1 >= x2) return; } - if (sprite->flags & SPRITE_FLIPY) + if (sprite.flags & SPRITE_FLIPY) { - y2 = sprite->y; - y1 = y2 + sprite->total_height; + y2 = sprite.y; + y1 = y2 + sprite.total_height; dy = -1; if (y2 < cliprect.min_y ) y2 = cliprect.min_y; if (y1 > cliprect.max_y ) @@ -225,8 +210,8 @@ void wecleman_state::do_blit_zoom32(_BitmapClass &bitmap, const rectangle &clipr } else { - y1 = sprite->y; - y2 = y1 + sprite->total_height; + y1 = sprite.y; + y2 = y1 + sprite.total_height; dy = 1; if (y1 < cliprect.min_y ) { @@ -238,14 +223,14 @@ void wecleman_state::do_blit_zoom32(_BitmapClass &bitmap, const rectangle &clipr } // calculate entry point decimals - src_fdy = (sprite->tile_height<<PRECISION_Y) / sprite->total_height; + src_fdy = (sprite.tile_height<<PRECISION_Y) / sprite.total_height; src_f0y = src_fdy * ycount0 + FPY_HALF; - src_fdx = (sprite->tile_width<<PRECISION_X) / sprite->total_width; + src_fdx = (sprite.tile_width<<PRECISION_X) / sprite.total_width; src_f0x = src_fdx * xcount0; // pre-loop assignments and adjustments - pal_base = sprite->pal_data; + pal_base = sprite.pal_data; if (x1 > cliprect.min_x) { @@ -255,13 +240,13 @@ void wecleman_state::do_blit_zoom32(_BitmapClass &bitmap, const rectangle &clipr for (sy = y1; sy != y2; sy += dy) { - uint8_t *row_base = sprite->pen_data + (src_f0y>>PRECISION_Y) * sprite->line_offset; + uint8_t *row_base = sprite.pen_data + (src_f0y>>PRECISION_Y) * sprite.line_offset; src_fpx = src_f0x; typename _BitmapClass::pixel_t *dst_ptr = &bitmap.pix(sy); if (bitmap.format() == BITMAP_FORMAT_RGB32) // Wec Le Mans { - if (!sprite->shadow_mode) + if (!sprite.shadow_mode) { for (sx = x1; sx != x2; sx += dx) { @@ -291,9 +276,9 @@ void wecleman_state::do_blit_zoom32(_BitmapClass &bitmap, const rectangle &clipr } else // Hot Chase { - pen_t base = sprite->pal_base; + pen_t base = sprite.pal_base; - if (!sprite->shadow_mode) + if (!sprite.shadow_mode) { for (sx = x1; sx != x2; sx += dx) { @@ -338,11 +323,11 @@ void wecleman_state::sprite_draw(_BitmapClass &bitmap, const rectangle &cliprect { sortsprite(m_spr_idx_list, m_spr_pri_list, m_spr_count); - for (i=0; i<m_spr_count; i++) do_blit_zoom32(bitmap, cliprect, m_spr_ptr_list[m_spr_idx_list[i]]); + for (i=0; i<m_spr_count; i++) do_blit_zoom32(bitmap, cliprect, *m_spr_ptr_list[m_spr_idx_list[i]]); } else // Hot Chase { - for (i=0; i<m_spr_count; i++) do_blit_zoom32(bitmap, cliprect, m_spr_ptr_list[i]); + for (i=0; i<m_spr_count; i++) do_blit_zoom32(bitmap, cliprect, *m_spr_ptr_list[i]); } } @@ -904,11 +889,11 @@ VIDEO_START_MEMBER(wecleman_state,wecleman) m_cloud_visible = 0; m_black_pen = m_palette->black_pen(); - m_rgb_half = (uint16_t*)(buffer + 0x00000); - m_t32x32pm = (int*)(buffer + 0x10020); - m_spr_ptr_list = (struct sprite **)(buffer + 0x12000); - m_spr_idx_list = (int *)(buffer + 0x12400); - m_spr_pri_list = (int *)(buffer + 0x12800); + m_rgb_half = (uint16_t*)(buffer + 0x00000); + m_t32x32pm = (int*)(buffer + 0x10020); + m_spr_ptr_list = (sprite_t **)(buffer + 0x12000); + m_spr_idx_list = (int *)(buffer + 0x12400); + m_spr_pri_list = (int *)(buffer + 0x12800); for (i=0; i<0x8000; i++) { @@ -924,7 +909,7 @@ VIDEO_START_MEMBER(wecleman_state,wecleman) } } - m_sprite_list = auto_alloc_array_clear(machine(), struct sprite, NUM_SPRITES); + m_sprite_list = std::make_unique<sprite_t []>(NUM_SPRITES); m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(wecleman_state::wecleman_get_bg_tile_info),this), TILEMAP_SCAN_ROWS, @@ -1001,9 +986,9 @@ VIDEO_START_MEMBER(wecleman_state,hotchase) m_spr_offsy = 0; m_black_pen = m_palette->black_pen(); - m_spr_ptr_list = (struct sprite **)buffer; + m_spr_ptr_list = (sprite_t **)buffer; - m_sprite_list = auto_alloc_array_clear(machine(), struct sprite, NUM_SPRITES); + m_sprite_list = std::make_unique<sprite_t []>(NUM_SPRITES); } diff --git a/src/mame/video/wgp.cpp b/src/mame/video/wgp.cpp index fd31d78b878..d0e162fc463 100644 --- a/src/mame/video/wgp.cpp +++ b/src/mame/video/wgp.cpp @@ -7,7 +7,7 @@ /*******************************************************************/ -inline void wgp_state::common_get_piv_tile_info( tile_data &tileinfo, int tile_index, int num ) +inline void wgp_state::common_get_piv_tile_info(tile_data &tileinfo, int tile_index, int num) { uint16_t tilenum = m_pivram[tile_index + num * 0x1000]; /* 3 blocks of $2000 */ uint16_t attr = m_pivram[tile_index + num * 0x1000 + 0x8000]; /* 3 blocks of $2000 */ @@ -34,7 +34,7 @@ TILE_GET_INFO_MEMBER(wgp_state::get_piv2_tile_info) } -void wgp_state::wgp_core_vh_start( int piv_xoffs, int piv_yoffs ) +void wgp_state::core_vh_start(int piv_xoffs, int piv_yoffs) { m_piv_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(wgp_state::get_piv0_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 64, 64); m_piv_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(wgp_state::get_piv1_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 64, 64); @@ -67,12 +67,12 @@ void wgp_state::wgp_core_vh_start( int piv_xoffs, int piv_yoffs ) void wgp_state::video_start() { - wgp_core_vh_start(32, 16); + core_vh_start(32, 16); } VIDEO_START_MEMBER(wgp_state,wgp2) { - wgp_core_vh_start(32, 16); + core_vh_start(32, 16); } @@ -120,12 +120,7 @@ custom chip capable of four rather than three tilemaps.) *******************************************************************/ -READ16_MEMBER(wgp_state::wgp_pivram_word_r) -{ - return m_pivram[offset]; -} - -WRITE16_MEMBER(wgp_state::wgp_pivram_word_w) +WRITE16_MEMBER(wgp_state::pivram_word_w) { COMBINE_DATA(&m_pivram[offset]); @@ -143,12 +138,7 @@ WRITE16_MEMBER(wgp_state::wgp_pivram_word_w) } } -READ16_MEMBER(wgp_state::wgp_piv_ctrl_word_r) -{ - return m_piv_ctrlram[offset]; -} - -WRITE16_MEMBER(wgp_state::wgp_piv_ctrl_word_w) +WRITE16_MEMBER(wgp_state::piv_ctrl_word_w) { uint16_t a, b; @@ -339,7 +329,7 @@ static const uint8_t ylookup[16] = 2, 2, 3, 3, 2, 2, 3, 3 }; -void wgp_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int y_offs ) +void wgp_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int y_offs) { uint16_t *spriteram = m_spriteram; int offs, i, j, k; @@ -478,8 +468,8 @@ void wgp_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const CUSTOM DRAW *********************************************************/ -static inline void bryan2_drawscanline( bitmap_ind16 &bitmap, int x, int y, int length, - const uint16_t *src, int transparent, uint32_t orient, bitmap_ind8 &priority, int pri ) +static inline void bryan2_drawscanline(bitmap_ind16 &bitmap, int x, int y, int length, + const uint16_t *src, int transparent, uint32_t orient, bitmap_ind8 &priority, int pri) { uint16_t *dsti = &bitmap.pix16(y, x); uint8_t *dstp = &priority.pix8(y, x); @@ -510,7 +500,7 @@ static inline void bryan2_drawscanline( bitmap_ind16 &bitmap, int x, int y, int -void wgp_state::wgp_piv_layer_draw( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int flags, uint32_t priority ) +void wgp_state::piv_layer_draw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int layer, int flags, uint32_t priority) { bitmap_ind16 &srcbitmap = m_piv_tilemap[layer]->pixmap(); bitmap_ind8 &flagsbitmap = m_piv_tilemap[layer]->flagsmap(); @@ -625,7 +615,7 @@ void wgp_state::wgp_piv_layer_draw( screen_device &screen, bitmap_ind16 &bitmap, SCREEN REFRESH **************************************************************/ -uint32_t wgp_state::screen_update_wgp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +uint32_t wgp_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { int i; uint8_t layer[3]; @@ -681,21 +671,21 @@ uint32_t wgp_state::screen_update_wgp(screen_device &screen, bitmap_ind16 &bitma #ifdef MAME_DEBUG if (m_dislayer[layer[0]] == 0) #endif - wgp_piv_layer_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 1); + piv_layer_draw(screen, bitmap, cliprect, layer[0], TILEMAP_DRAW_OPAQUE, 1); #ifdef MAME_DEBUG if (m_dislayer[layer[1]] == 0) #endif - wgp_piv_layer_draw(screen, bitmap, cliprect, layer[1], 0, 2); + piv_layer_draw(screen, bitmap, cliprect, layer[1], 0, 2); #ifdef MAME_DEBUG if (m_dislayer[layer[2]] == 0) #endif - wgp_piv_layer_draw(screen, bitmap, cliprect, layer[2], 0, 4); + piv_layer_draw(screen, bitmap, cliprect, layer[2], 0, 4); draw_sprites(screen, bitmap, cliprect, 16); -/* ... then here we should apply rotation from wgp_sate_ctrl[] to the bitmap before we draw the TC0100SCN layers on it */ +/* ... then here we should apply rotation from m_rotate_ctrl[] to the bitmap before we draw the TC0100SCN layers on it */ layer[0] = m_tc0100scn->bottomlayer(); layer[1] = layer[0] ^ 1; layer[2] = 2; @@ -711,7 +701,7 @@ uint32_t wgp_state::screen_update_wgp(screen_device &screen, bitmap_ind16 &bitma #if 0 { char buf[80]; - sprintf(buf,"wgp_piv_ctrl_reg: %04x y zoom: %04x %04x %04x",m_piv_ctrl_reg, + sprintf(buf,"piv_ctrl_reg: %04x y zoom: %04x %04x %04x",m_piv_ctrl_reg, m_piv_zoom[0],m_piv_zoom[1],m_piv_zoom[2]); popmessage(buf); } @@ -725,7 +715,7 @@ uint32_t wgp_state::screen_update_wgp(screen_device &screen, bitmap_ind16 &bitma for (i = 0; i < 8; i += 1) { - sprintf (buf, "%02x: %04x", i, wgp_rotate_ctrl[i]); + sprintf (buf, "%02x: %04x", i, rotate_ctrl[i]); ui_draw_text (buf, 0, i*8); } } diff --git a/src/osd/eigccppc.h b/src/osd/eigccppc.h index 7c322299e3c..7f932eb1e88 100644 --- a/src/osd/eigccppc.h +++ b/src/osd/eigccppc.h @@ -275,10 +275,9 @@ _count_leading_ones(uint32_t value) uint32_t result; __asm__ ( - " not %[result], %[value] \n" " cntlzw %[result], %[result] \n" : [result] "=r" (result) /* result can be in any register */ - : [value] "r" (value) /* 'value' can be in any register */ + : [value] "r" (~value) /* 'value' can be in any register */ ); return result; diff --git a/src/osd/eigccx86.h b/src/osd/eigccx86.h index 363daba5f5f..b3831d21524 100644 --- a/src/osd/eigccx86.h +++ b/src/osd/eigccx86.h @@ -472,15 +472,14 @@ _count_leading_zeros(uint32_t value) { uint32_t result; __asm__ ( - " bsrl %[value], %[result] ;" - " jnz 1f ;" - " movl $63, %[result] ;" - "1: xorl $31, %[result] ;" - : [result] "=r" (result) // result can be in any register - : [value] "rm" (value) // 'value' can be register or memory - : "cc" // clobbers condition codes + " bsrl %[value], %[result] ;" + " cmovzl %[bias], %[result] ;" + : [result] "=&r" (result) // result can be in any register + : [value] "rm" (value) // 'value' can be register or memory + , [bias] "rm" (~uint32_t(0)) // 'bias' can be register or memory + : "cc" // clobbers condition codes ); - return result; + return 31U - result; } @@ -495,17 +494,14 @@ _count_leading_ones(uint32_t value) { uint32_t result; __asm__ ( - " movl %[value], %[result] ;" - " notl %[result] ;" - " bsrl %[result], %[result] ;" - " jnz 1f ;" - " movl $63, %[result] ;" - "1: xorl $31, %[result] ;" - : [result] "=r" (result) // result can be in any register - : [value] "rmi" (value) // 'value' can be register, memory or immediate - : "cc" // clobbers condition codes + " bsrl %[value], %[result] ;" + " cmovzl %[bias], %[result] ;" + : [result] "=&r" (result) // result can be in any register + : [value] "rm" (~value) // 'value' can be register or memory + , [bias] "rm" (~uint32_t(0)) // 'bias' can be register or memory + : "cc" // clobbers condition codes ); - return result; + return 31U - result; } #endif // MAME_OSD_EIGCCX86_H diff --git a/src/osd/eivc.h b/src/osd/eivc.h index de4ea809a28..3fa34f51b3c 100644 --- a/src/osd/eivc.h +++ b/src/osd/eivc.h @@ -31,7 +31,7 @@ inline uint8_t _count_leading_zeros(uint32_t value) { unsigned long index; - return _BitScanReverse(&index, value) ? (index ^ 31) : 32; + return _BitScanReverse(&index, value) ? (31U - index) : 32U; } #endif @@ -46,7 +46,7 @@ inline uint8_t _count_leading_zeros(uint32_t value) inline uint8_t _count_leading_ones(uint32_t value) { unsigned long index; - return _BitScanReverse(&index, ~value) ? (index ^ 31) : 32; + return _BitScanReverse(&index, ~value) ? (31U - index) : 32U; } #endif diff --git a/src/osd/modules/debugger/debugimgui.cpp b/src/osd/modules/debugger/debugimgui.cpp index 293ac0229df..11e19b261eb 100644 --- a/src/osd/modules/debugger/debugimgui.cpp +++ b/src/osd/modules/debugger/debugimgui.cpp @@ -184,7 +184,6 @@ private: const char* font_name; float font_size; ImVec2 m_text_size; // size of character (assumes monospaced font is in use) - ImguiFontHandle m_font; uint8_t m_key_char; bool m_hide; int m_win_count; // number of active windows, does not decrease, used to ID individual windows @@ -677,7 +676,7 @@ void debug_imgui::draw_view(debug_area* view_ptr, bool exp_change) void debug_imgui::draw_bpoints(debug_area* view_ptr, bool* opened) { - ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiSetCond_Once); + ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiCond_Once); if(ImGui::Begin(view_ptr->title.c_str(),opened)) { view_ptr->is_collapsed = false; @@ -723,7 +722,7 @@ void debug_imgui::add_wpoints(int id) void debug_imgui::draw_log(debug_area* view_ptr, bool* opened) { - ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiSetCond_Once); + ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiCond_Once); if(ImGui::Begin(view_ptr->title.c_str(),opened)) { view_ptr->is_collapsed = false; @@ -757,7 +756,7 @@ void debug_imgui::draw_disasm(debug_area* view_ptr, bool* opened) { const debug_view_source* src; - ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiSetCond_Once); + ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiCond_Once); if(ImGui::Begin(view_ptr->title.c_str(),opened,ImGuiWindowFlags_MenuBar)) { int idx; @@ -844,7 +843,7 @@ void debug_imgui::draw_memory(debug_area* view_ptr, bool* opened) { const debug_view_source* src; - ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiSetCond_Once); + ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiCond_Once); if(ImGui::Begin(view_ptr->title.c_str(),opened,ImGuiWindowFlags_MenuBar)) { int idx; @@ -1241,7 +1240,7 @@ void debug_imgui::draw_console() rgb_t base(0xe6, 0xff, 0xff, 0xff); ImGuiWindowFlags flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; - ImGui::SetNextWindowSize(ImVec2(view_main_regs->width + view_main_disasm->width,view_main_disasm->height + view_main_console->height + ImGui::GetTextLineHeight()*3),ImGuiSetCond_Once); + ImGui::SetNextWindowSize(ImVec2(view_main_regs->width + view_main_disasm->width,view_main_disasm->height + view_main_console->height + ImGui::GetTextLineHeight()*3),ImGuiCond_Once); if(ImGui::Begin(view_main_console->title.c_str(), nullptr,flags)) { std::string str; @@ -1383,7 +1382,6 @@ void debug_imgui::update() ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabHovered,ImVec4(0.7f,0.7f,0.7f,0.8f)); ImGui::PushStyleColor(ImGuiCol_ScrollbarGrabActive,ImVec4(0.9f,0.9f,0.9f,0.8f)); ImGui::PushStyleColor(ImGuiCol_Border,ImVec4(0.7f,0.7f,0.7f,0.8f)); - ImGui::PushStyleColor(ImGuiCol_ComboBg,ImVec4(0.4f,0.4f,0.4f,0.9f)); m_text_size = ImGui::CalcTextSize("A"); // hopefully you're using a monospaced font... draw_console(); // We'll always have a console window @@ -1425,7 +1423,7 @@ void debug_imgui::update() global_free(to_delete); } - ImGui::PopStyleColor(13); + ImGui::PopStyleColor(12); } void debug_imgui::init_debugger(running_machine &machine) @@ -1478,8 +1476,7 @@ void debug_imgui::init_debugger(running_machine &machine) io.Fonts->AddFontDefault(); else io.Fonts->AddFontFromFileTTF(font_name,font_size); // for now, font name must be a path to a TTF file - m_font = imguiCreate(); - imguiSetFont(m_font); + imguiCreate(); } void debug_imgui::wait_for_debugger(device_t &device, bool firststop) diff --git a/src/osd/modules/file/winfile.cpp b/src/osd/modules/file/winfile.cpp index 745b9112b7b..66281d08b4a 100644 --- a/src/osd/modules/file/winfile.cpp +++ b/src/osd/modules/file/winfile.cpp @@ -185,6 +185,7 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags, { disposition = (!is_path_to_physical_drive(path.c_str()) && (openflags & OPEN_FLAG_CREATE)) ? CREATE_ALWAYS : OPEN_EXISTING; access = (openflags & OPEN_FLAG_READ) ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_WRITE; + if (is_path_to_physical_drive(path.c_str())) access |= GENERIC_READ; sharemode = FILE_SHARE_READ; } else if (openflags & OPEN_FLAG_READ) @@ -230,7 +231,25 @@ osd_file::error osd_file::open(std::string const &orig_path, uint32_t openflags, // get the file size DWORD upper, lower; - lower = GetFileSize(h, &upper); + if (is_path_to_physical_drive(path.c_str())) + { + GET_LENGTH_INFORMATION gli; + DWORD ret; + if (!DeviceIoControl(h, IOCTL_DISK_GET_LENGTH_INFO, nullptr, 0, &gli, sizeof(gli), &ret, nullptr)) + { + upper = 0; + lower = INVALID_FILE_SIZE; + } + else + { + lower = gli.Length.LowPart; + upper = gli.Length.HighPart; + } + } + else + { + lower = GetFileSize(h, &upper); + } if (INVALID_FILE_SIZE == lower) { DWORD const err = GetLastError(); diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp index 93e14313de8..a3cbed7c107 100644 --- a/src/osd/modules/input/input_sdl.cpp +++ b/src/osd/modules/input/input_sdl.cpp @@ -250,7 +250,8 @@ public: { machine().ui_input().push_mouse_down_event(window->target(), cx, cy); - if (click - last_click < double_click_speed + // avoid overflow with std::chrono::time_point::min() by adding rather than subtracting + if (click < last_click + double_click_speed && (cx >= last_x - 4 && cx <= last_x + 4) && (cy >= last_y - 4 && cy <= last_y + 4)) { diff --git a/src/osd/modules/render/bgfx/chainentry.cpp b/src/osd/modules/render/bgfx/chainentry.cpp index a53ed759940..4e27cb8c00b 100644 --- a/src/osd/modules/render/bgfx/chainentry.cpp +++ b/src/osd/modules/render/bgfx/chainentry.cpp @@ -12,7 +12,7 @@ #include "emu.h" #include <bgfx/bgfx.h> -#include <bx/fpumath.h> +#include <bx/math.h> #include "chainentry.h" @@ -57,8 +57,6 @@ bgfx_chain_entry::~bgfx_chain_entry() void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager& textures, uint16_t screen_count, uint16_t screen_width, uint16_t screen_height, float screen_scale_x, float screen_scale_y, float screen_offset_x, float screen_offset_y, uint32_t rotation_type, bool swap_xy, uint64_t blend, int32_t screen) { - bgfx::setViewSeq(view, true); - if (!setup_view(view, screen_width, screen_height, screen)) { return; @@ -71,7 +69,7 @@ void bgfx_chain_entry::submit(int view, render_primitive* prim, texture_manager& bgfx::TransientVertexBuffer buffer; put_screen_buffer(prim, &buffer); - bgfx::setVertexBuffer(&buffer); + bgfx::setVertexBuffer(0,&buffer); setup_auto_uniforms(prim, textures, screen_count, screen_width, screen_height, screen_scale_x, screen_scale_y, screen_offset_x, screen_offset_y, rotation_type, swap_xy, screen); @@ -260,8 +258,10 @@ bool bgfx_chain_entry::setup_view(int view, uint16_t screen_width, uint16_t scre bgfx::setViewFrameBuffer(view, handle); bgfx::setViewRect(view, 0, 0, width, height); + const bgfx::Caps* caps = bgfx::getCaps(); + float projMat[16]; - bx::mtxOrtho(projMat, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); + bx::mtxOrtho(projMat, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth); bgfx::setViewTransform(view, nullptr, projMat); m_clear->bind(view); diff --git a/src/osd/modules/render/bgfx/chainmanager.cpp b/src/osd/modules/render/bgfx/chainmanager.cpp index f3b12dfa125..393344016e8 100644 --- a/src/osd/modules/render/bgfx/chainmanager.cpp +++ b/src/osd/modules/render/bgfx/chainmanager.cpp @@ -10,7 +10,7 @@ //============================================================ #include <bx/readerwriter.h> -#include <bx/crtimpl.h> +#include <bx/file.h> #include "emu.h" #include "../frontend/mame/ui/slider.h" @@ -143,7 +143,7 @@ bgfx_chain* chain_manager::load_chain(std::string name, uint32_t screen_index) osd_subst_env(path, util::string_format("%s" PATH_SEPARATOR "chains" PATH_SEPARATOR, m_options.bgfx_path())); path += name; - bx::CrtFileReader reader; + bx::FileReader reader; if (!bx::open(&reader, path.c_str())) { printf("Unable to open chain file %s, falling back to no post processing\n", path.c_str()); diff --git a/src/osd/modules/render/bgfx/effect.cpp b/src/osd/modules/render/bgfx/effect.cpp index 7e0750a73a2..fb3d7d933ba 100644 --- a/src/osd/modules/render/bgfx/effect.cpp +++ b/src/osd/modules/render/bgfx/effect.cpp @@ -36,7 +36,7 @@ bgfx_effect::~bgfx_effect() delete uniform.second; } m_uniforms.clear(); - bgfx::destroyProgram(m_program_handle); + bgfx::destroy(m_program_handle); } void bgfx_effect::submit(int view, uint64_t blend) diff --git a/src/osd/modules/render/bgfx/effectmanager.cpp b/src/osd/modules/render/bgfx/effectmanager.cpp index 8627650aae2..6462ae75f72 100644 --- a/src/osd/modules/render/bgfx/effectmanager.cpp +++ b/src/osd/modules/render/bgfx/effectmanager.cpp @@ -13,7 +13,7 @@ #include <rapidjson/error/en.h> #include <bx/readerwriter.h> -#include <bx/crtimpl.h> +#include <bx/file.h> #include "emu.h" @@ -55,7 +55,7 @@ bgfx_effect* effect_manager::load_effect(std::string name) osd_subst_env(path, util::string_format("%s" PATH_SEPARATOR "effects" PATH_SEPARATOR, m_options.bgfx_path())); path += full_name; - bx::CrtFileReader reader; + bx::FileReader reader; if (!bx::open(&reader, path.c_str())) { printf("Unable to open effect file %s\n", path.c_str()); diff --git a/src/osd/modules/render/bgfx/shadermanager.cpp b/src/osd/modules/render/bgfx/shadermanager.cpp index c4a92e1ff32..7583b58dec5 100644 --- a/src/osd/modules/render/bgfx/shadermanager.cpp +++ b/src/osd/modules/render/bgfx/shadermanager.cpp @@ -9,9 +9,9 @@ // //============================================================ -#include <bx/fpumath.h> +#include <bx/math.h> #include <bx/readerwriter.h> -#include <bx/crtimpl.h> +#include <bx/file.h> #include "emu.h" @@ -23,7 +23,7 @@ shader_manager::~shader_manager() { for (std::pair<std::string, bgfx::ShaderHandle> shader : m_shaders) { - bgfx::destroyShader(shader.second); + bgfx::destroy(shader.second); } m_shaders.clear(); } @@ -96,7 +96,7 @@ bgfx::ShaderHandle shader_manager::load_shader(std::string name) const bgfx::Memory* shader_manager::load_mem(std::string name) { - bx::CrtFileReader reader; + bx::FileReader reader; if (bx::open(&reader, name.c_str())) { uint32_t size(bx::getSize(&reader)); diff --git a/src/osd/modules/render/bgfx/target.cpp b/src/osd/modules/render/bgfx/target.cpp index 74b284dfb1d..a5feee73b2e 100644 --- a/src/osd/modules/render/bgfx/target.cpp +++ b/src/osd/modules/render/bgfx/target.cpp @@ -80,15 +80,15 @@ bgfx_target::~bgfx_target() { for (int page = 0; page < m_page_count; page++) { - bgfx::destroyFrameBuffer(m_targets[page]); - bgfx::destroyTexture(m_textures[page]); + bgfx::destroy(m_targets[page]); + bgfx::destroy(m_textures[page]); } delete [] m_textures; delete [] m_targets; } else { - bgfx::destroyFrameBuffer(m_targets[0]); + bgfx::destroy(m_targets[0]); delete [] m_targets; } } diff --git a/src/osd/modules/render/bgfx/texture.cpp b/src/osd/modules/render/bgfx/texture.cpp index ac2d9008568..ecbf51121ab 100644 --- a/src/osd/modules/render/bgfx/texture.cpp +++ b/src/osd/modules/render/bgfx/texture.cpp @@ -45,5 +45,5 @@ bgfx_texture::bgfx_texture(std::string name, bgfx::TextureFormat::Enum format, u bgfx_texture::~bgfx_texture() { - bgfx::destroyTexture(m_texture); + bgfx::destroy(m_texture); } diff --git a/src/osd/modules/render/bgfx/texturemanager.cpp b/src/osd/modules/render/bgfx/texturemanager.cpp index 3e404635bab..61be4f8f247 100644 --- a/src/osd/modules/render/bgfx/texturemanager.cpp +++ b/src/osd/modules/render/bgfx/texturemanager.cpp @@ -94,7 +94,7 @@ bgfx::TextureHandle texture_manager::handle(std::string name) handle = (iter->second)->texture(); } - assert(handle.idx != bgfx::invalidHandle); + assert(handle.idx != bgfx::kInvalidHandle); return handle; } diff --git a/src/osd/modules/render/bgfx/uniform.cpp b/src/osd/modules/render/bgfx/uniform.cpp index 780705d8371..ef33c11f128 100644 --- a/src/osd/modules/render/bgfx/uniform.cpp +++ b/src/osd/modules/render/bgfx/uniform.cpp @@ -23,7 +23,7 @@ bgfx_uniform::bgfx_uniform(std::string name, bgfx::UniformType::Enum type) bgfx_uniform::~bgfx_uniform() { - bgfx::destroyUniform(m_handle); + bgfx::destroy(m_handle); delete [] m_data; } diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 31ddc58c145..b3c65db7b86 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -5,7 +5,7 @@ // drawbgfx.cpp - BGFX renderer // //============================================================ -#include <bx/fpumath.h> +#include <bx/math.h> #include <bx/readerwriter.h> #if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS) || defined(OSD_UWP) @@ -103,7 +103,7 @@ renderer_bgfx::~renderer_bgfx() m_targets->destroy_target("avibuffer0"); m_avi_target = nullptr; - bgfx::destroyTexture(m_avi_texture); + bgfx::destroy(m_avi_texture); delete m_avi_writer; delete [] m_avi_data; @@ -341,7 +341,7 @@ void renderer_bgfx::record() m_avi_writer->stop(); m_targets->destroy_target("avibuffer0"); m_avi_target = nullptr; - bgfx::destroyTexture(m_avi_texture); + bgfx::destroy(m_avi_texture); } else { @@ -474,14 +474,13 @@ void renderer_bgfx::render_post_screen_quad(int view, render_primitive* prim, bg } uint32_t blend = PRIMFLAG_GET_BLENDMODE(prim->flags); - bgfx::setVertexBuffer(buffer); + bgfx::setVertexBuffer(0,buffer); bgfx::setTexture(0, m_screen_effect[blend]->uniform("s_tex")->handle(), m_targets->target(screen, "output")->texture(), texture_flags); m_screen_effect[blend]->submit(view); } void renderer_bgfx::render_avi_quad() { - bgfx::setViewSeq(s_current_view, true); bgfx::setViewRect(s_current_view, 0, 0, m_width[0], m_height[0]); bgfx::setViewClear(s_current_view, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0); @@ -504,7 +503,7 @@ void renderer_bgfx::render_avi_quad() vertex(&vertices[4], x[2], y[2], 0, rgba, u[2], v[2]); vertex(&vertices[5], x[0], y[0], 0, rgba, u[0], v[0]); - bgfx::setVertexBuffer(&buffer); + bgfx::setVertexBuffer(0,&buffer); bgfx::setTexture(0, m_gui_effect[PRIMFLAG_GET_BLENDMODE(BLENDMODE_NONE)]->uniform("s_tex")->handle(), m_avi_target->texture()); m_gui_effect[PRIMFLAG_GET_BLENDMODE(BLENDMODE_NONE)]->submit(s_current_view); s_current_view++; @@ -544,11 +543,11 @@ void renderer_bgfx::render_textured_quad(render_primitive* prim, bgfx::Transient bgfx_effect** effects = PRIMFLAG_GET_SCREENTEX(prim->flags) ? m_screen_effect : m_gui_effect; uint32_t blend = PRIMFLAG_GET_BLENDMODE(prim->flags); - bgfx::setVertexBuffer(buffer); + bgfx::setVertexBuffer(0,buffer); bgfx::setTexture(0, effects[blend]->uniform("s_tex")->handle(), texture); effects[blend]->submit(m_ui_view); - bgfx::destroyTexture(texture); + bgfx::destroy(texture); } #define MAX_TEMP_COORDS 100 @@ -830,7 +829,7 @@ int renderer_bgfx::draw(int update) if (status != BUFFER_EMPTY && status != BUFFER_SCREEN) { - bgfx::setVertexBuffer(&buffer); + bgfx::setVertexBuffer(0,&buffer); bgfx::setTexture(0, m_gui_effect[blend]->uniform("s_tex")->handle(), m_texture_cache->texture()); m_gui_effect[blend]->submit(m_ui_view); } @@ -948,7 +947,6 @@ void renderer_bgfx::setup_view(uint32_t view_index, bool screen) bgfx::setViewFrameBuffer(view_index, m_framebuffer->target()); } - bgfx::setViewSeq(view_index, true); bgfx::setViewRect(view_index, 0, 0, width, height); #if SCENE_VIEW @@ -983,6 +981,7 @@ void renderer_bgfx::setup_matrices(uint32_t view_index, bool screen) float proj[16]; float view[16]; + const bgfx::Caps* caps = bgfx::getCaps(); if (screen) { static float offset = 0.0f; @@ -995,12 +994,12 @@ void renderer_bgfx::setup_matrices(uint32_t view_index, bool screen) float eye[3] = { width * 0.5f, eye_height, cam_z }; bx::mtxLookAt(view, eye, at, up); - bx::mtxProj(proj, 90.0f, float(width) / float(height), 0.1f, 5000.0f); + bx::mtxProj(proj, 90.0f, float(width) / float(height), 0.1f, 5000.0f, bgfx::getCaps()->homogeneousDepth); } else { bx::mtxIdentity(view); - bx::mtxOrtho(proj, 0.0f, width, height, 0.0f, 0.0f, 100.0f); + bx::mtxOrtho(proj, 0.0f, width, height, 0.0f, 0.0f, 100.0f, 0.0f, caps->homogeneousDepth); } bgfx::setViewTransform(view_index, view, proj); diff --git a/src/tools/castool.cpp b/src/tools/castool.cpp index 8fc9d3bd911..bba809cd88d 100644 --- a/src/tools/castool.cpp +++ b/src/tools/castool.cpp @@ -23,6 +23,7 @@ #include "formats/ace_tap.h" #include "formats/adam_cas.h" #include "formats/apf_apt.h" +#include "formats/atom_tap.h" #include "formats/cbm_tap.h" #include "formats/cgen_cas.h" #include "formats/coco_cas.h" @@ -69,6 +70,7 @@ struct SupportedCassetteFormats const struct SupportedCassetteFormats formats[] = { {"a26", a26_cassette_formats ,"Atari 2600 SuperCharger"}, {"apf", apf_cassette_formats ,"APF Imagination Machine"}, + {"atom", atom_cassette_formats ,"Acorn Atom"}, {"bbc", bbc_cassette_formats ,"Acorn BBC & Electron"}, {"cbm", cbm_cassette_formats ,"Commodore 8-bit series"}, {"cdt", cdt_cassette_formats ,"Amstrad CPC"}, @@ -110,7 +112,6 @@ const struct SupportedCassetteFormats formats[] = { {"trs80l2", trs80l2_cassette_formats ,"TRS-80 Level 2"}, {"tvc64", tvc64_cassette_formats ,"Videoton TVC 64"}, {"tzx", tzx_cassette_formats ,"Sinclair ZX Spectrum"}, - {"uef", uef_cassette_formats ,"Acorn Electron"}, {"vg5k", vg5k_cassette_formats ,"Philips VG 5000"}, {"vtech1", vtech1_cassette_formats ,"Video Technology Laser 110-310"}, {"vtech2", vtech2_cassette_formats ,"Video Technology Laser 350-700"}, @@ -205,7 +206,7 @@ int CLIB_DECL main(int argc, char *argv[]) } /* Usage */ - fprintf(stderr, "castool - Generic cassette manipulation tool for use with MESS\n\n"); + fprintf(stderr, "castool - Generic cassette manipulation tool for use with MAME\n\n"); display_usage(); fprintf(stderr, "\n"); display_formats(); diff --git a/src/tools/floptool.cpp b/src/tools/floptool.cpp index 58c3c652996..aea7dd9576a 100644 --- a/src/tools/floptool.cpp +++ b/src/tools/floptool.cpp @@ -42,6 +42,7 @@ #include "formats/ap_dsk35.h" #include "formats/ap2_dsk.h" +#include "formats/atom_dsk.h" #include "formats/acorn_dsk.h" #include "formats/oric_dsk.h" @@ -76,6 +77,7 @@ static floppy_format_type floppy_formats[] = { FLOPPY_RWTS18_FORMAT, FLOPPY_EDD_FORMAT, + FLOPPY_ATOM_FORMAT, FLOPPY_ACORN_SSD_FORMAT, FLOPPY_ACORN_DSD_FORMAT, FLOPPY_ACORN_DOS_FORMAT, diff --git a/src/tools/unidasm.cpp b/src/tools/unidasm.cpp index eafca32f14f..3a9809c5b62 100644 --- a/src/tools/unidasm.cpp +++ b/src/tools/unidasm.cpp @@ -9,41 +9,257 @@ ****************************************************************************/ #include "emu.h" -#include "cpu/sparc/sparcdasm.h" #include <algorithm> #include <cstring> #include <ctype.h> +#include "cpu/8x300/8x300dasm.h" +#include "cpu/adsp2100/2100dasm.h" +#include "cpu/alph8201/8201dasm.h" +#include "cpu/alto2/alto2dsm.h" +#include "cpu/am29000/am29dasm.h" +#include "cpu/amis2000/amis2000d.h" +#include "cpu/apexc/apexcdsm.h" +#include "cpu/arc/arcdasm.h" +#include "cpu/arcompact/arcompactdasm.h" +#include "cpu/arm/armdasm.h" +#include "cpu/arm7/arm7dasm.h" +#include "cpu/asap/asapdasm.h" +#include "cpu/avr8/avr8dasm.h" +#include "cpu/capricorn/capricorn_dasm.h" +#include "cpu/ccpu/ccpudasm.h" +#include "cpu/clipper/clipperd.h" +#include "cpu/cop400/cop410ds.h" +#include "cpu/cop400/cop420ds.h" +#include "cpu/cop400/cop424ds.h" +#include "cpu/cop400/cop444ds.h" +#include "cpu/cosmac/cosdasm.h" +#include "cpu/cp1610/1610dasm.h" +#include "cpu/cubeqcpu/cubedasm.h" +#include "cpu/dsp16/dsp16dis.h" +#include "cpu/dsp32/dsp32dis.h" +#include "cpu/dsp56k/dsp56dsm.h" +#include "cpu/e0c6200/e0c6200d.h" +#include "cpu/e132xs/32xsdasm.h" +#include "cpu/es5510/es5510d.h" +#include "cpu/esrip/esripdsm.h" +#include "cpu/f8/f8dasm.h" +#include "cpu/g65816/g65816ds.h" +#include "cpu/h6280/6280dasm.h" +#include "cpu/h8/h8d.h" +#include "cpu/h8/h8hd.h" +#include "cpu/h8/h8s2000d.h" +#include "cpu/h8/h8s2600d.h" +#include "cpu/hcd62121/hcd62121d.h" +#include "cpu/hd61700/hd61700d.h" +#include "cpu/hmcs40/hmcs40d.h" +#include "cpu/hphybrid/hphybrid_dasm.h" +#include "cpu/i386/i386dasm.h" +#include "cpu/i8008/8008dasm.h" +#include "cpu/i8085/8085dasm.h" +#include "cpu/i8089/i8089_dasm.h" +#include "cpu/i860/i860dis.h" +#include "cpu/i960/i960dis.h" +#include "cpu/ie15/ie15dasm.h" +#include "cpu/jaguar/jagdasm.h" +#include "cpu/lc8670/lc8670dsm.h" +#include "cpu/lh5801/5801dasm.h" +#include "cpu/lr35902/lr35902d.h" +#include "cpu/m37710/m7700ds.h" +#include "cpu/m6502/m4510d.h" +#include "cpu/m6502/m6502d.h" +#include "cpu/m6502/m6509d.h" +#include "cpu/m6502/m6510d.h" +#include "cpu/m6502/m65c02d.h" +#include "cpu/m6502/m65ce02d.h" +#include "cpu/m6502/m740d.h" +#include "cpu/m6800/6800dasm.h" +#include "cpu/m68000/m68kdasm.h" +#include "cpu/m6805/6805dasm.h" +#include "cpu/m6809/6x09dasm.h" +#include "cpu/mb86233/mb86233d.h" +#include "cpu/mb86235/mb86235d.h" +#include "cpu/mb88xx/mb88dasm.h" +#include "cpu/mc68hc11/hc11dasm.h" +#include "cpu/mcs40/mcs40dasm.h" +#include "cpu/mcs48/mcs48dsm.h" +#include "cpu/mcs51/mcs51dasm.h" +#include "cpu/mcs96/i8x9xd.h" +#include "cpu/mcs96/i8xc196d.h" +#include "cpu/melps4/melps4d.h" +#include "cpu/minx/minxd.h" +#include "cpu/mips/mips3dsm.h" +#include "cpu/mips/r3kdasm.h" +#include "cpu/mn10200/mn102dis.h" +#include "cpu/nanoprocessor/nanoprocessor_dasm.h" +#include "cpu/nec/necdasm.h" +#include "cpu/patinhofeio/patinho_feio_dasm.h" +#include "cpu/pdp1/pdp1dasm.h" +#include "cpu/pdp1/tx0dasm.h" +#include "cpu/pdp8/pdp8dasm.h" +#include "cpu/pic16c5x/16c5xdsm.h" +#include "cpu/pic16c62x/16c62xdsm.h" +#include "cpu/powerpc/ppc_dasm.h" +#include "cpu/pps4/pps4dasm.h" +#include "cpu/psx/psxdasm.h" +#include "cpu/rsp/rsp_dasm.h" +#include "cpu/s2650/2650dasm.h" +#include "cpu/saturn/saturnds.h" +#include "cpu/sc61860/scdasm.h" +#include "cpu/scmp/scmpdasm.h" +#include "cpu/score/scoredsm.h" +#include "cpu/scudsp/scudspdasm.h" +#include "cpu/se3208/se3208dis.h" +#include "cpu/sh/sh_dasm.h" +#include "cpu/sharc/sharcdsm.h" +#include "cpu/sm510/sm510d.h" +#include "cpu/sm8500/sm8500d.h" +#include "cpu/sparc/sparcdasm.h" +#include "cpu/spc700/spc700ds.h" +#include "cpu/ssem/ssemdasm.h" +#include "cpu/ssp1601/ssp1601d.h" +#include "cpu/superfx/sfx_dasm.h" +#include "cpu/t11/t11dasm.h" +#include "cpu/tlcs870/tlcs870d.h" +#include "cpu/tlcs90/tlcs90d.h" +#include "cpu/tlcs900/dasm900.h" +#include "cpu/tms1000/tms1k_dasm.h" +#include "cpu/tms32010/32010dsm.h" +#include "cpu/tms32025/32025dsm.h" +#include "cpu/tms32031/dis32031.h" +#include "cpu/tms32051/dis32051.h" +#include "cpu/tms32082/dis_mp.h" +#include "cpu/tms32082/dis_pp.h" +#include "cpu/tms34010/34010dsm.h" +#include "cpu/tms57002/57002dsm.h" +#include "cpu/tms7000/7000dasm.h" +#include "cpu/tms9900/9900dasm.h" +#include "cpu/tms9900/tms99com.h" +#include "cpu/ucom4/ucom4d.h" +#include "cpu/unsp/unspdasm.h" +#include "cpu/upd7725/dasm7725.h" +#include "cpu/upd7810/upd7810_dasm.h" +#include "cpu/v60/v60d.h" +#include "cpu/v810/v810dasm.h" +#include "cpu/z180/z180dasm.h" +#include "cpu/z8/z8dasm.h" +#include "cpu/z80/z80dasm.h" +#include "cpu/z8000/8000dasm.h" + +// Configuration classes -enum display_type +// Selected through dasm name +struct arm7_unidasm_t : public arm7_disassembler::config { - _8bit, - _8bitx, - _16be, - _16le, - _24be, - _24le, - _32be, - _32le, - _40be, - _40le, - _48be, - _48le, - _56be, - _56le, - _64be, - _64le -}; + bool t_flag; + arm7_unidasm_t() { t_flag = false; } + virtual ~arm7_unidasm_t() override = default; + virtual bool get_t_flag() const override { return t_flag; } +} arm7_unidasm; + +// Configuration missing +struct g65816_unidasm_t : g65816_disassembler::config +{ + bool m_flag; + bool x_flag; + + g65816_unidasm_t() { m_flag = false; x_flag = false; } + virtual ~g65816_unidasm_t() override = default; + virtual bool get_m_flag() const override { return m_flag; } + virtual bool get_x_flag() const override { return x_flag; } +} g65816_unidasm; + +// Configuration missing +struct m740_unidasm_t : m740_disassembler::config +{ + u32 inst_state_base; + m740_unidasm_t() { inst_state_base = 0; } + virtual ~m740_unidasm_t() override = default; + virtual u32 get_state_base() const override { return inst_state_base; } +} m740_unidasm; +// Configuration missing +struct m7700_unidasm_t : m7700_disassembler::config +{ + bool m_flag; + bool x_flag; + + m7700_unidasm_t() { m_flag = false; x_flag = false; } + virtual ~m7700_unidasm_t() override = default; + virtual bool get_m_flag() const override { return m_flag; } + virtual bool get_x_flag() const override { return x_flag; } +} m7700_unidasm; + + +// Configuration missing +struct s2650_unidasm_t : s2650_disassembler::config +{ + bool z80_mnemonics; + s2650_unidasm_t() { z80_mnemonics = false; } + virtual ~s2650_unidasm_t() override = default; + virtual bool get_z80_mnemonics_mode() const override { return z80_mnemonics; } +} s2650_unidasm; + +// Configuration missing +struct saturn_unidasm_t : saturn_disassembler::config +{ + bool nonstandard_mnemonics; + saturn_unidasm_t() { nonstandard_mnemonics = false; } + virtual ~saturn_unidasm_t() override = default; + virtual bool get_nonstandard_mnemonics_mode() const override { return nonstandard_mnemonics; } +} saturn_unidasm; + +// Configuration missing +struct superfx_unidasm_t : superfx_disassembler::config +{ + u16 sfr; + superfx_unidasm_t() { sfr = superfx_disassembler::SUPERFX_SFR_ALT0; } + virtual ~superfx_unidasm_t() override = default; + virtual u16 get_alt() const override { return sfr; } +} superfx_unidasm; + +// Selected through dasm name +struct i386_unidasm_t : i386_disassembler::config +{ + int mode; + i386_unidasm_t() { mode = 32; } + virtual ~i386_unidasm_t() override = default; + virtual int get_mode() const override { return mode; } +} i386_unidasm; + +// Configuration missing +struct z8000_unidasm_t : z8000_disassembler::config +{ + bool segmented_mode; + z8000_unidasm_t() { segmented_mode = false; } + virtual ~z8000_unidasm_t() override = default; + virtual bool get_segmented_mode() const override { return segmented_mode; } +} z8000_unidasm; + +// Configuration missing +struct hyperstone_unidasm_t : hyperstone_disassembler::config +{ + bool h; + u8 fp; + hyperstone_unidasm_t() { h = false; fp = 0; } + virtual ~hyperstone_unidasm_t() = default; + + virtual u8 get_fp() const { return fp; } + virtual bool get_h() const { return h; } +} hyperstone_unidasm; + + + +enum endianness { le, be }; struct dasm_table_entry { const char * name; - display_type display; - int8_t pcshift; - cpu_disassemble_func func; + endianness endian; + int8_t pcshift; + std::function<util::disasm_interface *()> alloc; }; @@ -51,363 +267,574 @@ struct options { const char * filename; offs_t basepc; - uint8_t norawbytes; - uint8_t lower; - uint8_t upper; - uint8_t flipped; + uint8_t norawbytes; + uint8_t lower; + uint8_t upper; + uint8_t flipped; int mode; const dasm_table_entry *dasm; - uint32_t skip; - uint32_t count; + uint32_t skip; + uint32_t count; +}; + +static const dasm_table_entry dasm_table[] = +{ + { "8x300", be, 0, []() -> util::disasm_interface * { return new n8x300_disassembler; } }, + { "adsp21xx", le, -2, []() -> util::disasm_interface * { return new adsp21xx_disassembler; } }, + { "alpha8201", le, 0, []() -> util::disasm_interface * { return new alpha8201_disassembler; } }, + { "alto2", be, -2, []() -> util::disasm_interface * { return new alto2_disassembler; } }, + { "am29000", be, 0, []() -> util::disasm_interface * { return new am29000_disassembler; } }, + { "amis2000", le, 0, []() -> util::disasm_interface * { return new amis2000_disassembler; } }, + { "apexc", be, 0, []() -> util::disasm_interface * { return new apexc_disassembler; } }, + { "arc", be, 0, []() -> util::disasm_interface * { return new arc_disassembler; } }, + { "arcompact", le, 0, []() -> util::disasm_interface * { return new arcompact_disassembler; } }, + { "arm", le, 0, []() -> util::disasm_interface * { return new arm_disassembler; } }, + { "arm_be", be, 0, []() -> util::disasm_interface * { return new arm_disassembler; } }, + { "arm7", le, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = false; return new arm7_disassembler(&arm7_unidasm); } }, + { "arm7_be", be, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = false; return new arm7_disassembler(&arm7_unidasm); } }, + { "arm7thumb", le, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = true; return new arm7_disassembler(&arm7_unidasm); } }, + { "arm7thumbb", be, 0, []() -> util::disasm_interface * { arm7_unidasm.t_flag = true; return new arm7_disassembler(&arm7_unidasm); } }, + { "asap", le, 0, []() -> util::disasm_interface * { return new asap_disassembler; } }, + { "avr8", le, 0, []() -> util::disasm_interface * { return new avr8_disassembler; } }, + { "capricorn", le, 0, []() -> util::disasm_interface * { return new capricorn_disassembler; } }, + { "ccpu", le, 0, []() -> util::disasm_interface * { return new ccpu_disassembler; } }, + { "cdp1801", le, 0, []() -> util::disasm_interface * { return new cosmac_disassembler(cosmac_disassembler::TYPE_1801); } }, + { "cdp1802", le, 0, []() -> util::disasm_interface * { return new cosmac_disassembler(cosmac_disassembler::TYPE_1802); } }, + { "clipper", le, 0, []() -> util::disasm_interface * { return new clipper_disassembler; } }, + { "coldfire", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_COLDFIRE); } }, + { "cop410", le, 0, []() -> util::disasm_interface * { return new cop410_disassembler; } }, + { "cop420", le, 0, []() -> util::disasm_interface * { return new cop420_disassembler; } }, + { "cop444", le, 0, []() -> util::disasm_interface * { return new cop444_disassembler; } }, + { "cop424", le, 0, []() -> util::disasm_interface * { return new cop424_disassembler; } }, + { "cp1610", be, -1, []() -> util::disasm_interface * { return new cp1610_disassembler; } }, + { "cquestlin", be, -3, []() -> util::disasm_interface * { return new cquestlin_disassembler; } }, + { "cquestrot", be, -3, []() -> util::disasm_interface * { return new cquestrot_disassembler; } }, + { "cquestsnd", be, -3, []() -> util::disasm_interface * { return new cquestsnd_disassembler; } }, + { "ds5002fp", le, 0, []() -> util::disasm_interface * { return new ds5002fp_disassembler; } }, + { "dsp16a", le, -1, []() -> util::disasm_interface * { return new dsp16a_disassembler; } }, + { "dsp32c", le, 0, []() -> util::disasm_interface * { return new dsp32c_disassembler; } }, + { "dsp56k", le, -1, []() -> util::disasm_interface * { return new dsp56k_disassembler; } }, + { "e0c6200", be, -1, []() -> util::disasm_interface * { return new e0c6200_disassembler; } }, +// { "es5510", be, 0, []() -> util::disasm_interface * { return new es5510_disassembler; } }, // Currently does nothing + { "esrip", be, 0, []() -> util::disasm_interface * { return new esrip_disassembler; } }, + { "f8", le, 0, []() -> util::disasm_interface * { return new f8_disassembler; } }, + { "g65816", le, 0, []() -> util::disasm_interface * { return new g65816_disassembler(&g65816_unidasm); } }, + { "h6280", le, 0, []() -> util::disasm_interface * { return new h6280_disassembler; } }, + { "h8", be, 0, []() -> util::disasm_interface * { return new h8_disassembler; } }, + { "h8h", be, 0, []() -> util::disasm_interface * { return new h8h_disassembler; } }, + { "h8s2000", be, 0, []() -> util::disasm_interface * { return new h8s2000_disassembler; } }, + { "h8s2600", be, 0, []() -> util::disasm_interface * { return new h8s2600_disassembler; } }, + { "hc11", le, 0, []() -> util::disasm_interface * { return new hc11_disassembler; } }, + { "hcd62121", le, 0, []() -> util::disasm_interface * { return new hcd62121_disassembler; } }, + { "hd61700", le, 0, []() -> util::disasm_interface * { return new hd61700_disassembler; } }, + { "hd6301", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6301); } }, + { "hd6309", le, 0, []() -> util::disasm_interface * { return new hd6309_disassembler; } }, + { "hd63701", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(63701); } }, + { "hmcs40", le, -1, []() -> util::disasm_interface * { return new hmcs40_disassembler; } }, + { "hp_hybrid", be, -1, []() -> util::disasm_interface * { return new hp_hybrid_disassembler; } }, + { "hp_5061_3001", be, -1, []() -> util::disasm_interface * { return new hp_5061_3001_disassembler; } }, + { "hyperstone", be, 0, []() -> util::disasm_interface * { return new hyperstone_disassembler(&hyperstone_unidasm); } }, + { "i4004", le, 0, []() -> util::disasm_interface * { return new i4004_disassembler; } }, + { "i4040", le, 0, []() -> util::disasm_interface * { return new i4040_disassembler; } }, + { "i8008", le, 0, []() -> util::disasm_interface * { return new i8008_disassembler; } }, + { "i8051", le, 0, []() -> util::disasm_interface * { return new i8051_disassembler; } }, + { "i8052", le, 0, []() -> util::disasm_interface * { return new i8052_disassembler; } }, + { "i8085", le, 0, []() -> util::disasm_interface * { return new i8085_disassembler; } }, + { "i8089", le, 0, []() -> util::disasm_interface * { return new i8089_disassembler; } }, + { "i80c51", le, 0, []() -> util::disasm_interface * { return new i80c51_disassembler; } }, + { "i80c52", le, 0, []() -> util::disasm_interface * { return new i80c52_disassembler; } }, + { "i860", le, 0, []() -> util::disasm_interface * { return new i860_disassembler; } }, + { "i8x9x", le, 0, []() -> util::disasm_interface * { return new i8x9x_disassembler; } }, + { "i8xc196", le, 0, []() -> util::disasm_interface * { return new i8xc196_disassembler; } }, + { "i960", le, 0, []() -> util::disasm_interface * { return new i960_disassembler; } }, + { "ie15", le, 0, []() -> util::disasm_interface * { return new ie15_disassembler; } }, + { "jaguardsp", be, 0, []() -> util::disasm_interface * { return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_DSP); } }, + { "jaguargpu", be, 0, []() -> util::disasm_interface * { return new jaguar_disassembler(jaguar_disassembler::JAGUAR_VARIANT_GPU); } }, + { "konami", le, 0, []() -> util::disasm_interface * { return new konami_disassembler; } }, + { "lc8670", be, 0, []() -> util::disasm_interface * { return new lc8670_disassembler; } }, + { "lh5801", le, 0, []() -> util::disasm_interface * { return new lh5801_disassembler; } }, + { "lr35902", le, 0, []() -> util::disasm_interface * { return new lr35902_disassembler; } }, + { "m146805", le, 0, []() -> util::disasm_interface * { return new m146805_disassembler; } }, + { "m37710", le, 0, []() -> util::disasm_interface * { return new m7700_disassembler(&m7700_unidasm); } }, + { "m4510", le, 0, []() -> util::disasm_interface * { return new m4510_disassembler; } }, + { "m58846", le, -1, []() -> util::disasm_interface * { return new melps4_disassembler; } }, + { "m6502", le, 0, []() -> util::disasm_interface * { return new m6502_disassembler; } }, + { "m6509", le, 0, []() -> util::disasm_interface * { return new m6509_disassembler; } }, + { "m6510", le, 0, []() -> util::disasm_interface * { return new m6510_disassembler; } }, + { "m65c02", le, 0, []() -> util::disasm_interface * { return new m65c02_disassembler; } }, + { "m65ce02", le, 0, []() -> util::disasm_interface * { return new m65ce02_disassembler; } }, + { "m6800", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6800); } }, + { "m68000", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68000); } }, + { "m68008", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68008); } }, + { "m6801", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6801); } }, + { "m68010", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68010); } }, + { "m6802", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6802); } }, + { "m68020", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68020); } }, + { "m6803", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6803); } }, + { "m68030", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68030); } }, + { "m68040", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68040); } }, + { "m6805", le, 0, []() -> util::disasm_interface * { return new m6805_disassembler; } }, + { "m6808", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(6808); } }, + { "m6809", le, 0, []() -> util::disasm_interface * { return new m6809_disassembler; } }, + { "m68340", be, 0, []() -> util::disasm_interface * { return new m68k_disassembler(m68k_disassembler::TYPE_68340); } }, + { "m68hc05", le, 0, []() -> util::disasm_interface * { return new m68hc05_disassembler; } }, + { "m740", le, 0, []() -> util::disasm_interface * { return new m740_disassembler(&m740_unidasm); } }, + { "mb86233", le, -2, []() -> util::disasm_interface * { return new mb86233_disassembler; } }, + { "mb86235", le, -3, []() -> util::disasm_interface * { return new mb86235_disassembler; } }, + { "mb88", le, 0, []() -> util::disasm_interface * { return new mb88_disassembler; } }, + { "mcs48", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(false); } }, + { "minx", le, 0, []() -> util::disasm_interface * { return new minx_disassembler; } }, + { "mips3be", be, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } }, + { "mips3le", le, 0, []() -> util::disasm_interface * { return new mips3_disassembler; } }, + { "mn10200", le, 0, []() -> util::disasm_interface * { return new mn10200_disassembler; } }, + { "nanoprocessor", le, 0, []() -> util::disasm_interface * { return new hp_nanoprocessor_disassembler; } }, + { "nec", le, 0, []() -> util::disasm_interface * { return new nec_disassembler; } }, + { "nsc8105", le, 0, []() -> util::disasm_interface * { return new m680x_disassembler(8105); } }, + { "patinho_feio", le, 0, []() -> util::disasm_interface * { return new patinho_feio_disassembler; } }, + { "pdp1", be, 0, []() -> util::disasm_interface * { return new pdp1_disassembler; } }, + { "pdp8", be, 0, []() -> util::disasm_interface * { return new pdp8_disassembler; } }, + { "pic16c5x", le, -1, []() -> util::disasm_interface * { return new pic16c5x_disassembler; } }, + { "pic16c62x", le, -1, []() -> util::disasm_interface * { return new pic16c62x_disassembler; } }, + { "powerpc", be, 0, []() -> util::disasm_interface * { return new powerpc_disassembler; } }, + { "pps4", le, 0, []() -> util::disasm_interface * { return new pps4_disassembler; } }, + { "psxcpu", le, 0, []() -> util::disasm_interface * { return new psxcpu_disassembler; } }, + { "r3000be", be, 0, []() -> util::disasm_interface * { return new r3000_disassembler; } }, + { "r3000le", le, 0, []() -> util::disasm_interface * { return new r3000_disassembler; } }, + { "rsp", le, 0, []() -> util::disasm_interface * { return new rsp_disassembler; } }, + { "s2650", le, 0, []() -> util::disasm_interface * { return new s2650_disassembler(&s2650_unidasm); } }, + { "saturn", le, 0, []() -> util::disasm_interface * { return new saturn_disassembler(&saturn_unidasm); } }, + { "sc61860", le, 0, []() -> util::disasm_interface * { return new sc61860_disassembler; } }, + { "scmp", le, 0, []() -> util::disasm_interface * { return new scmp_disassembler; } }, + { "scudsp", be, 0, []() -> util::disasm_interface * { return new scudsp_disassembler; } }, + { "se3208", le, 0, []() -> util::disasm_interface * { return new se3208_disassembler; } }, + { "sh2", be, 0, []() -> util::disasm_interface * { return new sh_disassembler(false); } }, + { "sh4", le, 0, []() -> util::disasm_interface * { return new sh_disassembler(true); } }, + { "sh4be", be, 0, []() -> util::disasm_interface * { return new sh_disassembler(true); } }, + { "sharc", le, -2, []() -> util::disasm_interface * { return new sharc_disassembler; } }, + { "sm500", le, 0, []() -> util::disasm_interface * { return new sm500_disassembler; } }, + { "sm510", le, 0, []() -> util::disasm_interface * { return new sm510_disassembler; } }, + { "sm511", le, 0, []() -> util::disasm_interface * { return new sm511_disassembler; } }, + { "sm590", le, 0, []() -> util::disasm_interface * { return new sm590_disassembler; } }, + { "sm5a", le, 0, []() -> util::disasm_interface * { return new sm5a_disassembler; } }, + { "sm8500", le, 0, []() -> util::disasm_interface * { return new sm8500_disassembler; } }, + { "sparcv7", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 7); } }, + { "sparcv8", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 8); } }, + { "sparcv9", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9); } }, + { "sparcv9vis1", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_1); } }, + { "sparcv9vis2", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_2); } }, + { "sparcv9vis2p", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_2p); } }, + { "sparcv9vis3", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_3); } }, + { "sparcv9vis3b", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_3b); } }, + { "spc700", le, 0, []() -> util::disasm_interface * { return new spc700_disassembler; } }, + { "ssem", le, 0, []() -> util::disasm_interface * { return new ssem_disassembler; } }, + { "ssp1601", be, -1, []() -> util::disasm_interface * { return new ssp1601_disassembler; } }, + { "superfx", le, 0, []() -> util::disasm_interface * { return new superfx_disassembler(&superfx_unidasm); } }, + { "t11", le, 0, []() -> util::disasm_interface * { return new t11_disassembler; } }, + { "tlcs870", le, 0, []() -> util::disasm_interface * { return new tlcs870_disassembler; } }, + { "tlcs90", le, 0, []() -> util::disasm_interface * { return new tlcs90_disassembler; } }, + { "tlcs900", le, 0, []() -> util::disasm_interface * { return new tlcs900_disassembler; } }, + { "tms0980", be, 0, []() -> util::disasm_interface * { return new tms0980_disassembler; } }, + { "tms1000", le, 0, []() -> util::disasm_interface * { return new tms1000_disassembler; } }, + { "tms1100", le, 0, []() -> util::disasm_interface * { return new tms1100_disassembler; } }, + { "tms32010", be, -1, []() -> util::disasm_interface * { return new tms32010_disassembler; } }, + { "tms32025", be, -1, []() -> util::disasm_interface * { return new tms32025_disassembler; } }, + { "tms32031", le, -2, []() -> util::disasm_interface * { return new tms32031_disassembler; } }, + { "tms32051", le, -1, []() -> util::disasm_interface * { return new tms32051_disassembler; } }, + { "tms32082_mp", be, 0, []() -> util::disasm_interface * { return new tms32082_mp_disassembler; } }, + { "tms32082_pp", be, 0, []() -> util::disasm_interface * { return new tms32082_pp_disassembler; } }, + { "tms34010", le, 3, []() -> util::disasm_interface * { return new tms34010_disassembler(false); } }, + { "tms34020", le, 3, []() -> util::disasm_interface * { return new tms34010_disassembler(true); } }, + { "tms57002", le, -2, []() -> util::disasm_interface * { return new tms57002_disassembler; } }, + { "tms7000", le, 0, []() -> util::disasm_interface * { return new tms7000_disassembler; } }, + { "tms9900", be, 0, []() -> util::disasm_interface * { return new tms9900_disassembler(TMS9900_ID); } }, + { "tms9980", le, 0, []() -> util::disasm_interface * { return new tms9900_disassembler(TMS9980_ID); } }, + { "tms9995", le, 0, []() -> util::disasm_interface * { return new tms9900_disassembler(TMS9995_ID); } }, + { "tp0320", be, 0, []() -> util::disasm_interface * { return new tp0320_disassembler; } }, + { "tx0_64kw", be, -2, []() -> util::disasm_interface * { return new tx0_64kw_disassembler; } }, + { "tx0_8kw", be, -2, []() -> util::disasm_interface * { return new tx0_8kw_disassembler; } }, + { "ucom4", le, 0, []() -> util::disasm_interface * { return new ucom4_disassembler; } }, + { "unsp", be, 0, []() -> util::disasm_interface * { return new unsp_disassembler; } }, + { "upd7725", be, 0, []() -> util::disasm_interface * { return new necdsp_disassembler; } }, + { "upd7801", le, 0, []() -> util::disasm_interface * { return new upd7801_disassembler; } }, + { "upd7807", le, 0, []() -> util::disasm_interface * { return new upd7807_disassembler; } }, + { "upd7810", le, 0, []() -> util::disasm_interface * { return new upd7810_disassembler; } }, + { "upd78c05", le, 0, []() -> util::disasm_interface * { return new upd78c05_disassembler; } }, + { "upi41", le, 0, []() -> util::disasm_interface * { return new mcs48_disassembler(true); } }, + { "v60", le, 0, []() -> util::disasm_interface * { return new v60_disassembler; } }, + { "v810", le, 0, []() -> util::disasm_interface * { return new v810_disassembler; } }, + { "x86_16", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 16; return new i386_disassembler(&i386_unidasm); } }, + { "x86_32", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 32; return new i386_disassembler(&i386_unidasm); } }, + { "x86_64", le, 0, []() -> util::disasm_interface * { i386_unidasm.mode = 64; return new i386_disassembler(&i386_unidasm); } }, + { "z180", le, 0, []() -> util::disasm_interface * { return new z180_disassembler; } }, + { "z8", le, 0, []() -> util::disasm_interface * { return new z8_disassembler; } }, + { "z80", le, 0, []() -> util::disasm_interface * { return new z80_disassembler; } }, + { "z8000", be, 0, []() -> util::disasm_interface * { return new z8000_disassembler(&z8000_unidasm); } }, }; +class unidasm_data_buffer : public util::disasm_interface::data_buffer +{ +public: + std::vector<u8> data; + offs_t base_pc; + u32 size; + + unidasm_data_buffer(util::disasm_interface *disasm, const dasm_table_entry *entry); + virtual ~unidasm_data_buffer() = default; -CPU_DISASSEMBLE( adsp21xx ); -CPU_DISASSEMBLE( alpha8201 ); -CPU_DISASSEMBLE( am29000 ); -CPU_DISASSEMBLE( amis2000 ); -CPU_DISASSEMBLE( apexc ); -CPU_DISASSEMBLE( arcompact ); -CPU_DISASSEMBLE( arm ); -CPU_DISASSEMBLE( arm_be ); -CPU_DISASSEMBLE( arm7arm ); -CPU_DISASSEMBLE( arm7arm_be ); -CPU_DISASSEMBLE( arm7thumb ); -CPU_DISASSEMBLE( arm7thumb_be ); -CPU_DISASSEMBLE( asap ); -CPU_DISASSEMBLE( avr8 ); -CPU_DISASSEMBLE( capricorn ); -CPU_DISASSEMBLE( ccpu ); -CPU_DISASSEMBLE( cdp1801 ); -CPU_DISASSEMBLE( cdp1802 ); -CPU_DISASSEMBLE( clipper ); -CPU_DISASSEMBLE( coldfire ); -CPU_DISASSEMBLE( cop410 ); -CPU_DISASSEMBLE( cop420 ); -CPU_DISASSEMBLE( cop444 ); -CPU_DISASSEMBLE( cop424 ); -CPU_DISASSEMBLE( cp1610 ); -CPU_DISASSEMBLE( cquestlin ); -CPU_DISASSEMBLE( cquestrot ); -CPU_DISASSEMBLE( cquestsnd ); -CPU_DISASSEMBLE( ds5002fp ); -CPU_DISASSEMBLE( dsp16a ); -CPU_DISASSEMBLE( dsp32c ); -CPU_DISASSEMBLE( dsp56k ); -CPU_DISASSEMBLE( e0c6200 ); -CPU_DISASSEMBLE( esrip ); -CPU_DISASSEMBLE( f8 ); -CPU_DISASSEMBLE( g65816_generic ); -CPU_DISASSEMBLE( h6280 ); -CPU_DISASSEMBLE( hc11 ); -CPU_DISASSEMBLE( hcd62121 ); -CPU_DISASSEMBLE( hd61700 ); -CPU_DISASSEMBLE( hd6301 ); -CPU_DISASSEMBLE( hd6309 ); -CPU_DISASSEMBLE( hd63701 ); -CPU_DISASSEMBLE( hmcs40 ); -CPU_DISASSEMBLE( hp_hybrid ); -CPU_DISASSEMBLE( hp_5061_3001 ); -CPU_DISASSEMBLE( hp_nanoprocessor ); -CPU_DISASSEMBLE( hyperstone_generic ); -CPU_DISASSEMBLE( i4004 ); -CPU_DISASSEMBLE( i4040 ); -CPU_DISASSEMBLE( i8008 ); -CPU_DISASSEMBLE( i8051 ); -CPU_DISASSEMBLE( i8052 ); -CPU_DISASSEMBLE( i8085 ); -CPU_DISASSEMBLE( i8089 ); -CPU_DISASSEMBLE( i80c51 ); -CPU_DISASSEMBLE( i80c52 ); -CPU_DISASSEMBLE( i860 ); -CPU_DISASSEMBLE( i960 ); -CPU_DISASSEMBLE( ie15 ); -CPU_DISASSEMBLE( jaguardsp ); -CPU_DISASSEMBLE( jaguargpu ); -CPU_DISASSEMBLE( konami ); -CPU_DISASSEMBLE( lh5801 ); -CPU_DISASSEMBLE( lr35902 ); -CPU_DISASSEMBLE( m58846 ); -CPU_DISASSEMBLE( m37710_generic ); -CPU_DISASSEMBLE( m6800 ); -CPU_DISASSEMBLE( m68000 ); -CPU_DISASSEMBLE( m68008 ); -CPU_DISASSEMBLE( m6801 ); -CPU_DISASSEMBLE( m68010 ); -CPU_DISASSEMBLE( m6802 ); -CPU_DISASSEMBLE( m68020 ); -CPU_DISASSEMBLE( m6803 ); -CPU_DISASSEMBLE( m68030 ); -CPU_DISASSEMBLE( m68040 ); -CPU_DISASSEMBLE( m6805 ); -CPU_DISASSEMBLE( m146805 ); -CPU_DISASSEMBLE( m68hc05 ); -CPU_DISASSEMBLE( m6808 ); -CPU_DISASSEMBLE( m6809 ); -CPU_DISASSEMBLE( m68340 ); -CPU_DISASSEMBLE( mb86233 ); -CPU_DISASSEMBLE( mb88 ); -CPU_DISASSEMBLE( mcs48 ); -CPU_DISASSEMBLE( minx ); -CPU_DISASSEMBLE( mips3be ); -CPU_DISASSEMBLE( mips3le ); -CPU_DISASSEMBLE( mn10200 ); -CPU_DISASSEMBLE( n8x300 ); -CPU_DISASSEMBLE( nec ); -CPU_DISASSEMBLE( nsc8105 ); -CPU_DISASSEMBLE( pdp1 ); -CPU_DISASSEMBLE( pdp8 ); -CPU_DISASSEMBLE( pic16c5x ); -CPU_DISASSEMBLE( pic16c62x ); -CPU_DISASSEMBLE( powerpc ); -CPU_DISASSEMBLE( pps4 ); -CPU_DISASSEMBLE( psxcpu_generic ); -CPU_DISASSEMBLE( r3000be ); -CPU_DISASSEMBLE( r3000le ); -CPU_DISASSEMBLE( rsp ); -CPU_DISASSEMBLE( s2650 ); -CPU_DISASSEMBLE( saturn ); -CPU_DISASSEMBLE( sc61860 ); -CPU_DISASSEMBLE( scmp ); -CPU_DISASSEMBLE( scudsp ); -CPU_DISASSEMBLE( se3208 ); -CPU_DISASSEMBLE( sh2 ); -CPU_DISASSEMBLE( sh4 ); -CPU_DISASSEMBLE( sh4be ); -CPU_DISASSEMBLE( sharc ); -CPU_DISASSEMBLE( sm500 ); -CPU_DISASSEMBLE( sm510 ); -CPU_DISASSEMBLE( sm511 ); -CPU_DISASSEMBLE( sm5a ); -CPU_DISASSEMBLE( sm8500 ); -CPU_DISASSEMBLE( spc700 ); -CPU_DISASSEMBLE( ssem ); -CPU_DISASSEMBLE( ssp1601 ); -CPU_DISASSEMBLE( superfx ); -CPU_DISASSEMBLE( t11 ); -CPU_DISASSEMBLE( t90 ); -CPU_DISASSEMBLE( tlcs900 ); -CPU_DISASSEMBLE( tms0980 ); -CPU_DISASSEMBLE( tms1000 ); -CPU_DISASSEMBLE( tms1100 ); -CPU_DISASSEMBLE( tms32010 ); -CPU_DISASSEMBLE( tms32025 ); -CPU_DISASSEMBLE( tms3203x ); -CPU_DISASSEMBLE( tms32051 ); -CPU_DISASSEMBLE( tms34010 ); -CPU_DISASSEMBLE( tms34020 ); -CPU_DISASSEMBLE( tms57002 ); -CPU_DISASSEMBLE( tms7000 ); -CPU_DISASSEMBLE( tms9900 ); -CPU_DISASSEMBLE( tms9980 ); -CPU_DISASSEMBLE( tms9995 ); -CPU_DISASSEMBLE( tp0320 ); -CPU_DISASSEMBLE( tx0_64kw ); -CPU_DISASSEMBLE( tx0_8kw ); -CPU_DISASSEMBLE( ucom4 ); -CPU_DISASSEMBLE( unsp ); -CPU_DISASSEMBLE( upd7725 ); -CPU_DISASSEMBLE( upd7801 ); -CPU_DISASSEMBLE( upd7807 ); -CPU_DISASSEMBLE( upd7810 ); -CPU_DISASSEMBLE( upd78c05 ); -CPU_DISASSEMBLE( upi41 ); -CPU_DISASSEMBLE( v60 ); -CPU_DISASSEMBLE( v70 ); -CPU_DISASSEMBLE( v810 ); -CPU_DISASSEMBLE( x86_16 ); -CPU_DISASSEMBLE( x86_32 ); -CPU_DISASSEMBLE( x86_64 ); -CPU_DISASSEMBLE( z180 ); -CPU_DISASSEMBLE( z8 ); -CPU_DISASSEMBLE( z80 ); -CPU_DISASSEMBLE( z8000 ); - -CPU_DISASSEMBLE( sparcv7 ) { static sparc_disassembler dasm(nullptr, 7); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); } -CPU_DISASSEMBLE( sparcv8 ) { static sparc_disassembler dasm(nullptr, 8); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); } -CPU_DISASSEMBLE( sparcv9 ) { static sparc_disassembler dasm(nullptr, 9); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); } -CPU_DISASSEMBLE( sparcv9vis1 ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_1); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); } -CPU_DISASSEMBLE( sparcv9vis2 ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_2); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); } -CPU_DISASSEMBLE( sparcv9vis2p ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_2p); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); } -CPU_DISASSEMBLE( sparcv9vis3 ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_3); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); } -CPU_DISASSEMBLE( sparcv9vis3b ) { static sparc_disassembler dasm(nullptr, 9, sparc_disassembler::vis_3b); return dasm.dasm(stream, pc, big_endianize_int32(*reinterpret_cast<const uint32_t *>(oprom))); } + void decrypt(const unidasm_data_buffer &buffer, bool opcode); + virtual u8 r8 (offs_t pc) const override { return lr8 (pc); } + virtual u16 r16(offs_t pc) const override { return lr16(pc); } + virtual u32 r32(offs_t pc) const override { return lr32(pc); } + virtual u64 r64(offs_t pc) const override { return lr64(pc); } -static const dasm_table_entry dasm_table[] = +private: + std::function<u8 (offs_t pc)> lr8; + std::function<u16 (offs_t pc)> lr16; + std::function<u32 (offs_t pc)> lr32; + std::function<u64 (offs_t pc)> lr64; + + util::disasm_interface *disasm; + const dasm_table_entry *entry; + + template<typename T> const T *get_ptr(offs_t pc) const { + if(pc < base_pc) + return nullptr; + offs_t delta = (pc - base_pc) * sizeof(T); + if(delta >= size) + return nullptr; + return reinterpret_cast<const T *>(&data[delta]); + } + + template<typename T> T get(offs_t pc) const { + auto p = get_ptr<T>(pc); + return p ? *p : 0; + } +}; + +struct dasm_line { - { "8x300", _16be, 0, CPU_DISASSEMBLE_NAME(n8x300) }, - { "adsp21xx", _24le, -2, CPU_DISASSEMBLE_NAME(adsp21xx) }, - { "alpha8201", _8bit, 0, CPU_DISASSEMBLE_NAME(alpha8201) }, - { "am29000", _32be, 0, CPU_DISASSEMBLE_NAME(am29000) }, - { "amis2000", _8bit, 0, CPU_DISASSEMBLE_NAME(amis2000) }, - { "apexc", _32be, 0, CPU_DISASSEMBLE_NAME(apexc) }, - { "arcompact", _16le, 0, CPU_DISASSEMBLE_NAME(arcompact) }, - { "arm", _32le, 0, CPU_DISASSEMBLE_NAME(arm) }, - { "arm_be", _32be, 0, CPU_DISASSEMBLE_NAME(arm_be) }, - { "arm7", _32le, 0, CPU_DISASSEMBLE_NAME(arm7arm) }, - { "arm7_be", _32be, 0, CPU_DISASSEMBLE_NAME(arm7arm_be) }, - { "arm7thumb", _16le, 0, CPU_DISASSEMBLE_NAME(arm7thumb) }, - { "arm7thumbb", _16be, 0, CPU_DISASSEMBLE_NAME(arm7thumb_be) }, - { "asap", _32le, 0, CPU_DISASSEMBLE_NAME(asap) }, - { "avr8", _16le, 0, CPU_DISASSEMBLE_NAME(avr8) }, - { "capricorn", _8bit, 0, CPU_DISASSEMBLE_NAME(capricorn) }, - { "ccpu", _8bit, 0, CPU_DISASSEMBLE_NAME(ccpu) }, - { "cdp1801", _8bit, 0, CPU_DISASSEMBLE_NAME(cdp1801) }, - { "cdp1802", _8bit, 0, CPU_DISASSEMBLE_NAME(cdp1802) }, - { "clipper", _16le, 0, CPU_DISASSEMBLE_NAME(clipper) }, - { "coldfire", _16be, 0, CPU_DISASSEMBLE_NAME(coldfire) }, - { "cop410", _8bit, 0, CPU_DISASSEMBLE_NAME(cop410) }, - { "cop420", _8bit, 0, CPU_DISASSEMBLE_NAME(cop420) }, - { "cop444", _8bit, 0, CPU_DISASSEMBLE_NAME(cop444) }, - { "cop424", _8bit, 0, CPU_DISASSEMBLE_NAME(cop424) }, - { "cp1610", _16be, -1, CPU_DISASSEMBLE_NAME(cp1610) }, - { "cquestlin", _64be, -3, CPU_DISASSEMBLE_NAME(cquestlin) }, - { "cquestrot", _64be, -3, CPU_DISASSEMBLE_NAME(cquestrot) }, - { "cquestsnd", _64be, -3, CPU_DISASSEMBLE_NAME(cquestsnd) }, - { "ds5002fp", _8bit, 0, CPU_DISASSEMBLE_NAME(ds5002fp) }, - { "dsp16a", _16le, -1, CPU_DISASSEMBLE_NAME(dsp16a) }, - { "dsp32c", _32le, 0, CPU_DISASSEMBLE_NAME(dsp32c) }, - { "dsp56k", _16le, -1, CPU_DISASSEMBLE_NAME(dsp56k) }, - { "e0c6200", _16be, -1, CPU_DISASSEMBLE_NAME(e0c6200) }, - { "esrip", _64be, 0, CPU_DISASSEMBLE_NAME(esrip) }, - { "f8", _8bit, 0, CPU_DISASSEMBLE_NAME(f8) }, - { "g65816", _8bit, 0, CPU_DISASSEMBLE_NAME(g65816_generic) }, - { "h6280", _8bit, 0, CPU_DISASSEMBLE_NAME(h6280) }, -// { "h8", _16be, 0, CPU_DISASSEMBLE_NAME(h8) }, -// { "h8_24", _16be, 0, CPU_DISASSEMBLE_NAME(h8_24) }, -// { "h8_32", _16be, 0, CPU_DISASSEMBLE_NAME(h8_32) }, - { "hc11", _8bit, 0, CPU_DISASSEMBLE_NAME(hc11) }, - { "hcd62121", _8bit, 0, CPU_DISASSEMBLE_NAME(hcd62121) }, - { "hd61700", _8bit, 0, CPU_DISASSEMBLE_NAME(hd61700) }, - { "hd6301", _8bit, 0, CPU_DISASSEMBLE_NAME(hd6301) }, - { "hd6309", _8bit, 0, CPU_DISASSEMBLE_NAME(hd6309) }, - { "hd63701", _8bit, 0, CPU_DISASSEMBLE_NAME(hd63701) }, - { "hmcs40", _16le, -1, CPU_DISASSEMBLE_NAME(hmcs40) }, - { "hp_hybrid", _16be, -1, CPU_DISASSEMBLE_NAME(hp_hybrid) }, - { "hp_5061_3001",_16be, -1, CPU_DISASSEMBLE_NAME(hp_5061_3001) }, - { "hyperstone", _16be, 0, CPU_DISASSEMBLE_NAME(hyperstone_generic) }, - { "i4004", _8bit, 0, CPU_DISASSEMBLE_NAME(i4004) }, - { "i4040", _8bit, 0, CPU_DISASSEMBLE_NAME(i4040) }, - { "i8008", _8bit, 0, CPU_DISASSEMBLE_NAME(i8008) }, - { "i8051", _8bit, 0, CPU_DISASSEMBLE_NAME(i8051) }, - { "i8052", _8bit, 0, CPU_DISASSEMBLE_NAME(i8052) }, - { "i8085", _8bit, 0, CPU_DISASSEMBLE_NAME(i8085) }, - { "i8089", _8bit, 0, CPU_DISASSEMBLE_NAME(i8089) }, - { "i80c51", _8bit, 0, CPU_DISASSEMBLE_NAME(i80c51) }, - { "i80c52", _8bit, 0, CPU_DISASSEMBLE_NAME(i80c52) }, - { "i860", _64le, 0, CPU_DISASSEMBLE_NAME(i860) }, - { "i960", _32le, 0, CPU_DISASSEMBLE_NAME(i960) }, - { "ie15", _8bit, 0, CPU_DISASSEMBLE_NAME(ie15) }, - { "jaguardsp", _16be, 0, CPU_DISASSEMBLE_NAME(jaguardsp) }, - { "jaguargpu", _16be, 0, CPU_DISASSEMBLE_NAME(jaguargpu) }, - { "konami", _8bit, 0, CPU_DISASSEMBLE_NAME(konami) }, - { "lh5801", _8bit, 0, CPU_DISASSEMBLE_NAME(lh5801) }, - { "lr35902", _8bit, 0, CPU_DISASSEMBLE_NAME(lr35902) }, - { "m58846", _16le, -1, CPU_DISASSEMBLE_NAME(m58846) }, - { "m37710", _8bit, 0, CPU_DISASSEMBLE_NAME(m37710_generic) }, - { "m6800", _8bit, 0, CPU_DISASSEMBLE_NAME(m6800) }, - { "m68000", _16be, 0, CPU_DISASSEMBLE_NAME(m68000) }, - { "m68008", _16be, 0, CPU_DISASSEMBLE_NAME(m68008) }, - { "m6801", _8bit, 0, CPU_DISASSEMBLE_NAME(m6801) }, - { "m68010", _16be, 0, CPU_DISASSEMBLE_NAME(m68010) }, - { "m6802", _8bit, 0, CPU_DISASSEMBLE_NAME(m6802) }, - { "m68020", _16be, 0, CPU_DISASSEMBLE_NAME(m68020) }, - { "m6803", _8bit, 0, CPU_DISASSEMBLE_NAME(m6803) }, - { "m68030", _16be, 0, CPU_DISASSEMBLE_NAME(m68030) }, - { "m68040", _16be, 0, CPU_DISASSEMBLE_NAME(m68040) }, - { "m6805", _8bit, 0, CPU_DISASSEMBLE_NAME(m6805) }, - { "m146805", _8bit, 0, CPU_DISASSEMBLE_NAME(m146805) }, - { "m68hc05", _8bit, 0, CPU_DISASSEMBLE_NAME(m68hc05) }, - { "m6808", _8bit, 0, CPU_DISASSEMBLE_NAME(m6808) }, - { "m6809", _8bit, 0, CPU_DISASSEMBLE_NAME(m6809) }, - { "m68340", _16be, 0, CPU_DISASSEMBLE_NAME(m68340) }, - { "mb86233", _32le, -2, CPU_DISASSEMBLE_NAME(mb86233) }, - { "mb88", _8bit, 0, CPU_DISASSEMBLE_NAME(mb88) }, - { "mcs48", _8bit, 0, CPU_DISASSEMBLE_NAME(mcs48) }, - { "minx", _8bit, 0, CPU_DISASSEMBLE_NAME(minx) }, - { "mips3be", _32be, 0, CPU_DISASSEMBLE_NAME(mips3be) }, - { "mips3le", _32le, 0, CPU_DISASSEMBLE_NAME(mips3le) }, - { "mn10200", _16le, 0, CPU_DISASSEMBLE_NAME(mn10200) }, - { "nanoprocessor",_8bit, 0, CPU_DISASSEMBLE_NAME(hp_nanoprocessor) }, - { "nec", _8bit, 0, CPU_DISASSEMBLE_NAME(nec) }, - { "nsc8105", _8bit, 0, CPU_DISASSEMBLE_NAME(nsc8105) }, - { "pdp1", _32be, 0, CPU_DISASSEMBLE_NAME(pdp1) }, - { "pdp8", _16be, 0, CPU_DISASSEMBLE_NAME(pdp8) }, - { "pic16c5x", _16le, -1, CPU_DISASSEMBLE_NAME(pic16c5x) }, - { "pic16c62x", _16le, -1, CPU_DISASSEMBLE_NAME(pic16c62x) }, - { "powerpc", _32be, 0, CPU_DISASSEMBLE_NAME(powerpc) }, - { "pps4", _8bit, 0, CPU_DISASSEMBLE_NAME(pps4) }, - { "psxcpu", _32le, 0, CPU_DISASSEMBLE_NAME(psxcpu_generic) }, - { "r3000be", _32be, 0, CPU_DISASSEMBLE_NAME(r3000be) }, - { "r3000le", _32le, 0, CPU_DISASSEMBLE_NAME(r3000le) }, - { "rsp", _32le, 0, CPU_DISASSEMBLE_NAME(rsp) }, - { "s2650", _8bit, 0, CPU_DISASSEMBLE_NAME(s2650) }, - { "saturn", _8bit, 0, CPU_DISASSEMBLE_NAME(saturn) }, - { "sc61860", _8bit, 0, CPU_DISASSEMBLE_NAME(sc61860) }, - { "scmp", _8bit, 0, CPU_DISASSEMBLE_NAME(scmp) }, - { "scudsp", _32be, 0, CPU_DISASSEMBLE_NAME(scudsp) }, - { "se3208", _16le, 0, CPU_DISASSEMBLE_NAME(se3208) }, - { "sh2", _16be, 0, CPU_DISASSEMBLE_NAME(sh2) }, - { "sh4", _16le, 0, CPU_DISASSEMBLE_NAME(sh4) }, - { "sh4be", _16be, 0, CPU_DISASSEMBLE_NAME(sh4be) }, - { "sharc", _48le, -2, CPU_DISASSEMBLE_NAME(sharc) }, - { "sm500", _8bit, 0, CPU_DISASSEMBLE_NAME(sm500) }, - { "sm510", _8bit, 0, CPU_DISASSEMBLE_NAME(sm510) }, - { "sm511", _8bit, 0, CPU_DISASSEMBLE_NAME(sm511) }, - { "sm5a", _8bit, 0, CPU_DISASSEMBLE_NAME(sm5a) }, - { "sm8500", _8bit, 0, CPU_DISASSEMBLE_NAME(sm8500) }, - { "sparcv7", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv7) }, - { "sparcv8", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv8) }, - { "sparcv9", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9) }, - { "sparcv9vis1", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis1) }, - { "sparcv9vis2", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis2) }, - { "sparcv9vis2p",_32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis2p) }, - { "sparcv9vis3", _32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis3) }, - { "sparcv9vis3b",_32be, 0, CPU_DISASSEMBLE_NAME(sparcv9vis3b) }, - { "spc700", _8bit, 0, CPU_DISASSEMBLE_NAME(spc700) }, - { "ssem", _32le, 0, CPU_DISASSEMBLE_NAME(ssem) }, - { "ssp1601", _16be, -1, CPU_DISASSEMBLE_NAME(ssp1601) }, -// { "superfx", _8bit, 0, CPU_DISASSEMBLE_NAME(superfx) }, - { "t11", _16le, 0, CPU_DISASSEMBLE_NAME(t11) }, -// { "t90", _8bit, 0, CPU_DISASSEMBLE_NAME(t90) }, - { "tlcs900", _8bit, 0, CPU_DISASSEMBLE_NAME(tlcs900) }, - { "tms0980", _16be, 0, CPU_DISASSEMBLE_NAME(tms0980) }, - { "tms1000", _8bit, 0, CPU_DISASSEMBLE_NAME(tms1000) }, - { "tms1100", _8bit, 0, CPU_DISASSEMBLE_NAME(tms1100) }, - { "tms32010", _16be, -1, CPU_DISASSEMBLE_NAME(tms32010) }, - { "tms32025", _16be, -1, CPU_DISASSEMBLE_NAME(tms32025) }, - { "tms3203x", _32le, -2, CPU_DISASSEMBLE_NAME(tms3203x) }, - { "tms32051", _16le, -1, CPU_DISASSEMBLE_NAME(tms32051) }, - { "tms34010", _8bit, 3, CPU_DISASSEMBLE_NAME(tms34010) }, - { "tms34020", _8bit, 3, CPU_DISASSEMBLE_NAME(tms34020) }, - { "tms57002", _32le, -2, CPU_DISASSEMBLE_NAME(tms57002) }, - { "tms7000", _8bit, 0, CPU_DISASSEMBLE_NAME(tms7000) }, - { "tms9900", _16be, 0, CPU_DISASSEMBLE_NAME(tms9900) }, - { "tms9980", _8bit, 0, CPU_DISASSEMBLE_NAME(tms9980) }, - { "tms9995", _8bit, 0, CPU_DISASSEMBLE_NAME(tms9995) }, - { "tp0320", _16be, 0, CPU_DISASSEMBLE_NAME(tp0320) }, - { "tx0_64kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_64kw) }, - { "tx0_8kw", _32be, -2, CPU_DISASSEMBLE_NAME(tx0_8kw) }, - { "ucom4", _8bit, 0, CPU_DISASSEMBLE_NAME(ucom4) }, - { "unsp", _16be, 0, CPU_DISASSEMBLE_NAME(unsp) }, - { "upd7725", _32be, 0, CPU_DISASSEMBLE_NAME(upd7725) }, - { "upd7801", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7801) }, - { "upd7807", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7807) }, - { "upd7810", _8bit, 0, CPU_DISASSEMBLE_NAME(upd7810) }, - { "upd78c05", _8bit, 0, CPU_DISASSEMBLE_NAME(upd78c05) }, - { "upi41", _8bit, 0, CPU_DISASSEMBLE_NAME(upi41) }, - { "v60", _8bit, 0, CPU_DISASSEMBLE_NAME(v60) }, - { "v70", _8bit, 0, CPU_DISASSEMBLE_NAME(v70) }, - { "v810", _16le, 0, CPU_DISASSEMBLE_NAME(v810) }, - { "x86_16", _8bit, 0, CPU_DISASSEMBLE_NAME(x86_16) }, - { "x86_32", _8bit, 0, CPU_DISASSEMBLE_NAME(x86_32) }, - { "x86_64", _8bit, 0, CPU_DISASSEMBLE_NAME(x86_64) }, - { "z180", _8bit, 0, CPU_DISASSEMBLE_NAME(z180) }, - { "z8", _8bit, 0, CPU_DISASSEMBLE_NAME(z8) }, - { "z80", _8bit, 0, CPU_DISASSEMBLE_NAME(z80) }, -// { "z8000", _16be, 0, CPU_DISASSEMBLE_NAME(z8000) }, + offs_t pc; + offs_t size; + std::string dasm; }; +unidasm_data_buffer::unidasm_data_buffer(util::disasm_interface *_disasm, const dasm_table_entry *_entry) : disasm(_disasm), entry(_entry) +{ + u32 flags = disasm->interface_flags(); + u32 page_mask = flags & util::disasm_interface::PAGED ? (1 << disasm->page_address_bits()) - 1 : 0; + + if(flags & util::disasm_interface::NONLINEAR_PC) { + switch(entry->pcshift) { + case -1: + lr8 = [](offs_t pc) -> u8 { throw emu_fatalerror("debug_disasm_buffer::debug_data_buffer: r8 access on 16-bits granularity bus\n"); }; + lr16 = [this](offs_t pc) -> u16 { + const u16 *src = get_ptr<u16>(pc); + return src[0]; + }; + + switch(entry->endian) { + case le: + lr32 = [this, page_mask](offs_t pc) -> u32 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u16>(disasm->pc_linear_to_real(lpc)) << (j*16); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + lr64 = [this, page_mask](offs_t pc) -> u64 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u64 r = 0; + for(int j=0; j != 4; j++) { + r |= u64(get<u16>(disasm->pc_linear_to_real(lpc))) << (j*16); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + break; + + case be: + lr32 = [this, page_mask](offs_t pc) -> u32 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u16>(disasm->pc_linear_to_real(lpc)) << ((1-j)*16); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + lr64 = [this, page_mask](offs_t pc) -> u64 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u64 r = 0; + for(int j=0; j != 4; j++) { + r |= u64(get<u16>(disasm->pc_linear_to_real(lpc))) << ((3-j)*16); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + break; + } + break; + + case 0: + lr8 = [this](offs_t pc) -> u8 { + const u8 *src = get_ptr<u8>(pc); + return src[0]; + }; + + switch(entry->endian) { + case le: + lr16 = [this, page_mask](offs_t pc) -> u16 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u16 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(disasm->pc_linear_to_real(lpc)) << (j*8); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + lr32 = [this, page_mask](offs_t pc) -> u32 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(disasm->pc_linear_to_real(lpc)) << (j*8); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + lr64 = [this, page_mask](offs_t pc) -> u64 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u64 r = 0; + for(int j=0; j != 8; j++) { + r |= u64(get<u8>(disasm->pc_linear_to_real(lpc))) << (j*8); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + break; + + case be: + lr16 = [this, page_mask](offs_t pc) -> u16 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u16 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(disasm->pc_linear_to_real(lpc)) << ((1-j)*8); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + lr32 = [this, page_mask](offs_t pc) -> u32 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u32 r = 0; + for(int j=0; j != 2; j++) { + r |= get<u8>(disasm->pc_linear_to_real(lpc)) << ((3-j)*8); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + lr64 = [this, page_mask](offs_t pc) -> u64 { + offs_t lpc = disasm->pc_real_to_linear(pc); + u64 r = 0; + for(int j=0; j != 8; j++) { + r |= u64(get<u8>(disasm->pc_linear_to_real(lpc))) << ((7-j)*8); + lpc = (lpc & ~page_mask) | ((lpc + 1) & page_mask); + } + return r; + }; + break; + } + break; + } + } else { + switch(entry->pcshift) { + case 0: + lr8 = [this](offs_t pc) -> u8 { + const u8 *p = get_ptr<u8>(pc); + return p ? + p[0] + : 0x00; + }; + switch(entry->endian) { + case le: + lr16 = [this](offs_t pc) -> u16 { + const u8 *p = get_ptr<u8>(pc); + return p ? + p[0] | + (p[1] << 8) + : 0x0000; + }; + lr32 = [this](offs_t pc) -> u32 { + const u8 *p = get_ptr<u8>(pc); + return p ? + p[0] | + (p[1] << 8) | + (p[2] << 16) | + (p[3] << 24) + : 0x00000000; + }; + lr64 = [this](offs_t pc) -> u64 { + const u8 *p = get_ptr<u8>(pc); + return p ? + p[0] | + (p[1] << 8) | + (p[2] << 16) | + (p[3] << 24) | + (u64(p[4]) << 32) | + (u64(p[5]) << 40) | + (u64(p[6]) << 48) | + (u64(p[7]) << 56) + : 0x0000000000000000; }; + break; + case be: + lr16 = [this](offs_t pc) -> u16 { + const u8 *p = get_ptr<u8>(pc); + return p ? + (p[0] << 8) | + p[1] + : 0x0000; + }; + lr32 = [this](offs_t pc) -> u32 { + const u8 *p = get_ptr<u8>(pc); + return p ? + (p[0] << 24) | + (p[1] << 16) | + (p[2] << 8) | + p[3] + : 0x00000000; + }; + lr64 = [this](offs_t pc) -> u64 { + const u8 *p = get_ptr<u8>(pc); + return p ? + (u64(p[0]) << 56) | + (u64(p[1]) << 48) | + (u64(p[2]) << 40) | + (u64(p[3]) << 32) | + (p[4] << 24) | + (p[5] << 16) | + (p[6] << 8) | + p[7] + : 0x0000000000000000; }; + break; + } + break; + + case -1: + lr8 = [](offs_t pc) -> u8 { abort(); }; + lr16 = [this](offs_t pc) -> u16 { + const u16 *p = get_ptr<u16>(pc); + return p ? + p[0] + : 0x0000; + }; + switch(entry->endian) { + case le: + lr32 = [this](offs_t pc) -> u32 { + const u16 *p = get_ptr<u16>(pc); + return p ? + p[0] | + (p[1] << 16) + : 0x00000000; + }; + lr64 = [this](offs_t pc) -> u64 { + const u16 *p = get_ptr<u16>(pc); + return p ? + p[0] | + (p[1] << 16) | + (u64(p[2]) << 32) | + (u64(p[3]) << 48) + : 0x0000000000000000; + }; + break; + case be: + lr32 = [this](offs_t pc) -> u32 { + const u16 *p = get_ptr<u16>(pc); + return p ? + (p[0] << 16)| + p[1] + : 0x00000000; + }; + lr64 = [this](offs_t pc) -> u64 { + const u16 *p = get_ptr<u16>(pc); + return p ? + (u64(p[0]) << 48) | + (u64(p[1]) << 32) | + (p[2] << 16) | + p[3] + : 0x0000000000000000; + }; + break; + } + break; + + case -2: + lr8 = [](offs_t pc) -> u8 { abort(); }; + lr16 = [](offs_t pc) -> u16 { abort(); }; + lr32 = [this](offs_t pc) -> u16 { + const u32 *p = get_ptr<u32>(pc); + return p ? + p[0] + : 0x00000000; + }; + switch(entry->endian) { + case le: + lr64 = [this](offs_t pc) -> u64 { + const u32 *p = get_ptr<u32>(pc); + return p ? + p[0] | + (u64(p[1]) << 32) + : 0x0000000000000000; + }; + break; + case be: + lr64 = [this](offs_t pc) -> u64 { + const u32 *p = get_ptr<u32>(pc); + return p ? + (u64(p[0]) << 32) | + p[1] + : 0x0000000000000000; + }; + break; + } + break; + + case -3: + lr8 = [](offs_t pc) -> u8 { abort(); }; + lr16 = [](offs_t pc) -> u16 { abort(); }; + lr32 = [](offs_t pc) -> u32 { abort(); }; + lr64 = [this](offs_t pc) -> u64 { + const u64 *p = get_ptr<u64>(pc); + return p ? + p[0] + : 0x0000000000000000; + }; + break; + + case 3: + lr8 = [](offs_t pc) -> u8 { abort(); }; + lr32 = [](offs_t pc) -> u32 { abort(); }; + lr64 = [](offs_t pc) -> u64 { abort(); }; + lr16 = [this](offs_t pc) -> u16 { + if(pc < base_pc) + return 0x0000; + offs_t delta = (pc - base_pc) >> 3; + if(delta >= size) + return 0x0000; + return reinterpret_cast<const u16 *>(&data[delta])[0]; + }; + break; + + default: + abort(); + } + } +} + +void unidasm_data_buffer::decrypt(const unidasm_data_buffer &buffer, bool opcode) +{ + abort(); +} static int parse_options(int argc, char *argv[], options *opts) { @@ -420,92 +847,87 @@ static int parse_options(int argc, char *argv[], options *opts) memset(opts, 0, sizeof(*opts)); // loop through arguments - for (unsigned arg = 1; arg < argc; arg++) - { + for(unsigned arg = 1; arg < argc; arg++) { char *curarg = argv[arg]; // is it a switch? - if (curarg[0] == '-') - { - if (pending_base || pending_arch || pending_mode || pending_skip || pending_count) + if(curarg[0] == '-') { + if(pending_base || pending_arch || pending_mode || pending_skip || pending_count) goto usage; - if (tolower((uint8_t)curarg[1]) == 'a') + if(tolower((uint8_t)curarg[1]) == 'a') pending_arch = true; - else if (tolower((uint8_t)curarg[1]) == 'b') + else if(tolower((uint8_t)curarg[1]) == 'b') pending_base = true; - else if (tolower((uint8_t)curarg[1]) == 'f') + else if(tolower((uint8_t)curarg[1]) == 'f') opts->flipped = true; - else if (tolower((uint8_t)curarg[1]) == 'l') + else if(tolower((uint8_t)curarg[1]) == 'l') opts->lower = true; - else if (tolower((uint8_t)curarg[1]) == 'm') + else if(tolower((uint8_t)curarg[1]) == 'm') pending_mode = true; - else if (tolower((uint8_t)curarg[1]) == 's') + else if(tolower((uint8_t)curarg[1]) == 's') pending_skip = true; - else if (tolower((uint8_t)curarg[1]) == 'c') + else if(tolower((uint8_t)curarg[1]) == 'c') pending_count = true; - else if (tolower((uint8_t)curarg[1]) == 'n') + else if(tolower((uint8_t)curarg[1]) == 'n') opts->norawbytes = true; - else if (tolower((uint8_t)curarg[1]) == 'u') + else if(tolower((uint8_t)curarg[1]) == 'u') opts->upper = true; else goto usage; } // base PC - else if (pending_base) + else if(pending_base) { int result; - if (curarg[0] == '0' && curarg[1] == 'x') + if(curarg[0] == '0' && curarg[1] == 'x') result = sscanf(&curarg[2], "%x", &opts->basepc); - else if (curarg[0] == '$') + else if(curarg[0] == '$') result = sscanf(&curarg[1], "%x", &opts->basepc); else result = sscanf(&curarg[0], "%x", &opts->basepc); - if (result != 1) + if(result != 1) goto usage; pending_base = false; } // mode - else if (pending_mode) + else if(pending_mode) { - if (sscanf(curarg, "%d", &opts->mode) != 1) + if(sscanf(curarg, "%d", &opts->mode) != 1) goto usage; pending_mode = false; } // architecture - else if (pending_arch) - { + else if(pending_arch) { int curarch; - for (curarch = 0; curarch < ARRAY_LENGTH(dasm_table); curarch++) - if (core_stricmp(curarg, dasm_table[curarch].name) == 0) + for(curarch = 0; curarch < ARRAY_LENGTH(dasm_table); curarch++) + if(core_stricmp(curarg, dasm_table[curarch].name) == 0) break; - if (curarch == ARRAY_LENGTH(dasm_table)) + if(curarch == ARRAY_LENGTH(dasm_table)) goto usage; opts->dasm = &dasm_table[curarch]; pending_arch = false; } // skip bytes - else if (pending_skip) - { - if (sscanf(curarg, "%d", &opts->skip) != 1) + else if(pending_skip) { + if(sscanf(curarg, "%d", &opts->skip) != 1) goto usage; pending_skip = false; } // size - else if (pending_count) - { - if (sscanf(curarg, "%d", &opts->count) != 1) + else if(pending_count) { + if(sscanf(curarg, "%d", &opts->count) != 1) goto usage; pending_count = false; } // filename - else if (opts->filename == nullptr) + else if(opts->filename == nullptr) opts->filename = curarg; // fail @@ -514,11 +936,11 @@ static int parse_options(int argc, char *argv[], options *opts) } // if we have a dangling option, error - if (pending_base || pending_arch || pending_mode || pending_skip || pending_count) + if(pending_base || pending_arch || pending_mode || pending_skip || pending_count) goto usage; // if no file or no architecture, fail - if (opts->filename == nullptr || opts->dasm == nullptr) + if(opts->filename == nullptr || opts->dasm == nullptr) goto usage; return 0; @@ -531,12 +953,12 @@ usage: const int colwidth = 1 + std::strlen(std::max_element(std::begin(dasm_table), std::end(dasm_table), [](const dasm_table_entry &a, const dasm_table_entry &b) { return std::strlen(a.name) < std::strlen(b.name); })->name); const int columns = std::max(1, 80 / colwidth); const int numrows = (ARRAY_LENGTH(dasm_table) + columns - 1) / columns; - for (unsigned curarch = 0; curarch < numrows * columns; curarch++) + for(unsigned curarch = 0; curarch < numrows * columns; curarch++) { const int row = curarch / columns; const int col = curarch % columns; const int index = col * numrows + row; - if (col == 0) + if(col == 0) printf("\n "); printf("%-*s", colwidth, (index < ARRAY_LENGTH(dasm_table)) ? dasm_table[index].name : ""); } @@ -547,191 +969,311 @@ usage: int main(int argc, char *argv[]) { - osd_file::error filerr; - int displayendian; - int displaychunk; - uint32_t curbyte; - uint32_t length; - int maxchunks; - uint32_t curpc; + // Parse options first options opts; - int numbytes; - void *data; - int result = 0; - - // parse options first - if (parse_options(argc, argv, &opts)) + if(parse_options(argc, argv, &opts)) return 1; - // load the file - filerr = util::core_file::load(opts.filename, &data, length); - if (filerr != osd_file::error::NONE) + // Load the file + void *data; + uint32_t length; + osd_file::error filerr = util::core_file::load(opts.filename, &data, length); + if(filerr != osd_file::error::NONE) { fprintf(stderr, "Error opening file '%s'\n", opts.filename); return 1; } - // precompute parameters - displaychunk = (opts.dasm->display / 2) + 1; - displayendian = opts.dasm->display % 2; - switch (displaychunk) - { - case 1: maxchunks = 6; break; - case 2: maxchunks = 3; break; - default: maxchunks = 1; break; + // Build the disasm object + std::unique_ptr<util::disasm_interface> disasm(opts.dasm->alloc()); + u32 flags = disasm->interface_flags(); + + // Compute the granularity in bytes (1-8) + offs_t granularity = opts.dasm->pcshift < 0 ? disasm->opcode_alignment() << -opts.dasm->pcshift : disasm->opcode_alignment() >> opts.dasm->pcshift; + + // Build the base buffer and fill it (with a margin) + unidasm_data_buffer base_buffer(disasm.get(), opts.dasm); + u32 rounded_size = (((length - opts.skip) | (granularity - 1)) & ~(granularity - 1)); + base_buffer.data.resize(rounded_size + 8, 0x00); + base_buffer.size = length; + base_buffer.base_pc = opts.basepc; + memcpy(&base_buffer.data[0], (const u8 *)data + opts.skip, length - opts.skip); + + // Build the decryption buffers if needed + unidasm_data_buffer opcodes_buffer(disasm.get(), opts.dasm), params_buffer(disasm.get(), opts.dasm); + if(flags & util::disasm_interface::INTERNAL_DECRYPTION) { + opcodes_buffer.decrypt(base_buffer, true); + if((flags & util::disasm_interface::SPLIT_DECRYPTION) == util::disasm_interface::SPLIT_DECRYPTION) + params_buffer.decrypt(base_buffer, false); } - // run it - try - { - if (length > opts.skip) - length = length - opts.skip; - if ((length > opts.count) && (opts.count != 0)) - length = opts.count; - curpc = opts.basepc; - - std::stringstream stream; - for (curbyte = 0; curbyte < length; curbyte += numbytes) - { - uint8_t *oprom = (uint8_t *)data + opts.skip + curbyte; - uint32_t pcdelta; - int numchunks; + // Select the buffers to actually use + unidasm_data_buffer *popcodes = opcodes_buffer.data.empty() ? &base_buffer : &opcodes_buffer; + unidasm_data_buffer *pparams = params_buffer.data.empty() ? popcodes : ¶ms_buffer; - // disassemble - stream.str(""); - pcdelta = (*opts.dasm->func)(nullptr, stream, curpc, oprom, oprom, opts.mode) & DASMFLAG_LENGTHMASK; - std::string buffer = stream.str(); + // Compute the pc warparound + offs_t pclength = opts.dasm->pcshift < 0 ? rounded_size >> -opts.dasm->pcshift : rounded_size << opts.dasm->pcshift; + offs_t limit = opts.basepc + pclength; + offs_t pc_mask; + if(!limit) + pc_mask = 0xffffffff; + else { + for(pc_mask = 2; pc_mask && pc_mask < limit; pc_mask *= 2); + pc_mask--; + } - if (opts.dasm->pcshift < 0) - numbytes = pcdelta << -opts.dasm->pcshift; - else - numbytes = pcdelta >> opts.dasm->pcshift; - - // force upper or lower - if (opts.lower) - { - std::transform( - std::begin(buffer), - std::end(buffer), - std::begin(buffer), - [](char c) { return tolower(c); }); - } - else if (opts.upper) - { - std::transform( - std::begin(buffer), - std::end(buffer), - std::begin(buffer), - [](char c) { return toupper(c); }); - } + // Compute the page warparound + offs_t page_mask = flags & util::disasm_interface::PAGED ? (1 << disasm->page_address_bits()) - 1 : 0; - // round to the nearest display chunk - numbytes = ((numbytes + displaychunk - 1) / displaychunk) * displaychunk; - if (numbytes == 0) - numbytes = displaychunk; - numchunks = numbytes / displaychunk; - - // non-flipped case - if (!opts.flipped) - { - // output the address - printf("%08X: ", curpc); - - // output the raw bytes - if (!opts.norawbytes) - { - int firstchunks = (numchunks < maxchunks) ? numchunks : maxchunks; - int chunknum, bytenum; - for (chunknum = 0; chunknum < firstchunks; chunknum++) - { - for (bytenum = 0; bytenum < displaychunk; bytenum++) - printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]); - printf(" "); - oprom += displaychunk; - } - for ( ; chunknum < maxchunks; chunknum++) - printf("%*s ", displaychunk * 2, ""); - printf(" "); - } - - // output the disassembly - printf("%s\n", buffer.c_str()); - - // output additional raw bytes - if (!opts.norawbytes && numchunks > maxchunks) - { - for (numchunks -= maxchunks; numchunks > 0; numchunks -= maxchunks) - { - int firstchunks = (numchunks < maxchunks) ? numchunks : maxchunks; - int chunknum, bytenum; - printf(" "); - for (chunknum = 0; chunknum < firstchunks; chunknum++) - { - for (bytenum = 0; bytenum < displaychunk; bytenum++) - printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]); - printf(" "); - oprom += displaychunk; - } - printf("\n"); - } - } - } + // Next pc computation lambdas + std::function<offs_t (offs_t, offs_t)> next_pc; + std::function<offs_t (offs_t, offs_t)> next_pc_wrap; + if(flags & util::disasm_interface::NONLINEAR_PC) { + // lfsr pc is always paged + next_pc = [pc_mask, page_mask, dis = disasm.get()](offs_t pc, offs_t size) { + offs_t lpc = dis->pc_real_to_linear(pc); + offs_t lpce = lpc + size; + if((lpc ^ lpce) & ~page_mask) + lpce = (lpc | page_mask) + 1; + lpce &= pc_mask; + return dis->pc_linear_to_real(lpce); + }; + next_pc_wrap = [page_mask, dis = disasm.get()](offs_t pc, offs_t size) { + offs_t lpc = dis->pc_real_to_linear(pc); + offs_t lpce = (lpc & ~page_mask) | ((lpc + size) & page_mask); + return dis->pc_linear_to_real(lpce); + }; - // flipped case - else - { - // output the disassembly and address - printf("\t%-40s ; %08X", buffer.c_str(), curpc); - - // output the raw bytes - if (!opts.norawbytes) - { - int chunknum, bytenum; - printf(": "); - for (chunknum = 0; chunknum < numchunks; chunknum++) - { - for (bytenum = 0; bytenum < displaychunk; bytenum++) - printf("%02X", oprom[displayendian ? (displaychunk - 1 - bytenum) : bytenum]); - printf(" "); - oprom += displaychunk; - } - } - printf("\n"); - } + } else if(flags & util::disasm_interface::PAGED) { + next_pc = [pc_mask, page_mask](offs_t pc, offs_t size) { + offs_t pce = pc + size; + if((pc ^ pce) & ~page_mask) + pce = (pc | page_mask) + 1; + pce &= pc_mask; + return pce; + }; + next_pc_wrap = [page_mask](offs_t pc, offs_t size) { + offs_t pce = (pc & ~page_mask) | ((pc + size) & page_mask); + return pce; + }; - // advance - curpc += pcdelta; - } + } else { + next_pc = [pc_mask](offs_t pc, offs_t size) { + return (pc + size) & pc_mask; + }; + next_pc_wrap = [pc_mask](offs_t pc, offs_t size) { + return (pc + size) & pc_mask; + }; } - catch (emu_fatalerror &fatal) - { - fprintf(stderr, "%s\n", fatal.string()); - result = 1; - if (fatal.exitcode() != 0) - result = fatal.exitcode(); + + // Compute the shift amount from pc delta to granularity-sized elements + u32 granularity_shift = 31 - count_leading_zeros(disasm->opcode_alignment()); + + // Number of pc steps to disassemble + u32 count = pclength; + + if((count > opts.count) && (opts.count != 0)) + count = opts.count; + + // pc to string conversion + std::function<std::string (offs_t pc)> pc_to_string; + int aw = 32 - count_leading_zeros(pc_mask); + bool is_octal = false; // Parameter? Per-cpu config? + if((flags & util::disasm_interface::PAGED2LEVEL) == util::disasm_interface::PAGED2LEVEL) { + int bits1 = disasm->page_address_bits(); + int bits2 = disasm->page2_address_bits(); + int bits3 = aw - bits1 - bits2; + offs_t sm1 = (1 << bits1) - 1; + int sh2 = bits1; + offs_t sm2 = (1 << bits2) - 1; + int sh3 = bits1+bits2; + + if(is_octal) { + int nc1 = (bits1+2)/3; + int nc2 = (bits2+2)/3; + int nc3 = (bits3+2)/3; + pc_to_string = [nc1, nc2, nc3, sm1, sm2, sh2, sh3](offs_t pc) -> std::string { + return util::string_format("%0*o:%0*o:%0*o", + nc3, pc >> sh3, + nc2, (pc >> sh2) & sm2, + nc1, pc & sm1); + }; + } else { + int nc1 = (bits1+3)/4; + int nc2 = (bits2+3)/4; + int nc3 = (bits3+3)/4; + pc_to_string = [nc1, nc2, nc3, sm1, sm2, sh2, sh3](offs_t pc) -> std::string { + return util::string_format("%0*x:%0*x:%0*x", + nc3, pc >> sh3, + nc2, (pc >> sh2) & sm2, + nc1, pc & sm1); + }; + } + + } else if(flags & util::disasm_interface::PAGED) { + int bits1 = disasm->page_address_bits(); + int bits2 = aw - bits1; + offs_t sm1 = (1 << bits1) - 1; + int sh2 = bits1; + + if(is_octal) { + int nc1 = (bits1+2)/3; + int nc2 = (bits2+2)/3; + pc_to_string = [nc1, nc2, sm1, sh2](offs_t pc) -> std::string { + return util::string_format("%0*o:%0*o", + nc2, pc >> sh2, + nc1, pc & sm1); + }; + } else { + int nc1 = (bits1+3)/4; + int nc2 = (bits2+3)/4; + pc_to_string = [nc1, nc2, sm1, sh2](offs_t pc) -> std::string { + return util::string_format("%0*x:%0*x", + nc2, pc >> sh2, + nc1, pc & sm1); + }; + } + + } else { + int bits1 = aw; + + if(is_octal) { + int nc1 = (bits1+2)/3; + pc_to_string = [nc1](offs_t pc) -> std::string { + return util::string_format("%0*o", + nc1, pc); + }; + } else { + int nc1 = (bits1+3)/4; + pc_to_string = [nc1](offs_t pc) -> std::string { + return util::string_format("%0*x", + nc1, pc); + }; + } } - catch (emu_exception &) - { - fprintf(stderr, "Caught unhandled emulator exception\n"); - result = 1; + + // Lower/upper optional transform + std::function<std::string (const std::string &)> tf; + if(opts.lower) + tf = [](const std::string &str) -> std::string { + std::string result = str; + std::transform(result.begin(), result.end(), result.begin(), [](char c) { return tolower(c); }); + return result; + }; + else if(opts.upper) + tf = [](const std::string &str) -> std::string { + std::string result = str; + std::transform(result.begin(), result.end(), result.begin(), [](char c) { return toupper(c); }); + return result; + }; + else + tf = [](const std::string &str) -> std::string { + return str; + }; + + + // Do the disassembly + std::vector<dasm_line> dasm_lines; + offs_t curpc = opts.basepc; + for(u32 i=0; i < count;) { + std::ostringstream stream; + offs_t result = disasm->disassemble(stream, curpc, *popcodes, *pparams); + offs_t len = result & util::disasm_interface::LENGTHMASK; + dasm_lines.emplace_back(dasm_line{ curpc, len, stream.str() }); + curpc = next_pc(curpc, len); + i += len; } - catch (tag_add_exception &aex) - { - fprintf(stderr, "Tag '%s' already exists in tagged map\n", aex.tag()); - result = 1; + + // Compute the extrema + offs_t max_len = 0; + size_t max_text = 0; + for(const auto &l : dasm_lines) { + if(max_len < l.size) + max_len = l.size; + size_t s = l.dasm.size(); + if(max_text < s) + max_text = s; } - catch (std::exception &ex) - { - fprintf(stderr, "Caught unhandled %s exception: %s\n", typeid(ex).name(), ex.what()); - result = 1; + + // Build the raw bytes generator and compute the field size + max_len >>= granularity_shift; + std::function<std::string (offs_t pc, offs_t size)> dump_raw_bytes; + + switch(granularity) { + case 1: + dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string { + std::string result = ""; + for(offs_t i=0; i != size; i++) { + if(i) + result += ' '; + result += util::string_format("%02x", base_buffer.r8(pc)); + pc = next_pc(pc, step); + } + return result; + }; + max_len = (max_len * 3) - 1; + break; + + case 2: + dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string { + std::string result = ""; + for(offs_t i=0; i != size; i++) { + if(i) + result += ' '; + result += util::string_format("%04x", base_buffer.r16(pc)); + pc = next_pc(pc, step); + } + return result; + }; + max_len = (max_len * 5) - 1; + break; + + case 4: + dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string { + std::string result = ""; + for(offs_t i=0; i != size; i++) { + if(i) + result += ' '; + result += util::string_format("%08x", base_buffer.r32(pc)); + pc = next_pc(pc, step); + } + return result; + }; + max_len = (max_len * 9) - 1; + break; + + case 8: + dump_raw_bytes = [step = disasm->opcode_alignment(), next_pc, base_buffer](offs_t pc, offs_t size) -> std::string { + std::string result = ""; + for(offs_t i=0; i != size; i++) { + if(i) + result += ' '; + result += util::string_format("%016x", base_buffer.r64(pc)); + pc = next_pc(pc, step); + } + return result; + }; + max_len = (max_len * 17) - 1; + break; } - catch (...) - { - fprintf(stderr, "Caught unhandled exception\n"); - result = 1; + + if(opts.flipped) { + if(opts.norawbytes) + for(const auto &l : dasm_lines) + util::stream_format(std::cout, "%-*s ; %s\n", max_text, tf(l.dasm), tf(pc_to_string(l.pc))); + else + for(const auto &l : dasm_lines) + util::stream_format(std::cout, "%-*s ; %s: %s\n", max_text, tf(l.dasm), tf(pc_to_string(l.pc)), tf(dump_raw_bytes(l.pc, l.size >> granularity_shift))); + } else { + if(opts.norawbytes) + for(const auto &l : dasm_lines) + util::stream_format(std::cout, "%s: %s\n", tf(pc_to_string(l.pc)), tf(l.dasm)); + else + for(const auto &l : dasm_lines) + util::stream_format(std::cout, "%s: %-*s %s\n", tf(pc_to_string(l.pc)), max_len, tf(dump_raw_bytes(l.pc, l.size >> granularity_shift)), tf(l.dasm)); } free(data); - return result; + return 0; } |